Decompiled source of SimpleTweaks v1.1.3

plugins/SimpleTweaks.dll

Decompiled a month ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using UnityEngine;
using Zorro.Core;
using Zorro.Core.Serizalization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyVersion("0.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 SimpleTweaks
{
	[HarmonyPatch(typeof(CharacterAnimations), "PlayEmote")]
	internal static class Patch_BackflipAlwaysSucceed
	{
		private const string BackflipEmote = "A_Scout_Emote_BackFlip";

		private static readonly FieldInfo CharacterField = AccessTools.Field(typeof(CharacterAnimations), "character");

		private static bool Prefix(CharacterAnimations __instance, string emoteName)
		{
			return SafeExec.RunPrefix("BackflipAlwaysSucceed", () => Body(__instance, emoteName));
		}

		private static bool Body(CharacterAnimations __instance, string emoteName)
		{
			if (!Plugin.cfgEnableBackflipAlwaysSucceed.Value)
			{
				return true;
			}
			if (emoteName != "A_Scout_Emote_BackFlip")
			{
				return true;
			}
			if (CharacterField == null)
			{
				return true;
			}
			object? value = CharacterField.GetValue(__instance);
			Character val = (Character)((value is Character) ? value : null);
			if (val == null)
			{
				return true;
			}
			if (val.refs == null || (Object)(object)val.refs.view == (Object)null)
			{
				return true;
			}
			val.refs.view.RPC("RPCA_PlayRemove", (RpcTarget)0, new object[2] { emoteName, false });
			return false;
		}
	}
	internal static class PendingClientSwap
	{
		internal struct Snapshot
		{
			public readonly byte HandSlotID;

			public readonly byte BackpackSlotID;

			public readonly BackpackReference BackpackRef;

			public Snapshot(byte handSlotID, byte backpackSlotID, BackpackReference bpRef)
			{
				//IL_000f: Unknown result type (might be due to invalid IL or missing references)
				//IL_0010: Unknown result type (might be due to invalid IL or missing references)
				HandSlotID = handSlotID;
				BackpackSlotID = backpackSlotID;
				BackpackRef = bpRef;
			}
		}

		private static bool _active;

		private static int _expectedItemViewID;

		private static Character _expectedCharacter;

		private static float _requestTime;

		private const float TimeoutSeconds = 1.5f;

		public static byte HandSlotID { get; private set; }

		public static byte BackpackSlotID { get; private set; }

		public static BackpackReference BackpackRef { get; private set; }

		public static void Set(Character character, int itemViewID, byte handSlotID, byte backpackSlotID, BackpackReference bpRef)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			_active = true;
			_expectedCharacter = character;
			_expectedItemViewID = itemViewID;
			HandSlotID = handSlotID;
			BackpackSlotID = backpackSlotID;
			BackpackRef = bpRef;
			_requestTime = Time.time;
		}

		public static void Clear()
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			_active = false;
			_expectedCharacter = null;
			_expectedItemViewID = 0;
			BackpackRef = default(BackpackReference);
		}

		public static bool TryConsume(Character character, out Snapshot snapshot)
		{
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			snapshot = default(Snapshot);
			if (!_active)
			{
				return false;
			}
			if (Time.time - _requestTime > 1.5f)
			{
				SafeExec.Verbose("待处理交换已超时,丢弃。");
				Clear();
				return false;
			}
			if ((Object)(object)_expectedCharacter == (Object)null || (Object)(object)_expectedCharacter != (Object)(object)character)
			{
				SafeExec.Verbose("待处理交换的角色不匹配,丢弃。");
				Clear();
				return false;
			}
			BackpackReference backpackRef = BackpackRef;
			if (!((BackpackReference)(ref backpackRef)).exists)
			{
				SafeExec.Verbose("待处理交换的背包已不存在,丢弃。");
				Clear();
				return false;
			}
			snapshot = new Snapshot(HandSlotID, BackpackSlotID, BackpackRef);
			Clear();
			return true;
		}
	}
	internal static class BackpackSwapLogic
	{
		private static readonly FieldInfo VisualItemsField = AccessTools.Field(typeof(BackpackVisuals), "visualItems");

		public static void DoSwapLogic(Character character, byte handSlotID, BackpackReference bpRef, byte bpSlotID)
		{
			//IL_006f: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			if (!PhotonNetwork.IsMasterClient)
			{
				return;
			}
			ItemSlot itemSlot = character.player.GetItemSlot(handSlotID);
			BackpackData data = ((BackpackReference)(ref bpRef)).GetData();
			if (itemSlot != null && data != null && bpSlotID < data.itemSlots.Length)
			{
				ItemSlot val = data.itemSlots[bpSlotID];
				if (val != null)
				{
					Item prefab = itemSlot.prefab;
					ItemInstanceData data2 = itemSlot.data;
					Item prefab2 = val.prefab;
					ItemInstanceData data3 = val.data;
					val.SetItem(prefab, data2);
					itemSlot.SetItem(prefab2, data3);
					ClearBackpackVisualSlot(bpRef, bpSlotID);
					SyncInventory(character);
					SyncBackpack(bpRef);
					((BackpackReference)(ref bpRef)).GetVisuals().RefreshVisuals();
					SafeExec.Verbose($"房主端交换完成:手部槽 {handSlotID} <-> 背包槽 {bpSlotID}");
				}
			}
		}

		private static void ClearBackpackVisualSlot(BackpackReference bpRef, byte slotID)
		{
			BackpackVisuals visuals = ((BackpackReference)(ref bpRef)).GetVisuals();
			if ((Object)(object)visuals == (Object)null)
			{
				return;
			}
			if (visuals.spawnedVisualItems.TryGetValue(slotID, out var value))
			{
				if ((Object)(object)value != (Object)null)
				{
					PhotonNetwork.Destroy(((Component)value).gameObject);
				}
				visuals.spawnedVisualItems.Remove(slotID);
			}
			if (!(VisualItemsField == null))
			{
				object value2 = VisualItemsField.GetValue(visuals);
				value2?.GetType().GetMethod("Remove", new Type[1] { typeof(byte) })?.Invoke(value2, new object[1] { slotID });
			}
		}

		private static void SyncInventory(Character character)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = IBinarySerializable.ToManagedArray<InventorySyncData>(new InventorySyncData(character.player.itemSlots, character.player.backpackSlot, character.player.tempFullSlot));
			((MonoBehaviourPun)character.player).photonView.RPC("SyncInventoryRPC", (RpcTarget)1, new object[2] { array, false });
		}

		private static void SyncBackpack(BackpackReference bpRef)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			if ((int)bpRef.type == 0)
			{
				bpRef.view.RPC("SetItemInstanceDataRPC", (RpcTarget)1, new object[1] { ((BackpackReference)(ref bpRef)).GetItemInstanceData() });
			}
		}

		public static void RefreshHandVisual(Character character, byte handSlotID)
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			if (!character.IsLocal)
			{
				return;
			}
			CharacterItems val = character.refs?.items;
			if (!((Object)(object)val == (Object)null))
			{
				if (handSlotID == 250)
				{
					((MonoBehaviourPun)val).photonView.RPC("DestroyHeldItemRpc", (RpcTarget)0, Array.Empty<object>());
				}
				val.EquipSlot(Optionable<byte>.Some(handSlotID));
			}
		}
	}
	[HarmonyPatch(typeof(Item), "Interact")]
	internal static class BackpackSwapPatch
	{
		private static bool Prefix(Item __instance, Character interactor)
		{
			return SafeExec.RunPrefix("BackpackSwap.Interact", () => Body(__instance, interactor));
		}

		private static bool Body(Item __instance, Character interactor)
		{
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_001a: Invalid comparison between Unknown and I4
			//IL_00ea: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			PendingClientSwap.Clear();
			if (!Plugin.cfgEnableBackpackSwap.Value)
			{
				return true;
			}
			if ((int)__instance.itemState != 2 || !__instance.backpackReference.IsSome)
			{
				return true;
			}
			if ((Object)(object)interactor == (Object)null || (Object)(object)interactor.player == (Object)null || interactor.refs == null || (Object)(object)interactor.refs.items == (Object)null)
			{
				return true;
			}
			if ((Object)(object)interactor.data.currentItem == (Object)null)
			{
				return true;
			}
			if (!interactor.refs.items.currentSelectedSlot.IsSome)
			{
				return true;
			}
			byte value = interactor.refs.items.currentSelectedSlot.Value;
			if (!interactor.data.currentItem.UIData.canPocket)
			{
				return true;
			}
			if (interactor.data.isClimbing && !__instance.UIData.canPocket)
			{
				return true;
			}
			var (b, bpRef) = __instance.backpackReference.Value;
			if (!((BackpackReference)(ref bpRef)).exists)
			{
				return true;
			}
			if (PhotonNetwork.IsMasterClient)
			{
				BackpackSwapLogic.DoSwapLogic(interactor, value, bpRef, b);
				BackpackSwapLogic.RefreshHandVisual(interactor, value);
				((Component)__instance).gameObject.SetActive(false);
				return false;
			}
			if (!interactor.player.HasEmptySlot(__instance.itemID))
			{
				return true;
			}
			if (interactor.data.isClimbingAnything)
			{
				return true;
			}
			int itemViewID = (((Object)(object)((MonoBehaviourPun)__instance).photonView != (Object)null) ? ((MonoBehaviourPun)__instance).photonView.ViewID : 0);
			PendingClientSwap.Set(interactor, itemViewID, value, b, bpRef);
			SafeExec.Verbose($"客户端发起交换:手部槽 {value} -> 背包槽 {b},等待房主回调。");
			return true;
		}
	}
	[HarmonyPatch(typeof(CharacterItems), "OnPickupAccepted")]
	internal static class BackpackSwapCompletePatch
	{
		private static bool Prefix(CharacterItems __instance, byte slotID)
		{
			bool handled = false;
			SafeExec.Run("BackpackSwap.OnPickupAccepted", delegate
			{
				handled = Body(__instance, slotID);
			});
			return !handled;
		}

		private static bool Body(CharacterItems __instance, byte slotID)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_009a: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null)
			{
				return false;
			}
			Character component = ((Component)__instance).GetComponent<Character>();
			SafeExec.Verbose($"OnPickupAccepted: slotID={slotID}");
			if (!PendingClientSwap.TryConsume(component, out var snapshot))
			{
				return false;
			}
			byte handSlotID = snapshot.HandSlotID;
			byte backpackSlotID = snapshot.BackpackSlotID;
			BackpackReference backpackRef = snapshot.BackpackRef;
			if ((Object)(object)component == (Object)null || !component.IsLocal || (Object)(object)component.player == (Object)null)
			{
				return false;
			}
			if (slotID == handSlotID || slotID == 3)
			{
				return false;
			}
			ItemSlot itemSlot = component.player.GetItemSlot(handSlotID);
			if (itemSlot == null || itemSlot.IsEmpty())
			{
				return false;
			}
			if (!((BackpackReference)(ref backpackRef)).exists || (Object)(object)backpackRef.view == (Object)null)
			{
				return false;
			}
			string text = (((int)backpackRef.type == 0) ? "RPCAddItemToBackpack" : "RPCAddItemToCharacterBackpack");
			backpackRef.view.RPC(text, (RpcTarget)0, new object[3]
			{
				((MonoBehaviourPun)component.player).photonView,
				handSlotID,
				backpackSlotID
			});
			ItemSlot itemSlot2 = component.player.GetItemSlot(slotID);
			if (handSlotID <= 2 && itemSlot2 != null && !itemSlot2.IsEmpty())
			{
				Item prefab = itemSlot2.prefab;
				ItemInstanceData data = itemSlot2.data;
				itemSlot2.EmptyOut();
				itemSlot.SetItem(prefab, data);
				ForceSyncInventory(component);
				SafeExec.Verbose($"取出物品已由槽 {slotID} 重排到原手持槽 {handSlotID}。");
				component.refs.items.EquipSlot(Optionable<byte>.Some(handSlotID));
				component.refs.items.RefreshAllCharacterCarryWeight();
				return true;
			}
			PlayerCompat.EmptySlot(component.player, handSlotID);
			return false;
		}

		private static void ForceSyncInventory(Character character)
		{
			//IL_0021: Unknown result type (might be due to invalid IL or missing references)
			byte[] array = IBinarySerializable.ToManagedArray<InventorySyncData>(new InventorySyncData(character.player.itemSlots, character.player.backpackSlot, character.player.tempFullSlot));
			((MonoBehaviourPun)character.player).photonView.RPC("SyncInventoryRPC", (RpcTarget)1, new object[2] { array, true });
		}
	}
	[HarmonyPatch(typeof(Character), "UpdateVariablesFixed")]
	internal static class Patch_DeathRegeneration
	{
		private static void Postfix(Character __instance)
		{
			SafeExec.Run("DeathRegeneration", delegate
			{
				Body(__instance);
			});
		}

		private static void Body(Character __instance)
		{
			if (!Plugin.cfgEnableDeathRegeneration.Value || (Object)(object)__instance == (Object)null || (Object)(object)((MonoBehaviourPun)__instance).photonView == (Object)null || !((MonoBehaviourPun)__instance).photonView.IsMine)
			{
				return;
			}
			CharacterData data = __instance.data;
			if (!((Object)(object)data == (Object)null) && data.fullyPassedOut && !((Object)(object)data.carrier == (Object)null) && __instance.refs != null && !((Object)(object)__instance.refs.afflictions == (Object)null) && !__instance.refs.afflictions.willZombify && !((Object)(object)__instance.input == (Object)null) && !__instance.input.interactIsPressed)
			{
				float num = Mathf.Max(0f, Plugin.cfgDeathRegenerationRate.Value);
				if (!(num <= 0f))
				{
					data.deathTimer = Mathf.Max(0f, data.deathTimer - num * Time.fixedDeltaTime / 60f);
				}
			}
		}
	}
	internal static class HungerOverflowState
	{
		private static readonly FieldInfo IncrementalField = AccessTools.Field(typeof(CharacterAfflictions), "currentIncrementalStatuses");

		private static float _capturedHunger = 0f;

		public static Character GetConsumer(ItemActionBase action)
		{
			if ((Object)(object)action == (Object)null)
			{
				return null;
			}
			Item component = ((Component)action).GetComponent<Item>();
			if (!((Object)(object)component != (Object)null))
			{
				return null;
			}
			return component.holderCharacter;
		}

		public static void CaptureBefore(Character character)
		{
			_capturedHunger = 0f;
			if (!((Object)(object)character == (Object)null) && character.IsLocal)
			{
				CharacterAfflictions val = character.refs?.afflictions;
				if (!((Object)(object)val == (Object)null))
				{
					_capturedHunger = Mathf.Max(0f, val.GetCurrentStatus((STATUSTYPE)1));
				}
			}
		}

		public static void Apply(Character character, float restoreAmount)
		{
			if ((Object)(object)character == (Object)null || !character.IsLocal)
			{
				return;
			}
			float capturedHunger = _capturedHunger;
			_capturedHunger = 0f;
			if (restoreAmount <= 0f)
			{
				return;
			}
			float num = Mathf.Max(0f, restoreAmount - capturedHunger);
			if (num <= 0f)
			{
				return;
			}
			CharacterAfflictions val = character.refs?.afflictions;
			if ((Object)(object)val == (Object)null)
			{
				return;
			}
			float num2 = val.hungerPerSecond * Ascents.hungerRateMultiplier;
			if (num2 <= 0f)
			{
				return;
			}
			float num3 = Mathf.Max(0f, Plugin.cfgHungerOverflowSecondsPerPoint.Value);
			float num4 = num * 100f * num3;
			float num5 = num4 * num2;
			if (!(IncrementalField == null) && IncrementalField.GetValue(val) is float[] array && array.Length > 1)
			{
				array[1] = Mathf.Min(array[1], 0f);
				float value = Plugin.cfgHungerOverflowMaxSeconds.Value;
				if (value > 0f)
				{
					float num6 = 0.025f - value * num2;
					array[1] = Mathf.Max(array[1] - num5, num6);
				}
				else
				{
					array[1] -= num5;
				}
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogDebug((object)$"[饥饿溢出] 溢出 {num * 100f:0.#} 点(恢复 {restoreAmount * 100f:0.#},已有 {capturedHunger * 100f:0.#})→ 倒计时延长 {num4:0.#} 秒");
				}
			}
		}
	}
	[HarmonyPatch(typeof(Action_RestoreHunger), "RunAction")]
	internal static class Patch_ActionRestoreHunger_Overflow
	{
		private static void Prefix(Action_RestoreHunger __instance)
		{
			SafeExec.Run("HungerOverflow.RestoreHunger.Prefix", delegate
			{
				if (Plugin.cfgEnableHungerOverflow.Value)
				{
					HungerOverflowState.CaptureBefore(HungerOverflowState.GetConsumer((ItemActionBase)(object)__instance));
				}
			});
		}

		private static void Postfix(Action_RestoreHunger __instance)
		{
			SafeExec.Run("HungerOverflow.RestoreHunger.Postfix", delegate
			{
				if (Plugin.cfgEnableHungerOverflow.Value)
				{
					HungerOverflowState.Apply(HungerOverflowState.GetConsumer((ItemActionBase)(object)__instance), __instance.restorationAmount);
				}
			});
		}
	}
	[HarmonyPatch(typeof(Action_ModifyStatus), "RunAction")]
	internal static class Patch_ActionModifyStatus_Overflow
	{
		private static readonly FieldInfo IfSkeletonField = AccessTools.Field(typeof(Action_ModifyStatus), "ifSkeleton");

		private static void Prefix(Action_ModifyStatus __instance, ref bool __state)
		{
			bool skip = true;
			SafeExec.Run("HungerOverflow.ModifyStatus.Prefix", delegate
			{
				skip = ShouldSkipPostfix(__instance);
			});
			__state = skip;
		}

		private static bool ShouldSkipPostfix(Action_ModifyStatus __instance)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Invalid comparison between Unknown and I4
			if (!Plugin.cfgEnableHungerOverflow.Value)
			{
				return true;
			}
			if ((int)__instance.statusType != 1 || __instance.changeAmount >= 0f)
			{
				return true;
			}
			Character consumer = HungerOverflowState.GetConsumer((ItemActionBase)(object)__instance);
			if (IfSkeletonField != null && (bool)IfSkeletonField.GetValue(__instance) && ((Object)(object)consumer == (Object)null || (Object)(object)consumer.data == (Object)null || !consumer.data.isSkeleton))
			{
				return true;
			}
			HungerOverflowState.CaptureBefore(consumer);
			return false;
		}

		private static void Postfix(Action_ModifyStatus __instance, bool __state)
		{
			if (!__state)
			{
				SafeExec.Run("HungerOverflow.ModifyStatus.Postfix", delegate
				{
					HungerOverflowState.Apply(HungerOverflowState.GetConsumer((ItemActionBase)(object)__instance), Mathf.Abs(__instance.changeAmount));
				});
			}
		}
	}
	internal static class PeakStatsExCompat
	{
		private const string PeakStatsExTypeName = "PeakStatsEx.StaminaInfoPatch";

		private static readonly FieldInfo IncrementalField = AccessTools.Field(typeof(CharacterAfflictions), "currentIncrementalStatuses");

		public static void Apply(Harmony harmony)
		{
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Expected O, but got Unknown
			Type type = AccessTools.TypeByName("PeakStatsEx.StaminaInfoPatch");
			if (type == null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)"PeakStatsEx 未加载,跳过饥饿倒计时显示兼容补丁。");
				}
				return;
			}
			MethodInfo methodInfo = AccessTools.Method(type, "GetHungerIncrementalStatus", (Type[])null, (Type[])null);
			if (methodInfo == null)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogWarning((object)"PeakStatsEx 已加载,但未找到 GetHungerIncrementalStatus,跳过兼容补丁。");
				}
				return;
			}
			MethodInfo methodInfo2 = AccessTools.Method(typeof(PeakStatsExCompat), "PostfixNegativeIncremental", (Type[])null, (Type[])null);
			harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(methodInfo2), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			ManualLogSource log3 = Plugin.Log;
			if (log3 != null)
			{
				log3.LogInfo((object)"已应用 PeakStatsEx 饥饿倒计时显示兼容补丁。");
			}
		}

		private static void PostfixNegativeIncremental(CharacterAfflictions afflictions, ref float __result)
		{
			float result = __result;
			SafeExec.Run("PeakStatsExCompat", delegate
			{
				if (!((Object)(object)afflictions == (Object)null) && !(IncrementalField == null) && IncrementalField.GetValue(afflictions) is float[] array && array.Length > 1)
				{
					float num = array[1];
					if (num < 0f)
					{
						result = num;
					}
				}
			});
			__result = result;
		}
	}
	internal static class PlayerCompat
	{
		private static MethodInfo _emptySlot;

		private static object[] _emptySlotArgsTemplate;

		private static bool _resolved;

		public static void EmptySlot(Player player, byte slotID)
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)player == (Object)null)
			{
				return;
			}
			Resolve();
			if (_emptySlot == null)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogWarning((object)"未能解析 Player.EmptySlot,跳过清空手部槽。");
				}
			}
			else
			{
				object[] array = (object[])_emptySlotArgsTemplate.Clone();
				array[0] = Optionable<byte>.Some(slotID);
				_emptySlot.Invoke(player, array);
			}
		}

		private static void Resolve()
		{
			if (_resolved)
			{
				return;
			}
			_resolved = true;
			_emptySlot = AccessTools.GetDeclaredMethods(typeof(Player)).FirstOrDefault((MethodInfo m) => m.Name == "EmptySlot" && m.GetParameters().Length >= 1 && m.GetParameters()[0].ParameterType == typeof(Optionable<byte>));
			if (_emptySlot == null)
			{
				return;
			}
			ParameterInfo[] parameters = _emptySlot.GetParameters();
			_emptySlotArgsTemplate = new object[parameters.Length];
			for (int num = 1; num < parameters.Length; num++)
			{
				if (parameters[num].HasDefaultValue)
				{
					_emptySlotArgsTemplate[num] = parameters[num].DefaultValue;
				}
				else if (parameters[num].ParameterType.IsValueType)
				{
					_emptySlotArgsTemplate[num] = Activator.CreateInstance(parameters[num].ParameterType);
				}
				else
				{
					_emptySlotArgsTemplate[num] = null;
				}
			}
			if (parameters.Length > 1)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)$"Player.EmptySlot 解析成功({parameters.Length} 个参数,已按游戏默认值补齐)。");
				}
			}
		}
	}
	internal static class SafeExec
	{
		private const int MaxLogsPerSite = 5;

		private static readonly Dictionary<string, int> _logCounts = new Dictionary<string, int>();

		public static bool VerboseEnabled
		{
			get
			{
				if (Plugin.cfgVerboseDiagnostics != null)
				{
					return Plugin.cfgVerboseDiagnostics.Value;
				}
				return false;
			}
		}

		public static void Run(string site, Action body)
		{
			try
			{
				body();
			}
			catch (Exception ex)
			{
				LogOnce(site, ex);
			}
		}

		public static bool RunPrefix(string site, Func<bool> body)
		{
			try
			{
				return body();
			}
			catch (Exception ex)
			{
				LogOnce(site, ex);
				return true;
			}
		}

		public static void Verbose(string message)
		{
			if (VerboseEnabled)
			{
				ManualLogSource log = Plugin.Log;
				if (log != null)
				{
					log.LogInfo((object)("[诊断] " + message));
				}
			}
		}

		private static void LogOnce(string site, Exception ex)
		{
			_logCounts.TryGetValue(site, out var value);
			if (value >= 5)
			{
				return;
			}
			_logCounts[site] = value + 1;
			ManualLogSource log = Plugin.Log;
			if (log != null)
			{
				log.LogError((object)$"[{site}] 补丁内部异常(已捕获,不影响游戏原版逻辑):{ex}");
			}
			if (value + 1 == 5)
			{
				ManualLogSource log2 = Plugin.Log;
				if (log2 != null)
				{
					log2.LogError((object)$"[{site}] 该位置异常已达 {5} 次,后续不再重复记录。");
				}
			}
		}
	}
	[BepInPlugin("com.simpletweaks.peak", "SimpleTweaks", "1.1.3")]
	[BepInProcess("PEAK.exe")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Plugin : BaseUnityPlugin
	{
		internal static ConfigEntry<bool> cfgEnableHungerOverflow;

		internal static ConfigEntry<float> cfgHungerOverflowSecondsPerPoint;

		internal static ConfigEntry<float> cfgHungerOverflowMaxSeconds;

		internal static ConfigEntry<bool> cfgEnableBackpackSwap;

		internal static ConfigEntry<bool> cfgEnableBackflipAlwaysSucceed;

		internal static ConfigEntry<bool> cfgEnableDeathRegeneration;

		internal static ConfigEntry<float> cfgDeathRegenerationRate;

		internal static ConfigEntry<bool> cfgVerboseDiagnostics;

		internal static ManualLogSource Log;

		private void Awake()
		{
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Expected O, but got Unknown
			Log = ((BaseUnityPlugin)this).Logger;
			cfgEnableHungerOverflow = ((BaseUnityPlugin)this).Config.Bind<bool>("Hunger", "EnableHungerOverflow", true, "饥饿溢出延长计时开关。吃食物时,超过当前饥饿值的恢复量会按比例延长下一次变饿的倒计时。");
			cfgHungerOverflowSecondsPerPoint = ((BaseUnityPlugin)this).Config.Bind<float>("Hunger", "HungerOverflowSecondsPerPoint", 10f, "每溢出 1 点饥饿值(1%)延长饥饿倒计时的秒数。默认 10 秒。");
			cfgHungerOverflowMaxSeconds = ((BaseUnityPlugin)this).Config.Bind<float>("Hunger", "HungerOverflowMaxSeconds", 120f, "饥饿倒计时延长后的上限(秒)。无论溢出多少,倒计时都不会超过此值,默认 120 秒(2 分钟)。0 表示不限制。");
			cfgEnableBackpackSwap = ((BaseUnityPlugin)this).Config.Bind<bool>("Backpack", "EnableBackpackSwap", true, "背包物品替换开关。手上已有物品时点击背包中物品,会将手中物品与背包物品互换位置。");
			cfgEnableBackflipAlwaysSucceed = ((BaseUnityPlugin)this).Config.Bind<bool>("Emote", "EnableBackflipAlwaysSucceed", true, "后空翻 100% 成功开关。原版后空翻有 50% 概率失败倒地,开启后必定成功落地。");
			cfgEnableDeathRegeneration = ((BaseUnityPlugin)this).Config.Bind<bool>("Death", "EnableDeathRegeneration", true, "死亡计时回复开关。本地玩家被其他玩家背着时,死亡计时(昏迷倒计时)会缓慢回复。");
			cfgDeathRegenerationRate = ((BaseUnityPlugin)this).Config.Bind<float>("Death", "DeathRegenerationRate", 1f, "死亡计时回复速率(相对原版消耗速率)。1.0 = 与消耗同速回复(默认);0.5 = 回复速度是消耗速度的一半。0 或负数表示不回复。");
			cfgVerboseDiagnostics = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "VerboseDiagnostics", false, "详细诊断日志开关。开启后会把拾取/背包交换的关键步骤输出到 BepInEx 日志,用于排查问题。日常游玩建议关闭。");
			Harmony val = new Harmony("com.simpletweaks.peak");
			val.PatchAll();
			PeakStatsExCompat.Apply(val);
			Log.LogInfo((object)"SimpleTweaks v1.1.3 已加载");
		}
	}
	internal static class PluginInfo
	{
		public const string PLUGIN_GUID = "com.simpletweaks.peak";

		public const string PLUGIN_NAME = "SimpleTweaks";

		public const string PLUGIN_VERSION = "1.1.3";
	}
}