diff --git a/BoneSync/BoneSync.csproj b/BoneSync/BoneSync.csproj
index 0555f47..6dee43f 100644
--- a/BoneSync/BoneSync.csproj
+++ b/BoneSync/BoneSync.csproj
@@ -40,24 +40,38 @@
..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Stationeers\MelonLoader\MelonLoader.dll
+ False
..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.TestPlatform.CoreUtilities.dll
+ False
..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.TestPlatform.PlatformAbstractions.dll
+ False
..\packages\Microsoft.TestPlatform.ObjectModel.17.12.0\lib\net462\Microsoft.VisualStudio.TestPlatform.ObjectModel.dll
+ False
+
+
+ ..\packages\MSTest.TestFramework.3.8.2\lib\net462\Microsoft.VisualStudio.TestPlatform.TestFramework.dll
+ False
+
+
+ ..\packages\MSTest.TestFramework.3.8.2\lib\net462\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll
+ False
..\packages\System.Collections.Immutable.1.5.0\lib\netstandard2.0\System.Collections.Immutable.dll
+ False
..\packages\System.Reflection.Metadata.1.6.0\lib\netstandard2.0\System.Reflection.Metadata.dll
+ False
@@ -67,16 +81,24 @@
- ..\packages\xunit.abstractions.2.0.3\lib\net35\xunit.abstractions.dll
+ False
+ ..\..\..\..\.nuget\packages\xunit.abstractions\2.0.3\lib\net35\xunit.abstractions.dll
+ False
- ..\packages\xunit.assert.2.9.3\lib\netstandard1.1\xunit.assert.dll
+ False
+ ..\..\..\..\.nuget\packages\xunit.assert\2.9.3\lib\netstandard1.1\xunit.assert.dll
+ False
- ..\packages\xunit.extensibility.core.2.9.3\lib\net452\xunit.core.dll
+ False
+ ..\..\..\..\.nuget\packages\xunit.extensibility.core\2.9.3\lib\net452\xunit.core.dll
+ False
- ..\packages\xunit.extensibility.execution.2.9.3\lib\net452\xunit.execution.desktop.dll
+ False
+ ..\..\..\..\.nuget\packages\xunit.extensibility.execution\2.9.3\lib\net452\xunit.execution.desktop.dll
+ False
@@ -92,19 +114,17 @@
-
-
- {0289f09e-d594-46a9-96a7-b0f31f5d97b0}
- Facepunch.Steamworks.Win64
-
+
-
-
+
+
+
+
diff --git a/BoneSync/MelonLoaderMod.cs b/BoneSync/MelonLoaderMod.cs
index 5365064..30933a1 100644
--- a/BoneSync/MelonLoaderMod.cs
+++ b/BoneSync/MelonLoaderMod.cs
@@ -25,8 +25,7 @@ namespace BoneSync
SteamLobbyManager steamLobbyManager = new SteamLobbyManager();
lobby = steamLobbyManager;
- transport = new SteamTransport(steamLobbyManager);
-
+ transport = new SteamTransport();
}
diff --git a/BoneSync/Networking/LobbyManager/LobbyManager.cs b/BoneSync/Networking/LobbyManager/LobbyManager.cs
index a42d18a..098157c 100644
--- a/BoneSync/Networking/LobbyManager/LobbyManager.cs
+++ b/BoneSync/Networking/LobbyManager/LobbyManager.cs
@@ -11,15 +11,11 @@ namespace BoneSync.Networking.LobbyManager
{
public abstract class LobbyManager
{
+ public abstract ulong[] GetPeers();
public abstract ulong GetLobbyId();
public abstract ulong GetHostId();
public abstract ulong GetLocalId();
- public virtual void CreateLobby()
- {
-
- }
-
public virtual void Initialize()
{
diff --git a/BoneSync/Networking/LobbyManager/SteamLobbyManager.cs b/BoneSync/Networking/LobbyManager/SteamLobbyManager.cs
index 216db29..5afd397 100644
--- a/BoneSync/Networking/LobbyManager/SteamLobbyManager.cs
+++ b/BoneSync/Networking/LobbyManager/SteamLobbyManager.cs
@@ -10,36 +10,52 @@ namespace BoneSync.Networking.LobbyManager
{
internal class SteamLobbyManager : LobbyManager
{
- public SteamId[] Peers;
- private Lobby lobbyInstance;
-
- public override ulong GetLocalId()
+ private Lobby _lobbyInstance;
+ public Friend[] LobbyMembers
{
- return SteamClient.SteamId.Value;
+ get;
+ private set;
}
- public override ulong GetHostId()
+ public SteamId[] steamIds
{
- return lobbyInstance.Owner.Id;
- }
- public override ulong GetLobbyId()
- {
- return lobbyInstance.Id;
- }
- public override void CreateLobby()
- {
-
+ get;
+ private set;
}
- public SteamId? getPeerFromId(ulong id)
+ public override ulong[] GetPeers() => steamIds.Select(x => x.Value).ToArray();
+ public override ulong GetLocalId() => SteamClient.SteamId.Value;
+ public override ulong GetHostId() => _lobbyInstance.Owner.Id.Value;
+ public override ulong GetLobbyId() => _lobbyInstance.Id.Value;
+
+ private void UpdateLobbyData()
{
- foreach (SteamId peer in Peers)
+ LobbyMembers = _lobbyInstance.Members.ToArray();
+ steamIds = LobbyMembers.Select(x => x.Id).ToArray();
+ }
+ public override void Initialize()
+ {
+ SteamMatchmaking.OnLobbyCreated += (Result result, Lobby lobby) =>
{
- if (peer.Value == id)
+ _lobbyInstance = lobby;
+ UpdateLobbyData();
+ };
+ SteamMatchmaking.OnLobbyEntered += (Lobby lobby) =>
+ {
+ _lobbyInstance = lobby;
+ UpdateLobbyData();
+ };
+ SteamMatchmaking.OnLobbyMemberLeave += (Lobby lobby, Friend friend) =>
+ {
+ if (friend.Id == SteamClient.SteamId)
{
- return peer;
+ _lobbyInstance = new Lobby();
}
- }
- return null;
+ UpdateLobbyData();
+ };
+ SteamMatchmaking.OnLobbyMemberJoined += (Lobby lobby, Friend friend) =>
+ {
+ UpdateLobbyData();
+ };
}
}
diff --git a/BoneSync/Networking/Messages/NetworkMessage.cs b/BoneSync/Networking/Messages/NetworkMessage.cs
index cf085c4..b426714 100644
--- a/BoneSync/Networking/Messages/NetworkMessage.cs
+++ b/BoneSync/Networking/Messages/NetworkMessage.cs
@@ -22,7 +22,7 @@ namespace BoneSync.Networking.Messages
public abstract class NetworkMessage
{
- private static bool _packetTypesRegistered = false;
+ private static bool PacketTypesRegistered => PacketTypeMap.Count > 0;
internal static Dictionary PacketTypeMap = new Dictionary();
@@ -34,25 +34,26 @@ namespace BoneSync.Networking.Messages
public PacketType GetPacketType()
{
+ RegisterPacketTypes();
if (_packetType == PacketType.Unknown)
{
- Type type = GetType();
- _packetType = PacketTypeMap.FirstOrDefault(x => x.Value == type).Key;
- if (_packetType == PacketType.Unknown)
+ string typeName = GetType().Name;
+ KeyValuePair found = PacketTypeMap.FirstOrDefault(x => x.Value.Name == typeName);
+ if (found.Value == null)
{
- throw new Exception("Cannot find packetType for " + type.Name);
+ throw new Exception("Cannot find packetType for " + typeName);
}
+ _packetType = found.Key;
}
return _packetType;
}
public static void RegisterPacketTypes()
{
- if (_packetTypesRegistered)
+ if (PacketTypesRegistered)
{
return;
}
- _packetTypesRegistered = true;
Assembly assembly = Assembly.GetExecutingAssembly();
Type[] types = assembly.GetTypes();
foreach (Type type in types)
@@ -61,7 +62,7 @@ namespace BoneSync.Networking.Messages
if (type.IsSubclassOf(typeof(NetworkMessage)))
{
PacketType? packetType = type.GetCustomAttributesData().Where(x => x.AttributeType == typeof(PacketTypeAttribute)).Select(x => (PacketType)x.ConstructorArguments[0].Value).FirstOrDefault();
- PacketTypeMap.Add((PacketType)packetType, type);
+ PacketTypeMap[packetType.Value] = type;
}
}
}
@@ -75,12 +76,7 @@ namespace BoneSync.Networking.Messages
}
Type type = PacketTypeMap[packet.Info.packetType];
// get the constructor that takes a Packet
- ConstructorInfo constructor = type.GetConstructor(new Type[] { typeof(Packet) });
- // create an instance of the class
- if (constructor == null)
- {
- throw new Exception("No constructor found for type " + type.Name);
- }
+ ConstructorInfo constructor = type.GetConstructor(new Type[] { typeof(Packet) }) ?? throw new Exception("No constructor found for type " + type.Name);
NetworkMessage networkMessage = (NetworkMessage)constructor.Invoke(new object[] { packet });
return networkMessage;
}
@@ -95,7 +91,7 @@ namespace BoneSync.Networking.Messages
}
public void Broadcast()
{
- Send(0);
+ Send(TransportBase.BORADCAST_ID);
}
public void Send(ulong receiverId)
{
diff --git a/BoneSync/Networking/Packet.cs b/BoneSync/Networking/Packet.cs
index 4a55bd4..87b3946 100644
--- a/BoneSync/Networking/Packet.cs
+++ b/BoneSync/Networking/Packet.cs
@@ -1,4 +1,5 @@
-using System;
+using BoneSync.Networking.Messages;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -33,7 +34,6 @@ namespace BoneSync.Networking
private PacketInfo _packetInfo;
private byte[] _dataBytes;
- private PacketInfo packetInfo;
public Packet(PacketInfo packetInfo, byte[] data)
{
@@ -45,21 +45,34 @@ namespace BoneSync.Networking
{
ByteEncoder byteEncoder = new ByteEncoder();
byteEncoder.WriteBytes(bytes);
- PacketInfo packetInfo = new PacketInfo(byteEncoder.ReadInt(), byteEncoder.ReadUlong(), byteEncoder.ReadUlong(), (PacketType)byteEncoder.ReadInt());
+
+ int packetType = byteEncoder.ReadInt();
+ int id = byteEncoder.ReadInt();
+ ulong senderId = byteEncoder.ReadUlong();
+ ulong receiverId = byteEncoder.ReadUlong();
+
+ PacketInfo packetInfo = new PacketInfo(id, senderId, receiverId, (PacketType)packetType);
return new Packet(packetInfo, byteEncoder.ToArray());
}
public byte[] ToBytes()
{
ByteEncoder byteEncoder = new ByteEncoder();
- byteEncoder.WriteInt(packetInfo.id);
- byteEncoder.WriteUlong(packetInfo.senderId);
- byteEncoder.WriteUlong(packetInfo.receiverId);
- byteEncoder.WriteInt((int)packetInfo.packetType);
+ byteEncoder.WriteInt((int)_packetInfo.packetType);
+ byteEncoder.WriteInt(_packetInfo.id);
+ byteEncoder.WriteUlong(_packetInfo.senderId);
+ byteEncoder.WriteUlong(_packetInfo.receiverId);
byteEncoder.WriteBytes(_dataBytes);
return byteEncoder.ToArray();
}
+ public static bool OnPacketReceived(Packet packet)
+ {
+ NetworkMessage networkMessage = NetworkMessage.ParsePacket(packet);
+ networkMessage.Execute();
+ return true;
+ }
+
public byte[] Data => _dataBytes;
public static int GenerateId()
@@ -77,15 +90,21 @@ namespace BoneSync.Networking
byte[] randomDataBytes = new byte[1024];
random.NextBytes(randomDataBytes);
- PacketInfo originalPacketInfo = new PacketInfo(1, 2, 3, PacketType.LobbyInfo);
+ PacketInfo originalPacketInfo = new PacketInfo(Packet.GenerateId(), 1, 2, PacketType.LobbyInfo);
Packet originalPacket = new Packet(originalPacketInfo, randomDataBytes);
byte[] bytes = originalPacket.ToBytes();
Packet parsedPacket = Packet.FromBytes(bytes);
- Assert.Equal(originalPacket.Info, parsedPacket.Info);
+
+ Assert.Equal(originalPacket.Info.id, parsedPacket.Info.id);
+ Assert.Equal(originalPacket.Info.senderId, parsedPacket.Info.senderId);
+ Assert.Equal(originalPacket.Info.receiverId, parsedPacket.Info.receiverId);
+ Assert.Equal(originalPacket.Info.packetType, parsedPacket.Info.packetType);
+
Assert.Equal(originalPacket.Data, parsedPacket.Data);
+
Assert.Equal(randomDataBytes, parsedPacket.Data);
Assert.NotEqual(bytes, randomDataBytes);
}
diff --git a/BoneSync/Networking/Transport/SteamTransport.cs b/BoneSync/Networking/Transport/SteamTransport.cs
index 7b64fcb..56303af 100644
--- a/BoneSync/Networking/Transport/SteamTransport.cs
+++ b/BoneSync/Networking/Transport/SteamTransport.cs
@@ -1,62 +1,82 @@
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using BoneSync.Networking.LobbyManager;
using Facepunch.Steamworks;
using Facepunch.Steamworks.Data;
+using MelonLoader;
namespace BoneSync.Networking.Transport
{
internal class SteamTransport : TransportBase
{
- SteamLobbyManager _instance;
- public override event Action OnReceive;
- public SteamTransport(SteamLobbyManager lobbyManager)
+ public SteamTransport()
{
SteamNetworking.OnP2PSessionRequest += OnP2PSessionRequest;
}
private void OnP2PSessionRequest(SteamId steamId)
{
- SteamNetworking.AcceptP2PSessionWithUser(steamId);
+ MelonLogger.Msg("P2P Request from " + steamId);
+ if (BoneSync.lobby.GetPeers().Contains(steamId))
+ SteamNetworking.AcceptP2PSessionWithUser(steamId);
}
private void ProcessPacket(P2Packet steamPacket)
{
Packet packet = Packet.FromBytes(steamPacket.Data);
- bool isTarget = packet.Info.receiverId == 0 || packet.Info.receiverId == _instance.GetLocalId();
+ bool isTarget = packet.Info.receiverId == BORADCAST_ID || packet.Info.receiverId == BoneSync.lobby.GetLocalId();
if (isTarget)
{
- OnReceive?.Invoke(packet);
+ Packet.OnPacketReceived(packet);
}
}
public override bool Tick()
{
+ int processed = 0;
while (SteamNetworking.IsP2PPacketAvailable())
{
- P2Packet packet = (P2Packet)SteamNetworking.ReadP2PPacket();
- ProcessPacket(packet);
+ P2Packet? packet = SteamNetworking.ReadP2PPacket();
+ if (!packet.HasValue) continue;
+ ProcessPacket(packet.Value);
+ processed++;
}
- return true;
+ return processed > 0;
+ }
+
+ public void SendP2P(SteamId peer, byte[] data)
+ {
+ if (peer == BoneSync.lobby.GetLocalId())
+ {
+ //MelonLogger.Msg("Trying to send packet to self");
+ return;
+ }
+ SteamNetworking.SendP2PPacket(peer, data, data.Length, 0, P2PSend.Reliable);
}
public override void Send(Packet packet)
{
- if (packet.Info.receiverId == 0)
+ LobbyManager.LobbyManager _instance = BoneSync.lobby;
+ if (_instance == null)
{
- foreach (SteamId peer in _instance.Peers)
+ MelonLogger.Msg("Lobby instance is null");
+ return;
+ }
+ if (packet.Info.receiverId == BORADCAST_ID)
+ {
+ foreach (SteamId peer in _instance.GetPeers())
{
- byte[] packetBytes = packet.ToBytes();
- SteamNetworking.SendP2PPacket(peer, packetBytes, packetBytes.Length, 0, P2PSend.Reliable);
+ SendP2P(peer, packet.ToBytes());
}
+
return;
}
else
{
- SteamId peer = (SteamId)_instance.getPeerFromId(packet.Info.receiverId);
- SteamNetworking.SendP2PPacket(peer, packet.ToBytes(), packet.ToBytes().Length, 0, P2PSend.Reliable);
+ SendP2P(packet.Info.receiverId, packet.ToBytes());
}
}
diff --git a/BoneSync/Networking/Transport/TransportBase.cs b/BoneSync/Networking/Transport/TransportBase.cs
index 891e1d4..e6bedde 100644
--- a/BoneSync/Networking/Transport/TransportBase.cs
+++ b/BoneSync/Networking/Transport/TransportBase.cs
@@ -8,9 +8,8 @@ namespace BoneSync.Networking.Transport
{
public abstract class TransportBase
{
+ public const int BORADCAST_ID = 0;
public abstract void Send(Packet packet);
public abstract bool Tick();
-
- public abstract event Action OnReceive;
}
}
diff --git a/BoneSync/packages.config b/BoneSync/packages.config
index a400c1b..a5081ad 100644
--- a/BoneSync/packages.config
+++ b/BoneSync/packages.config
@@ -1,11 +1,13 @@
+
+
-
+
diff --git a/Facepunch.Steamworks/Facepunch.Steamworks.Win64.csproj b/Facepunch.Steamworks/Facepunch.Steamworks.Win64.csproj
index 701650c..8f21335 100644
--- a/Facepunch.Steamworks/Facepunch.Steamworks.Win64.csproj
+++ b/Facepunch.Steamworks/Facepunch.Steamworks.Win64.csproj
@@ -24,11 +24,15 @@
https://github.com/Facepunch/Facepunch.Steamworks.git
git
+
+
+
+
-
- Always
-
+
+ Never
+
diff --git a/testEnvironments.json b/testEnvironments.json
new file mode 100644
index 0000000..a110b57
--- /dev/null
+++ b/testEnvironments.json
@@ -0,0 +1,17 @@
+{
+ "version": "1",
+ "environments": [
+ // See https://aka.ms/remotetesting for more details
+ // about how to configure remote environments.
+ //{
+ // "name": "WSL Ubuntu",
+ // "type": "wsl",
+ // "wslDistribution": "Ubuntu"
+ //},
+ //{
+ // "name": "Docker dotnet/sdk",
+ // "type": "docker",
+ // "dockerImage": "mcr.microsoft.com/dotnet/sdk"
+ //}
+ ]
+}
\ No newline at end of file