diff --git a/Multibonk/Game/GameEvents.cs b/Multibonk/Game/GameEvents.cs index f28b9f9..95c7040 100644 --- a/Multibonk/Game/GameEvents.cs +++ b/Multibonk/Game/GameEvents.cs @@ -39,6 +39,9 @@ internal static class GameEvents public static event Action SetIntEvent; public static event Action SetTriggerEvent; + public static event Action BaseInteractableSpawnedEvent; + public static event Action BaseInteractableDestroyedEvent; + public static void TriggerSetBool(Animator animator, string param, bool value) => SetBoolEvent?.Invoke(animator, param, value); public static void TriggerSetFloat(Animator animator, string param, float value) => SetFloatEvent?.Invoke(animator, param, value); @@ -79,5 +82,15 @@ public static void TriggerPlayerRotated(Quaternion newRotation) { PlayerRotateEvent?.Invoke(newRotation); } + + public static void TriggerBaseInteractableSpawned(BaseInteractable interactable) + { + BaseInteractableSpawnedEvent?.Invoke(interactable); + } + + public static void TriggerBaseInteractableDestroyed(int instanceId) + { + BaseInteractableDestroyedEvent?.Invoke(instanceId); + } } } diff --git a/Multibonk/Game/GameFunctions.cs b/Multibonk/Game/GameFunctions.cs index 2d809c6..8d4ebeb 100644 --- a/Multibonk/Game/GameFunctions.cs +++ b/Multibonk/Game/GameFunctions.cs @@ -92,6 +92,94 @@ public static void SpawnNetworkPlayer(ushort playerId, ECharacter character, Vec GamePatchFlags.PlayersCache.Add(playerId, new SpawnedNetworkPlayer(player)); } + + /// + /// Spawns a BaseInteractable in the scene from network data + /// + /// Instance ID of the interactable + /// Name of the prefab + /// World position + /// Rotation + /// Scale + /// Whether it is an item source + /// Whether to show outline + public static void SpawnNetworkInteractable( + int instanceId, + string prefabName, + Vector3 position, + Quaternion rotation, + Vector3 scale, + bool isItemSource, + bool showOutline) + { + try + { + // Try to find the original prefab in the scene + var originalObject = GameObject.Find(prefabName); + if (originalObject == null) + { + MelonLogger.Warning($"Could not find prefab {prefabName} in scene"); + return; + } + + // Instantiate a copy of the object + var obj = UnityEngine.Object.Instantiate(originalObject, position, rotation); + obj.name = $"{prefabName}_Network_{instanceId}"; + obj.transform.localScale = scale; + + // Get the BaseInteractable component + var interactable = obj.GetComponent(); + if (interactable != null) + { + interactable.isItemSource = isItemSource; + interactable.showOutline = showOutline; + + // Register in cache using the instanceId received from network + GamePatchFlags.TrackInteractable(instanceId, interactable); + + MelonLogger.Msg($"Spawned network interactable: {prefabName} (ID: {instanceId})"); + } + else + { + MelonLogger.Warning($"Object {prefabName} does not have BaseInteractable component"); + UnityEngine.Object.Destroy(obj); + } + } + catch (Exception ex) + { + MelonLogger.Error($"Error spawning interactable {prefabName}: {ex.Message}"); + } + } + + /// + /// Destroys a network-synchronized BaseInteractable + /// + /// Instance ID of the interactable + public static void DestroyNetworkInteractable(int instanceId) + { + try + { + var interactable = GamePatchFlags.GetTrackedInteractable(instanceId); + if (interactable != null && !interactable.IsNullOrDestroyed()) + { + MelonLogger.Msg($"Destroying network interactable (ID: {instanceId})"); + + // Remove from cache before destroying to avoid loops + GamePatchFlags.UntrackInteractable(instanceId); + + // Destroy the GameObject + UnityEngine.Object.Destroy(interactable.gameObject); + } + else + { + MelonLogger.Warning($"Attempted to destroy non-existent interactable (ID: {instanceId})"); + } + } + catch (Exception ex) + { + MelonLogger.Error($"Error destroying interactable {instanceId}: {ex.Message}"); + } + } } @@ -125,4 +213,3 @@ public void Rotate(Vector3 rotation) } } } - \ No newline at end of file diff --git a/Multibonk/Game/GamePatchFlags.cs b/Multibonk/Game/GamePatchFlags.cs index bf6649b..c9400c1 100644 --- a/Multibonk/Game/GamePatchFlags.cs +++ b/Multibonk/Game/GamePatchFlags.cs @@ -27,7 +27,8 @@ public static class GamePatchFlags /// public static List MapDataIndexedPrefabs { - get { + get + { if (SelectedMapData == null) return new List(); @@ -55,7 +56,11 @@ public static List MapDataIndexedPrefabs } } - public static Dictionary PlayersCache = new Dictionary(); + public static Dictionary PlayersCache = new Dictionary(); + + // Tracks BaseInteractables synchronized over the network + // Key: Unity InstanceID, Value: BaseInteractable + public static Dictionary InteractablesCache = new Dictionary(); public static int Seed { get; set; } = _rng.Next(int.MinValue, int.MaxValue); @@ -64,5 +69,28 @@ public static List MapDataIndexedPrefabs public static Vector3 LastPlayerPosition { get; set; } public static Quaternion LastPlayerRotation { get; set; } + + public static bool IsInteractableTracked(int instanceId) + { + return InteractablesCache.ContainsKey(instanceId); + } + + public static void TrackInteractable(int instanceId, BaseInteractable interactable) + { + if (!InteractablesCache.ContainsKey(instanceId)) + { + InteractablesCache.Add(instanceId, interactable); + } + } + + public static void UntrackInteractable(int instanceId) + { + InteractablesCache.Remove(instanceId); + } + + public static BaseInteractable GetTrackedInteractable(int instanceId) + { + return InteractablesCache.TryGetValue(instanceId, out var interactable) ? interactable : null; + } } } diff --git a/Multibonk/Game/Handlers/NetworkNotify/BaseInteractableEventHandler.cs b/Multibonk/Game/Handlers/NetworkNotify/BaseInteractableEventHandler.cs new file mode 100644 index 0000000..6b82d9a --- /dev/null +++ b/Multibonk/Game/Handlers/NetworkNotify/BaseInteractableEventHandler.cs @@ -0,0 +1,92 @@ +using Il2Cpp; +using Multibonk.Networking.Comms.Base.Packet; +using Multibonk.Networking.Comms.Multibonk.Networking.Comms; +using Multibonk.Networking.Lobby; + +namespace Multibonk.Game.Handlers.NetworkNotify +{ + /// + /// Handler responsible for processing BaseInteractable events and sending them over the network + /// + public class BaseInteractableEventHandler : GameEventHandler + { + private readonly NetworkService _network; + private readonly LobbyContext _lobbyContext; + + public BaseInteractableEventHandler( + NetworkService network, + LobbyContext lobbyContext + ) + { + _network = network; + _lobbyContext = lobbyContext; + + // BaseInteractable spawn event (server/host only) + GameEvents.BaseInteractableSpawnedEvent += (interactable) => + { + if (LobbyPatchFlags.IsHosting) + { + int instanceId = interactable.GetInstanceID(); + + // Register the interactable in cache + GamePatchFlags.TrackInteractable(instanceId, interactable); + + // Prepare data to send + string prefabName = interactable.gameObject.name.Replace("(Clone)", "").Trim(); + var position = interactable.transform.position; + var rotation = interactable.transform.rotation; + var scale = interactable.transform.localScale; + + // Create the packet + var spawnPacket = new SendSpawnInteractablePacket( + instanceId, + prefabName, + position, + rotation, + scale, + interactable.isItemSource, + interactable.showOutline + ); + + // Send to all clients + _lobbyContext.GetPlayers().ForEach(player => + { + if (player.Connection != null) + { + player.Connection.EnqueuePacket(spawnPacket); + } + }); + } + }; + + // BaseInteractable destruction event + GameEvents.BaseInteractableDestroyedEvent += (instanceId) => + { + if (LobbyPatchFlags.IsHosting) + { + // Remove from cache + GamePatchFlags.UntrackInteractable(instanceId); + + // Create destruction packet + var destroyPacket = new SendDestroyInteractablePacket(instanceId); + + // Send to all clients + _lobbyContext.GetPlayers().ForEach(player => + { + if (player.Connection != null) + { + player.Connection.EnqueuePacket(destroyPacket); + } + }); + } + else + { + // Client notifies the server + var destroyPacket = new SendClientDestroyInteractablePacket(instanceId); + _network.GetClientService().Enqueue(destroyPacket); + } + }; + } + } +} + diff --git a/Multibonk/Game/Patches/MainMenuPatches.cs b/Multibonk/Game/Patches/MainMenuPatches.cs index 0d890aa..0eaab44 100644 --- a/Multibonk/Game/Patches/MainMenuPatches.cs +++ b/Multibonk/Game/Patches/MainMenuPatches.cs @@ -266,6 +266,35 @@ static void Prefix(Animator __instance, string __0) } } + [HarmonyPatch(typeof(BaseInteractable), "Start")] + class BaseInteractableStartPatch + { + static void Postfix(BaseInteractable __instance) + { + // Only the host should propagate interactable creation + if (LobbyPatchFlags.IsHosting) + { + GameEvents.TriggerBaseInteractableSpawned(__instance); + } + } + } + + [HarmonyPatch(typeof(BaseInteractable), "OnDestroy")] + class BaseInteractableDestroyPatch + { + static void Prefix(BaseInteractable __instance) + { + // Anyone can propagate destruction (host or client) + int instanceId = __instance.GetInstanceID(); + + // Check if this interactable is being tracked + if (GamePatchFlags.IsInteractableTracked(instanceId)) + { + GameEvents.TriggerBaseInteractableDestroyed(instanceId); + } + } + } + //[HarmonyPatch(typeof(MapGenerationController), "Awake")] //class GeneratorAll @@ -283,7 +312,7 @@ class GenerateHookPatch2 { static bool Prefix(RandomObjectPlacer __instance) { - if(LobbyPatchFlags.IsHosting) + if (LobbyPatchFlags.IsHosting) return true; MelonLogger.Msg("Generating interactables called"); diff --git a/Multibonk/Multibonk.cs b/Multibonk/Multibonk.cs index 2397415..d93ab66 100644 --- a/Multibonk/Multibonk.cs +++ b/Multibonk/Multibonk.cs @@ -22,7 +22,7 @@ public class MultibonkMod : MelonMod public override void OnGUI() { - if(manager != null) + if (manager != null) manager.OnGUI(); } @@ -53,6 +53,7 @@ public override void OnInitializeMelon() services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); @@ -64,6 +65,7 @@ public override void OnInitializeMelon() services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); @@ -75,6 +77,8 @@ public override void OnInitializeMelon() services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); services.AddSingleton(); services.AddSingleton(); diff --git a/Multibonk/Multibonk.csproj b/Multibonk/Multibonk.csproj index a67ac21..174e554 100644 --- a/Multibonk/Multibonk.csproj +++ b/Multibonk/Multibonk.csproj @@ -1,7 +1,7 @@  - C:\Program Files (x86)\Steam\steamapps\common\Megabonk\Mods + G:\SteamLibrary\steamapps\common\Megabonk\Mods net6.0 enable disable @@ -9,442 +9,442 @@ - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\0Harmony.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\0Harmony.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\AsmResolver.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\AsmResolver.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\AsmResolver.DotNet.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\AsmResolver.DotNet.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\AsmResolver.PE.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\AsmResolver.PE.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\AsmResolver.PE.File.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\AsmResolver.PE.File.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Assembly-CSharp.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Assembly-CSharp.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\AssetRipper.Primitives.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\AssetRipper.Primitives.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\AssetsTools.NET.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\AssetsTools.NET.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\bHapticsLib.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\bHapticsLib.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Iced.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Iced.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppCoffee.UIParticle.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppCoffee.UIParticle.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2Cppcom.rlabrecque.steamworks.net.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2Cppcom.rlabrecque.steamworks.net.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppDiscord.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppDiscord.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Il2CppInterop.Common.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Il2CppInterop.Common.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Il2CppInterop.Generator.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Il2CppInterop.Generator.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Il2CppInterop.HarmonySupport.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Il2CppInterop.HarmonySupport.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Il2CppInterop.Runtime.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Il2CppInterop.Runtime.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppMK.Toon.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppMK.Toon.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppMono.Security.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppMono.Security.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2Cppmscorlib.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2Cppmscorlib.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppNewtonsoft.Json.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppNewtonsoft.Json.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppRewired_Core.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppRewired_Core.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppRewired_Windows.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppRewired_Windows.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Configuration.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Configuration.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Core.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Core.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Data.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Data.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Drawing.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Drawing.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Numerics.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Numerics.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Runtime.Serialization.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Runtime.Serialization.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Xml.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Xml.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Xml.Linq.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2CppSystem.Xml.Linq.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2Cpp__Generated.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Il2Cpp__Generated.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\IndexRange.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\IndexRange.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\MelonLoader.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\MelonLoader.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\MelonLoader.NativeHost.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\MelonLoader.NativeHost.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Bcl.AsyncInterfaces.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Bcl.AsyncInterfaces.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Diagnostics.NETCore.Client.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Diagnostics.NETCore.Client.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Diagnostics.Runtime.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Diagnostics.Runtime.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.Configuration.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.Configuration.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.Configuration.Abstractions.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.Configuration.Abstractions.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.Configuration.Binder.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.Configuration.Binder.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.DependencyInjection.Abstractions.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.DependencyInjection.Abstractions.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.Logging.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.Logging.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.Logging.Abstractions.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.Logging.Abstractions.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.Options.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.Options.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.Primitives.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Microsoft.Extensions.Primitives.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Mono.Cecil.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Mono.Cecil.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Mono.Cecil.Mdb.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Mono.Cecil.Mdb.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Mono.Cecil.Pdb.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Mono.Cecil.Pdb.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Mono.Cecil.Rocks.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Mono.Cecil.Rocks.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\MonoMod.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\MonoMod.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\MonoMod.Backports.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\MonoMod.Backports.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\MonoMod.ILHelpers.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\MonoMod.ILHelpers.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\MonoMod.RuntimeDetour.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\MonoMod.RuntimeDetour.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\MonoMod.Utils.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\MonoMod.Utils.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Newtonsoft.Json.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Newtonsoft.Json.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\System.Configuration.ConfigurationManager.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\System.Configuration.ConfigurationManager.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\System.Security.Cryptography.ProtectedData.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\System.Security.Cryptography.ProtectedData.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\System.Security.Permissions.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\System.Security.Permissions.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\System.Windows.Extensions.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\System.Windows.Extensions.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\Tomlet.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\Tomlet.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.Addressables.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.Addressables.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.Localization.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.Localization.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.Mathematics.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.Mathematics.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.Postprocessing.Runtime.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.Postprocessing.Runtime.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.ProBuilder.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.ProBuilder.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.ProBuilder.KdTree.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.ProBuilder.KdTree.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.ProBuilder.Poly2Tri.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.ProBuilder.Poly2Tri.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.ResourceManager.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.ResourceManager.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.Splines.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.Splines.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.TextMeshPro.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\Unity.TextMeshPro.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.AccessibilityModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.AccessibilityModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.AIModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.AIModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.AndroidJNIModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.AndroidJNIModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.AnimationModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.AnimationModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.ARModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.ARModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.AssetBundleModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.AssetBundleModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.AudioModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.AudioModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.ClothModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.ClothModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.CommandStateObserverModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.CommandStateObserverModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.ContentLoadModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.ContentLoadModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.CoreModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.CoreModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.CrashReportingModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.CrashReportingModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.DirectorModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.DirectorModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.DSPGraphModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.DSPGraphModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.GameCenterModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.GameCenterModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.GIModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.GIModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.GraphToolsFoundationModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.GraphToolsFoundationModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.GridModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.GridModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.HierarchyCoreModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.HierarchyCoreModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.HotReloadModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.HotReloadModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\UnityEngine.Il2CppAssetBundleManager.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\UnityEngine.Il2CppAssetBundleManager.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\UnityEngine.Il2CppImageConversionManager.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\UnityEngine.Il2CppImageConversionManager.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.ImageConversionModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.ImageConversionModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.IMGUIModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.IMGUIModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.InputForUIModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.InputForUIModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.InputLegacyModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.InputLegacyModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.InputModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.InputModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.JSONSerializeModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.JSONSerializeModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.LocalizationModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.LocalizationModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.MarshallingModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.MarshallingModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.MultiplayerModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.MultiplayerModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.ParticleSystemModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.ParticleSystemModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.PerformanceReportingModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.PerformanceReportingModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.Physics2DModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.Physics2DModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.PhysicsModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.PhysicsModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.ProfilerModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.ProfilerModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.PropertiesModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.PropertiesModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.RuntimeInitializeOnLoadManagerInitializerModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.ScreenCaptureModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.ScreenCaptureModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.SharedInternalsModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.SharedInternalsModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.SpriteMaskModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.SpriteMaskModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.SpriteShapeModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.SpriteShapeModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.StreamingModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.StreamingModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.SubstanceModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.SubstanceModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.SubsystemsModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.SubsystemsModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.TerrainModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.TerrainModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.TerrainPhysicsModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.TerrainPhysicsModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.TextCoreFontEngineModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.TextCoreFontEngineModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.TextCoreTextEngineModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.TextCoreTextEngineModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.TextRenderingModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.TextRenderingModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.TilemapModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.TilemapModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.TLSModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.TLSModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UI.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UI.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UIElementsModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UIElementsModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UIModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UIModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UmbraModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UmbraModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityAnalyticsCommonModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityAnalyticsCommonModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityAnalyticsModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityAnalyticsModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityConnectModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityConnectModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityCurlModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityCurlModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityTestProtocolModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityTestProtocolModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityWebRequestAssetBundleModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityWebRequestAssetBundleModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityWebRequestAudioModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityWebRequestAudioModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityWebRequestModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityWebRequestModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityWebRequestTextureModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityWebRequestTextureModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityWebRequestWWWModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.UnityWebRequestWWWModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.VehiclesModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.VehiclesModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.VFXModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.VFXModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.VideoModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.VideoModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.VRModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.VRModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.WindModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.WindModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.XRModule.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\Il2CppAssemblies\UnityEngine.XRModule.dll - ..\..\..\..\..\..\Program Files (x86)\Steam\steamapps\common\Megabonk\MelonLoader\net6\WebSocketDotNet.dll + G:\SteamLibrary\steamapps\common\Megabonk\MelonLoader\net6\WebSocketDotNet.dll diff --git a/Multibonk/Multibonk.sln b/Multibonk/Multibonk.sln new file mode 100644 index 0000000..be8877c --- /dev/null +++ b/Multibonk/Multibonk.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.002.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Multibonk", "Multibonk.csproj", "{F7F18F69-EDDC-47BD-8EDF-213A25CAC9A4}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F7F18F69-EDDC-47BD-8EDF-213A25CAC9A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F7F18F69-EDDC-47BD-8EDF-213A25CAC9A4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F7F18F69-EDDC-47BD-8EDF-213A25CAC9A4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F7F18F69-EDDC-47BD-8EDF-213A25CAC9A4}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {1A226C45-7427-4EC9-AC09-9DB8C522DCE1} + EndGlobalSection +EndGlobal diff --git a/Multibonk/Networking/Comms/Base/Packet/DestroyInteractablePacket.cs b/Multibonk/Networking/Comms/Base/Packet/DestroyInteractablePacket.cs new file mode 100644 index 0000000..120b5be --- /dev/null +++ b/Multibonk/Networking/Comms/Base/Packet/DestroyInteractablePacket.cs @@ -0,0 +1,43 @@ +using Multibonk.Networking.Comms.Packet.Base.Multibonk.Networking.Comms; + +namespace Multibonk.Networking.Comms.Base.Packet +{ + /// + /// Packet sent from server to clients when a BaseInteractable is destroyed + /// + public class SendDestroyInteractablePacket : OutgoingPacket + { + public readonly byte Id = (byte)ServerSentPacketId.DESTROY_INTERACTABLE_PACKET; + + public SendDestroyInteractablePacket(int instanceId) + { + Message.WriteByte(Id); + Message.WriteInt(instanceId); + } + } + + /// + /// Packet sent from client to server when a BaseInteractable is destroyed on the client + /// + public class SendClientDestroyInteractablePacket : OutgoingPacket + { + public readonly byte Id = (byte)ClientSentPacketId.DESTROY_INTERACTABLE_PACKET; + + public SendClientDestroyInteractablePacket(int instanceId) + { + Message.WriteByte(Id); + Message.WriteInt(instanceId); + } + } + + internal class DestroyInteractablePacket + { + public int InstanceId { get; private set; } + + public DestroyInteractablePacket(IncomingMessage msg) + { + InstanceId = msg.ReadInt(); + } + } +} + diff --git a/Multibonk/Networking/Comms/Base/Packet/SpawnInteractablePacket.cs b/Multibonk/Networking/Comms/Base/Packet/SpawnInteractablePacket.cs new file mode 100644 index 0000000..0b37de4 --- /dev/null +++ b/Multibonk/Networking/Comms/Base/Packet/SpawnInteractablePacket.cs @@ -0,0 +1,92 @@ +using Il2Cpp; +using Multibonk.Networking.Comms.Packet.Base.Multibonk.Networking.Comms; +using UnityEngine; + +namespace Multibonk.Networking.Comms.Base.Packet +{ + /// + /// Packet sent from server to clients when a BaseInteractable is created + /// + public class SendSpawnInteractablePacket : OutgoingPacket + { + public readonly byte Id = (byte)ServerSentPacketId.SPAWN_INTERACTABLE_PACKET; + + public SendSpawnInteractablePacket( + int instanceId, + string prefabName, + Vector3 position, + Quaternion rotation, + Vector3 scale, + bool isItemSource, + bool showOutline) + { + Message.WriteByte(Id); + Message.WriteInt(instanceId); + Message.WriteString(prefabName); + + // Position + Message.WriteFloat(position.x); + Message.WriteFloat(position.y); + Message.WriteFloat(position.z); + + // Rotation + Message.WriteFloat(rotation.x); + Message.WriteFloat(rotation.y); + Message.WriteFloat(rotation.z); + Message.WriteFloat(rotation.w); + + // Scale + Message.WriteFloat(scale.x); + Message.WriteFloat(scale.y); + Message.WriteFloat(scale.z); + + // Properties + Message.WriteBool(isItemSource); + Message.WriteBool(showOutline); + } + } + + internal class SpawnInteractablePacket + { + public int InstanceId { get; private set; } + public string PrefabName { get; private set; } + public Vector3 Position { get; private set; } + public Quaternion Rotation { get; private set; } + public Vector3 Scale { get; private set; } + public bool IsItemSource { get; private set; } + public bool ShowOutline { get; private set; } + + public SpawnInteractablePacket(IncomingMessage msg) + { + InstanceId = msg.ReadInt(); + PrefabName = msg.ReadString(); + + // Position + Position = new Vector3( + msg.ReadFloat(), + msg.ReadFloat(), + msg.ReadFloat() + ); + + // Rotation + Rotation = new Quaternion( + msg.ReadFloat(), + msg.ReadFloat(), + msg.ReadFloat(), + msg.ReadFloat() + ); + + // Scale + Scale = new Vector3( + msg.ReadFloat(), + msg.ReadFloat(), + msg.ReadFloat() + ); + + // Properties + IsItemSource = msg.ReadBool(); + ShowOutline = msg.ReadBool(); + } + } +} + diff --git a/Multibonk/Networking/Comms/Base/PacketId.cs b/Multibonk/Networking/Comms/Base/PacketId.cs index 395bcb6..acfb5b5 100644 --- a/Multibonk/Networking/Comms/Base/PacketId.cs +++ b/Multibonk/Networking/Comms/Base/PacketId.cs @@ -4,19 +4,21 @@ public enum ServerSentPacketId : byte { - LOBBY_PLAYER_LIST_PACKET = 0, - PLAYER_SELECTED_CHARACTER = 1, - START_GAME = 2, - PAUSE_GAME = 3, - UNPAUSE_GAME = 4, - MAP_FINISHED_LOADING = 5, - SPAWN_PLAYER_PACKET = 6, + LOBBY_PLAYER_LIST_PACKET = 0, + PLAYER_SELECTED_CHARACTER = 1, + START_GAME = 2, + PAUSE_GAME = 3, + UNPAUSE_GAME = 4, + MAP_FINISHED_LOADING = 5, + SPAWN_PLAYER_PACKET = 6, - PLAYER_MOVED_PACKET = 7, - PLAYER_ROTATED_PACKET = 8, - MAP_OBJECT_CHUNK_PACKET = 9, - XP_PACKET = 10, - PLAYER_ANIMATOR_CHANGED_PACKET = 11 + PLAYER_MOVED_PACKET = 7, + PLAYER_ROTATED_PACKET = 8, + MAP_OBJECT_CHUNK_PACKET = 9, + XP_PACKET = 10, + PLAYER_ANIMATOR_CHANGED_PACKET = 11, + SPAWN_INTERACTABLE_PACKET = 12, + DESTROY_INTERACTABLE_PACKET = 13 } public enum ClientSentPacketId : byte @@ -27,6 +29,7 @@ public enum ClientSentPacketId : byte PLAYER_MOVE_PACKET = 3, PLAYER_ROTATE_PACKET = 4, PICKUP_XP_PACKET = 5, - PLAYER_ANIMATOR_PACKET = 6 + PLAYER_ANIMATOR_PACKET = 6, + DESTROY_INTERACTABLE_PACKET = 7 } } diff --git a/Multibonk/Networking/Comms/Client/Handlers/DestroyInteractablePacketHandler.cs b/Multibonk/Networking/Comms/Client/Handlers/DestroyInteractablePacketHandler.cs new file mode 100644 index 0000000..9150141 --- /dev/null +++ b/Multibonk/Networking/Comms/Client/Handlers/DestroyInteractablePacketHandler.cs @@ -0,0 +1,30 @@ +using Multibonk.Game; +using Multibonk.Game.Handlers; +using Multibonk.Networking.Comms.Base; +using Multibonk.Networking.Comms.Base.Packet; +using Multibonk.Networking.Comms.Packet.Base.Multibonk.Networking.Comms; + +namespace Multibonk.Networking.Comms.Client.Handlers +{ + /// + /// Client handler to process BaseInteractable destruction packets sent by the server + /// + public class DestroyInteractablePacketHandler : IClientPacketHandler + { + public byte PacketId => (byte)ServerSentPacketId.DESTROY_INTERACTABLE_PACKET; + + public DestroyInteractablePacketHandler() { } + + public void Handle(IncomingMessage msg, Connection conn) + { + var packet = new DestroyInteractablePacket(msg); + + // Enqueue execution on Unity's main thread + GameDispatcher.Enqueue(() => + { + GameFunctions.DestroyNetworkInteractable(packet.InstanceId); + }); + } + } +} + diff --git a/Multibonk/Networking/Comms/Client/Handlers/SpawnInteractablePacketHandler.cs b/Multibonk/Networking/Comms/Client/Handlers/SpawnInteractablePacketHandler.cs new file mode 100644 index 0000000..102e7f7 --- /dev/null +++ b/Multibonk/Networking/Comms/Client/Handlers/SpawnInteractablePacketHandler.cs @@ -0,0 +1,38 @@ +using Multibonk.Game; +using Multibonk.Game.Handlers; +using Multibonk.Networking.Comms.Base; +using Multibonk.Networking.Comms.Base.Packet; +using Multibonk.Networking.Comms.Packet.Base.Multibonk.Networking.Comms; + +namespace Multibonk.Networking.Comms.Client.Handlers +{ + /// + /// Client handler to process BaseInteractable spawn packets sent by the server + /// + public class SpawnInteractablePacketHandler : IClientPacketHandler + { + public byte PacketId => (byte)ServerSentPacketId.SPAWN_INTERACTABLE_PACKET; + + public SpawnInteractablePacketHandler() { } + + public void Handle(IncomingMessage msg, Connection conn) + { + var packet = new SpawnInteractablePacket(msg); + + // Enqueue execution on Unity's main thread + GameDispatcher.Enqueue(() => + { + GameFunctions.SpawnNetworkInteractable( + packet.InstanceId, + packet.PrefabName, + packet.Position, + packet.Rotation, + packet.Scale, + packet.IsItemSource, + packet.ShowOutline + ); + }); + } + } +} + diff --git a/Multibonk/Networking/Comms/Server/Handlers/DestroyInteractablePacketHandler.cs b/Multibonk/Networking/Comms/Server/Handlers/DestroyInteractablePacketHandler.cs new file mode 100644 index 0000000..6209a91 --- /dev/null +++ b/Multibonk/Networking/Comms/Server/Handlers/DestroyInteractablePacketHandler.cs @@ -0,0 +1,48 @@ +using Multibonk.Game; +using Multibonk.Game.Handlers; +using Multibonk.Networking.Comms.Base; +using Multibonk.Networking.Comms.Base.Packet; +using Multibonk.Networking.Comms.Packet.Base.Multibonk.Networking.Comms; +using Multibonk.Networking.Lobby; + +namespace Multibonk.Networking.Comms.Server.Handlers +{ + /// + /// Server handler to process BaseInteractable destruction requests sent by clients + /// + public class DestroyInteractablePacketHandler : IServerPacketHandler + { + public byte PacketId => (byte)ClientSentPacketId.DESTROY_INTERACTABLE_PACKET; + + private readonly LobbyContext _lobbyContext; + + public DestroyInteractablePacketHandler(LobbyContext lobbyContext) + { + _lobbyContext = lobbyContext; + } + + public void Handle(IncomingMessage msg, Connection conn) + { + var packet = new DestroyInteractablePacket(msg); + + // Enqueue execution on Unity's main thread + GameDispatcher.Enqueue(() => + { + // Destroy the interactable on the server + GameFunctions.DestroyNetworkInteractable(packet.InstanceId); + }); + + // Propagate destruction to all other clients + foreach (var player in _lobbyContext.GetPlayers()) + { + // Don't send back to the requester + if (player.Connection == null || player.Connection == conn) + continue; + + var destroyPacket = new SendDestroyInteractablePacket(packet.InstanceId); + player.Connection.EnqueuePacket(destroyPacket); + } + } + } +} +