This commit is contained in:
2025-02-25 07:07:16 +02:00
parent 1c3f27d817
commit effd008aa2
10 changed files with 253 additions and 102 deletions

View File

@@ -47,8 +47,11 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="MelonLoaderMod.cs" /> <Compile Include="MelonLoaderMod.cs" />
<Compile Include="Networking\LobbyManager.cs" /> <Compile Include="Networking\LobbyManager\LobbyManager.cs" />
<Compile Include="Networking\PacketBase.cs" /> <Compile Include="Networking\LobbyManager\SteamLobbyManager.cs" />
<Compile Include="Networking\Packet.cs" />
<Compile Include="Networking\Transport\SteamTransport.cs" />
<Compile Include="Networking\Transport\TransportBase.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Networking\ByteEncoder.cs" /> <Compile Include="Networking\ByteEncoder.cs" />
</ItemGroup> </ItemGroup>

View File

@@ -1,4 +1,6 @@
using BoneSync.Networking; using BoneSync.Networking;
using BoneSync.Networking.LobbyManager;
using BoneSync.Networking.Transport;
using MelonLoader; using MelonLoader;
namespace BoneSync namespace BoneSync
@@ -14,10 +16,18 @@ namespace BoneSync
public class BoneSync : MelonMod public class BoneSync : MelonMod
{ {
LobbyManager lobby;
TransportBase transport;
public override void OnApplicationStart() public override void OnApplicationStart()
{ {
MelonLogger.Msg("OnApplicationStart"); MelonLogger.Msg("OnApplicationStart");
LobbyManager.Initialize(); // Initialize the LobbyManager
SteamLobbyManager steamLobbyManager = new SteamLobbyManager();
lobby = steamLobbyManager;
transport = new SteamTransport(steamLobbyManager);
} }
public override void OnSceneWasLoaded(int buildIndex, string sceneName) public override void OnSceneWasLoaded(int buildIndex, string sceneName)
@@ -37,7 +47,7 @@ namespace BoneSync
public override void OnUpdate() public override void OnUpdate()
{ {
MelonLogger.Msg("OnUpdate"); transport.Tick();
} }
public override void OnFixedUpdate() public override void OnFixedUpdate()

View File

@@ -100,5 +100,14 @@ namespace BoneSync.Networking
return Encoding.UTF8.GetString(ReadBytes(length)); return Encoding.UTF8.GetString(ReadBytes(length));
} }
public void WriteUlong(ulong value)
{
WriteBytes(BitConverter.GetBytes(value));
}
public ulong ReadUlong() {
return BitConverter.ToUInt64(ReadBytes(sizeof(ulong)), 0);
}
} }
} }

View File

@@ -1,38 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Facepunch.Steamworks;
using Facepunch.Steamworks.ServerList;
using Facepunch.Steamworks.Data;
namespace BoneSync.Networking
{
internal static class LobbyManager
{
static Lobby lobby;
public static void CreateLobby()
{
_ = SteamMatchmaking.CreateLobbyAsync(10);
}
private static void OnLobbyCreated(Result result, Lobby createdLobby)
{
if (result != Result.OK)
{
Console.WriteLine("Failed to create lobby: " + result);
return;
}
Console.WriteLine("Lobby created: " + createdLobby.Id);
lobby = createdLobby;
}
public static void Initialize()
{
SteamMatchmaking.OnLobbyCreated += OnLobbyCreated;
}
}
}

View File

@@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Facepunch.Steamworks;
using Facepunch.Steamworks.ServerList;
using Facepunch.Steamworks.Data;
namespace BoneSync.Networking.LobbyManager
{
internal abstract class LobbyManager
{
public abstract ulong GetLobbyId();
public abstract ulong GetHostId();
public abstract ulong GetLocalId();
public virtual void CreateLobby()
{
}
public virtual void Initialize()
{
}
}
}

View File

@@ -0,0 +1,46 @@
using Facepunch.Steamworks;
using Facepunch.Steamworks.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BoneSync.Networking.LobbyManager
{
internal class SteamLobbyManager : LobbyManager
{
public SteamId[] Peers;
private Lobby lobbyInstance;
public override ulong GetLocalId()
{
return SteamClient.SteamId.Value;
}
public override ulong GetHostId()
{
return lobbyInstance.Owner.Id;
}
public override ulong GetLobbyId()
{
return lobbyInstance.Id;
}
public override void CreateLobby()
{
}
public SteamId? getPeerFromId(ulong id)
{
foreach (SteamId peer in Peers)
{
if (peer.Value == id)
{
return peer;
}
}
return null;
}
}
}

View File

@@ -0,0 +1,71 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BoneSync.Networking
{
public enum PacketType
{
LobbyInfo = 0,
CharacterInfo = 1,
}
internal struct PacketInfo
{
public int id;
public int senderId;
public ulong receiverId;
public PacketType packetType;
public PacketInfo(int id, int senderId, ulong receiverId, PacketType packetType)
{
this.id = id;
this.senderId = senderId;
this.receiverId = receiverId;
this.packetType = packetType;
}
}
internal class Packet
{
public PacketInfo Info
{
get => _packetInfo;
private set => _packetInfo = value;
}
private PacketInfo _packetInfo;
private byte[] dataBytes;
private PacketInfo packetInfo;
public Packet(PacketInfo packetInfo, byte[] data)
{
this.packetInfo = packetInfo;
this.dataBytes = data;
}
public static Packet FromBytes(byte[] bytes)
{
ByteEncoder byteEncoder = new ByteEncoder();
byteEncoder.WriteBytes(bytes);
PacketInfo packetInfo = new PacketInfo(byteEncoder.ReadInt(), byteEncoder.ReadInt(), byteEncoder.ReadUlong(), (PacketType)byteEncoder.ReadInt());
return new Packet(packetInfo, byteEncoder.ToArray());
}
public byte[] ToBytes()
{
ByteEncoder byteEncoder = new ByteEncoder();
byteEncoder.WriteInt(packetInfo.id);
byteEncoder.WriteInt(packetInfo.senderId);
byteEncoder.WriteUlong(packetInfo.receiverId);
byteEncoder.WriteInt((int)packetInfo.packetType);
byteEncoder.WriteBytes(dataBytes);
return byteEncoder.ToArray();
}
public byte[] Data => dataBytes;
}
}

View File

@@ -1,60 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BoneSync.Networking
{
public enum PacketType
{
LobbyInfo = 0,
}
internal struct PacketInfo
{
public int id;
public int senderId;
public int receiverId;
public PacketType packetType;
public PacketInfo(int id, int senderId, int receiverId, PacketType packetType)
{
this.id = id;
this.senderId = senderId;
this.receiverId = receiverId;
this.packetType = packetType;
}
}
internal abstract class PacketBase
{
public PacketInfo Info;
public ByteEncoder Encoder;
public void OnReceive(byte[] bytes)
{
}
private void ParseInfo()
{
Info = new PacketInfo();
Info.id = Encoder.ReadInt();
Info.senderId = Encoder.ReadInt();
Info.receiverId = Encoder.ReadInt();
Info.packetType = (PacketType)Encoder.ReadInt();
}
private void WriteInfo()
{
Encoder.WriteInt(Info.id);
Encoder.WriteInt(Info.senderId);
Encoder.WriteInt(Info.receiverId);
Encoder.WriteInt((int)Info.packetType);
}
internal abstract void ParseData();
internal abstract void WriteData();
}
}

View File

@@ -0,0 +1,65 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BoneSync.Networking.LobbyManager;
using Facepunch.Steamworks;
using Facepunch.Steamworks.Data;
namespace BoneSync.Networking.Transport
{
internal class SteamTransport : TransportBase
{
SteamLobbyManager _instance;
public override event Action<Packet> OnReceive;
public SteamTransport(SteamLobbyManager lobbyManager)
{
SteamNetworking.OnP2PSessionRequest += OnP2PSessionRequest;
}
private void OnP2PSessionRequest(SteamId 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();
if (isTarget)
{
OnReceive?.Invoke(packet);
}
}
public override bool Tick()
{
while (SteamNetworking.IsP2PPacketAvailable())
{
P2Packet packet = (P2Packet)SteamNetworking.ReadP2PPacket();
ProcessPacket(packet);
}
return true;
}
public override void Send(Packet packet)
{
if (packet.Info.receiverId == 0)
{
foreach (SteamId peer in _instance.Peers)
{
byte[] packetBytes = packet.ToBytes();
SteamNetworking.SendP2PPacket(peer, packetBytes, packetBytes.Length, 0, P2PSend.Reliable);
}
return;
}
else
{
SteamId peer = (SteamId)_instance.getPeerFromId(packet.Info.receiverId);
SteamNetworking.SendP2PPacket(peer, packet.ToBytes(), packet.ToBytes().Length, 0, P2PSend.Reliable);
}
}
}
}

View File

@@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BoneSync.Networking.Transport
{
internal abstract class TransportBase
{
public abstract void Send(Packet packet);
public abstract bool Tick();
public abstract event Action<Packet> OnReceive;
}
}