Compare commits
2 Commits
ee1b827c91
...
1dce1960f6
| Author | SHA1 | Date | |
|---|---|---|---|
| 1dce1960f6 | |||
| ff70bad234 |
@@ -113,11 +113,18 @@
|
|||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="Networking\Messages\ObjectDamageMessage.cs" />
|
||||||
<Compile Include="Networking\Messages\ObjectSyncMessage.cs" />
|
<Compile Include="Networking\Messages\ObjectSyncMessage.cs" />
|
||||||
<Compile Include="Networking\Messages\RegisterSyncableMessage.cs" />
|
<Compile Include="Networking\Messages\RegisterSyncableMessage.cs" />
|
||||||
|
<Compile Include="Patching\CallPatchedMethod.cs" />
|
||||||
<Compile Include="Patching\InteractableHostPatches.cs" />
|
<Compile Include="Patching\InteractableHostPatches.cs" />
|
||||||
<Compile Include="Sync\Components\Syncable.cs" />
|
<Compile Include="Patching\ObjectHealthPatches.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\ObjectSync.cs" />
|
<Compile Include="Sync\ObjectSync.cs" />
|
||||||
|
<Compile Include="Sync\ObjectSyncCache.cs" />
|
||||||
<Compile Include="Sync\PlayerSync.cs" />
|
<Compile Include="Sync\PlayerSync.cs" />
|
||||||
<Compile Include="Facepunch.Steamworks\Callbacks\CallResult.cs" />
|
<Compile Include="Facepunch.Steamworks\Callbacks\CallResult.cs" />
|
||||||
<Compile Include="Facepunch.Steamworks\Callbacks\ICallbackData.cs" />
|
<Compile Include="Facepunch.Steamworks\Callbacks\ICallbackData.cs" />
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using StressLevelZero;
|
using StressLevelZero;
|
||||||
|
using StressLevelZero.Combat;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@@ -52,6 +53,16 @@ namespace BoneSync.Networking
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void WriteBool(bool value)
|
||||||
|
{
|
||||||
|
WriteByte((byte)(value ? 1 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool ReadBool()
|
||||||
|
{
|
||||||
|
return ReadByte() == 1;
|
||||||
|
}
|
||||||
|
|
||||||
public void WriteInt(int value)
|
public void WriteInt(int value)
|
||||||
{
|
{
|
||||||
WriteBytes(BitConverter.GetBytes(value));
|
WriteBytes(BitConverter.GetBytes(value));
|
||||||
@@ -168,5 +179,38 @@ namespace BoneSync.Networking
|
|||||||
scale = scale
|
scale = scale
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void WriteEnum<T>(T value) where T : Enum
|
||||||
|
{
|
||||||
|
WriteByte((byte)(object)value);
|
||||||
|
}
|
||||||
|
public T ReadEnum<T>() where T : Enum
|
||||||
|
{
|
||||||
|
return (T)(object)ReadByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteSLZAttack(Attack attack)
|
||||||
|
{
|
||||||
|
WriteEnum(attack.attackType);
|
||||||
|
WriteFloat(attack.damage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteMatrix4x4(UnityEngine.Matrix4x4 matrix)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
WriteFloat(matrix[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnityEngine.Matrix4x4 ReadMatrix4x4()
|
||||||
|
{
|
||||||
|
UnityEngine.Matrix4x4 matrix = new UnityEngine.Matrix4x4();
|
||||||
|
for (int i = 0; i < 16; i++)
|
||||||
|
{
|
||||||
|
matrix[i] = ReadFloat();
|
||||||
|
}
|
||||||
|
return matrix;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
80
BoneSync/Networking/Messages/ObjectDamageMessage.cs
Normal file
80
BoneSync/Networking/Messages/ObjectDamageMessage.cs
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
using StressLevelZero.Combat;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace BoneSync.Networking.Messages
|
||||||
|
{
|
||||||
|
public struct ObjectHealthInfo
|
||||||
|
{
|
||||||
|
public float _health;
|
||||||
|
public int _hits;
|
||||||
|
public Vector3 normal;
|
||||||
|
public float damage;
|
||||||
|
public bool crit;
|
||||||
|
public AttackType attackType;
|
||||||
|
public ObjectHealthInfo(float health, int hits, Vector3 normal, float damage, bool crit, AttackType attackType)
|
||||||
|
{
|
||||||
|
_health = health;
|
||||||
|
_hits = hits;
|
||||||
|
this.normal = normal;
|
||||||
|
this.damage = damage;
|
||||||
|
this.crit = crit;
|
||||||
|
this.attackType = attackType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public enum ObjectDamageType
|
||||||
|
{
|
||||||
|
Unknown = 0,
|
||||||
|
SyncHealth = 1,
|
||||||
|
DestructibleTakeDamage = 2,
|
||||||
|
PropHealthTakeDamage = 3,
|
||||||
|
}
|
||||||
|
public struct ObjectDamageInfo
|
||||||
|
{
|
||||||
|
public ushort objectId;
|
||||||
|
public ObjectDamageType eventType;
|
||||||
|
public ObjectHealthInfo objectHealthInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
[PacketType(PacketType.ObjectEvent), PacketReliability(PacketReliability.Reliable)]
|
||||||
|
public class ObjectDamageMessage : NetworkMessage
|
||||||
|
{
|
||||||
|
public ObjectDamageInfo objectEventInfo => _objectEventInfo;
|
||||||
|
private ObjectDamageInfo _objectEventInfo;
|
||||||
|
|
||||||
|
public ObjectDamageMessage(ObjectDamageInfo objectEventInfo)
|
||||||
|
{
|
||||||
|
_objectEventInfo = objectEventInfo;
|
||||||
|
byteEncoder.WriteUShort(_objectEventInfo.objectId);
|
||||||
|
byteEncoder.WriteEnum(_objectEventInfo.eventType);
|
||||||
|
byteEncoder.WriteFloat(_objectEventInfo.objectHealthInfo._health);
|
||||||
|
byteEncoder.WriteInt(_objectEventInfo.objectHealthInfo._hits);
|
||||||
|
if (_objectEventInfo.eventType == ObjectDamageType.SyncHealth) return; // No need to write the rest of the data
|
||||||
|
byteEncoder.WriteVector3(_objectEventInfo.objectHealthInfo.normal);
|
||||||
|
byteEncoder.WriteFloat(_objectEventInfo.objectHealthInfo.damage);
|
||||||
|
byteEncoder.WriteBool(_objectEventInfo.objectHealthInfo.crit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectDamageMessage(Packet packet)
|
||||||
|
{
|
||||||
|
byteEncoder.WriteBytes(packet.Data);
|
||||||
|
_objectEventInfo.objectId = byteEncoder.ReadUShort();
|
||||||
|
_objectEventInfo.eventType = byteEncoder.ReadEnum<ObjectDamageType>();
|
||||||
|
_objectEventInfo.objectHealthInfo._health = byteEncoder.ReadFloat();
|
||||||
|
_objectEventInfo.objectHealthInfo._hits = byteEncoder.ReadInt();
|
||||||
|
if (_objectEventInfo.eventType == ObjectDamageType.SyncHealth) return; // No need to read the rest of the data
|
||||||
|
_objectEventInfo.objectHealthInfo.normal = byteEncoder.ReadVector3();
|
||||||
|
_objectEventInfo.objectHealthInfo.damage = byteEncoder.ReadFloat();
|
||||||
|
_objectEventInfo.objectHealthInfo.crit = byteEncoder.ReadBool();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Execute()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,6 +13,7 @@ namespace BoneSync.Networking.Messages
|
|||||||
{
|
{
|
||||||
public SimpleTransform transform;
|
public SimpleTransform transform;
|
||||||
public Vector3 velocity;
|
public Vector3 velocity;
|
||||||
|
public Vector3 angularVelocity;
|
||||||
}
|
}
|
||||||
public struct ObjectSyncMessageData
|
public struct ObjectSyncMessageData
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ namespace BoneSync.Networking.Messages
|
|||||||
public RegisterSyncableMessage(RegisterSyncableInfo info)
|
public RegisterSyncableMessage(RegisterSyncableInfo info)
|
||||||
{
|
{
|
||||||
_info = info;
|
_info = info;
|
||||||
byteEncoder.WriteByte((byte)_info.type);
|
byteEncoder.WriteEnum<RegisterSyncType>(_info.type);
|
||||||
byteEncoder.WriteString(_info.transformPath);
|
byteEncoder.WriteString(_info.transformPath);
|
||||||
byteEncoder.WriteUlong(_info.ownerId);
|
byteEncoder.WriteUlong(_info.ownerId);
|
||||||
byteEncoder.WriteUShort(_info.id);
|
byteEncoder.WriteUShort(_info.id);
|
||||||
@@ -38,7 +38,7 @@ namespace BoneSync.Networking.Messages
|
|||||||
public RegisterSyncableMessage(Packet packet)
|
public RegisterSyncableMessage(Packet packet)
|
||||||
{
|
{
|
||||||
byteEncoder.WriteBytes(packet.Data);
|
byteEncoder.WriteBytes(packet.Data);
|
||||||
_info.type = (RegisterSyncType)byteEncoder.ReadByte();
|
_info.type = byteEncoder.ReadEnum<RegisterSyncType>();
|
||||||
_info.transformPath = byteEncoder.ReadString();
|
_info.transformPath = byteEncoder.ReadString();
|
||||||
_info.ownerId = byteEncoder.ReadUlong();
|
_info.ownerId = byteEncoder.ReadUlong();
|
||||||
_info.id = byteEncoder.ReadUShort();
|
_info.id = byteEncoder.ReadUShort();
|
||||||
|
|||||||
@@ -13,5 +13,6 @@ namespace BoneSync.Networking
|
|||||||
PlayerSync = 2,
|
PlayerSync = 2,
|
||||||
RegisterSyncable = 3,
|
RegisterSyncable = 3,
|
||||||
ObjectSync = 4,
|
ObjectSync = 4,
|
||||||
|
ObjectEvent = 5,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,17 +72,18 @@ namespace BoneSync.Networking.Transport
|
|||||||
return processed > 0;
|
return processed > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendP2P(SteamId peer, byte[] data)
|
public void SendP2P(SteamId peer, byte[] data, P2PSend sendType)
|
||||||
{
|
{
|
||||||
if (peer == BoneSync.lobby.GetLocalId())
|
if (peer == BoneSync.lobby.GetLocalId())
|
||||||
{
|
{
|
||||||
//MelonLogger.Msg("Trying to send packet to self");
|
//MelonLogger.Msg("Trying to send packet to self");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
SteamNetworking.SendP2PPacket(peer, data, data.Length, 0, P2PSend.Reliable);
|
SteamNetworking.SendP2PPacket(peer, data, data.Length, 0, sendType);
|
||||||
}
|
}
|
||||||
public override void Send(Packet packet)
|
public override void Send(Packet packet)
|
||||||
{
|
{
|
||||||
|
P2PSend sendType = (P2PSend)packet.Info.reliability;
|
||||||
LobbyManager.LobbyManager _instance = BoneSync.lobby;
|
LobbyManager.LobbyManager _instance = BoneSync.lobby;
|
||||||
if (_instance == null)
|
if (_instance == null)
|
||||||
{
|
{
|
||||||
@@ -93,14 +94,14 @@ namespace BoneSync.Networking.Transport
|
|||||||
{
|
{
|
||||||
foreach (SteamId peer in _instance.GetPeers())
|
foreach (SteamId peer in _instance.GetPeers())
|
||||||
{
|
{
|
||||||
SendP2P(peer, packet.ToBytes());
|
SendP2P(peer, packet.ToBytes(), sendType);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SendP2P(packet.Info.receiverId, packet.ToBytes());
|
SendP2P(packet.Info.receiverId, packet.ToBytes(), sendType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
42
BoneSync/Patching/CallPatchedMethod.cs
Normal file
42
BoneSync/Patching/CallPatchedMethod.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
using StressLevelZero.Combat;
|
||||||
|
using StressLevelZero.Pool;
|
||||||
|
using StressLevelZero.Props;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace BoneSync.Patching
|
||||||
|
{
|
||||||
|
public static class CallPatchedMethods
|
||||||
|
{
|
||||||
|
public static bool allowPatchedMethodCall
|
||||||
|
{
|
||||||
|
private set;
|
||||||
|
get;
|
||||||
|
}
|
||||||
|
public static void TakeDamage(ObjectDestructable __instance, ref Vector3 normal, ref float damage, ref bool crit, ref AttackType attackType)
|
||||||
|
{
|
||||||
|
allowPatchedMethodCall = true;
|
||||||
|
__instance.TakeDamage(normal, damage, crit, attackType);
|
||||||
|
allowPatchedMethodCall = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void TakeDamage(Prop_Health __instance, ref float damage, ref bool crit, ref AttackType attackType)
|
||||||
|
{
|
||||||
|
allowPatchedMethodCall = true;
|
||||||
|
__instance.TAKEDAMAGE(damage, crit, attackType);
|
||||||
|
allowPatchedMethodCall = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GameObject PoolSpawn(Pool __instance, ref Vector3 position, ref Quaternion rotation, ref Il2CppSystem.Nullable<Vector3> scale, ref Il2CppSystem.Nullable<bool> autoEnable)
|
||||||
|
{
|
||||||
|
allowPatchedMethodCall = true;
|
||||||
|
GameObject result = __instance.Spawn(position, rotation, scale, autoEnable);
|
||||||
|
allowPatchedMethodCall = false;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
64
BoneSync/Patching/ObjectHealthPatches.cs
Normal file
64
BoneSync/Patching/ObjectHealthPatches.cs
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
using BoneSync.Networking.Messages;
|
||||||
|
using BoneSync.Sync;
|
||||||
|
using BoneSync.Sync.Components;
|
||||||
|
using HarmonyLib;
|
||||||
|
using StressLevelZero.Combat;
|
||||||
|
using StressLevelZero.Props;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace BoneSync.Patching
|
||||||
|
{
|
||||||
|
[HarmonyPatch(typeof(ObjectDestructable))]
|
||||||
|
public class ObjectDestructablePatches
|
||||||
|
{
|
||||||
|
[HarmonyPatch(nameof(ObjectDestructable.TakeDamage))]
|
||||||
|
[HarmonyPrefix]
|
||||||
|
private static bool TakeDamagePatch(ObjectDestructable __instance, ref Vector3 normal, ref float damage, ref bool crit, ref AttackType attackType)
|
||||||
|
{
|
||||||
|
if (CallPatchedMethods.allowPatchedMethodCall) return true;
|
||||||
|
MelonLoader.MelonLogger.Msg("ObjectDestructable.TakeDamage: " + damage);
|
||||||
|
Syncable syncable = ObjectSync.GetSyncableFromCache(__instance.gameObject);
|
||||||
|
if (syncable != null)
|
||||||
|
{
|
||||||
|
if (!syncable.Registered) return true;
|
||||||
|
MelonLoader.MelonLogger.Msg("Patch: ObjectDestructable.TakeDamage: " + damage + " " + syncable.gameObject.name);
|
||||||
|
ObjectHealthInfo objectHealthInfo = new ObjectHealthInfo(__instance._health, __instance._hits, normal, damage, crit, attackType);
|
||||||
|
|
||||||
|
ObjectSync.SendObjectDamageMessage(syncable, ObjectDamageType.DestructibleTakeDamage, objectHealthInfo);
|
||||||
|
|
||||||
|
return false; // prevent networked objects from taking damage locally
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(Prop_Health))]
|
||||||
|
public class PropHealthPatches
|
||||||
|
{
|
||||||
|
[HarmonyPatch(nameof(Prop_Health.TAKEDAMAGE))]
|
||||||
|
[HarmonyPrefix]
|
||||||
|
private static bool TakeDamagePatch(Prop_Health __instance, ref float damage, ref bool crit, ref AttackType attackType)
|
||||||
|
{
|
||||||
|
if (CallPatchedMethods.allowPatchedMethodCall) return true;
|
||||||
|
MelonLoader.MelonLogger.Msg("Prop_Health.TAKEDAMAGE: " + damage);
|
||||||
|
Syncable syncable = ObjectSync.GetSyncableFromCache(__instance.gameObject);
|
||||||
|
if (syncable != null)
|
||||||
|
{
|
||||||
|
if (!syncable.Registered) return true;
|
||||||
|
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);
|
||||||
|
|
||||||
|
ObjectSync.SendObjectDamageMessage(syncable, ObjectDamageType.PropHealthTakeDamage, objectHealthInfo);
|
||||||
|
|
||||||
|
return false; // prevent networked objects from taking damage locally
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using HarmonyLib;
|
using HarmonyLib;
|
||||||
@@ -11,31 +12,31 @@ using UnityEngine;
|
|||||||
|
|
||||||
namespace BoneSync.Patching
|
namespace BoneSync.Patching
|
||||||
{
|
{
|
||||||
/*
|
|
||||||
[HarmonyPatch(typeof(Pool))]
|
[HarmonyPatch(typeof(Pool))]
|
||||||
internal class PoolPatches
|
internal class PoolPatches
|
||||||
{
|
{
|
||||||
|
|
||||||
[HarmonyPatch(nameof(Pool.Spawn))]
|
[HarmonyPatch(nameof(Pool.Spawn))]
|
||||||
[HarmonyPostfix]
|
[HarmonyPostfix]
|
||||||
private static void SpawnPatch(Pool __instance, ref GameObject __result)
|
private static void SpawnPatchPost(Pool __instance, ref GameObject __result)
|
||||||
{
|
{
|
||||||
MelonLogger.Msg("Spawned object: " + __result.name);
|
//MelonLogger.Msg("Spawned object: " + __result.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HarmonyPatch(nameof(Pool.FlagPooleeForRespawn))]
|
[HarmonyPatch(nameof(Pool.Spawn))]
|
||||||
[HarmonyPostfix]
|
[HarmonyPrefix]
|
||||||
private static void FlagPooleeForRespawnPatch(Pool __instance, ref GameObject p)
|
private static bool SpawnPatchPre(Pool __instance, ref Vector3 position, ref Quaternion rotation, ref Il2CppSystem.Nullable<Vector3> scale, ref Il2CppSystem.Nullable<bool> autoEnable)
|
||||||
{
|
{
|
||||||
MelonLogger.Msg("Flagged object for respawn: " + p.name);
|
if (CallPatchedMethods.allowPatchedMethodCall) return true;
|
||||||
|
|
||||||
|
if (BoneSync.lobby.IsConnected())
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("Patched Spawning object in pool: " + __instance.name);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
[HarmonyPatch(nameof(Pool.InstantiatePoolee))]
|
return true;
|
||||||
[HarmonyPostfix]
|
|
||||||
private static void InstantiatePooleePatch(Pool __instance, ref Poolee __result)
|
|
||||||
{
|
|
||||||
MelonLogger.Msg("Instantiated object: " + __result.name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ using BoneSync.Networking.Messages;
|
|||||||
using BoneSync.Networking;
|
using BoneSync.Networking;
|
||||||
using StressLevelZero.Data;
|
using StressLevelZero.Data;
|
||||||
using System.Collections;
|
using System.Collections;
|
||||||
|
using StressLevelZero.Props;
|
||||||
|
using BoneSync.Patching;
|
||||||
|
using StressLevelZero.Props.Weapons;
|
||||||
|
using StressLevelZero.AI;
|
||||||
|
using PuppetMasta;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
|
|
||||||
namespace BoneSync.Sync.Components
|
namespace BoneSync.Sync.Components
|
||||||
@@ -45,13 +51,13 @@ namespace BoneSync.Sync.Components
|
|||||||
}
|
}
|
||||||
|
|
||||||
[RegisterTypeInIl2Cpp]
|
[RegisterTypeInIl2Cpp]
|
||||||
public class Syncable : MonoBehaviour
|
public partial class Syncable : MonoBehaviour
|
||||||
{
|
{
|
||||||
public const int SYNC_FPS = 20;
|
public const int SYNC_FPS = 20;
|
||||||
|
|
||||||
public static List<Syncable> syncablesCache = new List<Syncable>();
|
public static Dictionary<GameObject, Syncable> syncablesCache = new Dictionary<GameObject, Syncable>();
|
||||||
public Syncable(IntPtr intPtr) : base(intPtr) {
|
public Syncable(IntPtr intPtr) : base(intPtr) {
|
||||||
syncablesCache.Add(this);
|
syncablesCache[gameObject] = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool _syncCoroutineRunning;
|
private bool _syncCoroutineRunning;
|
||||||
@@ -62,7 +68,7 @@ namespace BoneSync.Sync.Components
|
|||||||
get;
|
get;
|
||||||
}
|
}
|
||||||
private ushort _syncId;
|
private ushort _syncId;
|
||||||
private ulong _lastSyncTime;
|
private float _lastSyncTime;
|
||||||
|
|
||||||
private bool _attemptedRegister;
|
private bool _attemptedRegister;
|
||||||
|
|
||||||
@@ -70,6 +76,15 @@ namespace BoneSync.Sync.Components
|
|||||||
public bool isStale => Time.time - _lastSyncTime > 5f;
|
public bool isStale => Time.time - _lastSyncTime > 5f;
|
||||||
public bool isOwner => _ownerId == BoneSync.lobby.GetLocalId();
|
public bool isOwner => _ownerId == BoneSync.lobby.GetLocalId();
|
||||||
|
|
||||||
|
public bool ShouldSendSync()
|
||||||
|
{
|
||||||
|
if (!Registered) return false;
|
||||||
|
if (!isOwner) return false;
|
||||||
|
if (isStale) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public ushort GetSyncId() => _syncId;
|
public ushort GetSyncId() => _syncId;
|
||||||
public void SetSyncId(ushort id)
|
public void SetSyncId(ushort id)
|
||||||
{
|
{
|
||||||
@@ -78,84 +93,28 @@ namespace BoneSync.Sync.Components
|
|||||||
ObjectSyncCache.UpdateSyncId(this);
|
ObjectSyncCache.UpdateSyncId(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public InteractableHost interactableHost;
|
public InteractableHost interactableHost { private set; get; }
|
||||||
public InteractableHostManager interactableManager;
|
public InteractableHostManager interactableManager { private set; get; }
|
||||||
public Poolee poolee;
|
public Poolee poolee { private set; get; }
|
||||||
|
|
||||||
|
private Prop_Health propHealth;
|
||||||
|
private ObjectDestructable objectDestructable;
|
||||||
|
|
||||||
private Rigidbody[] rigidbodies;
|
private Rigidbody[] rigidbodies;
|
||||||
private Transform[] transforms;
|
private Transform[] _transforms;
|
||||||
|
|
||||||
private void SetKinematic(bool kinematic)
|
private Gun gun;
|
||||||
{
|
private Magazine magazine;
|
||||||
foreach (Rigidbody rb in rigidbodies)
|
|
||||||
{
|
|
||||||
rb.isKinematic = kinematic;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObjectSyncTransform[] GetObjectSyncTransforms()
|
private Plug[] plugs;
|
||||||
{
|
|
||||||
ObjectSyncTransform[] objectSyncTransforms = new ObjectSyncTransform[transforms.Length];
|
|
||||||
for (int i = 0; i < transforms.Length; i++)
|
|
||||||
{
|
|
||||||
objectSyncTransforms[i] = new ObjectSyncTransform()
|
|
||||||
{
|
|
||||||
transform = new SimpleTransform(transforms[i]),
|
|
||||||
velocity = Vector3.zero
|
|
||||||
};
|
|
||||||
}
|
|
||||||
return objectSyncTransforms;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ApplyObjectSyncTransforms(ObjectSyncTransform[] objectSyncTransforms)
|
private AIBrain aiBrain;
|
||||||
{
|
private PuppetMaster puppetMaster;
|
||||||
if (objectSyncTransforms.Length != transforms.Length)
|
|
||||||
{
|
|
||||||
MelonLogger.Warning("ObjectSyncTransforms length mismatch: " + objectSyncTransforms.Length + " != " + transforms.Length);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (int i = 0; i < objectSyncTransforms.Length; i++)
|
|
||||||
{
|
|
||||||
ObjectSyncTransform objectSyncTransform = objectSyncTransforms[i];
|
|
||||||
transforms[i].ApplySimpleTransform(objectSyncTransform.transform);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task SyncCoroutineAsync()
|
|
||||||
{
|
|
||||||
MelonLogger.Msg("Running sync coroutine for: " + gameObject.name);
|
|
||||||
if (_syncCoroutineRunning) return;
|
|
||||||
_syncCoroutineRunning = true;
|
|
||||||
while (isOwner)
|
|
||||||
{
|
|
||||||
MelonLogger.Msg("Sending object sync message for: " + gameObject.name);
|
|
||||||
ObjectSync.SendObjectSyncMessage(this);
|
|
||||||
await Task.Delay( GetSyncId() == 0 ? 1000 : 1000 / SYNC_FPS);
|
|
||||||
}
|
|
||||||
_syncCoroutineRunning = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnEnable()
|
public void OnEnable()
|
||||||
{
|
{
|
||||||
FindComponents();
|
FindComponents();
|
||||||
MelonLogger.Msg("Syncable enabled: " + transform.GetPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateTransformList()
|
|
||||||
{
|
|
||||||
if (interactableManager)
|
|
||||||
{
|
|
||||||
transforms = interactableManager.hosts.Select(host => host.transform).ToArray();
|
|
||||||
}
|
|
||||||
else if (interactableHost)
|
|
||||||
{
|
|
||||||
transforms = new Transform[] { interactableHost.transform };
|
|
||||||
}
|
|
||||||
else if (poolee)
|
|
||||||
{
|
|
||||||
transforms = new Transform[] { poolee.transform };
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetSyncableWorldPath()
|
public string GetSyncableWorldPath()
|
||||||
@@ -178,13 +137,18 @@ namespace BoneSync.Sync.Components
|
|||||||
interactableManager = GetComponent<InteractableHostManager>();
|
interactableManager = GetComponent<InteractableHostManager>();
|
||||||
interactableHost = GetComponent<InteractableHost>();
|
interactableHost = GetComponent<InteractableHost>();
|
||||||
poolee = GetComponent<Poolee>();
|
poolee = GetComponent<Poolee>();
|
||||||
rigidbodies = GetComponentsInChildren<Rigidbody>();
|
propHealth = GetComponent<Prop_Health>();
|
||||||
|
objectDestructable = GetComponent<ObjectDestructable>();
|
||||||
|
gun = GetComponent<Gun>();
|
||||||
|
magazine = GetComponent<Magazine>();
|
||||||
|
plugs = GetComponentsInChildren<Plug>();
|
||||||
|
//rigidbodies = GetComponentsInChildren<Rigidbody>();
|
||||||
UpdateTransformList();
|
UpdateTransformList();
|
||||||
|
|
||||||
ObjectSyncCache.AddSyncable(this);
|
ObjectSyncCache.AddSyncable(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool ShouldSync()
|
public bool CanBeSynced()
|
||||||
{
|
{
|
||||||
FindComponents();
|
FindComponents();
|
||||||
if (interactableManager && interactableManager.hosts.Count > 0)
|
if (interactableManager && interactableManager.hosts.Count > 0)
|
||||||
@@ -199,8 +163,15 @@ namespace BoneSync.Sync.Components
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnDestroy()
|
||||||
|
{
|
||||||
|
DiscardSyncable();
|
||||||
|
MelonLogger.Msg("Syncable destroyed: " + transform.GetPath());
|
||||||
|
}
|
||||||
|
|
||||||
public void DiscardSyncable()
|
public void DiscardSyncable()
|
||||||
{
|
{
|
||||||
|
syncablesCache.Remove(gameObject);
|
||||||
ObjectSyncCache.RemoveSyncable(this);
|
ObjectSyncCache.RemoveSyncable(this);
|
||||||
Destroy(this);
|
Destroy(this);
|
||||||
}
|
}
|
||||||
@@ -216,34 +187,14 @@ namespace BoneSync.Sync.Components
|
|||||||
MelonLogger.Warning("Registered Syncable disabled: " + transform.GetPath());
|
MelonLogger.Warning("Registered Syncable disabled: " + transform.GetPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetOwner(ulong ownerId)
|
|
||||||
{
|
|
||||||
_ownerId = ownerId;
|
|
||||||
MelonLogger.Msg("Set owner for " + gameObject.name + " to " + ownerId);
|
|
||||||
_ = SyncCoroutineAsync();
|
|
||||||
UpdateKinematic();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void UpdateKinematic()
|
|
||||||
{
|
|
||||||
SetKinematic(_ownerId != BoneSync.lobby.GetLocalId() && Registered);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void _SendRegisterSync()
|
|
||||||
{
|
|
||||||
MelonLogger.Msg("Registering syncable object: " + gameObject.name);
|
|
||||||
SetOwner(BoneSync.lobby.GetLocalId());
|
|
||||||
SetSyncId(ObjectSync.SendRegisterSyncableMessage(this));
|
|
||||||
}
|
|
||||||
public void RegisterSyncable()
|
public void RegisterSyncable()
|
||||||
{
|
{
|
||||||
if (!BoneSync.lobby.IsConnected()) return;
|
if (!BoneSync.lobby.IsConnected()) return;
|
||||||
if (_attemptedRegister) return;
|
if (_attemptedRegister) return;
|
||||||
if (Registered) return;
|
if (Registered) return;
|
||||||
if (!ShouldSync()) return;
|
if (!CanBeSynced()) return;
|
||||||
_attemptedRegister = true;
|
_attemptedRegister = true;
|
||||||
_SendRegisterSync();
|
_SendRegisterSync();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
58
BoneSync/Sync/Components/SyncableDamage.cs
Normal file
58
BoneSync/Sync/Components/SyncableDamage.cs
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
using BoneSync.Networking.Messages;
|
||||||
|
using BoneSync.Patching;
|
||||||
|
using MelonLoader;
|
||||||
|
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
|
||||||
|
{
|
||||||
|
private void SetHealth(float health, int hits = 0)
|
||||||
|
{
|
||||||
|
if (gameObject.activeSelf == false && health > 0)
|
||||||
|
{
|
||||||
|
gameObject.SetActive(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (propHealth)
|
||||||
|
{
|
||||||
|
propHealth.cur_Health = health;
|
||||||
|
propHealth.hits = hits;
|
||||||
|
}
|
||||||
|
if (objectDestructable)
|
||||||
|
{
|
||||||
|
objectDestructable._health = health;
|
||||||
|
objectDestructable._hits = hits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Damage(ObjectDamageInfo damageInfo)
|
||||||
|
{
|
||||||
|
ObjectHealthInfo healthInfo = damageInfo.objectHealthInfo;
|
||||||
|
SetHealth(healthInfo._health, healthInfo._hits); // always set health first
|
||||||
|
|
||||||
|
ObjectDamageType eventType = damageInfo.eventType;
|
||||||
|
if (eventType == ObjectDamageType.SyncHealth) return;
|
||||||
|
|
||||||
|
if (eventType == ObjectDamageType.DestructibleTakeDamage && objectDestructable)
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("NetworkDestructableTakeDamage: " + healthInfo.damage);
|
||||||
|
CallPatchedMethods.TakeDamage(objectDestructable, ref healthInfo.normal, ref healthInfo.damage, ref healthInfo.crit, ref healthInfo.attackType);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eventType == ObjectDamageType.PropHealthTakeDamage && propHealth)
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("NetworkPropHealthTakeDamage: " + healthInfo.damage);
|
||||||
|
CallPatchedMethods.TakeDamage(propHealth, ref healthInfo.damage, ref healthInfo.crit, ref healthInfo.attackType);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
46
BoneSync/Sync/Components/SyncableNetworking.cs
Normal file
46
BoneSync/Sync/Components/SyncableNetworking.cs
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
using MelonLoader;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace BoneSync.Sync.Components
|
||||||
|
{
|
||||||
|
// SyncableNetworking.cs
|
||||||
|
public partial class Syncable : MonoBehaviour
|
||||||
|
{
|
||||||
|
private void SendObjectSync()
|
||||||
|
{
|
||||||
|
_lastSyncTime = Time.time;
|
||||||
|
ObjectSync.SendObjectSyncMessage(this);
|
||||||
|
}
|
||||||
|
public async Task SyncCoroutineAsync()
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("Running sync coroutine for: " + transform.GetPath());
|
||||||
|
if (_syncCoroutineRunning) return;
|
||||||
|
_syncCoroutineRunning = true;
|
||||||
|
while (isOwner)
|
||||||
|
{
|
||||||
|
if (ShouldSendSync()) SendObjectSync();
|
||||||
|
await Task.Delay(!Registered ? 1000 : 1000 / SYNC_FPS);
|
||||||
|
}
|
||||||
|
_syncCoroutineRunning = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
public void SetOwner(ulong ownerId)
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("Setting owner for " + _syncId + " to " + ownerId);
|
||||||
|
_ownerId = ownerId;
|
||||||
|
_ = SyncCoroutineAsync();
|
||||||
|
UpdateKinematic();
|
||||||
|
}
|
||||||
|
private void _SendRegisterSync()
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("Registering syncable object: " + gameObject.name);
|
||||||
|
SetOwner(BoneSync.lobby.GetLocalId());
|
||||||
|
SetSyncId(ObjectSync.SendRegisterSyncableMessage(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
89
BoneSync/Sync/Components/SyncablePhysics.cs
Normal file
89
BoneSync/Sync/Components/SyncablePhysics.cs
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
using BoneSync.Networking;
|
||||||
|
using BoneSync.Networking.Messages;
|
||||||
|
using BoneSync.Patching;
|
||||||
|
using MelonLoader;
|
||||||
|
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
|
||||||
|
{
|
||||||
|
private void SetKinematic(bool kinematic)
|
||||||
|
{
|
||||||
|
foreach (Rigidbody rb in rigidbodies)
|
||||||
|
{
|
||||||
|
rb.isKinematic = kinematic;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectSyncTransform[] GetObjectSyncTransforms()
|
||||||
|
{
|
||||||
|
ObjectSyncTransform[] objectSyncTransforms = new ObjectSyncTransform[rigidbodies.Length];
|
||||||
|
for (int i = 0; i < _transforms.Length; i++)
|
||||||
|
{
|
||||||
|
objectSyncTransforms[i] = new ObjectSyncTransform()
|
||||||
|
{
|
||||||
|
transform = new SimpleTransform(_transforms[i]),
|
||||||
|
velocity = Vector3.zero
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return objectSyncTransforms;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyObjectSyncTransforms(ObjectSyncTransform[] objectSyncTransforms)
|
||||||
|
{
|
||||||
|
if (objectSyncTransforms.Length != rigidbodies.Length)
|
||||||
|
{
|
||||||
|
MelonLogger.Warning("ObjectSyncTransforms length mismatch: " + objectSyncTransforms.Length + " != " + _transforms.Length);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (int i = 0; i < objectSyncTransforms.Length; i++)
|
||||||
|
{
|
||||||
|
ObjectSyncTransform objectSyncTransform = objectSyncTransforms[i];
|
||||||
|
rigidbodies[i].angularVelocity = objectSyncTransform.angularVelocity;
|
||||||
|
rigidbodies[i].velocity = objectSyncTransform.velocity;
|
||||||
|
rigidbodies[i].position = objectSyncTransform.transform.position;
|
||||||
|
rigidbodies[i].rotation = objectSyncTransform.transform.rotation;
|
||||||
|
_transforms[i].localScale = objectSyncTransform.transform.scale;
|
||||||
|
//_transforms[i].ApplySimpleTransform(objectSyncTransform.transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Rigidbody[] UpdateRigidbodyList()
|
||||||
|
{
|
||||||
|
if (interactableManager)
|
||||||
|
{
|
||||||
|
return interactableManager.hosts.Select(host => host.rb).ToArray();
|
||||||
|
}
|
||||||
|
if (interactableHost)
|
||||||
|
{
|
||||||
|
return new Rigidbody[] { interactableHost.rb };
|
||||||
|
}
|
||||||
|
if (poolee)
|
||||||
|
{
|
||||||
|
return new Rigidbody[] { poolee.GetComponentInChildren<Rigidbody>() };
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Rigidbody[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateTransformList()
|
||||||
|
{
|
||||||
|
// get non-null rigidbodies
|
||||||
|
Rigidbody[] rbs = UpdateRigidbodyList().Where(rb => rb != null).ToArray();
|
||||||
|
rigidbodies = rbs;
|
||||||
|
_transforms = rbs.Select(rb => rb.transform).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateKinematic()
|
||||||
|
{
|
||||||
|
SetKinematic(_ownerId != BoneSync.lobby.GetLocalId() && Registered);
|
||||||
|
}
|
||||||
|
|
||||||
|
// on collision
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,138 +9,10 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
namespace BoneSync.Sync
|
namespace BoneSync.Sync
|
||||||
{
|
{
|
||||||
|
|
||||||
public static class ObjectSyncCache
|
|
||||||
{
|
|
||||||
private static Dictionary<string, Syncable> _pathToSyncable = new Dictionary<string, Syncable>();
|
|
||||||
private static Dictionary<ushort, Syncable> _idToSyncable = new Dictionary<ushort, Syncable>();
|
|
||||||
private static Dictionary<Poolee, Syncable> _pooleeToSyncable = new Dictionary<Poolee, Syncable>();
|
|
||||||
private static Dictionary<InteractableHost, Syncable> _interactableHostToSyncable = new Dictionary<InteractableHost, Syncable>();
|
|
||||||
private static Dictionary<InteractableHostManager, Syncable> _interactableHostManagerToSyncable = new Dictionary<InteractableHostManager, Syncable>();
|
|
||||||
|
|
||||||
|
|
||||||
public static void AddSyncable(Syncable syncable)
|
|
||||||
{
|
|
||||||
string path = syncable.transform.GetPath();
|
|
||||||
if (path != null && path != "")
|
|
||||||
{
|
|
||||||
_pathToSyncable[path] = syncable;
|
|
||||||
}
|
|
||||||
if (syncable.GetSyncId() != 0)
|
|
||||||
{
|
|
||||||
_idToSyncable[syncable.GetSyncId()] = syncable;
|
|
||||||
}
|
|
||||||
if (syncable.interactableHost)
|
|
||||||
{
|
|
||||||
_interactableHostToSyncable[syncable.interactableHost] = syncable;
|
|
||||||
}
|
|
||||||
if (syncable.interactableManager)
|
|
||||||
{
|
|
||||||
_interactableHostManagerToSyncable[syncable.interactableManager] = syncable;
|
|
||||||
}
|
|
||||||
if (syncable.poolee)
|
|
||||||
{
|
|
||||||
_pooleeToSyncable[syncable.poolee] = syncable;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void RemoveSyncable(Syncable syncable)
|
|
||||||
{
|
|
||||||
if (syncable.transform)
|
|
||||||
{
|
|
||||||
_pathToSyncable.Remove(syncable.transform.GetPath());
|
|
||||||
}
|
|
||||||
if (syncable.GetSyncId() != 0)
|
|
||||||
{
|
|
||||||
_idToSyncable.Remove(syncable.GetSyncId());
|
|
||||||
}
|
|
||||||
if (syncable.interactableHost)
|
|
||||||
{
|
|
||||||
_interactableHostToSyncable.Remove(syncable.interactableHost);
|
|
||||||
}
|
|
||||||
if (syncable.interactableManager)
|
|
||||||
{
|
|
||||||
_interactableHostManagerToSyncable.Remove(syncable.interactableManager);
|
|
||||||
}
|
|
||||||
if (syncable.poolee)
|
|
||||||
{
|
|
||||||
_pooleeToSyncable.Remove(syncable.poolee);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void UpdateSyncId(Syncable syncable)
|
|
||||||
{
|
|
||||||
// remove other enties where value is the same
|
|
||||||
foreach (KeyValuePair<ushort, Syncable> entry in _idToSyncable)
|
|
||||||
{
|
|
||||||
if (entry.Value == syncable)
|
|
||||||
{
|
|
||||||
_idToSyncable.Remove(entry.Key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ushort id = syncable.GetSyncId();
|
|
||||||
if (_idToSyncable.ContainsKey(id))
|
|
||||||
{
|
|
||||||
_idToSyncable.Remove(id);
|
|
||||||
}
|
|
||||||
_idToSyncable[id] = syncable;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Syncable GetSyncable(string path)
|
|
||||||
{
|
|
||||||
if (_pathToSyncable.ContainsKey(path))
|
|
||||||
{
|
|
||||||
return _pathToSyncable[path];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Syncable GetSyncable(ushort id)
|
|
||||||
{
|
|
||||||
if (_idToSyncable.ContainsKey(id))
|
|
||||||
{
|
|
||||||
return _idToSyncable[id];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Syncable GetSyncable(Poolee poolee)
|
|
||||||
{
|
|
||||||
if (_pooleeToSyncable.ContainsKey(poolee))
|
|
||||||
{
|
|
||||||
return _pooleeToSyncable[poolee];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Syncable GetSyncable(InteractableHost interactableHost)
|
|
||||||
{
|
|
||||||
if (_interactableHostToSyncable.ContainsKey(interactableHost))
|
|
||||||
{
|
|
||||||
return _interactableHostToSyncable[interactableHost];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Syncable GetSyncable(InteractableHostManager interactableHostManager)
|
|
||||||
{
|
|
||||||
if (_interactableHostManagerToSyncable.ContainsKey(interactableHostManager))
|
|
||||||
{
|
|
||||||
return _interactableHostManagerToSyncable[interactableHostManager];
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void DISCARD_ALL_SYNCABLES() {
|
|
||||||
foreach (Syncable syncable in Syncable.syncablesCache)
|
|
||||||
{
|
|
||||||
syncable.DiscardSyncable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
internal class ObjectSync
|
internal class ObjectSync
|
||||||
{
|
{
|
||||||
private static ushort _nextSyncableId = 1;
|
private static ushort _nextSyncableId = 1;
|
||||||
@@ -201,7 +73,8 @@ namespace BoneSync.Sync
|
|||||||
|
|
||||||
public static void SendObjectSyncMessage(Syncable syncable)
|
public static void SendObjectSyncMessage(Syncable syncable)
|
||||||
{
|
{
|
||||||
MelonLogger.Msg("Sending object sync message for: " + syncable.transform.name);
|
if (!syncable.Registered) return;
|
||||||
|
//MelonLogger.Msg("Sending object sync message for: " + syncable.transform.name);
|
||||||
ObjectSyncTransform[] objectSyncTransforms = syncable.GetObjectSyncTransforms();
|
ObjectSyncTransform[] objectSyncTransforms = syncable.GetObjectSyncTransforms();
|
||||||
|
|
||||||
ObjectSyncMessageData data = new ObjectSyncMessageData()
|
ObjectSyncMessageData data = new ObjectSyncMessageData()
|
||||||
@@ -215,6 +88,9 @@ namespace BoneSync.Sync
|
|||||||
}
|
}
|
||||||
private static Syncable _MakeOrGetSyncable(GameObject gameObject, bool deleteSubSyncabled = true)
|
private static Syncable _MakeOrGetSyncable(GameObject gameObject, bool deleteSubSyncabled = true)
|
||||||
{
|
{
|
||||||
|
//Scene scene = gameObject.scene;
|
||||||
|
//MelonLogger.Msg("Making or getting syncable for: " + gameObject.name + " in scene: " + scene.name);
|
||||||
|
|
||||||
Syncable[] subSyncables = gameObject.GetComponentsInChildren<Syncable>();
|
Syncable[] subSyncables = gameObject.GetComponentsInChildren<Syncable>();
|
||||||
Syncable syncable = gameObject.GetComponent<Syncable>();
|
Syncable syncable = gameObject.GetComponent<Syncable>();
|
||||||
|
|
||||||
@@ -238,6 +114,16 @@ namespace BoneSync.Sync
|
|||||||
return syncable;
|
return syncable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Syncable GetSyncableFromCache(GameObject gameObject)
|
||||||
|
{
|
||||||
|
bool success = Syncable.syncablesCache.TryGetValue(gameObject, out Syncable syncable);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return syncable;
|
||||||
|
}
|
||||||
|
|
||||||
public static Syncable MakeOrGetSyncable(InteractableHost interactableHost)
|
public static Syncable MakeOrGetSyncable(InteractableHost interactableHost)
|
||||||
{
|
{
|
||||||
if (interactableHost.manager) return MakeOrGetSyncable(interactableHost.manager);
|
if (interactableHost.manager) return MakeOrGetSyncable(interactableHost.manager);
|
||||||
@@ -279,10 +165,37 @@ namespace BoneSync.Sync
|
|||||||
Syncable syncable = ObjectSyncCache.GetSyncable(data.objectId);
|
Syncable syncable = ObjectSyncCache.GetSyncable(data.objectId);
|
||||||
if (syncable == null)
|
if (syncable == null)
|
||||||
{
|
{
|
||||||
MelonLogger.Msg("Syncable not found for id: " + data.objectId);
|
MelonLogger.Msg("SyncEvent: Syncable not found for id: " + data.objectId);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
syncable.ApplyObjectSyncTransforms(data.objectSyncTransforms);
|
syncable.ApplyObjectSyncTransforms(data.objectSyncTransforms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void OnObjectDamageMessage(ObjectDamageMessage damageMessge)
|
||||||
|
{
|
||||||
|
|
||||||
|
ObjectDamageInfo damageInfo = damageMessge.objectEventInfo;
|
||||||
|
if (damageInfo.objectId == 0) return;
|
||||||
|
Syncable syncable = ObjectSyncCache.GetSyncable(damageInfo.objectId);
|
||||||
|
if (syncable == null)
|
||||||
|
{
|
||||||
|
MelonLogger.Msg("DamageEvent: Syncable not found for id: " + damageInfo.objectId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
syncable.Damage(damageInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SendObjectDamageMessage(Syncable syncable, ObjectDamageType damageType, ObjectHealthInfo healthInfo)
|
||||||
|
{
|
||||||
|
ObjectDamageInfo damageInfo = new ObjectDamageInfo()
|
||||||
|
{
|
||||||
|
objectId = syncable.GetSyncId(),
|
||||||
|
objectHealthInfo = healthInfo,
|
||||||
|
eventType = damageType,
|
||||||
|
};
|
||||||
|
ObjectDamageMessage message = new ObjectDamageMessage(damageInfo);
|
||||||
|
message.Broadcast();
|
||||||
|
message.Execute();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
140
BoneSync/Sync/ObjectSyncCache.cs
Normal file
140
BoneSync/Sync/ObjectSyncCache.cs
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
using BoneSync.Sync.Components;
|
||||||
|
using StressLevelZero.Interaction;
|
||||||
|
using StressLevelZero.Pool;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace BoneSync.Sync
|
||||||
|
{
|
||||||
|
public static class ObjectSyncCache
|
||||||
|
{
|
||||||
|
private static Dictionary<string, Syncable> _pathToSyncable = new Dictionary<string, Syncable>();
|
||||||
|
private static Dictionary<ushort, Syncable> _idToSyncable = new Dictionary<ushort, Syncable>();
|
||||||
|
private static Dictionary<Poolee, Syncable> _pooleeToSyncable = new Dictionary<Poolee, Syncable>();
|
||||||
|
private static Dictionary<InteractableHost, Syncable> _interactableHostToSyncable = new Dictionary<InteractableHost, Syncable>();
|
||||||
|
private static Dictionary<InteractableHostManager, Syncable> _interactableHostManagerToSyncable = new Dictionary<InteractableHostManager, Syncable>();
|
||||||
|
|
||||||
|
public static void AddSyncable(Syncable syncable)
|
||||||
|
{
|
||||||
|
string path = syncable.transform.GetPath();
|
||||||
|
if (path != null && path != "")
|
||||||
|
{
|
||||||
|
_pathToSyncable[path] = syncable;
|
||||||
|
}
|
||||||
|
if (syncable.GetSyncId() != 0)
|
||||||
|
{
|
||||||
|
_idToSyncable[syncable.GetSyncId()] = syncable;
|
||||||
|
}
|
||||||
|
if (syncable.interactableHost)
|
||||||
|
{
|
||||||
|
_interactableHostToSyncable[syncable.interactableHost] = syncable;
|
||||||
|
}
|
||||||
|
if (syncable.interactableManager)
|
||||||
|
{
|
||||||
|
_interactableHostManagerToSyncable[syncable.interactableManager] = syncable;
|
||||||
|
}
|
||||||
|
if (syncable.poolee)
|
||||||
|
{
|
||||||
|
_pooleeToSyncable[syncable.poolee] = syncable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void RemoveSyncable(Syncable syncable)
|
||||||
|
{
|
||||||
|
if (syncable.transform)
|
||||||
|
{
|
||||||
|
_pathToSyncable.Remove(syncable.transform.GetPath());
|
||||||
|
}
|
||||||
|
if (syncable.GetSyncId() != 0)
|
||||||
|
{
|
||||||
|
_idToSyncable.Remove(syncable.GetSyncId());
|
||||||
|
}
|
||||||
|
if (syncable.interactableHost)
|
||||||
|
{
|
||||||
|
_interactableHostToSyncable.Remove(syncable.interactableHost);
|
||||||
|
}
|
||||||
|
if (syncable.interactableManager)
|
||||||
|
{
|
||||||
|
_interactableHostManagerToSyncable.Remove(syncable.interactableManager);
|
||||||
|
}
|
||||||
|
if (syncable.poolee)
|
||||||
|
{
|
||||||
|
_pooleeToSyncable.Remove(syncable.poolee);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void UpdateSyncId(Syncable syncable)
|
||||||
|
{
|
||||||
|
// remove other enties where value is the same
|
||||||
|
foreach (KeyValuePair<ushort, Syncable> entry in _idToSyncable)
|
||||||
|
{
|
||||||
|
if (entry.Value == syncable)
|
||||||
|
{
|
||||||
|
_idToSyncable.Remove(entry.Key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ushort id = syncable.GetSyncId();
|
||||||
|
if (_idToSyncable.ContainsKey(id))
|
||||||
|
{
|
||||||
|
_idToSyncable.Remove(id);
|
||||||
|
}
|
||||||
|
_idToSyncable[id] = syncable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Syncable GetSyncable(string path)
|
||||||
|
{
|
||||||
|
if (_pathToSyncable.ContainsKey(path))
|
||||||
|
{
|
||||||
|
return _pathToSyncable[path];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Syncable GetSyncable(ushort id)
|
||||||
|
{
|
||||||
|
if (_idToSyncable.ContainsKey(id))
|
||||||
|
{
|
||||||
|
return _idToSyncable[id];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Syncable GetSyncable(Poolee poolee)
|
||||||
|
{
|
||||||
|
if (_pooleeToSyncable.ContainsKey(poolee))
|
||||||
|
{
|
||||||
|
return _pooleeToSyncable[poolee];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Syncable GetSyncable(InteractableHost interactableHost)
|
||||||
|
{
|
||||||
|
if (_interactableHostToSyncable.ContainsKey(interactableHost))
|
||||||
|
{
|
||||||
|
return _interactableHostToSyncable[interactableHost];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Syncable GetSyncable(InteractableHostManager interactableHostManager)
|
||||||
|
{
|
||||||
|
if (_interactableHostManagerToSyncable.ContainsKey(interactableHostManager))
|
||||||
|
{
|
||||||
|
return _interactableHostManagerToSyncable[interactableHostManager];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DISCARD_ALL_SYNCABLES()
|
||||||
|
{
|
||||||
|
foreach (Syncable syncable in Syncable.syncablesCache.Values)
|
||||||
|
{
|
||||||
|
syncable.DiscardSyncable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user