mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
137 lines
4.1 KiB
C#
137 lines
4.1 KiB
C#
using Robust.Shared.Configuration;
|
|
using Robust.Shared.Network;
|
|
using Robust.Shared.Network.Messages;
|
|
using Robust.Shared.Timing;
|
|
using Robust.Shared.Utility;
|
|
using System.Collections.Generic;
|
|
using Robust.Shared.IoC;
|
|
using Robust.Shared.Replays;
|
|
|
|
namespace Robust.Server.Configuration;
|
|
|
|
internal sealed class ServerNetConfigurationManager : NetConfigurationManager, IServerNetConfigurationManager
|
|
{
|
|
[Dependency] private readonly IGameTiming _timing = default!;
|
|
[Dependency] private readonly IReplayRecordingManager _replayRecording = default!;
|
|
|
|
private readonly Dictionary<INetChannel, Dictionary<string, object>> _replicatedCVars = new();
|
|
|
|
public override void SetupNetworking()
|
|
{
|
|
base.SetupNetworking();
|
|
NetManager.Connected += PeerConnected;
|
|
NetManager.Disconnect += PeerDisconnected;
|
|
}
|
|
|
|
public override void Shutdown()
|
|
{
|
|
base.Shutdown();
|
|
_replicatedCVars.Clear();
|
|
}
|
|
|
|
private void PeerConnected(object? sender, NetChannelArgs e)
|
|
{
|
|
_replicatedCVars.Add(e.Channel, new Dictionary<string, object>());
|
|
}
|
|
|
|
private void PeerDisconnected(object? sender, NetDisconnectedArgs e)
|
|
{
|
|
_replicatedCVars.Remove(e.Channel);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override T GetClientCVar<T>(INetChannel channel, string name)
|
|
{
|
|
using var _ = Lock.ReadGuard();
|
|
|
|
if (!_configVars.TryGetValue(name, out var cVar) || !cVar.Registered)
|
|
throw new InvalidConfigurationException($"Trying to get unregistered variable '{name}'");
|
|
|
|
if (_replicatedCVars.TryGetValue(channel, out var clientCVars) && clientCVars.TryGetValue(name, out var value))
|
|
{
|
|
return (T)value;
|
|
}
|
|
|
|
return (T)(cVar.DefaultValue!);
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override void SetCVar(string name, object value, bool force)
|
|
{
|
|
CVar flags;
|
|
using (Lock.ReadGuard())
|
|
{
|
|
if (!_configVars.TryGetValue(name, out var cVar) || !cVar.Registered)
|
|
throw new InvalidConfigurationException($"Trying to set unregistered variable '{name}'");
|
|
|
|
flags = cVar.Flags;
|
|
}
|
|
|
|
if (!force && (flags & CVar.CLIENT) != 0)
|
|
{
|
|
Sawmill.Warning($"Only clients can change the '{name}' cvar.");
|
|
return;
|
|
}
|
|
|
|
// Actually set the CVar
|
|
base.SetCVar(name, value, force);
|
|
|
|
if ((flags & CVar.REPLICATED) == 0)
|
|
return;
|
|
|
|
var msg = new MsgConVars();
|
|
msg.Tick = Timing.CurTick;
|
|
msg.NetworkedVars = new List<(string name, object value)>{ (name, value) };
|
|
|
|
NetManager.ServerSendToAll(msg);
|
|
|
|
_replayRecording.RecordServerMessage(new ReplayMessage.CvarChangeMsg()
|
|
{
|
|
ReplicatedCvars = msg.NetworkedVars,
|
|
TimeBase = _timing.TimeBase
|
|
});
|
|
}
|
|
|
|
protected override void ApplyNetVarChange(
|
|
INetChannel msgChannel,
|
|
List<(string name, object value)> networkedVars,
|
|
GameTick tick)
|
|
{
|
|
Sawmill.Debug($"{msgChannel} Handling replicated cvars...");
|
|
|
|
// Client sent us a CVar update
|
|
if (!_replicatedCVars.TryGetValue(msgChannel, out var clientCVars))
|
|
{
|
|
Sawmill.Warning($"{msgChannel} tried to replicate CVars but is not in _replicatedCVars.");
|
|
return;
|
|
}
|
|
|
|
using var _ = Lock.ReadGuard();
|
|
|
|
foreach (var (name, value) in networkedVars)
|
|
{
|
|
if (!_configVars.TryGetValue(name, out var cVar))
|
|
{
|
|
Sawmill.Warning($"{msgChannel} tried to replicate an unknown CVar '{name}.'");
|
|
continue;
|
|
}
|
|
|
|
if (!cVar.Registered)
|
|
{
|
|
Sawmill.Warning($"{msgChannel} tried to replicate an unregistered CVar '{name}.'");
|
|
continue;
|
|
}
|
|
|
|
if ((cVar.Flags & CVar.REPLICATED) != 0)
|
|
{
|
|
clientCVars[name] = value;
|
|
Sawmill.Debug($"name={name}, val={value}");
|
|
}
|
|
else
|
|
{
|
|
Sawmill.Warning($"{msgChannel} tried to replicate an un-replicated CVar '{name}.'");
|
|
}
|
|
}
|
|
}
|
|
}
|