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<bool> InfiniteBombs;
internal static ConfigEntry<bool> InfiniteArrows;
internal static ConfigEntry<bool> 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<bool>("General", "InfiniteBombs", true, "Do not consume bombs when thrown. Does not create extra bombs.");
InfiniteArrows = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "InfiniteArrows", true, "Do not consume arrows when shot.");
DebugLog = ((BaseUnityPlugin)this).Config.Bind<bool>("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;
}
}
}