Decompiled source of KeepLoaded v1.0.1

KeepLoaded.dll

Decompiled 20 hours ago
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using ConditionalConfigSync;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: AssemblyCompany("KeepLoaded")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.1.0")]
[assembly: AssemblyInformationalVersion("1.0.1")]
[assembly: AssemblyProduct("KeepLoaded")]
[assembly: AssemblyTitle("KeepLoaded")]
[assembly: AssemblyVersion("1.0.1.0")]
[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 KeepLoaded
{
	[BepInPlugin("com.dreich.keeploaded", "Keep Loaded", "1.0.1")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class KeepLoaded : BaseUnityPlugin
	{
		public const string Guid = "com.dreich.keeploaded";

		public const string Name = "Keep Loaded";

		public const string Version = "1.0.1";

		internal const string ConfigSyncGuid = "_shudnal.ConditionalConfigSync";

		internal static ManualLogSource Log;

		internal static bool ConfigSyncAvailable;

		private static ConfigEntry<bool> ConfigLockedEntry;

		private static ConfigEntry<bool> KeepCrossbowEntry;

		private static ConfigEntry<bool> KeepGrapplingHookEntry;

		internal static bool KeepCrossbow => KeepCrossbowEntry.Value;

		internal static bool KeepGrapplingHook => KeepGrapplingHookEntry.Value;

		private void Awake()
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			Log = ((BaseUnityPlugin)this).Logger;
			ConfigSyncAvailable = Chainloader.PluginInfos.ContainsKey("_shudnal.ConditionalConfigSync");
			if (ConfigSyncAvailable)
			{
				ConfigSyncCompat.Initialize("com.dreich.keeploaded", "Keep Loaded", "1.0.1");
			}
			else
			{
				Log.LogInfo((object)"ConditionalConfigSync not found; configuration will not be synced from the server.");
			}
			ConfigLockedEntry = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "Lock Configuration", true, "If on, the configuration is locked and can be changed by server admins only. Requires ConditionalConfigSync.");
			if (ConfigSyncAvailable)
			{
				ConfigSyncCompat.AddLockingConfigEntry(ConfigLockedEntry);
			}
			KeepCrossbowEntry = BindShared("General", "KeepCrossbowLoaded", defaultValue: true, "A loaded crossbow stays loaded when you put it away, until you fire it.");
			KeepGrapplingHookEntry = BindShared("General", "KeepGrapplingHookLoaded", defaultValue: true, "A loaded grappling hook stays loaded when you put it away, until you fire it.");
			new Harmony("com.dreich.keeploaded").PatchAll();
		}

		private ConfigEntry<T> BindShared<T>(string section, string key, T defaultValue, string description)
		{
			ConfigEntry<T> val = ((BaseUnityPlugin)this).Config.Bind<T>(section, key, defaultValue, description);
			if (ConfigSyncAvailable)
			{
				ConfigSyncCompat.AddConfigEntry<T>(val, serverControlled: true);
			}
			return val;
		}
	}
	internal static class ConfigSyncCompat
	{
		private static object configSync;

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void Initialize(string guid, string name, string version)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//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)
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Expected O, but got Unknown
			configSync = (object)new ConfigSync(guid)
			{
				DisplayName = name,
				CurrentVersion = version,
				MinimumRequiredVersion = version,
				ModRequired = false,
				ModRequirementMode = (ModRequirementMode)1
			};
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void AddLockingConfigEntry(ConfigEntry<bool> entry)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			((ConditionalConfigSync)(ConfigSync)configSync).AddLockingConfigEntry<bool>(entry);
		}

		[MethodImpl(MethodImplOptions.NoInlining)]
		internal static void AddConfigEntry<T>(ConfigEntry<T> entry, bool serverControlled)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			((ConditionalConfigSync)(ConfigSync)configSync).AddConfigEntry<T>(entry, (ConfigSyncMode)((!serverControlled) ? 2 : 0));
		}
	}
	internal static class LoadState
	{
		public const string Key = "KeepLoaded_Loaded";

		public static bool Unequipping;

		private static readonly MethodInfo SetWeaponLoaded = AccessTools.Method(typeof(Player), "SetWeaponLoaded", (Type[])null, (Type[])null);

		private static readonly MethodInfo CancelReloadAction = AccessTools.Method(typeof(Player), "CancelReloadAction", (Type[])null, (Type[])null);

		public static bool RequiresReload(ItemData item)
		{
			if (item != null && item.m_shared != null && item.m_shared.m_attack != null)
			{
				return item.m_shared.m_attack.m_requiresReload;
			}
			return false;
		}

		public static bool IsGrapplingHook(ItemData item)
		{
			try
			{
				GameObject attackProjectile = item.m_shared.m_attack.m_attackProjectile;
				if ((Object)(object)attackProjectile != (Object)null)
				{
					Projectile component = attackProjectile.GetComponent<Projectile>();
					if ((Object)(object)component != (Object)null && (Object)(object)component.m_spawnOnHit != (Object)null && (Object)(object)component.m_spawnOnHit.GetComponent<GrapplingPoint>() != (Object)null)
					{
						return true;
					}
				}
			}
			catch (Exception)
			{
			}
			string name = item.m_shared.m_name;
			if (name != null)
			{
				return name.IndexOf("grapp", StringComparison.OrdinalIgnoreCase) >= 0;
			}
			return false;
		}

		public static bool Enabled(ItemData item)
		{
			if (!RequiresReload(item))
			{
				return false;
			}
			if (!IsGrapplingHook(item))
			{
				return KeepLoaded.KeepCrossbow;
			}
			return KeepLoaded.KeepGrapplingHook;
		}

		public static bool IsFlagged(ItemData item)
		{
			if (item != null && item.m_customData != null)
			{
				return item.m_customData.ContainsKey("KeepLoaded_Loaded");
			}
			return false;
		}

		public static void SetFlag(ItemData item)
		{
			if (item != null && item.m_customData != null)
			{
				item.m_customData["KeepLoaded_Loaded"] = "1";
			}
		}

		public static void ClearFlag(ItemData item)
		{
			if (item != null && item.m_customData != null)
			{
				item.m_customData.Remove("KeepLoaded_Loaded");
			}
		}

		public static void Restore(Player player, ItemData item)
		{
			if (SetWeaponLoaded == null)
			{
				KeepLoaded.Log.LogWarning((object)"Could not find Player.SetWeaponLoaded - cannot restore loaded state.");
				return;
			}
			if (CancelReloadAction != null)
			{
				CancelReloadAction.Invoke(player, null);
			}
			SetWeaponLoaded.Invoke(player, new object[1] { item });
		}
	}
	[HarmonyPatch(typeof(Player), "SetWeaponLoaded")]
	internal static class WeaponLoadedPatch
	{
		private static void Postfix(Player __instance, ItemData __0)
		{
			if (__0 != null && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && LoadState.Enabled(__0))
			{
				LoadState.SetFlag(__0);
			}
		}
	}
	[HarmonyPatch(typeof(Humanoid), "UnequipItem")]
	internal static class UnequipPatch
	{
		private static void Prefix(Humanoid __instance, ItemData __0)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer))
			{
				LoadState.Unequipping = true;
				if (LoadState.IsFlagged(__0) && !LoadState.Enabled(__0))
				{
					LoadState.ClearFlag(__0);
				}
			}
		}

		private static void Finalizer()
		{
			LoadState.Unequipping = false;
		}
	}
	[HarmonyPatch(typeof(Player), "ResetLoadedWeapon")]
	internal static class FiredPatch
	{
		private static void Prefix(Player __instance, ItemData ___m_weaponLoaded)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && !LoadState.Unequipping)
			{
				LoadState.ClearFlag(___m_weaponLoaded);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "UpdateWeaponLoading")]
	internal static class RestorePatch
	{
		private static bool Prefix(Player __instance, ItemData __0, ItemData ___m_weaponLoaded)
		{
			if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer || __0 == null)
			{
				return true;
			}
			if (___m_weaponLoaded == __0)
			{
				return true;
			}
			if (!LoadState.Enabled(__0) || !LoadState.IsFlagged(__0))
			{
				return true;
			}
			LoadState.Restore(__instance, __0);
			return false;
		}
	}
}