diff --git a/Torch.Mod/Messages/IncomingMessage.cs b/Torch.Mod/Messages/IncomingMessage.cs
deleted file mode 100644
index 114a89d..0000000
--- a/Torch.Mod/Messages/IncomingMessage.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace Torch.Mod.Messages
-{
- ///
- /// shim to store incoming message data
- ///
- internal class IncomingMessage : MessageBase
- {
- public IncomingMessage()
- {
- }
-
- public override void ProcessClient()
- {
- throw new Exception();
- }
-
- public override void ProcessServer()
- {
- throw new Exception();
- }
- }
-}
diff --git a/Torch.Mod/Messages/JoinServerMessage.cs b/Torch.Mod/Messages/JoinServerMessage.cs
index ffc8ab0..c13cc35 100644
--- a/Torch.Mod/Messages/JoinServerMessage.cs
+++ b/Torch.Mod/Messages/JoinServerMessage.cs
@@ -32,11 +32,6 @@ namespace Torch.Mod.Messages
public override void ProcessClient()
{
- if (TorchModCore.Debug)
- {
- MyAPIGateway.Utilities.ShowMessage("Torch", $"Joining server {Address} with delay {Delay}");
- }
-
if (Delay <= 0)
{
MyAPIGateway.Multiplayer.JoinServer(Address);
diff --git a/Torch.Mod/Messages/MessageBase.cs b/Torch.Mod/Messages/MessageBase.cs
index 55bc140..212b113 100644
--- a/Torch.Mod/Messages/MessageBase.cs
+++ b/Torch.Mod/Messages/MessageBase.cs
@@ -1,9 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using ProtoBuf;
+using ProtoBuf;
namespace Torch.Mod.Messages
{
@@ -17,36 +12,9 @@ namespace Torch.Mod.Messages
[ProtoContract]
public abstract class MessageBase
{
- [ProtoMember(101)]
public ulong SenderId;
public abstract void ProcessClient();
public abstract void ProcessServer();
-
- //members below not serialized, they're just metadata about the intended target(s) of this message
- internal MessageTarget TargetType;
- internal ulong Target;
- internal ulong[] Ignore;
- internal byte[] CompressedData;
- }
-
- public enum MessageTarget
- {
- ///
- /// Send to Target
- ///
- Single,
- ///
- /// Send to Server
- ///
- Server,
- ///
- /// Send to all Clients (only valid from server)
- ///
- AllClients,
- ///
- /// Send to all except those steam ID listed in Ignore
- ///
- AllExcept,
}
}
diff --git a/Torch.Mod/ModCommunication.cs b/Torch.Mod/ModCommunication.cs
index 76be249..deb14db 100644
--- a/Torch.Mod/ModCommunication.cs
+++ b/Torch.Mod/ModCommunication.cs
@@ -1,161 +1,50 @@
using System;
-using System.Collections.Concurrent;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
using Sandbox.ModAPI;
using Torch.Mod.Messages;
-using VRage;
-using VRage.Collections;
+using VRage.Game.Components;
using VRage.Game.ModAPI;
-using VRage.Network;
-using VRage.Utils;
-using Task = ParallelTasks.Task;
+#if TORCH
+using Torch.Utils;
+using VRage.Library.Collections;
+using System.Reflection;
+#endif
namespace Torch.Mod
{
- public static class ModCommunication
+ [MySessionComponentDescriptor(MyUpdateOrder.AfterSimulation)]
+ public class ModCommunication : MySessionComponentBase
{
- public const ushort NET_ID = 4352;
- private static bool _closing = false;
- private static BlockingCollection _processing;
- private static MyConcurrentPool _messagePool;
- private static List _playerCache;
+ public const ulong MOD_ID = 2915950488;
+ private const ushort CHANNEL = 7654;
- public static void Register()
+ public override void BeforeStart()
{
- MyLog.Default.WriteLineAndConsole("TORCH MOD: Registering mod communication.");
- _processing = new BlockingCollection(new ConcurrentQueue());
- _playerCache = new List();
- _messagePool = new MyConcurrentPool(8);
-
- MyAPIGateway.Multiplayer.RegisterMessageHandler(NET_ID, MessageHandler);
- //background thread to handle de/compression and processing
- _closing = false;
- MyAPIGateway.Parallel.StartBackground(DoProcessing);
- MyLog.Default.WriteLineAndConsole("TORCH MOD: Mod communication registered successfully.");
+ base.BeforeStart();
+ MyAPIGateway.Multiplayer.RegisterSecureMessageHandler(CHANNEL, MessageHandler);
}
- public static void Unregister()
+ private void MessageHandler(ushort channel, byte[] data, ulong sender, bool fromServer)
{
- MyLog.Default.WriteLineAndConsole("TORCH MOD: Unregistering mod communication.");
- MyAPIGateway.Multiplayer?.UnregisterMessageHandler(NET_ID, MessageHandler);
- _processing?.CompleteAdding();
- _closing = true;
- //_task.Wait();
+ if (!fromServer)
+ return;
+
+ var message = MyAPIGateway.Utilities.SerializeFromBinary(data);
+ message.SenderId = sender;
+
+ if (MyAPIGateway.Multiplayer.IsServer) message.ProcessServer();
+ else message.ProcessClient();
}
- private static void MessageHandler(byte[] bytes)
- {
- var m = _messagePool.Get();
- m.CompressedData = bytes;
#if TORCH
- m.SenderId = MyEventContext.Current.Sender.Value;
-#endif
+ [ReflectedMethodInfo(typeof(MyAPIUtilities), "VRage.Game.ModAPI.IMyUtilities.SerializeToBinary")]
+ private static MethodInfo _serializeMethod = null!;
- _processing.Add(m);
- }
+ private static readonly CacheList Players = new();
- public static void DoProcessing()
+ private static byte[] Serialize(MessageBase message)
{
- while (!_closing)
- {
- try
- {
- MessageBase m;
- try
- {
- m = _processing.Take();
- }
- catch
- {
- continue;
- }
-
- MyLog.Default.WriteLineAndConsole($"Processing message: {m.GetType().Name}");
-
- if (m is IncomingMessage) //process incoming messages
- {
- MessageBase i;
- try
- {
- var o = MyCompression.Decompress(m.CompressedData);
- m.CompressedData = null;
- _messagePool.Return((IncomingMessage)m);
- i = MyAPIGateway.Utilities.SerializeFromBinary(o);
- }
- catch (Exception ex)
- {
- MyLog.Default.WriteLineAndConsole($"TORCH MOD: Failed to deserialize message! {ex}");
- 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 //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);
-
- 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();
- }
- }
- catch (Exception ex)
- {
- MyLog.Default.WriteLineAndConsole($"TORCH MOD: Exception occurred in communication thread! {ex}");
- }
- }
-
- 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;
- _messagePool?.Clean();
- _messagePool = null;
- _playerCache = null;
+ return (byte[])_serializeMethod.MakeGenericMethod(message.GetType())
+ .Invoke(MyAPIGateway.Utilities, new object[] { message });
}
public static void SendMessageTo(MessageBase message, ulong target)
@@ -163,12 +52,7 @@ namespace Torch.Mod
if (!MyAPIGateway.Multiplayer.IsServer)
throw new Exception("Only server can send targeted messages");
- if (_closing)
- return;
-
- message.Target = target;
- message.TargetType = MessageTarget.Single;
- _processing.Add(message);
+ MyAPIGateway.Multiplayer.SendMessageTo(CHANNEL, Serialize(message), target);
}
public static void SendMessageToClients(MessageBase message)
@@ -176,11 +60,7 @@ namespace Torch.Mod
if (!MyAPIGateway.Multiplayer.IsServer)
throw new Exception("Only server can send targeted messages");
- if (_closing)
- return;
-
- message.TargetType = MessageTarget.AllClients;
- _processing.Add(message);
+ MyAPIGateway.Multiplayer.SendMessageToOthers(CHANNEL, Serialize(message));
}
public static void SendMessageExcept(MessageBase message, params ulong[] ignoredUsers)
@@ -188,21 +68,20 @@ namespace Torch.Mod
if (!MyAPIGateway.Multiplayer.IsServer)
throw new Exception("Only server can send targeted messages");
- if (_closing)
- return;
+ using var players = Players;
+ MyAPIGateway.Multiplayer.Players.GetPlayers(players, player => !ignoredUsers.Contains(player.SteamUserId));
- message.TargetType = MessageTarget.AllExcept;
- message.Ignore = ignoredUsers;
- _processing.Add(message);
+ var data = Serialize(message);
+ foreach (var player in players)
+ {
+ MyAPIGateway.Multiplayer.SendMessageTo(CHANNEL, data, player.SteamUserId);
+ }
}
public static void SendMessageToServer(MessageBase message)
{
- if (_closing)
- return;
-
- message.TargetType = MessageTarget.Server;
- _processing.Add(message);
+ throw new NotSupportedException();
}
+#endif
}
}
diff --git a/Torch.Mod/Torch.Mod.projitems b/Torch.Mod/Torch.Mod.projitems
index 8ab2e95..1142029 100644
--- a/Torch.Mod/Torch.Mod.projitems
+++ b/Torch.Mod/Torch.Mod.projitems
@@ -9,13 +9,11 @@
Torch.Mod
-
-
\ No newline at end of file
diff --git a/Torch.Mod/TorchModCore.cs b/Torch.Mod/TorchModCore.cs
deleted file mode 100644
index 7767b2e..0000000
--- a/Torch.Mod/TorchModCore.cs
+++ /dev/null
@@ -1,51 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Sandbox.ModAPI;
-using VRage.Game.Components;
-
-namespace Torch.Mod
-{
- [MySessionComponentDescriptor(MyUpdateOrder.AfterSimulation)]
- public class TorchModCore : MySessionComponentBase
- {
- public const ulong MOD_ID = 2722000298;
- private static bool _init;
- public static bool Debug;
-
- public override void UpdateAfterSimulation()
- {
- if (_init)
- return;
-
- _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()
- {
- try
- {
- MyAPIGateway.Utilities.MessageEntered -= Utilities_MessageEntered;
- ModCommunication.Unregister();
- }
- catch
- {
- //session unloading, don't care
- }
- }
- }
-}
diff --git a/Torch.Server/Managers/InstanceManager.cs b/Torch.Server/Managers/InstanceManager.cs
index 0849374..25a8196 100644
--- a/Torch.Server/Managers/InstanceManager.cs
+++ b/Torch.Server/Managers/InstanceManager.cs
@@ -146,7 +146,7 @@ namespace Torch.Server.Managers
{
DedicatedConfig.Mods.Clear();
//remove the Torch mod to avoid running multiple copies of it
- DedicatedConfig.SelectedWorld.WorldConfiguration.Mods.RemoveAll(m => m.PublishedFileId == TorchModCore.MOD_ID);
+ DedicatedConfig.SelectedWorld.WorldConfiguration.Mods.RemoveAll(m => m.PublishedFileId == ModCommunication.MOD_ID);
foreach (var m in DedicatedConfig.SelectedWorld.WorldConfiguration.Mods)
DedicatedConfig.Mods.Add(new ModItemInfo(m));
Task.Run(() => DedicatedConfig.UpdateAllModInfosAsync());
@@ -161,7 +161,7 @@ namespace Torch.Server.Managers
{
DedicatedConfig.Mods.Clear();
//remove the Torch mod to avoid running multiple copies of it
- DedicatedConfig.SelectedWorld.WorldConfiguration.Mods.RemoveAll(m => m.PublishedFileId == TorchModCore.MOD_ID);
+ DedicatedConfig.SelectedWorld.WorldConfiguration.Mods.RemoveAll(m => m.PublishedFileId == ModCommunication.MOD_ID);
foreach (var m in DedicatedConfig.SelectedWorld.WorldConfiguration.Mods)
DedicatedConfig.Mods.Add(new ModItemInfo(m));
Task.Run(() => DedicatedConfig.UpdateAllModInfosAsync());
diff --git a/Torch.Server/TorchServer.cs b/Torch.Server/TorchServer.cs
index 6342c56..df708eb 100644
--- a/Torch.Server/TorchServer.cs
+++ b/Torch.Server/TorchServer.cs
@@ -242,14 +242,12 @@ namespace Torch.Server
case TorchSessionState.Unloading:
_watchdog?.Dispose();
_watchdog = null;
- ModCommunication.Unregister();
break;
case TorchSessionState.Loaded:
_multiplayerManagerDedicated = CurrentSession.Managers.GetManager();
_multiplayerManagerDedicated.PlayerJoined += MultiplayerManagerDedicatedOnPlayerJoined;
_multiplayerManagerDedicated.PlayerLeft += MultiplayerManagerDedicatedOnPlayerLeft;
CurrentSession.Managers.GetManager().RegisterCommandModule(typeof(WhitelistCommands));
- ModCommunication.Register();
break;
case TorchSessionState.Loading:
case TorchSessionState.Unloaded:
diff --git a/Torch/Session/TorchSessionManager.cs b/Torch/Session/TorchSessionManager.cs
index 3cfb711..09b4b96 100644
--- a/Torch/Session/TorchSessionManager.cs
+++ b/Torch/Session/TorchSessionManager.cs
@@ -50,7 +50,7 @@ namespace Torch.Session
{
_overrideMods = new Dictionary();
if (Torch.Config.UgcServiceType == UGCServiceType.Steam)
- _overrideMods.Add(TorchModCore.MOD_ID, ModItemUtils.Create(TorchModCore.MOD_ID));
+ _overrideMods.Add(ModCommunication.MOD_ID, ModItemUtils.Create(ModCommunication.MOD_ID));
}
///
diff --git a/Torch/Torch.csproj b/Torch/Torch.csproj
index 6c2db3e..644196c 100644
--- a/Torch/Torch.csproj
+++ b/Torch/Torch.csproj
@@ -13,6 +13,7 @@
AnyCPU
true
true
+ TRACE;TORCH