Decompiled source of Equilibrium v2.1.1

Equilibrium.dll

Decompiled 4 days ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
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 System.Security;
using System.Security.Permissions;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using EntityStates.ScavBackpack;
using Equilibrium.Components;
using Equilibrium.Config;
using Equilibrium.Core;
using Equilibrium.Hooks;
using Equilibrium.Networking;
using Equilibrium.ObjectHandlers;
using Equilibrium.Utils;
using HG.Reflection;
using HarmonyLib;
using IL.EntityStates.ScavBackpack;
using IL.RoR2;
using IL.RoR2.Hologram;
using Mono.Cecil;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using On.RoR2;
using On.RoR2.Artifacts;
using On.RoR2.Hologram;
using R2API;
using R2API.Networking;
using R2API.Networking.Interfaces;
using R2API.Utils;
using RoR2;
using RoR2.Artifacts;
using RoR2.Hologram;
using UnityEngine;
using UnityEngine.Events;
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: OptIn]
[assembly: AssemblyTitle("Equilibrium")]
[assembly: AssemblyDescription("Artifact of Equilibrium - Risk of Rain 2 Mod")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Muskmelovon")]
[assembly: AssemblyProduct("Equilibrium")]
[assembly: AssemblyCopyright("Copyright © Muskmelovon 2024")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("8da79297-920b-437a-aad8-e8c59d499508")]
[assembly: AssemblyFileVersion("2.1.1")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.1.1.0")]
[module: UnverifiableCode]
namespace Equilibrium
{
	public static class AssetBundleLoader
	{
		private static AssetBundle _bundle;

		private static bool _loaded;

		public static bool IsLoaded => _loaded;

		public static void LoadFromEmbeddedResource()
		{
			if (_loaded)
			{
				return;
			}
			Assembly executingAssembly = Assembly.GetExecutingAssembly();
			string text = "Equilibrium.Resources.equilibrium";
			using Stream stream = executingAssembly.GetManifestResourceStream(text);
			if (stream == null)
			{
				Debug.LogError((object)("[均衡神器] 嵌入资源未找到: " + text));
				return;
			}
			byte[] array = new byte[stream.Length];
			stream.Read(array, 0, array.Length);
			_bundle = AssetBundle.LoadFromMemory(array);
			if ((Object)(object)_bundle == (Object)null)
			{
				Debug.LogError((object)"[均衡神器] 无法从内存解析 AssetBundle!");
				return;
			}
			_loaded = true;
			Debug.Log((object)"[均衡神器] AssetBundle 已从嵌入资源加载。");
		}

		public static void LoadFromFile(string path)
		{
			if (!_loaded)
			{
				if (!File.Exists(path))
				{
					Debug.LogError((object)("[均衡神器] 文件未找到: " + path));
					return;
				}
				_bundle = AssetBundle.LoadFromFile(path);
				_loaded = (Object)(object)_bundle != (Object)null;
			}
		}

		public static Sprite GetSprite(params string[] assetNames)
		{
			//IL_008b: 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)
			if (!_loaded || (Object)(object)_bundle == (Object)null)
			{
				return null;
			}
			foreach (string text in assetNames)
			{
				Sprite val = _bundle.LoadAsset<Sprite>(text);
				if ((Object)(object)val != (Object)null)
				{
					return val;
				}
				Texture2D val2 = _bundle.LoadAsset<Texture2D>(text);
				if ((Object)(object)val2 != (Object)null)
				{
					return Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f));
				}
			}
			return null;
		}

		public static void Unload()
		{
			AssetBundle bundle = _bundle;
			if (bundle != null)
			{
				bundle.Unload(true);
			}
			_bundle = null;
			_loaded = false;
		}
	}
	[BepInPlugin("com.muskmelovon.equilibrium", "Equilibrium", "2.1.1")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	public class Equilibrium : BaseUnityPlugin
	{
		public HookManager HookManager;

		public ObjectHandlerManager ObjectHandlerManager;

		public static ArtifactDef EquilibriumArtifactDef;

		private const string ArtifactLangTokenName = "EQUILIBRIUM";

		private static bool _patched;

		public static bool IsCloningForInstance;

		private float nextResendTime = 0f;

		public global::Equilibrium.Config.Config ModConfig { get; private set; }

		public bool InteractionLoggingEnabled
		{
			get
			{
				global::Equilibrium.Config.Config modConfig = ModConfig;
				if (modConfig == null)
				{
					return false;
				}
				return modConfig.LogInstanceInteractions?.Value ?? false;
			}
		}

		public static Equilibrium Instance { get; private set; }

		internal ManualLogSource Logger => ((BaseUnityPlugin)this).Logger;

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

		private string ArtifactDescription => "“是故风雨时节,五谷丰登,社稷安宁。”\nTherefore, during the season of wind and rain, the crops yield abundantly, and the country enjoys peace and prosperity.";

		public void Awake()
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
			//IL_013f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Expected O, but got Unknown
			//IL_010a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0110: Expected O, but got Unknown
			Instance = this;
			ModConfig = new global::Equilibrium.Config.Config(this, Logger);
			HookManager = new HookManager(this);
			ObjectHandlerManager = new ObjectHandlerManager(this);
			NetworkingAPI.RegisterMessageType<SyncInstances>();
			LoadAssetBundle();
			CreateLang();
			EquilibriumArtifactDef = ScriptableObject.CreateInstance<ArtifactDef>();
			EquilibriumArtifactDef.nameToken = "ARTIFACT_EQUILIBRIUM_NAME";
			EquilibriumArtifactDef.descriptionToken = "ARTIFACT_EQUILIBRIUM_DESCRIPTION";
			EquilibriumArtifactDef.smallIconSelectedSprite = AssetBundleLoader.GetSprite("equilibrium_selected") ?? CreatePlaceholderSprite(Color.green);
			EquilibriumArtifactDef.smallIconDeselectedSprite = AssetBundleLoader.GetSprite("equilibrium_deselected") ?? CreatePlaceholderSprite(Color.gray);
			ContentAddition.AddArtifactDef(EquilibriumArtifactDef);
			try
			{
				EquilibriumManager.Init();
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"[均衡神器] 调用 EquilibriumManager.Init() 失败:{arg}");
			}
			if (!_patched)
			{
				Harmony val = new Harmony("com.muskmelovon.equilibrium");
				val.PatchAll();
				_patched = true;
				Logger.LogInfo((object)"[均衡神器] Harmony 补丁已应用");
			}
			LogInfo("[均衡神器] 插件加载完成 | F5=调试信息 | F6=强制刷新");
			GameObject val2 = new GameObject("PlayerManager");
			val2.AddComponent<PlayerManager>();
			Object.DontDestroyOnLoad((Object)(object)val2);
			Logger.LogInfo((object)"[均衡神器] 插件 Awake 完成");
		}

		public void Start()
		{
			Logger.LogInfo((object)"[均衡神器] Start 完成");
		}

		public void OnEnable()
		{
			Instance = this;
			PlayerCharacterMasterController.onPlayerAdded += OnPlayerAdded;
			HookManager.RegisterHooks();
			Logger.LogInfo((object)"[均衡神器] 已启用并注册钩子");
		}

		public void OnDisable()
		{
			if ((Object)(object)Instance == (Object)(object)this)
			{
				Instance = null;
			}
			HookManager.UnregisterHooks();
			PlayerCharacterMasterController.onPlayerAdded -= OnPlayerAdded;
			InteractionDiagnostics.Clear();
			SyncInstances.ClearPending();
			Logger.LogInfo((object)"[均衡神器] 已禁用并注销钩子");
		}

		public void Update()
		{
			if (Input.GetKeyDown((KeyCode)286))
			{
				ShowPlayerListInfo();
			}
			if (Input.GetKeyDown((KeyCode)287))
			{
				ForceRefresh();
			}
			if (NetworkServer.active && Time.time >= nextResendTime)
			{
				nextResendTime = Time.time + 10f;
				ResendAllInstances();
			}
			if (!NetworkServer.active)
			{
				SyncInstances.CheckTimeouts();
			}
		}

		private void ResendAllInstances()
		{
			foreach (InstanceHandler instance in InstanceHandler.Instances)
			{
				if (Object.op_Implicit((Object)(object)instance) && instance.SharedInfo != null)
				{
					instance.SharedInfo.SyncToAll();
				}
			}
		}

		private static bool IsHostUser(NetworkUser user)
		{
			if ((Object)(object)user == (Object)null)
			{
				return false;
			}
			if (NetworkServer.active && NetworkClient.active)
			{
				return ((NetworkBehaviour)user).isLocalPlayer;
			}
			if (!NetworkServer.active && NetworkClient.active)
			{
				return ((NetworkBehaviour)user).playerControllerId == -1;
			}
			return ((NetworkBehaviour)user).isLocalPlayer;
		}

		private static void ShowPlayerListInfo()
		{
			//IL_0011: Unknown result type (might be due to invalid IL or missing references)
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			LogInfo("========== [均衡神器] 玩家列表信息 ==========");
			Scene activeScene = SceneManager.GetActiveScene();
			LogInfo("当前场景: " + ((Scene)(ref activeScene)).name);
			int num = NetworkUser.readOnlyInstancesList?.Count ?? 0;
			LogInfo($"NetworkUser 玩家数量: {num}人");
			if (NetworkUser.readOnlyInstancesList == null || num == 0)
			{
				LogInfo("玩家列表为空");
				LogInfo("=============================================");
				return;
			}
			foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList)
			{
				if (Object.op_Implicit((Object)(object)readOnlyInstances))
				{
					string text = (IsHostUser(readOnlyInstances) ? "[Host]" : "[Client]");
					string text2 = (((NetworkBehaviour)readOnlyInstances).isLocalPlayer ? " (You)" : "");
					LogInfo(text + " " + readOnlyInstances.userName + text2);
				}
			}
			LogInfo("=============================================");
		}

		private static void ForceRefresh()
		{
			LogInfo(">>> 正在强制刷新玩家数据...");
			if ((Object)(object)PlayerManager.Instance != (Object)null)
			{
				PlayerManager.Instance.RecalculatePlayerCount();
				LogInfo($">>> 刷新完成,当前玩家数: {PlayerManager.Instance.CurrentPlayerCount}人");
			}
			else
			{
				LogError(">>> 刷新失败:PlayerManager 未初始化");
			}
		}

		private void OnPlayerAdded(PlayerCharacterMasterController player)
		{
			if (!NetworkServer.active)
			{
				return;
			}
			object obj;
			if (player == null)
			{
				obj = null;
			}
			else
			{
				NetworkUser networkUser = player.networkUser;
				obj = ((networkUser != null) ? ((NetworkBehaviour)networkUser).connectionToClient : null);
			}
			if (obj == null)
			{
				return;
			}
			HashSet<InstanceHandler> hashSet = new HashSet<InstanceHandler>();
			foreach (InstanceHandler instance in InstanceHandler.Instances)
			{
				InstanceHandler instanceHandler = instance.LinkedHandlers?[0] ?? instance;
				if ((Object)(object)instanceHandler != (Object)null && !hashSet.Contains(instanceHandler))
				{
					hashSet.Add(instanceHandler);
					instanceHandler.SyncToPlayer(player);
				}
			}
			Logger.LogInfo((object)("[均衡神器] 向新加入玩家 " + player.networkUser?.userName + " 下发实例快照"));
		}

		public void HandleInstancing(GameObject obj, InstanceInfoTracker.InstanceOverrideInfo? overrideInfo = null, bool isObject = true)
		{
			//IL_0169: Unknown result type (might be due to invalid IL or missing references)
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)obj.GetComponent<TeleporterInteraction>() != (Object)null || (Object)(object)obj.GetComponent<PickupDropletController>() != (Object)null)
			{
				return;
			}
			InstanceInfoTracker component = obj.GetComponent<InstanceInfoTracker>();
			InstanceInfoTracker.InstanceOverrideInfo? instanceOverrideInfo = component?.Info;
			string text = overrideInfo?.ObjectType ?? instanceOverrideInfo?.ObjectType;
			PlayerCharacterMasterController val = overrideInfo?.Owner ?? instanceOverrideInfo?.Owner;
			if ((Object)(object)component == (Object)null && text == null)
			{
				return;
			}
			InstanceMode mode = ModConfig.GetMode(text ?? instanceOverrideInfo?.ObjectType);
			if (mode == InstanceMode.None)
			{
				return;
			}
			bool flag = false;
			bool flag2 = false;
			if (instanceOverrideInfo?.ObjectType == null)
			{
				InstanceMode instanceMode = mode;
				InstanceMode instanceMode2 = instanceMode;
				if ((uint)(instanceMode2 - 1) <= 1u)
				{
					flag = true;
					flag2 = false;
				}
			}
			bool flag3 = false;
			GenericPickupController component2 = obj.GetComponent<GenericPickupController>();
			if ((Object)(object)component2 != (Object)null)
			{
				PickupDef pickupDef = PickupCatalog.GetPickupDef(component2.pickupIndex);
				if (((pickupDef == null) ? (-1) : ((int)pickupDef.itemIndex)) != -1)
				{
					goto IL_0190;
				}
			}
			if ((Object)(object)obj.GetComponent<PickupPickerController>() != (Object)null)
			{
				goto IL_0190;
			}
			goto IL_01c5;
			IL_0190:
			if (!isObject)
			{
				flag3 = true;
				switch (mode)
				{
				case InstanceMode.InstanceObject:
					flag = false;
					break;
				case InstanceMode.InstanceBoth:
					flag = true;
					flag2 = true;
					break;
				}
			}
			goto IL_01c5;
			IL_01c5:
			if (!flag3 && flag)
			{
				flag = ObjectHandlerManager.CanInstanceObject(text, obj);
			}
			overrideInfo?.AttachTo(obj);
			if (flag && (!flag2 || !((Object)(object)val == (Object)null) || !((Object)(object)instanceOverrideInfo?.Owner == (Object)null)))
			{
				HashSet<PlayerCharacterMasterController> source = ((!flag2) ? ModConfig.GetValidPlayers() : new HashSet<PlayerCharacterMasterController> { val });
				List<PlayerCharacterMasterController> list = source.ToList();
				PlayerCharacterMasterController val2 = ((IEnumerable<PlayerCharacterMasterController>)list).FirstOrDefault((Func<PlayerCharacterMasterController, bool>)((PlayerCharacterMasterController p) => Object.op_Implicit((Object)(object)p.networkUser) && ((NetworkBehaviour)p.networkUser).isServer));
				if ((Object)(object)val2 != (Object)null && list.IndexOf(val2) != 0)
				{
					list.Remove(val2);
					list.Insert(0, val2);
				}
				if (flag3)
				{
					InstanceHandler instanceHandler = obj.AddComponent<InstanceHandler>();
					instanceHandler.SharedInfo = new InstanceHandler.SharedInstanceInfo
					{
						ObjectInstanceMode = ObjectInstanceMode.InstancedObject
					};
					instanceHandler.SetPlayers(list);
				}
				else
				{
					ObjectHandlerManager.InstanceObject(text, obj, list.ToArray());
				}
				Logger.LogInfo((object)$"[均衡神器] 对象 {((Object)obj).name} 应用实例化策略: {mode} (objectType={text}, isObject={isObject})");
			}
		}

		public static bool CanUninstance(InstanceHandler handler, PlayerCharacterMasterController player)
		{
			if (!handler.Players.Contains(player))
			{
				return false;
			}
			return handler.AllPlayers.Count == 1 || Object.op_Implicit((Object)(object)((Component)handler).GetComponent<CreatePickupInfoTracker>());
		}

		public static void LogDebug(string message)
		{
			Equilibrium instance = Instance;
			if (instance != null)
			{
				instance.Logger.LogInfo((object)("[调试] " + message));
			}
		}

		public static void LogWarning(string message)
		{
			Equilibrium instance = Instance;
			if (instance != null)
			{
				instance.Logger.LogWarning((object)("[警告] " + message));
			}
		}

		public static void LogError(string message)
		{
			Equilibrium instance = Instance;
			if (instance != null)
			{
				instance.Logger.LogError((object)("[错误] " + message));
			}
		}

		public static void LogInfo(string message)
		{
			Equilibrium instance = Instance;
			if (instance != null)
			{
				instance.Logger.LogInfo((object)("[信息] " + message));
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCReloadConfig(ConCommandArgs args)
		{
			if ((Object)(object)Instance == (Object)null)
			{
				return;
			}
			try
			{
				((BaseUnityPlugin)Instance).Config.Reload();
				Instance.ModConfig.OnConfigReloaded();
				Instance.Logger.LogInfo((object)"[均衡神器] 配置已重新加载并应用。");
			}
			catch (Exception arg)
			{
				Instance.Logger.LogError((object)$"[均衡神器] 重新加载配置时出错:{arg}");
			}
		}

		private IEnumerable<NetworkUser> GetPlayersFromPartial(string name)
		{
			if (string.IsNullOrEmpty(name))
			{
				return NetworkUser.readOnlyInstancesList;
			}
			if (int.TryParse(name, out var result))
			{
				if (result >= 0 && result < NetworkUser.readOnlyInstancesList.Count)
				{
					return new List<NetworkUser> { NetworkUser.readOnlyInstancesList[result] };
				}
				return new List<NetworkUser>();
			}
			name = name.ToUpperInvariant();
			List<NetworkUser> list = new List<NetworkUser>();
			foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList)
			{
				if ((Object)(object)readOnlyInstances != (Object)null && readOnlyInstances.userName.ToUpperInvariant().Contains(name))
				{
					list.Add(readOnlyInstances);
				}
			}
			return list;
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCPlayerList(ConCommandArgs args)
		{
			try
			{
				string text = ((((ConCommandArgs)(ref args)).Count > 0) ? ((ConCommandArgs)(ref args))[0] : "");
				IEnumerable<NetworkUser> playersFromPartial = Instance.GetPlayersFromPartial(text);
				StringBuilder stringBuilder = new StringBuilder();
				stringBuilder.AppendLine($"========== 当前玩家列表 (共 {playersFromPartial.Count()} 人) ==========");
				int num = 0;
				foreach (NetworkUser item in playersFromPartial)
				{
					if (!((Object)(object)item == (Object)null))
					{
						string text2 = (IsHostUser(item) ? "[Host]" : "[Client]");
						string text3 = (((NetworkBehaviour)item).isLocalPlayer ? " (You)" : "");
						stringBuilder.AppendLine($"[{num}] {text2} {item.userName}{text3}");
						num++;
					}
				}
				if (stringBuilder.Length > 0)
				{
					LogInfo(stringBuilder.ToString());
				}
				else
				{
					LogInfo("找不到匹配 \"" + text + "\" 的玩家。");
				}
			}
			catch (Exception ex)
			{
				LogError("获取玩家列表时出错: " + ex.Message);
			}
		}

		[ConCommand(/*Could not decode attribute arguments.*/)]
		private static void CCDebugUser(ConCommandArgs args)
		{
			//IL_0084: 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_008d: Unknown result type (might be due to invalid IL or missing references)
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.AppendLine("========== NetworkUser 调试 ==========");
			stringBuilder.AppendLine($"本机: NetworkServer.active={NetworkServer.active}, NetworkClient.active={NetworkClient.active}");
			foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList)
			{
				if (!((Object)(object)readOnlyInstances == (Object)null))
				{
					stringBuilder.AppendLine("--- " + readOnlyInstances.userName + " ---");
					NetworkUserId id = readOnlyInstances.id;
					stringBuilder.AppendLine($"  id.steamId: {((NetworkUserId)(ref id)).steamId}");
					stringBuilder.AppendLine($"  isLocalPlayer: {((NetworkBehaviour)readOnlyInstances).isLocalPlayer}");
					stringBuilder.AppendLine($"  hasAuthority: {((NetworkBehaviour)readOnlyInstances).hasAuthority}");
					stringBuilder.AppendLine($"  isServer: {((NetworkBehaviour)readOnlyInstances).isServer}");
					stringBuilder.AppendLine($"  isClient: {((NetworkBehaviour)readOnlyInstances).isClient}");
					stringBuilder.AppendLine($"  authed: {readOnlyInstances.authed}");
				}
			}
			LogInfo(stringBuilder.ToString());
		}

		protected void CreateLang()
		{
			LanguageAPI.Add("ARTIFACT_EQUILIBRIUM_NAME", DisplayName);
			LanguageAPI.Add("ARTIFACT_EQUILIBRIUM_DESCRIPTION", ArtifactDescription);
			Logger.LogInfo((object)("[均衡神器] 语言条目已注册:" + DisplayName));
		}

		private void LoadAssetBundle()
		{
			AssetBundleLoader.LoadFromEmbeddedResource();
			if (!AssetBundleLoader.IsLoaded)
			{
				string path = Path.Combine(Paths.PluginPath, "Equilibrium", "equilibrium");
				AssetBundleLoader.LoadFromFile(path);
			}
		}

		private Sprite CreatePlaceholderSprite(Color color)
		{
			//IL_0005: Unknown result type (might be due to invalid IL or missing references)
			//IL_000b: Expected O, but got Unknown
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: 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_0063: Unknown result type (might be due to invalid IL or missing references)
			Texture2D val = new Texture2D(64, 64);
			Color[] array = (Color[])(object)new Color[4096];
			for (int i = 0; i < array.Length; i++)
			{
				array[i] = color;
			}
			val.SetPixels(array);
			val.Apply();
			return Sprite.Create(val, new Rect(0f, 0f, 64f, 64f), new Vector2(0.5f, 0.5f));
		}

		private void OnDestroy()
		{
			AssetBundleLoader.Unload();
		}
	}
	public static class EquilibriumManager
	{
		private static bool _initialized;

		private static bool artifactEnabled = false;

		private static bool configEnabled = true;

		public static bool IsEnabled { get; private set; }

		public static void Init()
		{
			//IL_002b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Expected O, but got Unknown
			if (!_initialized)
			{
				_initialized = true;
				artifactEnabled = false;
				configEnabled = true;
				UpdateIsEnabled();
				RunArtifactManager.onArtifactEnabledGlobal += new ArtifactStateChangeDelegate(OnArtifactEnabled);
				RunArtifactManager.onArtifactDisabledGlobal += new ArtifactStateChangeDelegate(OnArtifactDisabled);
			}
		}

		private static void OnArtifactEnabled(RunArtifactManager manager, ArtifactDef def)
		{
			if ((Object)(object)def == (Object)(object)Equilibrium.EquilibriumArtifactDef)
			{
				artifactEnabled = true;
				UpdateIsEnabled();
			}
		}

		private static void OnArtifactDisabled(RunArtifactManager manager, ArtifactDef def)
		{
			if ((Object)(object)def == (Object)(object)Equilibrium.EquilibriumArtifactDef)
			{
				artifactEnabled = false;
				UpdateIsEnabled();
			}
		}

		public static void SetConfigEnabled(bool enabled)
		{
			configEnabled = enabled;
			UpdateIsEnabled();
		}

		private static void UpdateIsEnabled()
		{
			IsEnabled = artifactEnabled && configEnabled;
		}

		public static void Cleanup()
		{
			//IL_0016: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Expected O, but got Unknown
			if (_initialized)
			{
				RunArtifactManager.onArtifactEnabledGlobal -= new ArtifactStateChangeDelegate(OnArtifactEnabled);
				RunArtifactManager.onArtifactDisabledGlobal -= new ArtifactStateChangeDelegate(OnArtifactDisabled);
				_initialized = false;
				artifactEnabled = false;
				configEnabled = true;
				UpdateIsEnabled();
			}
		}
	}
	public class PlayerManager : MonoBehaviour
	{
		private float lastRecalculateTime = 0f;

		private const float RECALCULATE_INTERVAL = 2f;

		public static PlayerManager 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();
				Equilibrium.LogInfo($"[PlayerManager] 初始化完成,当前玩家数: {CurrentPlayerCount}");
				((MonoBehaviour)this).InvokeRepeating("PeriodicCheck", 5f, 5f);
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				Equilibrium.LogError("[PlayerManager] 初始化失败: " + ex2.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));
			Equilibrium.LogInfo("[PlayerManager] 玩家加入: " + joinedUser.userName);
		}

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

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

		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;
				}
				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++;
						}
					}
				}
				else
				{
					CurrentPlayerCount = 1;
					Equilibrium.LogDebug("[PlayerManager] 单人游戏模式: 1人");
				}
				if (CurrentPlayerCount != currentPlayerCount)
				{
					Equilibrium.LogInfo($"[PlayerManager] 玩家数量变化: {currentPlayerCount} -> {CurrentPlayerCount}");
				}
				lastRecalculateTime = Time.time;
			}
			catch (Exception ex)
			{
				Equilibrium.LogError("重新计算玩家数量失败: " + ex.Message);
				CurrentPlayerCount = Math.Max(1, currentPlayerCount);
			}
		}

		public void Reset()
		{
			CurrentPlayerCount = 0;
			RecalculatePlayerCount();
		}
	}
}
namespace Equilibrium.Utils
{
	public enum InstanceMode
	{
		None,
		InstanceObject,
		InstanceBoth
	}
	public enum ObjectInstanceMode
	{
		None,
		CopyObject,
		InstancedObject
	}
	public static class ObjectType
	{
		public const string Chest1 = "Chest1";

		public const string Chest2 = "Chest2";

		public const string GoldChest = "GoldChest";

		public const string Chest1StealthedVariant = "Chest1StealthedVariant";

		public const string CategoryChestDamage = "CategoryChestDamage";

		public const string CategoryChestHealing = "CategoryChestHealing";

		public const string CategoryChestUtility = "CategoryChestUtility";

		public const string CategoryChest2Damage = "CategoryChest2Damage";

		public const string CategoryChest2Healing = "CategoryChest2Healing";

		public const string CategoryChest2Utility = "CategoryChest2Utility";

		public const string EquipmentBarrel = "EquipmentBarrel";

		public const string LunarChest = "LunarChest";

		public const string VoidChest = "VoidChest";

		public const string Lockbox = "Lockbox";

		public const string ScavBackpack = "ScavBackpack";

		public const string ShrineChance = "ShrineChance";

		public const string ShrineBlood = "ShrineBlood";

		public const string ShrineRestack = "ShrineRestack";

		public const string TripleShop = "TripleShop";

		public const string TripleShopLarge = "TripleShopLarge";

		public const string TripleShopEquipment = "TripleShopEquipment";

		public const string FreeChestMultiShop = "FreeChestMultiShop";

		public const string VoidTriple = "VoidTriple";

		public const string LockboxVoid = "LockboxVoid";

		public const string Sacrifice = "Sacrifice";

		public const string HuntersTricorn = "HuntersTricorn";

		public const string SonorousWhispers = "SonorousWhispers";

		public const string TeleporterBoss = "TeleporterBoss";

		public const string SuperRoboBallEncounter = "SuperRoboBallEncounter";

		public const string BossGroup = "BossGroup";
	}
	public static class Utils
	{
		public static bool IsObjectInteractibleForPlayer(GameObject gameObject, PlayerCharacterMasterController player)
		{
			if ((Object)(object)gameObject == (Object)null)
			{
				return true;
			}
			InstanceHandler component = gameObject.GetComponent<InstanceHandler>();
			if ((Object)(object)component != (Object)null)
			{
				if (component.AllPlayers.Contains(player))
				{
					return component.LinkedHandlers.Where((InstanceHandler h) => h.Players.Contains(player)).Any(delegate(InstanceHandler h)
					{
						//IL_0036: Unknown result type (might be due to invalid IL or missing references)
						//IL_003c: Invalid comparison between Unknown and I4
						IInteractable component2 = ((Component)h).GetComponent<IInteractable>();
						if (component2 != null)
						{
							CharacterBody body = player.body;
							if (Object.op_Implicit((Object)(object)body))
							{
								Interactor component3 = ((Component)body).GetComponent<Interactor>();
								if (Object.op_Implicit((Object)(object)component3))
								{
									return (int)component2.GetInteractability(component3) > 0;
								}
							}
						}
						return true;
					});
				}
				return false;
			}
			return true;
		}

		public static bool IsObjectInstanceInteractibleForPlayer(GameObject gameObject, PlayerCharacterMasterController player)
		{
			if ((Object)(object)gameObject == (Object)null)
			{
				return true;
			}
			InstanceHandler component = gameObject.GetComponent<InstanceHandler>();
			if ((Object)(object)component != (Object)null)
			{
				return component.Players.Contains(player);
			}
			return true;
		}

		public static bool IsObjectInteractibleForCameraRigController(GameObject gameObject, CameraRigController cameraRigController)
		{
			if ((Object)(object)cameraRigController == (Object)null)
			{
				return true;
			}
			CharacterBody targetBody = cameraRigController.targetBody;
			if ((Object)(object)targetBody == (Object)null)
			{
				return true;
			}
			CharacterMaster master = targetBody.master;
			if ((Object)(object)master == (Object)null)
			{
				return true;
			}
			PlayerCharacterMasterController playerCharacterMasterController = master.playerCharacterMasterController;
			if ((Object)(object)playerCharacterMasterController == (Object)null)
			{
				return true;
			}
			return IsObjectInteractibleForPlayer(gameObject, playerCharacterMasterController);
		}

		public static bool IncreasesItemCount(InstanceMode instanceMode)
		{
			if ((uint)(instanceMode - 1) <= 1u)
			{
				return true;
			}
			return false;
		}
	}
}
namespace Equilibrium.ObjectHandlers
{
	public class ChestHandler : AbstractObjectHandler
	{
		public override string[] HandledObjectTypes { get; } = new string[15]
		{
			"Chest1", "Chest2", "GoldChest", "Chest1StealthedVariant", "CategoryChestDamage", "CategoryChestHealing", "CategoryChestUtility", "CategoryChest2Damage", "CategoryChest2Healing", "CategoryChest2Utility",
			"EquipmentBarrel", "LunarChest", "VoidChest", "Lockbox", "ScavBackpack"
		};

		public override ObjectInstanceMode ObjectInstanceMode => ObjectInstanceMode.CopyObject;

		public override bool CanObjectBeOwned(string objectType)
		{
			return objectType == "Lockbox";
		}

		public override bool IsValidForObject(string objectType, GameObject gameObject)
		{
			return (Object)(object)gameObject.GetComponent<ChestBehavior>() != (Object)null;
		}

		public override void Init(ObjectHandlerManager manager)
		{
			base.Init(manager);
			base.Plugin.HookManager.RegisterHandler<ChestBehaviorHandler>();
			base.Plugin.HookManager.RegisterHandler<ScavBackpackOpeningHandler>();
		}

		public override InstanceHandler InstanceSingleObjectFrom(GameObject source, GameObject target, PlayerCharacterMasterController[] players)
		{
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0096: Expected O, but got Unknown
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_0062: Expected O, but got Unknown
			ChestBehavior component = source.GetComponent<ChestBehavior>();
			ChestBehavior component2 = target.GetComponent<ChestBehavior>();
			if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
			{
				if (base.Plugin.ModConfig.ARollDrop.Value)
				{
					component2.rng = new Xoroshiro128Plus(Run.instance.treasureRng.nextUlong);
					component2.Roll();
					component2.dropCount = component.dropCount;
					component2.dropTable = component.dropTable;
				}
				else
				{
					component2.rng = new Xoroshiro128Plus(component.rng);
					component2.dropCount = component.dropCount;
					component2.currentPickup = component.currentPickup;
				}
			}
			return base.InstanceSingleObjectFrom(source, target, players);
		}
	}
	public class MultiShopHandler : AbstractObjectHandler
	{
		public override string[] HandledObjectTypes { get; } = new string[4] { "TripleShop", "TripleShopLarge", "TripleShopEquipment", "FreeChestMultiShop" };

		public override ObjectInstanceMode ObjectInstanceMode => ObjectInstanceMode.CopyObject;

		public override bool CanObjectBeOwned(string objectType)
		{
			return objectType == "FreeChestMultiShop";
		}

		public override bool IsValidForObject(string objectType, GameObject gameObject)
		{
			return (Object)(object)gameObject.GetComponent<MultiShopController>() != (Object)null || (Object)(object)gameObject.GetComponent<ShopTerminalBehavior>() != (Object)null;
		}

		public override void Init(ObjectHandlerManager manager)
		{
			base.Init(manager);
			base.Plugin.HookManager.RegisterHandler<MultiShopControllerHandler>();
		}

		public override InstanceHandler InstanceSingleObjectFrom(GameObject source, GameObject target, PlayerCharacterMasterController[] players)
		{
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Expected O, but got Unknown
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Expected O, but got Unknown
			//IL_0198: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Expected O, but got Unknown
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			InstanceHandler instanceHandler = base.InstanceSingleObjectFrom(source, target, players);
			if ((Object)(object)source == (Object)(object)target)
			{
				InstanceInfoTracker component = source.GetComponent<InstanceInfoTracker>();
				MultiShopController component2 = source.GetComponent<MultiShopController>();
				ShopTerminalBehavior component3 = source.GetComponent<ShopTerminalBehavior>();
				if ((Object)(object)component2 != (Object)null)
				{
					GameObject[] terminalGameObjects = component2.terminalGameObjects;
					foreach (GameObject val in terminalGameObjects)
					{
						InstanceSingleObjectFrom(val, val, players);
						component?.Info.AttachTo(val);
					}
				}
				if ((Object)(object)component3 != (Object)null)
				{
					instanceHandler.SharedInfo = new InstanceHandler.SharedInstanceInfo
					{
						SourceObject = target,
						ObjectInstanceMode = ObjectInstanceMode
					};
				}
			}
			else
			{
				MultiShopController component4 = target.GetComponent<MultiShopController>();
				if ((Object)(object)component4 != (Object)null)
				{
					MultiShopController component5 = source.GetComponent<MultiShopController>();
					component4.rng = new Xoroshiro128Plus(0uL);
					component4.CreateTerminals();
					component4.Networkcost = component5.Networkcost;
					component4.rng = new Xoroshiro128Plus(component5.rng);
					for (int j = 0; j < component4.terminalGameObjects.Length; j++)
					{
						AwaitObjectFor(component4.terminalGameObjects[j], new AwaitedObjectInfo
						{
							SourceObject = component5.terminalGameObjects[j],
							Players = players
						});
					}
				}
				ShopTerminalBehavior component6 = target.GetComponent<ShopTerminalBehavior>();
				if ((Object)(object)component6 != (Object)null)
				{
					ShopTerminalBehavior component7 = source.GetComponent<ShopTerminalBehavior>();
					component6.hasStarted = true;
					component6.rng = new Xoroshiro128Plus(component7.rng);
					component6.Networkpickup = component7.Networkpickup;
					component6.Networkhidden = component7.Networkhidden;
					component6.UpdatePickupDisplayAndAnimations();
				}
				PurchaseInteraction component8 = target.GetComponent<PurchaseInteraction>();
				if ((Object)(object)component8 != (Object)null)
				{
					PurchaseInteraction component9 = source.GetComponent<PurchaseInteraction>();
					component8.rng = component9.rng;
					component8.Networkcost = component9.Networkcost;
				}
			}
			return instanceHandler;
		}
	}
	public class OptionChestHandler : AbstractObjectHandler
	{
		public override string[] HandledObjectTypes { get; } = new string[2] { "VoidTriple", "LockboxVoid" };

		public override ObjectInstanceMode ObjectInstanceMode => ObjectInstanceMode.CopyObject;

		public override bool CanObjectBeOwned(string objectType)
		{
			return objectType == "LockboxVoid";
		}

		public override bool IsValidForObject(string objectType, GameObject gameObject)
		{
			return (Object)(object)gameObject.GetComponent<OptionChestBehavior>() != (Object)null;
		}

		public override void Init(ObjectHandlerManager manager)
		{
			base.Init(manager);
			base.Plugin.HookManager.RegisterHandler<OptionChestBehaviorHandler>();
		}

		public override InstanceHandler InstanceSingleObjectFrom(GameObject source, GameObject target, PlayerCharacterMasterController[] players)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			OptionChestBehavior component = source.GetComponent<OptionChestBehavior>();
			OptionChestBehavior component2 = target.GetComponent<OptionChestBehavior>();
			if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
			{
				component2.rng = new Xoroshiro128Plus(component.rng);
				component2.generatedPickups = component.generatedPickups;
			}
			return base.InstanceSingleObjectFrom(source, target, players);
		}
	}
	public class ShrineChanceHandler : AbstractObjectHandler
	{
		public override ObjectInstanceMode ObjectInstanceMode => ObjectInstanceMode.CopyObject;

		public override string[] HandledObjectTypes { get; } = new string[1] { "ShrineChance" };

		public override bool IsValidForObject(string objectType, GameObject gameObject)
		{
			return (Object)(object)gameObject.GetComponent<ShrineChanceBehavior>() != (Object)null;
		}

		public override void Init(ObjectHandlerManager manager)
		{
			base.Init(manager);
			base.Plugin.HookManager.RegisterHandler<ShrineBehaviorHandler>();
		}

		public override InstanceHandler InstanceSingleObjectFrom(GameObject source, GameObject target, PlayerCharacterMasterController[] players)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			ShrineChanceBehavior component = source.GetComponent<ShrineChanceBehavior>();
			ShrineChanceBehavior component2 = target.GetComponent<ShrineChanceBehavior>();
			if ((Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null)
			{
				component2.rng = new Xoroshiro128Plus(component.rng);
				component2.purchaseInteraction.Networkcost = component.purchaseInteraction.Networkcost;
			}
			return base.InstanceSingleObjectFrom(source, target, players);
		}
	}
	public class SpecialItemHandler : AbstractObjectHandler
	{
		public override string[] HandledObjectTypes { get; } = new string[5] { "Sacrifice", "HuntersTricorn", "TeleporterBoss", "SuperRoboBallEncounter", "BossGroup" };

		public override ObjectInstanceMode ObjectInstanceMode => ObjectInstanceMode.CopyObject;

		public override void Init(ObjectHandlerManager manager)
		{
			base.Init(manager);
			base.Plugin.HookManager.RegisterHandler<SacrificeArtifactManagerHandler>();
			base.Plugin.HookManager.RegisterHandler<BossGroupHandler>();
			base.Plugin.HookManager.RegisterHandler<BossHunterHandler>();
		}
	}
	public class SpecialObjectHandler : AbstractObjectHandler
	{
		public override string[] HandledObjectTypes { get; } = new string[2] { "ShrineBlood", "ShrineRestack" };

		public override ObjectInstanceMode ObjectInstanceMode => ObjectInstanceMode.CopyObject;

		public override void Init(ObjectHandlerManager manager)
		{
			base.Init(manager);
			base.Plugin.HookManager.RegisterHandler<ShrineBehaviorHandler>();
		}

		public override InstanceHandler InstanceSingleObjectFrom(GameObject source, GameObject target, PlayerCharacterMasterController[] players)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Expected O, but got Unknown
			ShrineRestackBehavior component = target.GetComponent<ShrineRestackBehavior>();
			if ((Object)(object)component != (Object)null)
			{
				ShrineRestackBehavior component2 = source.GetComponent<ShrineRestackBehavior>();
				component.purchaseInteraction = ((Component)component).GetComponent<PurchaseInteraction>();
				component.rng = new Xoroshiro128Plus(component2.rng);
			}
			ShrineBloodBehavior component3 = target.GetComponent<ShrineBloodBehavior>();
			if ((Object)(object)component3 != (Object)null)
			{
				component3.purchaseInteraction = ((Component)component3).GetComponent<PurchaseInteraction>();
			}
			return base.InstanceSingleObjectFrom(source, target, players);
		}
	}
}
namespace Equilibrium.Networking
{
	public class SyncInstances : INetMessage, ISerializableObject
	{
		public struct InstanceHandlerEntry
		{
			public GameObject target;

			public GameObject[] players;

			public GameObject origPlayer;

			public NetworkInstanceId _target;

			public NetworkInstanceId[] _players;

			public NetworkInstanceId _origPlayer;

			public int Cost;

			public CostTypeIndex CostType;

			private bool validated;

			public InstanceHandlerEntry(InstanceHandler instanceHandler)
			{
				//IL_005b: Unknown result type (might be due to invalid IL or missing references)
				//IL_0060: 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_0076: Unknown result type (might be due to invalid IL or missing references)
				//IL_00a8: 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)
				target = ((Component)instanceHandler).gameObject;
				players = instanceHandler.Players.Select((PlayerCharacterMasterController p) => ((Component)p).gameObject).ToArray();
				PlayerCharacterMasterController obj = instanceHandler.OrigPlayer;
				origPlayer = ((obj != null) ? ((Component)obj).gameObject : null);
				_target = NetworkInstanceId.Invalid;
				_players = Array.Empty<NetworkInstanceId>();
				_origPlayer = NetworkInstanceId.Invalid;
				PurchaseInteraction component = ((Component)instanceHandler).GetComponent<PurchaseInteraction>();
				Cost = (((Object)(object)component != (Object)null) ? component.cost : 0);
				CostType = (CostTypeIndex)(((Object)(object)component != (Object)null) ? ((int)component.costType) : 0);
				validated = true;
			}

			public bool TryProcess()
			{
				//IL_0014: 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_003d: Unknown result type (might be due to invalid IL or missing references)
				//IL_004e: 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)
				if (validated)
				{
					return true;
				}
				target = Util.FindNetworkObject(_target);
				if ((Object)(object)target == (Object)null)
				{
					return false;
				}
				if (_origPlayer != NetworkInstanceId.Invalid)
				{
					origPlayer = Util.FindNetworkObject(_origPlayer);
				}
				players = (GameObject[])(object)new GameObject[_players.Length];
				for (int i = 0; i < _players.Length; i++)
				{
					players[i] = Util.FindNetworkObject(_players[i]);
				}
				validated = true;
				return true;
			}

			public void Serialize(NetworkWriter writer)
			{
				//IL_000d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0039: Unknown result type (might be due to invalid IL or missing references)
				//IL_0032: Unknown result type (might be due to invalid IL or missing references)
				//IL_006a: 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_0098: Expected I4, but got Unknown
				writer.Write(target.GetComponent<NetworkIdentity>().netId);
				writer.Write(((Object)(object)origPlayer == (Object)null) ? NetworkInstanceId.Invalid : origPlayer.GetComponent<NetworkIdentity>().netId);
				writer.Write(players.Length);
				GameObject[] array = players;
				foreach (GameObject val in array)
				{
					writer.Write(val.GetComponent<NetworkIdentity>().netId);
				}
				writer.Write(Cost);
				writer.Write((int)CostType);
			}

			public static InstanceHandlerEntry Deserialize(NetworkReader reader)
			{
				//IL_0014: Unknown result type (might be due to invalid IL or missing references)
				//IL_0019: Unknown result type (might be due to invalid IL or missing references)
				//IL_0021: Unknown result type (might be due to invalid IL or missing references)
				//IL_0026: Unknown result type (might be due to invalid IL or missing references)
				//IL_004d: Unknown result type (might be due to invalid IL or missing references)
				//IL_0052: Unknown result type (might be due to invalid IL or missing references)
				//IL_007a: Unknown result type (might be due to invalid IL or missing references)
				InstanceHandlerEntry result = new InstanceHandlerEntry
				{
					validated = false,
					_target = reader.ReadNetworkId(),
					_origPlayer = reader.ReadNetworkId()
				};
				int num = reader.ReadInt32();
				result._players = (NetworkInstanceId[])(object)new NetworkInstanceId[num];
				for (int i = 0; i < num; i++)
				{
					result._players[i] = reader.ReadNetworkId();
				}
				result.Cost = reader.ReadInt32();
				result.CostType = (CostTypeIndex)reader.ReadInt32();
				return result;
			}
		}

		private class PendingInfo
		{
			public SyncInstances Message;

			public float Timestamp;
		}

		private NetworkInstanceId _sourceObject;

		private ObjectInstanceMode objectInstanceMode;

		private InstanceHandlerEntry[] entries;

		private static readonly List<PendingInfo> PendingMessages = new List<PendingInfo>();

		public static bool IsPending(GameObject target)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)target))
			{
				return false;
			}
			NetworkIdentity component = target.GetComponent<NetworkIdentity>();
			if (!Object.op_Implicit((Object)(object)component))
			{
				return false;
			}
			NetworkInstanceId targetId = component.netId;
			return PendingMessages.Any((PendingInfo msg) => msg.Message.entries.Any((InstanceHandlerEntry e) => e._target == targetId));
		}

		public static void ClearPending()
		{
			PendingMessages.Clear();
		}

		public SyncInstances()
		{
			entries = Array.Empty<InstanceHandlerEntry>();
		}

		public SyncInstances(InstanceHandler.SharedInstanceInfo instanceInfo)
		{
			//IL_006a: 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_006f: Unknown result type (might be due to invalid IL or missing references)
			entries = instanceInfo.LinkedHandlers.Select((InstanceHandler h) => new InstanceHandlerEntry(h)).ToArray();
			objectInstanceMode = instanceInfo.ObjectInstanceMode;
			_sourceObject = (((Object)(object)instanceInfo.SourceObject == (Object)null) ? NetworkInstanceId.Invalid : instanceInfo.SourceObject.GetComponent<NetworkIdentity>().netId);
		}

		public void Serialize(NetworkWriter writer)
		{
			//IL_0010: Unknown result type (might be due to invalid IL or missing references)
			writer.Write((int)objectInstanceMode);
			writer.Write(_sourceObject);
			writer.Write(entries.Length);
			InstanceHandlerEntry[] array = entries;
			foreach (InstanceHandlerEntry instanceHandlerEntry in array)
			{
				instanceHandlerEntry.Serialize(writer);
			}
		}

		public void Deserialize(NetworkReader reader)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			objectInstanceMode = (ObjectInstanceMode)reader.ReadInt32();
			_sourceObject = reader.ReadNetworkId();
			int num = reader.ReadInt32();
			entries = new InstanceHandlerEntry[num];
			for (int i = 0; i < num; i++)
			{
				entries[i] = InstanceHandlerEntry.Deserialize(reader);
			}
		}

		public void OnReceived()
		{
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			if (!NetworkServer.active)
			{
				PendingMessages.Add(new PendingInfo
				{
					Message = this,
					Timestamp = Time.realtimeSinceStartup
				});
				((MonoBehaviour)Equilibrium.Instance).StartCoroutine(HandleMessage(objectInstanceMode, entries, _sourceObject));
			}
		}

		private IEnumerator HandleMessage(ObjectInstanceMode mode, InstanceHandlerEntry[] entries, NetworkInstanceId sourceId)
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_001d: Unknown result type (might be due to invalid IL or missing references)
			bool validated = false;
			int retryCount = 0;
			GameObject sourceObject = null;
			while (!validated && retryCount < 20)
			{
				retryCount++;
				validated = true;
				for (int i = 0; i < entries.Length; i++)
				{
					if (!entries[i].TryProcess())
					{
						validated = false;
					}
				}
				if ((Object)(object)sourceObject == (Object)null && sourceId != NetworkInstanceId.Invalid)
				{
					sourceObject = Util.FindNetworkObject(sourceId);
				}
				if (!validated)
				{
					yield return null;
				}
			}
			try
			{
				InstanceHandler.SharedInstanceInfo sharedInfo = new InstanceHandler.SharedInstanceInfo
				{
					ObjectInstanceMode = mode,
					SourceObject = sourceObject
				};
				PlayerCharacterMasterController pc = default(PlayerCharacterMasterController);
				for (int j = 0; j < entries.Length; j++)
				{
					InstanceHandlerEntry entry = entries[j];
					GameObject target = Util.FindNetworkObject(entry._target);
					if ((Object)(object)target == (Object)null)
					{
						continue;
					}
					PurchaseInteraction pi = target.GetComponent<PurchaseInteraction>();
					if ((Object)(object)pi != (Object)null && entry.Cost > 0)
					{
						pi.cost = entry.Cost;
						pi.Networkcost = entry.Cost;
						pi.costType = entry.CostType;
					}
					InstanceHandler handler = target.GetComponent<InstanceHandler>();
					if ((Object)(object)handler == (Object)null)
					{
						handler = target.AddComponent<InstanceHandler>();
					}
					List<PlayerCharacterMasterController> validPlayers = new List<PlayerCharacterMasterController>();
					if (entry.players != null)
					{
						GameObject[] players = entry.players;
						foreach (GameObject pObj in players)
						{
							int num;
							if (Object.op_Implicit((Object)(object)pObj))
							{
								pc = pObj.GetComponent<PlayerCharacterMasterController>();
								num = 1;
							}
							else
							{
								num = 0;
							}
							if (num != 0)
							{
								validPlayers.Add(pc);
							}
							pc = null;
						}
					}
					handler.SetPlayers(validPlayers, sync: false);
					if ((Object)(object)entry.origPlayer != (Object)null)
					{
						handler.OrigPlayer = entry.origPlayer.GetComponent<PlayerCharacterMasterController>();
					}
					if ((Object)(object)sourceObject != (Object)null)
					{
						target.transform.position = sourceObject.transform.position;
						target.transform.rotation = sourceObject.transform.rotation;
						target.transform.localScale = sourceObject.transform.localScale;
					}
					handler.SharedInfo = sharedInfo;
				}
				sharedInfo.RecalculateAllPlayers();
				foreach (InstanceHandler handler2 in InstanceHandler.Instances)
				{
					if (Object.op_Implicit((Object)(object)handler2) && handler2.SharedInfo == sharedInfo)
					{
						handler2.UpdateVisuals();
					}
				}
			}
			catch (Exception ex)
			{
				Exception e = ex;
				Equilibrium.Instance.Logger.LogError((object)$"[均衡神器] 应用网络同步数据时出错: {e}");
			}
			finally
			{
				PendingInfo info = PendingMessages.FirstOrDefault((PendingInfo p) => p.Message == this);
				if (info != null)
				{
					PendingMessages.Remove(info);
				}
			}
		}

		public static void CheckTimeouts()
		{
			if (NetworkServer.active)
			{
				return;
			}
			float realtimeSinceStartup = Time.realtimeSinceStartup;
			for (int num = PendingMessages.Count - 1; num >= 0; num--)
			{
				if (realtimeSinceStartup - PendingMessages[num].Timestamp > 2f)
				{
					PendingMessages.RemoveAt(num);
				}
			}
		}
	}
}
namespace Equilibrium.Patches
{
	[HarmonyPatch(typeof(SwarmsArtifactManager), "OnSpawnCardOnSpawnedServerGlobal")]
	internal static class Swarms_OnSpawnCard_Patch
	{
		private static bool Prefix()
		{
			return !Equilibrium.IsCloningForInstance;
		}
	}
}
namespace Equilibrium.Core
{
	public abstract class AbstractHookHandler
	{
		internal HookManager HookManager;

		protected Equilibrium Plugin => HookManager.Plugin;

		protected global::Equilibrium.Config.Config ModConfig => Plugin.ModConfig;

		public void Init(HookManager hookManager)
		{
			HookManager = hookManager;
		}

		public abstract void RegisterHooks();

		public abstract void UnregisterHooks();
	}
	public abstract class AbstractObjectHandler
	{
		public struct AwaitedObjectInfo
		{
			public GameObject SourceObject;

			public PlayerCharacterMasterController[] Players;

			public object ExtraInfo;
		}

		private static Dictionary<string, SpawnCard> _spawnCardsForPrefabName;

		protected ObjectHandlerManager Manager;

		public readonly Dictionary<GameObject, AwaitedObjectInfo> InfoForAwaitedObjects = new Dictionary<GameObject, AwaitedObjectInfo>();

		public static Dictionary<string, SpawnCard> SpawnCardsForPrefabName
		{
			get
			{
				if (_spawnCardsForPrefabName == null)
				{
					GenerateSpawnCards();
				}
				return _spawnCardsForPrefabName;
			}
		}

		protected Equilibrium Plugin => Manager.Plugin;

		public abstract string[] HandledObjectTypes { get; }

		public abstract ObjectInstanceMode ObjectInstanceMode { get; }

		private static void GenerateSpawnCards()
		{
			_spawnCardsForPrefabName = new Dictionary<string, SpawnCard>();
			InteractableSpawnCard[] array = Resources.FindObjectsOfTypeAll<InteractableSpawnCard>();
			foreach (InteractableSpawnCard val in array)
			{
				string name = ((Object)((SpawnCard)val).prefab).name;
				if (!_spawnCardsForPrefabName.ContainsKey(name))
				{
					_spawnCardsForPrefabName.Add(name, (SpawnCard)(object)val);
				}
			}
		}

		public virtual void Init(ObjectHandlerManager manager)
		{
			Manager = manager;
		}

		public virtual bool CanObjectBeOwned(string objectType)
		{
			return false;
		}

		public virtual bool IsValidForObject(string objectType, GameObject gameObject)
		{
			return true;
		}

		public virtual void InstanceObject(string objectType, GameObject gameObject, PlayerCharacterMasterController[] players)
		{
			InstanceHandler.SharedInstanceInfo sharedInfo = new InstanceHandler.SharedInstanceInfo
			{
				SourceObject = gameObject,
				ObjectInstanceMode = ObjectInstanceMode
			};
			InstanceHandler[] array;
			PlayerCharacterMasterController[] players2;
			switch (ObjectInstanceMode)
			{
			case ObjectInstanceMode.InstancedObject:
				array = new InstanceHandler[1];
				players2 = players;
				break;
			case ObjectInstanceMode.CopyObject:
				array = new InstanceHandler[players.Length];
				players2 = (PlayerCharacterMasterController[])(object)new PlayerCharacterMasterController[1] { players[0] };
				break;
			default:
				throw new InvalidOperationException("Object handler 不支持此对象实例化模式");
			}
			(array[0] = InstanceSingleObjectFrom(gameObject, gameObject, players2)).SharedInfo = sharedInfo;
			if (ObjectInstanceMode == ObjectInstanceMode.CopyObject)
			{
				for (int i = 1; i < players.Length; i++)
				{
					GameObject val = CloneObject(objectType, gameObject);
					if ((Object)(object)val != (Object)null)
					{
						AwaitObjectFor(val, new AwaitedObjectInfo
						{
							SourceObject = gameObject,
							Players = (PlayerCharacterMasterController[])(object)new PlayerCharacterMasterController[1] { players[i] }
						});
					}
				}
			}
			FinalizeSourceObjectIfNotAwaited(gameObject);
		}

		public virtual GameObject CloneObject(string objectType, GameObject gameObject)
		{
			//IL_0074: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: 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_0091: Unknown result type (might be due to invalid IL or missing references)
			//IL_0098: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Expected O, but got Unknown
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: Expected O, but got Unknown
			//IL_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Expected O, but got Unknown
			//IL_00c6: 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_00d8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: 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_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0134: Unknown result type (might be due to invalid IL or missing references)
			SpawnCard value = null;
			SpawnCardTracker component = gameObject.GetComponent<SpawnCardTracker>();
			if ((Object)(object)component != (Object)null)
			{
				value = component.SpawnCard;
			}
			if ((Object)(object)value == (Object)null)
			{
				string key = ((Object)gameObject).name.Replace("(Clone)", "").Replace("(Cloned)", "").Trim();
				SpawnCardsForPrefabName.TryGetValue(key, out value);
			}
			if ((Object)(object)value != (Object)null)
			{
				DirectorPlacementRule val = new DirectorPlacementRule
				{
					placementMode = (PlacementMode)0,
					position = gameObject.transform.position,
					rotation = gameObject.transform.rotation
				};
				DirectorSpawnRequest val2 = new DirectorSpawnRequest(value, val, new Xoroshiro128Plus(0uL));
				GameObject val3 = null;
				try
				{
					Equilibrium.IsCloningForInstance = true;
					SpawnResult val4 = value.DoSpawn(gameObject.transform.position, gameObject.transform.rotation, val2);
					val3 = val4.spawnedInstance;
					if ((Object)(object)val3 != (Object)null)
					{
						val3.transform.position = gameObject.transform.position;
						val3.transform.rotation = gameObject.transform.rotation;
						val3.transform.localScale = gameObject.transform.localScale;
						val3.layer = gameObject.layer;
					}
				}
				finally
				{
					Equilibrium.IsCloningForInstance = false;
				}
				return val3;
			}
			Plugin.Logger.LogError((object)$"未找到 SpawnCard,用于复制对象 {gameObject}(objectType={objectType})");
			return null;
		}

		public virtual InstanceHandler InstanceSingleObjectFrom(GameObject source, GameObject target, PlayerCharacterMasterController[] players)
		{
			//IL_009b: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Expected O, but got Unknown
			InstanceHandler instanceHandler = target.AddComponent<InstanceHandler>();
			instanceHandler.SetPlayers(players, sync: false);
			if (ObjectInstanceMode == ObjectInstanceMode.CopyObject)
			{
				instanceHandler.OrigPlayer = players[0];
				InstanceInfoTracker component = source.GetComponent<InstanceInfoTracker>();
				if ((Object)(object)component != (Object)null)
				{
					component.Info.AttachTo(target);
				}
				InstanceHandler component2 = source.GetComponent<InstanceHandler>();
				if ((Object)(object)component2 != (Object)null)
				{
					instanceHandler.SharedInfo = component2.SharedInfo;
				}
			}
			PurchaseInteraction component3 = source.GetComponent<PurchaseInteraction>();
			PurchaseInteraction component4 = target.GetComponent<PurchaseInteraction>();
			if ((Object)(object)component3 != (Object)null && (Object)(object)component4 != (Object)null)
			{
				component4.costType = component3.costType;
				component4.cost = component3.cost;
				component4.Networkcost = component3.Networkcost;
				if (component3.rng != null)
				{
					component4.rng = new Xoroshiro128Plus(component3.rng);
				}
			}
			return instanceHandler;
		}

		public virtual void FinalizeSourceObjectIfNotAwaited(GameObject sourceObject)
		{
			if (InfoForAwaitedObjects.All((KeyValuePair<GameObject, AwaitedObjectInfo> pair) => (Object)(object)pair.Value.SourceObject != (Object)(object)sourceObject))
			{
				FinalizeObject(sourceObject);
			}
		}

		public virtual void FinalizeObject(GameObject sourceObject)
		{
			InstanceHandler component = sourceObject.GetComponent<InstanceHandler>();
			if ((Object)(object)component == (Object)null)
			{
				return;
			}
			component.SharedInfo.SyncToAll();
			foreach (InstanceHandler linkedHandler in component.SharedInfo.LinkedHandlers)
			{
				linkedHandler.UpdateVisuals();
			}
		}

		public virtual void AwaitObjectFor(GameObject target, AwaitedObjectInfo info)
		{
			InfoForAwaitedObjects.Add(target, info);
			Manager.RegisterAwaitedObject(target, this);
		}

		public virtual void HandleAwaitedObject(GameObject target)
		{
			if (InfoForAwaitedObjects.TryGetValue(target, out var value))
			{
				InfoForAwaitedObjects.Remove(target);
				InstanceSingleObjectFrom(value.SourceObject, target, value.Players);
				FinalizeSourceObjectIfNotAwaited(value.SourceObject);
			}
		}
	}
	public class HookManager
	{
		public readonly Dictionary<Type, AbstractHookHandler> HookHandlers = new Dictionary<Type, AbstractHookHandler>();

		public readonly Equilibrium Plugin;

		public HookManager(Equilibrium plugin)
		{
			Plugin = plugin;
			RegisterHandler<ChestBehaviorHandler>();
			RegisterHandler<ShrineBehaviorHandler>();
			RegisterHandler<MultiShopControllerHandler>();
			RegisterHandler<OptionChestBehaviorHandler>();
			RegisterHandler<SacrificeArtifactManagerHandler>();
			RegisterHandler<BossGroupHandler>();
			RegisterHandler<BossHunterHandler>();
			RegisterHandler<PurchaseInteractionHandler>();
			RegisterHandler<GenericPickupControllerHandler>();
			RegisterHandler<PickupDropletControllerHandler>();
			RegisterHandler<SpawnCardHandler>();
			RegisterHandler<ScavBackpackOpeningHandler>();
			RegisterHandler<PickupPickerControllerHandler>();
			RegisterHandler<DitherModelHandler>();
			RegisterHandler<InteractorHandler>();
			RegisterHandler<SonorousWhispersHandler>();
		}

		public void RegisterHandler<T>() where T : AbstractHookHandler, new()
		{
			if (!HookHandlers.ContainsKey(typeof(T)))
			{
				T val = new T();
				val.Init(this);
				HookHandlers[typeof(T)] = val;
			}
		}

		public T GetHandler<T>() where T : AbstractHookHandler
		{
			return (T)HookHandlers[typeof(T)];
		}

		public void RegisterHooks()
		{
			foreach (AbstractHookHandler value in HookHandlers.Values)
			{
				value.RegisterHooks();
			}
		}

		public void UnregisterHooks()
		{
			foreach (AbstractHookHandler value in HookHandlers.Values)
			{
				try
				{
					value.UnregisterHooks();
				}
				catch (Exception arg)
				{
					Plugin.Logger.LogError((object)$"Error unloading {value.GetType()}: {arg}");
				}
			}
		}
	}
	public class ObjectHandlerManager
	{
		public readonly Dictionary<Type, AbstractObjectHandler> ObjectHandlers = new Dictionary<Type, AbstractObjectHandler>();

		public readonly Dictionary<string, AbstractObjectHandler> HandlersForObjectType = new Dictionary<string, AbstractObjectHandler>();

		public readonly Dictionary<GameObject, AbstractObjectHandler> AwaitedObjects = new Dictionary<GameObject, AbstractObjectHandler>();

		public readonly Equilibrium Plugin;

		public ObjectHandlerManager(Equilibrium plugin)
		{
			Plugin = plugin;
			RegisterHandler<ChestHandler>();
			RegisterHandler<ShrineChanceHandler>();
			RegisterHandler<SpecialObjectHandler>();
			RegisterHandler<MultiShopHandler>();
			RegisterHandler<OptionChestHandler>();
			RegisterHandler<SpecialItemHandler>();
			Plugin.Logger.LogInfo((object)"[均衡神器] 对象处理器注册完成");
		}

		public void RegisterHandler<T>() where T : AbstractObjectHandler, new()
		{
			T val = new T();
			val.Init(this);
			ObjectHandlers[typeof(T)] = val;
			string[] handledObjectTypes = val.HandledObjectTypes;
			foreach (string key in handledObjectTypes)
			{
				HandlersForObjectType[key] = val;
			}
			Plugin.Logger.LogInfo((object)("[均衡神器] 注册对象处理器:" + typeof(T).Name));
		}

		public T GetHandler<T>() where T : AbstractObjectHandler
		{
			return (T)ObjectHandlers[typeof(T)];
		}

		public void InstanceObject(string objectType, GameObject gameObject, PlayerCharacterMasterController[] players)
		{
			if (HandlersForObjectType.TryGetValue(objectType, out var value))
			{
				value.InstanceObject(objectType, gameObject, players);
			}
			else
			{
				Plugin.Logger.LogWarning((object)("[均衡神器] 尝试实例化未知对象类型: " + objectType));
			}
		}

		public InstanceHandler InstanceSingleObject(string objectType, GameObject source, GameObject target, PlayerCharacterMasterController[] players)
		{
			AbstractObjectHandler value;
			return HandlersForObjectType.TryGetValue(objectType, out value) ? value.InstanceSingleObjectFrom(source, target, players) : null;
		}

		public bool CanInstanceObject(string objectType, GameObject gameObject)
		{
			AbstractObjectHandler value;
			return HandlersForObjectType.TryGetValue(objectType, out value) && value.IsValidForObject(objectType, gameObject);
		}

		public void RegisterAwaitedObject(GameObject gameObject, AbstractObjectHandler owningHandler)
		{
			AwaitedObjects.Add(gameObject, owningHandler);
			Plugin.Logger.LogDebug((object)("[均衡神器] 注册待等待对象: " + ((Object)gameObject).name));
		}

		public bool HandleAwaitedObject(GameObject gameObject)
		{
			if (!AwaitedObjects.TryGetValue(gameObject, out var value))
			{
				return false;
			}
			AwaitedObjects.Remove(gameObject);
			value.HandleAwaitedObject(gameObject);
			Plugin.Logger.LogDebug((object)("[均衡神器] 处理待等待对象: " + ((Object)gameObject).name));
			return true;
		}
	}
}
namespace Equilibrium.Config
{
	public class AcceptableValuesInstanceMode : AcceptableValueBase
	{
		public AcceptableValuesInstanceMode()
			: base(typeof(InstanceMode))
		{
		}

		public override object Clamp(object value)
		{
			return ((AcceptableValueBase)this).IsValid(value) ? value : ((object)InstanceMode.None);
		}

		public override bool IsValid(object value)
		{
			InstanceMode instanceMode = default(InstanceMode);
			int num;
			if (value is InstanceMode)
			{
				instanceMode = (InstanceMode)value;
				num = 1;
			}
			else
			{
				num = 0;
			}
			bool flag = (byte)num != 0;
			bool flag2 = flag;
			if (flag2)
			{
				bool flag3 = (uint)instanceMode <= 2u;
				flag2 = flag3;
			}
			return flag2;
		}

		public override string ToDescriptionString()
		{
			return "# Acceptable values: None, InstanceObject, InstanceBoth";
		}
	}
	public class Config
	{
		public readonly Equilibrium Plugin;

		private readonly ManualLogSource _logger;

		public ConfigEntry<InstanceMode> DefaultChestMode;

		public ConfigEntry<InstanceMode> DefaultShrineMode;

		public ConfigEntry<InstanceMode> DefaultShopMode;

		public ConfigEntry<InstanceMode> DefaultVoidMode;

		public ConfigEntry<InstanceMode> DefaultSpecialMode;

		public ConfigEntry<bool> GlobalInstancingEnabled;

		public ConfigEntry<float> InteractibleCreditMultiplier;

		public Dictionary<string, ConfigEntry<InstanceMode>> PerObjectMode = new Dictionary<string, ConfigEntry<InstanceMode>>();

		private readonly Dictionary<string, InstanceMode> _cache = new Dictionary<string, InstanceMode>();

		public ConfigEntry<bool> ARollDrop;

		public ConfigEntry<bool> LogInstanceInteractions;

		public Config(Equilibrium plugin, ManualLogSource logger)
		{
			Plugin = plugin;
			_logger = logger;
			ARollDrop = ((BaseUnityPlugin)Plugin).Config.Bind<bool>("ARollDrop", "ARollDrop", true, "When true, each chest copy will get a separate random seed and re-roll its items (random loot per player). When false, all copies will have the exact same items as the original chest.\n启用独立随机掉落:每个复制宝箱将使用独立的随机种子并重新生成物品(每个玩家看到不同的掉落)。关闭时,所有复制宝箱将与原宝箱拥有完全相同的物品。");
			LogInstanceInteractions = ((BaseUnityPlugin)Plugin).Config.Bind<bool>("Debug", "LogInstanceInteractions", false, "Enable detailed interaction diagnostics logging.\nLogs purchase calls, changed selections/pickup states and instance snapshots.\nCapped at 512 purchase, 512 selection/pickup lines per plugin session. Restart to collect a new trace.\n启用详细交互诊断日志。记录购买调用、选择/拾取状态变化和实例快照。\n每次插件会话最多记录 512 条购买、512 条选择/拾取日志,重启以重新收集。默认关闭。");
			GlobalInstancingEnabled = ((BaseUnityPlugin)Plugin).Config.Bind<bool>("AGeneral", "Enabled", true, "Global master switch for Equilibrium. When false, all object instancing modes behave as None.\n均衡神器的全局控制开关。当该开关为“false”时,所有对象实例化模式都将等同于“None”模式。(该开关由大厅内神器开关控制,保持默认即可)");
			InteractibleCreditMultiplier = ((BaseUnityPlugin)Plugin).Config.Bind<float>("AGeneral", "InteractibleCreditMultiplier", 0.76f, "Multiplayer interactable (chest/shrine) budget multiplier. Original game scales this significantly, causing chest floods. 1.0 = Vanilla; 0.7 = Recommended; 0.5 = Half.\n多人游戏下,交互物(宝箱/神龛/商店)生成预算的乘数。原版多人时宝箱会增加数量,且每人一个宝箱时导致最终战利品过多。这个系数用于减少多人时宝箱会增加数量从而平衡最终战利品\n原版:1.0;默认值:0.76;推荐值:0.7、0.75、0.76、0.8;减半:0.5。数值越大宝箱越多,单人游戏不受此配置影响始终为1。");
			DefaultChestMode = Bind("Chests", "Default", InstanceMode.InstanceBoth, "Default mode for all chests. InstanceObject = each player gets a copy, items free-for-all. InstanceBoth = each player gets a copy, items owner-only.\n所有宝箱的默认设置。InstanceObject模式:其他玩家也可以拾取;InstanceBoth模式:仅自己可拾取\n以下是宝箱对应名称:\n- Chest1: 普通宝箱\n- Chest2: 大宝箱\n- GoldChest: 传奇宝箱\n- Chest1StealthedVariant: 隐藏宝箱\n- CategoryChestDamage: 伤害箱\n- CategoryChestHealing: 治疗箱\n- CategoryChestUtility: 辅助箱\n- CategoryChest2Damage: 大伤害箱\n- CategoryChest2Healing: 大治疗箱\n- CategoryChest2Utility: 大辅助箱\n- EquipmentBarrel: 装备箱\n- LunarChest: 月球舱\n- VoidChest: 虚空摇篮\n- Lockbox: 生锈锁箱\n- ScavBackpack: 拾荒者背包");
			DefaultShrineMode = Bind("Shrines", "Default", InstanceMode.InstanceBoth, "Default mode for shrines.\n神龛的默认模式\n以下是神龛对应名称:\n- ShrineChance: 机遇神龛\n- ShrineBlood: 鲜血神龛\n- ShrineRestack: 塑形神龛maybe");
			DefaultShopMode = Bind("Shops", "Default", InstanceMode.InstanceBoth, "Default mode for multi shops.\n三选一商店的默认模式\n以下是三选一商店对应名称:\n- TripleShop: 三选一商店\n- TripleShopLarge: 大三选一商店?\n- TripleShopEquipment: 装备三选一商店\n- FreeChestMultiShop: 坠毁的多功能商店maybe┑(\uffe3Д \uffe3)┍");
			DefaultVoidMode = Bind("Void", "Default", InstanceMode.InstanceBoth, "Default mode for void objects.\n虚空物品的默认模式\n以下是虚空物品对应名称:\n- VoidTriple: 虚空潜能\n- LockboxVoid: 结壳宝箱");
			DefaultSpecialMode = Bind("Special", "Default", InstanceMode.InstanceBoth, "Default mode for sacrifice, boss drops, etc.\n牺牲、首领掉落物品等的处理方式的默认模式\n以下是牺牲、首领掉落物品对应名称:\n- Sacrifice: 牺牲掉落\n- HuntersTricorn: 米爹maybe\n- TeleporterBoss: 传送器BOSS\n- SuperRoboBallEncounter: 合金崇拜单体maybe\n- BossGroup: idk┑(\uffe3Д \uffe3)┍");
			FieldInfo[] fields = typeof(ObjectType).GetFields(BindingFlags.Static | BindingFlags.Public);
			foreach (FieldInfo fieldInfo in fields)
			{
				if (!(fieldInfo.FieldType != typeof(string)))
				{
					string text = (string)fieldInfo.GetValue(null);
					string category = GetCategory(text);
					if (1 == 0)
					{
					}
					InstanceMode instanceMode = category switch
					{
						"Chests" => DefaultChestMode.Value, 
						"Shrines" => DefaultShrineMode.Value, 
						"Shops" => DefaultShopMode.Value, 
						"Void" => DefaultVoidMode.Value, 
						_ => DefaultSpecialMode.Value, 
					};
					if (1 == 0)
					{
					}
					InstanceMode instanceMode2 = instanceMode;
					PerObjectMode[text] = ((BaseUnityPlugin)plugin).Config.Bind<InstanceMode>(category, text, instanceMode2, "Instancing mode for " + text);
				}
			}
			((BaseUnityPlugin)plugin).Config.SettingChanged += delegate(object _, SettingChangedEventArgs e)
			{
				_cache.Clear();
				if (GlobalInstancingEnabled != null && e.ChangedSetting.Definition.Equals(((ConfigEntryBase)GlobalInstancingEnabled).Definition))
				{
					EquilibriumManager.SetConfigEnabled(GlobalInstancingEnabled.Value);
					Plugin.Logger.LogInfo((object)$"[Equilibrium] Global instancing enabled.\n[均衡神器] 全局实例化已启用 = {GlobalInstancingEnabled.Value}");
				}
			};
			EquilibriumManager.SetConfigEnabled(GlobalInstancingEnabled.Value);
		}

		private ConfigEntry<InstanceMode> Bind(string section, string key, InstanceMode defaultValue, string description)
		{
			//IL_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0025: Expected O, but got Unknown
			return ((BaseUnityPlugin)Plugin).Config.Bind<InstanceMode>(section, key, defaultValue, new ConfigDescription(description, (AcceptableValueBase)(object)new AcceptableValuesInstanceMode(), Array.Empty<object>()));
		}

		public InstanceMode GetMode(string objectType)
		{
			if (GlobalInstancingEnabled != null && !GlobalInstancingEnabled.Value)
			{
				return InstanceMode.None;
			}
			if (objectType == null)
			{
				return InstanceMode.None;
			}
			if (_cache.TryGetValue(objectType, out var value))
			{
				return value;
			}
			ConfigEntry<InstanceMode> value2;
			InstanceMode instanceMode = (PerObjectMode.TryGetValue(objectType, out value2) ? value2.Value : InstanceMode.None);
			_cache[objectType] = instanceMode;
			return instanceMode;
		}

		public HashSet<PlayerCharacterMasterController> GetValidPlayers()
		{
			return new HashSet<PlayerCharacterMasterController>(PlayerCharacterMasterController.instances);
		}

		public void OnConfigReloaded()
		{
			_cache.Clear();
			EquilibriumManager.SetConfigEnabled(GlobalInstancingEnabled.Value);
			Plugin.Logger.LogInfo((object)"[Equilibrium] Config reloaded and applied.[均衡神器] 配置文件已重新加载并生效。");
		}

		private static string GetCategory(string objectType)
		{
			if (1 == 0)
			{
			}
			string result;
			switch (objectType)
			{
			case "Chest1":
			case "Chest2":
			case "GoldChest":
			case "Chest1StealthedVariant":
			case "CategoryChestDamage":
			case "CategoryChestHealing":
			case "CategoryChestUtility":
			case "CategoryChest2Damage":
			case "CategoryChest2Healing":
			case "CategoryChest2Utility":
			case "EquipmentBarrel":
			case "LunarChest":
			case "VoidChest":
			case "Lockbox":
			case "ScavBackpack":
				result = "Chests";
				break;
			case "ShrineChance":
			case "ShrineBlood":
			case "ShrineRestack":
				result = "Shrines";
				break;
			case "TripleShop":
			case "TripleShopLarge":
			case "TripleShopEquipment":
			case "FreeChestMultiShop":
				result = "Shops";
				break;
			case "VoidTriple":
			case "LockboxVoid":
				result = "Void";
				break;
			default:
				result = "Special";
				break;
			}
			if (1 == 0)
			{
			}
			return result;
		}
	}
}
namespace Equilibrium.Hooks
{
	public class AnimationEventsHandler : AbstractHookHandler
	{
		public static AnimationEvents CurrentAnimationEvents;

		public override void RegisterHooks()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			AnimationEvents.CreateEffect += new hook_CreateEffect(On_AnimationEvents_CreateEffect);
			AnimationEvents.CreatePrefab += new Manipulator(IL_AnimationEvents_CreatePrefab);
		}

		public override void UnregisterHooks()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			AnimationEvents.CreateEffect -= new hook_CreateEffect(On_AnimationEvents_CreateEffect);
			AnimationEvents.CreatePrefab -= new Manipulator(IL_AnimationEvents_CreatePrefab);
		}

		private void On_AnimationEvents_CreateEffect(orig_CreateEffect orig, AnimationEvents self, AnimationEvent animationEvent)
		{
			CurrentAnimationEvents = self;
			orig.Invoke(self, animationEvent);
			CurrentAnimationEvents = null;
			FadeBehavior component = ((Component)self).GetComponent<FadeBehavior>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.RefreshNextFrame();
			}
			EntityLocator component2 = ((Component)self).GetComponent<EntityLocator>();
			if (Object.op_Implicit((Object)(object)component2) && Object.op_Implicit((Object)(object)component2.entity))
			{
				FadeBehavior component3 = component2.entity.GetComponent<FadeBehavior>();
				if (Object.op_Implicit((Object)(object)component3))
				{
					component3.Refresh();
				}
			}
		}

		private void IL_AnimationEvents_CreatePrefab(ILContext il)
		{
			AnimationPrefabIL.Apply<Action<Transform, AnimationEvents, bool>>(il, HandlePrefabCreation);
		}

		public static void HandlePrefabCreation(Transform created, AnimationEvents parent, bool pooled)
		{
			if (!pooled && Object.op_Implicit((Object)(object)created))
			{
				HandleObjectCreation(((Component)created).gameObject, parent);
			}
		}

		public static void HandleEffectCreation(GameObject objectToAdd)
		{
			if ((Object)(object)CurrentAnimationEvents != (Object)null)
			{
				HandleObjectCreation(objectToAdd, CurrentAnimationEvents);
			}
		}

		public static void HandleObjectCreation(GameObject objectToAdd, AnimationEvents parent)
		{
			Transform val = objectToAdd.transform;
			Transform transform = ((Component)parent).transform;
			while ((Object)(object)val != (Object)(object)transform && (Object)(object)val != (Object)null)
			{
				val = val.parent;
			}
			FadeBehavior componentInParent = ((Component)parent).GetComponentInParent<FadeBehavior>();
			if ((Object)(object)componentInParent == (Object)null)
			{
				EntityLocator component = ((Component)parent).GetComponent<EntityLocator>();
				if ((Object)(object)component != (Object)null && (Object)(object)component.entity != (Object)null)
				{
					componentInParent = component.entity.GetComponentInParent<FadeBehavior>();
				}
			}
			if (!((Object)(object)componentInParent == (Object)null))
			{
				if ((Object)(object)val != (Object)(object)transform)
				{
					componentInParent.ExtraGameObjects.Add(objectToAdd);
				}
				componentInParent.Refresh();
			}
		}
	}
	internal static class AnimationPrefabIL
	{
		internal static void Apply<TDelegate>(ILContext il, TDelegate handleCreation) where TDelegate : Delegate
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Invalid comparison between Unknown and I4
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			int pooledLocal = -1;
			if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2]
			{
				IsShouldUsePooledEffectCall,
				(Instruction i) => ILPatternMatchingExt.MatchStloc(i, ref pooledLocal)
			}) || (int)((VariableReference)il.Body.Variables[pooledLocal]).VariableType.MetadataType != 2)
			{
				throw new InvalidOperationException(((MemberReference)il.Method).FullName + ": CreatePrefab pooled-effect flag pattern not found.");
			}
			val.Index = 0;
			int num = 0;
			while (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { IsDoSpawnEffectCall }))
			{
				val.Emit(OpCodes.Dup);
				val.Emit(OpCodes.Ldarg_0);
				val.Emit(OpCodes.Ldloc, il.Body.Variables[pooledLocal]);
				val.EmitDelegate<TDelegate>(handleCreation);
				num++;
			}
			if (num == 0)
			{
				throw new InvalidOperationException(((MemberReference)il.Method).FullName + ": CreatePrefab DoSpawnEffect pattern not found.");
			}
		}

		private static bool IsShouldUsePooledEffectCall(Instruction i)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Invalid comparison between Unknown and I4
			if (i.OpCode != OpCodes.Call)
			{
				return false;
			}
			object operand = i.Operand;
			MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
			if (val == null)
			{
				return false;
			}
			return ((MemberReference)((MemberReference)val).DeclaringType).FullName == "RoR2.EffectManager" && ((MemberReference)val).Name == "ShouldUsePooledEffect" && (int)val.ReturnType.MetadataType == 2 && val.Parameters.Count == 1 && ((MemberReference)((ParameterReference)val.Parameters[0]).ParameterType).FullName == "UnityEngine.GameObject";
		}

		private static bool IsDoSpawnEffectCall(Instruction i)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Invalid comparison between Unknown and I4
			if (i.OpCode != OpCodes.Call)
			{
				return false;
			}
			object operand = i.Operand;
			MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
			if (val == null)
			{
				return false;
			}
			return ((MemberReference)((MemberReference)val).DeclaringType).FullName == "RoR2.AnimationEvents" && !val.HasThis && ((MemberReference)val).Name.StartsWith("<CreatePrefab>g__DoSpawnEffect|", StringComparison.Ordinal) && ((MemberReference)val.ReturnType).FullName == "UnityEngine.Transform" && val.Parameters.Count == 5 && (int)((ParameterReference)val.Parameters[0]).ParameterType.MetadataType == 2 && ((MemberReference)((ParameterReference)val.Parameters[1]).ParameterType).FullName == "UnityEngine.GameObject" && ((MemberReference)((ParameterReference)val.Parameters[2]).ParameterType).FullName == "UnityEngine.Vector3" && ((MemberReference)((ParameterReference)val.Parameters[3]).ParameterType).FullName == "UnityEngine.Quaternion" && ((MemberReference)((ParameterReference)val.Parameters[4]).ParameterType).FullName == "UnityEngine.Transform";
		}
	}
	public class ChestBehaviorHandler : AbstractHookHandler
	{
		public override void RegisterHooks()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			ChestBehavior.ItemDrop += new hook_ItemDrop(OnItemDrop);
			ChestBehavior.Start += new hook_Start(OnStart);
		}

		public override void UnregisterHooks()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			ChestBehavior.ItemDrop -= new hook_ItemDrop(OnItemDrop);
			ChestBehavior.Start -= new hook_Start(OnStart);
		}

		private void OnItemDrop(orig_ItemDrop orig, ChestBehavior self)
		{
			InstanceInfoTracker component = ((Component)self).GetComponent<InstanceInfoTracker>();
			if ((Object)(object)component != (Object)null)
			{
				HookManager.GetHandler<PickupDropletControllerHandler>().InstanceOverrideInfo = component.Info;
				orig.Invoke(self);
				HookManager.GetHandler<PickupDropletControllerHandler>().InstanceOverrideInfo = null;
			}
			else
			{
				orig.Invoke(self);
			}
		}

		private void OnStart(orig_Start orig, ChestBehavior self)
		{
			if (!NetworkServer.active)
			{
				orig.Invoke(self);
			}
			else
			{
				if (base.Plugin.ObjectHandlerManager.HandleAwaitedObject(((Component)self).gameObject))
				{
					return;
				}
				if ((Object)(object)((Component)self).GetComponent<InstanceHandler>() != (Object)null)
				{
					orig.Invoke(self);
					return;
				}
				orig.Invoke(self);
				string name = ((Object)self).name;
				string text = name;
				if (1 == 0)
				{
				}
				string text2 = ((!name.StartsWith("Chest1")) ? ((!name.StartsWith("Chest2")) ? ((!name.StartsWith("GoldChest")) ? ((!name.StartsWith("Chest1StealthedVariant")) ? ((!name.StartsWith("CategoryChestDamage")) ? ((!name.StartsWith("CategoryChestHealing")) ? ((!name.StartsWith("CategoryChestUtility")) ? ((!name.StartsWith("CategoryChest2Damage")) ? ((!name.StartsWith("CategoryChest2Healing")) ? ((!name.StartsWith("CategoryChest2Utility")) ? ((!name.StartsWith("EquipmentBarrel")) ? ((!name.StartsWith("LunarChest")) ? ((!name.StartsWith("VoidChest")) ? ((!name.StartsWith("Lockbox")) ? ((!name.StartsWith("ScavBackpack")) ? null : "ScavBackpack") : "Lockbox") : "VoidChest") : "LunarChest") : "EquipmentBarrel") : "CategoryChest2Utility") : "CategoryChest2Healing") : "CategoryChest2Damage") : "CategoryChestUtility") : "CategoryChestHealing") : "CategoryChestDamage") : "Chest1StealthedVariant") : "GoldChest") : "Chest2") : "Chest1");
				if (1 == 0)
				{
				}
				string text3 = text2;
				if (text3 != null)
				{
					base.Plugin.HandleInstancing(((Component)self).gameObject, new InstanceInfoTracker.InstanceOverrideInfo(text3));
				}
			}
		}
	}
	public class BossGroupHandler : AbstractHookHandler
	{
		public override void RegisterHooks()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			BossGroup.Start += new hook_Start(OnStart);
			BossGroup.DropRewards += new hook_DropRewards(OnDropRewards);
			BossGroup.DropRewards += new Manipulator(IL_DropRewards);
		}

		public override void UnregisterHooks()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Expected O, but got Unknown
			//IL_002c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0036: Expected O, but got Unknown
			BossGroup.Start -= new hook_Start(OnStart);
			BossGroup.DropRewards -= new hook_DropRewards(OnDropRewards);
			BossGroup.DropRewards -= new Manipulator(IL_DropRewards);
		}

		private void OnStart(orig_Start orig, BossGroup self)
		{
			string name = ((Object)self).name;
			string text = name;
			if (1 == 0)
			{
			}
			string text2 = ((!name.StartsWith("LunarTeleporter")) ? ((!name.StartsWith("Teleporter")) ? ((!name.StartsWith("SuperRoboBallEncounter")) ? "BossGroup" : "SuperRoboBallEncounter") : "TeleporterBoss") : "TeleporterBoss");
			if (1 == 0)
			{
			}
			string objectType = text2;
			base.Plugin.HandleInstancing(((Component)self).gameObject, new InstanceInfoTracker.InstanceOverrideInfo(objectType), isObject: false);
		}

		private void OnDropRewards(orig_DropRewards orig, BossGroup self)
		{
			InstanceInfoTracker component = ((Component)self).GetComponent<InstanceInfoTracker>();
			if ((Object)(object)component == (Object)null)
			{
				orig.Invoke(self);
				return;
			}
			PickupDropletControllerHandler handler = HookManager.GetHandler<PickupDropletControllerHandler>();
			handler.InstanceOverrideInfo = component.Info;
			orig.Invoke(self);
			handler.InstanceOverrideInfo = null;
		}

		private void IL_DropRewards(ILContext il)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Expected O, but got Unknown
			//IL_005c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0068: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			int varLoopCount = -1;
			val.GotoNext((MoveType)0, new Func<Instruction, bool>[2]
			{
				(Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<PickupDropletController>(i, "CreatePickupDroplet"),
				(Instruction i) => ILPatternMatchingExt.MatchLdloc(i, ref varLoopCount)
			});
			val.Emit(OpCodes.Ldarg_0);
			val.Emit(OpCodes.Ldloc, varLoopCount);
			val.EmitDelegate<Action<BossGroup, int>>((Action<BossGroup, int>)delegate(BossGroup self, int loopCount)
			{
				if (self.scaleRewardsByPlayerCount && HookManager.GetHandler<PickupDropletControllerHandler>().InstanceOverrideInfo.HasValue)
				{
					int index = loopCount % Run.instance.participatingPlayerCount;
					PlayerCharacterMasterController owner = PlayerCharacterMasterController.instances[index];
					InstanceInfoTracker.InstanceOverrideInfo value = HookManager.GetHandler<PickupDropletControllerHandler>().InstanceOverrideInfo.Value;
					value.Owner = owner;
					HookManager.GetHandler<PickupDropletControllerHandler>().InstanceOverrideInfo = value;
				}
			});
		}
	}
	public class BossHunterHandler : AbstractHookHandler
	{
		public override void RegisterHooks()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			EquipmentSlot.FireBossHunter += new hook_FireBossHunter(OnFireBossHunter);
		}

		public override void UnregisterHooks()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			EquipmentSlot.FireBossHunter -= new hook_FireBossHunter(OnFireBossHunter);
		}

		private bool OnFireBossHunter(orig_FireBossHunter orig, EquipmentSlot self)
		{
			object obj;
			if (self == null)
			{
				obj = null;
			}
			else
			{
				CharacterBody characterBody = self.characterBody;
				if (characterBody == null)
				{
					obj = null;
				}
				else
				{
					CharacterMaster master = characterBody.master;
					obj = ((master != null) ? master.playerCharacterMasterController : null);
				}
			}
			PlayerCharacterMasterController owner = (PlayerCharacterMasterController)obj;
			PickupDropletControllerHandler handler = HookManager.GetHandler<PickupDropletControllerHandler>();
			handler.InstanceOverrideInfo = new InstanceInfoTracker.InstanceOverrideInfo("HuntersTricorn", owner);
			bool result = orig.Invoke(self);
			handler.InstanceOverrideInfo = null;
			return result;
		}
	}
	internal static class CommandCubeIL
	{
		internal static void Apply<TDelegate>(ILContext il, TDelegate onSpawned) where TDelegate : Delegate
		{
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Expected O, but got Unknown
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			Instruction[] array = ((IEnumerable<Instruction>)il.Body.Instructions).Where(IsNetworkServerSpawn).ToArray();
			if (array.Length == 1 && IsSpawnGameObjectMethod((MethodReference)/*isinst with value type is only supported in some contexts*/))
			{
				ILCursor val = new ILCursor(il);
				val.Goto(array[0], (MoveType)0, false);
				val.MoveAfterLabels();
				val.Emit(OpCodes.Dup);
				int index = val.Index;
				val.Index = index + 1;
				val.EmitDelegate<TDelegate>(onSpawned);
				return;
			}
			throw new InvalidOperationException(((MemberReference)il.Method).FullName + ": Command cube Spawn(GameObject) pattern not found.");
		}

		private static bool IsNetworkServerSpawn(Instruction i)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			if (i.OpCode != OpCodes.Call)
			{
				return false;
			}
			object operand = i.Operand;
			MethodReference val = (MethodReference)((operand is MethodReference) ? operand : null);
			if (val == null)
			{
				return false;
			}
			return ((MemberReference)((MemberReference)val).DeclaringType).FullName == "UnityEngine.Networking.NetworkServer" && ((MemberReference)val).Name == "Spawn";
		}

		private static bool IsSpawnGameObjectMethod(MethodReference method)
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0018: Invalid comparison between Unknown and I4
			return method != null && !method.HasThis && (int)method.ReturnType.MetadataType == 1 && method.Parameters.Count == 1 && ((MemberReference)((ParameterReference)method.Parameters[0]).ParameterType).FullName == "UnityEngine.GameObject";
		}
	}
	public class DitherModelHandler : AbstractHookHandler
	{
		public override void RegisterHooks()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			DitherModel.RefreshObstructorsForCamera += new Manipulator(IL_DitherModel_RefreshObstructorsForCamera);
		}

		public override void UnregisterHooks()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			DitherModel.RefreshObstructorsForCamera -= new Manipulator(IL_DitherModel_RefreshObstructorsForCamera);
		}

		private void IL_DitherModel_RefreshObstructorsForCamera(ILContext il)
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_000e: Expected O, but got Unknown
			//IL_00c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: 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_00fb: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0120: Unknown result type (might be due to invalid IL or missing references)
			//IL_012c: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Unknown result type (might be due to invalid IL or missing references)
			//IL_016c: Unknown result type (might be due to invalid IL or missing references)
			//IL_017d: 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_019e: Unknown result type (might be due to invalid IL or missing references)
			ILCursor val = new ILCursor(il);
			ILLabel val2 = il.DefineLabel();
			ILLabel val3 = il.DefineLabel();
			MethodInfo methodInfo = typeof(Component).GetMethods(BindingFlags.Instance | BindingFlags.Public).First((MethodInfo method) => method.Name == "GetComponent" && method.IsGenericMethod);
			MethodInfo methodInfo2 = methodInfo.MakeGenericMethod(typeof(FadeBehavior));
			int ditherModelLoc = -1;
			val.GotoNext((MoveType)0, new Func<Instruction, bool>[2]
			{
				(Instruction i) => ILPatternMatchingExt.MatchLdloc(i, ref ditherModelLoc),
				(Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<DitherModel>(i, "UpdateDither")
			});
			int index = val.Index;
			val.Index = index + 1;
			val.Emit(OpCodes.Dup);
			val.Emit(OpCodes.Dup);
			val.Emit(OpCodes.Call, (MethodBase)methodInfo2);
			val.Emit(OpCodes.Dup);
			val.Emit(OpCodes.Ldnull);
			val.Emit(OpCodes.Ceq);
			val.Emit(OpCodes.Brtrue, (object)val2);
			val.Emit(OpCodes.Ldarg_0);
			val.Emit<FadeBehavior>(OpCodes.Call, "GetFadeLevelForCameraRigController");
			val.Emit(OpCodes.Ldloc, ditherModelLoc);
			val.Emit<DitherModel>(OpCodes.Ldfld, "fade");
			val.Emit(OpCodes.Mul);
			val.Emit<DitherModel>(OpCodes.Stfld, "fade");
			val.Emit(OpCodes.Br, (object)val3);
			val.MarkLabel(val2);
			val.Emit(OpCodes.Pop);
			val.Emit(OpCodes.Pop);
			val.MarkLabel(val3);
		}
	}
	public class EffectManagerHandler : AbstractHookHandler
	{
		public override void RegisterHooks()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			EffectManager.SpawnEffect_EffectIndex_EffectData_bool += new Manipulator(IL_EffectManager_SpawnEffect);
		}

		public override void UnregisterHooks()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			EffectManager.SpawnEffect_EffectIndex_EffectData_bool -= new Manipulator(IL_EffectManager_SpawnEffect);
		}

		private void IL_Ef