Packet catchup and scene indexes in packets

This commit is contained in:
Aaro Varis
2025-03-09 22:32:47 +02:00
parent 20a624fb0f
commit 3b0c26a687
7 changed files with 94 additions and 15 deletions

View File

@@ -113,6 +113,7 @@ namespace BoneSync
{ {
IsConnected = lobby.IsConnected(); IsConnected = lobby.IsConnected();
transport.Tick(); transport.Tick();
Packet.TryCatchup();
PlayerRig.Tick(); PlayerRig.Tick();
} }

View File

@@ -19,7 +19,7 @@ namespace BoneSync.Networking.Messages
public byte socketIndex; public byte socketIndex;
} }
[PacketType(PacketType.PlugSync), PacketReliability(PacketReliability.ReliableFast)] [PacketType(PacketType.PlugSync), PacketReliability(PacketReliability.ReliableFast), PacketCatchup(10)]
internal class PlugSyncMessage : NetworkMessage internal class PlugSyncMessage : NetworkMessage
{ {
private PlugSyncMessageData messageData; private PlugSyncMessageData messageData;

View File

@@ -30,7 +30,7 @@ namespace BoneSync.Networking.Messages
public SpawnPoolableInfo? spawnInfo; public SpawnPoolableInfo? spawnInfo;
} }
[PacketType(PacketType.RegisterSyncable), PacketReliability(PacketReliability.ReliableFast), PacketCatchup(0)] [PacketType(PacketType.RegisterSyncable), PacketReliability(PacketReliability.ReliableFast), PacketCatchup(1)]
internal class RegisterSyncableMessage : NetworkMessage internal class RegisterSyncableMessage : NetworkMessage
{ {
private RegisterSyncableInfo _info; private RegisterSyncableInfo _info;

View File

@@ -1,5 +1,6 @@
using BoneSync.Data; using BoneSync.Data;
using BoneSync.Networking.Transport; using BoneSync.Networking.Transport;
using BoneSync.Sync;
using MelonLoader; using MelonLoader;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -37,12 +38,20 @@ namespace BoneSync.Networking
public class PacketCatchupAttribute : Attribute public class PacketCatchupAttribute : Attribute
{ {
public int order { get; } public int order { get; }
public PacketCatchupAttribute(int order = 1) public PacketCatchupAttribute(int order)
{ {
this.order = order; this.order = order;
} }
} }
public class AlwaysExecuteAttribute : Attribute
{
public AlwaysExecuteAttribute()
{
}
}
public abstract class NetworkMessage public abstract class NetworkMessage
{ {
public ulong senderId public ulong senderId
@@ -56,10 +65,19 @@ namespace BoneSync.Networking
internal PacketType _packetType; internal PacketType _packetType;
internal PacketReliability? _reliability; internal PacketReliability? _reliability;
internal int? _catchupOrder;
internal bool? _alwaysExecute;
internal ByteEncoder byteEncoder = new ByteEncoder(); internal ByteEncoder byteEncoder = new ByteEncoder();
public byte[] GetBytes() => byteEncoder.ToArray(); public byte[] GetBytes() => byteEncoder.ToArray();
public bool GetAlwaysExecute()
{
if (_alwaysExecute.HasValue) return _alwaysExecute.Value;
AlwaysExecuteAttribute alwaysExecuteAttribute = GetType().GetCustomAttribute<AlwaysExecuteAttribute>();
_alwaysExecute = alwaysExecuteAttribute != null;
return _alwaysExecute.Value;
}
public PacketType GetPacketType() public PacketType GetPacketType()
{ {
RegisterPacketTypes(); RegisterPacketTypes();
@@ -76,6 +94,20 @@ namespace BoneSync.Networking
return _packetType; return _packetType;
} }
public int GetCatchupOrder()
{
if (_catchupOrder.HasValue) return _catchupOrder.Value;
PacketCatchupAttribute catchupAttribute = GetType().GetCustomAttribute<PacketCatchupAttribute>();
if (catchupAttribute == null)
{
_catchupOrder = -1;
return -1;
}
_catchupOrder = catchupAttribute.order;
return _catchupOrder.Value;
}
public PacketReliability GetPacketReliability() public PacketReliability GetPacketReliability()
{ {
if (_reliability.HasValue) return _reliability.Value; if (_reliability.HasValue) return _reliability.Value;
@@ -130,7 +162,7 @@ namespace BoneSync.Networking
public Packet GetPacket(ulong senderId, ulong receiverId) 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()); Packet packet = new Packet(packetInfo, GetBytes());
return packet; return packet;
} }

View File

@@ -1,5 +1,6 @@
using BoneSync.Data; using BoneSync.Data;
using BoneSync.Networking.Messages; using BoneSync.Networking.Messages;
using BoneSync.Sync;
using Facepunch.Steamworks; using Facepunch.Steamworks;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -24,6 +25,7 @@ namespace BoneSync.Networking
public ulong id; public ulong id;
public ulong senderId; public ulong senderId;
public ulong receiverId; public ulong receiverId;
public byte sceneIndex;
public PacketType packetType; public PacketType packetType;
public PacketReliability reliability; public PacketReliability reliability;
@@ -31,8 +33,9 @@ namespace BoneSync.Networking
ulong senderId, ulong senderId,
ulong receiverId, ulong receiverId,
PacketType packetType, PacketType packetType,
PacketReliability reliability = PacketReliability.Reliable, PacketReliability reliability,
ulong id = 0 ulong id,
byte sceneIndex
) )
{ {
this.senderId = senderId; this.senderId = senderId;
@@ -40,11 +43,13 @@ namespace BoneSync.Networking
this.packetType = packetType; this.packetType = packetType;
this.reliability = reliability; this.reliability = reliability;
this.id = id == 0 ? Packet.GenerateId() : id; this.id = id == 0 ? Packet.GenerateId() : id;
this.sceneIndex = sceneIndex;
} }
} }
public class Packet public class Packet
{ {
private static Dictionary<byte, Queue<NetworkMessage>> _packetQueues = new Dictionary<byte, Queue<NetworkMessage>>();
private static ulong _packetId = 1; private static ulong _packetId = 1;
private static Dictionary<ulong, Dictionary<PacketType, ulong>> _latestPacketIds = new Dictionary<ulong, Dictionary<PacketType, ulong>>(); private static Dictionary<ulong, Dictionary<PacketType, ulong>> _latestPacketIds = new Dictionary<ulong, Dictionary<PacketType, ulong>>();
@@ -93,11 +98,12 @@ namespace BoneSync.Networking
byte packetType = byteEncoder.ReadByte(); byte packetType = byteEncoder.ReadByte();
byte reliability = byteEncoder.ReadByte(); byte reliability = byteEncoder.ReadByte();
byte sceneIndex = byteEncoder.ReadByte();
ulong id = byteEncoder.ReadULong(); ulong id = byteEncoder.ReadULong();
ulong senderId = byteEncoder.ReadULong(); ulong senderId = byteEncoder.ReadULong();
ulong receiverId = 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()); return new Packet(packetInfo, byteEncoder.ToArray());
} }
@@ -106,6 +112,7 @@ namespace BoneSync.Networking
ByteEncoder byteEncoder = new ByteEncoder(); ByteEncoder byteEncoder = new ByteEncoder();
byteEncoder.WriteByte((byte)_packetInfo.packetType); byteEncoder.WriteByte((byte)_packetInfo.packetType);
byteEncoder.WriteByte((byte)_packetInfo.reliability); byteEncoder.WriteByte((byte)_packetInfo.reliability);
byteEncoder.WriteByte(_packetInfo.sceneIndex);
byteEncoder.WriteULong(_packetInfo.id); byteEncoder.WriteULong(_packetInfo.id);
byteEncoder.WriteULong(_packetInfo.senderId); byteEncoder.WriteULong(_packetInfo.senderId);
byteEncoder.WriteULong(_packetInfo.receiverId); byteEncoder.WriteULong(_packetInfo.receiverId);
@@ -113,6 +120,14 @@ namespace BoneSync.Networking
return byteEncoder.ToArray(); return byteEncoder.ToArray();
} }
private static void EnsureQueueForScene(byte sceneIndex)
{
if (!_packetQueues.ContainsKey(sceneIndex))
{
_packetQueues.Add(sceneIndex, new Queue<NetworkMessage>());
}
}
public static bool OnPacketReceived(Packet packet) public static bool OnPacketReceived(Packet packet)
{ {
if (packet._packetInfo.reliability == PacketReliability.ReliableFast) if (packet._packetInfo.reliability == PacketReliability.ReliableFast)
@@ -125,10 +140,42 @@ namespace BoneSync.Networking
} }
NetworkMessage networkMessage = NetworkMessage.ParsePacket(packet); 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(); networkMessage.Execute();
return true; 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<NetworkMessage> queue = _packetQueues[sceneIndex];
int processed = 0;
while (queue.Count > 0 && processed < 10)
{
processed++;
NetworkMessage networkMessage = queue.Dequeue();
networkMessage.Execute();
}
}
public byte[] Data => _dataBytes; public byte[] Data => _dataBytes;
public static ulong GenerateId() public static ulong GenerateId()

View File

@@ -78,6 +78,7 @@ namespace BoneSync.Player
public void UpdatePlayerSync(PlayerSyncInfo playerSyncInfo) public void UpdatePlayerSync(PlayerSyncInfo playerSyncInfo)
{ {
EnsurePlayerRig();
//MelonLogger.Msg("Updating player sync for " + _ownerId); //MelonLogger.Msg("Updating player sync for " + _ownerId);
playerRig.transform.position = playerSyncInfo.rootPos; playerRig.transform.position = playerSyncInfo.rootPos;
@@ -224,13 +225,7 @@ namespace BoneSync.Player
// Catch errors so other players arent broken // Catch errors so other players arent broken
try try
{ {
EnsurePlayerRig(); if (body == null || characterAnimationManager == null || animator == null || playerRig == null) return;
//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;
animator.Update(Time.fixedDeltaTime); animator.Update(Time.fixedDeltaTime);
characterAnimationManager.OnLateUpdate(); characterAnimationManager.OnLateUpdate();

View File

@@ -16,6 +16,9 @@ namespace BoneSync.Sync
{ {
private static List<Scene> scenes = new List<Scene>(); private static List<Scene> scenes = new List<Scene>();
private static string _currentSceneName; private static string _currentSceneName;
private static int _currentSceneIndex;
public static int CurrentSceneIndex => _currentSceneIndex;
public static string CurrentSceneDisplayName public static string CurrentSceneDisplayName
{ {
@@ -66,6 +69,7 @@ namespace BoneSync.Sync
public static void OnSceneInit(int buildIndex) public static void OnSceneInit(int buildIndex)
{ {
Scene scene = SceneManager.GetSceneByBuildIndex(buildIndex); Scene scene = SceneManager.GetSceneByBuildIndex(buildIndex);
_currentSceneIndex = buildIndex;
string SceneName = scene.name; string SceneName = scene.name;
_currentSceneName = SceneName; _currentSceneName = SceneName;
MelonLogger.Msg("Scene initialized: " + SceneName); MelonLogger.Msg("Scene initialized: " + SceneName);