diff --git a/BoneSync/BoneSync.csproj b/BoneSync/BoneSync.csproj index 9107957..298185c 100644 --- a/BoneSync/BoneSync.csproj +++ b/BoneSync/BoneSync.csproj @@ -47,8 +47,11 @@ - - + + + + + diff --git a/BoneSync/MelonLoaderMod.cs b/BoneSync/MelonLoaderMod.cs index a9d6998..68dde4c 100644 --- a/BoneSync/MelonLoaderMod.cs +++ b/BoneSync/MelonLoaderMod.cs @@ -1,4 +1,6 @@ using BoneSync.Networking; +using BoneSync.Networking.LobbyManager; +using BoneSync.Networking.Transport; using MelonLoader; namespace BoneSync @@ -14,10 +16,18 @@ namespace BoneSync public class BoneSync : MelonMod { + LobbyManager lobby; + TransportBase transport; public override void 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) @@ -37,7 +47,7 @@ namespace BoneSync public override void OnUpdate() { - MelonLogger.Msg("OnUpdate"); + transport.Tick(); } public override void OnFixedUpdate() diff --git a/BoneSync/Networking/ByteEncoder.cs b/BoneSync/Networking/ByteEncoder.cs index da5bcd5..225a5e1 100644 --- a/BoneSync/Networking/ByteEncoder.cs +++ b/BoneSync/Networking/ByteEncoder.cs @@ -100,5 +100,14 @@ namespace BoneSync.Networking 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); + } + } } diff --git a/BoneSync/Networking/LobbyManager.cs b/BoneSync/Networking/LobbyManager.cs deleted file mode 100644 index 80674a9..0000000 --- a/BoneSync/Networking/LobbyManager.cs +++ /dev/null @@ -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; - } - } -} diff --git a/BoneSync/Networking/LobbyManager/LobbyManager.cs b/BoneSync/Networking/LobbyManager/LobbyManager.cs new file mode 100644 index 0000000..da19ed3 --- /dev/null +++ b/BoneSync/Networking/LobbyManager/LobbyManager.cs @@ -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() + { + + } + + } +} diff --git a/BoneSync/Networking/LobbyManager/SteamLobbyManager.cs b/BoneSync/Networking/LobbyManager/SteamLobbyManager.cs new file mode 100644 index 0000000..216db29 --- /dev/null +++ b/BoneSync/Networking/LobbyManager/SteamLobbyManager.cs @@ -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; + } + + } +} diff --git a/BoneSync/Networking/Packet.cs b/BoneSync/Networking/Packet.cs new file mode 100644 index 0000000..e61305e --- /dev/null +++ b/BoneSync/Networking/Packet.cs @@ -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; + + + } +} diff --git a/BoneSync/Networking/PacketBase.cs b/BoneSync/Networking/PacketBase.cs deleted file mode 100644 index fc9c26f..0000000 --- a/BoneSync/Networking/PacketBase.cs +++ /dev/null @@ -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(); - } -} diff --git a/BoneSync/Networking/Transport/SteamTransport.cs b/BoneSync/Networking/Transport/SteamTransport.cs new file mode 100644 index 0000000..7b64fcb --- /dev/null +++ b/BoneSync/Networking/Transport/SteamTransport.cs @@ -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 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); + } + } + + + } +} diff --git a/BoneSync/Networking/Transport/TransportBase.cs b/BoneSync/Networking/Transport/TransportBase.cs new file mode 100644 index 0000000..f10c39f --- /dev/null +++ b/BoneSync/Networking/Transport/TransportBase.cs @@ -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 OnReceive; + } +}