network stuff
This commit is contained in:
@@ -85,11 +85,13 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Networking\Messages\DiscardSyncableMessage.cs" />
|
<Compile Include="Networking\Messages\DiscardSyncableMessage.cs" />
|
||||||
|
<Compile Include="Networking\Messages\ObjectAttributeMessage.cs" />
|
||||||
<Compile Include="Networking\Messages\ObjectDamageMessage.cs" />
|
<Compile Include="Networking\Messages\ObjectDamageMessage.cs" />
|
||||||
<Compile Include="Networking\Messages\ObjectSyncMessage.cs" />
|
<Compile Include="Networking\Messages\ObjectSyncMessage.cs" />
|
||||||
<Compile Include="Networking\Messages\OwnershipTransferMessage.cs" />
|
<Compile Include="Networking\Messages\OwnershipTransferMessage.cs" />
|
||||||
<Compile Include="Networking\Messages\RegisterSyncableMessage.cs" />
|
<Compile Include="Networking\Messages\RegisterSyncableMessage.cs" />
|
||||||
<Compile Include="Patching\CallPatchedMethod.cs" />
|
<Compile Include="Patching\CallPatchedMethod.cs" />
|
||||||
|
<Compile Include="Patching\GripPatches.cs" />
|
||||||
<Compile Include="Patching\InteractableHostPatches.cs" />
|
<Compile Include="Patching\InteractableHostPatches.cs" />
|
||||||
<Compile Include="Patching\ObjectHealthPatches.cs" />
|
<Compile Include="Patching\ObjectHealthPatches.cs" />
|
||||||
<Compile Include="Sync\Components\SyncableBase.cs" />
|
<Compile Include="Sync\Components\SyncableBase.cs" />
|
||||||
|
|||||||
@@ -8,6 +8,40 @@ using System.Threading.Tasks;
|
|||||||
|
|
||||||
namespace BoneSync.Networking
|
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
|
internal class ByteEncoder
|
||||||
{
|
{
|
||||||
public List<byte> Data;
|
public List<byte> Data;
|
||||||
@@ -203,5 +237,19 @@ namespace BoneSync.Networking
|
|||||||
}
|
}
|
||||||
return matrix;
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace BoneSync.Networking.Messages
|
|||||||
{
|
{
|
||||||
public struct DiscardSyncableMessageData
|
public struct DiscardSyncableMessageData
|
||||||
{
|
{
|
||||||
public ushort syncableId;
|
public ushort syncId;
|
||||||
}
|
}
|
||||||
[PacketType(PacketType.DiscardSyncable), PacketReliability(PacketReliability.ReliableFast)]
|
[PacketType(PacketType.DiscardSyncable), PacketReliability(PacketReliability.ReliableFast)]
|
||||||
internal class DiscardSyncableMessage : NetworkMessage
|
internal class DiscardSyncableMessage : NetworkMessage
|
||||||
@@ -20,18 +20,18 @@ namespace BoneSync.Networking.Messages
|
|||||||
public DiscardSyncableMessage(DiscardSyncableMessageData discardSyncableMessageData)
|
public DiscardSyncableMessage(DiscardSyncableMessageData discardSyncableMessageData)
|
||||||
{
|
{
|
||||||
_data = discardSyncableMessageData;
|
_data = discardSyncableMessageData;
|
||||||
byteEncoder.WriteUShort(_data.syncableId);
|
byteEncoder.WriteUShort(_data.syncId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public DiscardSyncableMessage(Packet packet)
|
public DiscardSyncableMessage(Packet packet)
|
||||||
{
|
{
|
||||||
byteEncoder.WriteBytes(packet.Data);
|
byteEncoder.WriteBytes(packet.Data);
|
||||||
_data.syncableId = byteEncoder.ReadUShort();
|
_data.syncId = byteEncoder.ReadUShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Execute()
|
public override void Execute()
|
||||||
{
|
{
|
||||||
Syncable syncable = ObjectSyncCache.GetSyncable(_data.syncableId);
|
Syncable syncable = ObjectSyncCache.GetSyncable(_data.syncId);
|
||||||
if (syncable != null)
|
if (syncable != null)
|
||||||
{
|
{
|
||||||
syncable.DiscardSyncable(true);
|
syncable.DiscardSyncable(true);
|
||||||
|
|||||||
56
BoneSync/Networking/Messages/ObjectAttributeMessage.cs
Normal file
56
BoneSync/Networking/Messages/ObjectAttributeMessage.cs
Normal file
@@ -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<bool> attributes = new List<bool>();
|
||||||
|
_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(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -41,7 +41,7 @@ namespace BoneSync.Networking.Messages
|
|||||||
public ObjectHealthInfo objectHealthInfo;
|
public ObjectHealthInfo objectHealthInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
[PacketType(PacketType.ObjectEvent), PacketReliability(PacketReliability.Unreliable)]
|
[PacketType(PacketType.ObjectEvent), PacketReliability(PacketReliability.Unreliable), PacketCatchup(4)]
|
||||||
public class ObjectDamageMessage : NetworkMessage
|
public class ObjectDamageMessage : NetworkMessage
|
||||||
{
|
{
|
||||||
public ObjectDamageInfo objectEventInfo => _objectEventInfo;
|
public ObjectDamageInfo objectEventInfo => _objectEventInfo;
|
||||||
|
|||||||
@@ -9,19 +9,19 @@ namespace BoneSync.Networking.Messages
|
|||||||
{
|
{
|
||||||
public struct OwnershipTransferMessageData
|
public struct OwnershipTransferMessageData
|
||||||
{
|
{
|
||||||
public ushort SyncId;
|
public ushort syncId;
|
||||||
public bool force;
|
public bool force;
|
||||||
public ulong NewOwnerId;
|
public ulong NewOwnerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
[PacketType(PacketType.ObjectOwnership), PacketReliability(PacketReliability.ReliableFast)]
|
[PacketType(PacketType.ObjectOwnership), PacketReliability(PacketReliability.ReliableFast), PacketCatchup(2)]
|
||||||
internal class OwnershipTransferMessage : NetworkMessage
|
internal class OwnershipTransferMessage : NetworkMessage
|
||||||
{
|
{
|
||||||
private OwnershipTransferMessageData Data;
|
private OwnershipTransferMessageData Data;
|
||||||
public OwnershipTransferMessage(OwnershipTransferMessageData data)
|
public OwnershipTransferMessage(OwnershipTransferMessageData data)
|
||||||
{
|
{
|
||||||
Data = data;
|
Data = data;
|
||||||
byteEncoder.WriteUShort(Data.SyncId);
|
byteEncoder.WriteUShort(Data.syncId);
|
||||||
byteEncoder.WriteULong(Data.NewOwnerId);
|
byteEncoder.WriteULong(Data.NewOwnerId);
|
||||||
byteEncoder.WriteBool(Data.force);
|
byteEncoder.WriteBool(Data.force);
|
||||||
}
|
}
|
||||||
@@ -29,14 +29,14 @@ namespace BoneSync.Networking.Messages
|
|||||||
public OwnershipTransferMessage(Packet packet)
|
public OwnershipTransferMessage(Packet packet)
|
||||||
{
|
{
|
||||||
byteEncoder.WriteBytes(packet.Data);
|
byteEncoder.WriteBytes(packet.Data);
|
||||||
Data.SyncId = byteEncoder.ReadUShort();
|
Data.syncId = byteEncoder.ReadUShort();
|
||||||
Data.NewOwnerId = byteEncoder.ReadULong();
|
Data.NewOwnerId = byteEncoder.ReadULong();
|
||||||
Data.force = byteEncoder.ReadBool();
|
Data.force = byteEncoder.ReadBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
override public void Execute()
|
override public void Execute()
|
||||||
{
|
{
|
||||||
ObjectSync.OnOwnershipChangeMessage(Data.SyncId, Data.NewOwnerId, Data.force);
|
ObjectSync.OnOwnershipChangeMessage(Data.syncId, Data.NewOwnerId, Data.force);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace BoneSync.Networking.Messages
|
|||||||
public SpawnPoolableInfo? spawnInfo;
|
public SpawnPoolableInfo? spawnInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
[PacketType(PacketType.RegisterSyncable), PacketReliability(PacketReliability.ReliableFast)]
|
[PacketType(PacketType.RegisterSyncable), PacketReliability(PacketReliability.ReliableFast), PacketCatchup(0)]
|
||||||
internal class RegisterSyncableMessage : NetworkMessage
|
internal class RegisterSyncableMessage : NetworkMessage
|
||||||
{
|
{
|
||||||
private RegisterSyncableInfo _info;
|
private RegisterSyncableInfo _info;
|
||||||
|
|||||||
@@ -33,6 +33,15 @@ namespace BoneSync.Networking
|
|||||||
public PacketReliability reliability { get; }
|
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 abstract class NetworkMessage
|
||||||
{
|
{
|
||||||
public ulong senderId
|
public ulong senderId
|
||||||
|
|||||||
22
BoneSync/Patching/GripPatches.cs
Normal file
22
BoneSync/Patching/GripPatches.cs
Normal file
@@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)
|
private static bool TakeDamagePatch(ObjectDestructable __instance, ref Vector3 normal, ref float damage, ref bool crit, ref AttackType attackType)
|
||||||
{
|
{
|
||||||
if (CallPatchedMethods.allowPatchedMethodCall) return true;
|
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);
|
MelonLoader.MelonLogger.Msg("ObjectDestructable.TakeDamage: " + damage);
|
||||||
Syncable syncable = ObjectSync.MakeOrGetSyncable(__instance.gameObject);
|
Syncable syncable = ObjectSync.MakeOrGetSyncable(__instance.gameObject);
|
||||||
if (syncable != null)
|
if (syncable != null)
|
||||||
{
|
{
|
||||||
if (damage > 0.5f) syncable.RegisterSyncable();
|
if (damage > 0.5f) syncable.RegisterSyncable(); // register syncable if damage is very significant, e.g. a bullet hit
|
||||||
if (!syncable.isOwner) return true;
|
if (!syncable.isOwner) return false;
|
||||||
MelonLoader.MelonLogger.Msg("Patch: ObjectDestructable.TakeDamage: " + damage + " " + syncable.gameObject.name);
|
MelonLoader.MelonLogger.Msg("Patch: ObjectDestructable.TakeDamage: " + damage + " " + syncable.gameObject.name);
|
||||||
ObjectHealthInfo objectHealthInfo = new ObjectHealthInfo(__instance._health, __instance._hits, normal, damage, crit, attackType);
|
ObjectHealthInfo objectHealthInfo = new ObjectHealthInfo(__instance._health, __instance._hits, normal, damage, crit, attackType);
|
||||||
|
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ namespace BoneSync.Sync.Components
|
|||||||
{
|
{
|
||||||
DiscardSyncableMessageData discardSyncableMessageData = new DiscardSyncableMessageData()
|
DiscardSyncableMessageData discardSyncableMessageData = new DiscardSyncableMessageData()
|
||||||
{
|
{
|
||||||
syncableId = _syncId
|
syncId = _syncId
|
||||||
};
|
};
|
||||||
DiscardSyncableMessage discardSyncableMessage = new DiscardSyncableMessage(discardSyncableMessageData);
|
DiscardSyncableMessage discardSyncableMessage = new DiscardSyncableMessage(discardSyncableMessageData);
|
||||||
discardSyncableMessage.Broadcast();
|
discardSyncableMessage.Broadcast();
|
||||||
@@ -73,7 +73,7 @@ namespace BoneSync.Sync.Components
|
|||||||
MelonLogger.Msg("Sending ownership transfer for " + _syncId + " to " + newOwnerId);
|
MelonLogger.Msg("Sending ownership transfer for " + _syncId + " to " + newOwnerId);
|
||||||
OwnershipTransferMessageData data = new OwnershipTransferMessageData()
|
OwnershipTransferMessageData data = new OwnershipTransferMessageData()
|
||||||
{
|
{
|
||||||
SyncId = _syncId,
|
syncId = _syncId,
|
||||||
NewOwnerId = newOwnerId,
|
NewOwnerId = newOwnerId,
|
||||||
force = true
|
force = true
|
||||||
};
|
};
|
||||||
@@ -90,7 +90,7 @@ namespace BoneSync.Sync.Components
|
|||||||
MelonLogger.Msg("Attempting to become owner of " + _syncId);
|
MelonLogger.Msg("Attempting to become owner of " + _syncId);
|
||||||
OwnershipTransferMessageData data = new OwnershipTransferMessageData()
|
OwnershipTransferMessageData data = new OwnershipTransferMessageData()
|
||||||
{
|
{
|
||||||
SyncId = _syncId,
|
syncId = _syncId,
|
||||||
NewOwnerId = BoneSync.lobby.GetLocalId(),
|
NewOwnerId = BoneSync.lobby.GetLocalId(),
|
||||||
force = false
|
force = false
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -105,7 +105,12 @@ namespace BoneSync.Sync
|
|||||||
//Scene scene = gameObject.scene;
|
//Scene scene = gameObject.scene;
|
||||||
//MelonLogger.Msg("Making or getting syncable for: " + gameObject.name + " in scene: " + scene.name);
|
//MelonLogger.Msg("Making or getting syncable for: " + gameObject.name + " in scene: " + scene.name);
|
||||||
|
|
||||||
|
Syncable parentSyncable = gameObject.transform.parent.GetComponentInParent<Syncable>();
|
||||||
|
if (parentSyncable != null)
|
||||||
|
{
|
||||||
|
return parentSyncable;
|
||||||
|
}
|
||||||
|
|
||||||
Syncable syncable = gameObject.GetComponent<Syncable>();
|
Syncable syncable = gameObject.GetComponent<Syncable>();
|
||||||
|
|
||||||
// delete all sub syncables
|
// delete all sub syncables
|
||||||
@@ -128,7 +133,7 @@ namespace BoneSync.Sync
|
|||||||
return syncable;
|
return syncable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Syncable GetSyncableFromCache(GameObject gameObject)
|
private static Syncable _GetSyncableFromCache(GameObject gameObject)
|
||||||
{
|
{
|
||||||
bool success = Syncable.syncablesCache.TryGetValue(gameObject, out Syncable syncable);
|
bool success = Syncable.syncablesCache.TryGetValue(gameObject, out Syncable syncable);
|
||||||
if (!success)
|
if (!success)
|
||||||
@@ -140,7 +145,7 @@ namespace BoneSync.Sync
|
|||||||
|
|
||||||
public static Syncable MakeOrGetSyncable(GameObject gameObject)
|
public static Syncable MakeOrGetSyncable(GameObject gameObject)
|
||||||
{
|
{
|
||||||
Syncable syncable = GetSyncableFromCache(gameObject);
|
Syncable syncable = _GetSyncableFromCache(gameObject);
|
||||||
if (syncable == null)
|
if (syncable == null)
|
||||||
{
|
{
|
||||||
syncable = _MakeOrGetSyncable(gameObject);
|
syncable = _MakeOrGetSyncable(gameObject);
|
||||||
|
|||||||
Reference in New Issue
Block a user