This commit is contained in:
2025-03-03 20:10:39 +02:00
parent 6402afc72b
commit 51d7d81605
13 changed files with 337 additions and 75 deletions

View File

@@ -84,20 +84,27 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Data\ByteEncoder.cs" />
<Compile Include="Data\SpawnableManager.cs" />
<Compile Include="Data\Structs.cs" />
<Compile Include="Networking\Messages\DiscardSyncableMessage.cs" />
<Compile Include="Networking\Messages\ObjectAttributeMessage.cs" />
<Compile Include="Networking\Messages\MagazineSyncMessage.cs" />
<Compile Include="Networking\Messages\ObjectDamageMessage.cs" />
<Compile Include="Networking\Messages\ObjectSyncMessage.cs" />
<Compile Include="Networking\Messages\OwnershipTransferMessage.cs" />
<Compile Include="Networking\Messages\RegisterSyncableMessage.cs" />
<Compile Include="Patching\CallPatchedMethod.cs" />
<Compile Include="Patching\GripPatches.cs" />
<Compile Include="Patching\GunPatches.cs" />
<Compile Include="Patching\InteractableHostPatches.cs" />
<Compile Include="Patching\ObjectHealthPatches.cs" />
<Compile Include="Patching\PlugPatches.cs" />
<Compile Include="Sync\Components\SyncableBase.cs" />
<Compile Include="Sync\Components\SyncableDamage.cs" />
<Compile Include="Sync\Components\SyncableNetworking.cs" />
<Compile Include="Sync\Components\SyncablePhysics.cs" />
<Compile Include="Sync\Components\SyncablePlugs.cs" />
<Compile Include="Sync\Components\SyncableProperties.cs" />
<Compile Include="Sync\ObjectSync.cs" />
<Compile Include="Sync\ObjectSyncCache.cs" />
<Compile Include="Sync\PlayerSync.cs" />
@@ -254,13 +261,11 @@
<Compile Include="Networking\Messages\PlayerSyncMessage.cs" />
<Compile Include="Networking\Packet.cs" />
<Compile Include="Networking\PacketTypes.cs" />
<Compile Include="Networking\Structs.cs" />
<Compile Include="Networking\Transport\SteamTransport.cs" />
<Compile Include="Networking\Transport\TransportBase.cs" />
<Compile Include="Patching\PoolPatches.cs" />
<Compile Include="Player\PlayerRig.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Networking\ByteEncoder.cs" />
<Compile Include="Sync\SceneSync.cs" />
</ItemGroup>
<ItemGroup>

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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<bool> attributes = new List<bool>();
_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(),
};
}
}
}
}

View File

@@ -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;

View File

@@ -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,
}
}

View File

@@ -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);
}
}
}

View File

@@ -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);

View File

@@ -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);
}
}
}

View File

@@ -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<Gun>();
magazine = GetComponent<Magazine>();
plugs = GetComponentsInChildren<Plug>();
sockets = GetComponentsInChildren<Socket>();
spawnFragment = GetComponent<SpawnFragment>();
UpdateTransformList();

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -15,11 +15,57 @@ namespace BoneSync.Sync
private static Dictionary<string, Syncable> _pathToSyncable = new Dictionary<string, Syncable>();
private static Dictionary<ushort, Syncable> _idToSyncable = new Dictionary<ushort, Syncable>();
//private static Dictionary<Component, Syncable> _componentToSyncable = new Dictionary<Component, Syncable>();
private static Dictionary<Component, Syncable> _componentToSyncable = new Dictionary<Component, Syncable>();
private static Dictionary<Syncable, Component[]> _syncableToComponent = new Dictionary<Syncable, Component[]>();
public static Dictionary<ushort, Syncable> CallbackIdToSyncable = new Dictionary<ushort, Syncable>();
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<Component>(true);
List<Component> slzComponents = new List<Component>();
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)