using System; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace InfiniteBombsArrows { [BepInPlugin("com.syntx.stonewards.infinitebombsarrows", "Infinite Bombs and Arrows", "1.6.0")] public class Plugin : BaseUnityPlugin { public const string PluginGuid = "com.syntx.stonewards.infinitebombsarrows"; public const string PluginName = "Infinite Bombs and Arrows"; public const string PluginVersion = "1.6.0"; internal static Plugin Instance; internal static ManualLogSource Log; internal static ConfigEntry InfiniteBombs; internal static ConfigEntry InfiniteArrows; internal static ConfigEntry DebugLog; private Harmony _harmony; private void Awake() { //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; InfiniteBombs = ((BaseUnityPlugin)this).Config.Bind("General", "InfiniteBombs", true, "Do not consume bombs when thrown. Does not create extra bombs."); InfiniteArrows = ((BaseUnityPlugin)this).Config.Bind("General", "InfiniteArrows", true, "Do not consume arrows when shot."); DebugLog = ((BaseUnityPlugin)this).Config.Bind("General", "DebugLog", false, "Log skipped consumes."); Log.LogInfo((object)"===================================================="); Log.LogInfo((object)"Infinite Bombs and Arrows v1.6.0 loaded"); Log.LogInfo((object)"MUST be 1.6.0. This version NEVER adds bombs."); Log.LogInfo((object)"===================================================="); _harmony = new Harmony("com.syntx.stonewards.infinitebombsarrows"); int num = 0; num += Patch("BowTool", "ShootArrow", "ShootArrow_Prefix", "ShootArrow_Postfix"); num += Patch("InventorySystem", "CmdRemoveItemQuantity", "SkipArrowQty_Prefix", null); num += Patch("InventorySystem", "UserCode_CmdRemoveItemQuantity__String__Int32", "SkipArrowQty_Prefix", null); num += Patch("FirstPersonController", "UserCode_CmdThrowEquipment__FirstPersonController__String__Int32__Int32__Vector3__Vector3__Single", "Throw_Prefix", "Throw_Postfix"); num += Patch("InventorySystem", "ServerRemoveItemFromSlot", "SkipBombSlot_Prefix", null); num += Patch("InventorySystem", "TryRemove", "TryRemove_Prefix", null); num += Patch("PickableBomb", "CanPickupItem", "BlockThrownBombPickup_Prefix", null); num += Patch("PickableBomb", "IsPickable", "BlockThrownBombPickable_Prefix", null); num += Patch("PickableItem", "ServerTryPickup", "BlockThrownBombServerPickup_Prefix", null); num += Patch("PickableItem", "CanPickupItem", "BlockThrownBombPickup_Prefix", null); num += Patch("FirstPersonController", "UserCode_CmdAutoPickupItem__FirstPersonController__PickableItem", "BlockAutoPickupThrownBomb_Prefix", null); num += Patch("FirstPersonController", "UserCode_CmdPickupItem__FirstPersonController__PickableItem", "BlockAutoPickupThrownBomb_Prefix", null); Log.LogInfo((object)("Patches applied: " + num)); } private int Patch(string typeName, string methodName, string prefix, string postfix) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) Type type = AccessTools.TypeByName(typeName); if (type == null) { Log.LogError((object)("Type not found: " + typeName)); return 0; } MethodInfo methodInfo = null; MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo2 in methods) { if (methodInfo2.Name == methodName) { methodInfo = methodInfo2; break; } } if (methodInfo == null) { Log.LogError((object)("Method not found: " + typeName + "." + methodName)); return 0; } try { HarmonyMethod val = ((prefix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(Patches).GetMethod(prefix, BindingFlags.Static | BindingFlags.Public))); HarmonyMethod val2 = ((postfix == null) ? ((HarmonyMethod)null) : new HarmonyMethod(typeof(Patches).GetMethod(postfix, BindingFlags.Static | BindingFlags.Public))); _harmony.Patch((MethodBase)methodInfo, val, val2, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Log.LogInfo((object)("OK " + typeName + "." + methodInfo.Name)); return 1; } catch (Exception ex) { Log.LogError((object)("FAIL " + typeName + "." + methodName + " : " + ex.Message)); return 0; } } } public static class Patches { private static int _arrowDepth; private static int _bombDepth; public static void ShootArrow_Prefix() { if (Plugin.InfiniteArrows != null && Plugin.InfiniteArrows.Value) { _arrowDepth++; } } public static void ShootArrow_Postfix() { if (_arrowDepth > 0) { _arrowDepth--; } } public static bool SkipArrowQty_Prefix() { if (_arrowDepth <= 0) { return true; } if (Plugin.DebugLog != null && Plugin.DebugLog.Value) { Plugin.Log.LogInfo((object)"Skip arrow consume"); } return false; } public static void Throw_Prefix() { if (Plugin.InfiniteBombs != null && Plugin.InfiniteBombs.Value) { _bombDepth++; } } public static void Throw_Postfix() { if (_bombDepth > 0) { _bombDepth--; } } public static bool SkipBombSlot_Prefix(ref bool __result) { if (_bombDepth <= 0) { return true; } __result = true; if (Plugin.DebugLog != null && Plugin.DebugLog.Value) { Plugin.Log.LogInfo((object)"Skip bomb slot remove"); } return false; } public static bool TryRemove_Prefix(ref bool __result) { if (_bombDepth <= 0 && _arrowDepth <= 0) { return true; } __result = true; if (Plugin.DebugLog != null && Plugin.DebugLog.Value) { Plugin.Log.LogInfo((object)"Skip TryRemove"); } return false; } public static bool BlockThrownBombPickup_Prefix(object __instance, ref bool __result) { if (!IsThrownBomb(__instance)) { return true; } __result = false; return false; } public static bool BlockThrownBombPickable_Prefix(object __instance, ref bool __result) { if (!IsThrownBomb(__instance)) { return true; } __result = false; return false; } public static bool BlockThrownBombServerPickup_Prefix(object __instance, ref bool __result) { if (!IsThrownBomb(__instance)) { return true; } __result = false; return false; } public static bool BlockAutoPickupThrownBomb_Prefix(object[] __args) { if (__args == null) { return true; } for (int i = 0; i < __args.Length; i++) { if (IsThrownBomb(__args[i])) { if (Plugin.DebugLog != null && Plugin.DebugLog.Value) { Plugin.Log.LogInfo((object)"Blocked pickup of thrown bomb"); } return false; } } return true; } private static bool IsThrownBomb(object instance) { if (instance == null) { return false; } Type type = instance.GetType(); if (type.Name != "PickableBomb" && type.Name != "PickableItem") { if (!typeof(object).IsAssignableFrom(type)) { return false; } if (type.Name.IndexOf("Bomb", StringComparison.OrdinalIgnoreCase) < 0 && type.Name != "PickableItem") { return false; } } FieldInfo fieldInfo = AccessTools.Field(type, "hasBeenThrown"); if (fieldInfo != null) { try { if (Convert.ToBoolean(fieldInfo.GetValue(instance))) { return true; } } catch { } } FieldInfo fieldInfo2 = AccessTools.Field(type, "owner"); if (fieldInfo2 != null) { try { if (fieldInfo2.GetValue(instance) != null) { return true; } } catch { } } return false; } } }