Decompiled source of AmmoBag v1.2.0

BepInEx/plugins/AmmoBag.dll

Decompiled a week ago
using 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);
				}
			}
		}
	}
}