Decompiled source of ShareChest v1.0.2

ShareChest.dll

Decompiled 2 weeks ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using R2API;
using RoR2;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.SceneManagement;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("ShareChest")]
[assembly: AssemblyDescription("共享宝箱 - Risk of Rain 2 模组")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Muskmelovon")]
[assembly: AssemblyProduct("ShareChest")]
[assembly: AssemblyCopyright("Copyright © Muskmelovon 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("f2eff138-24ee-4741-88c1-c6ff8bf1d179")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace ShareChest
{
	public abstract class ArtifactBase
	{
		public ArtifactDef ArtifactDef;

		public abstract string ArtifactName { get; }

		public abstract string ArtifactLangTokenName { get; }

		public abstract string ArtifactDescription { get; }

		public abstract Sprite ArtifactEnabledIcon { get; }

		public abstract Sprite ArtifactDisabledIcon { get; }

		public virtual string DisplayName => ArtifactName;

		public bool ArtifactEnabled
		{
			get
			{
				RunArtifactManager instance = RunArtifactManager.instance;
				return instance != null && instance.IsArtifactEnabled(ArtifactDef);
			}
		}

		public abstract void Init(ConfigFile config);

		protected void CreateLang()
		{
			LanguageAPI.Add("ARTIFACT_" + ArtifactLangTokenName + "_NAME", DisplayName);
			LanguageAPI.Add("ARTIFACT_" + ArtifactLangTokenName + "_DESCRIPTION", ArtifactDescription);
		}

		protected bool CreateArtifact()
		{
			ArtifactDef = ScriptableObject.CreateInstance<ArtifactDef>();
			ArtifactDef.cachedName = "ARTIFACT_" + ArtifactLangTokenName;
			ArtifactDef.nameToken = "ARTIFACT_" + ArtifactLangTokenName + "_NAME";
			ArtifactDef.descriptionToken = "ARTIFACT_" + ArtifactLangTokenName + "_DESCRIPTION";
			ArtifactDef.smallIconSelectedSprite = ArtifactEnabledIcon;
			ArtifactDef.smallIconDeselectedSprite = ArtifactDisabledIcon;
			bool flag = ContentAddition.AddArtifactDef(ArtifactDef);
			if (!flag)
			{
				ShareChestPlugin.LogError("神器 " + ArtifactName + " 添加失败!可能图标为null或重复。");
			}
			return flag;
		}

		public abstract void Hooks();
	}
	internal class ArtifactOfEquilibrium : ArtifactBase
	{
		public override string ArtifactName => "Artifact of Equilibrium";

		public override string ArtifactLangTokenName => "EQUILIBRIUM";

		public override string DisplayName => "Artifact of Equilibrium - 均衡神器";

		public override string ArtifactDescription => "开启后,宝箱会掉落多倍物品(根据玩家数量动态调整或固定倍率,需前往配置文件修改配置)。\n启用此神器以激活共享宝箱Mod的多倍掉落。\n\nOnce activated, the treasure chest will drop items in multiple times (the multiplier is dynamically adjusted according to the number of players or can be set as a fixed rate. The configuration needs to be modified in the configuration file). \nEnable this artifact to activate the multiple-dropping feature of the Shared Treasure Chest Mod.";

		public override Sprite ArtifactEnabledIcon => GetIcon("ArtifactOfEquilibrium_On");

		public override Sprite ArtifactDisabledIcon => GetIcon("ArtifactOfEquilibrium_Off");

		private Sprite GetIcon(string iconName)
		{
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: 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)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: 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_009f: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)ShareChestPlugin.MainAssets != (Object)null)
			{
				Sprite val = ShareChestPlugin.MainAssets.LoadAsset<Sprite>(iconName);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
				ShareChestPlugin.LogWarning("未找到图标 " + iconName + ",将使用默认占位图标");
			}
			else
			{
				ShareChestPlugin.LogWarning("AssetBundle 未加载,使用默认占位图标");
			}
			Texture2D val2 = new Texture2D(2, 2);
			val2.SetPixels32((Color32[])(object)new Color32[4]
			{
				Color32.op_Implicit(Color.clear),
				Color32.op_Implicit(Color.clear),
				Color32.op_Implicit(Color.clear),
				Color32.op_Implicit(Color.clear)
			});
			val2.Apply();
			return Sprite.Create(val2, new Rect(0f, 0f, 2f, 2f), new Vector2(0.5f, 0.5f));
		}

		public override void Init(ConfigFile config)
		{
			CreateLang();
			if (CreateArtifact())
			{
				ShareChestPlugin.LogInfo("神器 " + ArtifactName + " 已成功注册到游戏。");
			}
			else
			{
				ShareChestPlugin.LogError("神器 " + ArtifactName + " 注册失败。");
			}
			Hooks();
		}

		public override void Hooks()
		{
			Run.onRunStartGlobal += OnRunStart;
		}

		private void OnRunStart(Run run)
		{
			if (NetworkServer.active)
			{
				ShareChestPlugin.IsArtifactEnabled = base.ArtifactEnabled;
				ShareChestPlugin.LogInfo("神器均衡宝箱状态: " + (ShareChestPlugin.IsArtifactEnabled ? "启用" : "禁用"));
			}
		}
	}
	[BepInPlugin("com.Muskmelovon.ShareChest", "共享宝箱", "1.0.0")]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class ShareChestPlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "com.Muskmelovon.ShareChest";

		public const string PluginName = "共享宝箱";

		public const string PluginVersion = "1.0.0";

		private static ManualLogSource Log;

		private static Harmony harmony;

		public static ConfigEntry<bool> ModEnabled;

		public static ConfigEntry<bool> EnableDynamicMultiplier;

		public static ConfigEntry<int> FixedMultiplier;

		public static ConfigEntry<bool> EnableDebugLogs;

		public static ConfigEntry<string> AffectedChestTypes;

		public static ConfigEntry<float> DropDistanceClamp;

		private static readonly string ChestListSeparator = ",";

		private static HashSet<string> affectedChestTypeSet = new HashSet<string>();

		public static AssetBundle MainAssets;

		private static List<ArtifactBase> artifacts = new List<ArtifactBase>();

		public static bool IsArtifactEnabled = false;

		public static bool IsInitialized { get; private set; } = false;


		public void Awake()
		{
			Log = ((BaseUnityPlugin)this).Logger;
			try
			{
				Log.LogInfo((object)"========== 共享宝箱 v1.0.0 初始化开始 ==========");
				LoadAssetBundle();
				InitializePlayerCountManager();
				InitializeConfiguration();
				InitializeArtifacts();
				InitializeHarmonyPatches();
				IsInitialized = true;
				Log.LogInfo((object)"插件初始化成功!");
				Log.LogInfo((object)$"当前配置:插件总开关={ModEnabled.Value}, 动态倍率={EnableDynamicMultiplier.Value}");
				Log.LogInfo((object)$"掉落距离设置:{DropDistanceClamp.Value}(原版为6)");
				Log.LogInfo((object)("应用倍率的宝箱类型:" + ((affectedChestTypeSet.Count > 0) ? string.Join(", ", affectedChestTypeSet) : "所有宝箱")));
				Log.LogInfo((object)"配置位置:BepInEx/config/com.Muskmelovon.ShareChest.cfg");
				Log.LogInfo((object)"调试命令:按 F5 显示调试信息,按 F6 强制重新计算玩家数量");
				Log.LogInfo((object)"==================================================");
			}
			catch (Exception ex)
			{
				Log.LogError((object)"插件初始化失败!");
				Log.LogError((object)("错误信息:" + ex.Message));
				Log.LogError((object)("堆栈跟踪:" + ex.StackTrace));
				if (ex.InnerException != null)
				{
					Log.LogError((object)("内部异常:" + ex.InnerException.Message));
				}
				try
				{
					Harmony obj = harmony;
					if (obj != null)
					{
						obj.UnpatchSelf();
					}
				}
				catch
				{
				}
				throw;
			}
		}

		private void LoadAssetBundle()
		{
			string[] manifestResourceNames = Assembly.GetExecutingAssembly().GetManifestResourceNames();
			string text = manifestResourceNames.FirstOrDefault((string r) => r.EndsWith(".assets", StringComparison.OrdinalIgnoreCase));
			if (text == null)
			{
				Log.LogWarning((object)"未找到任何 .assets 嵌入资源,神器图标将使用默认占位图。");
				return;
			}
			Log.LogInfo((object)("找到嵌入资源: " + text));
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(text);
			if (stream == null)
			{
				Log.LogError((object)("无法获取资源流: " + text));
				return;
			}
			MainAssets = AssetBundle.LoadFromStream(stream);
			if ((Object)(object)MainAssets == (Object)null)
			{
				Log.LogError((object)"AssetBundle.LoadFromStream 返回 null,请检查资源文件是否有效。");
			}
			else
			{
				Log.LogInfo((object)("AssetBundle 加载成功,包含的资源: " + string.Join(", ", MainAssets.GetAllAssetNames())));
			}
		}

		public void OnDestroy()
		{
			Harmony obj = harmony;
			if (obj != null)
			{
				obj.UnpatchSelf();
			}
		}

		public void Update()
		{
			if (Input.GetKeyDown((KeyCode)286))
			{
				ShowDebugInfo();
			}
			if (Input.GetKeyDown((KeyCode)287))
			{
				ForceRecalculate();
			}
		}

		private void InitializePlayerCountManager()
		{
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Expected O, but got Unknown
			Log.LogInfo((object)"正在初始化 PlayerCountManager...");
			if ((Object)(object)PlayerCountManager.Instance != (Object)null)
			{
				Log.LogWarning((object)"PlayerCountManager 已存在,跳过创建");
				return;
			}
			GameObject val = new GameObject("ShareChest_PlayerCountManager");
			val.AddComponent<PlayerCountManager>();
			Object.DontDestroyOnLoad((Object)(object)val);
			Log.LogInfo((object)"PlayerCountManager 初始化完成");
		}

		private void InitializeConfiguration()
		{
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Expected O, but got Unknown
			//IL_009c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a6: Expected O, but got Unknown
			//IL_00f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fa: Expected O, but got Unknown
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Expected O, but got Unknown
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Expected O, but got Unknown
			//IL_01f0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Expected O, but got Unknown
			Log.LogInfo((object)"正在初始化配置系统...");
			ModEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("通用设置", "启用插件", true, new ConfigDescription("插件总开关。注意:同时需要神器“共享宝箱”启用才能生效。", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 10,
					IsAdvanced = false
				}
			}));
			EnableDynamicMultiplier = ((BaseUnityPlugin)this).Config.Bind<bool>("掉落设置", "启用动态倍率", false, new ConfigDescription("是否根据玩家人数动态调整掉落倍率\n• true = 启用动态倍率(倍率 = 玩家人数)\n• false = 使用固定倍率", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 15,
					IsAdvanced = false
				}
			}));
			FixedMultiplier = ((BaseUnityPlugin)this).Config.Bind<int>("掉落设置", "固定掉落倍率", 5, new ConfigDescription("当'启用动态倍率'为false时使用的固定掉落倍率\n• 1 = 正常掉落(原版行为)\n• 5 = 掉落5个相同物品(推荐)\n• 单人固定倍率推荐1,多人推荐动态倍率\n• 注意:过高的值可能影响游戏性能", (AcceptableValueBase)(object)new AcceptableValueRange<int>(1, 50), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 20,
					IsAdvanced = false
				}
			}));
			DropDistanceClamp = ((BaseUnityPlugin)this).Config.Bind<float>("掉落设置", "掉落距离限制", 6f, new ConfigDescription("控制物品掉落时的最小距离限制\n• 默认值为6,不推荐更改\n• 较低的值使物品掉落更集中\n• 较高的值使物品掉落更分散\n• 注意:过高的值可能导致物品飞出太远", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 15f), new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 25,
					IsAdvanced = false
				}
			}));
			AffectedChestTypes = ((BaseUnityPlugin)this).Config.Bind<string>("宝箱类型设置", "应用倍率的宝箱类型", "Chest1(Clone),Chest2(Clone),GoldChest,LunarChest(Clone),VoidChest(Clone),CategoryChestUtility(Clone),CategoryChest2Utility Variant(Clone),CategoryChestHealing(Clone),CategoryChest2Healing Variant(Clone),CategoryChestDamage(Clone),CategoryChest2Damage Variant(Clone)", new ConfigDescription("指定哪些宝箱类型应用掉落倍率\n• 用逗号分隔多个宝箱类型\n• 常见宝箱类型:\n  - Chest1(Clone): 普通宝箱\n  - Chest2(Clone): 大宝箱\n  - GoldChest: 传奇宝箱\n  - LunarChest(Clone): 月球舱\n  - VoidChest(Clone): 虚空摇篮\n  - EquipmentBarrel(Clone): 装备箱(默认关闭)\n  - Lockbox(Clone): 生锈带锁箱(默认关闭)\n  - CategoryChestUtility(Clone): 辅助箱\n  - CategoryChest2Utility Variant(Clone): 大辅助箱\n  - CategoryChestHealing(Clone): 治疗箱\n  - CategoryChest2Healing Variant(Clone): 大治疗箱\n  - CategoryChestDamage(Clone): 伤害箱\n  - CategoryChest2Damage Variant(Clone): 大伤害箱\n• 默认关闭倍率宝箱类型:\n  - EquipmentBarrel(Clone): 装备箱\n  - Lockbox(Clone): 生锈带锁箱\n• 如需启用请在默认值中添加\n• 留空表示所有宝箱都应用倍率\n• 注意:名字必须完全匹配,包括大小写和括号", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 80,
					IsAdvanced = false
				}
			}));
			EnableDebugLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("调试设置", "启用调试日志", true, new ConfigDescription("启用详细的调试日志输出", (AcceptableValueBase)null, new object[1]
			{
				new ConfigurationManagerAttributes
				{
					Order = 1000,
					IsAdvanced = true
				}
			}));
			UpdateAffectedChestTypes();
			ModEnabled.SettingChanged += delegate
			{
				LogInfo("插件总开关已变更:" + (ModEnabled.Value ? "启用" : "禁用"));
			};
			EnableDynamicMultiplier.SettingChanged += delegate
			{
				LogInfo("倍率模式已变更:" + (EnableDynamicMultiplier.Value ? "动态" : "固定"));
			};
			FixedMultiplier.SettingChanged += delegate
			{
				LogInfo($"固定倍率已变更:{FixedMultiplier.Value}x");
			};
			DropDistanceClamp.SettingChanged += delegate
			{
				LogInfo($"掉落距离限制已变更:{DropDistanceClamp.Value}");
			};
			AffectedChestTypes.SettingChanged += delegate
			{
				UpdateAffectedChestTypes();
			};
			EnableDebugLogs.SettingChanged += delegate
			{
				LogInfo("调试日志已" + (EnableDebugLogs.Value ? "启用" : "禁用"));
			};
		}

		private void InitializeArtifacts()
		{
			Log.LogInfo((object)"正在初始化神器系统...");
			IEnumerable<Type> enumerable = from t in Assembly.GetExecutingAssembly().GetTypes()
				where !t.IsAbstract && t.IsSubclassOf(typeof(ArtifactBase))
				select t;
			foreach (Type item in enumerable)
			{
				ArtifactBase artifactBase = (ArtifactBase)Activator.CreateInstance(item);
				if (((BaseUnityPlugin)this).Config.Bind<bool>("神器设置", artifactBase.ArtifactName + "_启用", true, "是否在神器选择界面显示该神器").Value)
				{
					artifactBase.Init(((BaseUnityPlugin)this).Config);
					artifacts.Add(artifactBase);
					Log.LogInfo((object)("已加载神器: " + artifactBase.ArtifactName));
				}
			}
			Log.LogInfo((object)$"神器系统初始化完成,共加载 {artifacts.Count} 个神器");
		}

		private void InitializeHarmonyPatches()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			Log.LogInfo((object)"正在应用 Harmony 补丁...");
			harmony = new Harmony("com.Muskmelovon.ShareChest");
			harmony.PatchAll(Assembly.GetExecutingAssembly());
			IEnumerable<MethodBase> patchedMethods = harmony.GetPatchedMethods();
			Log.LogInfo((object)$"成功应用 {patchedMethods.Count()} 个 Harmony 补丁");
		}

		private static void ShowDebugInfo()
		{
			int currentPlayerCount = GetCurrentPlayerCount();
			int num = CalculateMultiplier(currentPlayerCount);
			LogInfo("=== 共享宝箱调试信息 ===");
			LogInfo($"插件总开关: {ModEnabled.Value}");
			LogInfo($"神器启用状态: {IsArtifactEnabled}");
			LogInfo($"当前玩家数量: {currentPlayerCount}");
			LogInfo($"动态倍率: {EnableDynamicMultiplier.Value}");
			LogInfo($"固定倍率: {FixedMultiplier.Value}");
			LogInfo($"掉落距离限制: {DropDistanceClamp.Value}");
			LogInfo($"计算后的倍率: {num}x");
			LogInfo("PlayerCountManager 实例: " + (((Object)(object)PlayerCountManager.Instance != (Object)null) ? "存在" : "不存在"));
			if ((Object)(object)PlayerCountManager.Instance != (Object)null)
			{
				LogInfo($"PlayerCountManager 计数: {PlayerCountManager.Instance.CurrentPlayerCount}");
			}
			LogInfo($"宝箱类型白名单: {affectedChestTypeSet.Count}种");
			if (affectedChestTypeSet.Count > 0)
			{
				LogInfo("白名单内容: " + string.Join(", ", affectedChestTypeSet));
			}
			LogInfo("========================");
		}

		private static void ForceRecalculate()
		{
			if ((Object)(object)PlayerCountManager.Instance != (Object)null)
			{
				PlayerCountManager.Instance.RecalculatePlayerCount();
				LogInfo($"已强制重新计算玩家数量: {PlayerCountManager.Instance.CurrentPlayerCount}人");
			}
			else
			{
				LogError("PlayerCountManager 实例不存在,无法重新计算");
			}
		}

		public static int CalculateMultiplier(int currentPlayerCount)
		{
			if (!EnableDynamicMultiplier.Value)
			{
				return Math.Max(1, FixedMultiplier.Value);
			}
			return Math.Max(1, currentPlayerCount);
		}

		[MethodImpl(MethodImplOptions.AggressiveInlining)]
		public static int GetCurrentPlayerCount()
		{
			if ((Object)(object)PlayerCountManager.Instance != (Object)null)
			{
				return PlayerCountManager.Instance.CurrentPlayerCount;
			}
			try
			{
				if (NetworkUser.readOnlyInstancesList != null)
				{
					return NetworkUser.readOnlyInstancesList.Count;
				}
				if (NetworkServer.active)
				{
					int num = 0;
					foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
					{
						if ((Object)(object)instance != (Object)null && ((Behaviour)instance).isActiveAndEnabled)
						{
							num++;
						}
					}
					return Math.Max(1, num);
				}
				return 1;
			}
			catch
			{
				return 1;
			}
		}

		public static string GetMultiplierInfo(int playerCount)
		{
			if (!EnableDynamicMultiplier.Value)
			{
				return $"固定倍率: {FixedMultiplier.Value}x";
			}
			return $"动态倍率: {CalculateMultiplier(playerCount)}x (玩家数: {playerCount}人)";
		}

		private static void UpdateAffectedChestTypes()
		{
			affectedChestTypeSet.Clear();
			string value = AffectedChestTypes.Value;
			if (string.IsNullOrWhiteSpace(value))
			{
				return;
			}
			IEnumerable<string> enumerable = from s in value.Split(new string[1] { ChestListSeparator }, StringSplitOptions.RemoveEmptyEntries)
				select s.Trim() into s
				where !string.IsNullOrEmpty(s)
				select s;
			foreach (string item in enumerable)
			{
				affectedChestTypeSet.Add(item);
			}
			LogDebug($"已加载 {affectedChestTypeSet.Count} 种宝箱类型");
		}

		public static bool ShouldApplyToChest(string chestName)
		{
			if (affectedChestTypeSet.Count == 0)
			{
				return true;
			}
			return affectedChestTypeSet.Contains(chestName);
		}

		public static bool ShouldApplyMultiplier(ChestBehavior chest)
		{
			if (!ModEnabled.Value || !IsArtifactEnabled)
			{
				LogDebug($"多倍掉落未生效:插件总开关={ModEnabled.Value}, 神器启用={IsArtifactEnabled}");
				return false;
			}
			if ((Object)(object)chest == (Object)null || (Object)(object)((Component)chest).gameObject == (Object)null)
			{
				return false;
			}
			string name = ((Object)((Component)chest).gameObject).name;
			if (!ShouldApplyToChest(name))
			{
				LogDebug("宝箱 " + name + " 不在允许列表中,不应用倍率");
				return false;
			}
			Traverse val = Traverse.Create((object)chest);
			if (val.Field("isChestOpened").GetValue<bool>())
			{
				return false;
			}
			if (chest.isCommandChest)
			{
				LogDebug("命令宝箱不应用倍率");
				return false;
			}
			int currentPlayerCount = GetCurrentPlayerCount();
			int num = CalculateMultiplier(currentPlayerCount);
			LogDebug($"将对宝箱 {name} 应用 {num}x 倍率");
			return true;
		}

		public static void LogDebug(string message)
		{
			if (EnableDebugLogs.Value && Log != null)
			{
				Log.LogInfo((object)("[调试] " + message));
			}
		}

		public static void LogWarning(string message)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogWarning((object)("[警告] " + message));
			}
		}

		public static void LogError(string message)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogError((object)("[错误] " + message));
			}
		}

		public static void LogInfo(string message)
		{
			ManualLogSource log = Log;
			if (log != null)
			{
				log.LogInfo((object)("[信息] " + message));
			}
		}
	}
	internal class ConfigurationManagerAttributes
	{
		public int? Order = null;

		public bool? IsAdvanced = null;

		public string Category = null;

		public Action<ConfigEntryBase> CustomDrawer = null;
	}
	public class PlayerCountManager : MonoBehaviour
	{
		private float lastRecalculateTime = 0f;

		private const float RECALCULATE_INTERVAL = 2f;

		public static PlayerCountManager Instance { get; private set; }

		public int CurrentPlayerCount { get; private set; }

		public bool IsMultiplayer => CurrentPlayerCount > 1;

		private void Awake()
		{
			if ((Object)(object)Instance == (Object)null)
			{
				Instance = this;
				Object.DontDestroyOnLoad((Object)(object)((Component)this).gameObject);
				((MonoBehaviour)this).StartCoroutine(DelayedInitialize());
			}
			else
			{
				Object.Destroy((Object)(object)((Component)this).gameObject);
			}
		}

		private IEnumerator DelayedInitialize()
		{
			yield return null;
			try
			{
				NetworkUser.onPostNetworkUserStart += new NetworkUserGenericDelegate(OnPlayerJoined);
				NetworkUser.onNetworkUserLost += new NetworkUserGenericDelegate(OnPlayerLost);
				SceneManager.activeSceneChanged += OnSceneChanged;
				RecalculatePlayerCount();
				ShareChestPlugin.LogInfo($"[PlayerCountManager] 初始化完成,当前玩家数: {CurrentPlayerCount}");
				((MonoBehaviour)this).InvokeRepeating("PeriodicCheck", 5f, 5f);
			}
			catch (Exception ex)
			{
				ShareChestPlugin.LogError("[PlayerCountManager] 初始化失败: " + ex.Message);
			}
		}

		private void OnDestroy()
		{
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Expected O, but got Unknown
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			try
			{
				NetworkUser.onPostNetworkUserStart -= new NetworkUserGenericDelegate(OnPlayerJoined);
				NetworkUser.onNetworkUserLost -= new NetworkUserGenericDelegate(OnPlayerLost);
				SceneManager.activeSceneChanged -= OnSceneChanged;
			}
			catch
			{
			}
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
			((MonoBehaviour)this).CancelInvoke("PeriodicCheck");
		}

		private void OnPlayerJoined(NetworkUser joinedUser)
		{
			((MonoBehaviour)this).StartCoroutine(UpdatePlayerCountDelayed(1f));
			ShareChestPlugin.LogInfo("[PlayerCountManager] 玩家加入: " + joinedUser.userName);
		}

		private void OnPlayerLost(NetworkUser lostUser)
		{
			((MonoBehaviour)this).StartCoroutine(UpdatePlayerCountDelayed(1f));
			ShareChestPlugin.LogInfo("[PlayerCountManager] 玩家离开: " + lostUser?.userName);
		}

		private void OnSceneChanged(Scene oldScene, Scene newScene)
		{
			RecalculatePlayerCount();
			ShareChestPlugin.LogInfo($"[PlayerCountManager] 场景变化: {((Scene)(ref oldScene)).name} -> {((Scene)(ref newScene)).name}, 玩家数: {CurrentPlayerCount}");
		}

		private IEnumerator UpdatePlayerCountDelayed(float delay)
		{
			yield return (object)new WaitForSeconds(delay);
			RecalculatePlayerCount();
		}

		private void PeriodicCheck()
		{
			if (Time.time - lastRecalculateTime > 2f)
			{
				RecalculatePlayerCount();
			}
		}

		public void RecalculatePlayerCount()
		{
			int currentPlayerCount = CurrentPlayerCount;
			try
			{
				if (NetworkUser.readOnlyInstancesList != null && NetworkUser.readOnlyInstancesList.Count >= 0)
				{
					CurrentPlayerCount = NetworkUser.readOnlyInstancesList.Count;
					ShareChestPlugin.LogInfo($"[PlayerCountManager] 通过NetworkUser获取: {CurrentPlayerCount}人");
				}
				else if (PlayerCharacterMasterController.instances != null && NetworkServer.active)
				{
					CurrentPlayerCount = 0;
					foreach (PlayerCharacterMasterController instance in PlayerCharacterMasterController.instances)
					{
						if ((Object)(object)instance != (Object)null && ((Behaviour)instance).isActiveAndEnabled)
						{
							CurrentPlayerCount++;
						}
					}
					ShareChestPlugin.LogDebug($"[PlayerCountManager] 通过PlayerController获取: {CurrentPlayerCount}人");
				}
				else
				{
					CurrentPlayerCount = 1;
					ShareChestPlugin.LogDebug("[PlayerCountManager] 单人游戏模式: 1人");
				}
				if (CurrentPlayerCount != currentPlayerCount)
				{
					ShareChestPlugin.LogInfo($"[PlayerCountManager] 玩家数量变化: {currentPlayerCount} -> {CurrentPlayerCount}");
					if (ShareChestPlugin.ModEnabled != null && ShareChestPlugin.ModEnabled.Value && ShareChestPlugin.EnableDynamicMultiplier != null && ShareChestPlugin.EnableDynamicMultiplier.Value)
					{
						ShareChestPlugin.LogInfo($"动态倍率更新: 当前{CurrentPlayerCount}人, 倍率{ShareChestPlugin.CalculateMultiplier(CurrentPlayerCount)}x");
					}
				}
				lastRecalculateTime = Time.time;
			}
			catch (Exception ex)
			{
				ShareChestPlugin.LogError("重新计算玩家数量失败: " + ex.Message);
				CurrentPlayerCount = Math.Max(1, currentPlayerCount);
			}
		}

		public void Reset()
		{
			CurrentPlayerCount = 0;
			RecalculatePlayerCount();
		}
	}
}
namespace ShareChest.Patches
{
	[HarmonyPatch]
	public static class ChestBehaviorPatches
	{
		private static readonly HashSet<uint> processedChests = new HashSet<uint>();

		private static int totalChestsGenerated = 0;

		private static int chestsOpenedCount = 0;

		private static float runStartTime = 0f;

		private static uint GetChestUniqueId(ChestBehavior chest)
		{
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)chest == (Object)null)
			{
				return 0u;
			}
			int instanceID = ((Object)chest).GetInstanceID();
			Vector3 position = ((Component)chest).transform.position;
			int hashCode = ((object)(Vector3)(ref position)).GetHashCode();
			return (uint)(instanceID ^ hashCode) & 0x7FFFFFFFu;
		}

		[HarmonyPatch(typeof(ChestBehavior), "BaseItemDrop")]
		[HarmonyPrefix]
		private static bool BaseItemDropPrefix(ChestBehavior __instance)
		{
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0192: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				uint chestUniqueId = GetChestUniqueId(__instance);
				if (!NetworkServer.active)
				{
					ShareChestPlugin.LogDebug($"[{chestUniqueId}] 非服务器端,跳过处理");
					return true;
				}
				if (processedChests.Contains(chestUniqueId))
				{
					ShareChestPlugin.LogDebug($"[{chestUniqueId}] 宝箱已处理过,防止重复");
					return false;
				}
				if (!ShareChestPlugin.ShouldApplyMultiplier(__instance))
				{
					return true;
				}
				if ((Object)(object)__instance == (Object)null || (Object)(object)((Component)__instance).gameObject == (Object)null)
				{
					return true;
				}
				Traverse val = Traverse.Create((object)__instance);
				if (val.Field("isChestOpened").GetValue<bool>())
				{
					return true;
				}
				UniquePickup currentPickup = __instance.currentPickup;
				if (!((UniquePickup)(ref currentPickup)).isValid)
				{
					__instance.Roll();
					currentPickup = __instance.currentPickup;
					if (!((UniquePickup)(ref currentPickup)).isValid)
					{
						ShareChestPlugin.LogWarning($"[{chestUniqueId}] 无法生成有效掉落物");
						return true;
					}
				}
				processedChests.Add(chestUniqueId);
				chestsOpenedCount++;
				int currentPlayerCount = ShareChestPlugin.GetCurrentPlayerCount();
				int num = ShareChestPlugin.CalculateMultiplier(currentPlayerCount);
				int dropCount = __instance.dropCount;
				int num2 = dropCount * num;
				if (num2 <= 0)
				{
					ShareChestPlugin.LogWarning($"[{chestUniqueId}] 最终掉落数量异常: {num2}");
					return false;
				}
				UniquePickup currentPickup2 = __instance.currentPickup;
				Transform dropTransform = __instance.dropTransform ?? ((Component)__instance).transform;
				ExecuteMultiDrop(__instance, dropTransform, currentPickup2, num2);
				val.Property("currentPickup", (object[])null).SetValue((object)UniquePickup.none);
				val.Field("isChestOpened").SetValue((object)true);
				__instance.NetworkisChestOpened = true;
				Util.PlaySound("Play_ui_item_world_pickup", ((Component)__instance).gameObject);
				ShareChestPlugin.LogDebug($"[{chestUniqueId}] 成功生成 {num2} 个掉落物 (原始:{dropCount} × {num})");
				return false;
			}
			catch (Exception ex)
			{
				ShareChestPlugin.LogError("BaseItemDropPrefix 错误: " + ex.Message + "\n" + ex.StackTrace);
				return true;
			}
		}

		[HarmonyPatch(typeof(ChestBehavior), "Open")]
		[HarmonyPostfix]
		private static void OpenPostfix(ChestBehavior __instance)
		{
			if (ShareChestPlugin.ModEnabled.Value)
			{
				uint chestUniqueId = GetChestUniqueId(__instance);
				bool flag = processedChests.Contains(chestUniqueId);
				Traverse val = Traverse.Create((object)__instance);
				bool value = val.Field("isChestOpened").GetValue<bool>();
				ShareChestPlugin.LogInfo($"[{chestUniqueId}] Open() 被调用 - 已处理:{flag}, 状态:{value}");
			}
		}

		[HarmonyPatch(typeof(ChestBehavior), "Start")]
		[HarmonyPostfix]
		private static void StartPostfix(ChestBehavior __instance)
		{
			if (ShareChestPlugin.ModEnabled.Value)
			{
				if (runStartTime == 0f)
				{
					runStartTime = Time.time;
					ShareChestPlugin.LogDebug($"新对局开始于: {runStartTime}");
				}
				totalChestsGenerated++;
				uint chestUniqueId = GetChestUniqueId(__instance);
				ShareChestPlugin.LogInfo($"[{chestUniqueId}] 宝箱生成 - 总计: {totalChestsGenerated}个, 类型: {((Object)((Component)__instance).gameObject).name}");
				LogChestType(__instance);
			}
		}

		[HarmonyPatch(typeof(ChestBehavior), "OnDisable")]
		[HarmonyPostfix]
		private static void OnDisablePostfix(ChestBehavior __instance)
		{
			uint chestUniqueId = GetChestUniqueId(__instance);
			processedChests.Remove(chestUniqueId);
		}

		[HarmonyPatch(typeof(Run), "Start")]
		[HarmonyPostfix]
		private static void RunStartPostfix()
		{
			processedChests.Clear();
			totalChestsGenerated = 0;
			chestsOpenedCount = 0;
			runStartTime = Time.time;
			if ((Object)(object)PlayerCountManager.Instance != (Object)null)
			{
				PlayerCountManager.Instance.Reset();
			}
			ShareChestPlugin.LogInfo("===== 新对局开始 =====");
		}

		[HarmonyPatch(typeof(Run), "OnDestroy")]
		[HarmonyPrefix]
		private static void RunOnDestroyPrefix()
		{
			if (totalChestsGenerated > 0)
			{
				float num = Time.time - runStartTime;
				int currentPlayerCount = ShareChestPlugin.GetCurrentPlayerCount();
				ShareChestPlugin.LogInfo("===== 对局结束统计 =====");
				ShareChestPlugin.LogInfo($"对局时长: {num:F1}秒");
				ShareChestPlugin.LogInfo($"玩家数量: {currentPlayerCount}人");
				ShareChestPlugin.LogInfo($"生成宝箱总数: {totalChestsGenerated}个");
				ShareChestPlugin.LogInfo($"已打开宝箱数: {chestsOpenedCount}个");
				ShareChestPlugin.LogInfo($"宝箱打开率: {(float)chestsOpenedCount * 100f / (float)totalChestsGenerated:F1}%");
				ShareChestPlugin.LogInfo("==========================");
			}
		}

		private static void LogChestType(ChestBehavior chest)
		{
			string text = ((Object)((Component)chest).gameObject).name.ToLower();
			string text2 = "未知";
			if (text.Contains("chest1"))
			{
				text2 = "普通宝箱";
			}
			else if (text.Contains("chest2"))
			{
				text2 = "大型宝箱";
			}
			else if (text.Contains("equipment"))
			{
				text2 = "装备桶";
			}
			else if (text.Contains("lunar"))
			{
				text2 = "月球宝箱";
			}
			else if (text.Contains("void"))
			{
				text2 = "虚空宝箱";
			}
			else if (text.Contains("category"))
			{
				text2 = "分类宝箱";
			}
			ShareChestPlugin.LogDebug("宝箱类型识别: " + text + " → " + text2);
		}

		private static void ExecuteMultiDrop(ChestBehavior chest, Transform dropTransform, UniquePickup basePickup, int dropCount)
		{
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_004f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_0061: Unknown result type (might be due to invalid IL or missing references)
			//IL_0069: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b4: 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)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				float num = 360f / (float)dropCount;
				float value = ShareChestPlugin.DropDistanceClamp.Value;
				float num2 = Mathf.Clamp(chest.dropForwardVelocityStrength, value, 7f);
				Vector3 val = Vector3.up * chest.dropUpVelocityStrength + Vector3.forward * num2;
				Quaternion val2 = Quaternion.AngleAxis(num, Vector3.up);
				Vector3 val3 = val;
				for (int i = 0; i < dropCount; i++)
				{
					CreatePickupInfo val4 = default(CreatePickupInfo);
					((CreatePickupInfo)(ref val4)).pickup = basePickup;
					val4.position = dropTransform.position + Vector3.up * 1.5f;
					val4.chest = chest;
					val4.artifactFlag = (PickupArtifactFlag)(chest.isCommandChest ? 1 : 0);
					CreatePickupInfo val5 = val4;
					CreatePickupDropletSafe(val5, val5.position, val3);
					val3 = val2 * val3;
				}
			}
			catch (Exception ex)
			{
				ShareChestPlugin.LogError("ExecuteMultiDrop 错误: " + ex.Message);
				throw;
			}
		}

		private static void CreatePickupDropletSafe(CreatePickupInfo pickupInfo, Vector3 position, Vector3 velocity)
		{
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0086: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				MethodInfo method = typeof(PickupDropletController).GetMethod("CreatePickupDroplet", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[3]
				{
					typeof(CreatePickupInfo),
					typeof(Vector3),
					typeof(Vector3)
				}, null);
				if (method != null)
				{
					method.Invoke(null, new object[3] { pickupInfo, position, velocity });
				}
				else
				{
					PickupDropletController.CreatePickupDroplet(((CreatePickupInfo)(ref pickupInfo)).pickup.pickupIndex, position, velocity);
				}
			}
			catch (Exception ex)
			{
				ShareChestPlugin.LogError("创建掉落物失败: " + ex.Message);
				try
				{
					PickupDropletController.CreatePickupDroplet(((CreatePickupInfo)(ref pickupInfo)).pickup.pickupIndex, position, velocity);
				}
				catch
				{
					ShareChestPlugin.LogError("备用创建方案也失败");
				}
			}
		}
	}
}