diff --git a/src/MultiplayerMod.Test/Environment/Network/CommandTools.cs b/src/MultiplayerMod.Test/Environment/Network/CommandTools.cs
index 73688f72..5590bb51 100644
--- a/src/MultiplayerMod.Test/Environment/Network/CommandTools.cs
+++ b/src/MultiplayerMod.Test/Environment/Network/CommandTools.cs
@@ -1,7 +1,7 @@
-using System.IO;
+using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using MultiplayerMod.Multiplayer.Commands;
-using MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+using MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
namespace MultiplayerMod.Test.Environment.Network;
diff --git a/src/MultiplayerMod.Test/Environment/Network/TestMultiplayerClient.cs b/src/MultiplayerMod.Test/Environment/Network/TestMultiplayerClient.cs
index 6859973a..29a4007c 100644
--- a/src/MultiplayerMod.Test/Environment/Network/TestMultiplayerClient.cs
+++ b/src/MultiplayerMod.Test/Environment/Network/TestMultiplayerClient.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using MultiplayerMod.ModRuntime;
using MultiplayerMod.Multiplayer.Commands;
@@ -83,4 +83,8 @@ public void Receive(IMultiplayerCommand command) {
}
}
+ public void Tick()
+ {
+ }
+
}
diff --git a/src/MultiplayerMod.Test/Environment/Network/TestMultiplayerServer.cs b/src/MultiplayerMod.Test/Environment/Network/TestMultiplayerServer.cs
index b19512a4..5631dd8f 100644
--- a/src/MultiplayerMod.Test/Environment/Network/TestMultiplayerServer.cs
+++ b/src/MultiplayerMod.Test/Environment/Network/TestMultiplayerServer.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using MultiplayerMod.Core.Extensions;
@@ -113,4 +113,8 @@ public void Receive(TestMultiplayerClient source, IMultiplayerCommand command, M
}
}
+ public void Tick()
+ {
+ }
+
}
diff --git a/src/MultiplayerMod.Test/Game/Chores/AbstractChoreTest.cs b/src/MultiplayerMod.Test/Game/Chores/AbstractChoreTest.cs
index d41e9026..c3fc9721 100644
--- a/src/MultiplayerMod.Test/Game/Chores/AbstractChoreTest.cs
+++ b/src/MultiplayerMod.Test/Game/Chores/AbstractChoreTest.cs
@@ -8,7 +8,7 @@
using MultiplayerMod.Multiplayer.Commands;
using MultiplayerMod.Multiplayer.Objects.Extensions;
using MultiplayerMod.Network;
-using MultiplayerMod.Platform.Steam.Network.Messaging;
+using MultiplayerMod.Platform.Common.Network.Messaging;
using MultiplayerMod.Test.Environment.Patches;
using MultiplayerMod.Test.GameRuntime;
using MultiplayerMod.Test.GameRuntime.Patches;
diff --git a/src/MultiplayerMod.Test/Multiplayer/Chores/ChoreTest.cs b/src/MultiplayerMod.Test/Multiplayer/Chores/ChoreTest.cs
index 980370f0..1fe3bc54 100644
--- a/src/MultiplayerMod.Test/Multiplayer/Chores/ChoreTest.cs
+++ b/src/MultiplayerMod.Test/Multiplayer/Chores/ChoreTest.cs
@@ -17,7 +17,7 @@
using MultiplayerMod.Multiplayer.StateMachines;
using MultiplayerMod.Multiplayer.StateMachines.Configuration;
using MultiplayerMod.Network;
-using MultiplayerMod.Platform.Steam.Network.Messaging;
+using MultiplayerMod.Platform.Common.Network.Messaging;
using MultiplayerMod.Test.Environment;
using MultiplayerMod.Test.Environment.Network;
using MultiplayerMod.Test.Environment.Patches;
diff --git a/src/MultiplayerMod.Test/MultiplayerMod.Test.csproj b/src/MultiplayerMod.Test/MultiplayerMod.Test.csproj
index 8e5b3f33..47744711 100644
--- a/src/MultiplayerMod.Test/MultiplayerMod.Test.csproj
+++ b/src/MultiplayerMod.Test/MultiplayerMod.Test.csproj
@@ -12,31 +12,32 @@
true
-
+
-
-
-
+
+
+
+
-
-
-
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/MultiplayerMod.Test/Network/CommandTests.cs b/src/MultiplayerMod.Test/Network/CommandTests.cs
index 4bf168bc..2751b83f 100644
--- a/src/MultiplayerMod.Test/Network/CommandTests.cs
+++ b/src/MultiplayerMod.Test/Network/CommandTests.cs
@@ -1,10 +1,10 @@
-using System;
+using System;
using System.Linq;
using System.Runtime.InteropServices;
using MultiplayerMod.Multiplayer.Commands;
using MultiplayerMod.Network;
-using MultiplayerMod.Platform.Steam.Network;
-using MultiplayerMod.Platform.Steam.Network.Messaging;
+using MultiplayerMod.Platform.Common;
+using MultiplayerMod.Platform.Common.Network.Messaging;
using NUnit.Framework;
namespace MultiplayerMod.Test.Network;
diff --git a/src/MultiplayerMod/Core/Patch/PatchTargetResolver.cs b/src/MultiplayerMod/Core/Patch/PatchTargetResolver.cs
index 262c8c8a..479b9096 100644
--- a/src/MultiplayerMod/Core/Patch/PatchTargetResolver.cs
+++ b/src/MultiplayerMod/Core/Patch/PatchTargetResolver.cs
@@ -1,10 +1,10 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using MultiplayerMod.Core.Logging;
-using MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+using MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
using UnityEngine;
namespace MultiplayerMod.Core.Patch;
diff --git a/src/MultiplayerMod/Directory.Build.targets b/src/MultiplayerMod/Directory.Build.targets
index 62b6f631..1466c3ce 100644
--- a/src/MultiplayerMod/Directory.Build.targets
+++ b/src/MultiplayerMod/Directory.Build.targets
@@ -43,6 +43,10 @@
+
+
+
+
@@ -62,10 +66,11 @@
+
diff --git a/src/MultiplayerMod/Multiplayer/Commands/ArgumentUtils.cs b/src/MultiplayerMod/Multiplayer/Commands/ArgumentUtils.cs
index 34702606..c2c2dd75 100644
--- a/src/MultiplayerMod/Multiplayer/Commands/ArgumentUtils.cs
+++ b/src/MultiplayerMod/Multiplayer/Commands/ArgumentUtils.cs
@@ -4,7 +4,7 @@
using System.Reflection;
using MultiplayerMod.Multiplayer.Objects.Extensions;
using MultiplayerMod.Multiplayer.Objects.Reference;
-using MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+using MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
using UnityEngine;
namespace MultiplayerMod.Multiplayer.Commands;
diff --git a/src/MultiplayerMod/MultiplayerMod.csproj b/src/MultiplayerMod/MultiplayerMod.csproj
index 62a67370..63d3e177 100644
--- a/src/MultiplayerMod/MultiplayerMod.csproj
+++ b/src/MultiplayerMod/MultiplayerMod.csproj
@@ -65,5 +65,6 @@
+
diff --git a/src/MultiplayerMod/Network/IMultiplayerClient.cs b/src/MultiplayerMod/Network/IMultiplayerClient.cs
index 96a77542..230c63cf 100644
--- a/src/MultiplayerMod/Network/IMultiplayerClient.cs
+++ b/src/MultiplayerMod/Network/IMultiplayerClient.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using MultiplayerMod.Multiplayer.Commands;
namespace MultiplayerMod.Network;
@@ -11,6 +11,7 @@ public interface IMultiplayerClient {
void Disconnect();
void Send(IMultiplayerCommand command, MultiplayerCommandOptions options = MultiplayerCommandOptions.None);
+ void Tick();
event Action StateChanged;
event Action CommandReceived;
diff --git a/src/MultiplayerMod/Network/IMultiplayerServer.cs b/src/MultiplayerMod/Network/IMultiplayerServer.cs
index d06cf2e2..3238922c 100644
--- a/src/MultiplayerMod/Network/IMultiplayerServer.cs
+++ b/src/MultiplayerMod/Network/IMultiplayerServer.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using MultiplayerMod.Multiplayer.Commands;
@@ -14,6 +14,7 @@ public interface IMultiplayerServer {
void Send(IMultiplayerClientId clientId, IMultiplayerCommand command);
void Send(IMultiplayerCommand command, MultiplayerCommandOptions options = MultiplayerCommandOptions.None);
+ void Tick();
event Action StateChanged;
event Action ClientConnected;
diff --git a/src/MultiplayerMod/Platform/Common/Configuration.cs b/src/MultiplayerMod/Platform/Common/Configuration.cs
new file mode 100644
index 00000000..f47dcaba
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Common/Configuration.cs
@@ -0,0 +1,18 @@
+using MultiplayerMod.Platform.Common.Network.Messaging;
+using MultiplayerMod.Platform.Lan.Network;
+using System;
+
+namespace MultiplayerMod.Platform.Common;
+
+public static class Configuration
+{
+ public const int MaxMessageSize = 524288; // 512 KiB
+ public static readonly int MaxFragmentDataSize = GetFragmentDataSize();
+
+ private static int GetFragmentDataSize() {
+ using var serialized = NetworkSerializer.Serialize(new NetworkMessageFragment(0, Array.Empty()));
+ return MaxMessageSize - (int) serialized.Size;
+ }
+
+ public static bool useSteam { get { return !LanConfiguration.instance.isConfigured; } }
+}
diff --git a/src/MultiplayerMod/Platform/Common/Network/Components/ClientComponent.cs b/src/MultiplayerMod/Platform/Common/Network/Components/ClientComponent.cs
new file mode 100644
index 00000000..7a8757ac
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Common/Network/Components/ClientComponent.cs
@@ -0,0 +1,17 @@
+using MultiplayerMod.Core.Dependency;
+using MultiplayerMod.Core.Unity;
+using MultiplayerMod.Platform.Common.Network;
+
+// ReSharper disable FieldCanBeMadeReadOnly.Local
+
+namespace MultiplayerMod.Platform.Common.Network.Components;
+
+public class ClientComponent : MultiplayerMonoBehaviour
+{
+
+ [InjectDependency]
+ private SharedClient client = null!;
+
+ private void Update() => client.Tick();
+
+}
diff --git a/src/MultiplayerMod/Platform/Common/Network/Components/ServerComponent.cs b/src/MultiplayerMod/Platform/Common/Network/Components/ServerComponent.cs
new file mode 100644
index 00000000..8645e8a0
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Common/Network/Components/ServerComponent.cs
@@ -0,0 +1,17 @@
+using MultiplayerMod.Core.Dependency;
+using MultiplayerMod.Core.Unity;
+using MultiplayerMod.Platform.Common.Network;
+
+// ReSharper disable FieldCanBeMadeReadOnly.Local
+
+namespace MultiplayerMod.Platform.Common.Network.Components;
+
+public class ServerComponent : MultiplayerMonoBehaviour
+{
+
+ [InjectDependency]
+ private SharedServer server = null!;
+
+ private void Update() => server.Tick();
+
+}
diff --git a/src/MultiplayerMod/Platform/Common/Network/Messaging/INetworkMessage.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/INetworkMessage.cs
new file mode 100644
index 00000000..853cf31d
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/INetworkMessage.cs
@@ -0,0 +1,3 @@
+namespace MultiplayerMod.Platform.Common.Network.Messaging;
+
+public interface INetworkMessage { }
diff --git a/src/MultiplayerMod/Platform/Common/Network/Messaging/INetworkMessageHandle.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/INetworkMessageHandle.cs
new file mode 100644
index 00000000..17506d02
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/INetworkMessageHandle.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace MultiplayerMod.Platform.Common.Network.Messaging;
+
+public interface INetworkMessageHandle : IDisposable
+{
+ public IntPtr Pointer { get; }
+ public uint Size { get; }
+}
diff --git a/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessage.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessage.cs
new file mode 100644
index 00000000..a0e0a810
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessage.cs
@@ -0,0 +1,39 @@
+using System;
+using System.IO;
+using System.Runtime.Serialization.Formatters.Binary;
+using MultiplayerMod.Multiplayer.Commands;
+using MultiplayerMod.Network;
+using MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
+
+namespace MultiplayerMod.Platform.Common.Network.Messaging;
+
+[Serializable]
+public class NetworkMessage : INetworkMessage
+{
+ private static BinaryFormatter formatter = new BinaryFormatter() { SurrogateSelector = SerializationSurrogates.Selector };
+
+ public IMultiplayerCommand Command { get; }
+ public MultiplayerCommandOptions Options { get; }
+
+ public NetworkMessage(IMultiplayerCommand command, MultiplayerCommandOptions options)
+ {
+ Command = command;
+ Options = options;
+ }
+
+ public byte[] toBytes() {
+ using (var memoryStream = new MemoryStream()) {
+ formatter.Serialize(memoryStream, this);
+ byte[] data = new byte[memoryStream.Length];
+ Array.Copy(memoryStream.GetBuffer(), 0, data, 0, data.Length);
+ return data;
+ }
+ }
+
+ public static NetworkMessage from(byte[] rawData) {
+ using (var memoryStream = new MemoryStream(rawData)) {
+ var message = (NetworkMessage) formatter.Deserialize(memoryStream);
+ return message;
+ }
+ }
+}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessageFactory.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessageFactory.cs
similarity index 75%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessageFactory.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessageFactory.cs
index c7711dc7..e6933357 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessageFactory.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessageFactory.cs
@@ -1,16 +1,19 @@
-using System;
+using System;
using System.Collections.Generic;
using MultiplayerMod.Multiplayer.Commands;
using MultiplayerMod.Network;
-using static MultiplayerMod.Platform.Steam.Network.Configuration;
+using static MultiplayerMod.Platform.Common.Configuration;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging;
+namespace MultiplayerMod.Platform.Common.Network.Messaging;
-public class NetworkMessageFactory {
+public class NetworkMessageFactory
+{
- public IEnumerable Create(IMultiplayerCommand command, MultiplayerCommandOptions options) {
+ public IEnumerable Create(IMultiplayerCommand command, MultiplayerCommandOptions options)
+ {
using var message = NetworkSerializer.Serialize(new NetworkMessage(command, options));
- if (message.Size <= MaxMessageSize) {
+ if (message.Size <= MaxMessageSize)
+ {
yield return message;
yield break;
}
@@ -20,7 +23,8 @@ public IEnumerable Create(IMultiplayerCommand command, Mu
var serializedHeader = NetworkSerializer.Serialize(header);
yield return serializedHeader;
- for (var i = 0; i < fragmentsCount; i++) {
+ for (var i = 0; i < fragmentsCount; i++)
+ {
var offset = i * MaxFragmentDataSize;
var bufferSize = Math.Min(Math.Max((int) message.Size - offset, 0), MaxFragmentDataSize);
var data = new byte[bufferSize];
diff --git a/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessageFragment.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessageFragment.cs
new file mode 100644
index 00000000..455ca138
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessageFragment.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace MultiplayerMod.Platform.Common.Network.Messaging;
+
+[Serializable]
+public class NetworkMessageFragment : INetworkMessage
+{
+
+ public int MessageId { get; }
+ public byte[] Data { get; }
+
+ public NetworkMessageFragment(int messageId, byte[] data)
+ {
+ MessageId = messageId;
+ Data = data;
+ }
+
+}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessageFragmentsHeader.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessageFragmentsHeader.cs
similarity index 60%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessageFragmentsHeader.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessageFragmentsHeader.cs
index ebc7df89..e61f3298 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessageFragmentsHeader.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessageFragmentsHeader.cs
@@ -1,17 +1,19 @@
using System;
using System.Threading;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging;
+namespace MultiplayerMod.Platform.Common.Network.Messaging;
[Serializable]
-public class NetworkMessageFragmentsHeader : INetworkMessage {
+public class NetworkMessageFragmentsHeader : INetworkMessage
+{
public int MessageId { get; }
public int FragmentsCount { get; }
private static int uniqueMessageId;
- public NetworkMessageFragmentsHeader(int fragmentsCount) {
+ public NetworkMessageFragmentsHeader(int fragmentsCount)
+ {
MessageId = Interlocked.Increment(ref uniqueMessageId);
FragmentsCount = fragmentsCount;
}
diff --git a/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessageHandle.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessageHandle.cs
new file mode 100644
index 00000000..999f1e59
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessageHandle.cs
@@ -0,0 +1,22 @@
+using System;
+
+namespace MultiplayerMod.Platform.Common.Network.Messaging;
+
+public class NetworkMessageHandle : INetworkMessageHandle
+{
+
+ public IntPtr Pointer { get; }
+ public uint Size { get; }
+
+ public NetworkMessageHandle(IntPtr pointer, uint size)
+ {
+ Pointer = pointer;
+ Size = size;
+ }
+
+ public void Dispose()
+ {
+ // No disposal required
+ }
+
+}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessageProcessor.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessageProcessor.cs
similarity index 82%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessageProcessor.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessageProcessor.cs
index 5e67b286..3c0d1124 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessageProcessor.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkMessageProcessor.cs
@@ -1,33 +1,38 @@
-using System;
+using System;
using System.Collections.Concurrent;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using MultiplayerMod.Core.Logging;
-using static MultiplayerMod.Platform.Steam.Network.Configuration;
+using static MultiplayerMod.Platform.Common.Configuration;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging;
+namespace MultiplayerMod.Platform.Common.Network.Messaging;
-public class NetworkMessageProcessor {
+public class NetworkMessageProcessor
+{
private readonly ConcurrentDictionary> fragments = new();
private readonly Core.Logging.Logger log = LoggerFactory.GetLogger();
public NetworkMessage? Process(uint clientId, INetworkMessageHandle handle) =>
- NetworkSerializer.Deserialize(handle) switch {
+ NetworkSerializer.Deserialize(handle) switch
+ {
NetworkMessage message => message,
NetworkMessageFragmentsHeader header => ProcessFragmentsHeader(clientId, header),
NetworkMessageFragment fragment => ProcessMessageFragment(clientId, fragment),
_ => null
};
- private NetworkMessage? ProcessFragmentsHeader(uint clientId, NetworkMessageFragmentsHeader header) {
+ private NetworkMessage? ProcessFragmentsHeader(uint clientId, NetworkMessageFragmentsHeader header)
+ {
fragments.TryGetValue(clientId, out var index);
- if (index == null) {
+ if (index == null)
+ {
index = new ConcurrentDictionary();
fragments[clientId] = index;
}
var buffer = new FragmentsBuffer(header.FragmentsCount);
- buffer.Timeout += () => {
+ buffer.Timeout += () =>
+ {
log.Warning($"Fragments buffer timed out (message id: {header.MessageId})");
index.TryRemove(header.MessageId, out _);
};
@@ -35,16 +40,19 @@ public class NetworkMessageProcessor {
return null;
}
- private NetworkMessage? ProcessMessageFragment(uint clientId, NetworkMessageFragment fragment) {
+ private NetworkMessage? ProcessMessageFragment(uint clientId, NetworkMessageFragment fragment)
+ {
string ExceptionMessage() =>
$"Message (id: {fragment.MessageId}) fragment received, but no fragments buffer found";
- if (!fragments.TryGetValue(clientId, out var index)) {
+ if (!fragments.TryGetValue(clientId, out var index))
+ {
log.Warning(ExceptionMessage());
return null;
}
- if (!index.TryGetValue(fragment.MessageId, out var buffer)) {
+ if (!index.TryGetValue(fragment.MessageId, out var buffer))
+ {
log.Warning(ExceptionMessage());
return null;
}
@@ -56,7 +64,8 @@ string ExceptionMessage() =>
return message;
}
- private class FragmentsBuffer {
+ private class FragmentsBuffer
+ {
private const int watchdogIntervalMs = 5000;
private int index;
@@ -65,18 +74,21 @@ private class FragmentsBuffer {
public event System.Action? Timeout;
- private readonly System.Timers.Timer watchdog = new(watchdogIntervalMs) {
+ private readonly System.Timers.Timer watchdog = new(watchdogIntervalMs)
+ {
Enabled = true,
AutoReset = false
};
- public FragmentsBuffer(int count) {
+ public FragmentsBuffer(int count)
+ {
this.count = count;
buffer = new byte[count * MaxFragmentDataSize];
watchdog.Elapsed += (_, _) => Timeout?.Invoke();
}
- public NetworkMessage? Append(NetworkMessageFragment fragment) {
+ public NetworkMessage? Append(NetworkMessageFragment fragment)
+ {
if (index >= count)
throw new NetworkPlatformException("Invalid fragmentation: more fragments than expected.");
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkSerializer.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkSerializer.cs
similarity index 71%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkSerializer.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkSerializer.cs
index bb2ef0fa..ed6dfdfa 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkSerializer.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/NetworkSerializer.cs
@@ -1,12 +1,14 @@
-using System.IO;
+using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
-using MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+using MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging;
+namespace MultiplayerMod.Platform.Common.Network.Messaging;
-public static class NetworkSerializer {
+public static class NetworkSerializer
+{
- public static SerializedNetworkMessage Serialize(INetworkMessage message) {
+ public static SerializedNetworkMessage Serialize(INetworkMessage message)
+ {
return new SerializedNetworkMessage(message);
}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/SerializedNetworkMessage.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/SerializedNetworkMessage.cs
similarity index 70%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/SerializedNetworkMessage.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/SerializedNetworkMessage.cs
index 9c80b66c..2abce90a 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/SerializedNetworkMessage.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/SerializedNetworkMessage.cs
@@ -1,12 +1,13 @@
-using System;
+using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
-using MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+using MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging;
+namespace MultiplayerMod.Platform.Common.Network.Messaging;
-public class SerializedNetworkMessage : INetworkMessageHandle {
+public class SerializedNetworkMessage : INetworkMessageHandle
+{
public IntPtr Pointer { get; }
public uint Size { get; }
@@ -14,7 +15,8 @@ public class SerializedNetworkMessage : INetworkMessageHandle {
private readonly MemoryStream memory;
private GCHandle handle;
- public SerializedNetworkMessage(INetworkMessage message) {
+ public SerializedNetworkMessage(INetworkMessage message)
+ {
memory = new MemoryStream();
var formatter = new BinaryFormatter { SurrogateSelector = SerializationSurrogates.Selector };
formatter.Serialize(memory, message);
@@ -23,7 +25,8 @@ public SerializedNetworkMessage(INetworkMessage message) {
Size = (uint) memory.Length;
}
- public void Dispose() {
+ public void Dispose()
+ {
handle.Free();
memory.Close();
}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/AssignmentGroupSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/AssignmentGroupSurrogate.cs
similarity index 81%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/AssignmentGroupSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/AssignmentGroupSurrogate.cs
index 6c5ceba9..f8f5317d 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/AssignmentGroupSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/AssignmentGroupSurrogate.cs
@@ -1,13 +1,15 @@
using System;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class AssignmentGroupSurrogate : ISerializationSurrogate, ISurrogateType {
+public class AssignmentGroupSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(AssignmentGroup);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var group = (AssignmentGroup) obj;
info.AddValue("id", group.id);
}
@@ -17,7 +19,8 @@ public void GetObjectData(object obj, SerializationInfo info, StreamingContext c
SerializationInfo info,
StreamingContext context,
ISurrogateSelector selector
- ) {
+ )
+ {
var id = info.GetString("id");
return global::Game.Instance.assignmentManager.assignment_groups[id];
}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/CarePackageInstanceDataSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/CarePackageInstanceDataSurrogate.cs
similarity index 89%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/CarePackageInstanceDataSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/CarePackageInstanceDataSurrogate.cs
index f545b1cb..9c8ffffb 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/CarePackageInstanceDataSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/CarePackageInstanceDataSurrogate.cs
@@ -1,13 +1,15 @@
using System;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class CarePackageInstanceDataSurrogate : ISerializationSurrogate, ISurrogateType {
+public class CarePackageInstanceDataSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(CarePackageContainer.CarePackageInstanceData);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var packageInstanceData = (CarePackageContainer.CarePackageInstanceData) obj;
info.AddValue("facadeID", packageInstanceData.facadeID);
info.AddValue("info.id", packageInstanceData.info.id);
@@ -20,7 +22,8 @@ public object SetObjectData(
SerializationInfo info,
StreamingContext context,
ISurrogateSelector selector
- ) {
+ )
+ {
var packageInstanceData = (CarePackageContainer.CarePackageInstanceData) obj;
packageInstanceData.info = new CarePackageInfo(
info.GetString("info.id"),
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/ChoreTypeSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/ChoreTypeSurrogate.cs
similarity index 81%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/ChoreTypeSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/ChoreTypeSurrogate.cs
index befce71d..c8c26eca 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/ChoreTypeSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/ChoreTypeSurrogate.cs
@@ -1,13 +1,15 @@
using System;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class ChoreTypeSurrogate : ISerializationSurrogate, ISurrogateType {
+public class ChoreTypeSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(ChoreType);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var choreType = (ChoreType) obj;
info.AddValue("id", choreType.Id);
}
@@ -17,7 +19,8 @@ public object SetObjectData(
SerializationInfo info,
StreamingContext context,
ISurrogateSelector selector
- ) {
+ )
+ {
var id = info.GetString("id");
return Db.Get().ChoreTypes.Get(id);
}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/ComplexRecipeSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/ComplexRecipeSurrogate.cs
similarity index 83%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/ComplexRecipeSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/ComplexRecipeSurrogate.cs
index 77f73768..f6654d67 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/ComplexRecipeSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/ComplexRecipeSurrogate.cs
@@ -2,13 +2,15 @@
using System.Linq;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class ComplexRecipeSurrogate : ISerializationSurrogate, ISurrogateType {
+public class ComplexRecipeSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(ComplexRecipe);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var recipe = (ComplexRecipe) obj;
info.AddValue("id", recipe.id);
}
@@ -18,7 +20,8 @@ public object SetObjectData(
SerializationInfo info,
StreamingContext context,
ISurrogateSelector selector
- ) {
+ )
+ {
var id = info.GetString("id");
var recipe = ComplexRecipeManager.Get().recipes.Single(recipe => recipe.id == id);
return recipe;
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/DeathSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/DeathSurrogate.cs
similarity index 81%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/DeathSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/DeathSurrogate.cs
index 0866e67e..9ac7df70 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/DeathSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/DeathSurrogate.cs
@@ -1,13 +1,15 @@
using System;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class DeathSurrogate : ISerializationSurrogate, ISurrogateType {
+public class DeathSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(Death);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var death = (Death) obj;
info.AddValue("id", death.Id);
}
@@ -17,7 +19,8 @@ public object SetObjectData(
SerializationInfo info,
StreamingContext context,
ISurrogateSelector selector
- ) {
+ )
+ {
var id = info.GetString("id");
return Db.Get().Deaths.Get(id);
}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/EmoteSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/EmoteSurrogate.cs
similarity index 81%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/EmoteSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/EmoteSurrogate.cs
index 91353bf3..57ed2f6b 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/EmoteSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/EmoteSurrogate.cs
@@ -2,13 +2,15 @@
using System.Runtime.Serialization;
using Klei.AI;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class EmoteSurrogate : ISerializationSurrogate, ISurrogateType {
+public class EmoteSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(Emote);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var emote = (Emote) obj;
info.AddValue("id", emote.Id);
}
@@ -18,7 +20,8 @@ public object SetObjectData(
SerializationInfo info,
StreamingContext context,
ISurrogateSelector selector
- ) {
+ )
+ {
var id = info.GetString("id");
return Db.Get().Emotes.Minion.Get(id);
}
diff --git a/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/ISurrogateType.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/ISurrogateType.cs
new file mode 100644
index 00000000..8bfacdb4
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/ISurrogateType.cs
@@ -0,0 +1,7 @@
+using System;
+
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
+
+public interface ISurrogateType {
+ public Type Type { get; }
+}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/KAnimFileSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/KAnimFileSurrogate.cs
similarity index 81%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/KAnimFileSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/KAnimFileSurrogate.cs
index 5be3bcf6..d48a8686 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/KAnimFileSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/KAnimFileSurrogate.cs
@@ -1,13 +1,15 @@
using System;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class KAnimFileSurrogate : ISerializationSurrogate, ISurrogateType {
+public class KAnimFileSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(KAnimFile);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var anim = (KAnimFile) obj;
info.AddValue("name", anim.name);
}
@@ -17,7 +19,8 @@ public object SetObjectData(
SerializationInfo info,
StreamingContext context,
ISurrogateSelector selector
- ) {
+ )
+ {
var name = info.GetString("name");
return Assets.GetAnim(name);
}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/MinionStartingStatsSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/MinionStartingStatsSurrogate.cs
similarity index 93%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/MinionStartingStatsSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/MinionStartingStatsSurrogate.cs
index f040a03d..8717cd8b 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/MinionStartingStatsSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/MinionStartingStatsSurrogate.cs
@@ -3,13 +3,15 @@
using System.Linq;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class MinionStartingStatsSurrogate : ISerializationSurrogate, ISurrogateType {
+public class MinionStartingStatsSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(MinionStartingStats);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var stats = (MinionStartingStats) obj;
info.AddValue("Name", stats.Name);
info.AddValue("NameStringKey", stats.NameStringKey);
@@ -32,7 +34,8 @@ public object SetObjectData(
SerializationInfo info,
StreamingContext context,
ISurrogateSelector selector
- ) {
+ )
+ {
var stats = (MinionStartingStats) obj;
stats.Name = info.GetString("Name");
stats.NameStringKey = info.GetString("NameStringKey");
@@ -63,9 +66,11 @@ ISurrogateSelector selector
private static Dictionary ToDictionary(
IReadOnlyList keys,
IReadOnlyList values
- ) {
+ )
+ {
var result = new Dictionary();
- for (var i = 0; i < keys.Count; i++) {
+ for (var i = 0; i < keys.Count; i++)
+ {
result[keys[i]] = values[i];
}
return result;
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/PathNodeSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/PathNodeSurrogate.cs
similarity index 77%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/PathNodeSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/PathNodeSurrogate.cs
index 9ee24ca9..99793410 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/PathNodeSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/PathNodeSurrogate.cs
@@ -1,19 +1,22 @@
using System;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class PathNodeSurrogate : ISerializationSurrogate, ISurrogateType {
+public class PathNodeSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(BaseUtilityBuildTool.PathNode);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var node = (BaseUtilityBuildTool.PathNode) obj;
info.AddValue("cell", node.cell);
info.AddValue("valid", node.valid);
}
- public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) {
+ public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
+ {
var node = (BaseUtilityBuildTool.PathNode) obj;
node.cell = info.GetInt32("cell");
node.valid = info.GetBoolean("valid");
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/PrioritySettingSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/PrioritySettingSurrogate.cs
similarity index 78%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/PrioritySettingSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/PrioritySettingSurrogate.cs
index d5fdffb4..d7dbe2fd 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/PrioritySettingSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/PrioritySettingSurrogate.cs
@@ -1,19 +1,22 @@
using System;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class PrioritySettingSurrogate : ISerializationSurrogate, ISurrogateType {
+public class PrioritySettingSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(PrioritySetting);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var priority = (PrioritySetting) obj;
info.AddValue("class", priority.priority_class);
info.AddValue("value", priority.priority_value);
}
- public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) {
+ public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
+ {
var priority = (PrioritySetting) obj;
priority.priority_class = (PriorityScreen.PriorityClass) info.GetInt32("class");
priority.priority_value = info.GetInt32("value");
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/RoomSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/RoomSurrogate.cs
similarity index 87%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/RoomSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/RoomSurrogate.cs
index a4b0e79c..72f74e3c 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/RoomSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/RoomSurrogate.cs
@@ -3,13 +3,15 @@
using System.Linq;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class RoomSurrogate : ISerializationSurrogate, ISurrogateType {
+public class RoomSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(Room);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var room = obj as Room;
var allIds = new List(room!.primary_buildings);
allIds.AddRange(room.buildings);
@@ -24,7 +26,8 @@ public void GetObjectData(object obj, SerializationInfo info, StreamingContext c
SerializationInfo info,
StreamingContext context,
ISurrogateSelector selector
- ) {
+ )
+ {
var cell = info.GetInt32("cell");
return global::Game.Instance.roomProber.GetCavityForCell(cell)?.room;
}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/ScheduleBlockTypeSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/ScheduleBlockTypeSurrogate.cs
similarity index 81%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/ScheduleBlockTypeSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/ScheduleBlockTypeSurrogate.cs
index a38ba1da..14e15656 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/ScheduleBlockTypeSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/ScheduleBlockTypeSurrogate.cs
@@ -1,13 +1,15 @@
using System;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class ScheduleBlockTypeSurrogate : ISerializationSurrogate, ISurrogateType {
+public class ScheduleBlockTypeSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(ScheduleBlockType);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var scheduleBlockType = (ScheduleBlockType) obj;
info.AddValue("id", scheduleBlockType.Id);
}
@@ -17,7 +19,8 @@ public void GetObjectData(object obj, SerializationInfo info, StreamingContext c
SerializationInfo info,
StreamingContext context,
ISurrogateSelector selector
- ) {
+ )
+ {
var id = info.GetString("id");
return Db.Get().ScheduleBlockTypes.Get(id);
}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/SerializationSurrogates.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/SerializationSurrogates.cs
similarity index 82%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/SerializationSurrogates.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/SerializationSurrogates.cs
index 3161d66f..e5377a5e 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/SerializationSurrogates.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/SerializationSurrogates.cs
@@ -1,13 +1,15 @@
-using System;
+using System;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public static class SerializationSurrogates {
+public static class SerializationSurrogates
+{
public static readonly SurrogateSelector Selector = new();
- static SerializationSurrogates() {
+ static SerializationSurrogates()
+ {
Selector.Add(new Vector2SerializationSurrogate());
Selector.Add(new Vector2fSerializationSurrogate());
Selector.Add(new Vector3SerializationSurrogate());
@@ -29,11 +31,13 @@ static SerializationSurrogates() {
}
private static void Add(this SurrogateSelector selector, T surrogate)
- where T : ISerializationSurrogate, ISurrogateType {
+ where T : ISerializationSurrogate, ISurrogateType
+ {
selector.AddSurrogate(surrogate.Type, new StreamingContext(StreamingContextStates.All), surrogate);
}
- public static bool HasSurrogate(Type type) {
+ public static bool HasSurrogate(Type type)
+ {
return Selector.GetSurrogate(type, new StreamingContext(StreamingContextStates.All), out var _) != null;
}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/SpaceDestinationSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/SpaceDestinationSurrogate.cs
similarity index 81%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/SpaceDestinationSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/SpaceDestinationSurrogate.cs
index d0d8f849..9bb1d178 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/SpaceDestinationSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/SpaceDestinationSurrogate.cs
@@ -1,13 +1,15 @@
using System;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class SpaceDestinationSurrogate : ISerializationSurrogate, ISurrogateType {
+public class SpaceDestinationSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(SpaceDestination);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var destination = (SpaceDestination) obj;
info.AddValue("id", destination.id);
}
@@ -17,7 +19,8 @@ public object SetObjectData(
SerializationInfo info,
StreamingContext context,
ISurrogateSelector selector
- ) {
+ )
+ {
var id = info.GetString("id");
return SpacecraftManager.instance.GetDestination(int.Parse(id));
}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/SpiceGrinderSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/SpiceGrinderSurrogate.cs
similarity index 82%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/SpiceGrinderSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/SpiceGrinderSurrogate.cs
index 711307cd..d41c26e7 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/SpiceGrinderSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/SpiceGrinderSurrogate.cs
@@ -1,13 +1,15 @@
using System;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class SpiceGrinderSurrogate : ISerializationSurrogate, ISurrogateType {
+public class SpiceGrinderSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(SpiceGrinder.Option);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var option = (SpiceGrinder.Option) obj;
info.AddValue("id", option.Id);
}
@@ -17,7 +19,8 @@ public object SetObjectData(
SerializationInfo info,
StreamingContext context,
ISurrogateSelector selector
- ) {
+ )
+ {
var tag = (Tag) info.GetValue("id", typeof(Tag));
return SpiceGrinder.SettingOptions[tag];
}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/TagSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/TagSurrogate.cs
similarity index 75%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/TagSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/TagSurrogate.cs
index 1487bc29..104ff7c0 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/TagSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/TagSurrogate.cs
@@ -1,18 +1,21 @@
using System;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class TagSurrogate : ISerializationSurrogate, ISurrogateType {
+public class TagSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(Tag);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var tag = (Tag) obj;
info.AddValue("hash", tag.hash);
}
- public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) {
+ public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector)
+ {
var tag = (Tag) obj;
tag.hash = info.GetInt32("hash");
tag.name = TagManager.GetProperName(tag, stripLink: true);
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/Vector2SerializationSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/Vector2SerializationSurrogate.cs
similarity index 82%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/Vector2SerializationSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/Vector2SerializationSurrogate.cs
index 9b097264..4e51fdf6 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/Vector2SerializationSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/Vector2SerializationSurrogate.cs
@@ -2,13 +2,15 @@
using System.Runtime.Serialization;
using UnityEngine;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class Vector2SerializationSurrogate : ISerializationSurrogate, ISurrogateType {
+public class Vector2SerializationSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(Vector2);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var vector = (Vector2) obj;
info.AddValue("x", vector.x);
info.AddValue("y", vector.y);
@@ -19,7 +21,8 @@ public object SetObjectData(
SerializationInfo info,
StreamingContext context,
ISurrogateSelector selector
- ) {
+ )
+ {
var vector = (Vector2) obj;
vector.x = info.GetSingle("x");
vector.y = info.GetSingle("y");
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/Vector2fSerializationSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/Vector2fSerializationSurrogate.cs
similarity index 83%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/Vector2fSerializationSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/Vector2fSerializationSurrogate.cs
index 5a2e4fcf..b576d9fb 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/Vector2fSerializationSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/Vector2fSerializationSurrogate.cs
@@ -1,14 +1,16 @@
using System;
using System.Runtime.Serialization;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
// ReSharper disable once InconsistentNaming
-public class Vector2fSerializationSurrogate : ISerializationSurrogate, ISurrogateType {
+public class Vector2fSerializationSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(Vector2f);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var vector = (Vector2f) obj;
info.AddValue("x", vector.x);
info.AddValue("y", vector.y);
@@ -19,7 +21,8 @@ public object SetObjectData(
SerializationInfo info,
StreamingContext context,
ISurrogateSelector selector
- ) {
+ )
+ {
var vector = (Vector2f) obj;
vector.x = info.GetSingle("x");
vector.y = info.GetSingle("y");
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/Vector3SerializationSurrogate.cs b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/Vector3SerializationSurrogate.cs
similarity index 84%
rename from src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/Vector3SerializationSurrogate.cs
rename to src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/Vector3SerializationSurrogate.cs
index 5ee6e60e..b678f0f7 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/Vector3SerializationSurrogate.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/Messaging/Surrogates/Vector3SerializationSurrogate.cs
@@ -2,13 +2,15 @@
using System.Runtime.Serialization;
using UnityEngine;
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
+namespace MultiplayerMod.Platform.Common.Network.Messaging.Surrogates;
-public class Vector3SerializationSurrogate : ISerializationSurrogate, ISurrogateType {
+public class Vector3SerializationSurrogate : ISerializationSurrogate, ISurrogateType
+{
public Type Type => typeof(Vector3);
- public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
+ public void GetObjectData(object obj, SerializationInfo info, StreamingContext context)
+ {
var vector = (Vector3) obj;
info.AddValue("x", vector.x);
info.AddValue("y", vector.y);
@@ -20,7 +22,8 @@ public object SetObjectData(
SerializationInfo info,
StreamingContext context,
ISurrogateSelector selector
- ) {
+ )
+ {
var vector = (Vector3) obj;
vector.x = info.GetSingle("x");
vector.y = info.GetSingle("y");
diff --git a/src/MultiplayerMod/Platform/Steam/Network/NetworkPlatformException.cs b/src/MultiplayerMod/Platform/Common/Network/NetworkPlatformException.cs
similarity index 57%
rename from src/MultiplayerMod/Platform/Steam/Network/NetworkPlatformException.cs
rename to src/MultiplayerMod/Platform/Common/Network/NetworkPlatformException.cs
index 57cb3cfb..73fe5143 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/NetworkPlatformException.cs
+++ b/src/MultiplayerMod/Platform/Common/Network/NetworkPlatformException.cs
@@ -1,8 +1,9 @@
-using System;
+using System;
-namespace MultiplayerMod.Platform.Steam.Network;
+namespace MultiplayerMod.Platform.Common.Network;
-public class NetworkPlatformException : PlatformException {
+public class NetworkPlatformException : PlatformException
+{
public NetworkPlatformException(string message) : base(message) { }
public NetworkPlatformException(string message, Exception cause) : base(message, cause) { }
}
diff --git a/src/MultiplayerMod/Platform/Common/Network/SharedClient.cs b/src/MultiplayerMod/Platform/Common/Network/SharedClient.cs
new file mode 100644
index 00000000..4694e417
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Common/Network/SharedClient.cs
@@ -0,0 +1,41 @@
+using System;
+using JetBrains.Annotations;
+using MultiplayerMod.Core.Dependency;
+using MultiplayerMod.Multiplayer.Commands;
+using MultiplayerMod.Network;
+using MultiplayerMod.Platform.Steam.Network;
+using MultiplayerMod.Platform.Lan.Network;
+
+namespace MultiplayerMod.Platform.Common.Network;
+
+[Dependency, UsedImplicitly]
+public class SharedClient : IMultiplayerClient
+{
+ public MultiplayerClientState State { get { return client.State; } }
+
+ public event Action? StateChanged { add { client.StateChanged += value; } remove { client.StateChanged -= value; } }
+ public event Action? CommandReceived { add { client.CommandReceived += value; } remove { client.CommandReceived -= value; } }
+ public IMultiplayerClientId Id { get { return client.Id; } }
+
+ public void Connect(IMultiplayerEndpoint endpoint) { client.Connect(endpoint); }
+ public void Disconnect() { client.Disconnect(); }
+ public void Send(IMultiplayerCommand command, MultiplayerCommandOptions options = MultiplayerCommandOptions.None) { client.Send(command, options); }
+ public void Tick() { client.Tick(); }
+
+ private IMultiplayerClient? cachedClient = null;
+ private IMultiplayerClient client
+ {
+ get
+ {
+ if (cachedClient != null) { return cachedClient; }
+
+ if (Configuration.useSteam) {
+ cachedClient = new SteamClient();
+ } else {
+ cachedClient = new LanClient();
+ }
+ return cachedClient;
+ }
+ }
+
+}
diff --git a/src/MultiplayerMod/Platform/Common/Network/SharedServer.cs b/src/MultiplayerMod/Platform/Common/Network/SharedServer.cs
new file mode 100644
index 00000000..e78a0ae8
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Common/Network/SharedServer.cs
@@ -0,0 +1,52 @@
+using System;
+using System.Collections.Generic;
+using JetBrains.Annotations;
+using MultiplayerMod.Core.Dependency;
+using MultiplayerMod.Multiplayer.Commands;
+using MultiplayerMod.Network;
+using MultiplayerMod.Platform.Steam.Network;
+using MultiplayerMod.Platform.Lan.Network;
+
+namespace MultiplayerMod.Platform.Common.Network;
+
+[Dependency, UsedImplicitly]
+public class SharedServer : IMultiplayerServer
+{
+ public MultiplayerServerState State { get { return server.State; } }
+
+ public IMultiplayerEndpoint Endpoint { get { return server.Endpoint; } }
+
+ public List Clients { get { return server.Clients; } }
+
+ public event Action StateChanged { add { server.StateChanged += value; } remove { server.StateChanged -= value; } }
+ public event Action ClientConnected { add { server.ClientConnected += value; } remove { server.ClientConnected -= value; } }
+ public event Action ClientDisconnected { add { server.ClientDisconnected += value; } remove { server.ClientDisconnected -= value; } }
+ public event Action CommandReceived { add { server.CommandReceived += value; } remove { server.CommandReceived -= value; } }
+
+ public void Send(IMultiplayerClientId clientId, IMultiplayerCommand command) { server.Send(clientId, command); }
+
+ public void Send(IMultiplayerCommand command, MultiplayerCommandOptions options = MultiplayerCommandOptions.None) { server.Send(command, options); }
+
+ public void Tick() { server.Tick(); }
+
+ public void Start() { server.Start(); }
+
+ public void Stop() { server.Stop(); }
+
+ private IMultiplayerServer? cachedServer = null;
+ private IMultiplayerServer server
+ {
+ get
+ {
+ if (cachedServer != null) { return cachedServer; }
+
+ if (Configuration.useSteam) {
+ cachedServer = new SteamServer();
+ } else {
+ cachedServer = new LanServer();
+ }
+ return cachedServer;
+ }
+ }
+
+}
diff --git a/src/MultiplayerMod/Platform/Common/SharedMultiplayerOperations.cs b/src/MultiplayerMod/Platform/Common/SharedMultiplayerOperations.cs
new file mode 100644
index 00000000..c24e5d37
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Common/SharedMultiplayerOperations.cs
@@ -0,0 +1,28 @@
+using JetBrains.Annotations;
+using MultiplayerMod.Core.Dependency;
+using MultiplayerMod.Multiplayer;
+using MultiplayerMod.Platform.Lan;
+using MultiplayerMod.Platform.Steam;
+
+namespace MultiplayerMod.Platform.Common;
+
+[Dependency, UsedImplicitly]
+public class SharedMultiplayerOperations : IMultiplayerOperations {
+
+ public void Join() => instance.Join();
+
+ private IMultiplayerOperations? cachedInstance = null;
+ private IMultiplayerOperations instance {
+ get {
+ if (cachedInstance != null) { return cachedInstance; }
+
+ if (Configuration.useSteam) {
+ cachedInstance = new SteamMultiplayerOperations();
+ } else {
+ cachedInstance = new LanMultiplayerOperations();
+ }
+ return cachedInstance;
+ }
+ }
+
+}
diff --git a/src/MultiplayerMod/Platform/Common/SharedPlayerProfileProvider.cs b/src/MultiplayerMod/Platform/Common/SharedPlayerProfileProvider.cs
new file mode 100644
index 00000000..2b43a4a5
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Common/SharedPlayerProfileProvider.cs
@@ -0,0 +1,28 @@
+using JetBrains.Annotations;
+using MultiplayerMod.Core.Dependency;
+using MultiplayerMod.Multiplayer.Players;
+using MultiplayerMod.Platform.Lan;
+using MultiplayerMod.Platform.Steam;
+
+namespace MultiplayerMod.Platform.Common;
+
+[Dependency, UsedImplicitly]
+public class SharedPlayerProfileProvider : IPlayerProfileProvider {
+
+ public PlayerProfile GetPlayerProfile() => instance.GetPlayerProfile();
+
+ private IPlayerProfileProvider? cachedInstance = null;
+ private IPlayerProfileProvider instance {
+ get {
+ if (cachedInstance != null) { return cachedInstance; }
+
+ if (Configuration.useSteam) {
+ cachedInstance = new SteamPlayerProfileProvider();
+ } else {
+ cachedInstance = new LanPlayerProfileProvider();
+ }
+ return cachedInstance;
+ }
+ }
+
+}
diff --git a/src/MultiplayerMod/Platform/Lan/LanJoinRequestComponent.cs b/src/MultiplayerMod/Platform/Lan/LanJoinRequestComponent.cs
new file mode 100644
index 00000000..4f767904
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Lan/LanJoinRequestComponent.cs
@@ -0,0 +1,19 @@
+using MultiplayerMod.Core.Dependency;
+using MultiplayerMod.Core.Events;
+using MultiplayerMod.Core.Unity;
+
+// ReSharper disable FieldCanBeMadeReadOnly.Local
+
+namespace MultiplayerMod.Platform.Lan;
+
+public class LanJoinRequestComponent : MultiplayerMonoBehaviour {
+ public static LanJoinRequestComponent? instance;
+
+ [InjectDependency]
+ public EventDispatcher eventDispatcher = null!;
+
+ LanJoinRequestComponent() {
+ instance = this;
+ }
+
+}
diff --git a/src/MultiplayerMod/Platform/Lan/LanMultiplayerOperations.cs b/src/MultiplayerMod/Platform/Lan/LanMultiplayerOperations.cs
new file mode 100644
index 00000000..8cd7f98b
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Lan/LanMultiplayerOperations.cs
@@ -0,0 +1,12 @@
+using MultiplayerMod.Multiplayer;
+using MultiplayerMod.Multiplayer.Players.Events;
+using MultiplayerMod.Platform.Lan.Network;
+using MultiplayerMod.Platform.Steam.Network;
+
+namespace MultiplayerMod.Platform.Lan;
+
+internal class LanMultiplayerOperations : IMultiplayerOperations {
+ public void Join() {
+ LanJoinRequestComponent.instance?.eventDispatcher.Dispatch(new MultiplayerJoinRequestedEvent(new LanServerEndpoint(), LanConfiguration.instance.displayName));
+ }
+}
diff --git a/src/MultiplayerMod/Platform/Lan/LanPlatformConfigurer.cs b/src/MultiplayerMod/Platform/Lan/LanPlatformConfigurer.cs
new file mode 100644
index 00000000..c4d1c208
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Lan/LanPlatformConfigurer.cs
@@ -0,0 +1,16 @@
+using JetBrains.Annotations;
+using MultiplayerMod.Core.Dependency;
+using MultiplayerMod.Core.Unity;
+using MultiplayerMod.ModRuntime.Loader;
+
+namespace MultiplayerMod.Platform.Lan;
+
+[UsedImplicitly]
+[ModComponentOrder(ModComponentOrder.Platform)]
+public class LanPlatformConfigurer : IModComponentConfigurer {
+
+ public void Configure(DependencyContainerBuilder builder) {
+ builder.ContainerCreated += _ => UnityObject.CreateStaticWithComponent();
+ }
+
+}
diff --git a/src/MultiplayerMod/Platform/Lan/LanPlayerProfileProvider.cs b/src/MultiplayerMod/Platform/Lan/LanPlayerProfileProvider.cs
new file mode 100644
index 00000000..c5a245ae
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Lan/LanPlayerProfileProvider.cs
@@ -0,0 +1,17 @@
+using MultiplayerMod.Multiplayer.Players;
+using MultiplayerMod.Platform.Lan.Network;
+using System;
+
+namespace MultiplayerMod.Platform.Lan
+{
+ internal class LanPlayerProfileProvider : IPlayerProfileProvider {
+
+ private readonly Lazy profile = new(
+ () => new PlayerProfile(
+ LanConfiguration.instance.playerName
+ )
+ );
+
+ public PlayerProfile GetPlayerProfile() => profile.Value;
+ }
+}
diff --git a/src/MultiplayerMod/Platform/Lan/Network/ClientMessage.cs b/src/MultiplayerMod/Platform/Lan/Network/ClientMessage.cs
new file mode 100644
index 00000000..e43b347a
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Lan/Network/ClientMessage.cs
@@ -0,0 +1,14 @@
+using MultiplayerMod.Network;
+using MultiplayerMod.Platform.Common.Network.Messaging;
+
+namespace MultiplayerMod.Platform.Lan.Network;
+
+internal class ClientMessage {
+ internal readonly IMultiplayerClientId clientId;
+ internal readonly NetworkMessage message;
+
+ public ClientMessage(IMultiplayerClientId clientId, NetworkMessage message) {
+ this.clientId = clientId;
+ this.message = message;
+ }
+}
diff --git a/src/MultiplayerMod/Platform/Lan/Network/LanClient.cs b/src/MultiplayerMod/Platform/Lan/Network/LanClient.cs
new file mode 100644
index 00000000..637c7834
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Lan/Network/LanClient.cs
@@ -0,0 +1,133 @@
+using MultiplayerMod.Core.Logging;
+using MultiplayerMod.Core.Scheduling;
+using MultiplayerMod.Core.Unity;
+using MultiplayerMod.ModRuntime.StaticCompatibility;
+using MultiplayerMod.Multiplayer.Commands;
+using MultiplayerMod.Multiplayer.Commands.Player;
+using MultiplayerMod.Multiplayer.UI.Overlays;
+using MultiplayerMod.Network;
+using MultiplayerMod.Platform.Common.Network.Components;
+using MultiplayerMod.Platform.Common.Network.Messaging;
+using System;
+using System.Collections.Concurrent;
+using System.Threading.Tasks;
+using UnityEngine;
+using WebSocketSharp;
+
+namespace MultiplayerMod.Platform.Lan.Network;
+
+internal class LanClient : IMultiplayerClient {
+ public static LanClient? instance = null;
+
+ public IMultiplayerClientId Id => lanMultiplayerClientId;
+ public MultiplayerClientState State { get; private set; } = MultiplayerClientState.Disconnected;
+
+ public event Action? StateChanged;
+ public event Action? CommandReceived;
+
+ internal readonly LanMultiplayerClientId lanMultiplayerClientId = new LanMultiplayerClientId();
+ private WebSocket? network;
+
+ private GameObject? gameObject = null!;
+
+ private readonly Core.Logging.Logger log = LoggerFactory.GetLogger();
+ private ConcurrentQueue commandQueue = new();
+
+ public LanClient() {
+ //log.Level = Core.Logging.LogLevel.Debug;
+ instance = this;
+ }
+
+ public void Connect(IMultiplayerEndpoint endpoint) {
+ LanConfiguration.reload();
+ log.Info("Client connecting to server " + LanConfiguration.instance.hostUrl);
+ commandQueue = new();
+ network = new WebSocket(LanConfiguration.instance.hostUrl+"/oni");
+ network.OnOpen += OnOpen;
+ network.OnMessage += OnMessage;
+ network.OnClose += OnClose;
+ network.OnError += OnError;
+ SetState(MultiplayerClientState.Connecting);
+ network.ConnectAsync();
+ gameObject = UnityObject.CreateStaticWithComponent();
+ }
+
+ public void Disconnect() {
+ if (network == null) { return; }
+ log.Info("Client disconnected from server");
+ var oldnetwork = network;
+ network = null;
+ oldnetwork.CloseAsync();
+ if (gameObject != null) {
+ UnityObject.Destroy(gameObject);
+ gameObject = null!;
+ }
+ }
+
+ public void Send(IMultiplayerCommand command, MultiplayerCommandOptions options = MultiplayerCommandOptions.None) {
+ if (network == null) { return; }
+ try {
+ var data = new NetworkMessage(command, options).toBytes();
+
+ if (command.GetType() != typeof(UpdatePlayerCursorPosition)) {
+ log.Debug("Client sending command " + command.GetType() + ". Client " + Id + ". Len " + data.Length);
+ }
+ network.Send(data);
+ } catch (Exception e) {
+ log.Debug("Client failed to send command " + command.GetType() + ". " + e.Message);
+ }
+ }
+
+ public void Tick() {
+ while (commandQueue.TryDequeue(out var action)) {
+ action();
+ }
+ }
+
+ private void SetState(MultiplayerClientState status) {
+ State = status;
+ StateChanged?.Invoke(status);
+ }
+
+ private void OnOpen(object sender, EventArgs e) {
+ log.Debug("Client connected to server");
+ commandQueue.Enqueue(() => {
+ SetState(MultiplayerClientState.Connected);
+ });
+ }
+
+ private void OnClose(object sender, CloseEventArgs e) {
+ log.Debug("Client disconnected from server");
+ commandQueue.Enqueue(() => {
+ if (State == MultiplayerClientState.Connecting) {
+ log.Warning("Multiplayer connection to server could not be established.");
+ MultiplayerStatusOverlay.Text = "Failed to connect to server";
+ Task _ = this.closeOverlay();
+ }
+ SetState(MultiplayerClientState.Disconnected);
+ Disconnect();
+ });
+ }
+
+ private async Task closeOverlay() {
+ await Task.Delay(2000);
+ Dependencies.Get().Run(MultiplayerStatusOverlay.Close);
+ }
+
+ private void OnMessage(object sender, MessageEventArgs e) {
+ var message = NetworkMessage.from(e.RawData);
+ log.Debug("Client received command " + message.Command.GetType() + ". Client " + Id + ". Len " + e.RawData.Length);
+ commandQueue.Enqueue(() => {
+ if (State != MultiplayerClientState.Connected) { return; }
+ CommandReceived?.Invoke(message.Command);
+ });
+ }
+
+ private void OnError(object sender, ErrorEventArgs e) {
+ log.Warning("Client error " + e.Message);
+ commandQueue.Enqueue(() => {
+ SetState(MultiplayerClientState.Error);
+ });
+ }
+
+}
diff --git a/src/MultiplayerMod/Platform/Lan/Network/LanConfiguration.cs b/src/MultiplayerMod/Platform/Lan/Network/LanConfiguration.cs
new file mode 100644
index 00000000..a930344c
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Lan/Network/LanConfiguration.cs
@@ -0,0 +1,87 @@
+using MultiplayerMod.Core.Logging;
+using System;
+using System.IO;
+using System.Reflection;
+using System.Text;
+
+namespace MultiplayerMod.Platform.Lan.Network;
+
+public class LanConfiguration
+{
+ public static LanConfiguration instance = new LanConfiguration();
+ public static void reload() {
+ var newConfig = new LanConfiguration();
+ if (newConfig.isConfigured != instance.isConfigured) {
+ instance.log.Warning("Unable to enable/disable lan configuration while running, please restart Oxygen Not Included.");
+ return;
+ }
+ instance = newConfig;
+ }
+
+ public bool isConfigured { get { return configured; } }
+ public string serverIp { get { return hostip; } }
+ public ushort serverPort { get { return hostport; } }
+
+ public string hostUrl { get {
+ return "ws://" + serverIp + ":" + serverPort;
+ }
+ }
+
+ public string displayName { get { return serverIp + " (" + serverPort + ")"; } }
+ public string playerName { get { return name; } }
+
+
+ private string hostfilename = "lanconfig.txt";
+ private bool configured = false;
+ private string name = "LanPlayer";
+ private string hostip = "127.0.0.1";
+ private ushort hostport = 7171;
+ private readonly Core.Logging.Logger log = LoggerFactory.GetLogger();
+
+ private LanConfiguration() {
+ //log.Level = LogLevel.Debug;
+ configured = readConfiguration();
+ }
+
+ private bool readConfiguration() {
+ string moddir = Path.GetDirectoryName(Assembly.GetAssembly(typeof(LanConfiguration)).Location);
+ string fulldir = Path.Combine(moddir, hostfilename);
+ if (!File.Exists(fulldir)) {
+ return false;
+ }
+
+ try {
+ using (FileStream fileStream = File.Open(fulldir, FileMode.Open, FileAccess.Read, FileShare.None)) {
+ using (var streamReader = new StreamReader(fileStream, Encoding.UTF8, true, 1024)) {
+ bool foundHost = false;
+ string line;
+ while ((line = streamReader.ReadLine()) != null) {
+ if (line.IndexOf("#") > -1) { line = line.Substring(0, line.IndexOf("#")); }
+ int splitat = line.IndexOf('=');
+ if (splitat == -1) { continue; }
+
+ string key = line.Substring(0, splitat).Trim().ToLowerInvariant();
+ string value = line.Substring(splitat + 1).Trim();
+ switch (key) {
+ case "hostip":
+ hostip = value;
+ foundHost = true;
+ continue;
+ case "hostport":
+ hostport = ushort.Parse(value);
+ continue;
+ case "playername":
+ name = value;
+ continue;
+ }
+ }
+ return foundHost;
+ }
+ }
+ } catch (Exception e) {
+ log.Warning("Unable to read lan configuration from " + fulldir + ": "+e.Message);
+ }
+ return false;
+ }
+
+}
diff --git a/src/MultiplayerMod/Platform/Lan/Network/LanConnection.cs b/src/MultiplayerMod/Platform/Lan/Network/LanConnection.cs
new file mode 100644
index 00000000..514e813f
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Lan/Network/LanConnection.cs
@@ -0,0 +1,15 @@
+using System;
+
+namespace MultiplayerMod.Platform.Lan.Network;
+
+internal class LanConnection : IEquatable {
+ internal readonly LanMultiplayerClientId id;
+
+ internal LanConnection(LanMultiplayerClientId id) {
+ this.id = id;
+ }
+
+ public bool Equals(LanConnection other) {
+ return other.id == id;
+ }
+}
diff --git a/src/MultiplayerMod/Platform/Lan/Network/LanMultiplayerClientId.cs b/src/MultiplayerMod/Platform/Lan/Network/LanMultiplayerClientId.cs
new file mode 100644
index 00000000..d058ee0c
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Lan/Network/LanMultiplayerClientId.cs
@@ -0,0 +1,23 @@
+using MultiplayerMod.Network;
+using System;
+
+namespace MultiplayerMod.Platform.Lan.Network;
+
+[Serializable]
+public record LanMultiplayerClientId : IMultiplayerClientId {
+ public readonly string Id;
+
+ public LanMultiplayerClientId() : this(Guid.NewGuid().ToString()) { }
+
+ public LanMultiplayerClientId(string id) {
+ Id = id;
+ }
+
+ public bool Equals(IMultiplayerClientId other) {
+ return other is LanMultiplayerClientId player && player.Equals(this);
+ }
+
+ public override string ToString() {
+ return Id;
+ }
+}
diff --git a/src/MultiplayerMod/Platform/Lan/Network/LanServer.cs b/src/MultiplayerMod/Platform/Lan/Network/LanServer.cs
new file mode 100644
index 00000000..b604e6d4
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Lan/Network/LanServer.cs
@@ -0,0 +1,200 @@
+using MultiplayerMod.Core.Logging;
+using MultiplayerMod.Core.Unity;
+using MultiplayerMod.Multiplayer.Commands;
+using MultiplayerMod.Network;
+using MultiplayerMod.Platform.Common.Network.Components;
+using System;
+using System.Collections.Generic;
+using UnityEngine;
+using MultiplayerMod.Platform.Common.Network;
+using MultiplayerMod.ModRuntime.StaticCompatibility;
+using MultiplayerMod.Multiplayer.Commands.Registry;
+using WebSocketSharp;
+using WebSocketSharp.Server;
+using System.Linq;
+using MultiplayerMod.Platform.Common.Network.Messaging;
+using MultiplayerMod.Core.Extensions;
+using MultiplayerMod.Core.Collections;
+using System.Collections.Concurrent;
+using MultiplayerMod.Multiplayer.Commands.Player;
+namespace MultiplayerMod.Platform.Lan.Network;
+public record ServerEndpoint : IMultiplayerEndpoint ;
+
+internal class LanServer : IMultiplayerServer {
+ public static LanServer? instance = null;
+
+ public MultiplayerServerState State { private set; get; } = MultiplayerServerState.Stopped;
+ public IMultiplayerEndpoint Endpoint => new ServerEndpoint();
+
+ public List Clients => new(clientIdToLanClient.Select(it => it.Key));
+
+ public event Action? StateChanged;
+ public event Action? ClientConnected;
+ public event Action? ClientDisconnected;
+ public event Action? CommandReceived;
+
+ private readonly Dictionary lanClientIdToClientId = new();
+ private readonly Dictionary clientIdToLanClient = new();
+
+ private readonly Core.Logging.Logger log = LoggerFactory.GetLogger();
+ private GameObject? gameObject;
+
+ private readonly MultiplayerCommandRegistry commands;
+
+ private WebSocketServer? network;
+ private ConcurrentQueue commandQueue = new();
+
+ public LanServer() : this(Dependencies.Get()) { }
+
+ public LanServer(MultiplayerCommandRegistry commands) {
+ //log.Level = Core.Logging.LogLevel.Debug;
+ instance = this;
+ this.commands = commands;
+ }
+
+ public void Start() {
+ LanConfiguration.reload();
+ log.Info("Server preparing to listen on "+ LanConfiguration.instance.hostUrl);
+ commandQueue = new();
+ SetState(MultiplayerServerState.Preparing);
+ network = new WebSocketServer(LanConfiguration.instance.serverPort);
+ network.AddWebSocketService("/oni");
+ SetState(MultiplayerServerState.Starting);
+ network.Start();
+ gameObject = UnityObject.CreateStaticWithComponent();
+ SetState(MultiplayerServerState.Started);
+ }
+
+ public void Stop() {
+ if (network == null) { return; }
+
+ if (State <= MultiplayerServerState.Stopped)
+ throw new NetworkPlatformException("Server isn't started");
+
+ log.Info("Server preparing to stop");
+ if (gameObject != null) {
+ UnityObject.Destroy(gameObject);
+ }
+ network.Stop();
+ network = null;
+ SetState(MultiplayerServerState.Stopped);
+ }
+
+ public void Send(IMultiplayerClientId clientId, IMultiplayerCommand command) {
+ var connections = new SingletonCollection(clientIdToLanClient[(LanMultiplayerClientId)clientId]);
+ SendCommand(command, MultiplayerCommandOptions.None, connections);
+ }
+
+ public void Send(IMultiplayerCommand command, MultiplayerCommandOptions options = MultiplayerCommandOptions.None) {
+ IEnumerable> recipients = clientIdToLanClient;
+ if (options.HasFlag(MultiplayerCommandOptions.SkipHost) && LanClient.instance != null) {
+ recipients = recipients.Where(entry => !entry.Key.Equals(LanClient.instance.Id));
+ }
+
+ SendCommand(command, options, recipients.Select(it => it.Value));
+ }
+
+ public void Tick() {
+ while (commandQueue.TryDequeue(out var action)) {
+ action();
+ }
+ }
+
+ private void SetState(MultiplayerServerState state) {
+ State = state;
+ StateChanged?.Invoke(state);
+ }
+
+ private void SendCommand(IMultiplayerCommand command, MultiplayerCommandOptions options, IEnumerable connections) {
+ var message = new NetworkMessage(command, options);
+ SendMessage(message, connections);
+ }
+
+ private void SendMessage(NetworkMessage message, IEnumerable connections) {
+ if (connections.Count() == 0) { return; }
+ var clientId = lanClientIdToClientId[connections.First().ID];
+ try {
+ var data = message.toBytes();
+
+ log.Debug("Server sending command " + message.Command.GetType() + " to " + connections.Count() + " clients (including " + clientId + "). Len " + data.Length);
+ connections.ForEach(client => { client.SendData(data); });
+ } catch (Exception e) {
+ log.Warning("Server failed to send command " + message.Command.GetType() + " to " + connections.Count() + " clients (including " + clientId + "). " + e.Message);
+ }
+ }
+
+ internal void AddClient(LanServerClient lanServerClient) {
+ LanMultiplayerClientId clientId;
+ if (lanClientIdToClientId.Count() == 0 && LanClient.instance != null) {
+ clientId = LanClient.instance.lanMultiplayerClientId;
+ } else {
+ clientId = new LanMultiplayerClientId(lanServerClient.ID);
+ }
+ lanClientIdToClientId.Add(lanServerClient.ID, clientId);
+ clientIdToLanClient.Add(clientId, lanServerClient);
+ commandQueue.Enqueue(() => {
+ log.Info("Server client connected - ID: " + clientId + ", IP: " + lanServerClient.Context.UserEndPoint.Address);
+ ClientConnected?.Invoke(clientId);
+ });
+ }
+
+ internal void RemoveClient(LanServerClient lanServerClient) {
+ var clientId = lanClientIdToClientId[lanServerClient.ID];
+ lanClientIdToClientId.Remove(lanServerClient.ID);
+ clientIdToLanClient.Remove(clientId);
+ commandQueue.Enqueue(() => {
+ log.Info("Server client disconnected - ID: " + clientId);
+ ClientDisconnected?.Invoke(clientId);
+ });
+ }
+
+ internal void MessageReceived(LanServerClient lanServerClient, MessageEventArgs e) {
+ var clientId = lanClientIdToClientId[lanServerClient.ID];
+ var message = NetworkMessage.from(e.RawData);
+
+ if (message.Command.GetType() != typeof(UpdatePlayerCursorPosition)) {
+ log.Debug("Server received command " + message.Command.GetType() + " from client " + clientId.Id + ". Len " + e.RawData.Length);
+ }
+
+ var configuration = commands.GetCommandConfiguration(message.Command.GetType());
+ commandQueue.Enqueue(() => {
+ if (State != MultiplayerServerState.Starting
+ && State != MultiplayerServerState.Started) {
+ return;
+ }
+
+ if (configuration.ExecuteOnServer) {
+ CommandReceived?.Invoke(clientId, message.Command);
+ } else {
+ var connections = clientIdToLanClient.Where(it => !it.Key.Equals(clientId)).Select(it => it.Value);
+ SendMessage(message, connections);
+ }
+ });
+ }
+
+}
+
+internal class LanServerClient : WebSocketBehavior {
+ private readonly Core.Logging.Logger log = LoggerFactory.GetLogger();
+
+ protected override void OnOpen() {
+ LanServer.instance?.AddClient(this);
+ }
+
+ protected override void OnClose(CloseEventArgs e) {
+ LanServer.instance?.RemoveClient(this);
+ }
+
+ protected override void OnMessage(MessageEventArgs e) {
+ LanServer.instance?.MessageReceived(this, e);
+ }
+
+ protected override void OnError(ErrorEventArgs e) {
+ log.Warning("Server client error " + e.Message);
+ }
+
+ internal void SendData(byte[] data) {
+ Send(data);
+ }
+}
+
diff --git a/src/MultiplayerMod/Platform/Lan/Network/LanServerEndpoint.cs b/src/MultiplayerMod/Platform/Lan/Network/LanServerEndpoint.cs
new file mode 100644
index 00000000..73634c5f
--- /dev/null
+++ b/src/MultiplayerMod/Platform/Lan/Network/LanServerEndpoint.cs
@@ -0,0 +1,5 @@
+using MultiplayerMod.Network;
+
+namespace MultiplayerMod.Platform.Steam.Network;
+
+public record LanServerEndpoint() : IMultiplayerEndpoint;
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Components/SteamClientComponent.cs b/src/MultiplayerMod/Platform/Steam/Network/Components/SteamClientComponent.cs
deleted file mode 100644
index 16ac645c..00000000
--- a/src/MultiplayerMod/Platform/Steam/Network/Components/SteamClientComponent.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using MultiplayerMod.Core.Dependency;
-using MultiplayerMod.Core.Unity;
-
-// ReSharper disable FieldCanBeMadeReadOnly.Local
-
-namespace MultiplayerMod.Platform.Steam.Network.Components;
-
-public class SteamClientComponent : MultiplayerMonoBehaviour {
-
- [InjectDependency]
- private SteamClient client = null!;
-
- private void Update() => client.Tick();
-
-}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Components/SteamServerComponent.cs b/src/MultiplayerMod/Platform/Steam/Network/Components/SteamServerComponent.cs
deleted file mode 100644
index f63c6715..00000000
--- a/src/MultiplayerMod/Platform/Steam/Network/Components/SteamServerComponent.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using MultiplayerMod.Core.Dependency;
-using MultiplayerMod.Core.Unity;
-
-// ReSharper disable FieldCanBeMadeReadOnly.Local
-
-namespace MultiplayerMod.Platform.Steam.Network.Components;
-
-public class SteamServerComponent : MultiplayerMonoBehaviour {
-
- [InjectDependency]
- private SteamServer server = null!;
-
- private void Update() => server.Tick();
-
-}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Configuration.cs b/src/MultiplayerMod/Platform/Steam/Network/Configuration.cs
index 13915866..17e58319 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Configuration.cs
+++ b/src/MultiplayerMod/Platform/Steam/Network/Configuration.cs
@@ -1,5 +1,3 @@
-using System;
-using MultiplayerMod.Platform.Steam.Network.Messaging;
using Steamworks;
namespace MultiplayerMod.Platform.Steam.Network;
@@ -14,12 +12,4 @@ public static class Configuration {
m_val = new SteamNetworkingConfigValue_t.OptionValue { m_int32 = size }
};
- public const int MaxMessageSize = 524288; // 512 KiB
- public static readonly int MaxFragmentDataSize = GetFragmentDataSize();
-
- private static int GetFragmentDataSize() {
- using var serialized = NetworkSerializer.Serialize(new NetworkMessageFragment(0, Array.Empty()));
- return MaxMessageSize - (int) serialized.Size;
- }
-
}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Extensions.cs b/src/MultiplayerMod/Platform/Steam/Network/Extensions.cs
index 47c1376f..311e4029 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/Extensions.cs
+++ b/src/MultiplayerMod/Platform/Steam/Network/Extensions.cs
@@ -1,4 +1,4 @@
-using MultiplayerMod.Platform.Steam.Network.Messaging;
+using MultiplayerMod.Platform.Common.Network.Messaging;
using Steamworks;
namespace MultiplayerMod.Platform.Steam.Network;
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/INetworkMessage.cs b/src/MultiplayerMod/Platform/Steam/Network/Messaging/INetworkMessage.cs
deleted file mode 100644
index 756a033a..00000000
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/INetworkMessage.cs
+++ /dev/null
@@ -1,3 +0,0 @@
-namespace MultiplayerMod.Platform.Steam.Network.Messaging;
-
-public interface INetworkMessage { }
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/INetworkMessageHandle.cs b/src/MultiplayerMod/Platform/Steam/Network/Messaging/INetworkMessageHandle.cs
deleted file mode 100644
index 27fe4aa9..00000000
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/INetworkMessageHandle.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using System;
-
-namespace MultiplayerMod.Platform.Steam.Network.Messaging;
-
-public interface INetworkMessageHandle : IDisposable {
- public IntPtr Pointer { get; }
- public uint Size { get; }
-}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessage.cs b/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessage.cs
deleted file mode 100644
index 5bbcb68b..00000000
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessage.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-using MultiplayerMod.Multiplayer.Commands;
-using MultiplayerMod.Network;
-
-namespace MultiplayerMod.Platform.Steam.Network.Messaging;
-
-[Serializable]
-public class NetworkMessage : INetworkMessage {
-
- public IMultiplayerCommand Command { get; }
- public MultiplayerCommandOptions Options { get; }
-
- public NetworkMessage(IMultiplayerCommand command, MultiplayerCommandOptions options) {
- Command = command;
- Options = options;
- }
-
-}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessageFragment.cs b/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessageFragment.cs
deleted file mode 100644
index a136012c..00000000
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessageFragment.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-
-namespace MultiplayerMod.Platform.Steam.Network.Messaging;
-
-[Serializable]
-public class NetworkMessageFragment : INetworkMessage {
-
- public int MessageId { get; }
- public byte[] Data { get; }
-
- public NetworkMessageFragment(int messageId, byte[] data) {
- MessageId = messageId;
- Data = data;
- }
-
-}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessageHandle.cs b/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessageHandle.cs
deleted file mode 100644
index 09a9dbfb..00000000
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/NetworkMessageHandle.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-using System;
-
-namespace MultiplayerMod.Platform.Steam.Network.Messaging;
-
-public class NetworkMessageHandle : INetworkMessageHandle {
-
- public IntPtr Pointer { get; }
- public uint Size { get; }
-
- public NetworkMessageHandle(IntPtr pointer, uint size) {
- Pointer = pointer;
- Size = size;
- }
-
- public void Dispose() {
- // No disposal required
- }
-
-}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/ISurrogateType.cs b/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/ISurrogateType.cs
deleted file mode 100644
index 7a438d47..00000000
--- a/src/MultiplayerMod/Platform/Steam/Network/Messaging/Surrogates/ISurrogateType.cs
+++ /dev/null
@@ -1,7 +0,0 @@
-using System;
-
-namespace MultiplayerMod.Platform.Steam.Network.Messaging.Surrogates;
-
-public interface ISurrogateType {
- public Type Type { get; }
-}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/SteamClient.cs b/src/MultiplayerMod/Platform/Steam/Network/SteamClient.cs
index ca9b324e..33048856 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/SteamClient.cs
+++ b/src/MultiplayerMod/Platform/Steam/Network/SteamClient.cs
@@ -1,22 +1,21 @@
-using System;
+using System;
using System.Runtime.InteropServices;
-using JetBrains.Annotations;
-using MultiplayerMod.Core.Dependency;
using MultiplayerMod.Core.Extensions;
using MultiplayerMod.Core.Logging;
using MultiplayerMod.Core.Unity;
+using MultiplayerMod.ModRuntime.StaticCompatibility;
using MultiplayerMod.Multiplayer.Commands;
using MultiplayerMod.Network;
-using MultiplayerMod.Platform.Steam.Network.Components;
-using MultiplayerMod.Platform.Steam.Network.Messaging;
+using MultiplayerMod.Platform.Common.Network.Messaging;
+using MultiplayerMod.Platform.Common.Network.Components;
using Steamworks;
using UnityEngine;
using static Steamworks.Constants;
using static Steamworks.ESteamNetConnectionEnd;
+using MultiplayerMod.Platform.Common.Network;
namespace MultiplayerMod.Platform.Steam.Network;
-[Dependency, UsedImplicitly]
public class SteamClient : IMultiplayerClient {
public IMultiplayerClientId Id => playerContainer.Value;
@@ -38,6 +37,8 @@ public class SteamClient : IMultiplayerClient {
private GameObject gameObject = null!;
+ public SteamClient() : this(Dependencies.Get()) { }
+
public SteamClient(SteamLobby lobby) {
this.lobby = lobby;
}
@@ -87,6 +88,8 @@ public void Send(IMultiplayerCommand command, MultiplayerCommandOptions options
if (State != MultiplayerClientState.Connected)
throw new NetworkPlatformException("Client not connected");
+ log.Debug("Client sending command " + command.GetType() + ". Client " + Id + ".");
+
messageFactory.Create(command, options).ForEach(
handle => {
var result = SteamNetworkingSockets.SendMessageToConnection(
@@ -124,7 +127,7 @@ private void OnLobbyJoin() {
SetRichPresence();
- gameObject = UnityObject.CreateStaticWithComponent();
+ gameObject = UnityObject.CreateStaticWithComponent();
SetState(MultiplayerClientState.Connected);
}
diff --git a/src/MultiplayerMod/Platform/Steam/Network/SteamLobby.cs b/src/MultiplayerMod/Platform/Steam/Network/SteamLobby.cs
index dd46a61b..b7a685f9 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/SteamLobby.cs
+++ b/src/MultiplayerMod/Platform/Steam/Network/SteamLobby.cs
@@ -1,9 +1,9 @@
-using JetBrains.Annotations;
+using JetBrains.Annotations;
using MultiplayerMod.Core.Dependency;
using MultiplayerMod.Core.Logging;
using Steamworks;
-namespace MultiplayerMod.Platform.Steam.Network;
+namespace MultiplayerMod.Platform.Common.Network;
[Dependency, UsedImplicitly]
public class SteamLobby {
diff --git a/src/MultiplayerMod/Platform/Steam/Network/SteamServer.cs b/src/MultiplayerMod/Platform/Steam/Network/SteamServer.cs
index d07874b1..4cc3360f 100644
--- a/src/MultiplayerMod/Platform/Steam/Network/SteamServer.cs
+++ b/src/MultiplayerMod/Platform/Steam/Network/SteamServer.cs
@@ -1,21 +1,21 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Threading.Tasks;
-using JetBrains.Annotations;
using MultiplayerMod.Core.Collections;
-using MultiplayerMod.Core.Dependency;
using MultiplayerMod.Core.Extensions;
using MultiplayerMod.Core.Logging;
using MultiplayerMod.Core.Scheduling;
using MultiplayerMod.Core.Unity;
+using MultiplayerMod.ModRuntime.StaticCompatibility;
using MultiplayerMod.Multiplayer.Commands;
using MultiplayerMod.Multiplayer.Commands.Registry;
using MultiplayerMod.Network;
-using MultiplayerMod.Platform.Steam.Network.Components;
-using MultiplayerMod.Platform.Steam.Network.Messaging;
+using MultiplayerMod.Platform.Common.Network;
+using MultiplayerMod.Platform.Common.Network.Components;
+using MultiplayerMod.Platform.Common.Network.Messaging;
using Steamworks;
using UnityEngine;
using static Steamworks.Constants;
@@ -25,7 +25,6 @@
namespace MultiplayerMod.Platform.Steam.Network;
-[Dependency, UsedImplicitly]
public class SteamServer : IMultiplayerServer {
public MultiplayerServerState State { private set; get; } = MultiplayerServerState.Stopped;
@@ -69,6 +68,8 @@ public IMultiplayerEndpoint Endpoint {
private GameObject? gameObject;
+ public SteamServer() : this(Dependencies.Get(), Dependencies.Get(), Dependencies.Get()) { }
+
public SteamServer(SteamLobby lobby, UnityTaskScheduler scheduler, MultiplayerCommandRegistry commands) {
this.lobby = lobby;
this.scheduler = scheduler;
@@ -88,7 +89,7 @@ public void Start() {
SetState(MultiplayerServerState.Error);
throw;
}
- gameObject = UnityObject.CreateStaticWithComponent();
+ gameObject = UnityObject.CreateStaticWithComponent();
}
public void Stop() {
@@ -132,7 +133,7 @@ private void SetState(MultiplayerServerState state) {
}
private void Initialize() {
- steamServersConnectedCallback = Callback
+ steamServersConnectedCallback = Callback
.CreateGameServer(_ => ConnectedToSteamCallback());
lobbyCompletionSource = new TaskCompletionSource();
diff --git a/src/MultiplayerMod/Platform/Steam/SteamMultiplayerOperations.cs b/src/MultiplayerMod/Platform/Steam/SteamMultiplayerOperations.cs
index ff86a0fa..396fb439 100644
--- a/src/MultiplayerMod/Platform/Steam/SteamMultiplayerOperations.cs
+++ b/src/MultiplayerMod/Platform/Steam/SteamMultiplayerOperations.cs
@@ -1,11 +1,8 @@
-using JetBrains.Annotations;
-using MultiplayerMod.Core.Dependency;
using MultiplayerMod.Multiplayer;
using Steamworks;
namespace MultiplayerMod.Platform.Steam;
-[Dependency, UsedImplicitly]
public class SteamMultiplayerOperations : IMultiplayerOperations {
public void Join() => SteamFriends.ActivateGameOverlay("friends");
diff --git a/src/MultiplayerMod/Platform/Steam/SteamPlayerProfileProvider.cs b/src/MultiplayerMod/Platform/Steam/SteamPlayerProfileProvider.cs
index 6f48b775..feb76d65 100644
--- a/src/MultiplayerMod/Platform/Steam/SteamPlayerProfileProvider.cs
+++ b/src/MultiplayerMod/Platform/Steam/SteamPlayerProfileProvider.cs
@@ -1,12 +1,9 @@
-using System;
-using JetBrains.Annotations;
-using MultiplayerMod.Core.Dependency;
+using System;
using MultiplayerMod.Multiplayer.Players;
using Steamworks;
namespace MultiplayerMod.Platform.Steam;
-[Dependency, UsedImplicitly]
public class SteamPlayerProfileProvider : IPlayerProfileProvider {
private readonly Lazy profile = new(
diff --git a/src/MultiplayerMod/lanconfig.example.txt b/src/MultiplayerMod/lanconfig.example.txt
new file mode 100644
index 00000000..09ceaf92
--- /dev/null
+++ b/src/MultiplayerMod/lanconfig.example.txt
@@ -0,0 +1,5 @@
+# To use a lan connection instead of the steam lobby, rename this file to lanconfig.txt and enter the ip of the host machine.
+# You may also wish to enter a name you'd like to use.
+playername=LanPlayer
+hostip=192.168.1.1
+hostport=7171