Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of AmmoBag v1.2.0
BepInEx/plugins/AmmoBag.dll
Decompiled a week agousing System; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using AmmoBag.Patches; using BepInEx; using BepInEx.Logging; using GameNetcodeStuff; using HarmonyLib; using LethalNetworkAPI; using Unity.Netcode; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("AmmoBag")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("AmmoBag")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("da0de89f-9696-4ca2-a169-d360d37a3b8f")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("1.0.0.0")] namespace AmmoBag { internal static class AmmoBagHelper { internal const int encode_base_number = 1000000; internal static ulong pendingBagNetworkObjectId; internal static int pendingAmmoInBagIndex; internal static int FindAmmoInBelt(PlayerControllerB player, ShotgunItem __instance) { for (int i = 0; i < player.ItemSlots.Length; i++) { if (CheckSlot(__instance, player.ItemSlots[i])) { BeltBagPatchBase.logSource.LogInfo((object)("Found shell in slot " + i)); return 1000000; } } if (CheckSlot(__instance, player.ItemOnlySlot)) { BeltBagPatchBase.logSource.LogInfo((object)"Found shell in utilitySlot"); return 1000000; } BeltBagPatchBase.logSource.LogInfo((object)"No shells found"); return -1; } private static bool CheckSlot(ShotgunItem __instance, GrabbableObject slot) { if ((Object)(object)slot == (Object)null) { return false; } BeltBagItem val = (BeltBagItem)(object)((slot is BeltBagItem) ? slot : null); if ((Object)(object)val == (Object)null) { return false; } int num = FindAmmoInBag(val, __instance.gunCompatibleAmmoID); if (num == -1) { return false; } pendingBagNetworkObjectId = ((Component)val).GetComponent<NetworkObject>().NetworkObjectId; pendingAmmoInBagIndex = num; return true; } private static int FindAmmoInBag(BeltBagItem bag, int ammoTypeID) { for (int num = bag.objectsInBag.Count - 1; num >= 0; num--) { GrabbableObject val = bag.objectsInBag[num]; if (!((Object)(object)val == (Object)null)) { GunAmmo val2 = (GunAmmo)(object)((val is GunAmmo) ? val : null); if ((Object)(object)val2 != (Object)null && val2.ammoType == ammoTypeID) { return num; } } } return -1; } } internal static class AmmoNetworking { private const string MessageId_sv = "PixelIndieDev_AmmoBag.msg_DeleteOnServer"; private const string MessageId_cl = "PixelIndieDev_AmmoBag.msg_DeleteOnClients"; private static LNetworkMessage<NetworkRequestStruct> msg_deleteShell_Server; private static LNetworkMessage<NetworkRequestStruct> msg_deleteShell_Client; internal static bool isHosting; internal static void SetNetworkMessage() { msg_deleteShell_Server = LNetworkMessage<NetworkRequestStruct>.Connect("PixelIndieDev_AmmoBag.msg_DeleteOnServer", (Action<NetworkRequestStruct, ulong>)OnRemoveAmmoReceivedServer, (Action<NetworkRequestStruct>)null, (Action<NetworkRequestStruct, ulong>)null); msg_deleteShell_Client = LNetworkMessage<NetworkRequestStruct>.Connect("PixelIndieDev_AmmoBag.msg_DeleteOnClients", (Action<NetworkRequestStruct, ulong>)null, (Action<NetworkRequestStruct>)OnRemoveAmmoReceivedClient, (Action<NetworkRequestStruct, ulong>)null); } public static void RequestRemoveAmmo(ulong bagNetworkObjectId, int ammoInBagIndex) { BeltBagPatchBase.logSource.LogInfo((object)"Requested remove ammo"); msg_deleteShell_Server.SendServer(new NetworkRequestStruct(bagNetworkObjectId, ammoInBagIndex)); } private static void OnRemoveAmmoReceivedServer(NetworkRequestStruct data, ulong senderClientId) { if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(data.bagNetworkObjectId, out var value)) { BeltBagItem component = ((Component)value).GetComponent<BeltBagItem>(); if ((Object)(object)component != (Object)null && data.ammoInBagIndex >= 0 && data.ammoInBagIndex < component.objectsInBag.Count) { component.objectsInBag.RemoveAt(data.ammoInBagIndex); BeltBagPatchBase.logSource.LogInfo((object)"Host removed shell from bag"); } else { BeltBagPatchBase.logSource.LogWarning((object)"SyncBagAmmoRemovalServerRpc: bag null or index out of range"); } } else { BeltBagPatchBase.logSource.LogWarning((object)("SyncBagAmmoRemovalServerRpc: could not find bag with id " + data.bagNetworkObjectId)); } msg_deleteShell_Client.SendClients(new NetworkRequestStruct(data.bagNetworkObjectId, data.ammoInBagIndex)); } private static void OnRemoveAmmoReceivedClient(NetworkRequestStruct @struct) { if (isHosting) { return; } if (!NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(@struct.bagNetworkObjectId, out var value)) { BeltBagPatchBase.logSource.LogWarning((object)("SyncBagAmmoRemoval: could not find bag with NetworkObjectId " + @struct.bagNetworkObjectId)); return; } BeltBagItem component = ((Component)value).GetComponent<BeltBagItem>(); if ((Object)(object)component == (Object)null) { BeltBagPatchBase.logSource.LogWarning((object)"SyncBagAmmoRemoval: NetworkObject is not a BeltBagItem"); } else if (@struct.ammoInBagIndex < 0 || @struct.ammoInBagIndex >= component.objectsInBag.Count) { BeltBagPatchBase.logSource.LogWarning((object)"SyncBagAmmoRemoval: ammoInBagIndex out of range"); } else { component.objectsInBag.RemoveAt(@struct.ammoInBagIndex); } } } public struct NetworkRequestStruct { public ulong bagNetworkObjectId; public int ammoInBagIndex; public NetworkRequestStruct(ulong bagNetworkObjectId, int ammoInBagIndex) { this.bagNetworkObjectId = bagNetworkObjectId; this.ammoInBagIndex = ammoInBagIndex; } } [BepInPlugin("PixelIndieDev_AmmoBag", "Ammo Bag", "1.2.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class BeltBagPatchBase : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("PixelIndieDev_AmmoBag"); private static BeltBagPatchBase instance; internal static ManualLogSource logSource; private void Awake() { if ((Object)(object)instance == (Object)null) { instance = this; } logSource = Logger.CreateLogSource("PixelIndieDev_AmmoBag"); harmony.PatchAll(typeof(BeltBagPatchBase)); harmony.PatchAll(typeof(NetworkPatch)); harmony.PatchAll(typeof(ShotgunPatch)); harmony.PatchAll(typeof(PlayerPatch)); harmony.PatchAll(typeof(MenuManagerPatch)); AmmoNetworking.SetNetworkMessage(); logSource.LogInfo((object)"Ammo Bag (version - 1.2.0.0): patches applied successfully"); } } internal static class ModInfo { internal const string modGUID = "PixelIndieDev_AmmoBag"; internal const string modName = "Ammo Bag"; internal const string modVersion = "1.2.0.0"; } } namespace AmmoBag.Patches { [HarmonyPatch(typeof(MenuManager))] internal class MenuManagerPatch { [HarmonyPatch("StartHosting")] [HarmonyPrefix] [HarmonyPriority(0)] private static void OnStartHostingPatch() { AmmoNetworking.isHosting = true; } [HarmonyPatch("StartAClient")] [HarmonyPrefix] [HarmonyPriority(0)] private static void OnStartConnectingPatch() { AmmoNetworking.isHosting = false; } } [HarmonyPatch(typeof(NetworkManager))] internal static class NetworkPatch { [HarmonyPostfix] [HarmonyPatch("SetSingleton")] private static void RegisterPrefab() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("PixelIndieDev_AmmoBag Prefab"); ((Object)val).hideFlags = (HideFlags)(((Object)val).hideFlags | 0x3D); Object.DontDestroyOnLoad((Object)(object)val); NetworkObject obj = val.AddComponent<NetworkObject>(); typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(obj, GetHash("PixelIndieDev_AmmoBag")); NetworkManager.Singleton.PrefabHandler.AddNetworkPrefab(val); } private static uint GetHash(string value) { return value?.Aggregate(17u, (uint current, char c) => (current * 31) ^ c) ?? 0; } } [HarmonyPatch(typeof(PlayerControllerB))] internal class PlayerPatch { [HarmonyPatch("DestroyItemInSlotAndSync")] [HarmonyPrefix] [HarmonyPriority(0)] private static bool PatchFindAmmo(PlayerControllerB __instance, int itemSlot) { if (itemSlot < 1000000) { return true; } ulong pendingBagNetworkObjectId = AmmoBagHelper.pendingBagNetworkObjectId; int pendingAmmoInBagIndex = AmmoBagHelper.pendingAmmoInBagIndex; if (!NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(pendingBagNetworkObjectId, out var _)) { BeltBagPatchBase.logSource.LogWarning((object)("Could not find belt bag NetworkObject with id " + pendingBagNetworkObjectId)); return false; } AmmoNetworking.RequestRemoveAmmo(pendingBagNetworkObjectId, pendingAmmoInBagIndex); return false; } } [HarmonyPatch(typeof(ShotgunItem))] internal class ShotgunPatch { [HarmonyPatch("FindAmmoInInventory")] [HarmonyPostfix] [HarmonyPriority(0)] private static void PatchFindAmmo(ref int __result, ShotgunItem __instance) { if (__result == -1) { PlayerControllerB playerHeldBy = ((GrabbableObject)__instance).playerHeldBy; if (!((Object)(object)playerHeldBy == (Object)null)) { __result = AmmoBagHelper.FindAmmoInBelt(playerHeldBy, __instance); } } } } }