Decompiled source of KeepInventory v1.0.1

Plugins/KeepInventoryMod.dll

Decompiled 3 weeks ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
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: AssemblyCompany("KeepInventoryMod")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+afe36626851150ec2b938dba2d7f227cff748b60")]
[assembly: AssemblyProduct("KeepInventoryMod")]
[assembly: AssemblyTitle("KeepInventoryMod")]
[assembly: AssemblyVersion("1.0.0.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 KeepInventoryMod
{
	[BepInPlugin("com.mods.keepinventory", "KeepInventory", "1.0.1")]
	public class Plugin : BaseUnityPlugin
	{
		public const string PLUGIN_GUID = "com.mods.keepinventory";

		public const string PLUGIN_NAME = "KeepInventory";

		public const string PLUGIN_VERSION = "1.0.1";

		public static ConfigEntry<bool> KeepItemsOnDeath;

		private Harmony _harmony;

		public static Plugin Instance { get; private set; }

		public static ManualLogSource Log { get; private set; }

		private void Awake()
		{
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Expected O, but got Unknown
			Instance = this;
			Log = ((BaseUnityPlugin)this).Logger;
			KeepItemsOnDeath = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "KeepItemsOnDeath", true, "Prevent items from dropping when the player dies");
			_harmony = new Harmony("com.mods.keepinventory");
			_harmony.PatchAll();
			Log.LogInfo((object)"KeepInventory v1.0.1 loaded!");
			Log.LogInfo((object)$"  KeepItemsOnDeath = {KeepItemsOnDeath.Value}");
		}

		private void OnDestroy()
		{
			Harmony harmony = _harmony;
			if (harmony != null)
			{
				harmony.UnpatchSelf();
			}
		}
	}
	public static class PluginInfo
	{
		public const string PLUGIN_GUID = "com.mods.keepinventory";

		public const string PLUGIN_NAME = "KeepInventory";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace KeepInventoryMod.Patches
{
	[HarmonyPatch]
	public static class DeathDropPatch
	{
		private static bool _playerIsDead;

		[HarmonyPatch(typeof(PlayerAvatar), "PlayerDeath")]
		[HarmonyPrefix]
		[HarmonyPriority(800)]
		private static void OnPlayerDeath()
		{
			if (Plugin.KeepItemsOnDeath.Value)
			{
				_playerIsDead = true;
				Plugin.Log.LogInfo((object)"[KeepInventory] PlayerDeath — dead flag ON");
			}
		}

		[HarmonyPatch(typeof(PlayerAvatar), "ReviveRPC")]
		[HarmonyPostfix]
		private static void OnRevive()
		{
			_playerIsDead = false;
			Plugin.Log.LogInfo((object)"[KeepInventory] ReviveRPC — dead flag OFF");
		}

		public static void ConditionalForceUnequip(Inventory inventory)
		{
			if (!Plugin.KeepItemsOnDeath.Value)
			{
				inventory.ForceUnequip();
			}
			else
			{
				Plugin.Log.LogInfo((object)"[KeepInventory] BLOCKED Inventory.ForceUnequip — slot items kept!");
			}
		}

		[HarmonyPatch(typeof(PlayerAvatar), "PlayerDeathDone")]
		[HarmonyTranspiler]
		private static IEnumerable<CodeInstruction> TranspileDeathDone(IEnumerable<CodeInstruction> instructions)
		{
			MethodInfo forceUnequipMethod = AccessTools.Method(typeof(Inventory), "ForceUnequip", (Type[])null, (Type[])null);
			MethodInfo replacement = AccessTools.Method(typeof(DeathDropPatch), "ConditionalForceUnequip", (Type[])null, (Type[])null);
			int patchCount = 0;
			foreach (CodeInstruction instruction in instructions)
			{
				if (forceUnequipMethod != null && CodeInstructionExtensions.Calls(instruction, forceUnequipMethod))
				{
					yield return new CodeInstruction(OpCodes.Call, (object)replacement);
					patchCount++;
				}
				else
				{
					yield return instruction;
				}
			}
			Plugin.Log.LogInfo((object)$"[KeepInventory] Transpiler: patched {patchCount} ForceUnequip calls in PlayerDeathDone");
		}

		[HarmonyPatch(typeof(StatsManager), "PlayerInventoryUpdate")]
		[HarmonyPrefix]
		private static bool PreventInventoryClear(string _steamID, string itemName, int spot, bool sync)
		{
			if (!Plugin.KeepItemsOnDeath.Value)
			{
				return true;
			}
			if (string.IsNullOrEmpty(itemName) && _playerIsDead)
			{
				Plugin.Log.LogInfo((object)$"[KeepInventory] BLOCKED inventory slot {spot} clear");
				return false;
			}
			return true;
		}

		public static void Reset()
		{
			_playerIsDead = false;
		}
	}
	[HarmonyPatch(typeof(MainMenuOpen), "Start")]
	public static class MainMenuClearPatch
	{
		[HarmonyPostfix]
		private static void Postfix()
		{
			DeathDropPatch.Reset();
			Plugin.Log.LogInfo((object)"[KeepInventory] Main menu — state reset.");
		}
	}
}