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";
}
}