Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Equilibrium v2.0.3
Equilibrium.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using 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.Artifacts; using Mono.Cecil.Cil; using MonoMod.Cil; using On.RoR2; using On.RoR2.Artifacts; using R2API; using R2API.Networking; using R2API.Networking.Interfaces; using R2API.Utils; using RoR2; using RoR2.Artifacts; 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("f2eff138-24ee-4741-88c1-c6ff8bf1d180")] [assembly: AssemblyFileVersion("2.0.3")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.0.3.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.0.3")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Equilibrium : BaseUnityPlugin { public HookManager HookManager; public ObjectHandlerManager ObjectHandlerManager; public static List<SyncInstances.InstanceHandlerEntry[]> FailedSyncs = new List<SyncInstances.InstanceHandlerEntry[]>(); public static ArtifactDef EquilibriumArtifactDef; private const string ArtifactLangTokenName = "EQUILIBRIUM"; private static bool _patched = false; public static bool IsCloningForInstance = false; public global::Equilibrium.Config.Config ModConfig { get; private set; } 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_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Expected O, but got Unknown //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0122: 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 ex) { Logger.LogWarning((object)$"[均衡神器] 调用 EquilibriumManager.Init() 失败:{ex}"); Logger.LogWarning((object)ex.ToString()); } 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); Application.logMessageReceived += new LogCallback(HandleLog); 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; Logger.LogInfo((object)"[均衡神器] 已禁用并注销钩子"); } public void Update() { if (Input.GetKeyDown((KeyCode)286)) { ShowPlayerListInfo(); } if (Input.GetKeyDown((KeyCode)287)) { ForceRefresh(); } } 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) { string text = "None"; List<string> list = new List<string>(); foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList) { if (Object.op_Implicit((Object)(object)readOnlyInstances)) { if (((NetworkBehaviour)readOnlyInstances).hasAuthority) { text = readOnlyInstances.userName; } else { list.Add(readOnlyInstances.userName); } } } LogInfo("Host: " + text); if (list.Count > 0) { foreach (string item in list) { LogInfo("Client: " + item); } } else { LogInfo("Client: (无)"); } } if ((Object)(object)PlayerManager.Instance != (Object)null) { LogInfo($"PlayerManager 计数: {PlayerManager.Instance.CurrentPlayerCount}人"); LogInfo($"是否多人: {PlayerManager.Instance.IsMultiplayer}"); } else { LogWarning("PlayerManager 实例不存在"); } 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 (!hashSet.Contains(instanceHandler)) { hashSet.Add(instanceHandler); instanceHandler.SyncToPlayer(player); } } foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList) { if (Object.op_Implicit((Object)(object)readOnlyInstances) && !((NetworkBehaviour)readOnlyInstances).hasAuthority) { Logger.LogInfo((object)(readOnlyInstances.userName ?? "")); } } Logger.LogInfo((object)("[均衡神器] 向新加入玩家 " + player.networkUser?.userName + " 下发实例信息")); } public void HandleInstancing(GameObject obj, InstanceInfoTracker.InstanceOverrideInfo? overrideInfo = null, bool isObject = true) { //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) 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_0162; } } if ((Object)(object)obj.GetComponent<PickupPickerController>() != (Object)null) { goto IL_0162; } goto IL_0197; IL_0162: if (!isObject) { flag3 = true; switch (mode) { case InstanceMode.InstanceObject: flag = false; break; case InstanceMode.InstanceBoth: flag = true; flag2 = true; break; } } goto IL_0197; IL_0197: 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> hashSet = ((!flag2) ? ModConfig.GetValidPlayers() : new HashSet<PlayerCharacterMasterController> { val }); if (flag3) { InstanceHandler instanceHandler = obj.AddComponent<InstanceHandler>(); instanceHandler.SharedInfo = new InstanceHandler.SharedInstanceInfo { ObjectInstanceMode = ObjectInstanceMode.InstancedObject }; instanceHandler.SetPlayers(hashSet); } else { ObjectHandlerManager.InstanceObject(text, obj, hashSet.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 arg = (((NetworkBehaviour)item).hasAuthority ? "[Host]" : "[Client]"); stringBuilder.AppendLine($"[{num}] {arg} {item.userName}"); num++; } } if (stringBuilder.Length > 0) { LogInfo(stringBuilder.ToString()); } else { LogInfo("找不到匹配 \"" + text + "\" 的玩家。"); } } catch (Exception ex) { LogError("获取玩家列表时出错: " + ex.Message); } } 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) { Logger.LogInfo((object)"[均衡神器] 嵌入资源加载失败,尝试从插件目录加载外部 AssetBundle..."); string path = Path.Combine(Paths.PluginPath, "Equilibrium", "equilibrium"); AssetBundleLoader.LoadFromFile(path); } if (AssetBundleLoader.IsLoaded) { Logger.LogInfo((object)"[均衡神器] AssetBundle 加载完成。"); } else { Logger.LogWarning((object)"[均衡神器] AssetBundle 未能加载,部分图标/资源可能不可用。"); } } 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() { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown AssetBundleLoader.Unload(); Logger.LogInfo((object)"[均衡神器] 已卸载资源(OnDestroy)"); Application.logMessageReceived -= new LogCallback(HandleLog); } private void HandleLog(string logString, string stackTrace, LogType type) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)type != 2 || (!logString.Contains("GiveItemString") && !logString.Contains("Did not find target for sync message"))) { Debug.Log((object)logString); } } } 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) { Equilibrium.LogError("[PlayerManager] 初始化失败: " + ex.Message); } } private void OnDestroy() { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Expected O, but got Unknown try { NetworkUser.onPostNetworkUserStart -= new NetworkUserGenericDelegate(OnPlayerJoined); NetworkUser.onNetworkUserLost -= new NetworkUserGenericDelegate(OnPlayerLost); SceneManager.activeSceneChanged -= OnSceneChanged; } catch { } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } ((MonoBehaviour)this).CancelInvoke("PeriodicCheck"); } private void OnPlayerJoined(NetworkUser joinedUser) { ((MonoBehaviour)this).StartCoroutine(UpdatePlayerCountDelayed(1f)); 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}"); } 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 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; private NetworkInstanceId _target; private NetworkInstanceId[] _players; private NetworkInstanceId _origPlayer; 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) 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; validated = true; } public bool TryProcess() { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0051: 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) if (validated) { return true; } target = Util.FindNetworkObject(_target); if ((Object)(object)target == (Object)null) { return false; } if (_origPlayer != NetworkInstanceId.Invalid) { origPlayer = Util.FindNetworkObject(_origPlayer); if ((Object)(object)origPlayer == (Object)null) { return false; } } players = (GameObject[])(object)new GameObject[_players.Length]; for (int i = 0; i < _players.Length; i++) { GameObject val = Util.FindNetworkObject(_players[i]); if ((Object)(object)val == (Object)null) { return false; } players[i] = val; } 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) 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); } } 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) InstanceHandlerEntry instanceHandlerEntry = default(InstanceHandlerEntry); instanceHandlerEntry.validated = false; instanceHandlerEntry._target = reader.ReadNetworkId(); instanceHandlerEntry._origPlayer = reader.ReadNetworkId(); InstanceHandlerEntry result = instanceHandlerEntry; int num = reader.ReadInt32(); result._players = (NetworkInstanceId[])(object)new NetworkInstanceId[num]; for (int i = 0; i < num; i++) { result._players[i] = reader.ReadNetworkId(); } return result; } } private NetworkInstanceId _sourceObject; private ObjectInstanceMode objectInstanceMode; private InstanceHandlerEntry[] entries; 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_001f: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active) { ((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) { if (retryCount > 40) { Equilibrium.Instance.Logger.LogError((object)"SyncInstances failed after 40 retries"); yield break; } retryCount++; validated = true; for (int i = 0; i < entries.Length; i++) { validated = validated && entries[i].TryProcess(); } if ((Object)(object)sourceObject == (Object)null && sourceId != NetworkInstanceId.Invalid) { sourceObject = Util.FindNetworkObject(sourceId); validated = validated && (Object)(object)sourceObject != (Object)null; } if (!validated) { yield return 0; } } InstanceHandler.SharedInstanceInfo sharedInfo = new InstanceHandler.SharedInstanceInfo { ObjectInstanceMode = mode, SourceObject = sourceObject }; for (int j = 0; j < entries.Length; j++) { InstanceHandlerEntry entry = entries[j]; InstanceHandler handler = entry.target.GetComponent<InstanceHandler>(); if ((Object)(object)handler == (Object)null) { handler = entry.target.AddComponent<InstanceHandler>(); } handler.SetPlayers(entry.players.Select((GameObject p) => p.GetComponent<PlayerCharacterMasterController>()), sync: false); if (Object.op_Implicit((Object)(object)entry.origPlayer)) { handler.OrigPlayer = entry.origPlayer.GetComponent<PlayerCharacterMasterController>(); } if ((Object)(object)sourceObject != (Object)null) { entry.target.transform.position = sourceObject.transform.position; entry.target.transform.rotation = sourceObject.transform.rotation; entry.target.transform.localScale = sourceObject.transform.localScale; } handler.SharedInfo = sharedInfo; } sharedInfo.RecalculateAllPlayers(); foreach (InstanceHandler handler2 in from e in entries select e.target.GetComponent<InstanceHandler>() into h where (Object)(object)h != (Object)null select h) { handler2.UpdateVisuals(); } } } } namespace Equilibrium.Hooks { 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; } } 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 GenericPickupControllerHandler : AbstractHookHandler { private delegate void CreatePickupDelegate(GameObject gameObject, ref CreatePickupInfo createPickupInfo); public InstanceInfoTracker.InstanceOverrideInfo? InstanceOverrideInfo; 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 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown GenericPickupController.Start += new hook_Start(OnStart); GenericPickupController.GetInteractability += new hook_GetInteractability(OnGetInteractability); GenericPickupController.OnTriggerStay += new hook_OnTriggerStay(OnTriggerStay); GenericPickupController.AttemptGrant += new Manipulator(IL_AttemptGrant); GenericPickupController.CreatePickup += new Manipulator(IL_CreatePickup); } 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 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown GenericPickupController.Start -= new hook_Start(OnStart); GenericPickupController.GetInteractability -= new hook_GetInteractability(OnGetInteractability); GenericPickupController.OnTriggerStay -= new hook_OnTriggerStay(OnTriggerStay); GenericPickupController.AttemptGrant -= new Manipulator(IL_AttemptGrant); GenericPickupController.CreatePickup -= new Manipulator(IL_CreatePickup); } private void OnStart(orig_Start orig, GenericPickupController self) { if (NetworkServer.active) { base.Plugin.HandleInstancing(((Component)self).gameObject, null, isObject: false); } orig.Invoke(self); } private Interactability OnGetInteractability(orig_GetInteractability orig, GenericPickupController self, Interactor activator) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0064: 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) //IL_0061: Unknown result type (might be due to invalid IL or missing references) Interactability result = orig.Invoke(self, activator); CharacterBody component = ((Component)activator).GetComponent<CharacterBody>(); object obj; if (component == null) { obj = null; } else { CharacterMaster master = component.master; obj = ((master != null) ? master.playerCharacterMasterController : null); } PlayerCharacterMasterController val = (PlayerCharacterMasterController)obj; if (Object.op_Implicit((Object)(object)val)) { InstanceHandler component2 = ((Component)self).GetComponent<InstanceHandler>(); if ((Object)(object)component2 != (Object)null && !component2.Players.Contains(val)) { result = (Interactability)0; } } return result; } private void OnTriggerStay(orig_OnTriggerStay orig, GenericPickupController self, Collider other) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Invalid comparison between Unknown and I4 Interactor component = ((Component)other).GetComponent<Interactor>(); if (!((Object)(object)component != (Object)null) || (int)self.GetInteractability(component) == 2) { orig.Invoke(self, other); } } private void IL_AttemptGrant(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); val.GotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchLdfld<GrantContext>(i, "shouldDestroy") }); val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldarg_1); val.EmitDelegate<Func<bool, GenericPickupController, CharacterBody, bool>>((Func<bool, GenericPickupController, CharacterBody, bool>)delegate(bool shouldDestroy, GenericPickupController self, CharacterBody body) { CharacterMaster master = body.master; PlayerCharacterMasterController val2 = ((master != null) ? master.playerCharacterMasterController : null); InstanceHandler component = ((Component)self).GetComponent<InstanceHandler>(); if ((Object)(object)val2 != (Object)null && (Object)(object)component != (Object)null) { component.RemovePlayer(val2); if (component.AllPlayers.Count > 0) { shouldDestroy = false; } } return shouldDestroy; }); } private void IL_CreatePickup(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); val.GotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<Object>(i, "Instantiate") }); val.Emit(OpCodes.Dup); val.Emit(OpCodes.Ldarg_0); val.EmitDelegate<CreatePickupDelegate>((CreatePickupDelegate)delegate(GameObject obj, ref CreatePickupInfo info) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) InstanceOverrideInfo?.AttachTo(obj); if ((Object)(object)obj != (Object)null) { CreatePickupInfoTracker createPickupInfoTracker = obj.AddComponent<CreatePickupInfoTracker>(); createPickupInfoTracker.CreatePickupInfo = info; } }); } } public class MultiShopControllerHandler : 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 MultiShopController.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 MultiShopController.Start -= new hook_Start(OnStart); } private void OnStart(orig_Start orig, MultiShopController 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("TripleShopLarge")) ? ((!name.StartsWith("TripleShopEquipment")) ? ((!name.StartsWith("TripleShop")) ? ((!name.StartsWith("FreeChestMultiShop")) ? null : "FreeChestMultiShop") : "TripleShop") : "TripleShopEquipment") : "TripleShopLarge"); if (1 == 0) { } string text3 = text2; if (text3 != null) { base.Plugin.HandleInstancing(((Component)self).gameObject, new InstanceInfoTracker.InstanceOverrideInfo(text3)); } } } } public class OptionChestBehaviorHandler : 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 OptionChestBehavior.ItemDrop += new hook_ItemDrop(OnItemDrop); OptionChestBehavior.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 OptionChestBehavior.ItemDrop -= new hook_ItemDrop(OnItemDrop); OptionChestBehavior.Start -= new hook_Start(OnStart); } private void OnItemDrop(orig_ItemDrop orig, OptionChestBehavior 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, OptionChestBehavior 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 = null; if (name.StartsWith("LockboxVoid")) { text = "LockboxVoid"; } if (name.StartsWith("VoidTriple")) { text = "VoidTriple"; } if (text != null) { base.Plugin.HandleInstancing(((Component)self).gameObject, new InstanceInfoTracker.InstanceOverrideInfo(text)); } } } } public class PickupDropletControllerHandler : AbstractHookHandler { public InstanceInfoTracker.InstanceOverrideInfo? InstanceOverrideInfo; 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 PickupDropletController.CreatePickupDroplet_CreatePickupInfo_Vector3_Vector3 += new Manipulator(IL_CreatePickupDroplet); PickupDropletController.OnCollisionEnter += new hook_OnCollisionEnter(OnCollisionEnter); PickupDropletController.CreateCommandCube += new Manipulator(IL_CreateCommandCube); } 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 PickupDropletController.CreatePickupDroplet_CreatePickupInfo_Vector3_Vector3 -= new Manipulator(IL_CreatePickupDroplet); PickupDropletController.OnCollisionEnter -= new hook_OnCollisionEnter(OnCollisionEnter); PickupDropletController.CreateCommandCube -= new Manipulator(IL_CreateCommandCube); } private void IL_CreatePickupDroplet(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); val.GotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchCall<Object>(i, "Instantiate") }); val.Emit(OpCodes.Dup); val.EmitDelegate<Action<GameObject>>((Action<GameObject>)delegate(GameObject obj) { if (InstanceOverrideInfo.HasValue) { base.Plugin.HandleInstancing(obj, InstanceOverrideInfo, isObject: false); } }); } private void OnCollisionEnter(orig_OnCollisionEnter orig, PickupDropletController self, Collision collision) { InstanceInfoTracker component = ((Component)self).GetComponent<InstanceInfoTracker>(); if ((Object)(object)component != (Object)null) { GenericPickupControllerHandler handler = HookManager.GetHandler<GenericPickupControllerHandler>(); handler.InstanceOverrideInfo = component.Info; orig.Invoke(self, collision); handler.InstanceOverrideInfo = null; } else { orig.Invoke(self, collision); } } private void IL_CreateCommandCube(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); val.GotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<NetworkServer>(i, "Spawn") }); val.Emit(OpCodes.Dup); int index = val.Index; val.Index = index + 1; val.EmitDelegate<Action<GameObject>>((Action<GameObject>)delegate(GameObject gameObject) { GenericPickupControllerHandler handler = HookManager.GetHandler<GenericPickupControllerHandler>(); if (handler.InstanceOverrideInfo.HasValue) { base.Plugin.HandleInstancing(gameObject, handler.InstanceOverrideInfo.Value, isObject: false); } }); } } public class PickupPickerControllerHandler : 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 PickupPickerController.Awake += new hook_Awake(On_PickupPickerController_Awake); PickupPickerController.GetInteractability += new hook_GetInteractability(On_PickupPickerController_GetInteractability); PickupPickerController.CreatePickup_PickupIndex += new hook_CreatePickup_PickupIndex(On_PickupPickerController_CreatePickup_PickupIndex); } 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 PickupPickerController.Awake -= new hook_Awake(On_PickupPickerController_Awake); PickupPickerController.GetInteractability -= new hook_GetInteractability(On_PickupPickerController_GetInteractability); PickupPickerController.CreatePickup_PickupIndex -= new hook_CreatePickup_PickupIndex(On_PickupPickerController_CreatePickup_PickupIndex); } private UnityAction<int> GenerateHandleDestroy(PickupPickerController self) { return HandleDestroy; void HandleDestroy(int pickupIndex) { InstanceHandler component = ((Component)self).GetComponent<InstanceHandler>(); if (!((Object)(object)component != (Object)null) || component.Players.Count <= 0) { Object.Destroy((Object)(object)((Component)self).gameObject); } } } private void On_PickupPickerController_Awake(orig_Awake orig, PickupPickerController self) { orig.Invoke(self); if (!NetworkServer.active) { return; } ((MonoBehaviour)self).StartCoroutine(Coroutine()); PickupIndexUnityEvent onPickupSelected = self.onPickupSelected; int persistentEventCount = ((UnityEventBase)onPickupSelected).GetPersistentEventCount(); bool flag = false; for (int i = 0; i < persistentEventCount; i++) { if (((UnityEventBase)onPickupSelected).GetPersistentTarget(i) is EventFunctions && ((UnityEventBase)onPickupSelected).GetPersistentMethodName(i) == "DestroySelf") { ((UnityEventBase)onPickupSelected).SetPersistentListenerState(i, (UnityEventCallState)0); flag = true; break; } } if (flag) { ((UnityEvent<int>)(object)onPickupSelected).AddListener(GenerateHandleDestroy(self)); } IEnumerator Coroutine() { yield return 0; base.Plugin.HandleInstancing(((Component)self).gameObject, null, isObject: false); } } private Interactability On_PickupPickerController_GetInteractability(orig_GetInteractability orig, PickupPickerController self, Interactor activator) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0064: 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) //IL_0061: Unknown result type (might be due to invalid IL or missing references) Interactability result = orig.Invoke(self, activator); CharacterBody component = ((Component)activator).GetComponent<CharacterBody>(); object obj; if (component == null) { obj = null; } else { CharacterMaster master = component.master; obj = ((master != null) ? master.playerCharacterMasterController : null); } PlayerCharacterMasterController val = (PlayerCharacterMasterController)obj; if (Object.op_Implicit((Object)(object)val)) { InstanceHandler component2 = ((Component)self).GetComponent<InstanceHandler>(); if ((Object)(object)component2 != (Object)null && !component2.Players.Contains(val)) { result = (Interactability)0; } } return result; } private void On_PickupPickerController_CreatePickup_PickupIndex(orig_CreatePickup_PickupIndex orig, PickupPickerController self, PickupIndex pickupindex) { //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) InstanceHandler component = ((Component)self).GetComponent<InstanceHandler>(); InstanceInfoTracker component2 = ((Component)self).GetComponent<InstanceInfoTracker>(); if (NetworkServer.active && (Object)(object)component != (Object)null && (Object)(object)component2 != (Object)null) { CharacterMaster currentParticipantMaster = self.networkUIPromptController.currentParticipantMaster; if ((Object)(object)currentParticipantMaster == (Object)null) { return; } PlayerCharacterMasterController playerCharacterMasterController = currentParticipantMaster.playerCharacterMasterController; if (!((Object)(object)playerCharacterMasterController == (Object)null) && component.Players.Contains(playerCharacterMasterController)) { InstanceInfoTracker.InstanceOverrideInfo info = component2.Info; info.PlayerOverride = (PlayerCharacterMasterController[])(object)new PlayerCharacterMasterController[1] { playerCharacterMasterController }; component.RemovePlayer(playerCharacterMasterController); GenericPickupControllerHandler handler = HookManager.GetHandler<GenericPickupControllerHandler>(); handler.InstanceOverrideInfo = info; orig.Invoke(self, pickupindex); handler.InstanceOverrideInfo = null; if ((Object)(object)self.networkUIPromptController != (Object)null) { self.networkUIPromptController.ClearParticipant(); } } } else if ((Object)(object)component2 != (Object)null) { GenericPickupControllerHandler handler2 = HookManager.GetHandler<GenericPickupControllerHandler>(); handler2.InstanceOverrideInfo = component2.Info; orig.Invoke(self, pickupindex); handler2.InstanceOverrideInfo = null; } else { orig.Invoke(self, pickupindex); } } } public class PurchaseInteractionHandler : 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 PurchaseInteraction.GetInteractability += new hook_GetInteractability(OnGetInteractability); PurchaseInteraction.OnInteractionBegin += new hook_OnInteractionBegin(OnInteractionBegin); } 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 PurchaseInteraction.GetInteractability -= new hook_GetInteractability(OnGetInteractability); PurchaseInteraction.OnInteractionBegin -= new hook_OnInteractionBegin(OnInteractionBegin); } private Interactability OnGetInteractability(orig_GetInteractability orig, PurchaseInteraction self, Interactor activator) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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_0064: 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) //IL_0061: Unknown result type (might be due to invalid IL or missing references) Interactability result = orig.Invoke(self, activator); CharacterBody component = ((Component)activator).GetComponent<CharacterBody>(); object obj; if (component == null) { obj = null; } else { CharacterMaster master = component.master; obj = ((master != null) ? master.playerCharacterMasterController : null); } PlayerCharacterMasterController val = (PlayerCharacterMasterController)obj; if (Object.op_Implicit((Object)(object)val)) { InstanceHandler component2 = ((Component)self).GetComponent<InstanceHandler>(); if ((Object)(object)component2 != (Object)null && !component2.Players.Contains(val)) { result = (Interactability)0; } } return result; } private void OnInteractionBegin(orig_OnInteractionBegin orig, PurchaseInteraction self, Interactor activator) { CharacterBody component = ((Component)activator).GetComponent<CharacterBody>(); object obj; if (component == null) { obj = null; } else { CharacterMaster master = component.master; obj = ((master != null) ? master.playerCharacterMasterController : null); } PlayerCharacterMasterController val = (PlayerCharacterMasterController)obj; if (Object.op_Implicit((Object)(object)val)) { InstanceInfoTracker.InstanceOverrideInfo.SetOwner(((Component)self).gameObject, val); } orig.Invoke(self, activator); } } public class SacrificeArtifactManagerHandler : 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 SacrificeArtifactManager.OnServerCharacterDeath += new hook_OnServerCharacterDeath(OnDeath); SacrificeArtifactManager.OnServerCharacterDeath += new Manipulator(IL_OnDeath); } 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 SacrificeArtifactManager.OnServerCharacterDeath -= new hook_OnServerCharacterDeath(OnDeath); SacrificeArtifactManager.OnServerCharacterDeath -= new Manipulator(IL_OnDeath); } private void OnDeath(orig_OnServerCharacterDeath orig, DamageReport report) { CharacterMaster val = report.attackerOwnerMaster ?? report.attackerMaster; PlayerCharacterMasterController owner = ((val != null) ? val.playerCharacterMasterController : null); PickupDropletControllerHandler handler = HookManager.GetHandler<PickupDropletControllerHandler>(); handler.InstanceOverrideInfo = new InstanceInfoTracker.InstanceOverrideInfo("Sacrifice", owner); orig.Invoke(report); handler.InstanceOverrideInfo = null; } private void IL_OnDeath(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown ILCursor val = new ILCursor(il); val.GotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt(i, typeof(Util), "GetExpAdjustedDropChancePercent") }); val.EmitDelegate<Func<float, float>>((Func<float, float>)((float chance) => chance)); } } public class ScavBackpackOpeningHandler : 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 Opening.OnEnter += new Manipulator(IL_OnEnter); } 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 Opening.OnEnter -= new Manipulator(IL_OnEnter); } private void IL_OnEnter(ILContext il) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown ILCursor val = new ILCursor(il); val.GotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchLdsfld<Opening>(i, "maxItemDropCount") }); val.EmitDelegate<Func<int, int>>((Func<int, int>)((int count) => count)); } } public class ShrineBehaviorHandler : 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 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown ShrineChanceBehavior.AddShrineStack += new hook_AddShrineStack(OnChanceStack); ShrineChanceBehavior.Start += new hook_Start(OnChanceStart); ShrineBloodBehavior.Start += new hook_Start(OnBloodStart); ShrineRestackBehavior.Start += new hook_Start(OnRestackStart); } 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 //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown ShrineChanceBehavior.AddShrineStack -= new hook_AddShrineStack(OnChanceStack); ShrineChanceBehavior.Start -= new hook_Start(OnChanceStart); ShrineBloodBehavior.Start -= new hook_Start(OnBloodStart); ShrineRestackBehavior.Start -= new hook_Start(OnRestackStart); } private void OnChanceStack(orig_AddShrineStack orig, ShrineChanceBehavior self, Interactor activator) { InstanceInfoTracker component = ((Component)self).GetComponent<InstanceInfoTracker>(); if ((Object)(object)component != (Object)null) { HookManager.GetHandler<PickupDropletControllerHandler>().InstanceOverrideInfo = component.Info; orig.Invoke(self, activator); HookManager.GetHandler<PickupDropletControllerHandler>().InstanceOverrideInfo = null; } else { orig.Invoke(self, activator); } } private void OnChanceStart(orig_Start orig, ShrineChanceBehavior 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); if (((Object)self).name.StartsWith("ShrineChance")) { base.Plugin.HandleInstancing(((Component)self).gameObject, new InstanceInfoTracker.InstanceOverrideInfo("ShrineChance")); } } } private void OnBloodStart(orig_Start orig, ShrineBloodBehavior 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); if (((Object)self).name.StartsWith("ShrineBlood")) { base.Plugin.HandleInstancing(((Component)self).gameObject, new InstanceInfoTracker.InstanceOverrideInfo("ShrineBlood")); } } } private void OnRestackStart(orig_Start orig, ShrineRestackBehavior 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); if (((Object)self).name.StartsWith("ShrineRestack")) { base.Plugin.HandleInstancing(((Component)self).gameObject, new InstanceInfoTracker.InstanceOverrideInfo("ShrineRestack")); } } } } public class SpawnCardHandler : 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 SpawnCard.DoSpawn += new hook_DoSpawn(OnDoSpawn); } 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 SpawnCard.DoSpawn -= new hook_DoSpawn(OnDoSpawn); } private SpawnResult OnDoSpawn(orig_DoSpawn orig, SpawnCard self, Vector3 position, Quaternion rotation, DirectorSpawnRequest spawnRequest) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) SpawnResult val = orig.Invoke(self, position, rotation, spawnRequest); if ((Object)(object)val.spawnedInstance != (Object)null) { SpawnCardTracker spawnCardTracker = val.spawnedInstance.AddComponent<SpawnCardTracker>(); spawnCardTracker.SpawnCard = self; } return val; } } } 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_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Expected O, but got Unknown //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Expected O, but got Unknown //IL_0081: 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_0093: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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) 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("(Cloned)", ""); SpawnCardsForPrefabName.TryGetValue(key, out value); } if ((Object)(object)value != (Object)null) { DirectorSpawnRequest val = new DirectorSpawnRequest(value, (DirectorPlacementRule)null, new Xoroshiro128Plus(0uL)); GameObject val2 = null; try { Equilibrium.IsCloningForInstance = true; SpawnResult val3 = value.DoSpawn(gameObject.transform.position, gameObject.transform.rotation, val); val2 = val3.spawnedInstance; if ((Object)(object)val2 != (Object)null) { val2.transform.position = gameObject.transform.position; val2.transform.rotation = gameObject.transform.rotation; val2.transform.localScale = gameObject.transform.localScale; } } finally { Equilibrium.IsCloningForInstance = false; } return val2; } Plugin.Logger.LogError((object)$"未找到 SpawnCard,用于复制对象 {gameObject}(objectType={objectType})"); return null; } public virtual InstanceHandler InstanceSingleObjectFrom(GameObject source, GameObject target, PlayerCharacterMasterController[] players) { 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; } } 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>(); } 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> Handler