diff --git a/BoneSync/BoneSync.csproj b/BoneSync/BoneSync.csproj
index 2e7a74b..fa7a262 100644
--- a/BoneSync/BoneSync.csproj
+++ b/BoneSync/BoneSync.csproj
@@ -84,20 +84,27 @@
+
+
+
-
+
+
+
+
+
@@ -254,13 +261,11 @@
-
-
diff --git a/BoneSync/Data/ByteEncoder.cs b/BoneSync/Data/ByteEncoder.cs
index 4baada6..49a6874 100644
--- a/BoneSync/Data/ByteEncoder.cs
+++ b/BoneSync/Data/ByteEncoder.cs
@@ -214,12 +214,6 @@ namespace BoneSync.Data
};
}
- public void WriteSLZAttack(Attack attack)
- {
- WriteByte((byte)attack.attackType);
- WriteFloat(attack.damage);
- }
-
public void WriteMatrix4x4(UnityEngine.Matrix4x4 matrix)
{
for (int i = 0; i < 16; i++)
@@ -251,5 +245,62 @@ namespace BoneSync.Data
byte[] bytes = ReadBytes(length);
return BitPacking.UnpackBits(bytes, length);
}
+
+ public void WriteAmmoVariables(AmmoVariables ammoVariables)
+ {
+ WriteBool(ammoVariables.Tracer);
+ WriteFloat(ammoVariables.ProjectileMass);
+ WriteFloat(ammoVariables.ExitVelocity);
+ WriteFloat(ammoVariables.AttackDamage);
+ WriteByte((byte)ammoVariables.AttackType);
+ WriteByte((byte)ammoVariables.cartridgeType);
+ }
+
+ public AmmoVariables ReadAmmoVariables()
+ {
+ AmmoVariables ammoVariables = new AmmoVariables()
+ {
+ Tracer = ReadBool(),
+ ProjectileMass = ReadFloat(),
+ ExitVelocity = ReadFloat(),
+ AttackDamage = ReadFloat(),
+ AttackType = (AttackType)ReadByte(),
+ cartridgeType = (Cart)ReadByte()
+ };
+ return ammoVariables;
+ }
+
+ public void WriteMagazineData(MagazineData magazineData)
+ {
+ WriteByte((byte)magazineData.weight);
+ WriteByte((byte)magazineData.platform);
+ WriteUShort((byte)magazineData.cartridgeType);
+ BulletObject[] bulletObjects = magazineData.AmmoSlots;
+ WriteByte((byte)bulletObjects.Length);
+ for (int i = 0; i < bulletObjects.Length; i++)
+ {
+ WriteAmmoVariables(bulletObjects[i].ammoVariables);
+ }
+ }
+
+ public MagazineData ReadMagazineData()
+ {
+ MagazineData mag = new MagazineData();
+ mag.weight = (Weight)ReadByte();
+ mag.platform = (Platform)ReadByte();
+ mag.cartridgeType = (Cart)ReadUShort();
+ byte bulletCount = ReadByte();
+
+ mag.AmmoSlots = new BulletObject[bulletCount];
+ for (int i = 0; i < bulletCount; i++)
+ {
+ mag.AmmoSlots[i] = new BulletObject()
+ {
+ ammoVariables = ReadAmmoVariables()
+ };
+ }
+
+ return mag;
+ }
}
}
diff --git a/BoneSync/Networking/Messages/MagazineSyncMessage.cs b/BoneSync/Networking/Messages/MagazineSyncMessage.cs
new file mode 100644
index 0000000..023dd7a
--- /dev/null
+++ b/BoneSync/Networking/Messages/MagazineSyncMessage.cs
@@ -0,0 +1,43 @@
+using BoneSync.Sync;
+using BoneSync.Sync.Components;
+using StressLevelZero.Combat;
+using StressLevelZero.Props.Weapons;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BoneSync.Networking.Messages
+{
+ public struct MagazineSyncData
+ {
+ public ushort syncId;
+ public MagazineData magazineData;
+ }
+
+ [PacketType(PacketType.MagazineSync), PacketReliability(PacketReliability.Unreliable)]
+ public class MagazineSyncMessage : NetworkMessage
+ {
+ public MagazineSyncData magazineData;
+
+ public MagazineSyncMessage(MagazineSyncData magazineData)
+ {
+ this.magazineData = magazineData;
+ byteEncoder.WriteMagazineData(magazineData.magazineData);
+ }
+
+ public MagazineSyncMessage(Packet packet)
+ {
+ byteEncoder.WriteBytes(packet.Data);
+ magazineData = new MagazineSyncData();
+ }
+
+ public override void Execute()
+ {
+ Syncable syncable = ObjectSyncCache.GetSyncable(magazineData.syncId);
+ if (!syncable) return;
+ syncable.ApplyMagazineData(magazineData.magazineData);
+ }
+ }
+}
diff --git a/BoneSync/Networking/Messages/ObjectAttributeMessage.cs b/BoneSync/Networking/Messages/ObjectAttributeMessage.cs
deleted file mode 100644
index 5dbb0df..0000000
--- a/BoneSync/Networking/Messages/ObjectAttributeMessage.cs
+++ /dev/null
@@ -1,58 +0,0 @@
-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;
- }
-
- [PacketType(PacketType.ObjectAttribute), PacketReliability(PacketReliability.ReliableFast)]
- 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.HasValue);
- if (_data.magazineData.HasValue)
- {
- 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 5369089..d4810ea 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), PacketCatchup(4)]
+ [PacketType(PacketType.ObjectDamageEvent), PacketReliability(PacketReliability.Unreliable), PacketCatchup(4)]
public class ObjectDamageMessage : NetworkMessage
{
public ObjectDamageInfo objectEventInfo => _objectEventInfo;
diff --git a/BoneSync/Networking/PacketTypes.cs b/BoneSync/Networking/PacketTypes.cs
index 3706946..62b07fd 100644
--- a/BoneSync/Networking/PacketTypes.cs
+++ b/BoneSync/Networking/PacketTypes.cs
@@ -13,9 +13,9 @@ namespace BoneSync.Networking
PlayerSync = 2,
RegisterSyncable = 3,
ObjectSync = 4,
- ObjectEvent = 5,
+ ObjectDamageEvent = 5,
ObjectOwnership = 6,
DiscardSyncable = 7,
- ObjectAttribute = 8,
+ MagazineSync = 8,
}
}
diff --git a/BoneSync/Patching/GunPatches.cs b/BoneSync/Patching/GunPatches.cs
new file mode 100644
index 0000000..5010275
--- /dev/null
+++ b/BoneSync/Patching/GunPatches.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using HarmonyLib;
+using StressLevelZero.Props.Weapons;
+
+namespace BoneSync.Patching
+{
+
+ [HarmonyPatch(typeof(Gun))]
+ public class GunPatches
+ {
+ [HarmonyPatch(nameof(Gun.Fire)), HarmonyPostfix]
+ public static void FirePatch(Gun __instance)
+ {
+ MelonLoader.MelonLogger.Msg("Gun fired: " + __instance.name);
+ }
+
+ }
+}
diff --git a/BoneSync/Patching/ObjectHealthPatches.cs b/BoneSync/Patching/ObjectHealthPatches.cs
index b36c01b..fb7085f 100644
--- a/BoneSync/Patching/ObjectHealthPatches.cs
+++ b/BoneSync/Patching/ObjectHealthPatches.cs
@@ -30,7 +30,7 @@ namespace BoneSync.Patching
if (syncable != null)
{
if (damage > 0.5f) syncable.RegisterSyncable(); // register syncable if damage is very significant, e.g. a bullet hit
- if (!syncable.isOwner) return false;
+ if (syncable.Registered && !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);
@@ -70,7 +70,7 @@ namespace BoneSync.Patching
if (syncable != null)
{
if (damage > 0.5f) syncable.RegisterSyncable();
- if (!syncable.isOwner) return true;
+ if (syncable.Registered && !syncable.isOwner) return false;
MelonLoader.MelonLogger.Msg("Patch: Prop_Health.TAKEDAMAGE: " + damage + " " + syncable.gameObject.name);
ObjectHealthInfo objectHealthInfo = new ObjectHealthInfo(__instance.cur_Health, __instance.hits, Vector3.zero, damage, crit, attackType);
diff --git a/BoneSync/Patching/PlugPatches.cs b/BoneSync/Patching/PlugPatches.cs
new file mode 100644
index 0000000..e154ac2
--- /dev/null
+++ b/BoneSync/Patching/PlugPatches.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using BoneSync.Sync;
+using BoneSync.Sync.Components;
+using HarmonyLib;
+using MelonLoader;
+using StressLevelZero.Interaction;
+
+namespace BoneSync.Patching
+{
+ [HarmonyPatch(typeof(Socket))]
+ public class SocketPatches
+ {
+ [HarmonyPatch(nameof(Socket.OnPlugEnter)), HarmonyPostfix]
+ public static void SocketEnterPatch(Socket __instance, Plug plug)
+ {
+ if (!plug) return;
+ MelonLogger.Msg("Plug entered: " + __instance.name + " Plug: " + plug.name);
+ Syncable syncable = ObjectSyncCache.GetSyncable(plug);
+ if (!syncable) return;
+ byte id = syncable.GetPlugId(plug);
+ MelonLogger.Msg("Plug entered: " + __instance.name + " Plug: " + plug.name + " ID: " + id);
+
+ }
+
+ [HarmonyPatch(nameof(Socket.OnPlugExit)), HarmonyPostfix]
+ public static void SocketExitPatch(Socket __instance, Plug plug)
+ {
+ if (!plug) return;
+ MelonLogger.Msg("Plug exited: " + __instance.name + " Plug: " + plug.name);
+ Syncable syncable = ObjectSyncCache.GetSyncable(plug);
+ if (!syncable) return;
+ byte id = syncable.GetPlugId(plug);
+ MelonLogger.Msg("Plug exited: " + __instance.name + " Plug: " + plug.name + " ID: " + id);
+ }
+ }
+}
diff --git a/BoneSync/Sync/Components/SyncableBase.cs b/BoneSync/Sync/Components/SyncableBase.cs
index 2636c14..1da68f7 100644
--- a/BoneSync/Sync/Components/SyncableBase.cs
+++ b/BoneSync/Sync/Components/SyncableBase.cs
@@ -108,6 +108,7 @@ namespace BoneSync.Sync.Components
private Magazine magazine;
private Plug[] plugs;
+ private Socket[] sockets;
private AIBrain aiBrain;
private PuppetMaster puppetMaster;
@@ -177,6 +178,7 @@ namespace BoneSync.Sync.Components
gun = GetComponent();
magazine = GetComponent();
plugs = GetComponentsInChildren();
+ sockets = GetComponentsInChildren();
spawnFragment = GetComponent();
UpdateTransformList();
diff --git a/BoneSync/Sync/Components/SyncablePlugs.cs b/BoneSync/Sync/Components/SyncablePlugs.cs
new file mode 100644
index 0000000..183ce2a
--- /dev/null
+++ b/BoneSync/Sync/Components/SyncablePlugs.cs
@@ -0,0 +1,59 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using UnityEngine;
+using MelonLoader;
+using StressLevelZero.Interaction;
+
+namespace BoneSync.Sync.Components
+{
+ public partial class Syncable : MonoBehaviour
+ {
+ public Plug GetPlugFromId(byte id)
+ {
+ if (plugs.Length <= id)
+ {
+ MelonLogger.Error("Plug ID out of range");
+ return null;
+ }
+
+ return plugs[id];
+ }
+
+ public Socket GetSocketFromId(byte id)
+ {
+ if (sockets.Length <= id)
+ {
+ MelonLogger.Error("Socket ID out of range");
+ return null;
+ }
+ return sockets[id];
+ }
+
+ public byte GetSocketId(Socket socket)
+ {
+ for (byte i = 0; i < sockets.Length; i++)
+ {
+ if (sockets[i] == socket)
+ {
+ return i;
+ }
+ }
+ return 255;
+ }
+
+ public byte GetPlugId(Plug plug)
+ {
+ for (byte i = 0; i < plugs.Length; i++)
+ {
+ if (plugs[i] == plug)
+ {
+ return i;
+ }
+ }
+ return 255;
+ }
+ }
+}
diff --git a/BoneSync/Sync/Components/SyncableProperties.cs b/BoneSync/Sync/Components/SyncableProperties.cs
new file mode 100644
index 0000000..49bd9c1
--- /dev/null
+++ b/BoneSync/Sync/Components/SyncableProperties.cs
@@ -0,0 +1,32 @@
+using BoneSync.Networking.Messages;
+using StressLevelZero.Combat;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using UnityEngine;
+
+namespace BoneSync.Sync.Components
+{
+ public partial class Syncable : MonoBehaviour
+ {
+ public void ApplyMagazineData(MagazineData magazineData)
+ {
+ if (!magazineData) return;
+ if (!magazine) return;
+ magazine.magazineData.AmmoSlots = magazineData.AmmoSlots;
+ magazine.magazineData.cartridgeType = magazineData.cartridgeType;
+ magazine.magazineData.weight = magazineData.weight;
+ magazine.magazineData.platform = magazineData.platform;
+ }
+
+ public MagazineSyncData GetMagazineData()
+ {
+ MagazineSyncData data = new MagazineSyncData();
+ data.syncId = GetSyncId();
+ data.magazineData = magazine.magazineData;
+ return data;
+ }
+ }
+}
diff --git a/BoneSync/Sync/ObjectSyncCache.cs b/BoneSync/Sync/ObjectSyncCache.cs
index 54ca40e..8516d94 100644
--- a/BoneSync/Sync/ObjectSyncCache.cs
+++ b/BoneSync/Sync/ObjectSyncCache.cs
@@ -15,11 +15,57 @@ namespace BoneSync.Sync
private static Dictionary _pathToSyncable = new Dictionary();
private static Dictionary _idToSyncable = new Dictionary();
- //private static Dictionary _componentToSyncable = new Dictionary();
+ private static Dictionary _componentToSyncable = new Dictionary();
+ private static Dictionary _syncableToComponent = new Dictionary();
public static Dictionary CallbackIdToSyncable = new Dictionary();
- public static void AddSyncable(Syncable syncable)
+ private static string GetComponentNamespace(Component component)
+ {
+ return component.GetType().Namespace;
+ }
+
+ private static bool IsSlzComponent(Component component)
+ {
+ string ns = GetComponentNamespace(component);
+ return ns.StartsWith("StressLevelZero") || ns.StartsWith("BoneSync");
+ }
+ private static Component[] GetSLZComponents(Syncable syncable)
+ {
+ Component[] components = syncable.GetComponentsInChildren(true);
+ List slzComponents = new List();
+ for (int i = 0; i < components.Length; i++)
+ {
+ if (IsSlzComponent(components[i]))
+ {
+ slzComponents.Add(components[i]);
+ }
+ }
+ return slzComponents.ToArray();
+ }
+ private static void _AddSyncableComponents(Syncable syncable)
+ {
+ Component[] components = GetSLZComponents(syncable);
+ _syncableToComponent[syncable] = components;
+ foreach (Component component in components)
+ {
+ _componentToSyncable[component] = syncable;
+ }
+ }
+ private static void _RemoveSyncableComponents(Syncable syncable)
+ {
+ if (_syncableToComponent.ContainsKey(syncable))
+ {
+ Component[] components = _syncableToComponent[syncable];
+ foreach (Component component in components)
+ {
+ _componentToSyncable.Remove(component);
+ }
+ _syncableToComponent.Remove(syncable);
+ }
+ }
+
+ private static void _AddSyncableKeys(Syncable syncable)
{
string path = syncable.GetSyncableWorldPath();
if (path != null && path != "")
@@ -32,7 +78,7 @@ namespace BoneSync.Sync
}
}
- public static void RemoveSyncable(Syncable syncable)
+ private static void _RemoveSyncableKeys(Syncable syncable)
{
string path = syncable.GetSyncableWorldPath();
if (path != null && path != "")
@@ -44,6 +90,17 @@ namespace BoneSync.Sync
_idToSyncable.Remove(syncable.GetSyncId());
}
}
+ public static void AddSyncable(Syncable syncable)
+ {
+ _AddSyncableKeys(syncable);
+ _AddSyncableComponents(syncable);
+ }
+
+ public static void RemoveSyncable(Syncable syncable)
+ {
+ _RemoveSyncableKeys(syncable);
+ _RemoveSyncableComponents(syncable);
+ }
public static void UpdateSyncId(Syncable syncable)
{
@@ -79,6 +136,15 @@ namespace BoneSync.Sync
return null;
}
+ public static Syncable GetSyncable(Component component)
+ {
+ if (_componentToSyncable.ContainsKey(component))
+ {
+ return _componentToSyncable[component];
+ }
+ return null;
+ }
+
public static void DISCARD_ALL_SYNCABLES()
{
foreach (Syncable syncable in Syncable.syncablesCache.Values)