Decompiled source of PropHunt v1.2.1
PropHunt/PropHunt.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using ComputerysModdingUtilities; using FishNet; using FishNet.Broadcast; using FishNet.Connection; using FishNet.Managing; using FishNet.Managing.Client; using FishNet.Managing.Object; using FishNet.Managing.Server; using FishNet.Object; using FishNet.Object.Synchronizing; using FishNet.Serializing; using FishNet.Transporting; using HarmonyLib; using Microsoft.CodeAnalysis; using Steamworks; using TMPro; using Unity.Collections; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: StraftatMod(false)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("0.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 PropHunt { internal static class Disguise { internal sealed class HiderSlot { internal int PlayerId; internal bool IsLocal; internal GameObject Clone; internal readonly List<Renderer> HiddenRenderers = new List<Renderer>(); internal readonly List<Collider> HiddenColliders = new List<Collider>(); internal PlayerHealth HiddenGraphicsOwner; internal readonly List<Mesh> OwnedMeshes = new List<Mesh>(4); internal readonly List<Material> OwnedMaterials = new List<Material>(8); internal bool CloneHitboxOk; internal bool CleanupPending; internal float CleanupPendingSince; internal float CleanupExtraSeconds; internal bool DeathHandled; } private enum MeshTier { None, SharedMesh, Asset, BatchExtract, ColliderProxy } private const float PickRange = 6f; private const int MaxAncestorHops = 4; private const string CloneName = "PropHunt_Disguise"; private const string HitboxName = "PropHunt_Hitbox"; private const int ShootableLayer = 11; private const string WalkBoxName = "PropHunt_WalkBox"; private const int WalkableLayer = 14; private const string PartName = "PropHunt_Part"; private const string DummyName = "PropHunt_WeaponDummy"; private const string LightName = "PropHunt_SpawnerLight"; private const string WalkColName = "PropHunt_WalkCollider"; private const string ProbeAnchorName = "PropHunt_ProbeAnchor"; private const string OutlineWidthProp = "_OutlineWidth"; private const string RuntimeMeshPrefix = "PropHunt_"; internal static readonly int PickMask = -2558413; private static readonly Dictionary<int, HiderSlot> _slots = new Dictionary<int, HiderSlot>(8); private static readonly List<HiderSlot> _slotList = new List<HiderSlot>(8); private static Dictionary<string, List<Mesh>> _assetMeshesByName; private static int _assetCacheSceneHandle; private static string _assetCacheSceneName; private static PropertyInfo _staticBatchRootProp; private static bool _staticBatchRootResolved; private static readonly RaycastHit[] _rayScratch = (RaycastHit[])(object)new RaycastHit[256]; private const float SpatialFallbackRange = 0.75f; private const float MaxGroundSlack = 0.6f; private const float WallMountMaxGap = 0.1f; private const float WallProbeMargin = 0.3f; internal const float WallNormalMaxY = 0.35f; private const float PendingCleanupMaxSeconds = 10f; internal static List<HiderSlot> SlotList => _slotList; private static HiderSlot GetOrCreateSlot(int playerId) { if (_slots.TryGetValue(playerId, out var value)) { return value; } value = new HiderSlot { PlayerId = playerId }; _slots[playerId] = value; _slotList.Add(value); return value; } private static void RemoveSlot(HiderSlot slot) { _slots.Remove(slot.PlayerId); _slotList.Remove(slot); } internal static bool SlotHasLiveClone(int playerId) { if (_slots.TryGetValue(playerId, out var value)) { return (Object)(object)value.Clone != (Object)null; } return false; } internal static bool RaycastNearestIgnoringRoot(Vector3 origin, Vector3 dir, float range, Transform ignoreRoot, out RaycastHit best, bool ignoreAllClones = false) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: 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) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) best = default(RaycastHit); int num = Physics.RaycastNonAlloc(origin, dir, _rayScratch, range, PickMask, (QueryTriggerInteraction)1); float num2 = float.MaxValue; for (int i = 0; i < num; i++) { RaycastHit val = _rayScratch[i]; if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !(((RaycastHit)(ref val)).distance >= num2) && (!((Object)(object)ignoreRoot != (Object)null) || !((Component)((RaycastHit)(ref val)).collider).transform.IsChildOf(ignoreRoot)) && (!ignoreAllClones || !IsUnderClone(((Component)((RaycastHit)(ref val)).collider).transform))) { best = val; num2 = ((RaycastHit)(ref val)).distance; } } return num2 < float.MaxValue; } internal static bool SphereCastNearestIgnoringRoot(Vector3 origin, float radius, Vector3 dir, float range, Transform ignoreRoot, out float distance) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) distance = 0f; int num = Physics.SphereCastNonAlloc(origin, radius, dir, _rayScratch, range, PickMask, (QueryTriggerInteraction)1); float num2 = float.MaxValue; for (int i = 0; i < num; i++) { RaycastHit val = _rayScratch[i]; if (!((Object)(object)((RaycastHit)(ref val)).collider == (Object)null) && !(((RaycastHit)(ref val)).distance >= num2) && (!((Object)(object)ignoreRoot != (Object)null) || !((Component)((RaycastHit)(ref val)).collider).transform.IsChildOf(ignoreRoot))) { num2 = ((RaycastHit)(ref val)).distance; } } if (num2 == float.MaxValue) { return false; } distance = num2; return true; } internal static bool IsUnderClone(Transform t) { if ((Object)(object)t == (Object)null) { return false; } for (int i = 0; i < _slotList.Count; i++) { GameObject clone = _slotList[i].Clone; if ((Object)(object)clone != (Object)null && t.IsChildOf(clone.transform)) { return true; } } return false; } internal static bool TryPick(FirstPersonController fpc, out string path, out string meshName, out Vector3 lossyScale, out int spawnerObjectId, out string fail) { //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_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) path = null; meshName = null; lossyScale = Vector3.one; spawnerObjectId = -1; fail = "internal error"; try { Camera playerCamera = fpc.playerCamera; if ((Object)(object)playerCamera == (Object)null) { fail = "no camera"; return PickFail(fail); } GameObject val; if (!RaycastNearestIgnoringRoot(((Component)playerCamera).transform.position, ((Component)playerCamera).transform.forward, 6f, ((Component)fpc).transform.root, out var best, ignoreAllClones: true)) { val = RayMissFallback(((Component)playerCamera).transform.position, ((Component)playerCamera).transform.forward); if ((Object)(object)val == (Object)null) { fail = "nothing in range (6 m)"; PickFail(fail); fail = "Nothing there to disguise as."; return false; } } else { val = ChooseCandidate(best, out fail); if ((Object)(object)val == (Object)null) { PickFail(fail); fail = FriendlyPickFail(fail); return false; } } if (!TryRecoverRenderMesh(val, out var mesh, out var _, out var meshKey, out var ownsMesh, out fail)) { Plugin.Activity("Disguise: pick '" + ((Object)val).name + "' failed mesh recovery - " + fail); return false; } if (ownsMesh && (Object)(object)mesh != (Object)null) { Object.Destroy((Object)(object)mesh); } try { ItemSpawner componentInParent = val.GetComponentInParent<ItemSpawner>(); if ((Object)(object)componentInParent != (Object)null && (Object)(object)((NetworkBehaviour)componentInParent).NetworkObject != (Object)null) { spawnerObjectId = ((NetworkBehaviour)componentInParent).NetworkObject.ObjectId; Plugin.Activity($"Disguise: pick resolved spawner '{((Object)componentInParent).name}' (ObjectId {spawnerObjectId})."); } } catch (Exception e) { Plugin.LogOnce("Disguise.SpawnerDetect", e); spawnerObjectId = -1; } path = BuildScenePath(val.transform); meshName = meshKey; lossyScale = val.transform.lossyScale; return true; } catch (Exception e2) { Plugin.LogOnce("Disguise.TryPick", e2); fail = "error (see log)"; return false; } } private static bool PickFail(string fail) { Plugin.Activity("Disguise: pick failed - " + fail); return false; } private static string FriendlyPickFail(string fail) { try { if (fail == null || !fail.StartsWith("too big (", StringComparison.Ordinal) || !fail.EndsWith(" m)", StringComparison.Ordinal)) { return fail; } if (float.TryParse(fail.Substring("too big (".Length, fail.Length - "too big (".Length - " m)".Length), out var result) && result > 50f) { return "That's part of the map - try a smaller object."; } return fail; } catch (Exception e) { Plugin.LogOnce("Disguise.FriendlyFail", e); return fail; } } private static GameObject ChooseCandidate(RaycastHit hit, out string fail) { //IL_0328: 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_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01a9: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_022e: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) fail = "that's not a solid prop"; try { HashSet<GameObject> hashSet = new HashSet<GameObject>(); List<GameObject> list = new List<GameObject>(16); Transform val = ((Component)((RaycastHit)(ref hit)).collider).transform; int num = 0; while (num <= 4 && (Object)(object)val != (Object)null) { if (hashSet.Add(((Component)val).gameObject)) { list.Add(((Component)val).gameObject); } num++; val = val.parent; } MeshFilter[] componentsInChildren = ((Component)((RaycastHit)(ref hit)).collider).GetComponentsInChildren<MeshFilter>(true); foreach (MeshFilter val2 in componentsInChildren) { if ((Object)(object)val2 != (Object)null && hashSet.Add(((Component)val2).gameObject)) { list.Add(((Component)val2).gameObject); } } GameObject val3 = null; float num2 = -1f; string strB = null; GameObject val4 = null; float num3 = float.MaxValue; string text = null; float num4 = float.MaxValue; int num5 = 0; int num6 = 0; foreach (GameObject item in list) { MeshFilter component = item.GetComponent<MeshFilter>(); if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null || ((Object)item).name == "PropHunt_Disguise" || IsUnderClone(item.transform)) { continue; } MeshRenderer component2 = item.GetComponent<MeshRenderer>(); if ((Object)(object)component2 == (Object)null) { continue; } if (!((Renderer)component2).enabled || !item.activeInHierarchy) { if (num5 < 12) { num5++; Plugin.Activity("Disguise: pick candidate '" + ((Object)item).name + "' skipped - not visible."); } else { num6++; } continue; } Bounds bounds = ((Renderer)component2).bounds; float num7 = Vector3.Distance(((RaycastHit)(ref hit)).point, ((Bounds)(ref bounds)).ClosestPoint(((RaycastHit)(ref hit)).point)); if (!ValidateSource(item, out var fail2)) { if (num5 < 12) { num5++; Plugin.Activity("Disguise: pick candidate '" + ((Object)item).name + "' rejected - " + fail2); } else { num6++; } if (num7 < num4) { num4 = num7; text = fail2; } continue; } Bounds val5 = bounds; ((Bounds)(ref val5)).Expand(0.6f); if (((Bounds)(ref val5)).Contains(((RaycastHit)(ref hit)).point)) { Vector3 size = ((Bounds)(ref bounds)).size; float num8 = size.x * size.y * size.z; string text2 = BuildScenePath(item.transform); if ((Object)(object)val3 == (Object)null || num8 > num2 || (num8 == num2 && string.CompareOrdinal(text2, strB) < 0)) { val3 = item; num2 = num8; strB = text2; } } else if (num7 < num3) { val4 = item; num3 = num7; } } if (num6 > 0) { Plugin.Activity($"Disguise: {num6} more candidate rejections suppressed (large subtree)."); } if ((Object)(object)val3 != (Object)null) { Plugin.Activity($"Disguise: pick chose '{((Object)val3).name}' (contains hit, vol {num2:0.###})"); return val3; } if ((Object)(object)val4 != (Object)null) { Plugin.Activity($"Disguise: pick chose '{((Object)val4).name}' (nearest to hit, {num3:0.##} m)"); return val4; } GameObject val6 = SpatialFallback(((RaycastHit)(ref hit)).point); if ((Object)(object)val6 != (Object)null) { return val6; } if (text != null) { fail = text; } return null; } catch (Exception e) { Plugin.LogOnce("Disguise.ChooseCandidate", e); return null; } } private static GameObject SpatialFallback(Vector3 hitPoint) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) try { float bestSqrOut; GameObject val = ScanNearestValidRenderer((Bounds b) => ((Bounds)(ref b)).SqrDistance(hitPoint), 0.5625f, out bestSqrOut); if ((Object)(object)val != (Object)null) { Plugin.Activity($"Disguise: spatial fallback chose '{((Object)val).name}' (dist {Mathf.Sqrt(bestSqrOut):0.00})"); } return val; } catch (Exception e) { Plugin.LogOnce("Disguise.SpatialFallback", e); return null; } } private static GameObject RayMissFallback(Vector3 origin, Vector3 dir) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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) try { float bestSqrOut; GameObject val = ScanNearestValidRenderer(delegate(Bounds b) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Clamp(Vector3.Dot(((Bounds)(ref b)).center - origin, dir), 0f, 6f); return ((Bounds)(ref b)).SqrDistance(origin + dir * num); }, 0.5625f, out bestSqrOut); if ((Object)(object)val != (Object)null) { Plugin.Activity($"Disguise: pick ray-miss fallback chose '{((Object)val).name}' (dist {Mathf.Sqrt(bestSqrOut):0.00})"); } return val; } catch (Exception e) { Plugin.LogOnce("Disguise.RayMissFallback", e); return null; } } private static GameObject ScanNearestValidRenderer(Func<Bounds, float> sqrDistOf, float maxSqr, out float bestSqrOut) { //IL_0098: Unknown result type (might be due to invalid IL or missing references) GameObject val = null; float num = float.MaxValue; string text = null; MeshRenderer[] array = Object.FindObjectsOfType<MeshRenderer>(); foreach (MeshRenderer val2 in array) { if ((Object)(object)val2 == (Object)null || !((Renderer)val2).enabled) { continue; } GameObject gameObject = ((Component)val2).gameObject; if (!gameObject.activeInHierarchy || ((Object)gameObject).name == "PropHunt_Disguise" || IsUnderClone(gameObject.transform)) { continue; } MeshFilter component = gameObject.GetComponent<MeshFilter>(); if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null) { continue; } float num2 = sqrDistOf(((Renderer)val2).bounds); if (num2 > maxSqr || num2 > num || !ValidateSource(gameObject, out var _)) { continue; } if (num2 < num) { val = gameObject; num = num2; text = null; continue; } if (text == null) { text = BuildScenePath(val.transform); } string text2 = BuildScenePath(gameObject.transform); if (string.CompareOrdinal(text2, text) < 0) { val = gameObject; text = text2; } } bestSqrOut = num; return val; } private static bool ValidateSource(GameObject go, out string fail) { //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) fail = null; if ((Object)(object)go.GetComponentInParent<ItemBehaviour>() != (Object)null) { fail = "that's a weapon/item"; return false; } if ((Object)(object)go.GetComponentInParent<PlayerHealth>() != (Object)null) { fail = "that's a player"; return false; } string name = ((Object)go).name; switch (name) { case "PROC_PLANE": case "SKINNED_PROC_PLANE": case "GlassGib": case "Bullet Hole": fail = "that's combat debris"; Plugin.Activity("Disguise: leftover excluded '" + name + "' (debris GO name)."); return false; default: { string name2 = ((Object)go.transform.root).name; if (name2.EndsWith("(Clone)", StringComparison.Ordinal)) { fail = "that's combat debris"; Plugin.Activity("Disguise: leftover excluded '" + name + "' (runtime-spawned root '" + name2 + "')."); return false; } if ((Object)(object)go.GetComponent<WFX_BulletHoleDecal>() != (Object)null) { fail = "that's combat debris"; Plugin.Activity("Disguise: leftover excluded '" + name + "' (bullet-hole decal)."); return false; } if ((Object)(object)go.GetComponentInParent<BodyParts>() != (Object)null) { fail = "that's combat debris"; Plugin.Activity("Disguise: leftover excluded '" + name + "' (dismemberment gib)."); return false; } NetworkObject componentInParent = go.GetComponentInParent<NetworkObject>(); if ((Object)(object)componentInParent != (Object)null && !componentInParent.IsSceneObject) { fail = "that's a networked object"; return false; } if (go.tag == "vfx" || go.tag == "Hat") { fail = "that's not a solid prop"; return false; } MeshRenderer component = go.GetComponent<MeshRenderer>(); if ((Object)(object)component == (Object)null) { fail = "that's not a solid prop"; return false; } Bounds bounds = ((Renderer)component).bounds; Vector3 size = ((Bounds)(ref bounds)).size; float num = Mathf.Max(size.x, Mathf.Max(size.y, size.z)); float value = Plugin.CfgMinPropSize.Value; float value2 = Plugin.CfgMaxPropSize.Value; if (num < value) { fail = $"too small ({num:0.0} m)"; return false; } if (num > value2) { fail = $"too big ({num:0.0} m)"; return false; } return true; } } } private static string BuildScenePath(Transform t) { StringBuilder stringBuilder = new StringBuilder(128); BuildScenePathInto(stringBuilder, t); return stringBuilder.ToString(); } private static void BuildScenePathInto(StringBuilder sb, Transform t) { if ((Object)(object)t.parent != (Object)null) { BuildScenePathInto(sb, t.parent); sb.Append('/'); } sb.Append(((Object)t).name); } internal static bool TryRecoverRenderMesh(GameObject go, out Mesh mesh, out Material[] materials, out string meshKey, out bool ownsMesh, out string fail) { mesh = null; materials = null; meshKey = null; ownsMesh = false; fail = "that prop can't be copied - pick a movable one"; MeshFilter component = go.GetComponent<MeshFilter>(); MeshRenderer component2 = go.GetComponent<MeshRenderer>(); if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null || (Object)(object)component2 == (Object)null) { return false; } Mesh assetMesh; MeshTier meshTier = DecideTier(go, component, component2, out assetMesh); meshKey = KeyForTier(go, component, meshTier); switch (meshTier) { case MeshTier.SharedMesh: mesh = component.sharedMesh; materials = ((Renderer)component2).sharedMaterials; Plugin.Activity("Disguise: tier A (sharedMesh) serves '" + ((Object)go).name + "'."); return true; case MeshTier.Asset: mesh = assetMesh; materials = ((Renderer)component2).sharedMaterials; Plugin.Activity("Disguise: tier ASSET ('" + ((Object)assetMesh).name + "') serves '" + ((Object)go).name + "'."); return true; case MeshTier.BatchExtract: try { if (TryExtractSubMeshes(go, component2, component.sharedMesh, out mesh)) { materials = ((Renderer)component2).sharedMaterials; ownsMesh = true; Plugin.Activity("Disguise: tier C (batch extract) serves '" + ((Object)go).name + "'."); return true; } } catch (Exception e) { Plugin.LogOnce("Disguise.TierCExtract", e); mesh = null; } break; default: meshKey = null; return false; case MeshTier.ColliderProxy: break; } MeshCollider component3 = go.GetComponent<MeshCollider>(); if ((Object)(object)component3 != (Object)null && (Object)(object)component3.sharedMesh != (Object)null && ColliderMeshLooksRenderable(go, component3, component2)) { mesh = component3.sharedMesh; materials = ((Renderer)component2).sharedMaterials; Plugin.Activity("Disguise: tier B (collider proxy) serves '" + ((Object)go).name + "'."); return true; } meshKey = null; mesh = null; return false; } private static MeshTier DecideTier(GameObject go, MeshFilter mf, MeshRenderer mr, out Mesh assetMesh) { assetMesh = null; if (!((Renderer)mr).isPartOfStaticBatch) { return MeshTier.SharedMesh; } if (TryFindAssetMesh(go, mr, out assetMesh)) { return MeshTier.Asset; } if (mf.sharedMesh.isReadable) { return MeshTier.BatchExtract; } MeshCollider component = go.GetComponent<MeshCollider>(); if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) { return MeshTier.ColliderProxy; } return MeshTier.None; } private static string KeyForTier(GameObject go, MeshFilter mf, MeshTier tier) { switch (tier) { case MeshTier.SharedMesh: return ((Object)mf.sharedMesh).name; case MeshTier.Asset: return "asset:" + BaseAssetName(((Object)go).name); case MeshTier.BatchExtract: return "batch:" + ((Object)mf.sharedMesh).name; case MeshTier.ColliderProxy: { MeshCollider component = go.GetComponent<MeshCollider>(); if (!((Object)(object)component != (Object)null) || !((Object)(object)component.sharedMesh != (Object)null)) { return null; } return "col:" + ((Object)component.sharedMesh).name; } default: return null; } } private static bool ColliderMeshLooksRenderable(GameObject go, MeshCollider mc, MeshRenderer mr) { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) try { string text = (((Object)mc.sharedMesh).name ?? "").ToLowerInvariant(); if (text.Contains("collider") || text.Contains("collision") || text.Contains("ucx") || text.Contains("phys")) { return false; } Bounds bounds = mc.sharedMesh.bounds; Vector3 val = Vector3.Scale(((Bounds)(ref bounds)).size, go.transform.lossyScale); float magnitude = ((Vector3)(ref val)).magnitude; bounds = ((Renderer)mr).bounds; val = ((Bounds)(ref bounds)).size; float magnitude2 = ((Vector3)(ref val)).magnitude; if (magnitude < 0.0001f || magnitude2 < 0.0001f) { return false; } float num = magnitude2 / magnitude; return num >= 0.75f && num <= 1.35f; } catch (Exception e) { Plugin.LogOnce("Disguise.TierBGate", e); return false; } } private static string GetMeshKey(GameObject go) { MeshFilter component = go.GetComponent<MeshFilter>(); MeshRenderer component2 = go.GetComponent<MeshRenderer>(); if ((Object)(object)component == (Object)null || (Object)(object)component.sharedMesh == (Object)null || (Object)(object)component2 == (Object)null) { return null; } Mesh assetMesh; return KeyForTier(go, component, DecideTier(go, component, component2, out assetMesh)); } private static bool TryFindAssetMesh(GameObject go, MeshRenderer mr, out Mesh mesh) { mesh = null; try { string text = BaseAssetName(((Object)go).name); if (string.IsNullOrEmpty(text)) { return false; } Dictionary<string, List<Mesh>> assetMeshCache = GetAssetMeshCache(); if (assetMeshCache == null || !assetMeshCache.TryGetValue(text, out var value) || value == null) { return false; } foreach (Mesh item in value) { if (!((Object)(object)item == (Object)null) && AssetMeshMatchesRenderer(item, go, mr)) { mesh = item; return true; } } return false; } catch (Exception e) { Plugin.LogOnce("Disguise.AssetLookup", e); return false; } } private static string BaseAssetName(string goName) { if (goName == null) { return null; } string text = goName.Trim(); bool flag = true; while (flag && text.Length > 0) { flag = false; if (text.EndsWith("(Clone)", StringComparison.Ordinal)) { text = text.Substring(0, text.Length - "(Clone)".Length).TrimEnd(Array.Empty<char>()); flag = true; } else { if (text[text.Length - 1] != ')') { continue; } int num = text.LastIndexOf('('); if (num <= 0 || text[num - 1] != ' ' || num + 1 >= text.Length - 1) { continue; } bool flag2 = true; for (int i = num + 1; i < text.Length - 1; i++) { if (!char.IsDigit(text[i])) { flag2 = false; break; } } if (flag2) { text = text.Substring(0, num - 1).TrimEnd(Array.Empty<char>()); flag = true; } } } return text; } private static Dictionary<string, List<Mesh>> GetAssetMeshCache() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) Scene activeScene = SceneManager.GetActiveScene(); int handle = ((Scene)(ref activeScene)).handle; string name = ((Scene)(ref activeScene)).name; if (_assetMeshesByName != null && handle == _assetCacheSceneHandle && name == _assetCacheSceneName) { return _assetMeshesByName; } Dictionary<string, List<Mesh>> dictionary = new Dictionary<string, List<Mesh>>(512, StringComparer.Ordinal); Mesh[] array = Resources.FindObjectsOfTypeAll<Mesh>(); foreach (Mesh val in array) { if ((Object)(object)val == (Object)null) { continue; } string name2 = ((Object)val).name; if (!string.IsNullOrEmpty(name2) && !name2.StartsWith("PropHunt_", StringComparison.Ordinal)) { if (!dictionary.TryGetValue(name2, out var value)) { value = (dictionary[name2] = new List<Mesh>(1)); } value.Add(val); } } foreach (List<Mesh> value2 in dictionary.Values) { if (value2.Count > 1) { value2.Sort(CompareAssetMeshes); } } _assetMeshesByName = dictionary; _assetCacheSceneHandle = handle; _assetCacheSceneName = name; Plugin.Activity($"Disguise: asset mesh cache built ({dictionary.Count} names)."); return dictionary; } private static int CompareAssetMeshes(Mesh a, Mesh b) { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_0049: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0065: Unknown result type (might be due to invalid IL or missing references) bool flag = (Object)(object)a == (Object)null; bool flag2 = (Object)(object)b == (Object)null; if (flag || flag2) { if (flag != flag2) { if (!flag) { return -1; } return 1; } return 0; } int num = a.vertexCount.CompareTo(b.vertexCount); if (num == 0) { Bounds bounds = a.bounds; Vector3 size = ((Bounds)(ref bounds)).size; float sqrMagnitude = ((Vector3)(ref size)).sqrMagnitude; bounds = b.bounds; size = ((Bounds)(ref bounds)).size; return sqrMagnitude.CompareTo(((Vector3)(ref size)).sqrMagnitude); } return num; } private static bool AssetMeshMatchesRenderer(Mesh mesh, GameObject go, MeshRenderer mr) { //IL_0006: 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_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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //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_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) Bounds val = TransformBounds(go.transform.localToWorldMatrix, mesh.bounds); Vector3 size = ((Bounds)(ref val)).size; Bounds bounds = ((Renderer)mr).bounds; Vector3 size2 = ((Bounds)(ref bounds)).size; for (int i = 0; i < 3; i++) { if (((Vector3)(ref size))[i] < 0.0001f || ((Vector3)(ref size2))[i] < 0.0001f) { return false; } float num = ((Vector3)(ref size2))[i] / ((Vector3)(ref size))[i]; if (num < 0.85f || num > 1.18f) { return false; } } return true; } private static bool TryExtractSubMeshes(GameObject go, MeshRenderer mr, Mesh combined, out Mesh extracted) { //IL_003d: 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_0042: 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) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: 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_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_009b: 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_024b: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) //IL_0254: Unknown result type (might be due to invalid IL or missing references) //IL_0256: Unknown result type (might be due to invalid IL or missing references) //IL_025b: Unknown result type (might be due to invalid IL or missing references) //IL_025f: Unknown result type (might be due to invalid IL or missing references) //IL_0264: Unknown result type (might be due to invalid IL or missing references) //IL_0268: Unknown result type (might be due to invalid IL or missing references) //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03d7: Expected O, but got Unknown //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0344: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_034e: Unknown result type (might be due to invalid IL or missing references) //IL_0383: Unknown result type (might be due to invalid IL or missing references) //IL_036b: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) //IL_0364: Unknown result type (might be due to invalid IL or missing references) //IL_0397: Unknown result type (might be due to invalid IL or missing references) //IL_044c: Unknown result type (might be due to invalid IL or missing references) //IL_0451: Unknown result type (might be due to invalid IL or missing references) //IL_0453: Unknown result type (might be due to invalid IL or missing references) //IL_0465: Unknown result type (might be due to invalid IL or missing references) extracted = null; Material[] sharedMaterials = ((Renderer)mr).sharedMaterials; int num = ((sharedMaterials != null) ? sharedMaterials.Length : 0); int subMeshCount = combined.subMeshCount; if (num <= 0 || subMeshCount < num) { return false; } Transform staticBatchRoot = GetStaticBatchRoot((Renderer)(object)mr); Matrix4x4 val = (((Object)(object)staticBatchRoot != (Object)null) ? staticBatchRoot.localToWorldMatrix : Matrix4x4.identity); Bounds bounds = ((Renderer)mr).bounds; int num2 = -1; float num3 = float.MaxValue; float num4 = float.MaxValue; for (int i = 0; i + num <= subMeshCount; i++) { Bounds val2 = default(Bounds); for (int j = 0; j < num; j++) { SubMeshDescriptor subMesh = combined.GetSubMesh(i + j); Bounds val3 = TransformBounds(val, ((SubMeshDescriptor)(ref subMesh)).bounds); if (j == 0) { val2 = val3; } else { ((Bounds)(ref val2)).Encapsulate(val3); } } Vector3 val4 = ((Bounds)(ref val2)).center - ((Bounds)(ref bounds)).center; Vector3 val5 = ((Bounds)(ref val2)).size - ((Bounds)(ref bounds)).size; float num5 = Mathf.Abs(val4.x) + Mathf.Abs(val4.y) + Mathf.Abs(val4.z) + Mathf.Abs(val5.x) + Mathf.Abs(val5.y) + Mathf.Abs(val5.z); if (num5 < num3) { num4 = num3; num3 = num5; num2 = i; } else if (num5 < num4) { num4 = num5; } } Vector3 size = ((Bounds)(ref bounds)).size; float num6 = 0.05f * Mathf.Max(1f, ((Vector3)(ref size)).magnitude); bool flag = num4 == float.MaxValue || (num4 >= 2f * num3 && num4 > 0f); if (num2 < 0 || num3 >= num6 || !flag) { Plugin.Activity("Disguise: batched submesh match rejected for '" + ((Object)go).name + "' " + $"(best {num3:0.###}, second {num4:0.###}, tol {num6:0.###})."); return false; } Vector3[] vertices = combined.vertices; Vector3[] normals = combined.normals; Vector2[] uv = combined.uv; Vector2[] uv2 = combined.uv2; bool flag2 = normals != null && normals.Length == combined.vertexCount; bool flag3 = uv != null && uv.Length == combined.vertexCount; bool flag4 = uv2 != null && uv2.Length == combined.vertexCount; Matrix4x4 worldToLocalMatrix = go.transform.worldToLocalMatrix; Matrix4x4 val6 = worldToLocalMatrix * val; val6 = ((Matrix4x4)(ref val6)).inverse; Matrix4x4 transpose = ((Matrix4x4)(ref val6)).transpose; int[] array = new int[combined.vertexCount]; for (int k = 0; k < array.Length; k++) { array[k] = -1; } List<Vector3> list = new List<Vector3>(); List<Vector3> list2 = (flag2 ? new List<Vector3>() : null); List<Vector2> list3 = (flag3 ? new List<Vector2>() : null); List<Vector2> list4 = (flag4 ? new List<Vector2>() : null); List<int[]> list5 = new List<int[]>(num); for (int l = 0; l < num; l++) { int[] indices = combined.GetIndices(num2 + l); int[] array2 = new int[indices.Length]; for (int m = 0; m < indices.Length; m++) { int num7 = indices[m]; int num8 = array[num7]; if (num8 < 0) { num8 = (array[num7] = list.Count); list.Add(((Matrix4x4)(ref worldToLocalMatrix)).MultiplyPoint3x4(((Matrix4x4)(ref val)).MultiplyPoint3x4(vertices[num7]))); if (flag2) { Vector3 val7 = ((Matrix4x4)(ref transpose)).MultiplyVector(normals[num7]); float magnitude = ((Vector3)(ref val7)).magnitude; list2.Add((magnitude > 0.0001f) ? (val7 / magnitude) : Vector3.up); } if (flag3) { list3.Add(uv[num7]); } if (flag4) { list4.Add(uv2[num7]); } } array2[m] = num8; } list5.Add(array2); } Mesh val8 = new Mesh(); try { ((Object)val8).name = "PropHunt_Extract_" + ((Object)go).name; if (list.Count > 65534) { val8.indexFormat = (IndexFormat)1; } val8.SetVertices(list); if (flag2) { val8.SetNormals(list2); } if (flag3) { val8.SetUVs(0, list3); } if (flag4) { val8.SetUVs(1, list4); } val8.subMeshCount = num; bool flag5 = true; for (int n = 0; n < num; n++) { MeshTopology topology = combined.GetTopology(num2 + n); if ((int)topology != 0) { flag5 = false; } val8.SetIndices(list5[n], topology, n); } if (!flag2 && flag5) { val8.RecalculateNormals(); } if (flag3 && flag5) { val8.RecalculateTangents(); } val8.RecalculateBounds(); } catch { Object.Destroy((Object)(object)val8); throw; } extracted = val8; return true; } private static Bounds TransformBounds(Matrix4x4 m, Bounds b) { //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_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_0018: 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_002a: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0062: 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) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: Unknown result type (might be due to invalid IL or missing references) Vector3 val = ((Matrix4x4)(ref m)).MultiplyPoint3x4(((Bounds)(ref b)).center); Vector3 extents = ((Bounds)(ref b)).extents; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(Mathf.Abs(m.m00) * extents.x + Mathf.Abs(m.m01) * extents.y + Mathf.Abs(m.m02) * extents.z, Mathf.Abs(m.m10) * extents.x + Mathf.Abs(m.m11) * extents.y + Mathf.Abs(m.m12) * extents.z, Mathf.Abs(m.m20) * extents.x + Mathf.Abs(m.m21) * extents.y + Mathf.Abs(m.m22) * extents.z); return new Bounds(val, val2 * 2f); } private static Transform GetStaticBatchRoot(Renderer r) { if (!_staticBatchRootResolved) { _staticBatchRootResolved = true; try { _staticBatchRootProp = typeof(Renderer).GetProperty("staticBatchRootTransform", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } catch { _staticBatchRootProp = null; } } if (_staticBatchRootProp == null) { return null; } try { object? value = _staticBatchRootProp.GetValue(r, null); return (Transform)((value is Transform) ? value : null); } catch { return null; } } internal static bool ApplyFromMessage(PropHuntNet msg, bool logResolutionFailure = true) { //IL_0271: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) HiderSlot hiderSlot = null; try { if (!Plugin.CfgEnabled.Value) { return true; } PropHuntManager instance = PropHuntManager.Instance; if ((Object)(object)instance == (Object)null) { return true; } int a = msg.A; int num = PropHuntManager.ConnIdForPlayer(a); if (num < 0) { if (logResolutionFailure) { Plugin.Activity($"Disguise: op-4 for unknown PlayerId {a} - ignored."); } return false; } PlayerHealth val = instance.FindHealthByConn(num); if ((Object)(object)val != (Object)null && !instance.IsBindableHealth(val)) { if (logResolutionFailure) { Plugin.Log.LogWarning((object)$"Disguise: player object for prop {a} is stale/despawning - that hider stays visible."); } return false; } if ((Object)(object)val == (Object)null) { if (logResolutionFailure) { Plugin.Log.LogWarning((object)$"Disguise: player object for prop {a} not found - that hider stays visible."); } return false; } hiderSlot = GetOrCreateSlot(a); hiderSlot.IsLocal = PropHuntManager.LocalRole == Role.Hider && a == PropHuntManager.LocalPlayerId(); string text = msg.S ?? ""; int num2 = text.IndexOf('\n'); string text2 = ((num2 >= 0) ? text.Substring(0, num2) : text); string text3 = ((num2 >= 0) ? text.Substring(num2 + 1) : ""); GameObject val2 = ResolveByPath(text2); if ((Object)(object)val2 != (Object)null && !HasRenderMesh(val2)) { val2 = null; } if ((Object)(object)val2 != (Object)null && !string.IsNullOrEmpty(text3)) { string meshKey = GetMeshKey(val2); if (meshKey == null || meshKey != text3) { Plugin.Log.LogWarning((object)("Disguise: path '" + text2 + "' resolved mesh key '" + (meshKey ?? "<none>") + "' instead of '" + text3 + "' - falling back to mesh search.")); val2 = null; } } if ((Object)(object)val2 == (Object)null && !string.IsNullOrEmpty(text3)) { val2 = FindUniqueByMeshName(text3); } ItemSpawner val3 = ((msg.B > 0) ? ResolveSpawner(msg.B - 1, val2) : null); if ((Object)(object)val2 == (Object)null && (Object)(object)val3 == (Object)null) { Plugin.Log.LogWarning((object)("Disguise: couldn't resolve prop '" + text2 + "' (mesh '" + text3 + "') - hider stays visible.")); return true; } if ((Object)(object)val2 != (Object)null) { Vector3 lossyScale = val2.transform.lossyScale; Vector3 val4 = lossyScale - msg.V; if (((Vector3)(ref val4)).sqrMagnitude > 0.01f * Mathf.Max(0.01f, ((Vector3)(ref msg.V)).sqrMagnitude)) { Plugin.Log.LogWarning((object)$"Disguise: resolved scale {lossyScale} differs from sender's {msg.V} - possible mismatched resolution."); } } DestroyClone(hiderSlot); bool isLocal = hiderSlot.IsLocal; if (!isLocal || Plugin.CfgShowOwnProp.Value) { bool flag = false; if ((Object)(object)val3 != (Object)null) { flag = BuildCloneSpawner(hiderSlot, val, val3); if (!flag && (Object)(object)val2 != (Object)null) { Plugin.Log.LogWarning((object)("Disguise: spawner composite failed for '" + ((Object)val3).name + "' - plain prop fallback.")); flag = BuildClone(hiderSlot, val, val2); } } else { flag = BuildClone(hiderSlot, val, val2); } if (!flag) { RestoreGraphics(hiderSlot); return true; } } HideGraphics(hiderSlot, val); if (hiderSlot.CloneHitboxOk) { HideHitboxColliders(hiderSlot, val); } else { RestoreHiddenColliders(hiderSlot); } if (isLocal) { PropHuntManager.ClientDisguisedThisTake = true; } Plugin.Activity($"Disguise: applied '{(((Object)(object)val3 != (Object)null) ? ((Object)val3).name : ((Object)val2).name)}' onto prop {a}."); return true; } catch (Exception e) { Plugin.LogOnce("Disguise.Apply", e); try { if (hiderSlot != null) { CleanupSlot(hiderSlot); } } catch { } return true; } } private static bool HasRenderMesh(GameObject go) { MeshFilter component = go.GetComponent<MeshFilter>(); if ((Object)(object)component != (Object)null && (Object)(object)component.sharedMesh != (Object)null) { return (Object)(object)go.GetComponent<MeshRenderer>() != (Object)null; } return false; } private static GameObject ResolveByPath(string path) { //IL_0024: 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) if (string.IsNullOrEmpty(path)) { return null; } string[] array = path.Split(new char[1] { '/' }); for (int i = 0; i < SceneManager.sceneCount; i++) { Scene sceneAt = SceneManager.GetSceneAt(i); if (!((Scene)(ref sceneAt)).isLoaded) { continue; } GameObject[] rootGameObjects = ((Scene)(ref sceneAt)).GetRootGameObjects(); foreach (GameObject val in rootGameObjects) { if (((Object)val).name != array[0]) { continue; } Transform val2 = val.transform; bool flag = true; for (int k = 1; k < array.Length; k++) { val2 = val2.Find(array[k]); if ((Object)(object)val2 == (Object)null) { flag = false; break; } } if (flag) { return ((Component)val2).gameObject; } } } return null; } private static GameObject FindUniqueByMeshName(string meshKey) { GameObject result = null; int num = 0; MeshFilter[] array = Object.FindObjectsOfType<MeshFilter>(true); foreach (MeshFilter val in array) { if ((Object)(object)val == (Object)null || (Object)(object)val.sharedMesh == (Object)null) { continue; } GameObject gameObject = ((Component)val).gameObject; if (!(((Object)gameObject).name == "PropHunt_Disguise") && !IsUnderClone(gameObject.transform) && !((Object)(object)gameObject.GetComponent<MeshRenderer>() == (Object)null) && !(GetMeshKey(gameObject) != meshKey) && ValidateSource(gameObject, out var _)) { result = gameObject; num++; if (num > 1) { return null; } } } if (num != 1) { return null; } return result; } private static bool BuildClone(HiderSlot slot, PlayerHealth hiderPh, GameObject source) { //IL_0326: Unknown result type (might be due to invalid IL or missing references) //IL_032b: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_033a: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_035e: Unknown result type (might be due to invalid IL or missing references) //IL_0360: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_039d: Unknown result type (might be due to invalid IL or missing references) //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03bb: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Expected O, but got Unknown //IL_0101: 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_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_014f: Unknown result type (might be due to invalid IL or missing references) //IL_015b: 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_016e: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0184: 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_0188: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_01a6: 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_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_0200: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0234: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_024d: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_0273: Expected O, but got Unknown //IL_02a4: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) try { MeshRenderer component = source.GetComponent<MeshRenderer>(); if ((Object)(object)component == (Object)null) { return false; } if (!TryRecoverRenderMesh(source, out var mesh, out var materials, out var _, out var ownsMesh, out var fail)) { Plugin.Log.LogWarning((object)("Disguise: mesh recovery failed for '" + ((Object)source).name + "' (" + fail + ") - hider stays visible.")); return false; } if (ownsMesh) { slot.OwnedMeshes.Add(mesh); } PropLighting.LogSceneInventoryOnce(); float num = ComputeGroundSlack(source, component, ((Component)hiderPh).transform); if (num > 0.01f) { Plugin.Activity($"Disguise: ground slack for '{((Object)source).name}' = {num:0.00}m"); } Transform transform = ((Component)hiderPh).transform; GameObject val = (slot.Clone = new GameObject("PropHunt_Disguise")); val.transform.SetParent(transform, false); val.AddComponent<MeshFilter>().sharedMesh = mesh; MeshRenderer val2 = val.AddComponent<MeshRenderer>(); ((Renderer)val2).sharedMaterials = materials; ((Renderer)val2).shadowCastingMode = ((Renderer)component).shadowCastingMode; ((Renderer)val2).receiveShadows = ((Renderer)component).receiveShadows; Vector3 lossyScale = transform.lossyScale; Vector3 lossyScale2 = source.transform.lossyScale; val.transform.localScale = new Vector3(SafeDiv(lossyScale2.x, lossyScale.x), SafeDiv(lossyScale2.y, lossyScale.y), SafeDiv(lossyScale2.z, lossyScale.z)); Quaternion val3 = YawOnly(transform.rotation); Quaternion val4 = Quaternion.Inverse(val3) * source.transform.rotation; val.transform.rotation = val3 * val4; val.transform.position = transform.position; CharacterController component2 = ((Component)hiderPh).GetComponent<CharacterController>(); float y; Bounds bounds; if (!((Object)(object)component2 != (Object)null)) { y = transform.position.y; } else { bounds = ((Collider)component2).bounds; y = ((Bounds)(ref bounds)).min.y; } float num2 = y; Bounds bounds2 = ((Renderer)val2).bounds; Transform transform2 = val.transform; transform2.position += new Vector3(transform.position.x - ((Bounds)(ref bounds2)).center.x, num2 - num - ((Bounds)(ref bounds2)).min.y, transform.position.z - ((Bounds)(ref bounds2)).center.z); try { GameObject val5 = new GameObject("PropHunt_Hitbox"); val5.layer = 11; val5.transform.SetParent(val.transform, false); BoxCollider val6 = val5.AddComponent<BoxCollider>(); ((Collider)val6).isTrigger = false; bounds = mesh.bounds; val6.center = ((Bounds)(ref bounds)).center; bounds = mesh.bounds; val6.size = ((Bounds)(ref bounds)).size; if ((Object)(object)component2 != (Object)null) { Physics.IgnoreCollision((Collider)(object)val6, (Collider)(object)component2, true); } if (HitboxResolvesHider(val5, hiderPh)) { slot.CloneHitboxOk = true; } else { Plugin.Log.LogWarning((object)"Disguise: prop hitbox wouldn't resolve the hider's PlayerHealth - keeping the humanoid hitbox."); Object.Destroy((Object)(object)val5); } } catch (Exception e) { Plugin.LogOnce("Disguise.Hitbox", e); slot.CloneHitboxOk = false; } bounds = mesh.bounds; Vector3 center = ((Bounds)(ref bounds)).center; bounds = mesh.bounds; AddWalkBox(val, center, ((Bounds)(ref bounds)).size, component2); DisguiseFollower disguiseFollower = val.AddComponent<DisguiseFollower>(); disguiseFollower.Root = transform; disguiseFollower.DeltaRot = val4; disguiseFollower.SrcLossyScale = lossyScale2; disguiseFollower.Cc = component2; disguiseFollower.GraphicsT = ResolveGraphicsAnchor(hiderPh); disguiseFollower.CloneMr = val2; disguiseFollower.GroundSlack = num; if (ComputeWallMount(source.transform, ((Renderer)component).bounds, transform, out var backLocal, out var gap, out var halfExtent)) { disguiseFollower.WallMounted = true; disguiseFollower.WallBackLocal = backLocal; disguiseFollower.WallGap = gap; disguiseFollower.WallHalfExtent = halfExtent; } disguiseFollower.SetManualYaw(disguiseFollower.SeedYaw = ((Quaternion)(ref val3)).eulerAngles.y); disguiseFollower.SlotPlayerId = slot.PlayerId; if (slot.IsLocal) { disguiseFollower.IsLocalHider = true; disguiseFollower.Fpc = ((Component)hiderPh).GetComponent<FirstPersonController>(); } return true; } catch (Exception e2) { Plugin.LogOnce("Disguise.BuildClone", e2); DestroyClone(slot); return false; } } private static bool HitboxResolvesHider(GameObject hitboxGo, PlayerHealth hiderPh) { PlayerHealth val = null; Transform root = hitboxGo.transform.root; if (((Component)root).CompareTag("Player")) { ((Component)root).TryGetComponent<PlayerHealth>(ref val); } else { val = hitboxGo.GetComponentInParent<PlayerHealth>(); } return (Object)(object)val == (Object)(object)hiderPh; } private static void AddWalkBox(GameObject clone, Vector3 localCenter, Vector3 localSize, CharacterController hiderCc) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) GameObject val = null; try { if (Plugin.CfgSolidProps.Value) { val = new GameObject("PropHunt_WalkBox"); val.layer = 14; val.transform.SetParent(clone.transform, false); BoxCollider val2 = val.AddComponent<BoxCollider>(); ((Collider)val2).isTrigger = false; val2.center = localCenter; val2.size = localSize; if ((Object)(object)hiderCc != (Object)null) { Physics.IgnoreCollision((Collider)(object)val2, (Collider)(object)hiderCc, true); } } } catch (Exception e) { Plugin.LogOnce("Disguise.WalkBox", e); if ((Object)(object)val != (Object)null) { try { Object.Destroy((Object)(object)val); return; } catch { return; } } } } private static ItemSpawner ResolveSpawner(int objectId, GameObject source) { //IL_00d6: 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_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) try { NetworkObject value = null; NetworkManager networkManager = InstanceFinder.NetworkManager; if ((Object)(object)networkManager != (Object)null) { if ((Object)(object)networkManager.ClientManager != (Object)null && networkManager.ClientManager.Objects != null) { ((ManagedObjects)networkManager.ClientManager.Objects).Spawned.TryGetValue(objectId, out value); } if ((Object)(object)value == (Object)null && networkManager.IsServer && (Object)(object)networkManager.ServerManager != (Object)null && networkManager.ServerManager.Objects != null) { ((ManagedObjects)networkManager.ServerManager.Objects).Spawned.TryGetValue(objectId, out value); } } if ((Object)(object)value != (Object)null) { ItemSpawner component = ((Component)value).GetComponent<ItemSpawner>(); if ((Object)(object)component != (Object)null) { return component; } } Plugin.Log.LogWarning((object)$"Disguise: spawner ObjectId {objectId} didn't resolve - trying nearest spawner."); if ((Object)(object)source != (Object)null) { Vector3 position = source.transform.position; ItemSpawner val = null; float num = 1f; ItemSpawner[] array = Object.FindObjectsOfType<ItemSpawner>(); foreach (ItemSpawner val2 in array) { if (!((Object)(object)val2 == (Object)null)) { Vector3 val3 = ((Component)val2).transform.position - position; float sqrMagnitude = ((Vector3)(ref val3)).sqrMagnitude; if (sqrMagnitude < num) { val = val2; num = sqrMagnitude; } } } if ((Object)(object)val != (Object)null) { Plugin.Activity($"Disguise: nearest-spawner fallback chose '{((Object)val).name}' ({Mathf.Sqrt(num):0.00} m)."); return val; } } Plugin.Log.LogWarning((object)"Disguise: spawner resolution failed entirely - plain prop fallback."); return null; } catch (Exception e) { Plugin.LogOnce("Disguise.ResolveSpawner", e); return null; } } private static bool BuildCloneSpawner(HiderSlot slot, PlayerHealth hiderPh, ItemSpawner spawner) { //IL_05e5: Unknown result type (might be due to invalid IL or missing references) //IL_05f1: Unknown result type (might be due to invalid IL or missing references) //IL_05f6: Unknown result type (might be due to invalid IL or missing references) //IL_05f8: Unknown result type (might be due to invalid IL or missing references) //IL_05fd: Unknown result type (might be due to invalid IL or missing references) //IL_06af: Unknown result type (might be due to invalid IL or missing references) //IL_06b1: Unknown result type (might be due to invalid IL or missing references) //IL_06b8: Unknown result type (might be due to invalid IL or missing references) //IL_06ba: Unknown result type (might be due to invalid IL or missing references) //IL_06e7: Unknown result type (might be due to invalid IL or missing references) //IL_0878: Unknown result type (might be due to invalid IL or missing references) //IL_087a: Unknown result type (might be due to invalid IL or missing references) //IL_0881: Unknown result type (might be due to invalid IL or missing references) //IL_0883: Unknown result type (might be due to invalid IL or missing references) //IL_088a: Unknown result type (might be due to invalid IL or missing references) //IL_0701: Unknown result type (might be due to invalid IL or missing references) //IL_0703: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_0748: Unknown result type (might be due to invalid IL or missing references) //IL_074d: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_075f: Unknown result type (might be due to invalid IL or missing references) //IL_0780: Unknown result type (might be due to invalid IL or missing references) //IL_079c: Unknown result type (might be due to invalid IL or missing references) //IL_07bb: Unknown result type (might be due to invalid IL or missing references) //IL_07d1: Unknown result type (might be due to invalid IL or missing references) //IL_07f0: Unknown result type (might be due to invalid IL or missing references) //IL_07fe: Unknown result type (might be due to invalid IL or missing references) //IL_0808: 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_0146: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Unknown result type (might be due to invalid IL or missing references) //IL_0188: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01e3: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0238: Unknown result type (might be due to invalid IL or missing references) //IL_02ae: Unknown result type (might be due to invalid IL or missing references) //IL_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02d8: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02e7: Unknown result type (might be due to invalid IL or missing references) //IL_02f1: Unknown result type (might be due to invalid IL or missing references) //IL_02f8: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Unknown result type (might be due to invalid IL or missing references) //IL_031a: Unknown result type (might be due to invalid IL or missing references) //IL_031c: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_0335: Unknown result type (might be due to invalid IL or missing references) //IL_033c: Unknown result type (might be due to invalid IL or missing references) //IL_0348: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_0365: Unknown result type (might be due to invalid IL or missing references) //IL_0386: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Unknown result type (might be due to invalid IL or missing references) //IL_03b0: Unknown result type (might be due to invalid IL or missing references) //IL_03b7: Unknown result type (might be due to invalid IL or missing references) //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03c1: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_03d2: Unknown result type (might be due to invalid IL or missing references) //IL_03c7: Unknown result type (might be due to invalid IL or missing references) //IL_03c9: Unknown result type (might be due to invalid IL or missing references) //IL_0490: Unknown result type (might be due to invalid IL or missing references) //IL_0495: Unknown result type (might be due to invalid IL or missing references) //IL_0499: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03e0: Unknown result type (might be due to invalid IL or missing references) //IL_03e4: Unknown result type (might be due to invalid IL or missing references) //IL_03e9: Unknown result type (might be due to invalid IL or missing references) //IL_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03f2: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_04ad: Unknown result type (might be due to invalid IL or missing references) //IL_04b2: Unknown result type (might be due to invalid IL or missing references) //IL_04c4: Unknown result type (might be due to invalid IL or missing references) //IL_04e7: Unknown result type (might be due to invalid IL or missing references) //IL_04ee: Unknown result type (might be due to invalid IL or missing references) //IL_04fa: Unknown result type (might be due to invalid IL or missing references) //IL_050b: Unknown result type (might be due to invalid IL or missing references) //IL_0518: Unknown result type (might be due to invalid IL or missing references) //IL_0524: Unknown result type (might be due to invalid IL or missing references) //IL_052f: Unknown result type (might be due to invalid IL or missing references) //IL_0534: Unknown result type (might be due to invalid IL or missing references) //IL_0546: Unknown result type (might be due to invalid IL or missing references) //IL_054d: Expected O, but got Unknown //IL_057f: Unknown result type (might be due to invalid IL or missing references) //IL_058d: Unknown result type (might be due to invalid IL or missing references) try { Transform transform = ((Component)spawner).transform; List<MeshRenderer> list = new List<MeshRenderer>(8); MeshRenderer[] componentsInChildren = ((Component)transform).GetComponentsInChildren<MeshRenderer>(false); foreach (MeshRenderer val in componentsInChildren) { if (!((Object)(object)val == (Object)null) && ((Renderer)val).enabled) { GameObject gameObject = ((Component)val).gameObject; MeshFilter component = gameObject.GetComponent<MeshFilter>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null) && !((Object)(object)gameObject.GetComponentInParent<ItemBehaviour>() != (Object)null) && !AnyAncestorOnLayer(gameObject.transform, transform, 7, 8)) { list.Add(val); } } } if (list.Count == 0) { Plugin.Log.LogWarning((object)("Disguise: spawner '" + ((Object)spawner).name + "' has no usable pedestal renderer.")); return false; } PropLighting.LogSceneInventoryOnce(); Bounds bounds = ((Renderer)list[0]).bounds; for (int j = 1; j < list.Count; j++) { ((Bounds)(ref bounds)).Encapsulate(((Renderer)list[j]).bounds); } float num = ComputeSpawnerBurial(transform, bounds, ((Component)hiderPh).transform); if (num > 0.01f) { Plugin.Activity($"Disguise: spawner burial for '{((Object)spawner).name}' = {num:0.00}m"); } Transform transform2 = ((Component)hiderPh).transform; GameObject val2 = (slot.Clone = new GameObject("PropHunt_Disguise")); val2.transform.SetParent(transform2, false); Vector3 lossyScale = transform2.lossyScale; Vector3 lossyScale2 = transform.lossyScale; val2.transform.localScale = new Vector3(SafeDiv(lossyScale2.x, lossyScale.x), SafeDiv(lossyScale2.y, lossyScale.y), SafeDiv(lossyScale2.z, lossyScale.z)); Quaternion val3 = YawOnly(transform2.rotation); Quaternion val4 = Quaternion.Inverse(val3) * transform.rotation; val2.transform.rotation = val3 * val4; val2.transform.position = transform2.position; List<MeshRenderer> list2 = new List<MeshRenderer>(list.Count); MeshRenderer val5 = null; float num2 = -1f; Bounds localBase = default(Bounds); bool flag = false; Matrix4x4 worldToLocalMatrix = transform.worldToLocalMatrix; Vector3 lossyScale3 = val2.transform.lossyScale; Bounds bounds2; foreach (MeshRenderer item in list) { if (!TryRecoverRenderMesh(((Component)item).gameObject, out var mesh, out var materials, out var _, out var ownsMesh, out var fail)) { Plugin.Activity("Disguise: spawner part '" + ((Object)((Component)item).gameObject).name + "' skipped - " + fail); continue; } if (ownsMesh) { slot.OwnedMeshes.Add(mesh); } Transform transform3 = ((Component)item).transform; GameObject val6 = new GameObject("PropHunt_Part") { layer = ((Component)item).gameObject.layer }; val6.transform.SetParent(val2.transform, false); val6.transform.localPosition = ((Matrix4x4)(ref worldToLocalMatrix)).MultiplyPoint3x4(transform3.position); val6.transform.localRotation = Quaternion.Inverse(transform.rotation) * transform3.rotation; Vector3 lossyScale4 = transform3.lossyScale; val6.transform.localScale = new Vector3(SafeDiv(lossyScale4.x, lossyScale3.x), SafeDiv(lossyScale4.y, lossyScale3.y), SafeDiv(lossyScale4.z, lossyScale3.z)); val6.AddComponent<MeshFilter>().sharedMesh = mesh; MeshRenderer val7 = val6.AddComponent<MeshRenderer>(); ((Renderer)val7).sharedMaterials = materials; ((Renderer)val7).shadowCastingMode = ((Renderer)item).shadowCastingMode; ((Renderer)val7).receiveShadows = ((Renderer)item).receiveShadows; list2.Add(val7); Bounds val8 = TransformBounds(worldToLocalMatrix * transform3.localToWorldMatrix, mesh.bounds); if (!flag) { localBase = val8; flag = true; } else { ((Bounds)(ref localBase)).Encapsulate(val8); } bounds2 = ((Renderer)item).bounds; Vector3 size = ((Bounds)(ref bounds2)).size; float num3 = size.x * size.y * size.z; if (num3 > num2) { num2 = num3; val5 = val7; } } if (list2.Count == 0) { Plugin.Log.LogWarning((object)("Disguise: every pedestal part of '" + ((Object)spawner).name + "' failed mesh recovery.")); DestroyClone(slot); return false; } CopySpawnerLights(val2, transform, worldToLocalMatrix); CharacterController component2 = ((Component)hiderPh).GetComponent<CharacterController>(); float y; if (!((Object)(object)component2 != (Object)null)) { y = transform2.position.y; } else { bounds2 = ((Collider)component2).bounds; y = ((Bounds)(ref bounds2)).min.y; } float num4 = y; Bounds bounds3 = ((Renderer)list2[0]).bounds; for (int k = 1; k < list2.Count; k++) { ((Bounds)(ref bounds3)).Encapsulate(((Renderer)list2[k]).bounds); } Transform transform4 = val2.transform; transform4.position += new Vector3(transform2.position.x - ((Bounds)(ref bounds3)).center.x, num4 - num - ((Bounds)(ref bounds3)).min.y, transform2.position.z - ((Bounds)(ref bounds3)).center.z); bool flag2 = false; try { GameObject val9 = new GameObject("PropHunt_Hitbox"); val9.layer = 11; val9.transform.SetParent(val2.transform, false); BoxCollider val10 = val9.AddComponent<BoxCollider>(); ((Collider)val10).isTrigger = false; val10.center = ((Bounds)(ref localBase)).center; val10.size = ((Bounds)(ref localBase)).size; if ((Object)(object)component2 != (Object)null) { Physics.IgnoreCollision((Collider)(object)val10, (Collider)(object)component2, true); } if (HitboxResolvesHider(val9, hiderPh)) { flag2 = true; } else { Plugin.Log.LogWarning((object)"Disguise: spawner base hitbox wouldn't resolve the hider - keeping the humanoid hitbox."); Object.Destroy((Object)(object)val9); } } catch (Exception e) { Plugin.LogOnce("Disguise.SpawnerHitbox", e); } AddSpawnerWalkColliders(val2, transform, localBase, component2); Transform dummyT = null; Vector3 bobBase = Vector3.zero; Vector3 bobOffset = Vector3.zero; List<MeshRenderer> list3 = new List<MeshRenderer>(list2); bool flag3 = true; try { ItemBehaviour val11 = null; ItemBehaviour[] componentsInChildren2 = ((Component)transform).GetComponentsInChildren<ItemBehaviour>(false); foreach (ItemBehaviour val12 in componentsInChildren2) { if ((Object)(object)val12 != (Object)null && (Object)(object)val12.rootObject == (Object)null && !val12.isTaken) { val11 = val12; break; } } if ((Object)(object)val11 != (Object)null) { flag3 = BuildWeaponDummy(slot, val2, transform, val11, hiderPh, component2, list3, out dummyT, out bobBase, out bobOffset); } } catch (Exception e2) { Plugin.LogOnce("Disguise.WeaponDummy", e2); dummyT = null; } slot.CloneHitboxOk = flag2 && flag3; DisguiseFollower disguiseFollower = val2.AddComponent<DisguiseFollower>(); disguiseFollower.Root = transform2; disguiseFollower.DeltaRot = val4; disguiseFollower.SrcLossyScale = lossyScale2; disguiseFollower.Cc = component2; disguiseFollower.GraphicsT = ResolveGraphicsAnchor(hiderPh); disguiseFollower.CloneMr = val5; disguiseFollower.GroundSlack = num; if (ComputeWallMount(transform, bounds, transform2, out var backLocal, out var gap, out var halfExtent)) { disguiseFollower.WallMounted = true; disguiseFollower.WallBackLocal = backLocal; disguiseFollower.WallGap = gap; disguiseFollower.WallHalfExtent = halfExtent; } disguiseFollower.BoundsRenderers = list2.ToArray(); list3.Remove(val5); disguiseFollower.ExtraLitRenderers = list3.ToArray(); try { Bounds bounds4 = ((Renderer)list2[0]).bounds; for (int l = 1; l < list2.Count; l++) { ((Bounds)(ref bounds4)).Encapsulate(((Renderer)list2[l]).bounds); } float num5 = num4; float num6 = Mathf.Max(((Bounds)(ref bounds4)).min.y, num5); float num7 = Mathf.Max(0.5f * (num6 + ((Bounds)(ref bounds4)).max.y), num5 + 0.15f); num7 = Mathf.Min(num7, ((Bounds)(ref bounds4)).max.y); Transform transform5 = new GameObject("PropHunt_ProbeAnchor").transform; transform5.SetParent(val2.transform, false); transform5.position = new Vector3(transform2.position.x, num7, transform2.position.z); ((Renderer)val5).probeAnchor = transform5; for (int m = 0; m < list3.Count; m++) { if ((Object)(object)list3[m] != (Object)null) { ((Renderer)list3[m]).probeAnchor = transform5; } } disguiseFollower.ProbeAnchorT = transform5; } catch (Exception e3) { Plugin.LogOnce("Disguise.ProbeAnchor", e3); } disguiseFollower.DummyT = dummyT; disguiseFollower.DummyBobBase = bobBase; disguiseFollower.DummyBobOffset = bobOffset; disguiseFollower.SetManualYaw(disguiseFollower.SeedYaw = ((Quaternion)(ref val3)).eulerAngles.y); disguiseFollower.SlotPlayerId = slot.PlayerId; if (slot.IsLocal) { disguiseFollower.IsLocalHider = true; disguiseFollower.Fpc = ((Component)hiderPh).GetComponent<FirstPersonController>(); } Plugin.Activity($"Disguise: spawner composite built ({list2.Count} parts, " + $"dummy={(Object)(object)dummyT != (Object)null}, burial {num:0.00}m)."); return true; } catch (Exception e4) { Plugin.LogOnce("Disguise.BuildSpawner", e4); DestroyClone(slot); return false; } } private static bool BuildWeaponDummy(HiderSlot slot, GameObject clone, Transform spawnerT, ItemBehaviour sitting, PlayerHealth hiderPh, CharacterController cc, List<MeshRenderer> extraLit, out Transform dummyT, out Vector3 bobBase, out Vector3 bobOffset) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_0098: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: 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_00fa: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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) //IL_0361: Unknown result type (might be due to invalid IL or missing references) //IL_0368: Expected O, but got Unknown //IL_0399: Unknown result type (might be due to invalid IL or missing references) //IL_03a7: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01a3: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0222: Unknown result type (might be due to invalid IL or missing references) //IL_0229: Unknown result type (might be due to invalid IL or missing references) //IL_0235: Unknown result type (might be due to invalid IL or missing references) //IL_023f: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0291: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02c5: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02bd: Unknown result type (might be due to invalid IL or missing references) dummyT = null; Transform transform = ((Component)sitting).transform; bobBase = spawnerT.InverseTransformPoint(spawnerT.position + Vector3.up * 0.5f); try { if (Reflect.ItemBobBaseField != null && (Object)(object)transform.parent == (Object)(object)spawnerT) { bobBase = (Vector3)Reflect.ItemBobBaseField.GetValue(sitting); } } catch (Exception e) { Plugin.LogOnce("Disguise.BobBase", e); } bobOffset = spawnerT.up * 0.5f; GameObject val = new GameObject("PropHunt_WeaponDummy"); Bounds val2 = default(Bounds); try { val.transform.SetParent(clone.transform, false); val.transform.localPosition = bobBase; val.transform.localRotation = Quaternion.Inverse(spawnerT.rotation) * transform.rotation; val.transform.localScale = transform.localScale; Matrix4x4 worldToLocalMatrix = transform.worldToLocalMatrix; Vector3 lossyScale = val.transform.lossyScale; bool flag = false; int num = 0; MeshRenderer[] componentsInChildren = ((Component)transform).GetComponentsInChildren<MeshRenderer>(false); foreach (MeshRenderer val3 in componentsInChildren) { if ((Object)(object)val3 == (Object)null || !((Renderer)val3).enabled) { continue; } GameObject gameObject = ((Component)val3).gameObject; if (gameObject.tag == "vfx") { continue; } MeshFilter component = gameObject.GetComponent<MeshFilter>(); if (!((Object)(object)component == (Object)null) && !((Object)(object)component.sharedMesh == (Object)null)) { GameObject val4 = new GameObject("PropHunt_Part"); val4.transform.SetParent(val.transform, false); val4.transform.localPosition = ((Matrix4x4)(ref worldToLocalMatrix)).MultiplyPoint3x4(((Component)val3).transform.position); val4.transform.localRotation = Quaternion.Inverse(transform.rotation) * ((Component)val3).transform.rotation; Vector3 lossyScale2 = ((Component)val3).transform.lossyScale; val4.transform.localScale = new Vector3(SafeDiv(lossyScale2.x, lossyScale.x), SafeDiv(lossyScale2.y, lossyScale.y), SafeDiv(lossyScale2.z, lossyScale.z)); val4.AddComponent<MeshFilter>().sharedMesh = component.sharedMesh; MeshRenderer val5 = val4.AddComponent<MeshRenderer>(); ((Renderer)val5).sharedMaterials = CloneDummyMaterials(slot, ((Renderer)val3).sharedMaterials); ((Renderer)val5).shadowCastingMode = ((Renderer)val3).shadowCastingMode; ((Renderer)val5).receiveShadows = ((Renderer)val3).receiveShadows; extraLit.Add(val5); Bounds val6 = TransformBounds(worldToLocalMatrix * ((Component)val3).transform.localToWorldMatrix, component.sharedMesh.bounds); if (!flag) { val2 = val6; flag = true; } else { ((Bounds)(ref val2)).Encapsulate(val6); } num++; } } if (num == 0) { Object.Destroy((Object)(object)val); Plugin.Activity("Disguise: sitting weapon '" + ((Object)sitting).name + "' had no copyable renderer - bare pedestal."); return true; } dummyT = val.transform; Plugin.Activity($"Disguise: weapon dummy '{((Object)sitting).name}' copied ({num} parts)."); } catch (Exception e2) { Plugin.LogOnce("Disguise.WeaponDummyCopy", e2); dummyT = null; try { Object.Destroy((Object)(object)val); } catch { } return true; } try { GameObject val7 = new GameObject("PropHunt_Hitbox"); val7.layer = 11; val7.transform.SetParent(val.transform, false); BoxCollider val8 = val7.AddComponent<BoxCollider>(); ((Collider)val8).isTrigger = false; val8.center = ((Bounds)(ref val2)).center; val8.size = ((Bounds)(ref val2)).size; if ((Object)(object)cc != (Object)null) { Physics.IgnoreCollision((Collider)(object)val8, (Collider)(object)cc, true); } if (HitboxResolvesHider(val7, hiderPh)) { return true; } Plugin.Log.LogWarning((object)"Disguise: weapon-dummy hitbox wouldn't resolve the hider - keeping the humanoid hitbox."); Object.Destroy((Object)(object)val7); return false; } catch (Exception e3) { Plugin.LogOnce("Disguise.WeaponHitbox", e3); return false; } } private static Material[] CloneDummyMaterials(HiderSlot slot, Material[] src) { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown if (src == null) { return null; } Material[] array = (Material[])(object)new Material[src.Length]; for (int i = 0; i < src.Length; i++) { Material val = src[i]; if ((Object)(object)val == (Object)null) { continue; } try { Material val2 = new Material(val); slot.OwnedMaterials.Add(val2); if (val2.HasProperty("_OutlineWidth")) { val2.SetFloat("_OutlineWidth", 0f); } array[i] = val2; } catch (Exception e) { Plugin.LogOnce("Disguise.DummyMaterials", e); array[i] = val; } } return array; } private static bool AnyAncestorOnLayer(Transform t, Transform stopAt, int layerA, int layerB) { Transform val = t; while ((Object)(object)val != (Object)null) { int layer = ((Component)val).gameObject.layer; if (layer == layerA || layer == layerB) { return true; } if ((Object)(object)val == (Object)(object)stopAt) { break; } val = val.parent; } return false; } private static void CopySpawnerLights(GameObject clone, Transform spawnerT, Matrix4x4 w2l) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: 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_0172: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) int num = 0; try { Light[] componentsInChildren = ((Component)spawnerT).GetComponentsInChildren<Light>(false); foreach (Light val in componentsInChildren) { if ((Object)(object)val == (Object)null || !((Behaviour)val).enabled) { continue; } GameObject game