mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-02-15 03:30:53 +01:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cbf01f0aa5 | ||
|
|
6973d43006 | ||
|
|
c5a961d9a0 | ||
|
|
b4f7d71ee7 | ||
|
|
cd3684e575 | ||
|
|
317b8ce965 | ||
|
|
ff96140afa | ||
|
|
bade95f6b7 |
Submodule Lidgren.Network/Lidgren.Network updated: 4a5cedacb2...73554e6061
@@ -36,7 +36,7 @@ namespace Robust.Client.Console
|
||||
Message = message;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <inheritdoc cref="IClientConsoleHost" />
|
||||
internal class ClientConsoleHost : ConsoleHost, IClientConsoleHost
|
||||
{
|
||||
@@ -47,12 +47,20 @@ namespace Robust.Client.Console
|
||||
{
|
||||
NetManager.RegisterNetMessage<MsgConCmdReg>(MsgConCmdReg.NAME, HandleConCmdReg);
|
||||
NetManager.RegisterNetMessage<MsgConCmdAck>(MsgConCmdAck.NAME, HandleConCmdAck);
|
||||
NetManager.RegisterNetMessage<MsgConCmd>(MsgConCmd.NAME);
|
||||
NetManager.RegisterNetMessage<MsgConCmd>(MsgConCmd.NAME, ProcessCommand);
|
||||
|
||||
Reset();
|
||||
LogManager.RootSawmill.AddHandler(new DebugConsoleLogHandler(this));
|
||||
}
|
||||
|
||||
private void ProcessCommand(MsgConCmd message)
|
||||
{
|
||||
string? text = message.Text;
|
||||
LogManager.GetSawmill(SawmillName).Info($"SERVER:{text}");
|
||||
|
||||
ExecuteCommand(null, text);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Reset()
|
||||
{
|
||||
@@ -104,14 +112,14 @@ namespace Robust.Client.Console
|
||||
args.RemoveAt(0);
|
||||
command1.Execute(new ConsoleShell(this, null), command, args.ToArray());
|
||||
}
|
||||
else if (!NetManager.IsConnected)
|
||||
else
|
||||
WriteError(null, "Unknown command: " + commandName);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void RemoteExecuteCommand(ICommonSession? session, string command)
|
||||
{
|
||||
if (!NetManager.IsConnected)
|
||||
if (!NetManager.IsConnected) // we don't care about session on client
|
||||
return;
|
||||
|
||||
var msg = NetManager.CreateNetMessage<MsgConCmd>();
|
||||
|
||||
@@ -78,6 +78,8 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
private void SetData(object key, object value)
|
||||
{
|
||||
if (data.TryGetValue(key, out var existing) && existing.Equals(value)) return;
|
||||
|
||||
data[key] = value;
|
||||
|
||||
MarkDirty();
|
||||
@@ -85,10 +87,9 @@ namespace Robust.Client.GameObjects
|
||||
|
||||
public override void HandleComponentState(ComponentState? curState, ComponentState? nextState)
|
||||
{
|
||||
if (curState == null)
|
||||
if (curState is not AppearanceComponentState actualState)
|
||||
return;
|
||||
|
||||
var actualState = (AppearanceComponentState) curState;
|
||||
data = actualState.Data;
|
||||
MarkDirty();
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace Robust.Client.UserInterface.CustomControls
|
||||
|
||||
_contents.Text = $@"Paused: {_gameTiming.Paused}, CurTick: {_gameTiming.CurTick}/{_gameTiming.CurTick-1}, CurServerTick: {_gameState.CurServerTick}, Pred: {_gameTiming.CurTick.Value - _gameState.CurServerTick.Value-1}
|
||||
CurTime: {_gameTiming.CurTime:hh\:mm\:ss\.ff}, RealTime: {_gameTiming.RealTime:hh\:mm\:ss\.ff}, CurFrame: {_gameTiming.CurFrame}
|
||||
TickTimingAdjustment: {_gameTiming.TickTimingAdjustment}";
|
||||
ServerTime: {_gameTiming.ServerTime}, TickTimingAdjustment: {_gameTiming.TickTimingAdjustment}";
|
||||
|
||||
MinimumSizeChanged();
|
||||
}
|
||||
|
||||
@@ -28,7 +28,12 @@ namespace Robust.Server.Console
|
||||
/// <inheritdoc />
|
||||
public override void RemoteExecuteCommand(ICommonSession? session, string command)
|
||||
{
|
||||
//TODO: Server -> Client remote execute, just like how the client forwards the command
|
||||
if (!NetManager.IsConnected || session is null)
|
||||
return;
|
||||
|
||||
var msg = NetManager.CreateNetMessage<MsgConCmd>();
|
||||
msg.Text = command;
|
||||
NetManager.ServerSendMessage(msg, ((IPlayerSession)session).ConnectedClient);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -52,16 +57,13 @@ namespace Robust.Server.Console
|
||||
/// <inheritdoc />
|
||||
public void Initialize()
|
||||
{
|
||||
RegisterCommand("sudo", "sudo make me a sandwich", "sudo <command>",(shell, _, args) =>
|
||||
RegisterCommand("sudo", "sudo make me a sandwich", "sudo <command>",(shell, argStr, _) =>
|
||||
{
|
||||
string command = args[0];
|
||||
var cArgs = args[1..].Select(CommandParsing.Escape);
|
||||
|
||||
var localShell = shell.ConsoleHost.LocalShell;
|
||||
var sudoShell = new SudoShell(this, localShell, shell);
|
||||
ExecuteInShell(sudoShell, $"{command} {string.Join(' ', cArgs)}");
|
||||
ExecuteInShell(sudoShell, argStr.Substring("sudo ".Length));
|
||||
});
|
||||
|
||||
|
||||
LoadConsoleCommands();
|
||||
|
||||
// setup networking with clients
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Net;
|
||||
using System;
|
||||
using System.Net;
|
||||
using Robust.Shared.Network;
|
||||
|
||||
namespace Robust.Shared.Interfaces.Network
|
||||
@@ -34,6 +35,16 @@ namespace Robust.Shared.Interfaces.Network
|
||||
|
||||
LoginType AuthType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Offset between local RealTime and remote RealTime.
|
||||
/// </summary>
|
||||
TimeSpan RemoteTimeOffset { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Remote RealTime.
|
||||
/// </summary>
|
||||
TimeSpan RemoteTime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Average round trip time in milliseconds between the remote peer and us.
|
||||
/// </summary>
|
||||
|
||||
@@ -31,6 +31,15 @@ namespace Robust.Shared.Interfaces.Timing
|
||||
/// </summary>
|
||||
TimeSpan RealTime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="RealTime"/> of the server.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// 0 if we are the client and we are not connected to a server.
|
||||
/// <see cref="RealTime"/> if we are the server.
|
||||
/// </remarks>
|
||||
TimeSpan ServerTime { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The simulated time it took to render the last frame.
|
||||
/// </summary>
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using Lidgren.Network;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
|
||||
namespace Robust.Shared.Network
|
||||
{
|
||||
/// <summary>
|
||||
/// A network connection from this local peer to a remote peer.
|
||||
/// </summary>
|
||||
internal class NetChannel : INetChannel
|
||||
{
|
||||
private readonly NetManager _manager;
|
||||
private readonly NetConnection _connection;
|
||||
|
||||
/// <inheritdoc />
|
||||
public long ConnectionId => _connection.RemoteUniqueIdentifier;
|
||||
|
||||
/// <inheritdoc />
|
||||
public INetManager NetPeer => _manager;
|
||||
|
||||
public string UserName { get; }
|
||||
public LoginType AuthType { get; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public short Ping => (short) Math.Round(_connection.AverageRoundtripTime * 1000);
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsConnected => _connection.Status == NetConnectionStatus.Connected;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IPEndPoint RemoteEndPoint => _connection.RemoteEndPoint;
|
||||
|
||||
/// <summary>
|
||||
/// Exposes the lidgren connection.
|
||||
/// </summary>
|
||||
public NetConnection Connection => _connection;
|
||||
|
||||
public NetUserId UserId { get; }
|
||||
|
||||
// Only used on server, contains the encryption to use for this channel.
|
||||
public NetEncryption? Encryption { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of a NetChannel.
|
||||
/// </summary>
|
||||
/// <param name="manager">The server this channel belongs to.</param>
|
||||
/// <param name="connection">The raw NetConnection to the remote peer.</param>
|
||||
internal NetChannel(NetManager manager, NetConnection connection, NetUserId userId, string userName, LoginType loginType)
|
||||
{
|
||||
_manager = manager;
|
||||
_connection = connection;
|
||||
UserId = userId;
|
||||
UserName = userName;
|
||||
AuthType = loginType;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public T CreateNetMessage<T>()
|
||||
where T : NetMessage
|
||||
{
|
||||
return _manager.CreateNetMessage<T>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SendMessage(NetMessage message)
|
||||
{
|
||||
if (_manager.IsClient)
|
||||
{
|
||||
_manager.ClientSendMessage(message);
|
||||
return;
|
||||
}
|
||||
|
||||
_manager.ServerSendMessage(message, this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Disconnect(string reason)
|
||||
{
|
||||
if (_connection.Status == NetConnectionStatus.Connected)
|
||||
_connection.Disconnect(reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
87
Robust.Shared/Network/NetManager.NetChannel.cs
Normal file
87
Robust.Shared/Network/NetManager.NetChannel.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using System;
|
||||
using System.Net;
|
||||
using Lidgren.Network;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
|
||||
namespace Robust.Shared.Network
|
||||
{
|
||||
public partial class NetManager
|
||||
{
|
||||
private class NetChannel : INetChannel
|
||||
{
|
||||
private readonly NetManager _manager;
|
||||
private readonly NetConnection _connection;
|
||||
|
||||
/// <inheritdoc />
|
||||
public long ConnectionId => _connection.RemoteUniqueIdentifier;
|
||||
|
||||
/// <inheritdoc />
|
||||
public INetManager NetPeer => _manager;
|
||||
|
||||
public string UserName { get; }
|
||||
public LoginType AuthType { get; }
|
||||
public TimeSpan RemoteTimeOffset => TimeSpan.FromSeconds(_connection.RemoteTimeOffset);
|
||||
public TimeSpan RemoteTime => _manager._timing.RealTime + RemoteTimeOffset;
|
||||
|
||||
/// <inheritdoc />
|
||||
public short Ping => (short) Math.Round(_connection.AverageRoundtripTime * 1000);
|
||||
|
||||
/// <inheritdoc />
|
||||
public bool IsConnected => _connection.Status == NetConnectionStatus.Connected;
|
||||
|
||||
/// <inheritdoc />
|
||||
public IPEndPoint RemoteEndPoint => _connection.RemoteEndPoint;
|
||||
|
||||
/// <summary>
|
||||
/// Exposes the lidgren connection.
|
||||
/// </summary>
|
||||
public NetConnection Connection => _connection;
|
||||
|
||||
public NetUserId UserId { get; }
|
||||
|
||||
// Only used on server, contains the encryption to use for this channel.
|
||||
public NetEncryption? Encryption { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of a NetChannel.
|
||||
/// </summary>
|
||||
/// <param name="manager">The server this channel belongs to.</param>
|
||||
/// <param name="connection">The raw NetConnection to the remote peer.</param>
|
||||
internal NetChannel(NetManager manager, NetConnection connection, NetUserId userId, string userName,
|
||||
LoginType loginType)
|
||||
{
|
||||
_manager = manager;
|
||||
_connection = connection;
|
||||
UserId = userId;
|
||||
UserName = userName;
|
||||
AuthType = loginType;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public T CreateNetMessage<T>()
|
||||
where T : NetMessage
|
||||
{
|
||||
return _manager.CreateNetMessage<T>();
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void SendMessage(NetMessage message)
|
||||
{
|
||||
if (_manager.IsClient)
|
||||
{
|
||||
_manager.ClientSendMessage(message);
|
||||
return;
|
||||
}
|
||||
|
||||
_manager.ServerSendMessage(message, this);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Disconnect(string reason)
|
||||
{
|
||||
if (_connection.Status == NetConnectionStatus.Connected)
|
||||
_connection.Disconnect(reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -105,7 +105,7 @@ namespace Robust.Shared.Network
|
||||
// Launcher gives the client the public RSA key of the server BUT
|
||||
// that doesn't persist if the server restarts.
|
||||
// In that case, the decrypt can fail here.
|
||||
connection.Disconnect("Token decryption failed./nPlease reconnect to this server from the launcher.");
|
||||
connection.Disconnect("Token decryption failed.\nPlease reconnect to this server from the launcher.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ using Prometheus;
|
||||
using Robust.Shared.Interfaces.Configuration;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.Interfaces.Serialization;
|
||||
using Robust.Shared.Interfaces.Timing;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Utility;
|
||||
@@ -112,6 +113,7 @@ namespace Robust.Shared.Network
|
||||
|
||||
[Dependency] private readonly IConfigurationManagerInternal _config = default!;
|
||||
[Dependency] private readonly IAuthManager _authManager = default!;
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Holds lookup table for NetMessage.Id -> NetMessage.Type
|
||||
@@ -235,6 +237,8 @@ namespace Robust.Shared.Network
|
||||
throw new InvalidOperationException("NetManager has already been initialized.");
|
||||
}
|
||||
|
||||
SynchronizeNetTime();
|
||||
|
||||
IsServer = isServer;
|
||||
|
||||
_config.OnValueChanged(CVars.NetVerbose, NetVerboseChanged);
|
||||
@@ -265,6 +269,24 @@ namespace Robust.Shared.Network
|
||||
}
|
||||
}
|
||||
|
||||
private void SynchronizeNetTime()
|
||||
{
|
||||
// Synchronize Lidgren NetTime with our RealTime.
|
||||
|
||||
for (var i = 0; i < 10; i++)
|
||||
{
|
||||
// Try and set this in a loop to avoid any JIT hang fuckery or similar.
|
||||
// Loop until the time is within acceptable margin.
|
||||
// Fixing this "properly" would basically require re-architecturing Lidgren to do DI stuff
|
||||
// so we can more sanely wire these together.
|
||||
NetTime.SetNow(_timing.RealTime.TotalSeconds);
|
||||
var dev = TimeSpan.FromSeconds(NetTime.Now) - _timing.RealTime;
|
||||
|
||||
if (Math.Abs(dev.TotalMilliseconds) < 0.05)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateNetMessageFunctions(MsgStringTableEntries.Entry[] entries)
|
||||
{
|
||||
foreach (var entry in entries)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.Interfaces.Timing;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Utility;
|
||||
using Robust.Shared.Log;
|
||||
|
||||
namespace Robust.Shared.Timing
|
||||
{
|
||||
@@ -20,6 +20,8 @@ namespace Robust.Shared.Timing
|
||||
private readonly List<long> _realFrameTimes = new(NumFrames);
|
||||
private TimeSpan _lastRealTime;
|
||||
|
||||
[Dependency] private readonly INetManager _netManager = default!;
|
||||
|
||||
/// <summary>
|
||||
/// Default constructor.
|
||||
/// </summary>
|
||||
@@ -87,6 +89,25 @@ namespace Robust.Shared.Timing
|
||||
/// </summary>
|
||||
public TimeSpan RealTime => _realTimer.Elapsed;
|
||||
|
||||
public TimeSpan ServerTime
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_netManager.IsServer)
|
||||
{
|
||||
return RealTime;
|
||||
}
|
||||
|
||||
var clientNetManager = (IClientNetManager) _netManager;
|
||||
if (clientNetManager.ServerChannel == null)
|
||||
{
|
||||
return TimeSpan.Zero;
|
||||
}
|
||||
|
||||
return clientNetManager.ServerChannel.RemoteTime;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The simulated time it took to render the last frame.
|
||||
/// </summary>
|
||||
|
||||
@@ -5,6 +5,8 @@ using System.Net;
|
||||
using System.Threading.Channels;
|
||||
using System.Threading.Tasks;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.Interfaces.Timing;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Utility;
|
||||
|
||||
@@ -14,6 +16,7 @@ namespace Robust.UnitTesting
|
||||
{
|
||||
internal sealed class IntegrationNetManager : IClientNetManager, IServerNetManager
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _gameTiming = default!;
|
||||
public bool IsServer { get; private set; }
|
||||
public bool IsClient => !IsServer;
|
||||
public bool IsRunning { get; private set; }
|
||||
@@ -371,6 +374,8 @@ namespace Robust.UnitTesting
|
||||
public NetUserId UserId { get; }
|
||||
public string UserName { get; }
|
||||
public LoginType AuthType => LoginType.GuestAssigned;
|
||||
public TimeSpan RemoteTimeOffset => TimeSpan.Zero; // TODO: Fix this
|
||||
public TimeSpan RemoteTime => _owner._gameTiming.RealTime + RemoteTimeOffset;
|
||||
public short Ping => default;
|
||||
|
||||
public IntegrationNetChannel(IntegrationNetManager owner, ChannelWriter<object> otherChannel, int uid,
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using Robust.Server.Reflection;
|
||||
@@ -12,11 +11,13 @@ using Robust.Shared.Interfaces.Log;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.Interfaces.Reflection;
|
||||
using Robust.Shared.Interfaces.Serialization;
|
||||
using Robust.Shared.Interfaces.Timing;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Serialization;
|
||||
using Robust.Shared.Timing;
|
||||
|
||||
namespace Robust.UnitTesting.Shared.GameObjects
|
||||
{
|
||||
@@ -38,6 +39,8 @@ namespace Robust.UnitTesting.Shared.GameObjects
|
||||
container.Register<IReflectionManager, ServerReflectionManager>();
|
||||
container.Register<IRobustSerializer, RobustSerializer>();
|
||||
container.Register<IRobustMappedStringSerializer, RobustMappedStringSerializer>();
|
||||
container.Register<IAuthManager, AuthManager>();
|
||||
container.Register<IGameTiming, GameTiming>();
|
||||
container.BuildGraph();
|
||||
|
||||
var cfg = container.Resolve<IConfigurationManagerInternal>();
|
||||
|
||||
Reference in New Issue
Block a user