From fc744fd1abc4d088fd8c6e4a35bbc96de5c47569 Mon Sep 17 00:00:00 2001 From: Aaro Varis Date: Sun, 2 Mar 2025 11:45:15 +0200 Subject: [PATCH] network stuff --- BoneSync/BoneSync.csproj | 2 + BoneSync/Networking/ByteEncoder.cs | 48 ++++++++++++++++ .../Messages/DiscardSyncableMessage.cs | 8 +-- .../Messages/ObjectAttributeMessage.cs | 56 +++++++++++++++++++ .../Messages/ObjectDamageMessage.cs | 2 +- .../Messages/OwnershipTransferMessage.cs | 10 ++-- .../Messages/RegisterSyncableMessage.cs | 2 +- BoneSync/Networking/NetworkMessage.cs | 9 +++ BoneSync/Patching/GripPatches.cs | 22 ++++++++ BoneSync/Patching/ObjectHealthPatches.cs | 5 +- .../Sync/Components/SyncableNetworking.cs | 6 +- BoneSync/Sync/ObjectSync.cs | 11 +++- 12 files changed, 162 insertions(+), 19 deletions(-) create mode 100644 BoneSync/Networking/Messages/ObjectAttributeMessage.cs create mode 100644 BoneSync/Patching/GripPatches.cs diff --git a/BoneSync/BoneSync.csproj b/BoneSync/BoneSync.csproj index db495eb..2e7a74b 100644 --- a/BoneSync/BoneSync.csproj +++ b/BoneSync/BoneSync.csproj @@ -85,11 +85,13 @@ + + diff --git a/BoneSync/Networking/ByteEncoder.cs b/BoneSync/Networking/ByteEncoder.cs index 68628b7..668a19c 100644 --- a/BoneSync/Networking/ByteEncoder.cs +++ b/BoneSync/Networking/ByteEncoder.cs @@ -8,6 +8,40 @@ using System.Threading.Tasks; namespace BoneSync.Networking { + public static class BitPacking + { + public static byte[] PackBits(bool[] bits) + { + int byteCount = bits.Length / 8; + if (bits.Length % 8 != 0) + { + byteCount++; + } + byte[] bytes = new byte[byteCount]; + for (int i = 0; i < bits.Length; i++) + { + int byteIndex = i / 8; + int bitIndex = i % 8; + if (bits[i]) + { + bytes[byteIndex] |= (byte)(1 << bitIndex); + } + } + return bytes; + } + + public static bool[] UnpackBits(byte[] bytes, int bitCount) + { + bool[] bits = new bool[bitCount]; + for (int i = 0; i < bitCount; i++) + { + int byteIndex = i / 8; + int bitIndex = i % 8; + bits[i] = (bytes[byteIndex] & (1 << bitIndex)) != 0; + } + return bits; + } + } internal class ByteEncoder { public List Data; @@ -203,5 +237,19 @@ namespace BoneSync.Networking } return matrix; } + + public void WriteBoolArray(bool[] array) + { + byte[] bytes = BitPacking.PackBits(array); + WriteByte((byte)bytes.Length); + WriteBytes(bytes); + } + + public bool[] ReadBoolArray() + { + byte length = ReadByte(); + byte[] bytes = ReadBytes(length); + return BitPacking.UnpackBits(bytes, length); + } } } diff --git a/BoneSync/Networking/Messages/DiscardSyncableMessage.cs b/BoneSync/Networking/Messages/DiscardSyncableMessage.cs index 8dbf470..f845296 100644 --- a/BoneSync/Networking/Messages/DiscardSyncableMessage.cs +++ b/BoneSync/Networking/Messages/DiscardSyncableMessage.cs @@ -10,7 +10,7 @@ namespace BoneSync.Networking.Messages { public struct DiscardSyncableMessageData { - public ushort syncableId; + public ushort syncId; } [PacketType(PacketType.DiscardSyncable), PacketReliability(PacketReliability.ReliableFast)] internal class DiscardSyncableMessage : NetworkMessage @@ -20,18 +20,18 @@ namespace BoneSync.Networking.Messages public DiscardSyncableMessage(DiscardSyncableMessageData discardSyncableMessageData) { _data = discardSyncableMessageData; - byteEncoder.WriteUShort(_data.syncableId); + byteEncoder.WriteUShort(_data.syncId); } public DiscardSyncableMessage(Packet packet) { byteEncoder.WriteBytes(packet.Data); - _data.syncableId = byteEncoder.ReadUShort(); + _data.syncId = byteEncoder.ReadUShort(); } public override void Execute() { - Syncable syncable = ObjectSyncCache.GetSyncable(_data.syncableId); + Syncable syncable = ObjectSyncCache.GetSyncable(_data.syncId); if (syncable != null) { syncable.DiscardSyncable(true); diff --git a/BoneSync/Networking/Messages/ObjectAttributeMessage.cs b/BoneSync/Networking/Messages/ObjectAttributeMessage.cs new file mode 100644 index 0000000..214eae5 --- /dev/null +++ b/BoneSync/Networking/Messages/ObjectAttributeMessage.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BoneSync.Networking.Messages +{ + public struct ObjectMagazineData + { + public byte ammoCount; + } + public struct ObjectAttributeMessageData + { + public ushort syncId; + public bool[] _attributes; + public ObjectMagazineData? magazineData; + } + internal class ObjectAttributeMessage : NetworkMessage + { + private ObjectAttributeMessageData _data; + + public ObjectAttributeMessage(ObjectAttributeMessageData objectAttributeMessageData) + { + List attributes = new List(); + _data = objectAttributeMessageData; + byteEncoder.WriteUShort(_data.syncId); + + attributes.Add(_data.magazineData != null); + if (_data.magazineData != null) + { + byteEncoder.WriteByte(_data.magazineData.Value.ammoCount); + } + + _data._attributes = attributes.ToArray(); + + + } + + public ObjectAttributeMessage(Packet packet) + { + byteEncoder.WriteBytes(packet.Data); + _data.syncId = byteEncoder.ReadUShort(); + _data._attributes = byteEncoder.ReadBoolArray(); + + if (_data._attributes[0]) + { + _data.magazineData = new ObjectMagazineData() + { + ammoCount = byteEncoder.ReadByte(), + }; + } + } + + } +} diff --git a/BoneSync/Networking/Messages/ObjectDamageMessage.cs b/BoneSync/Networking/Messages/ObjectDamageMessage.cs index c3308df..5369089 100644 --- a/BoneSync/Networking/Messages/ObjectDamageMessage.cs +++ b/BoneSync/Networking/Messages/ObjectDamageMessage.cs @@ -41,7 +41,7 @@ namespace BoneSync.Networking.Messages public ObjectHealthInfo objectHealthInfo; } - [PacketType(PacketType.ObjectEvent), PacketReliability(PacketReliability.Unreliable)] + [PacketType(PacketType.ObjectEvent), PacketReliability(PacketReliability.Unreliable), PacketCatchup(4)] public class ObjectDamageMessage : NetworkMessage { public ObjectDamageInfo objectEventInfo => _objectEventInfo; diff --git a/BoneSync/Networking/Messages/OwnershipTransferMessage.cs b/BoneSync/Networking/Messages/OwnershipTransferMessage.cs index 66ff587..014c986 100644 --- a/BoneSync/Networking/Messages/OwnershipTransferMessage.cs +++ b/BoneSync/Networking/Messages/OwnershipTransferMessage.cs @@ -9,19 +9,19 @@ namespace BoneSync.Networking.Messages { public struct OwnershipTransferMessageData { - public ushort SyncId; + public ushort syncId; public bool force; public ulong NewOwnerId; } - [PacketType(PacketType.ObjectOwnership), PacketReliability(PacketReliability.ReliableFast)] + [PacketType(PacketType.ObjectOwnership), PacketReliability(PacketReliability.ReliableFast), PacketCatchup(2)] internal class OwnershipTransferMessage : NetworkMessage { private OwnershipTransferMessageData Data; public OwnershipTransferMessage(OwnershipTransferMessageData data) { Data = data; - byteEncoder.WriteUShort(Data.SyncId); + byteEncoder.WriteUShort(Data.syncId); byteEncoder.WriteULong(Data.NewOwnerId); byteEncoder.WriteBool(Data.force); } @@ -29,14 +29,14 @@ namespace BoneSync.Networking.Messages public OwnershipTransferMessage(Packet packet) { byteEncoder.WriteBytes(packet.Data); - Data.SyncId = byteEncoder.ReadUShort(); + Data.syncId = byteEncoder.ReadUShort(); Data.NewOwnerId = byteEncoder.ReadULong(); Data.force = byteEncoder.ReadBool(); } override public void Execute() { - ObjectSync.OnOwnershipChangeMessage(Data.SyncId, Data.NewOwnerId, Data.force); + ObjectSync.OnOwnershipChangeMessage(Data.syncId, Data.NewOwnerId, Data.force); } } diff --git a/BoneSync/Networking/Messages/RegisterSyncableMessage.cs b/BoneSync/Networking/Messages/RegisterSyncableMessage.cs index 4b217d8..0726fff 100644 --- a/BoneSync/Networking/Messages/RegisterSyncableMessage.cs +++ b/BoneSync/Networking/Messages/RegisterSyncableMessage.cs @@ -29,7 +29,7 @@ namespace BoneSync.Networking.Messages public SpawnPoolableInfo? spawnInfo; } - [PacketType(PacketType.RegisterSyncable), PacketReliability(PacketReliability.ReliableFast)] + [PacketType(PacketType.RegisterSyncable), PacketReliability(PacketReliability.ReliableFast), PacketCatchup(0)] internal class RegisterSyncableMessage : NetworkMessage { private RegisterSyncableInfo _info; diff --git a/BoneSync/Networking/NetworkMessage.cs b/BoneSync/Networking/NetworkMessage.cs index 7ca5dc9..ddd0d5e 100644 --- a/BoneSync/Networking/NetworkMessage.cs +++ b/BoneSync/Networking/NetworkMessage.cs @@ -33,6 +33,15 @@ namespace BoneSync.Networking public PacketReliability reliability { get; } } + public class PacketCatchupAttribute : Attribute + { + public int order { get; } + public PacketCatchupAttribute(int order = 1) + { + this.order = order; + } + } + public abstract class NetworkMessage { public ulong senderId diff --git a/BoneSync/Patching/GripPatches.cs b/BoneSync/Patching/GripPatches.cs new file mode 100644 index 0000000..707c59c --- /dev/null +++ b/BoneSync/Patching/GripPatches.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BoneSync.Sync; +using HarmonyLib; +using StressLevelZero.Interaction; +namespace BoneSync.Patching +{ + [HarmonyPatch(typeof(ForcePullGrip))] + internal class ForcePullGripPatches + { + [HarmonyPatch(nameof(ForcePullGrip.Pull)), HarmonyPostfix] + public static void OnEnablePatch(ForcePullGrip __instance) + { + MelonLoader.MelonLogger.Msg("ForcePullGrip.Pull: " + __instance.name); + ObjectSync.MakeOrGetSyncable(__instance.gameObject); + } + + } +} diff --git a/BoneSync/Patching/ObjectHealthPatches.cs b/BoneSync/Patching/ObjectHealthPatches.cs index 24f3ec1..c1f9b98 100644 --- a/BoneSync/Patching/ObjectHealthPatches.cs +++ b/BoneSync/Patching/ObjectHealthPatches.cs @@ -23,12 +23,13 @@ namespace BoneSync.Patching private static bool TakeDamagePatch(ObjectDestructable __instance, ref Vector3 normal, ref float damage, ref bool crit, ref AttackType attackType) { if (CallPatchedMethods.allowPatchedMethodCall) return true; + if (damage < 0.05f) return true; // ignore small damage (e.g. a little bit of fall damage) MelonLoader.MelonLogger.Msg("ObjectDestructable.TakeDamage: " + damage); Syncable syncable = ObjectSync.MakeOrGetSyncable(__instance.gameObject); if (syncable != null) { - if (damage > 0.5f) syncable.RegisterSyncable(); - if (!syncable.isOwner) return true; + if (damage > 0.5f) syncable.RegisterSyncable(); // register syncable if damage is very significant, e.g. a bullet hit + if (!syncable.isOwner) return false; MelonLoader.MelonLogger.Msg("Patch: ObjectDestructable.TakeDamage: " + damage + " " + syncable.gameObject.name); ObjectHealthInfo objectHealthInfo = new ObjectHealthInfo(__instance._health, __instance._hits, normal, damage, crit, attackType); diff --git a/BoneSync/Sync/Components/SyncableNetworking.cs b/BoneSync/Sync/Components/SyncableNetworking.cs index 3bb82a7..4cf50f0 100644 --- a/BoneSync/Sync/Components/SyncableNetworking.cs +++ b/BoneSync/Sync/Components/SyncableNetworking.cs @@ -60,7 +60,7 @@ namespace BoneSync.Sync.Components { DiscardSyncableMessageData discardSyncableMessageData = new DiscardSyncableMessageData() { - syncableId = _syncId + syncId = _syncId }; DiscardSyncableMessage discardSyncableMessage = new DiscardSyncableMessage(discardSyncableMessageData); discardSyncableMessage.Broadcast(); @@ -73,7 +73,7 @@ namespace BoneSync.Sync.Components MelonLogger.Msg("Sending ownership transfer for " + _syncId + " to " + newOwnerId); OwnershipTransferMessageData data = new OwnershipTransferMessageData() { - SyncId = _syncId, + syncId = _syncId, NewOwnerId = newOwnerId, force = true }; @@ -90,7 +90,7 @@ namespace BoneSync.Sync.Components MelonLogger.Msg("Attempting to become owner of " + _syncId); OwnershipTransferMessageData data = new OwnershipTransferMessageData() { - SyncId = _syncId, + syncId = _syncId, NewOwnerId = BoneSync.lobby.GetLocalId(), force = false }; diff --git a/BoneSync/Sync/ObjectSync.cs b/BoneSync/Sync/ObjectSync.cs index 813f619..839afc5 100644 --- a/BoneSync/Sync/ObjectSync.cs +++ b/BoneSync/Sync/ObjectSync.cs @@ -105,7 +105,12 @@ namespace BoneSync.Sync //Scene scene = gameObject.scene; //MelonLogger.Msg("Making or getting syncable for: " + gameObject.name + " in scene: " + scene.name); - + Syncable parentSyncable = gameObject.transform.parent.GetComponentInParent(); + if (parentSyncable != null) + { + return parentSyncable; + } + Syncable syncable = gameObject.GetComponent(); // delete all sub syncables @@ -128,7 +133,7 @@ namespace BoneSync.Sync return syncable; } - public static Syncable GetSyncableFromCache(GameObject gameObject) + private static Syncable _GetSyncableFromCache(GameObject gameObject) { bool success = Syncable.syncablesCache.TryGetValue(gameObject, out Syncable syncable); if (!success) @@ -140,7 +145,7 @@ namespace BoneSync.Sync public static Syncable MakeOrGetSyncable(GameObject gameObject) { - Syncable syncable = GetSyncableFromCache(gameObject); + Syncable syncable = _GetSyncableFromCache(gameObject); if (syncable == null) { syncable = _MakeOrGetSyncable(gameObject);