From 3b0c26a687f16148bbb2a97ad79d34e55edf910b Mon Sep 17 00:00:00 2001 From: Aaro Varis Date: Sun, 9 Mar 2025 22:32:47 +0200 Subject: [PATCH] Packet catchup and scene indexes in packets --- BoneSync/MelonLoaderMod.cs | 1 + .../Networking/Messages/PlugSyncMessage.cs | 2 +- .../Messages/RegisterSyncableMessage.cs | 2 +- BoneSync/Networking/NetworkMessage.cs | 36 +++++++++++- BoneSync/Networking/Packet.cs | 55 +++++++++++++++++-- BoneSync/Player/PlayerRig.cs | 9 +-- BoneSync/Sync/SceneSync.cs | 4 ++ 7 files changed, 94 insertions(+), 15 deletions(-) diff --git a/BoneSync/MelonLoaderMod.cs b/BoneSync/MelonLoaderMod.cs index 64b9e0d..5dde35d 100644 --- a/BoneSync/MelonLoaderMod.cs +++ b/BoneSync/MelonLoaderMod.cs @@ -113,6 +113,7 @@ namespace BoneSync { IsConnected = lobby.IsConnected(); transport.Tick(); + Packet.TryCatchup(); PlayerRig.Tick(); } diff --git a/BoneSync/Networking/Messages/PlugSyncMessage.cs b/BoneSync/Networking/Messages/PlugSyncMessage.cs index d5135a4..0d9568e 100644 --- a/BoneSync/Networking/Messages/PlugSyncMessage.cs +++ b/BoneSync/Networking/Messages/PlugSyncMessage.cs @@ -19,7 +19,7 @@ namespace BoneSync.Networking.Messages public byte socketIndex; } - [PacketType(PacketType.PlugSync), PacketReliability(PacketReliability.ReliableFast)] + [PacketType(PacketType.PlugSync), PacketReliability(PacketReliability.ReliableFast), PacketCatchup(10)] internal class PlugSyncMessage : NetworkMessage { private PlugSyncMessageData messageData; diff --git a/BoneSync/Networking/Messages/RegisterSyncableMessage.cs b/BoneSync/Networking/Messages/RegisterSyncableMessage.cs index b8d24be..c036685 100644 --- a/BoneSync/Networking/Messages/RegisterSyncableMessage.cs +++ b/BoneSync/Networking/Messages/RegisterSyncableMessage.cs @@ -30,7 +30,7 @@ namespace BoneSync.Networking.Messages public SpawnPoolableInfo? spawnInfo; } - [PacketType(PacketType.RegisterSyncable), PacketReliability(PacketReliability.ReliableFast), PacketCatchup(0)] + [PacketType(PacketType.RegisterSyncable), PacketReliability(PacketReliability.ReliableFast), PacketCatchup(1)] internal class RegisterSyncableMessage : NetworkMessage { private RegisterSyncableInfo _info; diff --git a/BoneSync/Networking/NetworkMessage.cs b/BoneSync/Networking/NetworkMessage.cs index 8d18cd4..2715952 100644 --- a/BoneSync/Networking/NetworkMessage.cs +++ b/BoneSync/Networking/NetworkMessage.cs @@ -1,5 +1,6 @@ using BoneSync.Data; using BoneSync.Networking.Transport; +using BoneSync.Sync; using MelonLoader; using System; using System.Collections.Generic; @@ -37,12 +38,20 @@ namespace BoneSync.Networking public class PacketCatchupAttribute : Attribute { public int order { get; } - public PacketCatchupAttribute(int order = 1) + public PacketCatchupAttribute(int order) { this.order = order; } } + public class AlwaysExecuteAttribute : Attribute + { + public AlwaysExecuteAttribute() + { + + } + } + public abstract class NetworkMessage { public ulong senderId @@ -56,10 +65,19 @@ namespace BoneSync.Networking internal PacketType _packetType; internal PacketReliability? _reliability; + internal int? _catchupOrder; + internal bool? _alwaysExecute; internal ByteEncoder byteEncoder = new ByteEncoder(); public byte[] GetBytes() => byteEncoder.ToArray(); + public bool GetAlwaysExecute() + { + if (_alwaysExecute.HasValue) return _alwaysExecute.Value; + AlwaysExecuteAttribute alwaysExecuteAttribute = GetType().GetCustomAttribute(); + _alwaysExecute = alwaysExecuteAttribute != null; + return _alwaysExecute.Value; + } public PacketType GetPacketType() { RegisterPacketTypes(); @@ -76,6 +94,20 @@ namespace BoneSync.Networking return _packetType; } + public int GetCatchupOrder() + { + if (_catchupOrder.HasValue) return _catchupOrder.Value; + PacketCatchupAttribute catchupAttribute = GetType().GetCustomAttribute(); + if (catchupAttribute == null) + { + _catchupOrder = -1; + return -1; + } + + _catchupOrder = catchupAttribute.order; + return _catchupOrder.Value; + } + public PacketReliability GetPacketReliability() { if (_reliability.HasValue) return _reliability.Value; @@ -130,7 +162,7 @@ namespace BoneSync.Networking public Packet GetPacket(ulong senderId, ulong receiverId) { - PacketInfo packetInfo = new PacketInfo(senderId, receiverId, GetPacketType(), GetPacketReliability()); + PacketInfo packetInfo = new PacketInfo(senderId, receiverId, GetPacketType(), GetPacketReliability(), 0, (byte)SceneSync.CurrentSceneIndex); Packet packet = new Packet(packetInfo, GetBytes()); return packet; } diff --git a/BoneSync/Networking/Packet.cs b/BoneSync/Networking/Packet.cs index b9772bd..96cfee8 100644 --- a/BoneSync/Networking/Packet.cs +++ b/BoneSync/Networking/Packet.cs @@ -1,5 +1,6 @@ using BoneSync.Data; using BoneSync.Networking.Messages; +using BoneSync.Sync; using Facepunch.Steamworks; using System; using System.Collections.Generic; @@ -24,6 +25,7 @@ namespace BoneSync.Networking public ulong id; public ulong senderId; public ulong receiverId; + public byte sceneIndex; public PacketType packetType; public PacketReliability reliability; @@ -31,8 +33,9 @@ namespace BoneSync.Networking ulong senderId, ulong receiverId, PacketType packetType, - PacketReliability reliability = PacketReliability.Reliable, - ulong id = 0 + PacketReliability reliability, + ulong id, + byte sceneIndex ) { this.senderId = senderId; @@ -40,11 +43,13 @@ namespace BoneSync.Networking this.packetType = packetType; this.reliability = reliability; this.id = id == 0 ? Packet.GenerateId() : id; - + this.sceneIndex = sceneIndex; } } public class Packet { + private static Dictionary> _packetQueues = new Dictionary>(); + private static ulong _packetId = 1; private static Dictionary> _latestPacketIds = new Dictionary>(); @@ -93,11 +98,12 @@ namespace BoneSync.Networking byte packetType = byteEncoder.ReadByte(); byte reliability = byteEncoder.ReadByte(); + byte sceneIndex = byteEncoder.ReadByte(); ulong id = byteEncoder.ReadULong(); ulong senderId = byteEncoder.ReadULong(); ulong receiverId = byteEncoder.ReadULong(); - PacketInfo packetInfo = new PacketInfo(senderId, receiverId, (PacketType)packetType, (PacketReliability)reliability, id); + PacketInfo packetInfo = new PacketInfo(senderId, receiverId, (PacketType)packetType, (PacketReliability)reliability, id, sceneIndex); return new Packet(packetInfo, byteEncoder.ToArray()); } @@ -106,6 +112,7 @@ namespace BoneSync.Networking ByteEncoder byteEncoder = new ByteEncoder(); byteEncoder.WriteByte((byte)_packetInfo.packetType); byteEncoder.WriteByte((byte)_packetInfo.reliability); + byteEncoder.WriteByte(_packetInfo.sceneIndex); byteEncoder.WriteULong(_packetInfo.id); byteEncoder.WriteULong(_packetInfo.senderId); byteEncoder.WriteULong(_packetInfo.receiverId); @@ -113,6 +120,14 @@ namespace BoneSync.Networking return byteEncoder.ToArray(); } + private static void EnsureQueueForScene(byte sceneIndex) + { + if (!_packetQueues.ContainsKey(sceneIndex)) + { + _packetQueues.Add(sceneIndex, new Queue()); + } + } + public static bool OnPacketReceived(Packet packet) { if (packet._packetInfo.reliability == PacketReliability.ReliableFast) @@ -125,10 +140,42 @@ namespace BoneSync.Networking } NetworkMessage networkMessage = NetworkMessage.ParsePacket(packet); + + if (packet._packetInfo.sceneIndex != SceneSync.CurrentSceneIndex && !networkMessage.GetAlwaysExecute()) + { + bool addToQueue = networkMessage.GetCatchupOrder() > 0; + if (!addToQueue) return false; + EnsureQueueForScene(packet._packetInfo.sceneIndex); + _packetQueues[packet._packetInfo.sceneIndex].Enqueue(networkMessage); + return true; + } + networkMessage.Execute(); return true; } + public static void TryCatchup() + { + if (!BoneSync.IsConnected) + { + if (_packetQueues.Count > 0) _packetQueues.Clear(); + return; + } + byte sceneIndex = (byte)SceneSync.CurrentSceneIndex; + if (!_packetQueues.ContainsKey(sceneIndex)) + { + return; + } + Queue queue = _packetQueues[sceneIndex]; + int processed = 0; + while (queue.Count > 0 && processed < 10) + { + processed++; + NetworkMessage networkMessage = queue.Dequeue(); + networkMessage.Execute(); + } + } + public byte[] Data => _dataBytes; public static ulong GenerateId() diff --git a/BoneSync/Player/PlayerRig.cs b/BoneSync/Player/PlayerRig.cs index d679bec..65e689f 100644 --- a/BoneSync/Player/PlayerRig.cs +++ b/BoneSync/Player/PlayerRig.cs @@ -78,6 +78,7 @@ namespace BoneSync.Player public void UpdatePlayerSync(PlayerSyncInfo playerSyncInfo) { + EnsurePlayerRig(); //MelonLogger.Msg("Updating player sync for " + _ownerId); playerRig.transform.position = playerSyncInfo.rootPos; @@ -224,13 +225,7 @@ namespace BoneSync.Player // Catch errors so other players arent broken try { - EnsurePlayerRig(); - //Re-Apply playermodel if unloaded - //if ((!currentSkinBundle || !currentSkinObject) && isCustomSkinned) - // PlayerSkinLoader.ApplyPlayermodel(this, currentSkinPath); - // Prevent exceptions if we are in the middle of deleting a playermodel - if (!animator) - return; + if (body == null || characterAnimationManager == null || animator == null || playerRig == null) return; animator.Update(Time.fixedDeltaTime); characterAnimationManager.OnLateUpdate(); diff --git a/BoneSync/Sync/SceneSync.cs b/BoneSync/Sync/SceneSync.cs index 6f2b379..62e755f 100644 --- a/BoneSync/Sync/SceneSync.cs +++ b/BoneSync/Sync/SceneSync.cs @@ -16,6 +16,9 @@ namespace BoneSync.Sync { private static List scenes = new List(); private static string _currentSceneName; + private static int _currentSceneIndex; + + public static int CurrentSceneIndex => _currentSceneIndex; public static string CurrentSceneDisplayName { @@ -66,6 +69,7 @@ namespace BoneSync.Sync public static void OnSceneInit(int buildIndex) { Scene scene = SceneManager.GetSceneByBuildIndex(buildIndex); + _currentSceneIndex = buildIndex; string SceneName = scene.name; _currentSceneName = SceneName; MelonLogger.Msg("Scene initialized: " + SceneName);