PlugSync stuff

This commit is contained in:
2025-03-05 15:35:18 +02:00
parent 8c887ae0e4
commit 4bd96e59bd
11 changed files with 275 additions and 15 deletions

View File

@@ -93,7 +93,9 @@
<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\PlugSyncMessage.cs" />
<Compile Include="Networking\Messages\RegisterSyncableMessage.cs" /> <Compile Include="Networking\Messages\RegisterSyncableMessage.cs" />
<Compile Include="Networking\Messages\SimpleSyncableEventMessage.cs" />
<Compile Include="Patching\CallPatchedMethod.cs" /> <Compile Include="Patching\CallPatchedMethod.cs" />
<Compile Include="Patching\DebugPatches.cs" /> <Compile Include="Patching\DebugPatches.cs" />
<Compile Include="Patching\GripPatches.cs" /> <Compile Include="Patching\GripPatches.cs" />

View File

@@ -0,0 +1,67 @@
using BoneSync.Sync;
using BoneSync.Sync.Components;
using StressLevelZero.Interaction;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BoneSync.Networking.Messages
{
public struct PlugSyncMessageData
{
public ushort plugSyncId;
public byte plugIndex;
public ushort socketSyncId;
public byte socketIndex;
}
[PacketType(PacketType.PlugSync), PacketReliability(PacketReliability.ReliableFast)]
internal class PlugSyncMessage : NetworkMessage
{
private PlugSyncMessageData messageData;
public PlugSyncMessage(PlugSyncMessageData plugSyncMessageData)
{
this.messageData = plugSyncMessageData;
byteEncoder.WriteUShort(plugSyncMessageData.plugSyncId);
byteEncoder.WriteByte(plugSyncMessageData.plugIndex);
byteEncoder.WriteUShort(plugSyncMessageData.socketSyncId);
byteEncoder.WriteByte(plugSyncMessageData.socketIndex);
}
public PlugSyncMessage(Packet packet) {
byteEncoder.WriteBytes(packet.Data);
messageData.plugSyncId = byteEncoder.ReadUShort();
messageData.plugIndex = byteEncoder.ReadByte();
messageData.socketSyncId = byteEncoder.ReadUShort();
messageData.socketIndex = byteEncoder.ReadByte();
}
public override void Execute()
{
Syncable plugSyncable = ObjectSyncCache.GetSyncable(messageData.plugSyncId);
Syncable socketSyncable = ObjectSyncCache.GetSyncable(messageData.socketSyncId);
if (!plugSyncable || messageData.plugIndex == byte.MaxValue) { return; }
AlignPlug plug = (AlignPlug)plugSyncable.GetPlugFromId(messageData.plugIndex);
if (plug == null) { return; }
if (!socketSyncable || messageData.socketIndex == byte.MaxValue) {
plug.SafeEject();
return;
}
Socket socket = socketSyncable.GetSocketFromId(messageData.socketIndex);
if (socket == null)
{
plug.SafeEject();
return;
}
plug.SafeInsert(socket);
}
}
}

View File

@@ -0,0 +1,50 @@
using BoneSync.Sync;
using BoneSync.Sync.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BoneSync.Networking.Messages
{
public enum SimpleEventType
{
None = 0,
OnDevicePull = 1,
OnDeviceRelease = 2
}
public struct SimpleSyncableEvent
{
public ushort syncId;
public SimpleEventType eventType;
//public object[] args;
}
[PacketType(PacketType.SimpleObjectEventSync)]
public class SimpleSyncableEventMessage : NetworkMessage
{
private SimpleSyncableEvent eventData;
public SimpleSyncableEventMessage(SimpleSyncableEvent simpleSyncableEvent)
{
eventData = simpleSyncableEvent;
byteEncoder.WriteULong(simpleSyncableEvent.syncId);
byteEncoder.WriteByte((byte)simpleSyncableEvent.eventType);
}
public SimpleSyncableEventMessage(Packet packet)
{
byteEncoder.WriteBytes(packet.Data);
eventData.syncId = byteEncoder.ReadUShort();
eventData.eventType = (SimpleEventType)byteEncoder.ReadByte();
}
public override void Execute()
{
Syncable syncable = ObjectSyncCache.GetSyncable(eventData.syncId);
if (syncable == null) return;
syncable.OnSimpleSyncableEvent(eventData);
}
}
}

View File

@@ -18,5 +18,7 @@ namespace BoneSync.Networking
DiscardSyncable = 7, DiscardSyncable = 7,
MagazineSync = 8, MagazineSync = 8,
GunSync = 9, GunSync = 9,
SimpleObjectEventSync = 10,
PlugSync = 11,
} }
} }

View File

@@ -11,7 +11,7 @@ using UnityEngine;
namespace BoneSync.Patching namespace BoneSync.Patching
{ {
[HarmonyPatch(typeof(PoolSpawner))] /*[HarmonyPatch(typeof(PoolSpawner))]
internal class DebugPatches internal class DebugPatches
{ {
// patch the static method "PoolSpawner.SpawnProjectile" // patch the static method "PoolSpawner.SpawnProjectile"
@@ -20,5 +20,6 @@ namespace BoneSync.Patching
{ {
MelonLoader.MelonLogger.Msg("PoolSpawner.SpawnProjectile " + weaponName); MelonLoader.MelonLogger.Msg("PoolSpawner.SpawnProjectile " + weaponName);
} }
} }*/
} }

View File

@@ -3,11 +3,13 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
using BoneSync.Networking.Messages;
using BoneSync.Sync; using BoneSync.Sync;
using BoneSync.Sync.Components; using BoneSync.Sync.Components;
using HarmonyLib; using HarmonyLib;
using MelonLoader; using MelonLoader;
using StressLevelZero.Interaction; using StressLevelZero.Interaction;
using static MelonLoader.MelonLogger;
namespace BoneSync.Patching namespace BoneSync.Patching
{ {
@@ -70,16 +72,66 @@ namespace BoneSync.Patching
[HarmonyPatch(typeof(AlignPlug))] [HarmonyPatch(typeof(AlignPlug))]
public static class AlignPlugPatches public static class AlignPlugPatches
{ {
public static void OnPlugSocketChange(AlignPlug plug, Socket socket)
{
Syncable plugSyncable = plug.GetComponentInParent<Syncable>();
Syncable socketSyncable = socket.GetComponentInParent<Syncable>();
if (!plugSyncable)
{
MelonLogger.Warning("PlugSyncable not found");
return;
}
if (!plugSyncable.Registered)
{
MelonLogger.Warning("PlugSyncable not registered");
return;
}
if (!socketSyncable)
{
MelonLogger.Warning("SocketSyncable not found");
}
if (socketSyncable && socketSyncable.isOwner && !plugSyncable.isOwner)
{
plugSyncable.TryBecomeOwner(true); // forcefully take ownership of the plug
}
byte plugId = plugSyncable.GetPlugId(plug);
byte socketId = socketSyncable ? socketSyncable.GetSocketId(socket) : byte.MaxValue;
MelonLogger.Msg("AlignPlug state: " + plug.transform.GetPath() + " Socket: " + socket.transform.GetPath() + " Plug ID: " + plugId + " Socket ID: " + socketId);
if (!plugSyncable.isOwner) return;
PlugSyncMessageData messageData = new PlugSyncMessageData
{
plugSyncId = plugSyncable.GetSyncId(),
plugIndex = plugId,
socketSyncId = socketSyncable ? socketSyncable.GetSyncId() : ushort.MinValue,
socketIndex = socketId
};
PlugSyncMessage plugSyncMessage = new PlugSyncMessage(messageData);
plugSyncMessage.Broadcast();
}
[HarmonyPatch(nameof(AlignPlug.InsertPlug)), HarmonyPostfix] [HarmonyPatch(nameof(AlignPlug.InsertPlug)), HarmonyPostfix]
public static void AlignPlugInsertPatch(AlignPlug __instance, Socket socket) public static void AlignPlugInsertPatch(AlignPlug __instance, Socket socket)
{ {
MelonLogger.Msg("AlignPlug inserted: " + __instance.transform.GetPath() + " Socket: " + socket.transform.GetPath()); MelonLogger.Msg("AlignPlug inserted: " + __instance.transform.GetPath() + " Socket: " + socket.transform.GetPath());
OnPlugSocketChange(__instance, socket);
} }
[HarmonyPatch(nameof(AlignPlug.EjectPlug)), HarmonyPostfix] [HarmonyPatch(nameof(AlignPlug.EjectPlug)), HarmonyPostfix]
public static void AlignPlugEjectPatch(AlignPlug __instance) public static void AlignPlugEjectPatch(AlignPlug __instance)
{ {
MelonLogger.Msg("AlignPlug ejected: " + __instance.transform.GetPath()); MelonLogger.Msg("AlignPlug ejected: " + __instance.transform.GetPath());
OnPlugSocketChange(__instance, null);
} }
} }

View File

@@ -185,6 +185,7 @@ namespace BoneSync.Sync.Components
spawnFragment = GetComponent<SpawnFragment>(); spawnFragment = GetComponent<SpawnFragment>();
UpdateTransformList(); UpdateTransformList();
_TryPatchPullDevice();
ObjectSyncCache.AddSyncable(this); ObjectSyncCache.AddSyncable(this);
} }

View File

@@ -86,19 +86,24 @@ namespace BoneSync.Sync.Components
} }
} }
public void TryBecomeOwner() public void TryBecomeOwner(bool force = false)
{ {
if (Registered && !isOwner) if (Registered && !isOwner)
{ {
MelonLogger.Msg("Attempting to become owner of " + _syncId); ulong localId = BoneSync.lobby.GetLocalId();
MelonLogger.Msg("Attempting to become owner of " + _syncId + " force: " + force);
OwnershipTransferMessageData data = new OwnershipTransferMessageData() OwnershipTransferMessageData data = new OwnershipTransferMessageData()
{ {
syncId = _syncId, syncId = _syncId,
NewOwnerId = BoneSync.lobby.GetLocalId(), NewOwnerId = localId,
force = false force = force
}; };
OwnershipTransferMessage message = new OwnershipTransferMessage(data); OwnershipTransferMessage message = new OwnershipTransferMessage(data);
message.Broadcast(); message.Broadcast();
if (force)
{
SetOwner(localId);
}
} }
} }
@@ -111,6 +116,18 @@ namespace BoneSync.Sync.Components
return true; return true;
} }
private void _SendSimpleEvent(SimpleEventType eType)
{
SimpleSyncableEvent data = new SimpleSyncableEvent()
{
syncId = _syncId,
eventType = eType
};
SimpleSyncableEventMessage simpleSyncEvent = new SimpleSyncableEventMessage(data);
simpleSyncEvent.Broadcast();
}
public ushort GetSyncId() => _syncId; public ushort GetSyncId() => _syncId;
public void SetSyncId(ushort id) public void SetSyncId(ushort id)
{ {

View File

@@ -17,15 +17,25 @@ namespace BoneSync.Sync.Components
{ {
private bool pullDevicePatched = false; private bool pullDevicePatched = false;
void OnPull() void DeviceOnPull()
{ {
MelonLogger.Msg("OnPull"); MelonLogger.Msg("OnPull");
if (!isOwner) { return; }
_SendSimpleEvent(SimpleEventType.OnDevicePull);
}
void DeviceOnRelease()
{
MelonLogger.Msg("OnRelease");
if (!isOwner) { return; }
_SendSimpleEvent(SimpleEventType.OnDeviceRelease);
} }
private void _TryPatchPullDevice() private void _TryPatchPullDevice()
{ {
if (pullDevicePatched) return; if (pullDevicePatched) return;
if (!pullDevice) return; if (!pullDevice) return;
pullDevice.OnHandlePull.AddListener((UnityAction)OnPull); pullDevice.OnHandlePull.AddListener((UnityAction)DeviceOnPull);
pullDevice.OnHandleReturn.AddListener((UnityAction)DeviceOnRelease);
pullDevicePatched = true;
} }
public bool AllRigidbodiesSleeping() public bool AllRigidbodiesSleeping()
@@ -45,6 +55,7 @@ namespace BoneSync.Sync.Components
private void SetKinematic(bool kinematic) private void SetKinematic(bool kinematic)
{ {
if (!this) return; if (!this) return;
if (rigidbodies.Length == 0) return;
foreach (Rigidbody rb in rigidbodies) foreach (Rigidbody rb in rigidbodies)
{ {
try try
@@ -119,6 +130,19 @@ namespace BoneSync.Sync.Components
SetKinematic(_ownerId != BoneSync.lobby.GetLocalId() && Registered); SetKinematic(_ownerId != BoneSync.lobby.GetLocalId() && Registered);
} }
internal void OnSimpleSyncableEvent(SimpleSyncableEvent eventData)
{
MelonLogger.Msg("OnSimpleSyncableEvent: " + eventData.eventType);
SimpleEventType eType = eventData.eventType;
switch (eType) {
case SimpleEventType.OnDevicePull:
pullDevice?.OnHandlePull?.Invoke();
break;
case SimpleEventType.OnDeviceRelease:
pullDevice?.OnHandleReturn?.Invoke();
break;
}
}
// on collision // on collision
} }
} }

View File

@@ -9,6 +9,39 @@ using StressLevelZero.Interaction;
namespace BoneSync.Sync.Components namespace BoneSync.Sync.Components
{ {
public static class PlugExtensions
{
public static Socket GetSocket(this AlignPlug plug)
{
Socket socket = plug._lastSocket;
if (!socket) return null;
if (socket.LockedPlug == plug)
{
return socket;
}
return null;
}
public static bool SafeEject(this AlignPlug plug)
{
if (!plug.GetSocket()) return false;
plug.EjectPlug();
return true;
}
public static bool SafeInsert(this AlignPlug plug, Socket socket)
{
if (!socket) return false;
if (socket.LockedPlug) return false;
if (plug.GetSocket() && plug._lastSocket != socket)
{
plug.EjectPlug();
plug.ClearFromSocket();
}
plug.InsertPlug(socket);
return true;
}
}
public partial class Syncable : MonoBehaviour public partial class Syncable : MonoBehaviour
{ {
public Plug GetPlugFromId(byte id) public Plug GetPlugFromId(byte id)
@@ -55,5 +88,6 @@ namespace BoneSync.Sync.Components
} }
return 255; return 255;
} }
} }
} }

View File

@@ -1,6 +1,7 @@
using BoneSync.Sync.Components; using BoneSync.Sync.Components;
using StressLevelZero.Interaction; using StressLevelZero.Interaction;
using StressLevelZero.Pool; using StressLevelZero.Pool;
using StressLevelZero.Props.Weapons;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
@@ -26,18 +27,27 @@ namespace BoneSync.Sync
return component.GetType().Namespace; return component.GetType().Namespace;
} }
private static bool IsSlzComponent(Component component) private static bool IsCachableComponent(MonoBehaviour component)
{ {
string ns = GetComponentNamespace(component); if (component is InteractableHost) return true;
return ns.StartsWith("StressLevelZero") || ns.StartsWith("BoneSync"); if (component is Poolee) return true;
if (component is Plug) return true;
if (component is Socket) return true;
if (component is AlignPlug) return true;
if (component is Gun) return true;
if (component is Magazine) return true;
return false;
//string ns = GetComponentNamespace(component);
//return ns.StartsWith("StressLevelZero") || ns.StartsWith("BoneSync");
} }
private static MonoBehaviour[] GetSLZComponents(Syncable syncable) private static MonoBehaviour[] GetComponentsToCache(Syncable syncable)
{ {
MonoBehaviour[] components = syncable.GetComponentsInChildren<MonoBehaviour>(true); MonoBehaviour[] components = syncable.GetComponentsInChildren<MonoBehaviour>(true);
List<MonoBehaviour> slzComponents = new List<MonoBehaviour>(); List<MonoBehaviour> slzComponents = new List<MonoBehaviour>();
for (int i = 0; i < components.Length; i++) for (int i = 0; i < components.Length; i++)
{ {
if (IsSlzComponent(components[i])) if (IsCachableComponent(components[i]))
{ {
slzComponents.Add(components[i]); slzComponents.Add(components[i]);
} }
@@ -46,7 +56,7 @@ namespace BoneSync.Sync
} }
private static void _AddSyncableComponents(Syncable syncable) private static void _AddSyncableComponents(Syncable syncable)
{ {
MonoBehaviour[] components = GetSLZComponents(syncable); MonoBehaviour[] components = GetComponentsToCache(syncable);
_syncableToComponent[syncable] = components; _syncableToComponent[syncable] = components;
foreach (MonoBehaviour component in components) foreach (MonoBehaviour component in components)
{ {