A Razor UI page for the spawn menu that displays server limit settings. It builds a list of editable properties from the LimitSystem's static convars and exposes them through a UISheet, only visible to the host.
@using Sandbox;
@using Sandbox.UI;
@inherits UtilityPage
@namespace Sandbox
@attribute [Icon( "🚧" )]
@attribute [Title( "#server.group.limits" )]
@attribute [Group( "#spawnmenu.utility.group.server" )]
@attribute [Order( 10 )]
<root class="page">
<UISheet Target="@Settings" PropertyFilter="@UISheet.PropertiesAndButtons" />
</root>
@code
{
// The limits are replicated server convars - only the host can change them.
public override bool IsPageVisible() => Networking.IsHost;
readonly List<SerializedProperty> Settings = BuildSettings();
// One row per limit convar, written through the console system so the replicated value changes for everyone.
static List<SerializedProperty> BuildSettings()
{
var limits = Game.TypeLibrary.GetType( typeof( LimitsSystem ) );
return limits.Properties
.Where( p => p.IsStatic && p.HasAttribute<ConVarAttribute>() )
.OrderBy( p => p.GetCustomAttribute<OrderAttribute>()?.Value ?? 0 )
.Select( p =>
{
var convar = p.GetCustomAttribute<ConVarAttribute>().Name;
var phrase = $"#server.{convar["sandbox.".Length..]}";
var attributes = new List<Attribute> { new PropertyAttribute(), new DescriptionAttribute( $"{phrase}.description" ), new StepAttribute( 1 ) };
if ( p.GetCustomAttribute<RangeAttribute>() is { } range ) attributes.Add( range );
// the name is what the row shows
return Game.TypeLibrary.CreateProperty<int>( phrase, () => (int)p.GetValue( null ), v => ConsoleSystem.SetValue( convar, v ), attributes.ToArray() );
} )
.ToList();
}
}