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 ZeroGravityExtraction DroneToOrbItem Fix v1.0.5
ZeroGravityExtraction DroneToOrbItem Fix.dll
Decompiled 2 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using UnityEngine; [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("ZeroGravityExtractionDroneToOrbFix")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ZeroGravityExtractionDroneToOrbFix")] [assembly: AssemblyTitle("ZeroGravityExtractionDroneToOrbFix")] [assembly: AssemblyVersion("1.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 ZeroGravityExtractionDroneToOrbFix { [BepInPlugin("REPOJP.ZeroGravityExtractionDroneToOrbFix", "ZeroGravityExtraction DroneToOrbItem Fix", "1.0.5")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { private sealed class DroneAnchorLatch : MonoBehaviour { public object Drone; public GameObject Anchor; public object AnchorPhysObject; public float RefreshUntil; private bool _savedFlags; private object _targetNonValuables; private object _targetValuables; private object _targetEnemies; private object _targetPlayers; public void CaptureOriginalTargetFlags(object drone) { if (!_savedFlags && drone != null) { _targetNonValuables = GetMember(drone, "targetNonValuables"); _targetValuables = GetMember(drone, "targetValuables"); _targetEnemies = GetMember(drone, "targetEnemies"); _targetPlayers = GetMember(drone, "targetPlayers"); _savedFlags = true; } } public void ReleaseNow() { Release(); Object.Destroy((Object)(object)this); } private void LateUpdate() { if (Time.time > RefreshUntil || Drone == null || (Object)(object)Anchor == (Object)null || AnchorPhysObject == null) { ReleaseNow(); } else if (!IsPoweredZeroGravityDrone(Drone) || !IsDroneInsideAnchorZone((Component)(object)this, Anchor, 3.95f)) { ReleaseNow(); } else { ApplyDroneLatchTransform(Drone, (Component)(object)this, Anchor, AnchorPhysObject, force: false); } } private void OnDestroy() { Release(); } private void Release() { if (Drone != null && AnchorPhysObject != null) { ClearDroneAnchorTarget(Drone, AnchorPhysObject); RestoreOriginalTargetFlags(); } Drone = null; Anchor = null; AnchorPhysObject = null; } private void RestoreOriginalTargetFlags() { if (_savedFlags && Drone != null) { SetMember(Drone, "targetNonValuables", _targetNonValuables); SetMember(Drone, "targetValuables", _targetValuables); SetMember(Drone, "targetEnemies", _targetEnemies); SetMember(Drone, "targetPlayers", _targetPlayers); _savedFlags = false; } } } private sealed class Candidate { public readonly string ItemName; public readonly string ResourcePath; public readonly GameObject AffectPrefab; public readonly int Score; public Candidate(string itemName, string resourcePath, GameObject affectPrefab, int score) { ItemName = itemName; ResourcePath = resourcePath; AffectPrefab = affectPrefab; Score = score; } } public const string PluginGuid = "REPOJP.ZeroGravityExtractionDroneToOrbFix"; public const string PluginName = "ZeroGravityExtraction DroneToOrbItem Fix"; public const string PluginVersion = "1.0.5"; private static readonly Dictionary<string, Type> TypeCache = new Dictionary<string, Type>(); private static readonly HashSet<string> MissingTypeCache = new HashSet<string>(); private static readonly Dictionary<string, object> MemberCache = new Dictionary<string, object>(); private static readonly Dictionary<string, object> FieldCache = new Dictionary<string, object>(); private static readonly object MissingMember = new object(); private static readonly object MissingField = new object(); private static ManualLogSource Log; private static float _nextDebugLog; private static MethodInfo _isMultiplayerMethod; private Harmony _harmony; private bool _patched; private void Awake() { Log = ((BaseUnityPlugin)this).Logger; } private IEnumerator Start() { yield return null; yield return null; ApplyPatches(); } private void OnDestroy() { if (_harmony != null) { _harmony.UnpatchSelf(); } } private void ApplyPatches() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown if (!_patched) { _patched = true; _harmony = new Harmony("REPOJP.ZeroGravityExtractionDroneToOrbFix"); PatchZeroGravityExtraction(_harmony); Log.LogInfo((object)"ZeroGravityExtraction DroneToOrbItem Fix v1.0.5 loaded."); } } private static void PatchZeroGravityExtraction(Harmony harmony) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Expected O, but got Unknown //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Expected O, but got Unknown //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Expected O, but got Unknown //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Expected O, but got Unknown Type type = FindType("ZeroGravityExtraction.Services.ZeroGravityPadService"); if (type == null) { Log.LogError((object)"ZeroGravityPadService type was not found."); return; } MethodInfo methodInfo = AccessTools.Method(type, "TryResolveEffect", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(type, "ResetLevelState", (Type[])null, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(type, "EnsureAnchor", (Type[])null, (Type[])null); MethodInfo methodInfo4 = AccessTools.Method(type, "CollectDroneZoneTargets", (Type[])null, (Type[])null); MethodInfo methodInfo5 = AccessTools.Method(type, "IsPadPowered", (Type[])null, (Type[])null); if (methodInfo != null) { harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Plugin), "TryResolveEffectPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { Log.LogError((object)"TryResolveEffect method was not found."); } if (methodInfo2 != null) { harmony.Patch((MethodBase)methodInfo2, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "ResetLevelStatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (methodInfo3 != null) { harmony.Patch((MethodBase)methodInfo3, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "EnsureAnchorPostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (methodInfo4 != null) { harmony.Patch((MethodBase)methodInfo4, new HarmonyMethod(typeof(Plugin), "CollectDroneZoneTargetsPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } if (methodInfo5 != null) { harmony.Patch((MethodBase)methodInfo5, new HarmonyMethod(typeof(Plugin), "IsPadPoweredPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } PatchItemDrone(harmony); } private static void PatchItemDrone(Harmony harmony) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Expected O, but got Unknown Type type = FindType("ItemDrone"); if (!(type == null)) { MethodInfo methodInfo = AccessTools.Method(type, "Update", (Type[])null, (Type[])null); if (methodInfo != null) { harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "ItemDroneUpdatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } } } private static void ItemDroneUpdatePostfix(object __instance) { object zeroGravityPadServiceInstance = GetZeroGravityPadServiceInstance(); if (zeroGravityPadServiceInstance != null) { ConfigureVanillaPlusAnchors(zeroGravityPadServiceInstance); List<GameObject> droneAnchors = GetDroneAnchors(zeroGravityPadServiceInstance); if (droneAnchors.Count != 0) { EnforceDroneAnchorLatch(__instance, droneAnchors); } } } private static object GetZeroGravityPadServiceInstance() { object staticMember = GetStaticMember("ZeroGravityExtraction.Services.ZeroGravityPadService", "Instance"); if (staticMember != null) { return staticMember; } return GetStaticMember("ZeroGravityPadService", "Instance"); } private static void ResetLevelStatePostfix(object __instance) { ResetResolveFailure(__instance); SetMember(__instance, "_affectPrefab", null); SetMember(__instance, "_orbResourcePath", null); } private static bool TryResolveEffectPrefix(object __instance, ref bool __result) { __result = TryResolveEffect(__instance); return false; } private static void EnsureAnchorPostfix(object __instance) { ConfigureVanillaPlusAnchors(__instance); } private static void CollectDroneZoneTargetsPrefix(object __instance) { ConfigureVanillaPlusAnchors(__instance); EncourageZeroGravityDronesToAnchors(__instance); } private static bool IsPadPoweredPrefix(object __instance, object[] __args, ref bool __result) { __result = false; if (__args == null || __args.Length == 0) { return false; } object point = __args[0]; GameObject anchorForPoint = GetAnchorForPoint(__instance, point); if ((Object)(object)anchorForPoint == (Object)null) { return false; } object componentByName = GetComponentByName(anchorForPoint, "PhysGrabObject"); if (componentByName == null) { return false; } __result = HasPoweredZeroGravityDroneLatchedToAnchor(anchorForPoint, componentByName, 3.25f); return false; } private static void ConfigureVanillaPlusAnchors(object service) { IEnumerable dictionaryValues = GetDictionaryValues(GetMember(service, "_anchors")); if (dictionaryValues == null) { return; } foreach (object item in dictionaryValues) { GameObject val = (GameObject)((item is GameObject) ? item : null); if ((Object)(object)val == (Object)null) { continue; } object componentByName = GetComponentByName(val, "PadAnchor"); if (componentByName != null) { object member = GetMember(componentByName, "ButtonMode"); if (member is bool && (bool)member) { continue; } } ConfigureDroneAnchor(val); } } private static void ConfigureDroneAnchor(GameObject anchor) { if ((Object)(object)anchor == (Object)null) { return; } try { anchor.tag = "Phys Grab Object"; } catch { } try { int num = LayerMask.NameToLayer("PhysGrabObject"); if (num >= 0) { anchor.layer = num; } } catch { } Collider val = anchor.GetComponent<Collider>(); if ((Object)(object)val == (Object)null) { val = (Collider)(object)anchor.AddComponent<SphereCollider>(); } val.enabled = true; val.isTrigger = false; Rigidbody val2 = anchor.GetComponent<Rigidbody>(); if ((Object)(object)val2 == (Object)null) { val2 = anchor.AddComponent<Rigidbody>(); } val2.useGravity = false; val2.isKinematic = true; val2.constraints = (RigidbodyConstraints)126; object orAddComponentByName = GetOrAddComponentByName(anchor, "PhysGrabObject"); if (orAddComponentByName != null) { SetMember(orAddComponentByName, "isNonValuable", true); SetMember(orAddComponentByName, "isValuable", false); SetMember(orAddComponentByName, "isEnemy", false); SetMember(orAddComponentByName, "grabDisable", false); SetMember(orAddComponentByName, "disabled", false); SetMember(orAddComponentByName, "dead", false); } GetOrAddComponentByName(anchor, "PhysGrabObjectCollider"); Renderer component = anchor.GetComponent<Renderer>(); if ((Object)(object)component != (Object)null) { component.enabled = false; } } private static void EncourageZeroGravityDronesToAnchors(object service) { List<GameObject> droneAnchors = GetDroneAnchors(service); if (droneAnchors.Count == 0 || !(GetStaticMember("ItemDrone", "activeDrones") is IEnumerable enumerable)) { return; } foreach (object item in enumerable) { EnforceDroneAnchorLatch(item, droneAnchors); } } private static void EnforceDroneAnchorLatch(object drone, List<GameObject> anchors) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (drone == null || anchors == null || anchors.Count == 0) { return; } Component val = (Component)((drone is Component) ? drone : null); if ((Object)(object)val == (Object)null) { return; } DroneAnchorLatch component = val.gameObject.GetComponent<DroneAnchorLatch>(); if (!IsPoweredZeroGravityDrone(drone)) { if ((Object)(object)component != (Object)null) { component.ReleaseNow(); } else { ClearAnchorTargetIfNeeded(drone, anchors); } return; } GameObject val2 = FindNearestAnchor(val.transform.position, anchors, 3.75f); if ((Object)(object)val2 == (Object)null) { if ((Object)(object)component != (Object)null) { component.ReleaseNow(); } else { ClearAnchorTargetIfNeeded(drone, anchors); } return; } object componentByName = GetComponentByName(val2, "PhysGrabObject"); if (componentByName != null) { AttachDroneLatch(drone, val, val2, componentByName); } } private static List<GameObject> GetDroneAnchors(object service) { List<GameObject> list = new List<GameObject>(); IEnumerable dictionaryValues = GetDictionaryValues(GetMember(service, "_anchors")); if (dictionaryValues == null) { return list; } foreach (object item in dictionaryValues) { GameObject val = (GameObject)((item is GameObject) ? item : null); if ((Object)(object)val == (Object)null) { continue; } object componentByName = GetComponentByName(val, "PadAnchor"); if (componentByName != null) { object member = GetMember(componentByName, "ButtonMode"); if (member is bool && (bool)member) { continue; } } list.Add(val); } return list; } private static GameObject FindNearestAnchor(Vector3 position, List<GameObject> anchors, float maxDistance) { //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_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) GameObject result = null; float num = maxDistance * maxDistance; for (int i = 0; i < anchors.Count; i++) { GameObject val = anchors[i]; if (!((Object)(object)val == (Object)null)) { Vector3 val2 = val.transform.position - position; float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude; if (sqrMagnitude <= num) { num = sqrMagnitude; result = val; } } } return result; } private static bool IsDroneNearAnchorTarget(Component droneComponent, GameObject anchor, float maxDistance) { //IL_001a: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)droneComponent == (Object)null || (Object)(object)anchor == (Object)null) { return false; } Vector3 val = droneComponent.transform.position - anchor.transform.position; return ((Vector3)(ref val)).sqrMagnitude <= maxDistance * maxDistance; } private static void AttachDroneLatch(object drone, Component droneComponent, GameObject anchor, object anchorPhysObject) { if (drone != null && !((Object)(object)droneComponent == (Object)null) && !((Object)(object)anchor == (Object)null) && anchorPhysObject != null) { DroneAnchorLatch droneAnchorLatch = droneComponent.gameObject.GetComponent<DroneAnchorLatch>(); if ((Object)(object)droneAnchorLatch == (Object)null) { droneAnchorLatch = droneComponent.gameObject.AddComponent<DroneAnchorLatch>(); } droneAnchorLatch.CaptureOriginalTargetFlags(drone); droneAnchorLatch.Drone = drone; droneAnchorLatch.Anchor = anchor; droneAnchorLatch.AnchorPhysObject = anchorPhysObject; droneAnchorLatch.RefreshUntil = Time.time + 0.75f; ApplyDroneLatchTransform(drone, droneComponent, anchor, anchorPhysObject, force: false); } } private static void ApplyDroneLatchTransform(object drone, Component droneComponent, GameObject anchor, object anchorPhysObject, bool force) { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0161: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) if (drone == null || (Object)(object)droneComponent == (Object)null || (Object)(object)anchor == (Object)null || anchorPhysObject == null) { return; } if (!IsDroneInsideAnchorZone(droneComponent, anchor, 3.95f)) { ClearDroneAnchorTarget(drone, anchorPhysObject); return; } SetMember(drone, "targetNonValuables", true); SetMember(drone, "targetValuables", false); SetMember(drone, "targetEnemies", false); SetMember(drone, "targetPlayers", false); SetMember(drone, "magnetTargetPhysGrabObject", anchorPhysObject); SetMember(drone, "targetPhysGrabObject", anchorPhysObject); SetMember(drone, "currentTargetPhysGrabObject", anchorPhysObject); SetMember(drone, "magnetTargetTransform", anchor.transform); SetMember(drone, "targetTransform", anchor.transform); SetMember(drone, "magnetTargetGameObject", anchor); SetMember(drone, "targetGameObject", anchor); SetMember(drone, "magnetTargetPosition", anchor.transform.position); SetMember(drone, "targetPosition", anchor.transform.position); SetMember(drone, "magnetActive", true); if (!force && IsDroneGrabbed(droneComponent)) { return; } Component obj = FindMoveRoot(droneComponent); Vector3 position = anchor.transform.position; obj.transform.position = position; Rigidbody[] componentsInChildren = obj.gameObject.GetComponentsInChildren<Rigidbody>(true); foreach (Rigidbody val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { val.velocity = Vector3.zero; val.angularVelocity = Vector3.zero; } } } private static bool IsDroneInsideAnchorZone(Component droneComponent, GameObject anchor, float maxHorizontalDistance) { //IL_001a: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: 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_005f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)droneComponent == (Object)null || (Object)(object)anchor == (Object)null) { return false; } Vector3 val = droneComponent.transform.position - anchor.transform.position; if (val.x * val.x + val.z * val.z > maxHorizontalDistance * maxHorizontalDistance) { return false; } if (val.y > -2.5f) { return val.y < 6.5f; } return false; } private static Component FindMoveRoot(Component droneComponent) { if ((Object)(object)droneComponent == (Object)null) { return null; } object componentByName = GetComponentByName(droneComponent.gameObject, "PhysGrabObject"); Component val = (Component)((componentByName is Component) ? componentByName : null); if ((Object)(object)val != (Object)null) { return val; } object componentInParentByName = GetComponentInParentByName(droneComponent.gameObject, "PhysGrabObject"); val = (Component)((componentInParentByName is Component) ? componentInParentByName : null); if ((Object)(object)val != (Object)null) { return val; } return droneComponent; } private static bool IsDroneGrabbed(Component droneComponent) { if ((Object)(object)droneComponent == (Object)null) { return false; } object obj = GetComponentByName(droneComponent.gameObject, "PhysGrabObject"); if (obj == null) { obj = GetComponentInParentByName(droneComponent.gameObject, "PhysGrabObject"); } if (obj == null) { return false; } object member = GetMember(obj, "grabbed"); if (member is bool) { return (bool)member; } return false; } private static void ClearAnchorTargetIfNeeded(object drone, List<GameObject> anchors) { if (drone != null && anchors != null) { object member = GetMember(drone, "magnetTargetPhysGrabObject"); if (member != null && IsAnchorPhysObject(member, anchors)) { ClearDroneAnchorTarget(drone, member); } } } private static void ClearDroneAnchorTarget(object drone, object anchorPhysObject) { if (drone != null && anchorPhysObject != null && GetMember(drone, "magnetTargetPhysGrabObject") == anchorPhysObject) { SetMember(drone, "magnetTargetPhysGrabObject", null); SetMember(drone, "targetPhysGrabObject", null); SetMember(drone, "currentTargetPhysGrabObject", null); SetMember(drone, "magnetTargetTransform", null); SetMember(drone, "targetTransform", null); SetMember(drone, "magnetTargetGameObject", null); SetMember(drone, "targetGameObject", null); SetMember(drone, "magnetActive", false); } } private static GameObject GetAnchorForPoint(object service, object point) { if (service == null || point == null) { return null; } Object val = (Object)((point is Object) ? point : null); if (val == (Object)null) { return null; } if (!(GetMember(service, "_anchors") is IDictionary dictionary)) { return null; } object? obj = dictionary[val.GetInstanceID()]; return (GameObject)((obj is GameObject) ? obj : null); } private static bool HasPoweredZeroGravityDroneLatchedToAnchor(GameObject anchor, object anchorPhysObject, float maxDistance) { if (!(GetStaticMember("ItemDrone", "activeDrones") is IEnumerable enumerable)) { return false; } foreach (object item in enumerable) { if (!IsPoweredZeroGravityDrone(item)) { continue; } object member = GetMember(item, "magnetActive"); if ((!(member is bool) || (bool)member) && GetMember(item, "magnetTargetPhysGrabObject") == anchorPhysObject) { Component val = (Component)((item is Component) ? item : null); if (!((Object)(object)val != (Object)null) || IsDroneNearAnchorTarget(val, anchor, maxDistance)) { return true; } } } return false; } private static bool IsPoweredZeroGravityDrone(object drone) { if (drone == null) { return false; } object member = GetMember(drone, "itemActivated"); if (member is bool && !(bool)member) { return false; } Component val = (Component)((drone is Component) ? drone : null); if ((Object)(object)val == (Object)null || GetComponentByName(val.gameObject, "ItemDroneZeroGravity") == null) { return false; } object componentByName = GetComponentByName(val.gameObject, "ItemBattery"); if (componentByName != null) { object member2 = GetMember(componentByName, "batteryLife"); if (member2 is float && (float)member2 <= 0f) { return false; } } return true; } private static bool IsAnchorPhysObject(object physObject, List<GameObject> anchors) { if (physObject == null) { return false; } for (int i = 0; i < anchors.Count; i++) { object componentByName = GetComponentByName(anchors[i], "PhysGrabObject"); if (physObject == componentByName) { return true; } } return false; } private static object GetOrAddComponentByName(GameObject gameObject, string typeName) { if ((Object)(object)gameObject == (Object)null) { return null; } object componentByName = GetComponentByName(gameObject, typeName); if (componentByName != null) { return componentByName; } Type type = FindType(typeName); if (type == null) { return null; } try { return gameObject.AddComponent(type); } catch { return null; } } private static object GetComponentByName(GameObject gameObject, string typeName) { if ((Object)(object)gameObject == (Object)null) { return null; } Type type = FindType(typeName); if (type == null) { return null; } try { return gameObject.GetComponent(type); } catch { return null; } } private static object GetComponentInParentByName(GameObject gameObject, string typeName) { if ((Object)(object)gameObject == (Object)null) { return null; } Type type = FindType(typeName); if (type == null) { return null; } try { return gameObject.GetComponentInParent(type); } catch { return null; } } private static bool TryResolveEffect(object service) { ResetResolveFailure(service); object staticMember = GetStaticMember("StatsManager", "instance"); if (staticMember == null) { return false; } IEnumerable dictionaryValues = GetDictionaryValues(GetMember(staticMember, "itemDictionary")); if (dictionaryValues == null) { return false; } bool flag = IsMultiplayer(); Candidate candidate = null; int num = 0; int num2 = 0; int num3 = 0; int num4 = 0; foreach (object item in dictionaryValues) { num++; if (item == null) { continue; } GameObject prefabFromRef = GetPrefabFromRef(GetMember(item, "prefab")); if ((Object)(object)prefabFromRef == (Object)null) { continue; } object obj = FindComponentInChildren(prefabFromRef, "ItemStaffZeroGravity"); if (obj == null) { continue; } num2++; object member = GetMember(obj, "projectilePrefab"); string stringMember = GetStringMember(member, "ResourcePath"); GameObject prefabFromRef2 = GetPrefabFromRef(member); if ((Object)(object)prefabFromRef2 == (Object)null) { continue; } object obj2 = FindComponentInChildren(prefabFromRef2, "SemiAreaOfEffect"); if (obj2 == null) { continue; } GameObject prefabFromRef3 = GetPrefabFromRef(GetMember(obj2, "semiAffectPrefab")); if ((Object)(object)prefabFromRef3 == (Object)null || FindComponentInChildren(prefabFromRef3, "SemiAffectZeroGravity") == null) { continue; } num3++; if (flag && string.IsNullOrEmpty(stringMember)) { num4++; continue; } string unityName = GetUnityName(item); Candidate candidate2 = new Candidate(unityName, stringMember, prefabFromRef3, ScoreCandidate(unityName, stringMember)); if (candidate == null || candidate2.Score > candidate.Score) { candidate = candidate2; } } if (candidate != null) { SetMember(service, "_affectPrefab", candidate.AffectPrefab); SetMember(service, "_orbResourcePath", string.IsNullOrEmpty(candidate.ResourcePath) ? null : candidate.ResourcePath); ResetResolveFailure(service); Log.LogInfo((object)("Resolved zero-gravity effect from '" + candidate.ItemName + "' resourcePath='" + NullText(candidate.ResourcePath) + "'.")); return true; } if (Time.realtimeSinceStartup >= _nextDebugLog) { _nextDebugLog = Time.realtimeSinceStartup + 15f; Log.LogDebug((object)("Zero-gravity effect not ready. scanned=" + num + " staff=" + num2 + " effect=" + num3 + " rejectedForMultiplayerPath=" + num4 + ".")); } ResetResolveFailure(service); return false; } private static int ScoreCandidate(string itemName, string resourcePath) { int num = 0; string text = ((itemName ?? string.Empty) + " " + (resourcePath ?? string.Empty)).ToLowerInvariant(); if (!string.IsNullOrEmpty(resourcePath)) { num += 1000; } if (text.Contains("staff")) { num += 100; } if (text.Contains("orb")) { num -= 25; } if (text.Contains("zero") && text.Contains("gravity")) { num += 10; } return num; } private static void ResetResolveFailure(object service) { if (service != null) { SetMember(service, "_resolveFailed", false); SetMember(service, "_resolveAttempts", 0); } } private static object GetStaticMember(string typeName, string memberName) { Type type = FindType(typeName); if (type == null) { return null; } return GetMember(type, memberName); } private static object GetMember(object target, string memberName) { if (target == null) { return null; } bool num = target is Type; Type type = (num ? ((Type)target) : target.GetType()); object obj = (num ? null : target); object cachedMember = GetCachedMember(type, memberName); if (cachedMember == MissingMember) { return null; } PropertyInfo propertyInfo = cachedMember as PropertyInfo; if (propertyInfo != null) { try { return propertyInfo.GetValue(obj, null); } catch { return null; } } FieldInfo fieldInfo = cachedMember as FieldInfo; if (fieldInfo != null) { try { return fieldInfo.GetValue(obj); } catch { return null; } } return null; } private static object GetCachedMember(Type type, string memberName) { string key = type.AssemblyQualifiedName + "|" + memberName; if (MemberCache.TryGetValue(key, out var value)) { return value; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; PropertyInfo property = type.GetProperty(memberName, bindingAttr); if (property != null) { MemberCache[key] = property; return property; } FieldInfo field = type.GetField(memberName, bindingAttr); if (field != null) { MemberCache[key] = field; return field; } MemberCache[key] = MissingMember; return MissingMember; } private static void SetMember(object target, string memberName, object value) { if (target == null) { return; } FieldInfo cachedField = GetCachedField(target.GetType(), memberName); if (cachedField == null) { return; } try { cachedField.SetValue(target, value); } catch { } } private static FieldInfo GetCachedField(Type type, string memberName) { string key = type.AssemblyQualifiedName + "|" + memberName; if (FieldCache.TryGetValue(key, out var value)) { if (value != MissingField) { return value as FieldInfo; } return null; } BindingFlags bindingAttr = BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic; FieldInfo field = type.GetField(memberName, bindingAttr); if (field == null) { FieldCache[key] = MissingField; return null; } FieldCache[key] = field; return field; } private static IEnumerable GetDictionaryValues(object dictionary) { if (dictionary == null) { return null; } if (dictionary is IDictionary dictionary2) { return dictionary2.Values; } return GetMember(dictionary, "Values") as IEnumerable; } private static GameObject GetPrefabFromRef(object prefabRef) { if (prefabRef == null) { return null; } object member = GetMember(prefabRef, "Prefab"); return (GameObject)((member is GameObject) ? member : null); } private static string GetStringMember(object target, string memberName) { return GetMember(target, memberName) as string; } private static object FindComponentInChildren(GameObject root, string typeName) { if ((Object)(object)root == (Object)null) { return null; } Type type = FindType(typeName); if (type == null) { return null; } try { return root.GetComponentInChildren(type, true); } catch { return null; } } private static Type FindType(string typeName) { if (TypeCache.TryGetValue(typeName, out var value)) { return value; } if (MissingTypeCache.Contains(typeName)) { return null; } Type type = AccessTools.TypeByName(typeName); if (type != null) { TypeCache[typeName] = type; return type; } Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); for (int i = 0; i < assemblies.Length; i++) { try { type = assemblies[i].GetType(typeName, throwOnError: false); if (type != null) { TypeCache[typeName] = type; return type; } Type[] types = assemblies[i].GetTypes(); for (int j = 0; j < types.Length; j++) { if (types[j].Name == typeName || types[j].FullName == typeName) { TypeCache[typeName] = types[j]; return types[j]; } } } catch (ReflectionTypeLoadException ex) { Type[] types2 = ex.Types; foreach (Type type2 in types2) { if (type2 != null && (type2.Name == typeName || type2.FullName == typeName)) { TypeCache[typeName] = type2; return type2; } } } catch { } } MissingTypeCache.Add(typeName); return null; } private static bool IsMultiplayer() { if (_isMultiplayerMethod == null) { Type type = FindType("SemiFunc"); if (type == null) { return false; } _isMultiplayerMethod = AccessTools.Method(type, "IsMultiplayer", (Type[])null, (Type[])null); if (_isMultiplayerMethod == null) { return false; } } try { object obj = _isMultiplayerMethod.Invoke(null, null); if (obj is bool) { return (bool)obj; } } catch { } return false; } private static string GetUnityName(object obj) { Object val = (Object)((obj is Object) ? obj : null); if (val != (Object)null) { return val.name; } return obj.GetType().Name; } private static string NullText(string text) { if (!string.IsNullOrEmpty(text)) { return text; } return "<empty>"; } } }