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 InstancedLoot continuation v2.0.0
InstancedLoot\InstancedLoot.dll
Decompiled 3 weeks agousing System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using IL.RoR2; using IL.RoR2.Hologram; using InstancedLoot.Components; using InstancedLoot.Configuration; using InstancedLoot.Enums; using InstancedLoot.Hooks; using InstancedLoot.Networking; using InstancedLoot.ObjectInstancing; using Microsoft.CodeAnalysis; using Mono.Cecil; using Mono.Cecil.Cil; using MonoMod.Cil; using On.RoR2; using On.RoR2.Hologram; using R2API.Networking; using R2API.Networking.Interfaces; using R2API.Utils; using RoR2; using RoR2.Hologram; using RoR2.UI; using UnityEngine; using UnityEngine.Networking; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("KubeRoot")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("2.0.0.0")] [assembly: AssemblyInformationalVersion("2.0.0+c17cf1db15c8bfa52dd267983168225cc3dd2165")] [assembly: AssemblyProduct("InstancedLoot")] [assembly: AssemblyTitle("InstancedLoot")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace InstancedLoot { [BepInPlugin("com.kuberoot.instancedloot", "InstancedLoot", "2.0.0")] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class InstancedLoot : BaseUnityPlugin { private float nextResend; public static InstancedLoot Instance { get; private set; } internal ManualLogSource _logger => ((BaseUnityPlugin)this).Logger; public Config ModConfig { get; private set; } public HookManager HookManager { get; private set; } public ObjectInstanceService Objects { get; private set; } public void Awake() { ModConfig = new Config(this, ((BaseUnityPlugin)this).Logger); ModConfig.Init(); Objects = new ObjectInstanceService(this); HookManager = new HookManager(this); NetworkingAPI.RegisterMessageType<OwnerSnapshot>(); } public void OnEnable() { Instance = this; HookManager.RegisterHooks(); SceneManager.activeSceneChanged += SceneChanged; PlayerCharacterMasterController.onPlayerAdded += PlayerAdded; } public void OnDisable() { SceneManager.activeSceneChanged -= SceneChanged; PlayerCharacterMasterController.onPlayerAdded -= PlayerAdded; HookManager.UnregisterHooks(); Clear(); InstancedLootBehaviour[] array = Object.FindObjectsOfType<InstancedLootBehaviour>(); for (int i = 0; i < array.Length; i++) { Object.Destroy((Object)(object)array[i]); } Instance = null; } private void Clear() { Objects.Clear(); OwnerSnapshot.Clear(); } private void SceneChanged(Scene previous, Scene current) { Objects.Clear(); OwnerSnapshot.SceneChanged(); } private void PlayerAdded(PlayerCharacterMasterController player) { Resend(); } private void Resend() { if (!NetworkServer.active || !Object.op_Implicit((Object)(object)Run.instance)) { return; } foreach (InstanceHandler instance in InstanceHandler.Instances) { if (Object.op_Implicit((Object)(object)instance) && Object.op_Implicit((Object)(object)instance.Owner)) { new OwnerSnapshot(instance).SendToAll(); } } } public void Update() { Objects.Pump(); OwnerSnapshot.Pump(); if (Time.unscaledTime >= nextResend) { nextResend = Time.unscaledTime + 2f; Resend(); } } } public static class Utils { public static bool IsObjectInteractibleForPlayer(GameObject target, PlayerCharacterMasterController player) { if (!Object.op_Implicit((Object)(object)target) || !Object.op_Implicit((Object)(object)player)) { return true; } if (PendingOwnership.IsPending(target)) { return false; } InstanceHandler component = target.GetComponent<InstanceHandler>(); if (!Object.op_Implicit((Object)(object)component)) { return true; } return component.LinkedHandlers.Where((InstanceHandler handler) => handler.IsInstancedFor(player)).Any(delegate(InstanceHandler handler) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 PurchaseInteraction component2 = ((Component)handler).GetComponent<PurchaseInteraction>(); Interactor val = (Object.op_Implicit((Object)(object)player.body) ? ((Component)player.body).GetComponent<Interactor>() : null); return !Object.op_Implicit((Object)(object)component2) || !Object.op_Implicit((Object)(object)val) || (int)component2.GetInteractability(val) > 0; }); } public static bool IsObjectInstanceInteractibleForPlayer(GameObject target, PlayerCharacterMasterController player) { if (PendingOwnership.IsPending(target)) { return false; } InstanceHandler instanceHandler = (Object.op_Implicit((Object)(object)target) ? target.GetComponent<InstanceHandler>() : null); if (Object.op_Implicit((Object)(object)instanceHandler)) { return instanceHandler.IsInstancedFor(player); } return true; } private static PlayerCharacterMasterController CameraPlayer(CameraRigController camera) { CharacterBody val = (Object.op_Implicit((Object)(object)camera) ? camera.targetBody : null); if (!Object.op_Implicit((Object)(object)val) || !Object.op_Implicit((Object)(object)val.master)) { return null; } return val.master.playerCharacterMasterController; } public static bool IsObjectInteractibleForCameraRigController(GameObject target, CameraRigController camera) { return IsObjectInteractibleForPlayer(target, CameraPlayer(camera)); } public static bool IsObjectInstanceInteractibleForCameraRigController(GameObject target, CameraRigController camera) { if (Object.op_Implicit((Object)(object)CameraPlayer(camera))) { return IsObjectInstanceInteractibleForPlayer(target, CameraPlayer(camera)); } return true; } } } namespace InstancedLoot.ObjectInstancing { public static class NativeAdapters { public sealed class Chest : ObjectAdapter { public override Action<GameObject> CaptureState(GameObject source) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) Action<GameObject> purchase = base.CaptureState(source); ChestBehavior component = source.GetComponent<ChestBehavior>(); Xoroshiro128Plus rng = new Xoroshiro128Plus(component.rng); UniquePickup pickup = component.currentPickup; int count = component.dropCount; return delegate(GameObject target) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) purchase(target); ChestBehavior component2 = target.GetComponent<ChestBehavior>(); component2.rng = new Xoroshiro128Plus(rng); component2.currentPickup = pickup; component2.dropCount = count; }; } } public sealed class OptionChest : ObjectAdapter { public override Action<GameObject> CaptureState(GameObject source) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Expected O, but got Unknown Action<GameObject> purchase = base.CaptureState(source); OptionChestBehavior component = source.GetComponent<OptionChestBehavior>(); Xoroshiro128Plus rng = new Xoroshiro128Plus(component.rng); UniquePickup[] pickups = component.generatedPickups.ToArray(); return delegate(GameObject target) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown purchase(target); OptionChestBehavior component2 = target.GetComponent<OptionChestBehavior>(); component2.rng = new Xoroshiro128Plus(rng); component2.generatedPickups = pickups.ToList(); }; } } public sealed class Roulette : ObjectAdapter { public override Action<GameObject> CaptureState(GameObject source) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Expected O, but got Unknown Action<GameObject> purchase = base.CaptureState(source); Xoroshiro128Plus rng = new Xoroshiro128Plus(source.GetComponent<RouletteChestController>().rng); return delegate(GameObject target) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown purchase(target); target.GetComponent<RouletteChestController>().rng = new Xoroshiro128Plus(rng); }; } } public sealed class MultiShop : ObjectAdapter { public override bool IsReady(GameObject source) { return source.GetComponent<MultiShopController>().terminalGameObjects.All((GameObject terminal) => Object.op_Implicit((Object)(object)terminal) && terminal.GetComponent<ShopTerminalBehavior>().hasStarted); } public override IEnumerable<GameObject> OwnedObjects(GameObject root) { yield return root; GameObject[] terminalGameObjects = root.GetComponent<MultiShopController>().terminalGameObjects; for (int i = 0; i < terminalGameObjects.Length; i++) { yield return terminalGameObjects[i]; } } public override Action<GameObject> CaptureState(GameObject source) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown MultiShopController component = source.GetComponent<MultiShopController>(); int cost = component.Networkcost; bool available = component.Networkavailable; Xoroshiro128Plus rng = new Xoroshiro128Plus(component.rng); Action<GameObject>[] terminals = ((IEnumerable<GameObject>)component.terminalGameObjects).Select((Func<GameObject, Action<GameObject>>)delegate(GameObject terminal) { //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0025: 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) Action<GameObject> purchase = base.CaptureState(terminal); ShopTerminalBehavior component2 = terminal.GetComponent<ShopTerminalBehavior>(); UniquePickup pickup = component2.Networkpickup; bool hidden = component2.Networkhidden; Xoroshiro128Plus terminalRng = ((component2.rng == null) ? ((Xoroshiro128Plus)null) : new Xoroshiro128Plus(component2.rng)); return delegate(GameObject target) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown purchase(target); ShopTerminalBehavior component3 = target.GetComponent<ShopTerminalBehavior>(); component3.hasStarted = true; if (terminalRng != null) { component3.rng = new Xoroshiro128Plus(terminalRng); } component3.Networkpickup = pickup; component3.Networkhidden = hidden; component3.UpdatePickupDisplayAndAnimations(); }; }).ToArray(); return delegate(GameObject target) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected O, but got Unknown MultiShopController component2 = target.GetComponent<MultiShopController>(); if (component2.terminalGameObjects.Length != terminals.Length) { throw new InvalidOperationException("MultiShop terminal count differs from the initialized source."); } component2.Networkcost = cost; component2.Networkavailable = available; component2.rng = new Xoroshiro128Plus(rng); for (int i = 0; i < terminals.Length; i++) { terminals[i](component2.terminalGameObjects[i]); } }; } } public sealed class Shrine : ObjectAdapter { public override Action<GameObject> CaptureState(GameObject source) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) Action<GameObject> purchase = base.CaptureState(source); ShrineChanceBehavior component = source.GetComponent<ShrineChanceBehavior>(); ShrineRestackBehavior component2 = source.GetComponent<ShrineRestackBehavior>(); Xoroshiro128Plus rng = ((!Object.op_Implicit((Object)(object)component)) ? ((!Object.op_Implicit((Object)(object)component2)) ? ((Xoroshiro128Plus)null) : new Xoroshiro128Plus(component2.rng)) : new Xoroshiro128Plus(component.rng)); return delegate(GameObject target) { //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown purchase(target); PurchaseInteraction component3 = target.GetComponent<PurchaseInteraction>(); ShrineChanceBehavior component4 = target.GetComponent<ShrineChanceBehavior>(); ShrineRestackBehavior component5 = target.GetComponent<ShrineRestackBehavior>(); ShrineBloodBehavior component6 = target.GetComponent<ShrineBloodBehavior>(); if (Object.op_Implicit((Object)(object)component4)) { component4.purchaseInteraction = component3; component4.rng = new Xoroshiro128Plus(rng); } if (Object.op_Implicit((Object)(object)component5)) { component5.purchaseInteraction = component3; component5.rng = new Xoroshiro128Plus(rng); } if (Object.op_Implicit((Object)(object)component6)) { component6.purchaseInteraction = component3; } }; } } public sealed class Repair : ObjectAdapter { public override Action<GameObject> CaptureState(GameObject source) { Action<GameObject> purchase = base.CaptureState(source); SummonMasterBehavior component = source.GetComponent<SummonMasterBehavior>(); GameObject master = component.masterPrefab; int upgrades = component.droneUpgradeCount; bool destroy = component.destroyAfterSummoning; return delegate(GameObject target) { purchase(target); SummonMasterBehavior component2 = target.GetComponent<SummonMasterBehavior>(); component2.masterPrefab = master; component2.NetworkdroneUpgradeCount = upgrades; component2.destroyAfterSummoning = destroy; }; } } public static readonly string[] ChestTypes = new string[15] { "Chest1", "Chest2", "GoldChest", "Chest1StealthedVariant", "CategoryChestDamage", "CategoryChestHealing", "CategoryChestUtility", "CategoryChest2Damage", "CategoryChest2Healing", "CategoryChest2Utility", "EquipmentBarrel", "LunarChest", "VoidChest", "Lockbox", "ScavBackpack" }; public static readonly string[] ObjectTypes = ChestTypes.Concat(new string[11] { "VoidTriple", "LockboxVoid", "CasinoChest", "TripleShop", "TripleShopEquipment", "FreeChestMultiShop", "ShrineChance", "ShrineBlood", "ShrineRestack", "Drone", "Turret" }).ToArray(); public static string Identify(GameObject target, IEnumerable<string> types) { return types.FirstOrDefault((string type) => string.Equals(((Object)target).name.Replace("(Clone)", "").Trim(), type, StringComparison.Ordinal)); } } public abstract class ObjectAdapter { public virtual bool IsReady(GameObject source) { return true; } public virtual IEnumerable<GameObject> OwnedObjects(GameObject root) { yield return root; } public virtual Action<GameObject> CaptureState(GameObject source) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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) PurchaseInteraction component = source.GetComponent<PurchaseInteraction>(); if (!Object.op_Implicit((Object)(object)component)) { return delegate { }; } CostTypeIndex costType = component.costType; int cost = component.cost; bool available = component.available; Xoroshiro128Plus rng = ((component.rng == null) ? ((Xoroshiro128Plus)null) : new Xoroshiro128Plus(component.rng)); return delegate(GameObject target) { //IL_001c: 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_0057: Expected O, but got Unknown PurchaseInteraction component2 = target.GetComponent<PurchaseInteraction>(); if (!Object.op_Implicit((Object)(object)component2)) { throw new InvalidOperationException("Copy is missing PurchaseInteraction."); } component2.NetworkcostType = costType; component2.Networkcost = cost; component2.Networkavailable = available; if (rng != null) { component2.rng = new Xoroshiro128Plus(rng); } }; } } public sealed class ObjectInstanceService { private sealed class PendingCopy { public Action<GameObject> ApplyState; public ObjectAdapter Adapter; public PlayerCharacterMasterController Owner; public int Group; public GameObject[] OwnedObjects; } private readonly InstancedLoot plugin; private readonly Dictionary<GameObject, PendingCopy> pending = new Dictionary<GameObject, PendingCopy>(); private readonly HashSet<GameObject> initialized = new HashSet<GameObject>(); private readonly List<(ObjectAdapter adapter, GameObject source, string type)> sources = new List<(ObjectAdapter, GameObject, string)>(); private readonly HashSet<GameObject> pendingChildren = new HashSet<GameObject>(); private Run run; private int nextGroup; public ObjectInstanceService(InstancedLoot plugin) { this.plugin = plugin; } public bool InitializeCopy(GameObject target) { CheckRun(); if (!NetworkServer.active || !pending.TryGetValue(target, out var value)) { return false; } try { if (!Object.op_Implicit((Object)(object)value.Owner)) { throw new InvalidOperationException("Copy owner has left."); } value.ApplyState(target); AssignTree(value.Adapter, target, value.Owner, value.Group); } catch (Exception arg) { plugin._logger.LogError((object)$"Copy initialization failed for {((Object)target).name}: {arg}"); DestroyCopy(value); } finally { pending.Remove(target); GameObject[] ownedObjects = value.OwnedObjects; foreach (GameObject item in ownedObjects) { pendingChildren.Remove(item); } } return true; } public bool IsPendingChild(GameObject target) { return pendingChildren.Contains(target); } private void CheckRun() { if (!((Object)(object)run == (Object)(object)Run.instance)) { Clear(); run = Run.instance; OwnerSnapshot.RunChanged(); } } public void InitializeSource(ObjectAdapter adapter, GameObject source, string objectType) { CheckRun(); if (!NetworkServer.active || !Object.op_Implicit((Object)(object)source) || !initialized.Add(source) || !plugin.ModConfig.IsEnabled(objectType)) { return; } foreach (GameObject item in adapter.OwnedObjects(source)) { PendingOwnership.Mark(item); } sources.Add((adapter, source, objectType)); } public void Pump() { CheckRun(); if (!NetworkServer.active) { return; } (ObjectAdapter, GameObject, string)[] array = sources.ToArray(); for (int i = 0; i < array.Length; i++) { (ObjectAdapter, GameObject, string) item = array[i]; if (!Object.op_Implicit((Object)(object)item.Item2)) { sources.Remove(item); } else if (item.Item1.IsReady(item.Item2)) { sources.Remove(item); try { CreateCopies(item.Item1, item.Item2); } catch (Exception arg) { ResolveTree(item.Item1, item.Item2); plugin._logger.LogError((object)$"Object instancing failed for {((Object)item.Item2).name}: {arg}"); } } } } private void CreateCopies(ObjectAdapter adapter, GameObject source) { PlayerCharacterMasterController[] array = PlayerCharacterMasterController.instances.Where((PlayerCharacterMasterController player) => Object.op_Implicit((Object)(object)player)).ToArray(); if (array.Length == 0) { ResolveTree(adapter, source); return; } int num = ++nextGroup; Action<GameObject> applyState = adapter.CaptureState(source); List<GameObject> list = new List<GameObject>(); try { for (int num2 = 1; num2 < array.Length; num2++) { GameObject val = SpawnCopy(source); if (!Object.op_Implicit((Object)(object)val)) { throw new InvalidOperationException("SpawnCard did not create all player copies; keeping the source vanilla."); } list.Add(val); GameObject[] array2 = adapter.OwnedObjects(val).ToArray(); pending.Add(val, new PendingCopy { ApplyState = applyState, Adapter = adapter, Owner = array[num2], Group = num, OwnedObjects = array2 }); GameObject[] array3 = array2; foreach (GameObject val2 in array3) { PendingOwnership.Mark(val2); if ((Object)(object)val2 != (Object)(object)val) { pendingChildren.Add(val2); } } } AssignTree(adapter, source, array[0], num); } catch { foreach (GameObject item2 in list) { if (pending.TryGetValue(item2, out var value)) { DestroyCopy(value); GameObject[] array3 = value.OwnedObjects; foreach (GameObject item in array3) { pendingChildren.Remove(item); } pending.Remove(item2); continue; } foreach (GameObject item3 in adapter.OwnedObjects(item2).Reverse()) { if (Object.op_Implicit((Object)(object)item3)) { NetworkServer.Destroy(item3); } } } throw; } } private void AssignTree(ObjectAdapter adapter, GameObject root, PlayerCharacterMasterController owner, int group) { int num = 0; List<InstanceHandler> list = new List<InstanceHandler>(); try { foreach (GameObject item in adapter.OwnedObjects(root)) { if (Object.op_Implicit((Object)(object)item)) { InstanceHandler instanceHandler = item.GetComponent<InstanceHandler>() ?? item.AddComponent<InstanceHandler>(); list.Add(instanceHandler); instanceHandler.Assign(owner, checked(group * 16 + num++)); } } } catch { foreach (InstanceHandler item2 in list) { if (Object.op_Implicit((Object)(object)item2)) { Object.Destroy((Object)(object)item2); } } throw; } foreach (InstanceHandler item3 in list) { try { new OwnerSnapshot(item3).SendToAll(); } catch (Exception arg) { plugin._logger.LogError((object)$"Owner snapshot send failed for {((Object)item3).name}: {arg}"); } } } public GameObject SpawnCopy(GameObject source) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_0095: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Expected O, but got Unknown //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Expected O, but got Unknown //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active || !Object.op_Implicit((Object)(object)source)) { return null; } SpawnCard val = source.GetComponent<SpawnCardTracker>()?.SpawnCard; if (!Object.op_Implicit((Object)(object)val)) { val = (SpawnCard)(object)((IEnumerable<InteractableSpawnCard>)Resources.FindObjectsOfTypeAll<InteractableSpawnCard>()).FirstOrDefault((Func<InteractableSpawnCard, bool>)((InteractableSpawnCard candidate) => Object.op_Implicit((Object)(object)((SpawnCard)candidate).prefab) && ((Object)((SpawnCard)candidate).prefab).name == ((Object)source).name.Replace("(Clone)", "").Trim())); } if (!Object.op_Implicit((Object)(object)val)) { plugin._logger.LogError((object)("No SpawnCard for " + ((Object)source).name + "; additional player copies were not created.")); return null; } DirectorPlacementRule val2 = new DirectorPlacementRule { placementMode = (PlacementMode)6, position = source.transform.position, rotation = source.transform.rotation }; SpawnResult val3 = val.DoSpawn(source.transform.position, source.transform.rotation, new DirectorSpawnRequest(val, val2, new Xoroshiro128Plus(0uL))); if (Object.op_Implicit((Object)(object)val3.spawnedInstance)) { val3.spawnedInstance.transform.position = source.transform.position; val3.spawnedInstance.transform.rotation = source.transform.rotation; val3.spawnedInstance.transform.localScale = source.transform.localScale; } return val3.spawnedInstance; } public void Clear() { if (NetworkServer.active) { foreach (PendingCopy value in pending.Values) { DestroyCopy(value); } } foreach (var source in sources) { if (Object.op_Implicit((Object)(object)source.source)) { ResolveTree(source.adapter, source.source); } } pending.Clear(); pendingChildren.Clear(); sources.Clear(); initialized.Clear(); } private static void DestroyCopy(PendingCopy copy) { foreach (GameObject item in copy.OwnedObjects.AsEnumerable().Reverse()) { if (Object.op_Implicit((Object)(object)item)) { NetworkServer.Destroy(item); } } } private static void ResolveTree(ObjectAdapter adapter, GameObject source) { foreach (GameObject item in adapter.OwnedObjects(source)) { if (Object.op_Implicit((Object)(object)item)) { PendingOwnership.Resolve(item); } } } } } namespace InstancedLoot.Networking { public sealed class OwnerSnapshot : INetMessage, ISerializableObject { public const int ProtocolVersion = 2; private int version = 2; private NetworkInstanceId runId; private NetworkInstanceId targetId; private NetworkInstanceId ownerId; private int stage; private int epoch; private int revision; private int group; private string scene; private float expires; private static int serverEpoch = 1; private static readonly Dictionary<(NetworkInstanceId run, int epoch, NetworkInstanceId target), OwnerSnapshot> pending = new Dictionary<(NetworkInstanceId, int, NetworkInstanceId), OwnerSnapshot>(); private static readonly Dictionary<(NetworkInstanceId run, int epoch, NetworkInstanceId target), int> latest = new Dictionary<(NetworkInstanceId, int, NetworkInstanceId), int>(); private static readonly Dictionary<NetworkInstanceId, int> newestEpoch = new Dictionary<NetworkInstanceId, int>(); private static readonly Dictionary<NetworkInstanceId, int> appliedEpoch = new Dictionary<NetworkInstanceId, int>(); private static readonly Dictionary<NetworkInstanceId, int> minimumEpoch = new Dictionary<NetworkInstanceId, int>(); private (NetworkInstanceId, int, NetworkInstanceId) Key => (runId, epoch, targetId); public static int PendingCount => pending.Count; private bool CurrentSession { get { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (Object.op_Implicit((Object)(object)Run.instance) && ((NetworkBehaviour)Run.instance).netId == runId && Run.instance.stageClearCount == stage) { Scene activeScene = SceneManager.GetActiveScene(); return ((Scene)(ref activeScene)).name == scene; } return false; } } private bool Obsolete { get { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (!minimumEpoch.TryGetValue(runId, out var value) || epoch >= value) { if (newestEpoch.TryGetValue(runId, out var value2)) { return epoch < value2; } return false; } return true; } } public OwnerSnapshot() { } public OwnerSnapshot(InstanceHandler handler) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002e: 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_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) runId = ((NetworkBehaviour)Run.instance).netId; stage = Run.instance.stageClearCount; Scene activeScene = SceneManager.GetActiveScene(); scene = ((Scene)(ref activeScene)).name; epoch = serverEpoch; targetId = ((Component)handler).GetComponent<NetworkIdentity>().netId; ownerId = ((Component)handler.Owner).GetComponent<NetworkIdentity>().netId; revision = handler.Revision; group = handler.GroupId; } public void Serialize(NetworkWriter writer) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) writer.Write(version); writer.Write(runId); writer.Write(stage); writer.Write(scene); writer.Write(epoch); writer.Write(targetId); writer.Write(ownerId); writer.Write(revision); writer.Write(group); } public void Deserialize(NetworkReader reader) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) version = reader.ReadInt32(); runId = reader.ReadNetworkId(); stage = reader.ReadInt32(); scene = reader.ReadString(); epoch = reader.ReadInt32(); targetId = reader.ReadNetworkId(); ownerId = reader.ReadNetworkId(); revision = reader.ReadInt32(); group = reader.ReadInt32(); } public void OnReceived() { //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) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) if (!NetworkServer.active && version == 2 && !(runId == NetworkInstanceId.Invalid) && !(targetId == NetworkInstanceId.Invalid) && !(ownerId == NetworkInstanceId.Invalid) && epoch > 0 && revision > 0 && group > 0 && !Obsolete && (!latest.TryGetValue(Key, out var value) || revision >= value)) { newestEpoch[runId] = epoch; latest[Key] = revision; expires = Time.realtimeSinceStartup + 30f; pending[Key] = this; Pump(); } } private static void Release(OwnerSnapshot snapshot) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) GameObject val = Util.FindNetworkObject(snapshot.targetId); if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)val.GetComponent<InstanceHandler>())) { PendingOwnership.Resolve(val); } pending.Remove(snapshot.Key); } public static void Pump() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) OwnerSnapshot[] array = pending.Values.ToArray(); foreach (OwnerSnapshot ownerSnapshot in array) { if (ownerSnapshot.Obsolete || Time.realtimeSinceStartup > ownerSnapshot.expires) { Release(ownerSnapshot); } else if (ownerSnapshot.CurrentSession) { appliedEpoch[ownerSnapshot.runId] = ownerSnapshot.epoch; GameObject val = Util.FindNetworkObject(ownerSnapshot.targetId); GameObject obj = Util.FindNetworkObject(ownerSnapshot.ownerId); PlayerCharacterMasterController val2 = ((obj != null) ? obj.GetComponent<PlayerCharacterMasterController>() : null); if (Object.op_Implicit((Object)(object)val) && !Object.op_Implicit((Object)(object)val2)) { PendingOwnership.Mark(val); } if (Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val2)) { (val.GetComponent<InstanceHandler>() ?? val.AddComponent<InstanceHandler>()).Assign(val2, ownerSnapshot.group, ownerSnapshot.revision); pending.Remove(ownerSnapshot.Key); } } } } public void SendToAll() { if (NetworkServer.active && Object.op_Implicit((Object)(object)Run.instance)) { NetMessageExtensions.Send((INetMessage)(object)this, (NetworkDestination)1); } } public static void SceneChanged() { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active) { serverEpoch++; return; } if (Object.op_Implicit((Object)(object)Run.instance) && appliedEpoch.TryGetValue(((NetworkBehaviour)Run.instance).netId, out var value)) { minimumEpoch[((NetworkBehaviour)Run.instance).netId] = value + 1; } Pump(); } public static void RunChanged() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) if (NetworkServer.active) { serverEpoch++; return; } OwnerSnapshot[] array = pending.Values.ToArray(); foreach (OwnerSnapshot ownerSnapshot in array) { if (Object.op_Implicit((Object)(object)Run.instance) && ownerSnapshot.runId != ((NetworkBehaviour)Run.instance).netId) { Release(ownerSnapshot); } } Pump(); } public static void Clear() { OwnerSnapshot[] array = pending.Values.ToArray(); for (int i = 0; i < array.Length; i++) { Release(array[i]); } latest.Clear(); newestEpoch.Clear(); appliedEpoch.Clear(); minimumEpoch.Clear(); } } } namespace InstancedLoot.Enums { public enum InstanceMode { InstanceObject } } namespace InstancedLoot.Configuration { public sealed class Config { private readonly InstancedLoot plugin; private readonly Dictionary<string, ConfigEntry<bool>> enabled = new Dictionary<string, ConfigEntry<bool>>(); public ConfigEntry<InstanceMode> PreferredInstanceMode { get; private set; } public ConfigEntry<bool> ReduceInteractibleBudget { get; private set; } public ConfigEntry<bool> ReduceMoneyDrops { get; private set; } public Config(InstancedLoot plugin, ManualLogSource logger) { this.plugin = plugin; } public void Init() { PreferredInstanceMode = ((BaseUnityPlugin)plugin).Config.Bind<InstanceMode>("General", "PreferredInstanceMode", InstanceMode.InstanceObject, "InstanceObject is the only supported allocation strategy. Every player owns a native purchase object."); ReduceInteractibleBudget = ((BaseUnityPlugin)plugin).Config.Bind<bool>("General - Balance", "ReduceInteractibleBudget", true, "Use the single-player interactable budget. Does not change object prices or payment rules."); ReduceMoneyDrops = ((BaseUnityPlugin)plugin).Config.Bind<bool>("General - Balance", "ReduceMoneyDrops", false, "Divide native team money rewards by participating player count. Purchases still charge the native payer."); string[] objectTypes = NativeAdapters.ObjectTypes; foreach (string text in objectTypes) { string text2 = (text.StartsWith("Shrine") ? "Shrines" : ((text == "Drone" || text == "Turret") ? "Repairs" : "Objects")); enabled[text] = ((BaseUnityPlugin)plugin).Config.Bind<bool>(text2, text, true, "Create an independently usable purchase object per player. False keeps vanilla behavior. Applies to newly spawned objects."); } } public bool IsEnabled(string type) { if (enabled.TryGetValue(type, out var value)) { return value.Value; } return false; } } } namespace InstancedLoot.Components { public sealed class FadeBehavior : InstancedLootBehaviour { private static readonly int Fade; public float FadeLevel; public readonly HashSet<GameObject> ExtraGameObjects = new HashSet<GameObject>(); public static readonly List<FadeBehavior> InstancesList; private readonly HashSet<Renderer> renderers = new HashSet<Renderer>(); private readonly HashSet<Behaviour> effects = new HashSet<Behaviour>(); private MaterialPropertyBlock properties; private bool dirty = true; private readonly Dictionary<Renderer, bool> originalForce = new Dictionary<Renderer, bool>(); private readonly Dictionary<Behaviour, bool> originalEffects = new Dictionary<Behaviour, bool>(); private readonly Dictionary<Renderer, MaterialPropertyBlock> originalProperties = new Dictionary<Renderer, MaterialPropertyBlock>(); static FadeBehavior() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Expected O, but got Unknown Fade = Shader.PropertyToID("_Fade"); InstancesList = new List<FadeBehavior>(); SceneCamera.onSceneCameraPreCull += (SceneCameraDelegate)delegate(SceneCamera camera) { RefreshAll(camera, cull: true); }; SceneCamera.onSceneCameraPreRender += (SceneCameraDelegate)delegate(SceneCamera camera) { RefreshAll(camera, cull: false); }; SceneCamera.onSceneCameraPostRender += (SceneCameraDelegate)delegate { foreach (FadeBehavior instances in InstancesList) { instances.RestoreAfterCamera(); } }; } private static void RefreshAll(SceneCamera camera, bool cull) { CharacterBody val = (Object.op_Implicit((Object)(object)camera.cameraRigController) ? camera.cameraRigController.targetBody : null); PlayerCharacterMasterController player = ((Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.master)) ? val.master.playerCharacterMasterController : null); foreach (FadeBehavior instances in InstancesList) { if (cull) { instances.RefreshForPreCull(player); } else { instances.RefreshForPreRender(player); } } } public void Awake() { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown properties = new MaterialPropertyBlock(); } public void OnEnable() { InstancesList.Add(this); } public void OnDisable() { RestoreAfterCamera(); InstancesList.Remove(this); } public void OnDestroy() { RestoreAfterCamera(); InstancesList.Remove(this); } public void Refresh() { dirty = true; } public void RefreshNextFrame() { Refresh(); } public void RefreshComponentLists() { dirty = false; renderers.Clear(); effects.Clear(); ExtraGameObjects.RemoveWhere((GameObject target) => !Object.op_Implicit((Object)(object)target)); HashSet<GameObject> hashSet = new HashSet<GameObject>(ExtraGameObjects) { ((Component)this).gameObject }; ModelLocator[] componentsInChildren = ((Component)this).GetComponentsInChildren<ModelLocator>(); foreach (ModelLocator val in componentsInChildren) { if ((Object)(object)val.modelTransform != (Object)null) { hashSet.Add(((Component)val.modelTransform).gameObject); } } GameObject[] array = hashSet.ToArray(); for (int num = 0; num < array.Length; num++) { CostHologramContent[] componentsInChildren2 = array[num].GetComponentsInChildren<CostHologramContent>(); foreach (CostHologramContent val2 in componentsInChildren2) { if (Object.op_Implicit((Object)(object)val2.targetTextMesh)) { hashSet.Add(((Component)val2.targetTextMesh).gameObject); } } } foreach (GameObject item in hashSet) { renderers.UnionWith(item.GetComponentsInChildren<Renderer>()); effects.UnionWith((IEnumerable<Behaviour>)(object)item.GetComponentsInChildren<Highlight>()); effects.UnionWith((IEnumerable<Behaviour>)(object)item.GetComponentsInChildren<Light>()); } renderers.RemoveWhere(delegate(Renderer renderer) { if (Object.op_Implicit((Object)(object)renderer)) { FadeBehavior componentInParent = ((Component)renderer).GetComponentInParent<FadeBehavior>(); if (Object.op_Implicit((Object)(object)componentInParent)) { return (Object)(object)componentInParent != (Object)(object)this; } } return false; }); effects.RemoveWhere(delegate(Behaviour effect) { if (Object.op_Implicit((Object)(object)effect)) { FadeBehavior componentInParent = ((Component)effect).GetComponentInParent<FadeBehavior>(); if (Object.op_Implicit((Object)(object)componentInParent)) { return (Object)(object)componentInParent != (Object)(object)this; } } return false; }); } private bool Visible(PlayerCharacterMasterController player) { if (PendingOwnership.IsPending(((Component)this).gameObject)) { return false; } InstanceHandler component = ((Component)this).GetComponent<InstanceHandler>(); if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)player)) { return component.IsInstancedFor(player); } return true; } public float GetFadeLevelForCameraRigController(CameraRigController camera) { CharacterBody val = (Object.op_Implicit((Object)(object)camera) ? camera.targetBody : null); if (!Visible((Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.master)) ? val.master.playerCharacterMasterController : null)) { return FadeLevel; } return 1f; } public void RefreshForPreCull(PlayerCharacterMasterController player) { RestoreAfterCamera(); if (dirty) { RefreshComponentLists(); } bool flag = Visible(player); foreach (Renderer renderer in renderers) { if (Object.op_Implicit((Object)(object)renderer)) { originalForce[renderer] = renderer.forceRenderingOff; renderer.forceRenderingOff = renderer.forceRenderingOff || !flag; } } foreach (Behaviour effect in effects) { if (Object.op_Implicit((Object)(object)effect)) { originalEffects[effect] = effect.enabled; if (!flag) { effect.enabled = false; } } } } public void RefreshForPreRender(PlayerCharacterMasterController player) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown if (dirty) { RefreshComponentLists(); } float num = (Visible(player) ? 1f : FadeLevel); foreach (Renderer renderer in renderers) { if (Object.op_Implicit((Object)(object)renderer)) { if (!originalProperties.ContainsKey(renderer)) { MaterialPropertyBlock val = new MaterialPropertyBlock(); renderer.GetPropertyBlock(val); originalProperties[renderer] = val; } renderer.GetPropertyBlock(properties); properties.SetFloat(Fade, num); renderer.SetPropertyBlock(properties); } } } public void RestoreAfterCamera() { foreach (KeyValuePair<Renderer, bool> item in originalForce) { if (Object.op_Implicit((Object)(object)item.Key)) { item.Key.forceRenderingOff = item.Value; } } foreach (KeyValuePair<Behaviour, bool> originalEffect in originalEffects) { if (Object.op_Implicit((Object)(object)originalEffect.Key)) { originalEffect.Key.enabled = originalEffect.Value; } } foreach (KeyValuePair<Renderer, MaterialPropertyBlock> originalProperty in originalProperties) { if (Object.op_Implicit((Object)(object)originalProperty.Key)) { originalProperty.Key.SetPropertyBlock(originalProperty.Value); } } originalForce.Clear(); originalEffects.Clear(); originalProperties.Clear(); } public static FadeBehavior Attach(GameObject target) { FadeBehavior obj = target.GetComponent<FadeBehavior>() ?? target.AddComponent<FadeBehavior>(); obj.Refresh(); return obj; } } public static class InstanceAccessPolicy { public static PlayerCharacterMasterController ResolvePlayer(Interactor interactor) { if (!Object.op_Implicit((Object)(object)interactor)) { return null; } return ResolvePlayer(((Component)interactor).GetComponent<CharacterBody>()); } public static PlayerCharacterMasterController ResolvePlayer(CharacterBody body) { if (!Object.op_Implicit((Object)(object)body) || !Object.op_Implicit((Object)(object)body.master)) { return null; } return body.master.playerCharacterMasterController; } public static bool CanInteract(InstanceHandler handler, PlayerCharacterMasterController player) { if (Object.op_Implicit((Object)(object)handler)) { return handler.IsInstancedFor(player); } return false; } public static bool CanInteract(InstanceHandler handler, Interactor interactor) { return CanInteract(handler, ResolvePlayer(interactor)); } public static bool CanInteract(GameObject target, Interactor interactor) { if (PendingOwnership.IsPending(target)) { return false; } InstanceHandler instanceHandler = (Object.op_Implicit((Object)(object)target) ? target.GetComponent<InstanceHandler>() : null); if (Object.op_Implicit((Object)(object)instanceHandler)) { return CanInteract(instanceHandler, interactor); } return true; } } public class InstancedLootBehaviour : MonoBehaviour { } public sealed class InstanceHandler : InstancedLootBehaviour { public static readonly List<InstanceHandler> Instances = new List<InstanceHandler>(); public PlayerCharacterMasterController Owner { get; private set; } public int GroupId { get; private set; } public int Revision { get; private set; } public IEnumerable<InstanceHandler> LinkedHandlers => Instances.Where((InstanceHandler handler) => Object.op_Implicit((Object)(object)handler) && handler.GroupId == GroupId); public IEnumerable<PlayerCharacterMasterController> AllPlayers => (from handler in LinkedHandlers select handler.Owner into player where Object.op_Implicit((Object)(object)player) select player).Distinct(); public HashSet<PlayerCharacterMasterController> Players { get { if (!Object.op_Implicit((Object)(object)Owner)) { return new HashSet<PlayerCharacterMasterController>(); } return new HashSet<PlayerCharacterMasterController> { Owner }; } } public PlayerCharacterMasterController OrigPlayer => Owner; public void Awake() { Instances.Add(this); } public void Assign(PlayerCharacterMasterController owner, int groupId, int revision = 1) { Owner = owner; GroupId = groupId; Revision = revision; PendingOwnership.Resolve(((Component)this).gameObject); FadeBehavior.Attach(((Component)this).gameObject).Refresh(); } public bool IsInstancedFor(PlayerCharacterMasterController player) { if (Object.op_Implicit((Object)(object)player)) { return (Object)(object)Owner == (Object)(object)player; } return false; } public bool IsObjectInstancedFor(PlayerCharacterMasterController player) { return IsInstancedFor(player); } public bool IsInstancedForInteractor(Interactor interactor) { return InstanceAccessPolicy.CanInteract(this, interactor); } public void OnDestroy() { Instances.Remove(this); FadeBehavior component = ((Component)this).GetComponent<FadeBehavior>(); if (Object.op_Implicit((Object)(object)component)) { Object.Destroy((Object)(object)component); } } } public sealed class PendingOwnership : InstancedLootBehaviour { public bool Resolved; public static void Mark(GameObject target) { if (!Object.op_Implicit((Object)(object)target.GetComponent<PendingOwnership>())) { target.AddComponent<PendingOwnership>(); } FadeBehavior.Attach(target).Refresh(); } public static bool IsPending(GameObject target) { PendingOwnership pendingOwnership = (Object.op_Implicit((Object)(object)target) ? target.GetComponent<PendingOwnership>() : null); if (Object.op_Implicit((Object)(object)pendingOwnership)) { return !pendingOwnership.Resolved; } return false; } public static void Resolve(GameObject target) { PendingOwnership component = target.GetComponent<PendingOwnership>(); if (Object.op_Implicit((Object)(object)component)) { component.Resolved = true; Object.Destroy((Object)(object)component); FadeBehavior component2 = target.GetComponent<FadeBehavior>(); if (Object.op_Implicit((Object)(object)component2)) { component2.Refresh(); } } } } public sealed class PingerControllerRenderBehaviour : InstancedLootBehaviour { public static readonly List<PingerControllerRenderBehaviour> InstancesList; private readonly Dictionary<Renderer, bool> originalForce = new Dictionary<Renderer, bool>(); private PingerController pinger; static PingerControllerRenderBehaviour() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Expected O, but got Unknown InstancesList = new List<PingerControllerRenderBehaviour>(); SceneCamera.onSceneCameraPreCull += (SceneCameraDelegate)delegate(SceneCamera camera) { CharacterBody val = (Object.op_Implicit((Object)(object)camera.cameraRigController) ? camera.cameraRigController.targetBody : null); PlayerCharacterMasterController player = ((Object.op_Implicit((Object)(object)val) && Object.op_Implicit((Object)(object)val.master)) ? val.master.playerCharacterMasterController : null); foreach (PingerControllerRenderBehaviour instances in InstancesList) { instances.RefreshForPlayer(player); } }; SceneCamera.onSceneCameraPostRender += (SceneCameraDelegate)delegate { foreach (PingerControllerRenderBehaviour instances2 in InstancesList) { instances2.RestoreAfterCamera(); } }; } public void Awake() { pinger = ((Component)this).GetComponent<PingerController>(); } public void OnEnable() { InstancesList.Add(this); } public void OnDisable() { RestoreAfterCamera(); InstancesList.Remove(this); } public void OnDestroy() { RestoreAfterCamera(); InstancesList.Remove(this); } public void RefreshForPlayer(PlayerCharacterMasterController player) { RestoreAfterCamera(); if (Object.op_Implicit((Object)(object)pinger) && Object.op_Implicit((Object)(object)pinger.pingIndicator)) { PingIndicator pingIndicator = pinger.pingIndicator; bool flag = Utils.IsObjectInteractibleForPlayer(pingIndicator.pingTarget, player); Renderer[] componentsInChildren = ((Component)pingIndicator).GetComponentsInChildren<Renderer>(); foreach (Renderer val in componentsInChildren) { originalForce[val] = val.forceRenderingOff; val.forceRenderingOff = val.forceRenderingOff || !flag; } } } public void RestoreAfterCamera() { foreach (KeyValuePair<Renderer, bool> item in originalForce) { if (Object.op_Implicit((Object)(object)item.Key)) { item.Key.forceRenderingOff = item.Value; } } originalForce.Clear(); } } public class SpawnCardTracker : InstancedLootBehaviour { public SpawnCard SpawnCard; } } namespace InstancedLoot.Hooks { public abstract class AbstractHookHandler { internal HookManager hookManager; protected InstancedLoot Plugin => hookManager.Plugin; protected Config ModConfig => Plugin.ModConfig; public void Init(HookManager _hookManager) { hookManager = _hookManager; } public abstract void RegisterHooks(); public abstract void UnregisterHooks(); } public sealed class HookManager { public readonly Dictionary<Type, AbstractHookHandler> HookHandlers = new Dictionary<Type, AbstractHookHandler>(); public readonly InstancedLoot Plugin; public HookManager(InstancedLoot plugin) { Plugin = plugin; RegisterHandler<ObjectLifecycleHooks>(); RegisterHandler<PurchaseInteractionHandler>(); RegisterHandler<InteractorHandler>(); RegisterHandler<SpawnCardHandler>(); RegisterHandler<SceneDirectorHandler>(); RegisterHandler<DeathRewardsHandler>(); RegisterHandler<DitherModelHandler>(); RegisterHandler<HologramProjectorHandler>(); RegisterHandler<AnimationEventsHandler>(); RegisterHandler<EffectManagerHandler>(); RegisterHandler<PingHandler>(); } public void RegisterHandler<T>() where T : AbstractHookHandler, new() { if (!HookHandlers.ContainsKey(typeof(T))) { T val = new T(); val.Init(this); HookHandlers.Add(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) { value.UnregisterHooks(); } } } public class AnimationEventsHandler : AbstractHookHandler { public static AnimationEvents CurrentAnimationEvents; public override void RegisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown AnimationEvents.CreateEffect += new hook_CreateEffect(On_AnimationEvents_CreateEffect); AnimationEvents.CreatePrefab += new Manipulator(IL_AnimationEvents_CreatePrefab); } public override void UnregisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown AnimationEvents.CreateEffect -= new hook_CreateEffect(On_AnimationEvents_CreateEffect); AnimationEvents.CreatePrefab -= new Manipulator(IL_AnimationEvents_CreatePrefab); } private void On_AnimationEvents_CreateEffect(orig_CreateEffect orig, AnimationEvents self, AnimationEvent animationEvent) { CurrentAnimationEvents = self; orig.Invoke(self, animationEvent); CurrentAnimationEvents = null; FadeBehavior component = ((Component)self).GetComponent<FadeBehavior>(); if (Object.op_Implicit((Object)(object)component)) { component.RefreshNextFrame(); } EntityLocator component2 = ((Component)self).GetComponent<EntityLocator>(); if (Object.op_Implicit((Object)(object)component2) && Object.op_Implicit((Object)(object)component2.entity)) { FadeBehavior component3 = component2.entity.GetComponent<FadeBehavior>(); if (Object.op_Implicit((Object)(object)component3)) { component3.Refresh(); } } } private void IL_AnimationEvents_CreatePrefab(ILContext il) { AnimationPrefabIL.Apply<Action<Transform, AnimationEvents, bool>>(il, HandlePrefabCreation); } public static void HandlePrefabCreation(Transform created, AnimationEvents parent, bool pooled) { if (!pooled && Object.op_Implicit((Object)(object)created)) { HandleObjectCreation(((Component)created).gameObject, parent); } } public static void HandleEffectCreation(GameObject objectToAdd) { if ((Object)(object)CurrentAnimationEvents != (Object)null) { HandleObjectCreation(objectToAdd, CurrentAnimationEvents); } } public static void HandleObjectCreation(GameObject objectToAdd, AnimationEvents parent) { Transform val = objectToAdd.transform; Transform transform = ((Component)parent).transform; while ((Object)(object)val != (Object)(object)transform && (Object)(object)val != (Object)null) { val = val.parent; } FadeBehavior componentInParent = ((Component)parent).GetComponentInParent<FadeBehavior>(); if ((Object)(object)componentInParent == (Object)null) { EntityLocator component = ((Component)parent).GetComponent<EntityLocator>(); if ((Object)(object)component != (Object)null && (Object)(object)component.entity != (Object)null) { componentInParent = component.entity.GetComponentInParent<FadeBehavior>(); } } if (!((Object)(object)componentInParent == (Object)null)) { if ((Object)(object)val != (Object)(object)transform) { componentInParent.ExtraGameObjects.Add(objectToAdd); } componentInParent.Refresh(); } } } internal static class AnimationPrefabIL { internal static void Apply<TDelegate>(ILContext il, TDelegate handleCreation) where TDelegate : Delegate { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Invalid comparison between Unknown and I4 //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); int pooledLocal = -1; if (!val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[2] { delegate(Instruction i) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Invalid comparison between Unknown and I4 if (i.OpCode == OpCodes.Call) { object operand = i.Operand; MethodReference val2 = (MethodReference)((operand is MethodReference) ? operand : null); if (val2 != null && ((MemberReference)((MemberReference)val2).DeclaringType).FullName == "RoR2.EffectManager" && ((MemberReference)val2).Name == "ShouldUsePooledEffect" && (int)val2.ReturnType.MetadataType == 2 && val2.Parameters.Count == 1) { return ((MemberReference)((ParameterReference)val2.Parameters[0]).ParameterType).FullName == "UnityEngine.GameObject"; } } return false; }, (Instruction i) => ILPatternMatchingExt.MatchStloc(i, ref pooledLocal) }) || (int)((VariableReference)il.Body.Variables[pooledLocal]).VariableType.MetadataType != 2) { throw new InvalidOperationException(((MemberReference)il.Method).FullName + ": CreatePrefab pooled-effect flag pattern not found."); } val.Index = 0; int num = 0; while (val.TryGotoNext((MoveType)2, new Func<Instruction, bool>[1] { delegate(Instruction i) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Invalid comparison between Unknown and I4 if (i.OpCode == OpCodes.Call) { object operand = i.Operand; MethodReference val2 = (MethodReference)((operand is MethodReference) ? operand : null); if (val2 != null && ((MemberReference)((MemberReference)val2).DeclaringType).FullName == "RoR2.AnimationEvents" && !val2.HasThis && ((MemberReference)val2).Name.StartsWith("<CreatePrefab>g__DoSpawnEffect|", StringComparison.Ordinal) && ((MemberReference)val2.ReturnType).FullName == "UnityEngine.Transform" && val2.Parameters.Count == 5 && (int)((ParameterReference)val2.Parameters[0]).ParameterType.MetadataType == 2 && ((MemberReference)((ParameterReference)val2.Parameters[1]).ParameterType).FullName == "UnityEngine.GameObject" && ((MemberReference)((ParameterReference)val2.Parameters[2]).ParameterType).FullName == "UnityEngine.Vector3" && ((MemberReference)((ParameterReference)val2.Parameters[3]).ParameterType).FullName == "UnityEngine.Quaternion") { return ((MemberReference)((ParameterReference)val2.Parameters[4]).ParameterType).FullName == "UnityEngine.Transform"; } } return false; } })) { val.Emit(OpCodes.Dup); val.Emit(OpCodes.Ldarg_0); val.Emit(OpCodes.Ldloc, il.Body.Variables[pooledLocal]); val.EmitDelegate<TDelegate>(handleCreation); num++; } if (num == 0) { throw new InvalidOperationException(((MemberReference)il.Method).FullName + ": CreatePrefab DoSpawnEffect pattern not found."); } } } public class DeathRewardsHandler : AbstractHookHandler { public override void RegisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown DeathRewards.OnKilledServer += new Manipulator(IL_DeathRewards_OnKilledServer); } public override void UnregisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown DeathRewards.OnKilledServer -= new Manipulator(IL_DeathRewards_OnKilledServer); } private void IL_DeathRewards_OnKilledServer(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); val.GotoNext((MoveType)0, new Func<Instruction, bool>[1] { (Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<TeamManager>(i, "GiveTeamMoney") }); val.EmitDelegate<Func<uint, uint>>((Func<uint, uint>)delegate(uint money) { if (base.ModConfig.ReduceMoneyDrops.Value) { money /= (uint)Math.Max(1, Run.instance.participatingPlayerCount); } return money; }); } } public class DitherModelHandler : AbstractHookHandler { public override void RegisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown DitherModel.RefreshObstructorsForCamera += new Manipulator(IL_DitherModel_RefreshObstructorsForCamera); } public override void UnregisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown DitherModel.RefreshObstructorsForCamera -= new Manipulator(IL_DitherModel_RefreshObstructorsForCamera); } private void IL_DitherModel_RefreshObstructorsForCamera(ILContext il) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Expected O, but got Unknown //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_011a: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) ILCursor val = new ILCursor(il); ILLabel val2 = il.DefineLabel(); ILLabel val3 = il.DefineLabel(); MethodInfo methodInfo = typeof(Component).GetMethods(BindingFlags.Instance | BindingFlags.Public).First((MethodInfo method) => method.Name == "GetComponent" && method.IsGenericMethod).MakeGenericMethod(typeof(FadeBehavior)); int ditherModelLoc = -1; val.GotoNext((MoveType)0, new Func<Instruction, bool>[2] { (Instruction i) => ILPatternMatchingExt.MatchLdloc(i, ref ditherModelLoc), (Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<DitherModel>(i, "UpdateDither") }); int index = val.Index; val.Index = index + 1; val.Emit(OpCodes.Dup); val.Emit(OpCodes.Dup); val.Emit(OpCodes.Call, (MethodBase)methodInfo); val.Emit(OpCodes.Dup); val.Emit(OpCodes.Ldnull); val.Emit(OpCodes.Ceq); val.Emit(OpCodes.Brtrue, (object)val2); val.Emit(OpCodes.Ldarg_0); val.Emit<FadeBehavior>(OpCodes.Call, "GetFadeLevelForCameraRigController"); val.Emit(OpCodes.Ldloc, ditherModelLoc); val.Emit<DitherModel>(OpCodes.Ldfld, "fade"); val.Emit(OpCodes.Mul); val.Emit<DitherModel>(OpCodes.Stfld, "fade"); val.Emit(OpCodes.Br, (object)val3); val.MarkLabel(val2); val.Emit(OpCodes.Pop); val.Emit(OpCodes.Pop); val.MarkLabel(val3); } } public class EffectManagerHandler : AbstractHookHandler { public override void RegisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown EffectManager.SpawnEffect_EffectIndex_EffectData_bool += new Manipulator(IL_EffectManager_SpawnEffect); } public override void UnregisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown EffectManager.SpawnEffect_EffectIndex_EffectData_bool -= new Manipulator(IL_EffectManager_SpawnEffect); } private void IL_EffectManager_SpawnEffect(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_0044: 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<AnimationEventsHandler>(OpCodes.Call, "HandleEffectCreation"); } } public class HologramProjectorHandler : AbstractHookHandler { private readonly MethodInfo Method_ReadOnlyCollection_PlayerCharacterMasterController_get_Item = typeof(ReadOnlyCollection<PlayerCharacterMasterController>).GetMethod("get_Item", BindingFlags.Instance | BindingFlags.Public); public override void RegisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown HologramProjector.FindViewer += new Manipulator(IL_HologramProjector_FindViewer); HologramProjector.BuildHologram += new hook_BuildHologram(On_HologramProjector_BuildHologram); HologramProjector.DestroyHologram += new hook_DestroyHologram(On_HologramProjector_DestroyHologram); } public override void UnregisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown HologramProjector.FindViewer -= new Manipulator(IL_HologramProjector_FindViewer); HologramProjector.BuildHologram -= new hook_BuildHologram(On_HologramProjector_BuildHologram); HologramProjector.DestroyHologram -= new hook_DestroyHologram(On_HologramProjector_DestroyHologram); } private void On_HologramProjector_BuildHologram(orig_BuildHologram orig, HologramProjector self) { orig.Invoke(self); FadeBehavior component = ((Component)self).GetComponent<FadeBehavior>(); if ((Object)(object)component != (Object)null) { component.Refresh(); component.RefreshNextFrame(); } } private void On_HologramProjector_DestroyHologram(orig_DestroyHologram orig, HologramProjector self) { bool num = (Object)(object)self.hologramContentInstance != (Object)null; orig.Invoke(self); FadeBehavior component = ((Component)self).GetComponent<FadeBehavior>(); if (num && (Object)(object)component != (Object)null) { component.Refresh(); } } private void IL_HologramProjector_FindViewer(ILContext il) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_01d7: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)base.Plugin == (Object)null || !((Behaviour)base.Plugin).enabled) { return; } ILCursor val = new ILCursor(il); MethodInfo methodInfo = typeof(Component).GetMethods(BindingFlags.Instance | BindingFlags.Public).First((MethodInfo method) => method.Name == "GetComponent" && method.IsGenericMethod).MakeGenericMethod(typeof(InstanceHandler)); ILLabel val2 = il.DefineLabel(); ILLabel val3 = il.DefineLabel(); ILLabel val4 = il.DefineLabel(); int playersVariableId = -1; int indexVariableId = -1; val.GotoNext((MoveType)0, new Func<Instruction, bool>[3] { (Instruction i) => ILPatternMatchingExt.MatchLdloc(i, ref playersVariableId), (Instruction i) => ILPatternMatchingExt.MatchLdloc(i, ref indexVariableId), (Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt(i, (MethodBase)Method_ReadOnlyCollection_PlayerCharacterMasterController_get_Item) }); val.Emit(OpCodes.Ldarg_0); foreach (ILLabel incomingLabel in val.IncomingLabels) { incomingLabel.Target = val.Prev; } val.Emit(OpCodes.Call, (MethodBase)methodInfo); val.Emit(OpCodes.Dup); val.Emit(OpCodes.Ldnull); val.Emit(OpCodes.Ceq); val.Emit(OpCodes.Brtrue, (object)val3); val.Emit(OpCodes.Ldloc, playersVariableId); val.Emit(OpCodes.Ldloc, indexVariableId); val.Emit<ReadOnlyCollection<PlayerCharacterMasterController>>(OpCodes.Callvirt, "get_Item"); val.Emit<InstanceHandler>(OpCodes.Call, "IsObjectInstancedFor"); val.Emit(OpCodes.Brtrue, (object)val4); val.Emit(OpCodes.Ldc_I4_0); val.Emit(OpCodes.Br, (object)val2); val.MarkLabel(val3); val.Emit(OpCodes.Pop); val.MarkLabel(val4); ILLabel val5 = default(ILLabel); val.GotoNext((MoveType)0, new Func<Instruction, bool>[2] { (Instruction i) => ILPatternMatchingExt.MatchCallOrCallvirt<Object>(i, "op_Implicit"), (Instruction i) => ILPatternMatchingExt.MatchBrfalse(i, ref val5) }); int index = val.Index; val.Index = index + 1; val.MarkLabel(val2); } } public static class InteractorCandidateIL { public static void Apply<T>(ILContext il, T filter) where T : Delegate { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) Instruction[] array = ((IEnumerable<Instruction>)il.Body.Instructions).Where(delegate(Instruction instruction) { object operand = instruction.Operand; GenericInstanceMethod val2 = (GenericInstanceMethod)((operand is GenericInstanceMethod) ? operand : null); return val2 != null && ((MemberReference)val2).Name == "TryGetComponent" && ((MemberReference)((MemberReference)val2).DeclaringType).FullName == "UnityEngine.GameObject" && val2.GenericArguments.Count == 1 && ((MemberReference)val2.GenericArguments[0]).FullName == "RoR2.IInteractable"; }).ToArray(); if (array.Length != 2) { throw new InvalidOperationException($"Expected raycast and overlap candidate sites, found {array.Length}."); } for (int num = 0; num < array.Length; num++) { ILCursor val = new ILCursor(il); val.Goto(array[num], (MoveType)0, false); ILLabel[] array2 = val.IncomingLabels.ToArray(); val.Emit(OpCodes.Ldarg_0); ILLabel[] array3 = array2; for (int num2 = 0; num2 < array3.Length; num2++) { array3[num2].Target = val.Prev; } val.Emit((num == 0) ? OpCodes.Ldc_I4_0 : OpCodes.Ldc_I4_1); val.Remove(); val.EmitDelegate<T>(filter); } } } public sealed class InteractorHandler : AbstractHookHandler { public delegate bool CandidateFilter(GameObject target, out IInteractable result, Interactor actor, bool spherecast); [CompilerGenerated] private static class <>O { public static Manipulator <0>__FilterCandidates; public static hook_PerformInteraction <1>__Perform; public static CandidateFilter <2>__TryCandidate; } public override void RegisterHooks() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown object obj = <>O.<0>__FilterCandidates; if (obj == null) { Manipulator val = FilterCandidates; <>O.<0>__FilterCandidates = val; obj = (object)val; } Interactor.FindBestInteractableObject += (Manipulator)obj; object obj2 = <>O.<1>__Perform; if (obj2 == null) { hook_PerformInteraction val2 = Perform; <>O.<1>__Perform = val2; obj2 = (object)val2; } Interactor.PerformInteraction += (hook_PerformInteraction)obj2; } public override void UnregisterHooks() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown object obj = <>O.<0>__FilterCandidates; if (obj == null) { Manipulator val = FilterCandidates; <>O.<0>__FilterCandidates = val; obj = (object)val; } Interactor.FindBestInteractableObject -= (Manipulator)obj; object obj2 = <>O.<1>__Perform; if (obj2 == null) { hook_PerformInteraction val2 = Perform; <>O.<1>__Perform = val2; obj2 = (object)val2; } Interactor.PerformInteraction -= (hook_PerformInteraction)obj2; } private static void FilterCandidates(ILContext il) { InteractorCandidateIL.Apply<CandidateFilter>(il, TryCandidate); } public static bool TryCandidate(GameObject target, out IInteractable result, Interactor actor, bool spherecast) { //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Invalid comparison between Unknown and I4 result = null; if (!Object.op_Implicit((Object)(object)target)) { return false; } if (!Object.op_Implicit((Object)(object)target.GetComponent<InstanceHandler>()) && !PendingOwnership.IsPending(target)) { return target.TryGetComponent<IInteractable>(ref result); } if (!InstanceAccessPolicy.CanInteract(target, actor)) { return false; } IInteractable[] components = target.GetComponents<IInteractable>(); foreach (IInteractable val in components) { Behaviour val2 = (Behaviour)(object)((val is Behaviour) ? val : null); if ((val2 != null && !val2.isActiveAndEnabled) || (spherecast && val.ShouldIgnoreSpherecastForInteractibility(actor))) { continue; } Interactability interactability = val.GetInteractability(actor); if ((int)interactability != 0) { result = val; if ((int)interactability == 2) { return true; } } } return result != null; } private static void Perform(orig_PerformInteraction orig, Interactor self, GameObject target) { if (!NetworkServer.active || InstanceAccessPolicy.CanInteract(target, self)) { orig.Invoke(self, target); } } } public sealed class ObjectLifecycleHooks : AbstractHookHandler { private readonly NativeAdapters.Chest chest = new NativeAdapters.Chest(); private readonly NativeAdapters.OptionChest option = new NativeAdapters.OptionChest(); private readonly NativeAdapters.MultiShop shop = new NativeAdapters.MultiShop(); private readonly NativeAdapters.Roulette roulette = new NativeAdapters.Roulette(); private readonly NativeAdapters.Shrine shrine = new NativeAdapters.Shrine(); private readonly NativeAdapters.Repair repair = new NativeAdapters.Repair(); public override void RegisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown ChestBehavior.Start += new hook_Start(ChestStart); OptionChestBehavior.Start += new hook_Start(OptionStart); MultiShopController.Start += new hook_Start(ShopStart); ShopTerminalBehavior.Start += new hook_Start(TerminalStart); RouletteChestController.Start += new hook_Start(RouletteStart); ShrineChanceBehavior.Start += new hook_Start(ChanceStart); ShrineBloodBehavior.Start += new hook_Start(BloodStart); ShrineRestackBehavior.Start += new hook_Start(OrderStart); SummonMasterBehavior.Start += new hook_Start(RepairStart); } public override void UnregisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0099: Expected O, but got Unknown ChestBehavior.Start -= new hook_Start(ChestStart); OptionChestBehavior.Start -= new hook_Start(OptionStart); MultiShopController.Start -= new hook_Start(ShopStart); ShopTerminalBehavior.Start -= new hook_Start(TerminalStart); RouletteChestController.Start -= new hook_Start(RouletteStart); ShrineChanceBehavior.Start -= new hook_Start(ChanceStart); ShrineBloodBehavior.Start -= new hook_Start(BloodStart); ShrineRestackBehavior.Start -= new hook_Start(OrderStart); SummonMasterBehavior.Start -= new hook_Start(RepairStart); } private void Start(Component component, Action original, ObjectAdapter adapter, string type, bool initializeCopyDisplay = false) { if (NetworkServer.active && base.Plugin.Objects.InitializeCopy(component.gameObject)) { if (initializeCopyDisplay && Object.op_Implicit((Object)(object)component)) { original(); } return; } original(); if (NetworkServer.active && type != null) { base.Plugin.Objects.InitializeSource(adapter, component.gameObject, type); } } private void ChestStart(orig_Start orig, ChestBehavior self) { Start((Component)(object)self, delegate { orig.Invoke(self); }, chest, NativeAdapters.Identify(((Component)self).gameObject, NativeAdapters.ChestTypes)); } private void OptionStart(orig_Start orig, OptionChestBehavior self) { Start((Component)(object)self, delegate { orig.Invoke(self); }, option, NativeAdapters.Identify(((Component)self).gameObject, new string[2] { "VoidTriple", "LockboxVoid" })); } private void ShopStart(orig_Start orig, MultiShopController self) { Start((Component)(object)self, delegate { orig.Invoke(self); }, shop, NativeAdapters.Identify(((Component)self).gameObject, new string[3] { "TripleShopEquipment", "TripleShop", "FreeChestMultiShop" })); } private void TerminalStart(orig_Start orig, ShopTerminalBehavior self) { if (!NetworkServer.active || (!base.Plugin.Objects.IsPendingChild(((Component)self).gameObject) && (!Object.op_Implicit((Object)(object)((Component)self).GetComponent<InstanceHandler>()) || !self.hasStarted))) { orig.Invoke(self); } } private void RouletteStart(orig_Start orig, RouletteChestController self) { Start((Component)(object)self, delegate { orig.Invoke(self); }, roulette, ((Object)self).name.StartsWith("CasinoChest") ? "CasinoChest" : null); } private void ChanceStart(orig_Start orig, ShrineChanceBehavior self) { Start((Component)(object)self, delegate { orig.Invoke(self); }, shrine, "ShrineChance"); } private void BloodStart(orig_Start orig, ShrineBloodBehavior self) { Start((Component)(object)self, delegate { orig.Invoke(self); }, shrine, "ShrineBlood"); } private void OrderStart(orig_Start orig, ShrineRestackBehavior self) { Start((Component)(object)self, delegate { orig.Invoke(self); }, shrine, "ShrineRestack"); } private void RepairStart(orig_Start orig, SummonMasterBehavior self) { string type = null; if (Object.op_Implicit((Object)(object)((Component)self).GetComponent<PurchaseInteraction>()) && Object.op_Implicit((Object)(object)self.masterPrefab) && self.destroyAfterSummoning) { string name = ((Object)((Component)self).gameObject).name; if (name.IndexOf("Broken", StringComparison.OrdinalIgnoreCase) >= 0) { if (name.IndexOf("Turret", StringComparison.OrdinalIgnoreCase) >= 0) { type = "Turret"; } else if (name.IndexOf("Drone", StringComparison.OrdinalIgnoreCase) >= 0) { type = "Drone"; } } } Start((Component)(object)self, delegate { orig.Invoke(self); }, repair, type, initializeCopyDisplay: true); } } public sealed class PingHandler : AbstractHookHandler { public override void RegisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown PingerController.RebuildPing += new hook_RebuildPing(Rebuild); PositionIndicator.UpdatePositions += new hook_UpdatePositions(Positions); } public override void UnregisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown PingerController.RebuildPing -= new hook_RebuildPing(Rebuild); PositionIndicator.UpdatePositions -= new hook_UpdatePositions(Positions); } private void Rebuild(orig_RebuildPing orig, PingerController self, PingInfo info) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)((Component)self).GetComponent<PingerControllerRenderBehaviour>())) { ((Component)self).gameObject.AddComponent<PingerControllerRenderBehaviour>(); } orig.Invoke(self, info); } private void Positions(orig_UpdatePositions orig, UICamera camera) { orig.Invoke(camera); foreach (PositionIndicator instances in PositionIndicator.instancesList) { if (Object.op_Implicit((Object)(object)instances.targetTransform) && !Utils.IsObjectInteractibleForCameraRigController(((Component)instances.targetTransform).gameObject, camera.cameraRigController)) { if (Object.op_Implicit((Object)(object)instances.insideViewObject)) { instances.insideViewObject.SetActive(false); } if (Object.op_Implicit((Object)(object)instances.outsideViewObject)) { instances.outsideViewObject.SetActive(false); } if (Object.op_Implicit((Object)(object)instances.alwaysVisibleObject)) { instances.alwaysVisibleObject.SetActive(false); } } } } } public sealed class PurchaseInteractionHandler : AbstractHookHandler { private readonly HashSet<Object> inProgress = new HashSet<Object>(); public override void RegisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown PurchaseInteraction.GetInteractability += new hook_GetInteractability(GetInteractability); PurchaseInteraction.OnInteractionBegin += new hook_OnInteractionBegin(Begin); } public override void UnregisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Expected O, but got Unknown PurchaseInteraction.GetInteractability -= new hook_GetInteractability(GetInteractability); PurchaseInteraction.OnInteractionBegin -= new hook_OnInteractionBegin(Begin); inProgress.Clear(); } private Interactability GetInteractability(orig_GetInteractability orig, PurchaseInteraction self, Interactor actor) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) if (!InstanceAccessPolicy.CanInteract(((Component)self).gameObject, actor)) { return (Interactability)0; } return orig.Invoke(self, actor); } private void Begin(orig_OnInteractionBegin orig, PurchaseInteraction self, Interactor actor) { if (!NetworkServer.active) { orig.Invoke(self, actor); return; } if (!Object.op_Implicit((Object)(object)((Component)self).GetComponent<InstanceHandler>()) && !PendingOwnership.IsPending(((Component)self).gameObject)) { orig.Invoke(self, actor); return; } ShopTerminalBehavior component = ((Component)self).GetComponent<ShopTerminalBehavior>(); Object item = (Object)((Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)component.serverMultiShopController)) ? ((object)component.serverMultiShopController) : ((object)self)); if (!InstanceAccessPolicy.CanInteract(((Component)self).gameObject, actor) || !self.available || !inProgress.Add(item)) { return; } try { orig.Invoke(self, actor); } finally { inProgress.Remove(item); } } } public sealed class SceneDirectorHandler : AbstractHookHandler { public override void RegisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown SceneDirector.Start += new Manipulator(Budget); } public override void UnregisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown SceneDirector.Start -= new Manipulator(Budget); } private void Budget(ILContext il) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown ILCursor val = new ILCursor(il); val.GotoNext((MoveType)2, new Func<Instruction, bool>[1] { (Instruction instruction) => ILPatternMatchingExt.MatchCallOrCallvirt<Run>(instruction, "get_participatingPlayerCount") }); val.EmitDelegate<Func<int, int>>((Func<int, int>)((int count) => base.ModConfig.ReduceInteractibleBudget.Value ? 1 : count)); } } public class SpawnCardHandler : AbstractHookHandler { public override void RegisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown SpawnCard.DoSpawn += new hook_DoSpawn(On_SpawnCard_DoSpawn); } public override void UnregisterHooks() { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown SpawnCard.DoSpawn -= new hook_DoSpawn(On_SpawnCard_DoSpawn); } private void HandleSpawnResult(SpawnCard spawnCard, SpawnResult result) { //IL_0000: 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) if (Object.op_Implicit((Object)(object)result.spawnedInstance)) { result.spawnedInstance.AddComponent<SpawnCardTracker>().SpawnCard = spawnCard; } } private SpawnResult On_SpawnCard_DoSpawn(orig_DoSpawn orig, SpawnCard self, Vector3 position, Quaternion rotation, DirectorSpawnRequest spawnRequest) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) SpawnResult result = orig.Invoke(self, position, rotation, spawnRequest); HandleSpawnResult(self, result); return result; } } }