From f1616f6532f64dae72f238e9418f4ba961e451cf Mon Sep 17 00:00:00 2001 From: Brant Martin Date: Fri, 16 Aug 2019 12:48:16 -0400 Subject: [PATCH] Implement kick on restart --- Torch.API/ITorchConfig.cs | 1 + Torch.Mod/Messages/JoinServerMessage.cs | 57 ++++++++++++++++ Torch.Mod/Messages/MessageBase.cs | 3 +- Torch.Mod/ModCommunication.cs | 91 +++++++++++++++---------- Torch.Mod/Torch.Mod.projitems | 1 + Torch.Mod/TorchModCore.cs | 13 ++++ Torch.Server/TorchConfig.cs | 3 + Torch.Server/TorchServer.cs | 6 ++ 8 files changed, 138 insertions(+), 37 deletions(-) create mode 100644 Torch.Mod/Messages/JoinServerMessage.cs diff --git a/Torch.API/ITorchConfig.cs b/Torch.API/ITorchConfig.cs index 70cc019..1fa9c4f 100644 --- a/Torch.API/ITorchConfig.cs +++ b/Torch.API/ITorchConfig.cs @@ -22,6 +22,7 @@ namespace Torch string WaitForPID { get; set; } string ChatName { get; set; } string ChatColor { get; set; } + bool DisconnectOnRestart { get; set; } bool Save(string path = null); } diff --git a/Torch.Mod/Messages/JoinServerMessage.cs b/Torch.Mod/Messages/JoinServerMessage.cs new file mode 100644 index 0000000..ffc8ab0 --- /dev/null +++ b/Torch.Mod/Messages/JoinServerMessage.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Text; +using ProtoBuf; +using Sandbox.ModAPI; + +namespace Torch.Mod.Messages +{ + [ProtoContract] + public class JoinServerMessage : MessageBase + { + [ProtoMember(201)] + public int Delay; + [ProtoMember(202)] + public string Address; + + private JoinServerMessage() + { + + } + + public JoinServerMessage(string address) + { + Address = address; + } + + public JoinServerMessage(string address, int delay) + { + Address = address; + Delay = delay; + } + + public override void ProcessClient() + { + if (TorchModCore.Debug) + { + MyAPIGateway.Utilities.ShowMessage("Torch", $"Joining server {Address} with delay {Delay}"); + } + + if (Delay <= 0) + { + MyAPIGateway.Multiplayer.JoinServer(Address); + return; + } + + MyAPIGateway.Parallel.StartBackground(() => + { + MyAPIGateway.Parallel.Sleep(Delay); + MyAPIGateway.Multiplayer.JoinServer(Address); + }); + } + + public override void ProcessServer() + { + } + } +} diff --git a/Torch.Mod/Messages/MessageBase.cs b/Torch.Mod/Messages/MessageBase.cs index 3a00738..55bc140 100644 --- a/Torch.Mod/Messages/MessageBase.cs +++ b/Torch.Mod/Messages/MessageBase.cs @@ -11,6 +11,7 @@ namespace Torch.Mod.Messages [ProtoInclude(1, typeof(DialogMessage))] [ProtoInclude(2, typeof(NotificationMessage))] [ProtoInclude(3, typeof(VoxelResetMessage))] + [ProtoInclude(4, typeof(JoinServerMessage))] #endregion [ProtoContract] @@ -28,7 +29,7 @@ namespace Torch.Mod.Messages internal ulong[] Ignore; internal byte[] CompressedData; } - + public enum MessageTarget { /// diff --git a/Torch.Mod/ModCommunication.cs b/Torch.Mod/ModCommunication.cs index 2c7b492..76be249 100644 --- a/Torch.Mod/ModCommunication.cs +++ b/Torch.Mod/ModCommunication.cs @@ -10,6 +10,7 @@ using Torch.Mod.Messages; using VRage; using VRage.Collections; using VRage.Game.ModAPI; +using VRage.Network; using VRage.Utils; using Task = ParallelTasks.Task; @@ -50,6 +51,10 @@ namespace Torch.Mod { var m = _messagePool.Get(); m.CompressedData = bytes; +#if TORCH + m.SenderId = MyEventContext.Current.Sender.Value; +#endif + _processing.Add(m); } @@ -59,10 +64,19 @@ namespace Torch.Mod { try { - var m = _processing.Take(); + MessageBase m; + try + { + m = _processing.Take(); + } + catch + { + continue; + } + MyLog.Default.WriteLineAndConsole($"Processing message: {m.GetType().Name}"); - if (m is IncomingMessage) + if (m is IncomingMessage) //process incoming messages { MessageBase i; try @@ -78,50 +92,55 @@ namespace Torch.Mod continue; } + if (TorchModCore.Debug) + MyAPIGateway.Utilities.ShowMessage("Torch", $"Received message of type {i.GetType().Name}"); + if (MyAPIGateway.Multiplayer.IsServer) i.ProcessServer(); else i.ProcessClient(); } - else + else //process outgoing messages { + if (TorchModCore.Debug) + MyAPIGateway.Utilities.ShowMessage("Torch", $"Sending message of type {m.GetType().Name}"); + var b = MyAPIGateway.Utilities.SerializeToBinary(m); m.CompressedData = MyCompression.Compress(b); - MyAPIGateway.Utilities.InvokeOnGameThread(() => + switch (m.TargetType) { + case MessageTarget.Single: + MyAPIGateway.Multiplayer.SendMessageTo(NET_ID, m.CompressedData, m.Target); + break; + case MessageTarget.Server: + MyAPIGateway.Multiplayer.SendMessageToServer(NET_ID, m.CompressedData); + break; + case MessageTarget.AllClients: + MyAPIGateway.Players.GetPlayers(_playerCache); + foreach (var p in _playerCache) + { + if (p.SteamUserId == MyAPIGateway.Multiplayer.MyId) + continue; + MyAPIGateway.Multiplayer.SendMessageTo(NET_ID, m.CompressedData, p.SteamUserId); + } - switch (m.TargetType) - { - case MessageTarget.Single: - MyAPIGateway.Multiplayer.SendMessageTo(NET_ID, m.CompressedData, m.Target); - break; - case MessageTarget.Server: - MyAPIGateway.Multiplayer.SendMessageToServer(NET_ID, m.CompressedData); - break; - case MessageTarget.AllClients: - MyAPIGateway.Players.GetPlayers(_playerCache); - foreach (var p in _playerCache) - { - if (p.SteamUserId == MyAPIGateway.Multiplayer.MyId) - continue; - MyAPIGateway.Multiplayer.SendMessageTo(NET_ID, m.CompressedData, p.SteamUserId); - } - break; - case MessageTarget.AllExcept: - MyAPIGateway.Players.GetPlayers(_playerCache); - foreach (var p in _playerCache) - { - if (p.SteamUserId == MyAPIGateway.Multiplayer.MyId || m.Ignore.Contains(p.SteamUserId)) - continue; - MyAPIGateway.Multiplayer.SendMessageTo(NET_ID, m.CompressedData, p.SteamUserId); - } - break; - default: - throw new Exception(); - } - _playerCache.Clear(); - }); + break; + case MessageTarget.AllExcept: + MyAPIGateway.Players.GetPlayers(_playerCache); + foreach (var p in _playerCache) + { + if (p.SteamUserId == MyAPIGateway.Multiplayer.MyId || m.Ignore.Contains(p.SteamUserId)) + continue; + MyAPIGateway.Multiplayer.SendMessageTo(NET_ID, m.CompressedData, p.SteamUserId); + } + + break; + default: + throw new Exception(); + } + + _playerCache.Clear(); } } catch (Exception ex) @@ -130,7 +149,7 @@ namespace Torch.Mod } } - MyLog.Default.WriteLineAndConsole("TORCH MOD: COMMUNICATION THREAD: EXIT SIGNAL RECEIVED!"); + MyLog.Default.WriteLineAndConsole("TORCH MOD: INFO: Communication thread shut down successfully! THIS IS NOT AN ERROR"); //exit signal received. Clean everything and GTFO _processing?.Dispose(); _processing = null; diff --git a/Torch.Mod/Torch.Mod.projitems b/Torch.Mod/Torch.Mod.projitems index 632d99a..8ab2e95 100644 --- a/Torch.Mod/Torch.Mod.projitems +++ b/Torch.Mod/Torch.Mod.projitems @@ -10,6 +10,7 @@ + diff --git a/Torch.Mod/TorchModCore.cs b/Torch.Mod/TorchModCore.cs index 83f3a33..9ccddf6 100644 --- a/Torch.Mod/TorchModCore.cs +++ b/Torch.Mod/TorchModCore.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Sandbox.ModAPI; using VRage.Game.Components; namespace Torch.Mod @@ -12,6 +13,7 @@ namespace Torch.Mod { public const ulong MOD_ID = 1406994352; private static bool _init; + public static bool Debug; public override void UpdateAfterSimulation() { @@ -20,6 +22,17 @@ namespace Torch.Mod _init = true; ModCommunication.Register(); + MyAPIGateway.Utilities.MessageEntered += Utilities_MessageEntered; + } + + private void Utilities_MessageEntered(string messageText, ref bool sendToOthers) + { + if (messageText == "@!debug") + { + Debug = !Debug; + MyAPIGateway.Utilities.ShowMessage("Torch", $"Debug: {Debug}"); + sendToOthers = false; + } } protected override void UnloadData() diff --git a/Torch.Server/TorchConfig.cs b/Torch.Server/TorchConfig.cs index 7c86e24..7b3717b 100644 --- a/Torch.Server/TorchConfig.cs +++ b/Torch.Server/TorchConfig.cs @@ -94,6 +94,9 @@ namespace Torch.Server [Arg("localplugins", "Loads all pluhins from disk, ignores the plugins defined in config.")] public bool LocalPlugins { get; set; } + [Arg("disconnect", "When server restarts, all clients are rejected to main menu to prevent auto rejoin")] + public bool DisconnectOnRestart { get; set; } + public string ChatName { get; set; } = "Server"; public string ChatColor { get; set; } = "Red"; diff --git a/Torch.Server/TorchServer.cs b/Torch.Server/TorchServer.cs index 7835f39..d017354 100644 --- a/Torch.Server/TorchServer.cs +++ b/Torch.Server/TorchServer.cs @@ -19,6 +19,7 @@ using Torch.API.Managers; using Torch.API.Session; using Torch.Commands; using Torch.Mod; +using Torch.Mod.Messages; using Torch.Server.Commands; using Torch.Server.Managers; using Torch.Utils; @@ -152,6 +153,11 @@ namespace Torch.Server /// public override void Restart() { + if (Config.DisconnectOnRestart) + { + ModCommunication.SendMessageToClients(new JoinServerMessage("0.0.0.0:25555")); + } + if (IsRunning) Save().ContinueWith(DoRestart, this, TaskContinuationOptions.RunContinuationsAsynchronously); else