using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using HarmonyLib;
using UnityEngine;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("InfiniteToolDurability")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("InfiniteToolDurability")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("1a8e59b1-6fe8-4007-9642-0e7d28f62831")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
[BepInPlugin("InfiniteToolDurability", "Infinite Tool Durability", "1.1.0")]
public class InfiniteToolDurability : BaseUnityPlugin
{
public const string PluginGuid = "InfiniteToolDurability";
public const string PluginName = "Infinite Tool Durability";
public const string PluginVersion = "1.1.0";
private void Awake()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
new Harmony("InfiniteToolDurability").PatchAll();
}
}
internal static class InfiniteConsumptionTargets
{
private static readonly string[] WeaponNameTokens = new string[2] { "musket", "crossbow" };
private static readonly string[] AmmoNameTokens = new string[2] { "bullet", "crossbowbolt" };
private static readonly HashSet<ushort> WeaponDataIds = new HashSet<ushort>();
private static readonly HashSet<ushort> AmmoDataIds = new HashSet<ushort>();
private static bool _initialized;
internal static void BuildFromItemManager(ItemManager im)
{
if (_initialized || (Object)(object)im == (Object)null || (Object)(object)im.itemDataHub == (Object)null || im.itemDataHub.itemData == null)
{
return;
}
ItemData[] itemData = im.itemDataHub.itemData;
foreach (ItemData val in itemData)
{
if (!((Object)(object)val == (Object)null))
{
string normalized = Normalize(val.name);
if (ContainsAny(normalized, WeaponNameTokens))
{
WeaponDataIds.Add(val.id);
}
if (ContainsAny(normalized, AmmoNameTokens))
{
AmmoDataIds.Add(val.id);
}
}
}
_initialized = true;
}
internal static bool IsWeapon(ushort itemDataId)
{
return WeaponDataIds.Contains(itemDataId);
}
internal static bool IsAmmo(ushort itemDataId)
{
return AmmoDataIds.Contains(itemDataId);
}
private static bool ContainsAny(string normalized, string[] tokens)
{
if (string.IsNullOrEmpty(normalized))
{
return false;
}
for (int i = 0; i < tokens.Length; i++)
{
if (normalized.IndexOf(tokens[i], StringComparison.OrdinalIgnoreCase) >= 0)
{
return true;
}
}
return false;
}
private static string Normalize(string s)
{
if (string.IsNullOrEmpty(s))
{
return string.Empty;
}
char[] array = new char[s.Length];
int length = 0;
foreach (char c in s)
{
if (char.IsLetterOrDigit(c))
{
array[length++] = char.ToLowerInvariant(c);
}
}
return new string(array, 0, length);
}
}
[HarmonyPatch(typeof(ItemManager), "Awake")]
internal static class ItemManager_Awake_InitTargets_Patch
{
private static void Postfix(ItemManager __instance)
{
InfiniteConsumptionTargets.BuildFromItemManager(__instance);
}
}
[HarmonyPatch(typeof(ItemManager), "DamageToolServerRpc")]
internal static class ItemManager_DamageToolServerRpc_Patch
{
private static bool Prefix()
{
return false;
}
}
[HarmonyPatch(typeof(ContainerNet), "RemoveAmountServerRpc")]
internal static class ContainerNet_RemoveAmountServerRpc_Patch
{
private static bool Prefix(ushort itemDataId, ushort amount)
{
return !InfiniteConsumptionTargets.IsAmmo(itemDataId);
}
}
[HarmonyPatch(typeof(ContainerNet), "TryRemoveAmount")]
internal static class ContainerNet_TryRemoveAmount_Patch
{
private static bool Prefix(ushort itemDataId, ushort amount, ref ushort __result)
{
if (InfiniteConsumptionTargets.IsAmmo(itemDataId))
{
__result = 0;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(ContainerNet), "RemoveChargeServerRpc")]
internal static class ContainerNet_RemoveChargeServerRpc_Patch
{
private static bool Prefix(ushort itemDataId, ushort charge)
{
return !InfiniteConsumptionTargets.IsWeapon(itemDataId);
}
}
[HarmonyPatch(typeof(ContainerNet), "TryRemoveCharge")]
internal static class ContainerNet_TryRemoveCharge_Patch
{
private static bool Prefix(ushort itemDataId, ushort charge, ref ushort itemsRemoved, ref ushort __result)
{
if (InfiniteConsumptionTargets.IsWeapon(itemDataId))
{
itemsRemoved = 0;
__result = 0;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(ContainerNet), "RemoveItemChargeServerRpc")]
internal static class ContainerNet_RemoveItemChargeServerRpc_Patch
{
private static bool Prefix(ContainerNet __instance, uint itemId, ushort charge)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance == (Object)null || itemId == 0)
{
return true;
}
Item val = default(Item);
if (!__instance.GetItemById(itemId, ref val, false))
{
return true;
}
return !InfiniteConsumptionTargets.IsWeapon(val.dataId);
}
}
[HarmonyPatch(typeof(ContainerNet), "RemoveItemAmount")]
internal static class ContainerNet_RemoveItemAmount_Patch
{
private static bool Prefix(ContainerNet __instance, uint itemId, ushort v, ref bool __result)
{
//IL_001c: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)__instance == (Object)null || itemId == 0)
{
return true;
}
Item val = default(Item);
if (!__instance.GetItemById(itemId, ref val, false))
{
return true;
}
if (InfiniteConsumptionTargets.IsAmmo(val.dataId))
{
__result = true;
return false;
}
return true;
}
}
[HarmonyPatch(typeof(GunTool), "Fire")]
internal static class GunTool_Fire_KeepClip_Patch
{
private static void Prefix(GunTool __instance, out int __stateClip)
{
__stateClip = __instance.clipContent;
}
private static void Postfix(GunTool __instance, int __stateClip)
{
__instance.clipContent = __stateClip;
}
}