From 252f6ba49a456f6fa873cd020220dec1f30e9772 Mon Sep 17 00:00:00 2001 From: Aaro Varis Date: Sat, 8 Mar 2025 17:45:29 +0200 Subject: [PATCH] Player Sync stuff --- BoneSync/BoneSync.csproj | 7 +- BoneSync/Data/ByteEncoder.cs | 25 +- BoneSync/MelonLoaderMod.cs | 24 +- .../LobbyManager/SteamLobbyManager.cs | 3 +- .../Networking/Messages/GunSyncMessage.cs | 7 +- .../Networking/Messages/PlayerSyncMessage.cs | 30 ++- .../Messages/SimpleSyncableEventMessage.cs | 4 +- BoneSync/Player/PlayerRig.cs | 246 +++++++++++++++++- BoneSync/Sync/Components/SyncableAI.cs | 15 ++ BoneSync/Sync/Components/SyncableBase.cs | 6 +- .../Sync/Components/SyncableNetworking.cs | 6 +- BoneSync/Sync/Components/SyncablePhysics.cs | 73 +++++- BoneSync/Sync/PlayerSync.cs | 24 +- 13 files changed, 424 insertions(+), 46 deletions(-) create mode 100644 BoneSync/Sync/Components/SyncableAI.cs diff --git a/BoneSync/BoneSync.csproj b/BoneSync/BoneSync.csproj index da32c39..671feac 100644 --- a/BoneSync/BoneSync.csproj +++ b/BoneSync/BoneSync.csproj @@ -75,6 +75,10 @@ False ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\BONEWORKS\BONEWORKS\MelonLoader\Managed\UnityEngine.AnimationModule.dll + + False + A:\SteamLibrary\steamapps\common\BONEWORKS\BONEWORKS\MelonLoader\Managed\UnityEngine.AssetBundleModule.dll + ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\BONEWORKS\BONEWORKS\MelonLoader\Managed\UnityEngine.CoreModule.dll @@ -105,6 +109,7 @@ + @@ -280,7 +285,7 @@ - + diff --git a/BoneSync/Data/ByteEncoder.cs b/BoneSync/Data/ByteEncoder.cs index 49a6874..e23f804 100644 --- a/BoneSync/Data/ByteEncoder.cs +++ b/BoneSync/Data/ByteEncoder.cs @@ -1,4 +1,5 @@ -using StressLevelZero; +using BoneSync.Networking.Messages; +using StressLevelZero; using StressLevelZero.Combat; using System; using System.Collections.Generic; @@ -302,5 +303,27 @@ namespace BoneSync.Data return mag; } + + public void WriteFingerCurl(SimpleFingerCurl fingerCurl) + { + WriteFloat(fingerCurl.thumb); + WriteFloat(fingerCurl.index); + WriteFloat(fingerCurl.middle); + WriteFloat(fingerCurl.ring); + WriteFloat(fingerCurl.pinky); + } + + public SimpleFingerCurl ReadFingerCurl() + { + SimpleFingerCurl fingerCurl = new SimpleFingerCurl() + { + thumb = ReadFloat(), + index = ReadFloat(), + middle = ReadFloat(), + ring = ReadFloat(), + pinky = ReadFloat() + }; + return fingerCurl; + } } } diff --git a/BoneSync/MelonLoaderMod.cs b/BoneSync/MelonLoaderMod.cs index be252c0..27b088b 100644 --- a/BoneSync/MelonLoaderMod.cs +++ b/BoneSync/MelonLoaderMod.cs @@ -9,6 +9,7 @@ using BoneSync.Sync; using Facepunch.Steamworks; using System.Reflection.Emit; using BoneSync.Data; +using BoneSync.Networking.Messages; namespace BoneSync { @@ -39,6 +40,8 @@ namespace BoneSync SpawnableManager.Initialize(); + PlayerRig.LoadBundle(); + PatchAll(); } @@ -57,6 +60,7 @@ namespace BoneSync { //MelonLogger.Msg("OnLevelWasInitialized: " + sceneName); SceneSync.OnSceneInit(buildIndex); + PlayerScripts.GetPlayerScripts(); } public override void OnSceneWasUnloaded(int buildIndex, string sceneName) @@ -79,6 +83,24 @@ namespace BoneSync { lobby.CreateLobby(); } + + if (Input.GetKeyDown(KeyCode.L)) + { + MelonLogger.Msg("Reloading bundle"); + PlayerRig.LoadBundle(); + } + + if (Input.GetKeyDown(KeyCode.N)) + { + MelonLogger.Msg("Creting debug player rig"); + PlayerRig debugRig = PlayerRig.GetPlayerRig(0); + PlayerSyncInfo? playerSyncInfo = PlayerRig.GetLocalSyncInfo(); + if (!playerSyncInfo.HasValue) + { + MelonLogger.Msg("PlayerSyncInfo is null"); + } + debugRig.UpdatePlayerSync(playerSyncInfo.Value); + } } public override void BONEWORKS_OnLoadingScreen() @@ -88,7 +110,7 @@ namespace BoneSync public override void OnFixedUpdate() { - //MelonLogger.Msg("OnFixedUpdate"); + PlayerRig.Tick(); } public override void OnLateUpdate() diff --git a/BoneSync/Networking/LobbyManager/SteamLobbyManager.cs b/BoneSync/Networking/LobbyManager/SteamLobbyManager.cs index afd656c..0bfeb12 100644 --- a/BoneSync/Networking/LobbyManager/SteamLobbyManager.cs +++ b/BoneSync/Networking/LobbyManager/SteamLobbyManager.cs @@ -1,4 +1,5 @@ -using BoneSync.Sync; +using BoneSync.Player; +using BoneSync.Sync; using Facepunch.Steamworks; using Facepunch.Steamworks.Data; using MelonLoader; diff --git a/BoneSync/Networking/Messages/GunSyncMessage.cs b/BoneSync/Networking/Messages/GunSyncMessage.cs index 877873f..08989c1 100644 --- a/BoneSync/Networking/Messages/GunSyncMessage.cs +++ b/BoneSync/Networking/Messages/GunSyncMessage.cs @@ -38,6 +38,7 @@ namespace BoneSync.Networking.Messages byteEncoder.WriteByte((byte)gunSyncInfo.messageType); byteEncoder.WriteByte((byte)gunSyncInfo.hammerState); byteEncoder.WriteByte((byte)gunSyncInfo.cartridgeState); + byteEncoder.WriteBool(gunSyncInfo.bulletObject != null); byteEncoder.WriteAmmoVariables(gunSyncInfo.bulletObject.ammoVariables); @@ -49,11 +50,9 @@ namespace BoneSync.Networking.Messages gunSyncInfo.messageType = (GunSyncMessageType)byteEncoder.ReadByte(); gunSyncInfo.hammerState = (Gun.HammerStates)byteEncoder.ReadByte(); gunSyncInfo.cartridgeState = (Gun.CartridgeStates)byteEncoder.ReadByte(); + if (byteEncoder.ReadBool()) { // If bulletObject is not null - gunSyncInfo.bulletObject = new BulletObject() - { - ammoVariables = byteEncoder.ReadAmmoVariables() - }; + gunSyncInfo.bulletObject = new BulletObject() { ammoVariables = byteEncoder.ReadAmmoVariables() }; } } diff --git a/BoneSync/Networking/Messages/PlayerSyncMessage.cs b/BoneSync/Networking/Messages/PlayerSyncMessage.cs index 975d484..c3a03b4 100644 --- a/BoneSync/Networking/Messages/PlayerSyncMessage.cs +++ b/BoneSync/Networking/Messages/PlayerSyncMessage.cs @@ -2,23 +2,43 @@ using BoneSync.Data; using BoneSync.Sync; +using StressLevelZero.Player; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using UnityEngine; namespace BoneSync.Networking.Messages { - + public struct SimpleFingerCurl + { + public float thumb; + public float index; + public float middle; + public float ring; + public float pinky; + public SimpleFingerCurl(FingerCurl fingerCurl) + { + thumb = fingerCurl.thumb; + index = fingerCurl.index; + middle = fingerCurl.middle; + ring = fingerCurl.ring; + pinky = fingerCurl.pinky; + } + } public struct PlayerSyncInfo { + public Vector3 rootPos; public SimpleSyncTransform headPos; public SimpleSyncTransform leftHandPos; public SimpleSyncTransform rightHandPos; + public SimpleFingerCurl leftHandFingerCurl; + public SimpleFingerCurl rightHandFingerCurl; } - [PacketType(PacketType.PlayerSync)] + [PacketType(PacketType.PlayerSync), PacketReliability(PacketReliability.Unreliable)] internal class PlayerSyncMessage : NetworkMessage { private PlayerSyncInfo _playerSyncInfo; @@ -27,17 +47,23 @@ namespace BoneSync.Networking.Messages public PlayerSyncMessage(PlayerSyncInfo playerSyncInfo) { _playerSyncInfo = playerSyncInfo; + byteEncoder.WriteVector3(_playerSyncInfo.rootPos); byteEncoder.WriteSimpleTransform(_playerSyncInfo.headPos); byteEncoder.WriteSimpleTransform(_playerSyncInfo.leftHandPos); byteEncoder.WriteSimpleTransform(_playerSyncInfo.rightHandPos); + byteEncoder.WriteFingerCurl(_playerSyncInfo.leftHandFingerCurl); + byteEncoder.WriteFingerCurl(_playerSyncInfo.rightHandFingerCurl); } public PlayerSyncMessage(Packet packet) { byteEncoder.WriteBytes(packet.Data); + _playerSyncInfo.rootPos = byteEncoder.ReadVector3(); _playerSyncInfo.headPos = byteEncoder.ReadSimpleTransform(); _playerSyncInfo.leftHandPos = byteEncoder.ReadSimpleTransform(); _playerSyncInfo.rightHandPos = byteEncoder.ReadSimpleTransform(); + _playerSyncInfo.leftHandFingerCurl = byteEncoder.ReadFingerCurl(); + _playerSyncInfo.rightHandFingerCurl = byteEncoder.ReadFingerCurl(); } public override void Execute() diff --git a/BoneSync/Networking/Messages/SimpleSyncableEventMessage.cs b/BoneSync/Networking/Messages/SimpleSyncableEventMessage.cs index 93f6fbb..e199533 100644 --- a/BoneSync/Networking/Messages/SimpleSyncableEventMessage.cs +++ b/BoneSync/Networking/Messages/SimpleSyncableEventMessage.cs @@ -12,7 +12,9 @@ namespace BoneSync.Networking.Messages { None = 0, OnDevicePull = 1, - OnDeviceRelease = 2 + OnDeviceRelease = 2, + OnButtonPress = 3, + OnButtonRelease = 4, } public struct SimpleSyncableEvent { diff --git a/BoneSync/Player/PlayerRig.cs b/BoneSync/Player/PlayerRig.cs index fc430ab..51fc782 100644 --- a/BoneSync/Player/PlayerRig.cs +++ b/BoneSync/Player/PlayerRig.cs @@ -11,39 +11,269 @@ using StressLevelZero.Player; using StressLevelZero.VRMK; using BoneSync.Networking; using BoneSync.Networking.Messages; +using System.Reflection; +using System.IO; +using BoneSync.Data; +using StressLevelZero.Interaction; +using UnhollowerBaseLib; namespace BoneSync.Player { + public static class EmebeddedAssetBundle + { + // Credit to the "Entanglement" mod. The playerrep asset bundle is also by them. + public static AssetBundle LoadFromAssembly(string name) + { + Assembly assembly = Assembly.GetExecutingAssembly(); + string[] manifestResources = assembly.GetManifestResourceNames(); + + if (manifestResources.Contains(name)) + { + MelonLogger.Msg($"Loading embedded bundle data {name}..."); + + byte[] bytes; + using (Stream str = assembly.GetManifestResourceStream(name)) + using (MemoryStream memoryStream = new MemoryStream()) + { + str.CopyTo(memoryStream); + bytes = memoryStream.ToArray(); + } + + MelonLogger.Msg($"Loading bundle from data {name}, please be patient..."); + AssetBundle temp = AssetBundle.LoadFromMemory(bytes); + MelonLogger.Msg($"Done!"); + return temp; + } + + return null; + } + } + internal class PlayerRig { - //public const string RIGMANAGER_SCENE_NAME = "[RigManager (Default Brett)]"; + private const float RIG_SYNC_FPS = 30; - private static List _playerRigs = new List(); + public static AssetBundle rigBundle; + private static float _lastLocalSyncTime = 0; + private static Dictionary _playerRigs = new Dictionary(); + + private ulong _ownerId; private GameObject playerRig; - private RigManager rigManager; private SLZ_Body body; private CharacterAnimationManager characterAnimationManager; - private Animator repAnimator; + private Animator animator; + private Transform headTransform; + private Transform leftHandTransform; + private Transform rightHandTransform; + + public static void LoadBundle() + { + rigBundle = EmebeddedAssetBundle.LoadFromAssembly("BoneSync.playerrep.eres"); + + if (rigBundle == null) + throw new NullReferenceException("playerRepBundle is null! Did you forget to compile the player bundle into the dll?"); + + + MelonLogger.Msg("Loaded playerRepBundle success"); + } + + public static void Tick() + { + foreach (PlayerRig playerRig in _playerRigs.Values) + { + playerRig.UpdateIK(); + } + + if (Time.time - _lastLocalSyncTime > 1 / RIG_SYNC_FPS) + { + SendLocalPlayerSync(); + _lastLocalSyncTime = Time.time; + } + } + + + private void SetFingerCurl(Handedness handedness, SimpleFingerCurl fingerCurl) + { + characterAnimationManager.ApplyFingerCurl(handedness, 1f - fingerCurl.thumb, 1f - fingerCurl.index, 1f - fingerCurl.middle, 1f - fingerCurl.ring, 1f - fingerCurl.pinky); + } public void UpdatePlayerSync(PlayerSyncInfo playerSyncInfo) { - //playerRig.transform.ApplySimpleTransform(playerSyncInfo.headPos); + playerRig.transform.position = playerSyncInfo.rootPos; + + headTransform.ApplySimpleTransform(playerSyncInfo.headPos); + leftHandTransform.ApplySimpleTransform(playerSyncInfo.leftHandPos); + rightHandTransform.ApplySimpleTransform(playerSyncInfo.rightHandPos); + + SetFingerCurl(Handedness.LEFT, playerSyncInfo.leftHandFingerCurl); + SetFingerCurl(Handedness.RIGHT, playerSyncInfo.rightHandFingerCurl); } - public PlayerRig() + public static PlayerSyncInfo? GetLocalSyncInfo() { + GameObject localPlayerRig = GameObject.Find("[RigManager (Default Brett)]/[SkeletonRig (GameWorld Brett)]"); + if (localPlayerRig == null) + { + MelonLogger.Msg("Local player rig not found"); + return null; + } + Transform root = localPlayerRig.transform; - _playerRigs.Add(this); + Transform localHeadTransform = root.Find("Head"); + Transform localLeftHandTransform = root.Find("Hand (left)"); + Transform localRightHandTransform = root.Find("Hand (right)"); + + if (localHeadTransform == null || localLeftHandTransform == null || localRightHandTransform == null) + { + MelonLogger.Msg("Local player rig components not found"); + return null; + } + + PlayerSyncInfo playerSyncInfo = new PlayerSyncInfo() + { + rootPos = root.position, + headPos = new SimpleSyncTransform(localHeadTransform), + leftHandPos = new SimpleSyncTransform(localLeftHandTransform), + rightHandPos = new SimpleSyncTransform(localRightHandTransform), + //leftHandFingerCurl = new SimpleFingerCurl(PlayerScripts.playerLeftHand.fingerCurl), + //rightHandFingerCurl = new SimpleFingerCurl(PlayerScripts.playerRightHand.fingerCurl) + + }; + + return playerSyncInfo; + } + + private static void SendLocalPlayerSync() + { + if (!BoneSync.lobby.IsConnected()) return; + PlayerSyncInfo? playerSyncInfo = GetLocalSyncInfo(); + if (!playerSyncInfo.HasValue) return; + PlayerSyncMessage playerSyncMessage = new PlayerSyncMessage(playerSyncInfo.Value); + playerSyncMessage.Broadcast(); + } + + public static PlayerRig GetPlayerRig(ulong ownerId) + { + if (_playerRigs.ContainsKey(ownerId)) + { + MelonLogger.Msg("PlayerRig already exists for " + ownerId); + return _playerRigs[ownerId]; + } + + if (rigBundle == null) + { + MelonLogger.Msg("playerRepBundle is null! Did you forget to load the bundle?"); + return null; + } + PlayerRig rig = new PlayerRig(ownerId); + rig.EnsurePlayerRig(); + return rig; + } + + public static void DestroyRig(ulong ownerId) + { + if (_playerRigs.ContainsKey(ownerId)) + { + _playerRigs[ownerId].Destroy(); + } + } + + private void EnsurePlayerRig() { + if (playerRig != null) return; + + playerRig = GameObject.Instantiate(rigBundle.LoadAsset("PlayerRep")); + playerRig.name = "PlayerRep"; + + body = playerRig.GetComponentInChildren(); + characterAnimationManager = playerRig.GetComponentInChildren(); + animator = playerRig.GetComponentInChildren(); + + headTransform = playerRig.transform.Find("Head"); + leftHandTransform = playerRig.transform.Find("Hand (left)"); + rightHandTransform = playerRig.transform.Find("Hand (right)"); + + body.OnStart(); + + } + + public void UpdateIK() + { + // Catch errors so other players arent broken + try + { + EnsurePlayerRig(); + //Re-Apply playermodel if unloaded + //if ((!currentSkinBundle || !currentSkinObject) && isCustomSkinned) + // PlayerSkinLoader.ApplyPlayermodel(this, currentSkinPath); + // Prevent exceptions if we are in the middle of deleting a playermodel + if (!animator) + return; + + animator.Update(Time.fixedDeltaTime); + characterAnimationManager.OnLateUpdate(); + Vector3 repInputVel = Vector3.zero; + + body.FullBodyUpdate(repInputVel, Vector3.zero); + body.ArtToBlender.UpdateBlender(); + } + catch { } + } + + + private PlayerRig(ulong id) + { + _playerRigs.Add(id, this); + _ownerId = id; } public void Destroy() { - _playerRigs.Remove(this); + _playerRigs.Remove(_ownerId); GameObject.Destroy(playerRig); } } + + // copied from Entanglement mod + public static class PlayerScripts + { + public static RigManager playerRig; + public static PhysBody playerPhysBody; + public static Player_Health playerHealth; + public static PhysGrounder playerGrounder; + public static Hand playerLeftHand; + public static Hand playerRightHand; + public static bool reloadLevelOnDeath; + public static RuntimeAnimatorController playerAnimatorController; + public static Il2CppStringArray playerHandPoses = null; + + public static void GetPlayerScripts() + { + GameObject localPlayerRig = GameObject.Find("[RigManager (Default Brett)]/[SkeletonRig (GameWorld Brett)]"); + playerRig = localPlayerRig.GetComponentInChildren(); + playerHealth = playerRig.playerHealth; + + reloadLevelOnDeath = playerHealth.reloadLevelOnDeath; + + playerHealth.reloadLevelOnDeath = !BoneSync.lobby.IsConnected(); + + PhysicsRig physicsRig = playerRig.physicsRig; + playerPhysBody = physicsRig.physBody; + playerGrounder = playerPhysBody.physG; + playerLeftHand = physicsRig.leftHand; + playerRightHand = physicsRig.rightHand; + playerAnimatorController = playerRig.gameWorldSkeletonRig.characterAnimationManager.animator.runtimeAnimatorController; + GetHandPoses(); + } + + public static void GetHandPoses() + { + // Checks if we already got the hand poses to prevent crashes + if (playerHandPoses == null) + CharacterAnimationManager.FetchHandPoseList(out playerHandPoses); // Lets hope this is constant! + } + } } diff --git a/BoneSync/Sync/Components/SyncableAI.cs b/BoneSync/Sync/Components/SyncableAI.cs new file mode 100644 index 0000000..67692a9 --- /dev/null +++ b/BoneSync/Sync/Components/SyncableAI.cs @@ -0,0 +1,15 @@ +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 + { + + + } +} diff --git a/BoneSync/Sync/Components/SyncableBase.cs b/BoneSync/Sync/Components/SyncableBase.cs index e6dface..a6e4fee 100644 --- a/BoneSync/Sync/Components/SyncableBase.cs +++ b/BoneSync/Sync/Components/SyncableBase.cs @@ -122,6 +122,7 @@ namespace BoneSync.Sync.Components private PuppetMaster puppetMaster; private PullDevice pullDevice; + private ButtonToggle[] buttonToggles; private SpawnFragment spawnFragment; @@ -192,6 +193,9 @@ namespace BoneSync.Sync.Components gun = GetComponent(); magazine = GetComponent(); sockets = GetComponentsInChildren(); + aiBrain = GetComponent(); + buttonToggles = GetComponentsInChildren(); + puppetMaster = aiBrain.puppetMaster; if (sockets.Length == 0) { plugs = GetComponentsInChildren(); @@ -202,7 +206,7 @@ namespace BoneSync.Sync.Components spawnFragment = GetComponent(); UpdateTransformList(); - _TryPatchPullDevice(); + TryPatchUnityEvents(); ObjectSyncCache.AddSyncable(this); } diff --git a/BoneSync/Sync/Components/SyncableNetworking.cs b/BoneSync/Sync/Components/SyncableNetworking.cs index 82d982a..45b1c40 100644 --- a/BoneSync/Sync/Components/SyncableNetworking.cs +++ b/BoneSync/Sync/Components/SyncableNetworking.cs @@ -124,12 +124,14 @@ namespace BoneSync.Sync.Components return true; } - private void _SendSimpleEvent(SimpleEventType eType) + private void _SendSimpleEvent(SimpleEventType eType, byte index = 0) { + MelonLogger.Msg("Sending simple event: " + eType); SimpleSyncableEvent data = new SimpleSyncableEvent() { syncId = _syncId, - eventType = eType + eventType = eType, + index = index }; SimpleSyncableEventMessage simpleSyncEvent = new SimpleSyncableEventMessage(data); diff --git a/BoneSync/Sync/Components/SyncablePhysics.cs b/BoneSync/Sync/Components/SyncablePhysics.cs index d8651bd..ce94609 100644 --- a/BoneSync/Sync/Components/SyncablePhysics.cs +++ b/BoneSync/Sync/Components/SyncablePhysics.cs @@ -4,6 +4,7 @@ using BoneSync.Networking.Messages; using BoneSync.Patching; using Facepunch.Steamworks; using MelonLoader; +using StressLevelZero.Interaction; using System; using System.Collections.Generic; using System.Linq; @@ -13,22 +14,65 @@ using UnityEngine; using UnityEngine.Events; namespace BoneSync.Sync.Components { + public static class UnityEventExtentions + { + public static void AddListenerWithArgsRaw(this UnityEvent unityEvent, Action action, object[] args) + { + unityEvent.AddListener((UnityAction)(() => action(args))); + } + + public static void AddListenerWithArgs(this UnityEvent unityEvent, Action action, params object[] args) + { + unityEvent.AddListenerWithArgsRaw((object[] argss) => action((T)argss[0], argss), args); + } + } public partial class Syncable : MonoBehaviour { + private HashSet patchedButtonToggles = new HashSet(); private bool pullDevicePatched = false; + void ButtonOnPress(ButtonToggle toggle) + { + MelonLogger.Msg("ButtonToggle:OnPress " + toggle.transform.GetPath()); + byte index = (byte)Array.IndexOf(buttonToggles, toggle); + MelonLogger.Msg("ButtonToggle:OnPress"); + if (!isOwner) { return; } + _SendSimpleEvent(SimpleEventType.OnButtonPress, index); + } + void ButtonOnRelease(ButtonToggle toggle) + { + MelonLogger.Msg("ButtonToggle:OnRelease " + toggle.transform.GetPath()); + byte index = (byte)Array.IndexOf(buttonToggles, toggle); + if (!isOwner) { return; } + _SendSimpleEvent(SimpleEventType.OnButtonRelease, index); + } + void DeviceOnPull() { - MelonLogger.Msg("OnPull"); if (!isOwner) { return; } _SendSimpleEvent(SimpleEventType.OnDevicePull); } void DeviceOnRelease() { - MelonLogger.Msg("OnRelease"); if (!isOwner) { return; } _SendSimpleEvent(SimpleEventType.OnDeviceRelease); } + + private void TryPatchUnityEvents() + { + try + { + _TryPatchPullDevice(); + foreach (ButtonToggle buttonToggle in GetComponentsInChildren()) + { + _TryPatchButtonToggle(buttonToggle); + } + } catch (Exception e) + { + MelonLogger.Error("Failed to patch UnityEvents: " + e); + } + } + private void _TryPatchPullDevice() { if (pullDevicePatched) return; @@ -38,6 +82,16 @@ namespace BoneSync.Sync.Components pullDevicePatched = true; } + private void _TryPatchButtonToggle(ButtonToggle buttonToggle) + { + if (patchedButtonToggles.Contains(buttonToggle)) return; + MelonLogger.Msg("Patching ButtonToggle: " + buttonToggle.transform.GetPath()); + buttonToggle.onPress.AddListenerWithArgs((btn, args) => ButtonOnPress(btn), buttonToggle); + buttonToggle.onDepress.AddListenerWithArgs((btn, args) => ButtonOnRelease(btn), buttonToggle); + + patchedButtonToggles.Add(buttonToggle); + } + public bool AllRigidbodiesSleeping() { if (rigidbodies.Length == 0) return false; @@ -158,6 +212,7 @@ namespace BoneSync.Sync.Components { MelonLogger.Msg("OnSimpleSyncableEvent: " + eventData.eventType); SimpleEventType eType = eventData.eventType; + byte index = eventData.index; switch (eType) { case SimpleEventType.OnDevicePull: pullDevice?.OnHandlePull?.Invoke(); @@ -165,6 +220,20 @@ namespace BoneSync.Sync.Components case SimpleEventType.OnDeviceRelease: pullDevice?.OnHandleReturn?.Invoke(); break; + case SimpleEventType.OnButtonPress: + if (index < buttonToggles.Length) + { + buttonToggles[index]?.onPress.Invoke(); + } + break; + case SimpleEventType.OnButtonRelease: + if (index < buttonToggles.Length) + { + buttonToggles[index]?.onDepress.Invoke(); + } + break; + + } } // on collision diff --git a/BoneSync/Sync/PlayerSync.cs b/BoneSync/Sync/PlayerSync.cs index a8850e7..049d652 100644 --- a/BoneSync/Sync/PlayerSync.cs +++ b/BoneSync/Sync/PlayerSync.cs @@ -16,27 +16,6 @@ namespace BoneSync.Sync private static GameObject _localPlayerRig; - private static Dictionary _playerRigMap = new Dictionary(); - private static PlayerRig GetPlayerRig(ulong playerId) - { - if (!_playerRigMap.ContainsKey(playerId)) - { - PlayerRig playerRig = new PlayerRig(); - _playerRigMap.Add(playerId, playerRig); - } - - return _playerRigMap[playerId]; - } - - public static void CleanUp() - { - foreach (PlayerRig playerRig in _playerRigMap.Values) - { - playerRig.Destroy(); - } - _playerRigMap.Clear(); - } - public static void SyncPlayer() { PlayerSyncInfo playerSyncInfo = new PlayerSyncInfo(); @@ -50,7 +29,8 @@ namespace BoneSync.Sync public static void OnPlayerSync(PlayerSyncMessage playerSyncMessage) { - PlayerRig playerRig = GetPlayerRig(playerSyncMessage.senderId); + PlayerRig playerRig = PlayerRig.GetPlayerRig(playerSyncMessage.senderId); + if (playerRig == null) return; playerRig.UpdatePlayerSync(playerSyncMessage.playerSyncInfo); }