using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.Rendering; using UnityEngine.UI; using Zorro.ControllerSupport; using Zorro.Core; using Zorro.Core.Serizalization; using Zorro.Settings; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("youxia173")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.5.7.0")] [assembly: AssemblyInformationalVersion("1.5.7")] [assembly: AssemblyProduct("SymbioticGhost")] [assembly: AssemblyTitle("SymbioticGhost")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.5.7.0")] [module: UnverifiableCode] [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 SymbioticGhost { internal static class Configuration { internal static ConfigEntry ToggleKey; internal static ConfigEntry MoveSpeed; internal static ConfigEntry MoveDamping; internal static ConfigEntry LookSensitivityMultiplier; internal static ConfigEntry LeashDistance; internal static ConfigEntry LeashCountdownSeconds; internal static ConfigEntry EnableNames; internal static ConfigEntry NameVisibleAngle; internal static ConfigEntry DisplayWhenBlind; internal static ConfigEntry ShowNameDistance; internal static ConfigEntry NameDisplayToggle; internal static ConfigEntry NameDisplayDuration; internal static ConfigEntry PingTextDuration; internal static ConfigEntry ShowPingNameShort; internal static ConfigEntry EnableGhostPing; internal static ConfigEntry EnableGhostHaul; internal static ConfigEntry MaxGhostHaulDisplayWeight; internal static ConfigEntry GhostHaulKey; internal static ConfigEntry GhostHaulRange; internal static ConfigEntry EnableGhostBackpack; internal static ConfigEntry EnableDownedMarkers; internal static ConfigEntry DeadCorpseMarkerMinutes; internal static void Initialize(ConfigFile config) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Expected O, but got Unknown //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown //IL_01d2: 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_0219: Expected O, but got Unknown //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Expected O, but got Unknown //IL_02eb: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Expected O, but got Unknown //IL_033f: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Expected O, but got Unknown //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_039c: Expected O, but got Unknown ToggleKey = config.Bind("1. Hotkeys 热键", "Free Fly Toggle 自由飞行开关", (KeyCode)284, "EN: Solo — free-fly while passed out. Multiplayer — only after fully dead.\n中文:单人 — 昏迷即可灵魂离体;多人 — 须完全死亡后才能按 F3 离体。"); MoveSpeed = config.Bind("2. Camera 相机", "Move Speed 移动速度", 12f, new ConfigDescription("EN: Free-fly movement force.\n中文:自由飞行移动力度。", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 50f), Array.Empty())); MoveDamping = config.Bind("2. Camera 相机", "Move Damping 移动阻尼", 3f, new ConfigDescription("EN: Velocity settle damping.\n中文:自由飞行速度阻尼。", (AcceptableValueBase)(object)new AcceptableValueRange(0.5f, 20f), Array.Empty())); LookSensitivityMultiplier = config.Bind("2. Camera 相机", "Look Sensitivity Multiplier 视角灵敏度倍率", 1f, new ConfigDescription("EN: Multiplies the game Mouse/Controller Sensitivity. 1 = same as living character.\n中文:自由飞行视角 = 游戏设置灵敏度 × 本倍率;1 表示与活着时一致。", (AcceptableValueBase)(object)new AcceptableValueRange(0.25f, 3f), Array.Empty())); LeashDistance = config.Bind("3. Symbiosis 共生", "Leash Distance 寄宿距离", 20f, new ConfigDescription("EN: Beyond this distance from the host, free-fly countdown starts.\n中文:超过与寄宿玩家的该直线距离后开始倒计时。", (AcceptableValueBase)(object)new AcceptableValueRange(5f, 100f), Array.Empty())); LeashCountdownSeconds = config.Bind("3. Symbiosis 共生", "Leash Countdown 寄宿倒计时秒数", 30f, new ConfigDescription("EN: Seconds before free-fly is forced off when out of leash range.\n中文:超出寄宿距离后,多少秒强制退出自由飞行。", (AcceptableValueBase)(object)new AcceptableValueRange(1f, 60f), Array.Empty())); EnableNames = config.Bind("4. Player Names 队友名字", "Enable Names 启用名字显示", true, "EN: Show teammate names when looking toward them.\n中文:看向队友时显示名字。"); NameVisibleAngle = config.Bind("4. Player Names 队友名字", "Visible Angle 可见角度", 52f, new ConfigDescription("EN: Cone angle for name visibility.\n中文:名字显示的视角锥角。", (AcceptableValueBase)(object)new AcceptableValueRange(10f, 180f), Array.Empty())); DisplayWhenBlind = config.Bind("4. Player Names 队友名字", "Display When Blind 致盲时显示", false, "EN: Force names when the target is blind.\n中文:目标致盲时是否仍显示名字。"); ShowNameDistance = config.Bind("4. Player Names 队友名字", "Show Distance 显示距离", true, "EN: Show distance under the player name.\n中文:在名字下方显示距离。"); NameDisplayToggle = config.Bind("4. Player Names 队友名字", "Name Display Toggle 名字显示开关", new KeyboardShortcut((KeyCode)116, Array.Empty()), "EN: Hotkey to toggle name display.\n中文:切换队友名字显示的热键。"); NameDisplayDuration = config.Bind("4. Player Names 队友名字", "Name Display Duration 名字显示秒数", 0f, new ConfigDescription("EN: Seconds names stay on after toggle; 0 = sticky on/off.\n中文:按下开关后名字保持显示的秒数;0 表示手动开关直至再按。", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 300f), Array.Empty())); PingTextDuration = config.Bind("5. Ping Distance 标记距离", "Ping Text Duration 标记距离秒数", 3f, new ConfigDescription("EN: How long ping distance text stays on screen.\n中文:标记距离文字停留秒数。", (AcceptableValueBase)(object)new AcceptableValueRange(0.1f, 30f), Array.Empty())); ShowPingNameShort = config.Bind("5. Ping Distance 标记距离", "Show Ping Name Short 标记名缩写", true, "EN: Show a short name after ping distance.\n中文:在标记距离后显示玩家名缩写。"); EnableGhostPing = config.Bind("6. Ghost Ping 幽灵标记", "Enable Ghost Ping 启用幽灵标记", true, "EN: Allow pinging while dead / passed out, and show no-LOS pings.\n中文:死亡/昏厥时也可标记,并显示无视线标记。"); EnableGhostHaul = config.Bind("7. Ghost Haul 幽灵搬运", "Enable Ghost Haul 启用幽灵搬运", true, "EN: When every player has this mod, ghosts may haul light ground items and use feedable items on teammates.\n中文:仅当全员安装时:幽灵可提起轻物到临时手持,并对队友使用可喂物品。"); EnableGhostBackpack = config.Bind("8. Ghost Backpack 幽灵背包", "Enable Ghost Backpack 启用幽灵背包", true, "EN: Ghosts can open ground/worn backpacks to stash or take one held item; wearing and hotbar storage are blocked.\n中文:幽灵可打开地上或他人背上的背包存取(仅临时手持一件);禁止背起,也不会进快捷栏。"); MaxGhostHaulDisplayWeight = config.Bind("7. Ghost Haul 幽灵搬运", "Max Display Weight 最大界面重量", 2.5f, new ConfigDescription("EN: Max item UI weight (CarryWeight × 2.5). Default 2.5 = rescue claw tier; airplane meal is 5.\n中文:物品界面重量上限(负重槽用的 CarryWeight×2.5)。默认 2.5 为救援爪档;飞机餐为 5。", (AcceptableValueBase)(object)new AcceptableValueRange(2.5f, 20f), Array.Empty())); GhostHaulKey = config.Bind("7. Ghost Haul 幽灵搬运", "Haul Key 搬运按键", (KeyCode)101, "EN: Pick up / drop while spectating as a ghost.\n中文:幽灵状态下提起或放下物品的按键。"); GhostHaulRange = config.Bind("7. Ghost Haul 幽灵搬运", "Haul Range 搬运距离", 4f, new ConfigDescription("EN: How far the ghost can reach to haul an item.\n中文:幽灵可提起物品的最大距离。", (AcceptableValueBase)(object)new AcceptableValueRange(1.5f, 12f), Array.Empty())); EnableDownedMarkers = config.Bind("9. Downed Markers 倒地指示", "Enable Downed Markers 启用倒地指示", true, "EN: Show markers for passed-out / dead bodies (incl. your own so ghosts can find their corpse).\n中文:显示昏厥/死亡位置指示(含自己的尸体,方便幽灵找回身体)。"); DeadCorpseMarkerMinutes = config.Bind("9. Downed Markers 倒地指示", "Dead Corpse Marker Minutes 尸体标记分钟", 6f, new ConfigDescription("EN: How long the corpse marker stays after death (minutes); 0 = hide immediately.\n中文:队友(或自己)死亡后,尸体标记再显示多少分钟;0 = 立刻隐藏。", (AcceptableValueBase)(object)new AcceptableValueRange(0f, 20f), Array.Empty())); } } internal sealed class DownedMarker : MonoBehaviour { private Character _character; private string _playerName = ""; private Vector3 _lastPosition; private TextMeshProUGUI _distanceText; private TextMeshProUGUI _statusText; private bool _isDead; private bool _hasPosition; internal void Bind(Character character) { _character = character; _isDead = false; _hasPosition = false; _playerName = ResolveName(character); CacheTexts(); if ((Object)(object)_statusText != (Object)null) { ((TMP_Text)_statusText).text = "(@_@;)"; } CapturePositionNow(); } internal void MarkDead() { _isDead = true; _playerName = ResolveName(_character); if ((Object)(object)_statusText != (Object)null) { ((TMP_Text)_statusText).text = "(x_x;)"; } } internal void CapturePositionNow() { TryCapturePosition(); } private void Start() { CacheTexts(); if ((Object)(object)_statusText != (Object)null && string.IsNullOrEmpty(((TMP_Text)_statusText).text)) { ((TMP_Text)_statusText).text = "(@_@;)"; } } private void CacheTexts() { if ((Object)(object)_distanceText == (Object)null) { Transform val = ((Component)this).transform.Find("DistanceText"); if ((Object)(object)val != (Object)null) { _distanceText = ((Component)val).GetComponent(); } } if ((Object)(object)_statusText == (Object)null) { Transform val2 = ((Component)this).transform.Find("StatusText"); if ((Object)(object)val2 != (Object)null) { _statusText = ((Component)val2).GetComponent(); } } } private void LateUpdate() { //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_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_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: 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_00f8: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_0105: 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) CacheTexts(); Camera val = SpectatorUiCamera.Get(); if ((Object)(object)val == (Object)null || (Object)(object)_distanceText == (Object)null || (Object)(object)_statusText == (Object)null) { return; } if (!_isDead) { TryCapturePosition(); if ((Object)(object)_character != (Object)null) { _playerName = ResolveName(_character); } } if (!_hasPosition) { return; } Vector3 position = ((Component)val).transform.position; Vector3 val2 = _lastPosition - position; Vector3 val3 = val.WorldToScreenPoint(_lastPosition); float num = ((((Vector3)(ref val2)).sqrMagnitude > 0.0001f) ? Vector3.Angle(((Component)val).transform.forward, val2) : 180f); bool active = val3.z > 0.1f && num < 90f; ((Component)this).transform.position = val3; Color color = (((Object)(object)_character != (Object)null) ? PingDistanceManager.GetReadablePlayerColor(_character) : Color.white); ((Graphic)_statusText).color = color; ((Graphic)_distanceText).color = color; float num2 = Mathf.Max(1f, Mathf.Round(((Vector3)(ref val2)).magnitude)); int num3 = 100; try { if ((Object)(object)_character != (Object)null && (Object)(object)_character.data != (Object)null) { num3 = 100 - Mathf.CeilToInt(_character.data.deathTimer * 100f); num3 = Mathf.Clamp(num3, 0, 100); } } catch { num3 = 0; } string arg = (string.IsNullOrEmpty(_playerName) ? GameL10n.Pick("Unknown", "未知") : _playerName); string arg2 = (_isDead ? GameL10n.Pick("DEAD", "已死亡") : GameL10n.Pick($"{num3}% to revive", $"{num3}% 待救援")); ((TMP_Text)_distanceText).text = (_isDead ? GameL10n.Pick($"{arg}'s corpse · {num2}m | {arg2}", $"{arg} 的尸体 · {num2}m | {arg2}") : $"{arg} · {num2}m | {arg2}"); ((Component)_statusText).gameObject.SetActive(active); ((Component)_distanceText).gameObject.SetActive(active); } private static string ResolveName(Character character) { if ((Object)(object)character == (Object)null) { return ""; } try { if (!string.IsNullOrEmpty(character.characterName)) { return character.characterName; } } catch { } return ((Object)character).name; } private void TryCapturePosition() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_character == (Object)null) { return; } try { _lastPosition = _character.TorsoPos(); _hasPosition = true; } catch { try { _lastPosition = _character.Center; _hasPosition = true; } catch { } } } } internal sealed class DownedMarkerManager { private TMP_FontAsset _font; private Material _fontMaterial; private Canvas _canvas; private GameObject _template; private readonly Dictionary _instances = new Dictionary(); internal bool IsInitialized { get { if ((Object)(object)Plugin.Instance != (Object)null && (Object)(object)_canvas != (Object)null) { return (Object)(object)_template != (Object)null; } return false; } } internal void Initialize() { if (IsInitialized) { return; } try { CreateCanvas(); CreateTemplate(); } catch (Exception ex) { Plugin.Log.LogError((object)("DownedMarkerManager.Initialize failed: " + ex)); } } internal void Cleanup() { if ((Object)(object)_canvas != (Object)null) { Object.Destroy((Object)(object)((Component)_canvas).gameObject); _canvas = null; } _template = null; _instances.Clear(); } private void FindFont() { TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll(); TextMeshProUGUI[] array2 = array; foreach (TextMeshProUGUI val in array2) { if (!((Object)(object)val == (Object)null)) { Material materialForRendering = ((Graphic)val).materialForRendering; if (((Object)val).name == "Text" && (Object)(object)materialForRendering != (Object)null && ((Object)materialForRendering).name.Contains("DarumaDropOne-Regular SDF")) { _font = ((TMP_Text)val).font; _fontMaterial = materialForRendering; return; } } } array2 = array; foreach (TextMeshProUGUI val2 in array2) { if (!((Object)(object)((val2 != null) ? ((TMP_Text)val2).font : null) == (Object)null) && (((Object)((TMP_Text)val2).font).name.Contains("Daruma") || ((Object)(object)((Graphic)val2).materialForRendering != (Object)null && ((Object)((Graphic)val2).materialForRendering).name.Contains("Daruma")))) { _font = ((TMP_Text)val2).font; _fontMaterial = ((Graphic)val2).materialForRendering; break; } } } private void CreateCanvas() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_canvas != (Object)null)) { _instances.Clear(); GameObject val = GameObject.Find("GAME/GUIManager"); if (!((Object)(object)val == (Object)null)) { GameObject val2 = new GameObject("Canvas_SymbioticGhostDownedMarkers", new Type[3] { typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); val2.transform.SetParent(val.transform, false); _canvas = val2.GetComponent(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 101; CanvasScaler component = val2.GetComponent(); component.uiScaleMode = (ScaleMode)1; component.referenceResolution = new Vector2(1920f, 1080f); component.screenMatchMode = (ScreenMatchMode)1; val2.layer = LayerMask.NameToLayer("UI"); } } } private void CreateTemplate() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0091: 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) if (!((Object)(object)_template != (Object)null) && !((Object)(object)_canvas == (Object)null)) { _template = new GameObject("DownedMarker", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(DownedMarker) }); _template.transform.SetParent(((Component)_canvas).transform, false); TextMeshProUGUI component = AddTmpChild("StatusText", _template.transform, new Vector2(200f, 80f)).GetComponent(); ((TMP_Text)component).fontSize = 35f; ((TMP_Text)component).outlineWidth = 0f; ((TMP_Text)component).alignment = (TextAlignmentOptions)258; TextMeshProUGUI component2 = AddTmpChild("DistanceText", _template.transform, new Vector2(360f, 70f)).GetComponent(); ((TMP_Text)component2).fontStyle = (FontStyles)1; ((TMP_Text)component2).alignment = (TextAlignmentOptions)1026; _template.SetActive(false); } } private GameObject AddTmpChild(string name, Transform parent, Vector2 size) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_013e: Unknown result type (might be due to invalid IL or missing references) //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Expected O, but got Unknown if ((Object)(object)_font == (Object)null) { FindFont(); } GameObject val = new GameObject(name, new Type[4] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI), typeof(Shadow) }); val.transform.SetParent(parent, false); RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = size; TextMeshProUGUI component2 = val.GetComponent(); ((TMP_Text)component2).font = _font; if ((Object)(object)_fontMaterial != (Object)null) { ((TMP_Text)component2).fontMaterial = _fontMaterial; } ((TMP_Text)component2).fontSize = 20f; ((Graphic)component2).color = Color.white; ((TMP_Text)component2).outlineWidth = 0.2f; ((TMP_Text)component2).outlineColor = Color32.op_Implicit(Color.black); ((TMP_Text)component2).enableAutoSizing = false; ((TMP_Text)component2).alignment = (TextAlignmentOptions)514; ((Graphic)component2).raycastTarget = false; Shadow component3 = val.GetComponent(); component3.effectColor = new Color(0f, 0f, 0f, 0.95f); component3.effectDistance = new Vector2(2f, -2f); return val; } internal void CreateInstance(Character character) { if (Configuration.EnableDownedMarkers.Value && !((Object)(object)_canvas == (Object)null) && !((Object)(object)_template == (Object)null) && !((Object)(object)character == (Object)null) && (!_instances.TryGetValue(character, out var value) || !((Object)(object)value != (Object)null))) { GameObject val = Object.Instantiate(_template, ((Component)_canvas).transform); val.GetComponent().Bind(character); val.SetActive(true); _instances[character] = val; } } internal void PrepareForDeath(Character character) { if (Configuration.EnableDownedMarkers.Value && !((Object)(object)character == (Object)null)) { if ((Object)(object)_canvas == (Object)null || (Object)(object)_template == (Object)null) { Initialize(); } CreateInstance(character); if (_instances.TryGetValue(character, out var value) && (Object)(object)value != (Object)null) { value.GetComponent()?.CapturePositionNow(); } } } internal void UpdateInstance(Character character, bool isDead = false) { if ((Object)(object)character == (Object)null) { return; } if (!_instances.TryGetValue(character, out var value) || (Object)(object)value == (Object)null) { if (isDead) { CreateInstance(character); if (_instances.TryGetValue(character, out value) && (Object)(object)value != (Object)null) { MarkDeadAndScheduleRemoval(character, value); } } } else if (isDead) { MarkDeadAndScheduleRemoval(character, value); } else { _instances.Remove(character); Object.Destroy((Object)(object)value); } } private void MarkDeadAndScheduleRemoval(Character character, GameObject instance) { instance.GetComponent()?.MarkDead(); float num = Mathf.Max(0f, Configuration.DeadCorpseMarkerMinutes.Value) * 60f; _instances.Remove(character); if (num <= 0.01f) { Object.Destroy((Object)(object)instance); } else { Object.Destroy((Object)(object)instance, num); } } } [HarmonyPatch(typeof(GUIManager))] internal static class DownedMarkerGuiPatches { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPostfix() { Plugin.DownedMarkers?.Initialize(); } [HarmonyPatch("LateUpdate")] [HarmonyPostfix] private static void LateUpdatePostfix() { if (Plugin.DownedMarkers != null && !Plugin.DownedMarkers.IsInitialized) { Plugin.DownedMarkers.Initialize(); } } [HarmonyPatch("OnDestroy")] [HarmonyPostfix] private static void OnDestroyPostfix() { Plugin.DownedMarkers?.Cleanup(); } } [HarmonyPatch(typeof(Character))] internal static class DownedMarkerCharacterPatches { [HarmonyPatch("RPCA_PassOut")] [HarmonyPostfix] private static void PassOutPostfix(Character __instance) { Plugin.DownedMarkers?.CreateInstance(__instance); } [HarmonyPatch("RPCA_UnPassOut")] [HarmonyPostfix] private static void UnPassOutPostfix(Character __instance) { Plugin.DownedMarkers?.UpdateInstance(__instance); } [HarmonyPatch("RPCA_ReviveAtPosition")] [HarmonyPostfix] private static void RevivePostfix(Character __instance) { Plugin.DownedMarkers?.UpdateInstance(__instance); } [HarmonyPatch("RPCA_Die")] [HarmonyPrefix] private static void DiePrefix(Character __instance) { Plugin.DownedMarkers?.PrepareForDeath(__instance); } [HarmonyPatch("RPCA_Die")] [HarmonyPostfix] private static void DiePostfix(Character __instance) { Plugin.DownedMarkers?.UpdateInstance(__instance, isDead: true); } [HarmonyPatch("OnDestroy")] [HarmonyPostfix] private static void DestroyPostfix(Character __instance) { Plugin.DownedMarkers?.UpdateInstance(__instance); } } [HarmonyPatch(typeof(GodCam), "Update")] internal static class FreeCamPatches { private static bool Prefix(Transform transform, MainCamera cam) { FreeSpectatorController instance = FreeSpectatorController.Instance; if (instance == null || !instance.IsActive) { return true; } instance.UpdateFreeCam(transform, cam); return false; } } internal sealed class FreeSpectatorController { private static readonly FieldInfo IsGodCamField = AccessTools.Field(typeof(MainCameraMovement), "isGodCam"); private static readonly FieldInfo LookDataField = AccessTools.Field(typeof(GodCam), "lookData"); private static readonly FieldInfo LookVelField = AccessTools.Field(typeof(GodCam), "lookVel"); private static readonly FieldInfo VelField = AccessTools.Field(typeof(GodCam), "vel"); private static readonly MethodInfo SpecCharacterSetter = AccessTools.PropertySetter(typeof(MainCameraMovement), "specCharacter"); private Vector3 _velocity; private Vector2 _lookData; private Vector2 _lookVel; internal static FreeSpectatorController Instance { get; private set; } internal bool IsActive { get; private set; } internal FreeSpectatorController() { Instance = this; } internal void Update() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) HostBond.Instance?.Tick(); if (Input.GetKeyDown(Configuration.ToggleKey.Value)) { if (IsActive) { SetActive(active: false); } else if (CanEnterFreeFly()) { SetActive(active: true); } else { TryShowFreeFlyBlockedTip(); } } if (IsActive && !CanStayInFreeFly()) { SetActive(active: false); } } internal void SetActive(bool active, bool forcedByLeash = false) { //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005d: 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) MainCameraMovement instance = Singleton.Instance; if ((Object)(object)instance == (Object)null) { IsActive = false; } else if (active == IsActive) { IsGodCamField?.SetValue(instance, active); } else if (active) { HostBond.Instance?.LockHostFromCurrentSpec(); SyncLookFromCamera(instance); _velocity = Vector3.zero; _lookVel = Vector2.zero; IsActive = true; IsGodCamField?.SetValue(instance, true); Cursor.lockState = (CursorLockMode)1; Cursor.visible = false; HostBond.Instance?.RefillTimer(); GhostFreeSync.NotifyLocalFreeFlyStarted(); Plugin.Log.LogInfo((object)"Free-fly enabled."); } else { IsActive = false; IsGodCamField?.SetValue(instance, false); Character obj = (((Object)(object)HostBond.Instance != (Object)null) ? HostBond.Instance.Host : null); RestoreSpecTarget(obj); HostBond.Instance?.RefillTimer(); GhostFreeSync.NotifyLocalFreeFlyStopped(obj); Plugin.Log.LogInfo((object)(forcedByLeash ? "Free-fly forced off by leash countdown; returned to attach spectate." : "Free-fly disabled; returned to attach spectate.")); } } internal void ForceExitByLeash() { if (IsActive) { SetActive(active: false, forcedByLeash: true); } } internal void UpdateFreeCam(Transform transform, MainCamera cam) { //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_000b: 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_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_0069: 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_017e: 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_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: 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_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: 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) //IL_01c7: 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_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: 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_022f: Unknown result type (might be due to invalid IL or missing references) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0271: 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) if (GUIManager.InPauseMenu) { _velocity = Vector3.zero; _lookVel = Vector2.zero; LookDataField?.SetValue(Singleton.Instance?.godcam, _lookData); LookVelField?.SetValue(Singleton.Instance?.godcam, _lookVel); VelField?.SetValue(Singleton.Instance?.godcam, _velocity); return; } ApplyCharacterMatchedLook(transform); SyncCharacterLookFromFreeFly(transform); Vector3 zero = Vector3.zero; if (Input.GetKey((KeyCode)119)) { zero.z += 1f; } if (Input.GetKey((KeyCode)115)) { zero.z -= 1f; } if (Input.GetKey((KeyCode)97)) { zero.x -= 1f; } if (Input.GetKey((KeyCode)100)) { zero.x += 1f; } if (Input.GetKey((KeyCode)32)) { zero.y += 1f; } if (Input.GetKey((KeyCode)306)) { zero.y -= 1f; } float num = Configuration.MoveSpeed.Value; if (Input.GetKey((KeyCode)304) || Input.GetKey((KeyCode)303)) { num *= 3f; } _velocity += transform.TransformDirection(zero) * num * Time.unscaledDeltaTime; _velocity = FRILerp.Lerp(_velocity, Vector3.zero, Configuration.MoveDamping.Value, false); transform.position += _velocity * Time.unscaledDeltaTime; LookDataField?.SetValue(Singleton.Instance?.godcam, _lookData); LookVelField?.SetValue(Singleton.Instance?.godcam, _lookVel); VelField?.SetValue(Singleton.Instance?.godcam, _velocity); GhostFreeSync.TickLocalPose(transform.position, transform.rotation); } private void ApplyCharacterMatchedLook(Transform transform) { //IL_001b: 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_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) float num = GetGameLookSensitivity() * Mathf.Max(0.01f, Configuration.LookSensitivityMultiplier.Value); Vector2 val = ReadLookInput(); int invertSign = GetInvertSign(isY: false); int invertSign2 = GetInvertSign(isY: true); _lookData.x += val.x * num * (float)invertSign; _lookData.y += val.y * num * (float)invertSign2; _lookData.y = Mathf.Clamp(_lookData.y, -85f, 85f); _lookVel = Vector2.zero; transform.rotation = Quaternion.LookRotation(HelperFunctions.LookToDirection(new Vector3(_lookData.x, _lookData.y, 0f), Vector3.forward)); } private static Vector2 ReadLookInput() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) try { InputAction action_look = CharacterInput.action_look; if (action_look != null) { return action_look.ReadValue(); } } catch { } return new Vector2(Input.GetAxis("Mouse X"), Input.GetAxis("Mouse Y")); } private static float GetGameLookSensitivity() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 try { SettingsHandler val = (((Object)(object)GameHandler.Instance != (Object)null) ? GameHandler.Instance.SettingsHandler : null); if (val == null) { return 2f; } bool flag = false; try { flag = (int)InputHandler.GetCurrentUsedInputScheme() == 1; } catch { flag = false; } if (flag) { ControllerSensitivitySetting setting = val.GetSetting(); if (setting != null) { return ((FloatSetting)setting).Value; } } else { MouseSensitivitySetting setting2 = val.GetSetting(); if (setting2 != null) { return ((FloatSetting)setting2).Value; } } } catch { } return 2f; } private static int GetInvertSign(bool isY) { //IL_0049: 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) try { SettingsHandler val = (((Object)(object)GameHandler.Instance != (Object)null) ? GameHandler.Instance.SettingsHandler : null); if (val == null) { return 1; } if (isY) { InvertYSetting setting = val.GetSetting(); if (setting != null) { return ((int)((EnumSetting)(object)setting).Value == 0) ? 1 : (-1); } } else { InvertXSetting setting2 = val.GetSetting(); if (setting2 != null) { return ((int)((EnumSetting)(object)setting2).Value == 0) ? 1 : (-1); } } } catch { } return 1; } private void SyncCharacterLookFromFreeFly(Transform camTransform) { //IL_002b: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0064: 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_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: 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_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter?.data == (Object)null || (Object)(object)camTransform == (Object)null) { return; } localCharacter.data.lookValues = _lookData; Vector3 forward = camTransform.forward; if (!(((Vector3)(ref forward)).sqrMagnitude < 0.0001f)) { ((Vector3)(ref forward)).Normalize(); localCharacter.data.lookDirection = forward; Vector3 lookDirection_Flat = HelperFunctions.ZeroY(forward); if (((Vector3)(ref lookDirection_Flat)).sqrMagnitude > 0.0001f) { ((Vector3)(ref lookDirection_Flat)).Normalize(); localCharacter.data.lookDirection_Flat = lookDirection_Flat; CharacterData data = localCharacter.data; Vector3 val = Vector3.Cross(Vector3.up, forward); data.lookDirection_Right = ((Vector3)(ref val)).normalized; CharacterData data2 = localCharacter.data; val = Vector3.Cross(forward, localCharacter.data.lookDirection_Right); data2.lookDirection_Up = ((Vector3)(ref val)).normalized; } } } private static bool CanEnterFreeFly() { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || !localCharacter.data.fullyPassedOut) { return false; } if (IsSoloPlay()) { return true; } return localCharacter.data.dead; } private static bool CanStayInFreeFly() { return CanEnterFreeFly(); } private static bool IsSoloPlay() { try { if (PhotonNetwork.OfflineMode) { return true; } if (!PhotonNetwork.InRoom) { return true; } Player[] playerList = PhotonNetwork.PlayerList; if (playerList == null || playerList.Length == 0) { return true; } int num = 0; foreach (Player val in playerList) { if (val != null && !val.IsInactive) { num++; } } return num <= 1; } catch { return true; } } private static void TryShowFreeFlyBlockedTip() { Character localCharacter = Character.localCharacter; if (!((Object)(object)localCharacter?.data == (Object)null) && localCharacter.data.fullyPassedOut && !IsSoloPlay() && !localCharacter.data.dead) { GhostItemHaulToast.Show("Multiplayer: free-fly unlocks only after you fully die", "多人模式:昏迷中不能灵魂离体,完全死亡后才能按 F3", 2.8f); } } private void SyncLookFromCamera(MainCameraMovement movement) { //IL_0009: 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_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) Transform transform = ((Component)movement).transform; _lookData = Vector2.op_Implicit(HelperFunctions.DirectionToLook(transform.forward)); LookDataField?.SetValue(movement.godcam, _lookData); LookVelField?.SetValue(movement.godcam, Vector2.zero); VelField?.SetValue(movement.godcam, Vector3.zero); } private static void RestoreSpecTarget(Character target) { if ((Object)(object)target == (Object)null || (Object)(object)((Component)target).gameObject == (Object)null || !((Component)target).gameObject.activeInHierarchy) { return; } try { if (!target.data.canBeSpectated) { return; } } catch { return; } SpecCharacterSetter?.Invoke(null, new object[1] { target }); } } internal static class GameL10n { internal static bool UseChinese { get { //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) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Invalid comparison between Unknown and I4 //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 Language cURRENT_LANGUAGE = LocalizedText.CURRENT_LANGUAGE; if ((int)cURRENT_LANGUAGE != 9) { return (int)cURRENT_LANGUAGE == 10; } return true; } } internal static string Pick(string english, string chinese) { if (!UseChinese) { return english; } return chinese; } } internal static class GhostBackpackPatches { private const byte TempHoldSlot = 250; private static bool GhostMode { get { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null) { return localCharacter.data.fullyPassedOut; } return false; } } private static bool FeatureEnabled { get { if (Configuration.EnableGhostBackpack.Value) { return GhostMode; } return false; } } private static bool GhostInteractionEnabled { get { if (GhostMode && ModPresence.AllPlayersHaveMod) { if (!Configuration.EnableGhostBackpack.Value) { return GhostFeedPatches.GhostCanFeed; } return true; } return false; } } [HarmonyPatch(typeof(Interaction), "LateUpdate")] [HarmonyPrefix] private static bool InteractionLateUpdatePrefix(Interaction __instance) { if (!GhostInteractionEnabled) { return true; } GhostFeedPatches.SyncGhostLookFromCamera(); GhostFeedPatches.SampleGhostUseInputs(Character.localCharacter.input); __instance.currentHovered = null; __instance.bestInteractable = null; __instance.bestCharacter = null; IInteractible result = null; CharacterInteractible result2 = null; if (GhostFeedPatches.GhostCanFeed && TryFindFeedCharacter(out result2)) { result = (IInteractible)(object)result2; } else if (Configuration.EnableGhostBackpack.Value) { TryFindBackpackInteractable(out result); } if (result == null) { ClearHeldInteract(__instance); return false; } __instance.bestInteractable = result; __instance.bestCharacter = result2; AccessTools.Method(typeof(Interaction), "DoInteraction", (Type[])null, (Type[])null)?.Invoke(__instance, new object[1] { result }); __instance.currentHovered = result; __instance.bestInteractableName = (((Object)(object)result.GetTransform() != (Object)null) ? ((Object)((Component)result.GetTransform()).gameObject).name : "ghost-interact"); return false; } private static bool TryFindFeedCharacter(out CharacterInteractible result) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_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_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) result = null; MainCamera instance = MainCamera.instance; Character localCharacter = Character.localCharacter; if ((Object)(object)instance == (Object)null || (Object)(object)localCharacter == (Object)null || (Object)(object)Interaction.instance == (Object)null) { return false; } float distance = Interaction.instance.distance; Ray val = new Ray(((Component)instance).transform.position, ((Component)instance).transform.forward); CharacterInteractible val2 = null; float num = distance + 1.5f; RaycastHit val3 = default(RaycastHit); if (Physics.Raycast(val, ref val3, num, -1, (QueryTriggerInteraction)2)) { CharacterInteractible val4 = (((Object)(object)((RaycastHit)(ref val3)).collider != (Object)null) ? ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent() : null); if ((Object)(object)val4 != (Object)null && val4.IsSecondaryInteractible(localCharacter)) { val2 = val4; num = ((RaycastHit)(ref val3)).distance; } } Collider[] array = Physics.OverlapSphere(((Component)instance).transform.position + ((Component)instance).transform.forward * 1f, 1.35f); for (int i = 0; i < array.Length; i++) { CharacterInteractible val5 = (((Object)(object)array[i] != (Object)null) ? ((Component)array[i]).GetComponentInParent() : null); if (!((Object)(object)val5 == (Object)null) && val5.IsSecondaryInteractible(localCharacter)) { Vector3 val6 = val5.Center() - ((Component)instance).transform.position; float magnitude = ((Vector3)(ref val6)).magnitude; if (!(magnitude >= num) && !(Vector3.Angle(((Component)instance).transform.forward, val6) > 40f)) { val2 = val5; num = magnitude; } } } result = val2; return (Object)(object)val2 != (Object)null; } [HarmonyPatch(typeof(Player), "AddItem")] [HarmonyPrefix] private static bool AddItemPrefix(Player __instance, ushort itemID, ItemInstanceData instanceData, out ItemSlot slot, ref bool __result) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown //IL_00c2: Unknown result type (might be due to invalid IL or missing references) slot = null; Character character = __instance.character; if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null || !character.data.fullyPassedOut) { return true; } if (!PhotonNetwork.IsMasterClient) { Debug.LogError((object)"Only Master Client can add items!"); __result = false; return false; } ItemInstanceData val = instanceData; if (val == null) { val = new ItemInstanceData(Guid.NewGuid()); ItemInstanceDataHandler.AddInstanceData(val); } Item val2 = default(Item); if (!ItemDatabase.TryGetItem(itemID, ref val2)) { __result = false; return false; } if (val2 is Backpack) { __result = false; return false; } if (!__instance.tempFullSlot.IsEmpty() || character.data.isClimbingAnything) { __result = false; return false; } __instance.tempFullSlot.SetItem(val2, val); slot = __instance.tempFullSlot; byte[] array = IBinarySerializable.ToManagedArray(new InventorySyncData(__instance.itemSlots, __instance.backpackSlot, __instance.tempFullSlot)); __instance.view.RPC("SyncInventoryRPC", (RpcTarget)1, new object[2] { array, false }); __result = true; return false; } [HarmonyPatch(typeof(BackpackWheel), "Choose")] [HarmonyPrefix] private static bool ChoosePrefix(BackpackWheel __instance) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) if (!GhostMode || !Configuration.EnableGhostBackpack.Value) { return true; } if (!__instance.chosenSlice.IsSome) { return true; } SliceData value = __instance.chosenSlice.Value; if (value.isBackpackWear) { return true; } ItemSlot val = ((BackpackReference)(ref __instance.backpack)).GetData().itemSlots[value.slotID]; if (value.isStashSlice || val == null || val.IsEmpty() || !((Object)(object)Character.localCharacter.data.currentItem == (Object)null)) { if (!value.isStashSlice && val != null && !val.IsEmpty() && (!Character.localCharacter.player.tempFullSlot.IsEmpty() || (Object)(object)Character.localCharacter.data.currentItem != (Object)null)) { GhostItemHaulToast.Show("Ghosts can only hold one item", "幽灵同时只能持有一件物品"); return false; } return true; } if (!Character.localCharacter.player.tempFullSlot.IsEmpty()) { GhostItemHaulToast.Show("Ghosts can only hold one item", "幽灵同时只能持有一件物品"); return false; } Item prefab = val.prefab; if (!GhostItemHaul.IsWithinWeightLimit(prefab)) { GhostItemHaul.ShowTooHeavyToast(prefab); return false; } return true; } [HarmonyPatch(typeof(Backpack), "Wear")] [HarmonyPrefix] private static bool WearPrefix(Character interactor) { if ((Object)(object)interactor != (Object)null && (Object)(object)interactor.data != (Object)null && interactor.data.fullyPassedOut) { GhostItemHaulToast.Show("Ghosts cannot wear backpacks", "幽灵不能背起背包"); return false; } return true; } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] private static void WearSliceInteractPostfix(BackpackWheelSlice __instance, ref bool __result) { if (__result && __instance.isBackpackWear && GhostMode) { __result = false; } } [HarmonyPatch(typeof(BackpackOnBackVisuals), "IsInteractible")] [HarmonyPrefix] private static bool WornBackpackInteractiblePrefix(BackpackOnBackVisuals __instance, Character interactor, ref bool __result) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) if (!FeatureEnabled || (Object)(object)interactor == (Object)null || !interactor.IsLocal) { return true; } MainCamera instance = MainCamera.instance; if ((Object)(object)instance == (Object)null) { __result = false; return false; } Vector3 val = HelperFunctions.ZeroY(((Component)instance).transform.forward); Vector3 val2 = HelperFunctions.ZeroY(((Component)__instance).transform.forward); __result = Vector3.Angle(val, val2) < 110f; return false; } [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPostfix] private static void CenterPostfix(Character __instance, ref Vector3 __result) { //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) if (!((Object)(object)__instance == (Object)null) && __instance.IsLocal && !((Object)(object)__instance.data == (Object)null) && __instance.data.fullyPassedOut && __instance.data.usingBackpackWheel) { __result = NameAnchor.GetViewerPosition(); } } [HarmonyPatch(typeof(CharacterItems), "GetItemHoldPos")] [HarmonyPostfix] private static void HoldPosPostfix(CharacterItems __instance, Item item, bool pushOffTerrain, ref Vector3 __result) { //IL_0013: 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) if (TryGetGhostHoldPose(__instance.character, out var position, out var _)) { __result = position; } } [HarmonyPatch(typeof(CharacterItems), "AttachItem")] [HarmonyPrefix] private static bool AttachItemPrefix(CharacterItems __instance) { Character character = __instance.character; if (!((Object)(object)character == (Object)null) && !((Object)(object)character.data == (Object)null)) { return !character.data.fullyPassedOut; } return true; } [HarmonyPatch(typeof(CharacterItems), "HoldItem")] [HarmonyPrefix] private static bool HoldItemPrefix(CharacterItems __instance, Item item) { //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Unknown result type (might be due to invalid IL or missing references) Character character = __instance.character; if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null || !character.data.fullyPassedOut || (Object)(object)item == (Object)null) { return true; } if (!TryGetGhostHoldPose(character, out var position, out var rotation)) { return true; } DetachGhostHandJoints(character); EnsureGhostHeldItemNonSolid(item); Vector3 position2 = ((Component)item).transform.position; item.Move(position, rotation); bool flag = false; try { flag = (Object)(object)((MonoBehaviourPun)item).photonView != (Object)null && ((MonoBehaviourPun)item).photonView.IsMine; } catch { flag = character.IsLocal; } if (flag && Vector3.Distance(position2, position) > 8f) { try { item.ForceSyncForFrames(15); } catch { } } return false; } [HarmonyPatch(typeof(CharacterItems), "AddGravity")] [HarmonyPrefix] private static bool SkipGhostItemGravity(CharacterItems __instance) { return !IsGhostHolding(__instance); } [HarmonyPatch(typeof(CharacterItems), "AddMovementForce")] [HarmonyPrefix] private static bool SkipGhostItemMoveForce(CharacterItems __instance) { return !IsGhostHolding(__instance); } [HarmonyPatch(typeof(CharacterItems), "AddDrag")] [HarmonyPrefix] private static bool SkipGhostItemDrag(CharacterItems __instance) { return !IsGhostHolding(__instance); } private static bool IsGhostHolding(CharacterItems items) { Character val = (((Object)(object)items != (Object)null) ? items.character : null); if ((Object)(object)val != (Object)null && (Object)(object)val.data != (Object)null && val.data.fullyPassedOut) { return (Object)(object)val.data.currentItem != (Object)null; } return false; } private static void EnsureGhostHeldItemNonSolid(Item item) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null) { return; } try { if ((Object)(object)item.rig != (Object)null) { item.rig.isKinematic = true; item.rig.detectCollisions = false; item.rig.useGravity = false; item.rig.linearVelocity = Vector3.zero; item.rig.angularVelocity = Vector3.zero; } } catch { } try { Collider[] colliders = item.colliders; if (colliders == null) { return; } for (int i = 0; i < colliders.Length; i++) { if ((Object)(object)colliders[i] != (Object)null) { colliders[i].enabled = false; } } } catch { } } internal static bool TryGetGhostHoldPosePublic(Character character, out Vector3 position, out Quaternion rotation) { return TryGetGhostHoldPose(character, out position, out rotation); } private static bool TryGetGhostHoldPose(Character character, out Vector3 position, out Quaternion rotation) { //IL_0001: 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_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) //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_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: 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_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) position = default(Vector3); rotation = Quaternion.identity; if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null || !character.data.fullyPassedOut) { return false; } if ((Object)(object)character.refs?.items == (Object)null) { return false; } Optionable currentSelectedSlot = character.refs.items.currentSelectedSlot; if (!currentSelectedSlot.IsSome || currentSelectedSlot.Value != 250) { return false; } Vector3 ghostFeetPosition = NameAnchor.GetGhostFeetPosition(character); Vector3 val = NameAnchor.GetGhostLookForward(character); val.y = 0f; if (((Vector3)(ref val)).sqrMagnitude < 0.001f) { val = Vector3.forward; } ((Vector3)(ref val)).Normalize(); position = ghostFeetPosition + val * 0.75f + Vector3.up * 0.45f; rotation = Quaternion.LookRotation(val, Vector3.up); return true; } private static void DetachGhostHandJoints(Character character) { DestroyHandJoint(character, (BodypartType)7); DestroyHandJoint(character, (BodypartType)10); } private static void DestroyHandJoint(Character character, BodypartType part) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) try { Rigidbody bodypartRig = character.GetBodypartRig(part); FixedJoint val = default(FixedJoint); if ((Object)(object)bodypartRig != (Object)null && ((Component)bodypartRig).gameObject.TryGetComponent(ref val)) { Object.Destroy((Object)(object)val); } } catch { } } [HarmonyPatch(typeof(CharacterItems), "DropItemRpc")] [HarmonyPrefix] private static void DropItemRpcPrefix(CharacterItems __instance, float throwCharge, ref Vector3 spawnPos) { //IL_0072: 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_008b: 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_006a: Unknown result type (might be due to invalid IL or missing references) Character character = __instance.character; if (!((Object)(object)character == (Object)null) && !((Object)(object)character.data == (Object)null) && character.data.fullyPassedOut) { if (character.IsLocal) { GhostFeedPatches.SyncGhostLookFromCamera(); } if (throwCharge > 0.05f && (Object)(object)character.data.currentItem != (Object)null) { spawnPos = ((Component)character.data.currentItem).transform.position; } else { spawnPos = NameAnchor.GetGhostFeetPosition(character) + Vector3.up * 0.4f; } } } private static void ClearHeldInteract(Interaction interaction) { if (!Character.localCharacter.input.interactIsPressed) { interaction.readyToInteract = true; AccessTools.Method(typeof(Interaction), "CancelHeldInteract", (Type[])null, (Type[])null)?.Invoke(interaction, null); } } private static bool TryFindBackpackInteractable(out IInteractible result) { //IL_0039: 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_0077: 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) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: 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_00cf: 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_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) result = null; MainCamera instance = MainCamera.instance; if ((Object)(object)instance == (Object)null) { return false; } float num = (((Object)(object)Interaction.instance != (Object)null) ? Interaction.instance.distance : 2.5f); RaycastHit val = default(RaycastHit); if (Physics.Raycast(new Ray(((Component)instance).transform.position, ((Component)instance).transform.forward), ref val, num + 1.5f, -1, (QueryTriggerInteraction)2) && TryGetBackpackInteractable(((RaycastHit)(ref val)).collider, out result)) { return true; } Collider[] array = Physics.OverlapSphere(((Component)instance).transform.position + ((Component)instance).transform.forward * 1.2f, 1.25f); float num2 = 40f; IInteractible val2 = null; for (int i = 0; i < array.Length; i++) { if (TryGetBackpackInteractable(array[i], out var interactable)) { Vector3 val3 = interactable.Center() - ((Component)instance).transform.position; float num3 = Vector3.Angle(((Component)instance).transform.forward, val3); if (num3 < num2 && ((Vector3)(ref val3)).magnitude <= num + 2f) { num2 = num3; val2 = interactable; } } } result = val2; return val2 != null; } private static bool TryGetBackpackInteractable(Collider col, out IInteractible interactable) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) interactable = null; if ((Object)(object)col == (Object)null) { return false; } Backpack componentInParent = ((Component)col).GetComponentInParent(); if ((Object)(object)componentInParent != (Object)null && (int)((Item)componentInParent).itemState == 0 && ((Item)componentInParent).IsInteractible(Character.localCharacter)) { interactable = (IInteractible)(object)componentInParent; return true; } BackpackOnBackVisuals componentInParent2 = ((Component)col).GetComponentInParent(); if ((Object)(object)componentInParent2 != (Object)null && componentInParent2.IsInteractible(Character.localCharacter)) { interactable = (IInteractible)(object)componentInParent2; return true; } return false; } } internal static class GhostFeedPatches { internal static bool GhostCanFeed { get { if (!Configuration.EnableGhostHaul.Value || !ModPresence.AllPlayersHaveMod) { return false; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || !localCharacter.data.fullyPassedOut) { return false; } return CanGhostFeedItem(localCharacter.data.currentItem); } } internal static bool IsBlockedGhostFeedItem(Item item) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null) { return true; } try { if (((Enum)item.itemTags).HasFlag((Enum)(object)(ItemTags)512)) { return true; } } catch { } return false; } internal static bool CanGhostFeedItem(Item item) { if ((Object)(object)item != (Object)null && item.canUseOnFriend) { return !IsBlockedGhostFeedItem(item); } return false; } internal static void SyncGhostLookFromCamera() { //IL_0046: 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) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: 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_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //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_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) Character localCharacter = Character.localCharacter; MainCamera instance = MainCamera.instance; if ((Object)(object)localCharacter?.data == (Object)null || !localCharacter.IsLocal || (Object)(object)instance == (Object)null || !localCharacter.data.fullyPassedOut) { return; } Vector3 forward = ((Component)instance).transform.forward; if (!(((Vector3)(ref forward)).sqrMagnitude < 0.0001f)) { ((Vector3)(ref forward)).Normalize(); localCharacter.data.lookDirection = forward; localCharacter.data.lookValues = Vector2.op_Implicit(HelperFunctions.DirectionToLook(forward)); Vector3 lookDirection_Flat = HelperFunctions.ZeroY(forward); if (((Vector3)(ref lookDirection_Flat)).sqrMagnitude > 0.0001f) { ((Vector3)(ref lookDirection_Flat)).Normalize(); localCharacter.data.lookDirection_Flat = lookDirection_Flat; CharacterData data = localCharacter.data; Vector3 val = Vector3.Cross(Vector3.up, forward); data.lookDirection_Right = ((Vector3)(ref val)).normalized; CharacterData data2 = localCharacter.data; val = Vector3.Cross(forward, localCharacter.data.lookDirection_Right); data2.lookDirection_Up = ((Vector3)(ref val)).normalized; } } } internal static void SampleGhostUseInputs(CharacterInput input) { if (!((Object)(object)input == (Object)null)) { InputAction action_interact = CharacterInput.action_interact; InputAction action_useSecondary = CharacterInput.action_useSecondary; InputAction action_usePrimary = CharacterInput.action_usePrimary; InputAction action_drop = CharacterInput.action_drop; if (action_interact != null) { input.interactWasPressed = action_interact.WasPressedThisFrame(); input.interactIsPressed = action_interact.IsPressed(); input.interactWasReleased = action_interact.WasReleasedThisFrame(); } if (action_useSecondary != null) { input.useSecondaryWasPressed = action_useSecondary.WasPressedThisFrame(); input.useSecondaryIsPressed = action_useSecondary.IsPressed(); input.useSecondaryWasReleased = action_useSecondary.WasReleasedThisFrame(); } if (action_usePrimary != null) { input.usePrimaryWasPressed = action_usePrimary.WasPressedThisFrame(); input.usePrimaryIsPressed = action_usePrimary.IsPressed(); input.usePrimaryWasReleased = action_usePrimary.WasReleasedThisFrame(); } if (action_drop != null) { input.dropWasPressed = action_drop.WasPressedThisFrame(); input.dropIsPressed = action_drop.IsPressed(); input.dropWasReleased = action_drop.WasReleasedThisFrame(); } } } [HarmonyPatch(typeof(CharacterMovement), "Update")] [HarmonyPostfix] private static void MovementUpdatePostfix(CharacterMovement __instance) { Character character = __instance.character; if (!((Object)(object)character == (Object)null) && character.IsLocal && !((Object)(object)character.data == (Object)null) && character.data.fullyPassedOut) { SampleGhostSpectatorInputs(character.input); MainCameraMovement instance = Singleton.Instance; if (!((Object)(object)instance == (Object)null) && instance.isGodCam && Configuration.EnableGhostHaul.Value && ModPresence.AllPlayersHaveMod) { SampleGhostUseInputs(character.input); } } } internal static void SampleGhostSpectatorInputs(CharacterInput input) { if (!((Object)(object)input == (Object)null)) { SampleGhostPauseInput(input); SampleGhostPingInput(input); } } internal static void SampleGhostPauseInput(CharacterInput input) { if ((Object)(object)input == (Object)null) { return; } try { InputAction action_pause = CharacterInput.action_pause; if (action_pause != null) { input.pauseWasPressed = action_pause.WasPressedThisFrame(); } } catch { } } internal static void SampleGhostPingInput(CharacterInput input) { if ((Object)(object)input == (Object)null || !Configuration.EnableGhostPing.Value) { return; } if (GUIManager.InPauseMenu) { input.pingWasPressed = false; return; } try { InputAction action_ping = CharacterInput.action_ping; if (action_ping != null) { input.pingWasPressed = action_ping.WasPressedThisFrame(); } } catch { } } [HarmonyPatch(typeof(CharacterItems), "DoUsing")] [HarmonyPrefix] private static bool DoUsingPrefix(CharacterItems __instance) { Character character = __instance.character; if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null || !character.data.fullyPassedOut) { return true; } if (!character.IsLocal) { return false; } if (!Configuration.EnableGhostHaul.Value || !ModPresence.AllPlayersHaveMod) { return false; } Item currentItem = character.data.currentItem; if (!CanGhostFeedItem(currentItem)) { return false; } SyncGhostLookFromCamera(); CharacterInput input = character.input; if (input.useSecondaryIsPressed && currentItem.CanUseSecondary()) { currentItem.StartUseSecondary(); } if (input.useSecondaryIsPressed && currentItem.CanUseSecondary()) { currentItem.ContinueUseSecondary(); } if (input.useSecondaryWasReleased || (currentItem.isUsingSecondary && !currentItem.CanUseSecondary())) { currentItem.CancelUseSecondary(); } return false; } } internal sealed class GhostFreeSync : MonoBehaviour, IOnEventCallback, IMatchmakingCallbacks, IInRoomCallbacks { internal struct RemoteLink { public Vector3 GhostPosition; public Quaternion GhostRotation; public int HostViewId; public bool Active; public float LastUpdateUnscaledTime; } internal const byte EventCode = 174; private const float SendInterval = 0.05f; private const float StaleLinkSeconds = 2.5f; private static readonly Dictionary RemoteLinks = new Dictionary(); private static GhostFreeSync _instance; private static float _nextSendTime; private static bool _localFreeActive; private static int _localGhostViewId = -1; private static float _nextStaleSweep; internal static IEnumerable> EnumerateRemoteLinks() { return RemoteLinks; } internal static bool TryGetRemoteLink(int ghostViewId, out RemoteLink link) { return RemoteLinks.TryGetValue(ghostViewId, out link); } internal static void Ensure() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("SymbioticGhost_GhostFreeSync"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } } private void OnEnable() { PhotonNetwork.AddCallbackTarget((object)this); } private void OnDisable() { PhotonNetwork.RemoveCallbackTarget((object)this); ForceSendLocalFreeFlyStopped(); } private void OnApplicationQuit() { ForceSendLocalFreeFlyStopped(); } private void Update() { if (!(Time.unscaledTime < _nextStaleSweep)) { _nextStaleSweep = Time.unscaledTime + 0.5f; PurgeStaleRemoteLinks(); } } internal static void NotifyLocalFreeFlyStarted() { //IL_007e: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) _localFreeActive = true; _nextSendTime = 0f; PlayerGhost val = (((Object)(object)Character.localCharacter != (Object)null) ? Character.localCharacter.Ghost : null); Character val2 = (((Object)(object)HostBond.Instance != (Object)null) ? HostBond.Instance.Host : null); int hostViewId = (((Object)(object)val2 != (Object)null && val2.refs != null && (Object)(object)val2.refs.view != (Object)null) ? val2.refs.view.ViewID : (-1)); Vector3 localGhostWorldPosition = HostBond.GetLocalGhostWorldPosition(); Quaternion rotation = (((Object)(object)MainCamera.instance != (Object)null) ? ((Component)MainCamera.instance).transform.rotation : Quaternion.identity); if ((Object)(object)val != (Object)null && (Object)(object)val.m_view != (Object)null) { _localGhostViewId = val.m_view.ViewID; SendState(val.m_view.ViewID, active: true, localGhostWorldPosition, rotation, hostViewId, reliable: true); } } internal static void NotifyLocalFreeFlyStopped(Character reattachTarget) { //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_0085: 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) _localFreeActive = false; PlayerGhost val = (((Object)(object)Character.localCharacter != (Object)null) ? Character.localCharacter.Ghost : null); int hostViewId = (((Object)(object)reattachTarget != (Object)null && reattachTarget.refs != null && (Object)(object)reattachTarget.refs.view != (Object)null) ? reattachTarget.refs.view.ViewID : (-1)); if ((Object)(object)val != (Object)null && (Object)(object)val.m_view != (Object)null) { SendState(val.m_view.ViewID, active: false, ((Component)val).transform.position, ((Component)val).transform.rotation, hostViewId, reliable: true); if ((Object)(object)reattachTarget != (Object)null && reattachTarget.refs != null && (Object)(object)reattachTarget.refs.view != (Object)null) { val.m_view.RPC("RPCA_SetTarget", (RpcTarget)0, new object[1] { reattachTarget.refs.view }); } } else if (_localGhostViewId >= 0) { SendState(_localGhostViewId, active: false, Vector3.zero, Quaternion.identity, hostViewId, reliable: true); } SnapLocalHeldItemAfterFreeFlyExit(); if (_localGhostViewId >= 0) { RemoteLinks.Remove(_localGhostViewId); _localGhostViewId = -1; } } private static void ForceSendLocalFreeFlyStopped() { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) if (_localFreeActive || _localGhostViewId >= 0) { int num = _localGhostViewId; PlayerGhost val = (((Object)(object)Character.localCharacter != (Object)null) ? Character.localCharacter.Ghost : null); if ((Object)(object)val != (Object)null && (Object)(object)val.m_view != (Object)null) { num = val.m_view.ViewID; } _localFreeActive = false; if (num >= 0 && PhotonNetwork.InRoom) { SendState(num, active: false, Vector3.zero, Quaternion.identity, -1, reliable: true); } _localGhostViewId = -1; } } private static void SnapLocalHeldItemAfterFreeFlyExit() { //IL_0044: 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) Character localCharacter = Character.localCharacter; Item val = (((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null) ? localCharacter.data.currentItem : null); if ((Object)(object)val == (Object)null) { return; } try { if (GhostBackpackPatches.TryGetGhostHoldPosePublic(localCharacter, out var position, out var rotation)) { val.Move(position, rotation); val.ForceSyncForFrames(20); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Snap held item after free-fly exit failed: " + ex.Message)); } } internal static void TickLocalPose(Vector3 cameraPosition, Quaternion cameraRotation) { //IL_0050: 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_010a: 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) if (!_localFreeActive) { return; } PlayerGhost val = (((Object)(object)Character.localCharacter != (Object)null) ? Character.localCharacter.Ghost : null); if ((Object)(object)val != (Object)null && (Object)(object)val.m_view != (Object)null) { _localGhostViewId = val.m_view.ViewID; ((Component)val).transform.position = cameraPosition; ((Component)val).transform.rotation = cameraRotation; } if (PhotonNetwork.InRoom && !(Time.unscaledTime < _nextSendTime)) { _nextSendTime = Time.unscaledTime + 0.05f; Character val2 = (((Object)(object)HostBond.Instance != (Object)null) ? HostBond.Instance.Host : null); int hostViewId = (((Object)(object)val2 != (Object)null && val2.refs != null && (Object)(object)val2.refs.view != (Object)null) ? val2.refs.view.ViewID : (-1)); int num = (((Object)(object)val != (Object)null && (Object)(object)val.m_view != (Object)null) ? val.m_view.ViewID : _localGhostViewId); if (num >= 0) { SendState(num, active: true, cameraPosition, cameraRotation, hostViewId, reliable: false); } } } internal static bool TryApplyFreePose(PlayerGhost ghost) { //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ghost == (Object)null || (Object)(object)ghost.m_view == (Object)null) { return false; } int viewID = ghost.m_view.ViewID; if (_localFreeActive && (Object)(object)Character.localCharacter != (Object)null && (Object)(object)ghost == (Object)(object)Character.localCharacter.Ghost) { MainCamera instance = MainCamera.instance; if ((Object)(object)instance != (Object)null) { ((Component)ghost).transform.position = ((Component)instance).transform.position; ((Component)ghost).transform.rotation = ((Component)instance).transform.rotation; } return true; } if (RemoteLinks.TryGetValue(viewID, out var value) && value.Active) { if (Time.unscaledTime - value.LastUpdateUnscaledTime > 2.5f) { RemoteLinks.Remove(viewID); return false; } ((Component)ghost).transform.position = value.GhostPosition; ((Component)ghost).transform.rotation = value.GhostRotation; return true; } return false; } private static void SendState(int viewId, bool active, Vector3 position, Quaternion rotation, int hostViewId, bool reliable) { //IL_0023: 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_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //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_0096: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Expected O, but got Unknown //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) if (PhotonNetwork.InRoom) { object[] array = new object[10] { viewId, active, position.x, position.y, position.z, rotation.x, rotation.y, rotation.z, rotation.w, hostViewId }; RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)0 }; SendOptions val2 = (reliable ? SendOptions.SendReliable : SendOptions.SendUnreliable); PhotonNetwork.RaiseEvent((byte)174, (object)array, val, val2); } } public void OnEvent(EventData photonEvent) { //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: 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) if (photonEvent.Code == 174 && photonEvent.CustomData is object[] array && array.Length >= 10 && array[0] is int key) { object obj = array[1]; bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) == 0) { RemoteLinks.Remove(key); return; } Vector3 ghostPosition = default(Vector3); ((Vector3)(ref ghostPosition))..ctor(ToFloat(array[2]), ToFloat(array[3]), ToFloat(array[4])); Quaternion ghostRotation = default(Quaternion); ((Quaternion)(ref ghostRotation))..ctor(ToFloat(array[5]), ToFloat(array[6]), ToFloat(array[7]), ToFloat(array[8])); int hostViewId = ((array[9] is int num2) ? num2 : (-1)); RemoteLinks[key] = new RemoteLink { GhostPosition = ghostPosition, GhostRotation = ghostRotation, HostViewId = hostViewId, Active = true, LastUpdateUnscaledTime = Time.unscaledTime }; } } private static void PurgeStaleRemoteLinks() { if (RemoteLinks.Count == 0) { return; } List list = null; float unscaledTime = Time.unscaledTime; foreach (KeyValuePair remoteLink in RemoteLinks) { bool num = unscaledTime - remoteLink.Value.LastUpdateUnscaledTime > 2.5f; bool flag = (Object)(object)PhotonNetwork.GetPhotonView(remoteLink.Key) == (Object)null; if (num || flag) { if (list == null) { list = new List(); } list.Add(remoteLink.Key); } } if (list != null) { for (int i = 0; i < list.Count; i++) { RemoteLinks.Remove(list[i]); } } } private static void RemoveLinksOwnedBy(Player player) { if (player == null || RemoteLinks.Count == 0) { return; } List list = null; foreach (KeyValuePair remoteLink in RemoteLinks) { PhotonView photonView = PhotonNetwork.GetPhotonView(remoteLink.Key); bool num = (Object)(object)photonView != (Object)null && photonView.Owner != null && photonView.Owner.ActorNumber == player.ActorNumber; bool flag = (Object)(object)photonView == (Object)null; if (num || flag) { if (list == null) { list = new List(); } list.Add(remoteLink.Key); } } if (list != null) { for (int i = 0; i < list.Count; i++) { RemoteLinks.Remove(list[i]); } } } private static float ToFloat(object value) { if (!(value is float result)) { if (!(value is double num)) { if (value is int num2) { return num2; } return 0f; } return (float)num; } return result; } public void OnFriendListUpdate(List friendList) { } public void OnCreatedRoom() { } public void OnCreateRoomFailed(short returnCode, string message) { } public void OnJoinedRoom() { } public void OnJoinRoomFailed(short returnCode, string message) { } public void OnJoinRandomFailed(short returnCode, string message) { } public void OnLeftRoom() { ForceSendLocalFreeFlyStopped(); RemoteLinks.Clear(); } public void OnPlayerEnteredRoom(Player newPlayer) { } public void OnPlayerLeftRoom(Player otherPlayer) { RemoveLinksOwnedBy(otherPlayer); } public void OnRoomPropertiesUpdate(Hashtable propertiesThatChanged) { } public void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { } public void OnMasterClientSwitched(Player newMasterClient) { } } [HarmonyPatch(typeof(PlayerGhost), "Update")] internal static class PlayerGhostFreeFlyPatch { private static bool Prefix(PlayerGhost __instance) { return !GhostFreeSync.TryApplyFreePose(__instance); } } internal sealed class GhostItemHaul : MonoBehaviour { private static GhostItemHaul _instance; private Item _lookTarget; private float _lookTargetUntil; internal static void Ensure() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("SymbioticGhost_GhostItemHaul"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } } private void Update() { //IL_0047: Unknown result type (might be due to invalid IL or missing references) if (!Configuration.EnableGhostHaul.Value) { return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null && localCharacter.data.fullyPassedOut && ModPresence.AllPlayersHaveMod && Input.GetKeyDown(Configuration.GhostHaulKey.Value) && (!((Object)(object)Interaction.instance != (Object)null) || Interaction.instance.bestInteractable == null)) { if ((Object)(object)localCharacter.data.currentItem != (Object)null) { DropHeldItem(localCharacter); } else { TryPickupLookedItem(localCharacter); } } } private void OnGUI() { //IL_0100: 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_00b7: 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_01dc: 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) if (!Configuration.EnableGhostHaul.Value) { return; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter == (Object)null || (Object)(object)localCharacter.data == (Object)null || !localCharacter.data.fullyPassedOut || !ModPresence.AllPlayersHaveMod) { return; } string text = null; Item currentItem = localCharacter.data.currentItem; if ((Object)(object)currentItem != (Object)null) { text = (GhostFeedPatches.CanGhostFeedItem(currentItem) ? GameL10n.Pick("Holding " + currentItem.GetName() + " · Aim teammate + secondary to apply (consumed on use)", "手持 " + currentItem.GetName() + " · 瞄准队友按副键使用(用完即消耗,无需放下)") : ((!GhostFeedPatches.IsBlockedGhostFeedItem(currentItem) || !currentItem.canUseOnFriend) ? GameL10n.Pick($"Ghost haul: {currentItem.GetName()} · Press {Configuration.GhostHaulKey.Value} to drop", $"幽灵搬运中:{currentItem.GetName()} · 按 {Configuration.GhostHaulKey.Value} 放下") : GameL10n.Pick($"Ghost haul: {currentItem.GetName()} · Scout amulets cannot be used on teammates as a ghost · Press {Configuration.GhostHaulKey.Value} to drop", $"幽灵搬运中:{currentItem.GetName()} · 童军护身符无法由幽灵对队友使用 · 按 {Configuration.GhostHaulKey.Value} 放下"))); } else { Item lookItem = GetLookItem(); if ((Object)(object)lookItem != (Object)null && IsHaulCandidate(lookItem) && IsWithinWeightLimit(lookItem)) { float num = (float)lookItem.CarryWeight * 2.5f; string text2 = (GhostFeedPatches.CanGhostFeedItem(lookItem) ? GameL10n.Pick(" (can use on teammate)", "(可对队友使用)") : ((GhostFeedPatches.IsBlockedGhostFeedItem(lookItem) && lookItem.canUseOnFriend) ? GameL10n.Pick(" (amulet: ghost cannot use on teammate)", "(护身符:幽灵不可对队友使用)") : string.Empty)); text = GameL10n.Pick($"Can haul: {lookItem.GetName()} ({num:0.#}){text2} · Press {Configuration.GhostHaulKey.Value}", $"可幽灵搬运:{lookItem.GetName()}({num:0.#}){text2}· 按 {Configuration.GhostHaulKey.Value} 提起"); } } if (!string.IsNullOrEmpty(text)) { DrawBottomHint(text); } } private static void DrawBottomHint(string text) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Expected O, but got Unknown //IL_0025: 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) GUIStyle val = new GUIStyle(GUI.skin.box) { alignment = (TextAnchor)4, fontSize = 14 }; val.normal.textColor = Color.white; float num = 620f; GUI.Box(new Rect(((float)Screen.width - num) * 0.5f, (float)Screen.height - 72f, num, 36f), text, val); } private void TryPickupLookedItem(Character local) { Item lookItem = GetLookItem(); if (!((Object)(object)lookItem == (Object)null) && IsHaulCandidate(lookItem)) { if (!IsWithinWeightLimit(lookItem)) { ShowTooHeavyToast(lookItem); return; } if (!local.player.tempFullSlot.IsEmpty() || (Object)(object)local.data.currentItem != (Object)null) { GhostItemHaulToast.Show("Ghosts can only hold one item", "幽灵同时只能持有一件物品"); return; } if (!local.player.HasEmptySlot(lookItem.itemID)) { GhostItemHaulToast.Show("Ghosts can only hold one item", "幽灵同时只能持有一件物品"); return; } Plugin.Log.LogInfo((object)$"Ghost haul pickup: {((Object)lookItem).name} (CarryWeight={lookItem.CarryWeight}, UI={(float)lookItem.CarryWeight * 2.5f:0.#}, feedable={lookItem.canUseOnFriend})"); lookItem.Interact(local); } } private static void DropHeldItem(Character local) { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_00c7: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)local?.refs?.items == (Object)null || (Object)(object)local.data.currentItem == (Object)null || (Object)(object)local.player == (Object)null) { return; } CharacterItems items = local.refs.items; if (!items.currentSelectedSlot.IsSome) { return; } byte value = items.currentSelectedSlot.Value; ItemSlot itemSlot = local.player.GetItemSlot(value); if (itemSlot == null || itemSlot.IsEmpty()) { try { items.EquipSlot(Optionable.None); return; } catch (Exception ex) { Plugin.Log.LogWarning((object)("Ghost haul drop failed: " + ex.Message)); return; } } try { Vector3 val = NameAnchor.GetGhostFeetPosition(local) + Vector3.up * 0.4f; Vector3 zero = Vector3.zero; Quaternion rotation = ((Component)local.data.currentItem).transform.rotation; items.photonView.RPC("DropItemRpc", (RpcTarget)0, new object[7] { 0f, value, val, zero, rotation, itemSlot.data, false }); items.EquipSlot(Optionable.None); } catch (Exception ex2) { Plugin.Log.LogWarning((object)("Ghost haul drop failed: " + ex2.Message)); } } private Item GetLookItem() { //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: 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_0110: Unknown result type (might be due to invalid IL or missing references) //IL_0115: 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_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_lookTarget != (Object)null && Time.unscaledTime < _lookTargetUntil && IsItemStillValid(_lookTarget)) { return _lookTarget; } MainCamera instance = MainCamera.instance; if ((Object)(object)instance == (Object)null) { return null; } Transform transform = ((Component)instance).transform; float value = Configuration.GhostHaulRange.Value; Ray val = new Ray(transform.position, transform.forward); Item val2 = null; float num = value; RaycastHit val3 = default(RaycastHit); if (Physics.Raycast(val, ref val3, value, -1, (QueryTriggerInteraction)1)) { Item val4 = (((Object)(object)((RaycastHit)(ref val3)).collider != (Object)null) ? ((Component)((RaycastHit)(ref val3)).collider).GetComponentInParent() : null); if ((Object)(object)val4 != (Object)null) { val2 = val4; num = ((RaycastHit)(ref val3)).distance; } } Collider[] array = Physics.OverlapSphere(transform.position + transform.forward * Mathf.Min(2f, value * 0.5f), 1.1f); for (int i = 0; i < array.Length; i++) { Item val5 = (((Object)(object)array[i] != (Object)null) ? ((Component)array[i]).GetComponentInParent() : null); if (!((Object)(object)val5 == (Object)null)) { Vector3 val6 = val5.Center() - transform.position; float magnitude = ((Vector3)(ref val6)).magnitude; if (!(magnitude > value) && !(magnitude >= num) && !(Vector3.Angle(transform.forward, val6) > 35f)) { val2 = val5; num = magnitude; } } } _lookTarget = val2; _lookTargetUntil = Time.unscaledTime + 0.15f; return val2; } private static bool IsHaulCandidate(Item item) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) if (!IsItemStillValid(item)) { return false; } if ((int)item.itemState != 0) { return false; } if (item.blockInteraction) { return false; } return true; } internal static bool IsWithinWeightLimit(Item item) { if ((Object)(object)item == (Object)null) { return false; } return (float)item.CarryWeight * 2.5f <= Configuration.MaxGhostHaulDisplayWeight.Value + 0.001f; } internal static void ShowTooHeavyToast(Item item) { if (!((Object)(object)item == (Object)null)) { float num = (float)item.CarryWeight * 2.5f; float value = Configuration.MaxGhostHaulDisplayWeight.Value; GhostItemHaulToast.Show($"Too heavy to haul ({num:0.#} > {value:0.#})", $"物品过重,无法搬运({num:0.#} > {value:0.#})"); } } private static bool IsItemStillValid(Item item) { if ((Object)(object)item != (Object)null && (Object)(object)((Component)item).gameObject != (Object)null) { return ((Component)item).gameObject.activeInHierarchy; } return false; } } internal static class GhostItemHaulToast { private static string _text; private static float _until; internal static void Show(string english, string chinese, float seconds = 2.2f) { _text = GameL10n.Pick(english, chinese); _until = Time.unscaledTime + seconds; } internal static void DrawIfAny() { //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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(_text) && !(Time.unscaledTime > _until)) { GUIStyle val = new GUIStyle(GUI.skin.box) { alignment = (TextAnchor)4, fontSize = 16, fontStyle = (FontStyle)1, wordWrap = true }; val.normal.textColor = new Color(1f, 0.85f, 0.45f); float num = Mathf.Min(640f, (float)Screen.width * 0.7f); GUI.Box(new Rect(((float)Screen.width - num) * 0.5f, (float)Screen.height * 0.22f, num, 48f), _text, val); } } } internal static class GhostPingPatches { [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPrefix] private static bool CanPingIgnoreDeath(PointPinger __instance, ref bool __result) { if (!Configuration.EnableGhostPing.Value) { return true; } __result = !Traverse.Create((object)__instance).Property("inCooldown", (object[])null).GetValue(); return false; } [HarmonyPatch(typeof(PointPinger), "TryGetPingHit")] [HarmonyPrefix] private static bool TryGetPingHitFromSpectatorCamera(ref bool __result, out RaycastHit hit) { //IL_0001: 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_0055: 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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) hit = default(RaycastHit); if (!Configuration.EnableGhostPing.Value) { return true; } Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter?.data == (Object)null || !localCharacter.data.fullyPassedOut) { return true; } Camera val = SpectatorUiCamera.Get(); if ((Object)(object)val == (Object)null) { return true; } Ray val2 = val.ScreenPointToRay(Input.mousePosition); int num = LayerMask.op_Implicit(HelperExtensions.ToLayerMask((LayerType)1)); __result = Physics.Raycast(val2, ref hit, 5000f, num); return false; } [HarmonyPatch(typeof(PointPinger), "ReceivePoint_Rpc")] [HarmonyTranspiler] private static IEnumerable ReceivePointSkipVisibilityCull(IEnumerable instructions) { //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Expected O, but got Unknown List list = new List(instructions); for (int i = 0; i < list.Count - 2; i++) { if (!(list[i].opcode != OpCodes.Ldc_R4) && list[i].operand is float num && num == 0f) { CodeInstruction val = list[i + 1]; if ((!(val.opcode != OpCodes.Bgt_Un_S) || !(val.opcode != OpCodes.Bgt_Un)) && !(list[i + 2].opcode != OpCodes.Ret)) { object operand = val.operand; list[i] = new CodeInstruction(OpCodes.Pop, (object)null); list[i + 1] = new CodeInstruction(OpCodes.Br_S, operand); list.RemoveAt(i + 2); Plugin.Log.LogInfo((object)"GhostPing: ReceivePoint_Rpc visibility cull removed (stack-safe)."); break; } } } return list; } [HarmonyPatch(typeof(PointPing), "Update")] [HarmonyPrefix] private static void PointPingUseSpectatorCamera(PointPing __instance) { Character localCharacter = Character.localCharacter; if (!((Object)(object)localCharacter?.data == (Object)null) && localCharacter.data.fullyPassedOut) { Camera val = SpectatorUiCamera.Get(); if (!((Object)(object)val == (Object)null)) { Traverse.Create((object)__instance).Field("camera").SetValue((object)val); } } } } internal sealed class HostBond : MonoBehaviour { private Character _host; private float _remaining; private GUIStyle _barBgStyle; private GUIStyle _labelStyle; private GUIStyle _hintStyle; private Texture2D _bgTex; private Texture2D _fillOkTex; private Texture2D _fillWarnTex; internal static HostBond Instance { get; private set; } internal Character Host { get { if (!IsValidHost(_host)) { return null; } return _host; } } internal float RemainingSeconds => _remaining; internal float Fill01 { get { float num = Mathf.Max(0.01f, Configuration.LeashCountdownSeconds.Value); return Mathf.Clamp01(_remaining / num); } } internal float CurrentDistance { get { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) Character host = Host; if ((Object)(object)host == (Object)null) { return 0f; } return Vector3.Distance(GetLocalGhostWorldPosition(), host.Center); } } internal static void Ensure() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)Instance != (Object)null)) { GameObject val = new GameObject("SymbioticGhost_HostBond"); Object.DontDestroyOnLoad((Object)val); Instance = val.AddComponent(); } } private void Awake() { Instance = this; RefillTimer(); } internal void RefillTimer() { _remaining = Mathf.Max(0.01f, Configuration.LeashCountdownSeconds.Value); } internal void LockHostFromCurrentSpec() { Character specCharacter = MainCameraMovement.specCharacter; if (IsValidHost(specCharacter)) { _host = specCharacter; } } internal void Tick() { Character localCharacter = Character.localCharacter; if (!((Object)(object)localCharacter != (Object)null) || !((Object)(object)localCharacter.data != (Object)null) || !localCharacter.data.fullyPassedOut) { _host = null; RefillTimer(); return; } if (FreeSpectatorController.Instance == null || !FreeSpectatorController.Instance.IsActive) { Character specCharacter = MainCameraMovement.specCharacter; if (IsValidHost(specCharacter)) { _host = specCharacter; } RefillTimer(); return; } if (!IsValidHost(_host)) { LockHostFromCurrentSpec(); if (!IsValidHost(_host)) { FreeSpectatorController.Instance?.ForceExitByLeash(); return; } } float value = Configuration.LeashDistance.Value; float currentDistance = CurrentDistance; float num = Mathf.Max(0.01f, Configuration.LeashCountdownSeconds.Value); if (currentDistance <= value) { _remaining = Mathf.Min(num, _remaining + Time.unscaledDeltaTime * 2f); return; } _remaining -= Time.unscaledDeltaTime; if (_remaining <= 0f) { _remaining = 0f; FreeSpectatorController.Instance?.ForceExitByLeash(); RefillTimer(); } } private void OnGUI() { Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null && localCharacter.data.fullyPassedOut) { EnsureStyles(); GhostItemHaulToast.DrawIfAny(); if (FreeSpectatorController.Instance == null || !FreeSpectatorController.Instance.IsActive) { DrawVanillaSpectateHint(); } else { DrawFreeFlyHud(); } } } private void DrawVanillaSpectateHint() { //IL_0005: 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) string text = ((object)Configuration.ToggleKey.Value/*cast due to .constrained prefix*/).ToString(); string text2 = GameL10n.Pick("Press " + text + " to enter free roam", "按下 " + text + " 进入自由行动"); DrawBottomHint(text2); } private void DrawFreeFlyHud() { //IL_00a1: 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_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) string arg = (((Object)(object)Host != (Object)null) ? Host.characterName : GameL10n.Pick("None", "无")); float currentDistance = CurrentDistance; float value = Configuration.LeashDistance.Value; bool flag = currentDistance <= value; string text = GameL10n.Pick($"Host: {arg} · {currentDistance:0.0}m", $"宿主:{arg} · {currentDistance:0.0}m"); float num = Mathf.Min(480f, (float)Screen.width * 0.5f); Rect val = new Rect(((float)Screen.width - num) * 0.5f, 12f, num, 26f); GUI.Box(val, GUIContent.none, _barBgStyle); GUI.Label(val, text, _labelStyle); float num2 = Mathf.Min(520f, (float)Screen.width * 0.55f); float num3 = 28f; float num4 = ((float)Screen.width - num2) * 0.5f; float num5 = 42f; Rect val2 = new Rect(num4, num5, num2, num3); GUI.Box(val2, GUIContent.none, _barBgStyle); float fill = Fill01; GUI.DrawTexture(new Rect(num4 + 2f, num5 + 2f, (num2 - 4f) * fill, num3 - 4f), (Texture)(object)(flag ? _fillOkTex : _fillWarnTex)); string text2 = ((!flag) ? GameL10n.Pick($"Out of range · return in {_remaining:0.0}s", $"脱离寄宿范围 · {_remaining:0.0}s 后强制返回观战") : GameL10n.Pick($"Link stable · {currentDistance:0.0}m / {value:0}m", $"灵魂链接稳定 · {currentDistance:0.0}m / {value:0}m")); GUI.Label(val2, text2, _labelStyle); string text3 = ((object)Configuration.ToggleKey.Value/*cast due to .constrained prefix*/).ToString(); string text4 = GameL10n.Pick("Free roam: WASD move · Space up · Ctrl down · Shift ×3 · " + text3 + " exit", "自由行动:WASD 移动 · 空格上升 · Ctrl 下降 · Shift ×3 加速 · " + text3 + " 退出"); DrawBottomHint(text4); } private void DrawBottomHint(string text) { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) float num = Mathf.Min(720f, (float)Screen.width * 0.75f); float num2 = 34f; Rect val = new Rect(((float)Screen.width - num) * 0.5f, (float)Screen.height - 110f, num, num2); GUI.Box(val, GUIContent.none, _barBgStyle); GUI.Label(val, text, _hintStyle); } private void EnsureStyles() { //IL_001e: 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_0066: 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_008a: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Expected O, but got Unknown //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: 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_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Expected O, but got Unknown //IL_012a: Unknown result type (might be due to invalid IL or missing references) if (_labelStyle == null) { _bgTex = MakeTex(new Color(0f, 0f, 0f, 0.55f)); _fillOkTex = MakeTex(new Color(0.25f, 0.85f, 0.75f, 0.9f)); _fillWarnTex = MakeTex(new Color(0.95f, 0.45f, 0.25f, 0.95f)); _barBgStyle = new GUIStyle(GUI.skin.box); _barBgStyle.normal.background = _bgTex; _labelStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 14, fontStyle = (FontStyle)1 }; _labelStyle.normal.textColor = Color.white; _hintStyle = new GUIStyle(GUI.skin.label) { alignment = (TextAnchor)4, fontSize = 13, fontStyle = (FontStyle)1 }; _hintStyle.normal.textColor = new Color(0.95f, 0.95f, 0.95f, 1f); } } private static Texture2D MakeTex(Color color) { //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_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown Texture2D val = new Texture2D(1, 1, (TextureFormat)5, false); val.SetPixel(0, 0, color); val.Apply(); return val; } internal static Vector3 GetLocalGhostWorldPosition() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_0079: 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) if (FreeSpectatorController.Instance != null && FreeSpectatorController.Instance.IsActive) { MainCamera instance = MainCamera.instance; if ((Object)(object)instance != (Object)null) { return ((Component)instance).transform.position; } } PlayerGhost val = (((Object)(object)Character.localCharacter != (Object)null) ? Character.localCharacter.Ghost : null); if ((Object)(object)val != (Object)null) { return ((Component)val).transform.position; } MainCamera instance2 = MainCamera.instance; if (!((Object)(object)instance2 != (Object)null)) { return Vector3.zero; } return ((Component)instance2).transform.position; } private static bool IsValidHost(Character character) { if ((Object)(object)character == (Object)null || (Object)(object)((Component)character).gameObject == (Object)null || !((Component)character).gameObject.activeInHierarchy) { return false; } try { return (Object)(object)character.data != (Object)null && character.data.canBeSpectated; } catch { return false; } } } internal sealed class IntervalTimer { private float _lastTime; private readonly float _interval; private readonly Action _onReady; internal IntervalTimer(float interval, Action onReady) { _interval = interval; _onReady = onReady; } internal void Update() { if (Time.time - _lastTime >= _interval) { _lastTime = Time.time; _onReady?.Invoke(); } } } internal sealed class ModPresence : MonoBehaviourPunCallbacks { internal const string PropertyKey = "SG"; private static ModPresence _instance; private static float _nextRecheck; private static bool _cachedAllPresent; internal static bool AllPlayersHaveMod { get { if (!PhotonNetwork.InRoom) { return false; } if (Time.unscaledTime >= _nextRecheck) { _nextRecheck = Time.unscaledTime + 1f; _cachedAllPresent = Evaluate(); } return _cachedAllPresent; } } internal static void Ensure() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("SymbioticGhost_ModPresence"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } } private void Start() { Publish(); } public override void OnJoinedRoom() { Publish(); Invalidate(); } public override void OnPlayerEnteredRoom(Player newPlayer) { Invalidate(); } public override void OnPlayerLeftRoom(Player otherPlayer) { Invalidate(); } public override void OnPlayerPropertiesUpdate(Player targetPlayer, Hashtable changedProps) { if (changedProps != null && ((Dictionary)(object)changedProps).ContainsKey((object)"SG")) { Invalidate(); } } private static void Invalidate() { _nextRecheck = 0f; } private static void Publish() { //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_0025: Expected O, but got Unknown //IL_0026: Expected O, but got Unknown if (PhotonNetwork.IsConnectedAndReady && PhotonNetwork.LocalPlayer != null) { Hashtable val = new Hashtable(); ((Dictionary)val).Add((object)"SG", (object)1); Hashtable val2 = val; PhotonNetwork.LocalPlayer.SetCustomProperties(val2, (Hashtable)null, (WebFlags)null); } } private static bool Evaluate() { Player[] playerList = PhotonNetwork.PlayerList; if (playerList == null || playerList.Length == 0) { return false; } foreach (Player val in playerList) { if (val != null && !val.IsInactive && (val.CustomProperties == null || !((Dictionary)(object)val.CustomProperties).TryGetValue((object)"SG", out object value) || !(value is int num) || num != 1)) { return false; } } return true; } } internal static class NameAnchor { private const float GhostNameHeight = 0.75f; private const float FreeFlyFeetBelowCamera = 1.35f; internal static Color GetLabelColor(Character character) { //IL_000f: 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) if (IsGhostLike(character)) { return Color.white; } return PingDistanceManager.GetReadablePlayerColor(character); } internal static bool IsGhostLike(Character character) { if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null) { return false; } try { if ((Object)(object)character.Ghost != (Object)null && (Object)(object)((Component)character.Ghost).gameObject != (Object)null && ((Component)character.Ghost).gameObject.activeInHierarchy) { return true; } return character.data.dead || character.data.fullyPassedOut; } catch { return false; } } internal static Vector3 GetWorldPosition(Character character, Transform fallbackNamePos) { //IL_000a: 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_002c: 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) if (TryGetGhostAnchor(character, out var position)) { return position; } if ((Object)(object)fallbackNamePos != (Object)null) { return fallbackNamePos.position; } if (!((Object)(object)character != (Object)null)) { return Vector3.zero; } return character.Center; } internal static bool TryGetGhostAnchor(Character character, out Vector3 position) { //IL_0001: 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_0018: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) position = default(Vector3); if (!IsGhostLike(character)) { return false; } position = GetGhostWorldPosition(character) + Vector3.up * 0.75f; return true; } internal static Vector3 GetGhostWorldPosition(Character character) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_008f: 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_0058: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null) { return Vector3.zero; } if (character.IsLocal) { return HostBond.GetLocalGhostWorldPosition(); } PlayerGhost ghost = character.Ghost; if ((Object)(object)ghost != (Object)null && (Object)(object)ghost.m_view != (Object)null && GhostFreeSync.TryGetRemoteLink(ghost.m_view.ViewID, out var link) && link.Active) { return link.GhostPosition; } if ((Object)(object)ghost != (Object)null && (Object)(object)((Component)ghost).gameObject != (Object)null && ((Component)ghost).gameObject.activeInHierarchy) { return ((Component)ghost).transform.position; } return character.Center; } internal static Vector3 GetGhostFeetPosition(Character character) { //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: 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_011c: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0046: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0096: 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_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character == (Object)null) { return Vector3.zero; } if (character.IsLocal && FreeSpectatorController.Instance != null && FreeSpectatorController.Instance.IsActive && (Object)(object)MainCamera.instance != (Object)null) { return ((Component)MainCamera.instance).transform.position + Vector3.down * 1.35f; } PlayerGhost ghost = character.Ghost; if ((Object)(object)ghost != (Object)null && (Object)(object)ghost.m_view != (Object)null && GhostFreeSync.TryGetRemoteLink(ghost.m_view.ViewID, out var link) && link.Active) { return link.GhostPosition + Vector3.down * 0.35f; } if ((Object)(object)ghost != (Object)null && (Object)(object)((Component)ghost).gameObject != (Object)null && ((Component)ghost).gameObject.activeInHierarchy) { return ((Component)ghost).transform.position + Vector3.down * 0.35f; } try { return character.HipPos(); } catch { return character.Center + Vector3.down * 0.9f; } } internal static Vector3 GetLivingFeetPosition(Character character) { //IL_001b: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_0037: 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) if ((Object)(object)character == (Object)null) { return Vector3.zero; } try { return character.HipPos(); } catch { return character.Center + Vector3.down * 0.9f; } } internal static Vector3 GetGhostLookForward(Character character) { //IL_00aa: 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_00b2: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: 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_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_007f: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character != (Object)null && character.IsLocal && (Object)(object)MainCamera.instance != (Object)null) { return ((Component)MainCamera.instance).transform.forward; } PlayerGhost val = (((Object)(object)character != (Object)null) ? character.Ghost : null); if ((Object)(object)val != (Object)null && (Object)(object)val.m_view != (Object)null && GhostFreeSync.TryGetRemoteLink(val.m_view.ViewID, out var link) && link.Active) { return link.GhostRotation * Vector3.forward; } if ((Object)(object)val != (Object)null) { return ((Component)val).transform.forward; } try { return character.data.lookDirection; } catch { return Vector3.forward; } } internal static Vector3 GetViewerPosition() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)MainCamera.instance != (Object)null) { return ((Component)MainCamera.instance).transform.position; } if ((Object)(object)Character.localCharacter != (Object)null) { try { return Character.localCharacter.Center; } catch { } } return Vector3.zero; } } internal static class PeakCinemaCompat { private const string Guid = "com.github.megalon.peakcinema"; private static float _lastFindTime; private static Component _cinema; private static PropertyInfo _onProp; internal static bool ShouldHideNames() { if (!Chainloader.PluginInfos.ContainsKey("com.github.megalon.peakcinema")) { return false; } try { if ((Object)(object)_cinema == (Object)null && Time.time - _lastFindTime > 1f) { _lastFindTime = Time.time; Type type = FindType("CinemaCamera"); if (type == null) { return false; } Object obj = Object.FindAnyObjectByType(type); _cinema = (Component)(object)((obj is Component) ? obj : null); _onProp = type.GetProperty("on", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); } if ((Object)(object)_cinema == (Object)null || _onProp == null) { return false; } object value = _onProp.GetValue(_cinema); bool flag = default(bool); int num; if (value is bool) { flag = (bool)value; num = 1; } else { num = 0; } return (byte)((uint)num & (flag ? 1u : 0u)) != 0; } catch { return false; } } private static Type FindType(string typeName) { Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { try { Type type = assembly.GetType(typeName); if (type != null) { return type; } } catch { } } return null; } } internal sealed class PingDistance : MonoBehaviour { internal Vector3 position; internal Color color = Color.white; internal string nameShort = ""; private TextMeshProUGUI _tmp; private void Awake() { EnsureTmp(); } private void OnEnable() { EnsureTmp(); } private void EnsureTmp() { if ((Object)(object)_tmp == (Object)null) { _tmp = ((Component)this).GetComponentInChildren(true); } if (!((Object)(object)_tmp == (Object)null)) { ((TMP_Text)_tmp).overflowMode = (TextOverflowModes)0; ((TMP_Text)_tmp).textWrappingMode = (TextWrappingModes)0; } } private void LateUpdate() { //IL_0025: 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_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_0092: 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_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) EnsureTmp(); Camera val = SpectatorUiCamera.Get(); if (!((Object)(object)val == (Object)null) && !((Object)(object)_tmp == (Object)null)) { Vector3 val2 = position - ((Component)val).transform.position; float num = Mathf.Round(((Vector3)(ref val2)).magnitude); if (num < 1f) { num = 1f; } float num2 = Mathf.Clamp(2f / (num / 10f), 0.85f, 1.5f); float num3 = Vector3.Angle(((Component)val).transform.forward, val2); Vector3 val3 = val.WorldToScreenPoint(position); bool active = val3.z > 0.1f && num3 < 90f; ((Component)this).transform.position = val3; ((Component)this).transform.localScale = new Vector3(num2, num2, num2); ((Graphic)_tmp).color = MakeOpaque(color); ((TMP_Text)_tmp).text = ((Configuration.ShowPingNameShort.Value && !string.IsNullOrEmpty(nameShort)) ? $"{nameShort} {num}m" : $"{num}m"); ((Component)_tmp).gameObject.SetActive(active); } } private static Color MakeOpaque(Color c) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Unknown result type (might be due to invalid IL or missing references) c.a = 1f; if (float.IsNaN(c.r) || float.IsNaN(c.g) || float.IsNaN(c.b)) { return Color.white; } return c; } } internal sealed class PingDistanceManager { private TMP_FontAsset _font; private Material _fontMaterial; private Canvas _pingDistanceCanvas; private GameObject _template; private readonly Dictionary _instances = new Dictionary(); internal bool IsInitialized { get { if ((Object)(object)Plugin.Instance != (Object)null && (Object)(object)_pingDistanceCanvas != (Object)null) { return (Object)(object)_template != (Object)null; } return false; } } internal void Initialize() { if (IsInitialized) { return; } try { CreateCanvas(); CreateTemplate(); } catch (Exception ex) { Plugin.Log.LogError((object)("PingDistanceManager.Initialize failed: " + ex)); } } internal void Cleanup() { if ((Object)(object)_pingDistanceCanvas != (Object)null) { Object.Destroy((Object)(object)((Component)_pingDistanceCanvas).gameObject); _pingDistanceCanvas = null; } _template = null; _instances.Clear(); } private void FindFont() { TextMeshProUGUI[] array = Resources.FindObjectsOfTypeAll(); TextMeshProUGUI[] array2 = array; foreach (TextMeshProUGUI val in array2) { if (!((Object)(object)val == (Object)null)) { Material materialForRendering = ((Graphic)val).materialForRendering; if (((Object)val).name == "Text" && (Object)(object)materialForRendering != (Object)null && ((Object)materialForRendering).name.Contains("DarumaDropOne-Regular SDF")) { _font = ((TMP_Text)val).font; _fontMaterial = materialForRendering; return; } } } array2 = array; foreach (TextMeshProUGUI val2 in array2) { if (!((Object)(object)((val2 != null) ? ((TMP_Text)val2).font : null) == (Object)null) && (((Object)((TMP_Text)val2).font).name.Contains("Daruma") || ((Object)(object)((Graphic)val2).materialForRendering != (Object)null && ((Object)((Graphic)val2).materialForRendering).name.Contains("Daruma")))) { _font = ((TMP_Text)val2).font; _fontMaterial = ((Graphic)val2).materialForRendering; break; } } } private void CreateCanvas() { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Expected O, but got Unknown //IL_00b6: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_pingDistanceCanvas != (Object)null)) { _instances.Clear(); GameObject val = GameObject.Find("GAME/GUIManager"); if (!((Object)(object)val == (Object)null)) { GameObject val2 = new GameObject("Canvas_SymbioticGhostPingDistance", new Type[3] { typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster) }); val2.transform.SetParent(val.transform, false); _pingDistanceCanvas = val2.GetComponent(); _pingDistanceCanvas.renderMode = (RenderMode)0; _pingDistanceCanvas.sortingOrder = 100; CanvasScaler component = val2.GetComponent(); component.uiScaleMode = (ScaleMode)1; component.referenceResolution = new Vector2(1920f, 1080f); component.screenMatchMode = (ScreenMatchMode)1; val2.layer = LayerMask.NameToLayer("UI"); } } } private void CreateTemplate() { //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_template != (Object)null) && !((Object)(object)_pingDistanceCanvas == (Object)null)) { _template = new GameObject("PingDistanceIndicator", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(PingDistance) }); _template.transform.SetParent(((Component)_pingDistanceCanvas).transform, false); AddTmpChild("DistanceText", _template.transform, new Vector2(320f, 50f)); _template.SetActive(false); } } private void AddTmpChild(string name, Transform parent, Vector2 size) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_009c: 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_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_0178: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_font == (Object)null) { FindFont(); } GameObject val = new GameObject(name, new Type[4] { typeof(RectTransform), typeof(CanvasRenderer), typeof(TextMeshProUGUI), typeof(Shadow) }); val.transform.SetParent(parent, false); RectTransform component = val.GetComponent(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = size; TextMeshProUGUI component2 = val.GetComponent(); if ((Object)(object)_font != (Object)null) { ((TMP_Text)component2).font = _font; } if ((Object)(object)_fontMaterial != (Object)null) { ((TMP_Text)component2).fontMaterial = _fontMaterial; } ((TMP_Text)component2).fontSize = 30f; ((Graphic)component2).color = Color.white; ((TMP_Text)component2).outlineWidth = 0.1f; ((TMP_Text)component2).outlineColor = Color32.op_Implicit(Color.black); ((TMP_Text)component2).enableAutoSizing = false; ((TMP_Text)component2).overflowMode = (TextOverflowModes)0; ((TMP_Text)component2).textWrappingMode = (TextWrappingModes)0; ((TMP_Text)component2).alignment = (TextAlignmentOptions)514; ((TMP_Text)component2).horizontalAlignment = (HorizontalAlignmentOptions)2; ((TMP_Text)component2).verticalAlignment = (VerticalAlignmentOptions)512; Shadow component3 = val.GetComponent(); component3.effectColor = new Color(0f, 0f, 0f, 0.95f); component3.effectDistance = new Vector2(2f, -2f); } internal void CreateInstance(PointPinger pinger, Vector3 position) { //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) try { if ((Object)(object)_pingDistanceCanvas == (Object)null || (Object)(object)_template == (Object)null) { Initialize(); if ((Object)(object)_pingDistanceCanvas == (Object)null || (Object)(object)_template == (Object)null) { return; } } int num = 0; try { if ((Object)(object)pinger != (Object)null && (Object)(object)pinger.photonView != (Object)null) { num = pinger.photonView.ViewID; } } catch { num = 0; } if (num != 0 && _instances.TryGetValue(num, out var value) && (Object)(object)value != (Object)null) { Object.Destroy((Object)(object)value); _instances.Remove(num); } GameObject val = Object.Instantiate(_template, ((Component)_pingDistanceCanvas).transform); ((Object)val).name = ((num != 0) ? $"PingDistance_{num}" : "PingDistance"); PingDistance component = val.GetComponent(); component.position = position; component.color = ResolveVisiblePingColor(pinger); component.nameShort = ResolvePlayerNameShort(pinger); val.SetActive(true); if (num != 0) { _instances[num] = val; } Object.Destroy((Object)(object)val, Mathf.Max(0.1f, Configuration.PingTextDuration.Value)); } catch (Exception ex) { Plugin.Log.LogError((object)("PingDistance CreateInstance failed: " + ex)); } } private static string ResolvePlayerNameShort(PointPinger pinger) { if (!Configuration.ShowPingNameShort.Value) { return ""; } string text = null; try { if ((Object)(object)pinger?.character != (Object)null && !string.IsNullOrWhiteSpace(pinger.character.characterName)) { text = pinger.character.characterName; } } catch { text = null; } if (string.IsNullOrWhiteSpace(text)) { try { Player val = null; if ((Object)(object)pinger?.photonView != (Object)null) { val = pinger.photonView.Owner; } if (val == null && (Object)(object)pinger?.character != (Object)null && (Object)(object)pinger.character.view != (Object)null) { val = pinger.character.view.Owner; } if (val != null && !string.IsNullOrWhiteSpace(val.NickName)) { text = val.NickName; } } catch { } } return FormatNameShort(text); } internal static string FormatNameShort(string fullName) { if (string.IsNullOrWhiteSpace(fullName)) { return ""; } string text = fullName.Trim(); if (text.Length == 0) { return ""; } string text2 = text; foreach (char c in text2) { if (IsCjk(c)) { return char.ToString(c); } } text2 = text; foreach (char c2 in text2) { if ((c2 >= 'A' && c2 <= 'Z') || (c2 >= 'a' && c2 <= 'z')) { return char.ToString(c2); } } return char.ToString(text[0]); } private static bool IsCjk(char c) { if ((c < '一' || c > '鿿') && (c < '㐀' || c > '䶿')) { if (c >= '豈') { return c <= '\ufaff'; } return false; } return true; } private static Color ResolveVisiblePingColor(PointPinger pinger) { //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: 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_00ae: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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) Character val = null; try { val = (((Object)(object)pinger != (Object)null) ? pinger.character : null); } catch { val = null; } if (TryGetPlayerSkinColor(val, out var color)) { return MakeReadable(color); } try { GameObject val2 = (((Object)(object)pinger != (Object)null) ? pinger.pingInstance : null); if ((Object)(object)val2 != (Object)null) { Material val3 = null; PointPing component = val2.GetComponent(); if ((Object)(object)component != (Object)null) { val3 = component.material; } if ((Object)(object)val3 == (Object)null) { MeshRenderer componentInChildren = val2.GetComponentInChildren(); if ((Object)(object)componentInChildren != (Object)null) { val3 = ((Renderer)componentInChildren).sharedMaterial ?? ((Renderer)componentInChildren).material; } } if ((Object)(object)val3 != (Object)null) { Color c = SampleMaterialColor(val3); if (HasValidRgb(c) && !IsNearWhite(c)) { return MakeReadable(c); } } } } catch { } return GetReadablePlayerColor(val); } internal static Color GetReadablePlayerColor(Character character) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0056: 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_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) try { if (TryGetPlayerSkinColor(character, out var color)) { return MakeReadable(color); } } catch { } try { SkinnedMeshRenderer val = character?.refs?.mainRenderer; if ((Object)(object)val != (Object)null) { Material val2 = ((Renderer)val).sharedMaterial ?? ((Renderer)val).material; if ((Object)(object)val2 != (Object)null) { Color c = SampleMaterialColor(val2); if (HasValidRgb(c) && !IsNearWhite(c)) { return MakeReadable(c); } } } } catch { } return Color.white; } private static bool TryGetPlayerSkinColor(Character character, out Color color) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_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_0046: 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) //IL_011d: Unknown result type (might be due to invalid IL or missing references) color = Color.white; if ((Object)(object)character?.refs?.customization == (Object)null) { return false; } CharacterCustomization customization = character.refs.customization; try { color = customization.PlayerColor; if (HasValidRgb(color)) { return true; } } catch { } try { CustomizationOption[] array = (((Object)(object)Singleton.Instance != (Object)null) ? Singleton.Instance.skins : null); if (array == null || array.Length == 0) { return false; } Player val = null; try { if ((Object)(object)customization.view != (Object)null) { val = customization.view.Owner; } } catch { } if (val == null) { try { if ((Object)(object)character.view != (Object)null) { val = character.view.Owner; } } catch { } } if (val == null) { return false; } CharacterCustomizationData customizationData = CharacterCustomization.GetCustomizationData(val); if (customizationData == null) { return false; } int currentSkin = customizationData.currentSkin; if (currentSkin < 0 || currentSkin >= array.Length) { return false; } CustomizationOption val2 = array[currentSkin]; if ((Object)(object)val2 == (Object)null) { return false; } color = val2.color; return HasValidRgb(color); } catch { return false; } } private static Color SampleMaterialColor(Material mat) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (mat.HasProperty("_Color")) { return mat.GetColor("_Color"); } if (mat.HasProperty("_BaseColor")) { return mat.GetColor("_BaseColor"); } return mat.color; } private static bool HasValidRgb(Color c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (!float.IsNaN(c.r) && !float.IsNaN(c.g)) { return !float.IsNaN(c.b); } return false; } private static bool IsNearWhite(Color c) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) if (c.r > 0.92f && c.g > 0.92f) { return c.b > 0.92f; } return false; } private static Color MakeReadable(Color c) { //IL_000c: 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_0025: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0071: 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) c.a = 1f; float num = c.r * 0.299f + c.g * 0.587f + c.b * 0.114f; if (float.IsNaN(num)) { return Color.white; } if (num < 0.12f) { float num2 = 0.12f / Mathf.Max(num, 0.001f); c.r = Mathf.Clamp01(c.r * num2); c.g = Mathf.Clamp01(c.g * num2); c.b = Mathf.Clamp01(c.b * num2); } return c; } } [HarmonyPatch(typeof(PointPinger))] internal static class PointPingerDistancePatches { [HarmonyPatch("Awake")] [HarmonyPostfix] private static void AwakePostfix() { if (Plugin.PingDistances != null && !Plugin.PingDistances.IsInitialized) { Plugin.PingDistances.Initialize(); } } [HarmonyPatch("ReceivePoint_Rpc")] [HarmonyPostfix] private static void ReceivePointRpcPostfix(PointPinger __instance, Vector3 point, Vector3 hitNormal) { //IL_0030: 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_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Unknown result type (might be due to invalid IL or missing references) try { if (Plugin.PingDistances != null) { if (!Plugin.PingDistances.IsInitialized) { Plugin.PingDistances.Initialize(); } if (!((Object)(object)__instance == (Object)null)) { Vector3 val = hitNormal; val = ((!(((Vector3)(ref val)).sqrMagnitude > 1E-08f)) ? Vector3.up : ((Vector3)(ref val)).normalized); Vector3 position = (((Object)(object)__instance.pingInstance != (Object)null) ? (__instance.pingInstance.transform.position + val * 0.15f) : (point + val * 0.15f)); Plugin.PingDistances.CreateInstance(__instance, position); } } } catch (Exception ex) { Plugin.Log.LogError((object)("Ping distance Postfix failed: " + ex)); } } } [HarmonyPatch(typeof(GUIManager))] internal static class GuiManagerPingPatches { [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPostfix() { Plugin.PingDistances?.Initialize(); } [HarmonyPatch("LateUpdate")] [HarmonyPostfix] private static void LateUpdatePostfix() { if (Plugin.PingDistances != null && !Plugin.PingDistances.IsInitialized) { Plugin.PingDistances.Initialize(); } } [HarmonyPatch("OnDestroy")] [HarmonyPostfix] private static void OnDestroyPostfix() { Plugin.PingDistances?.Cleanup(); } } [HarmonyPatch(typeof(IsLookedAt))] [HarmonyWrapSafe] internal static class PlayerNamePatches { [HarmonyPatch("Update")] [HarmonyPrefix] private static bool UpdatePrefix(IsLookedAt __instance) { //IL_0144: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d0: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_007c: 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) //IL_0087: Unknown result type (might be due to invalid IL or missing references) if (!Configuration.EnableNames.Value) { return true; } if ((Object)(object)GUIManager.instance?.playerNames == (Object)null || (Object)(object)MainCamera.instance == (Object)null) { return false; } FieldInfo fieldInfo = AccessTools.Field(typeof(IsLookedAt), "index"); if (fieldInfo == null) { return true; } int num = (int)fieldInfo.GetValue(__instance); Character val = ResolveCharacter(__instance); if ((Object)(object)val == (Object)null) { return false; } Vector3 worldPosition = NameAnchor.GetWorldPosition(val, __instance.playerNamePos); Vector3 viewerPosition = NameAnchor.GetViewerPosition(); int num2 = 0; try { if ((Object)(object)__instance.mouth != (Object)null) { num2 = __instance.mouth.amplitudeIndex; } } catch { num2 = 0; } if (!Plugin.NamesDisplayActive) { GUIManager.instance.playerNames.UpdateName(num, worldPosition, false, num2); return false; } bool flag = false; Vector3 val2 = worldPosition - viewerPosition; if (((Vector3)(ref val2)).sqrMagnitude > 0.0001f && Vector3.Angle(((Component)MainCamera.instance).transform.forward, val2) < Configuration.NameVisibleAngle.Value) { flag = true; } try { if ((Object)(object)val.data != (Object)null && val.data.isBlind) { flag = Configuration.DisplayWhenBlind.Value; } } catch { } GUIManager.instance.playerNames.UpdateName(num, worldPosition, flag, num2); ApplyNameColor(num, val); RefreshDistance(num); return false; } private static Character ResolveCharacter(IsLookedAt instance) { try { if ((Object)(object)instance.mouth != (Object)null && (Object)(object)instance.mouth.character != (Object)null) { return instance.mouth.character; } } catch { } try { return ((Object)(object)instance.characterInteractible != (Object)null) ? instance.characterInteractible.character : null; } catch { return null; } } private static void ApplyNameColor(int index, Character character) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) PlayerName playerNameByIndex = GetPlayerNameByIndex(index); if (!((Object)(object)playerNameByIndex?.text == (Object)null)) { ((Graphic)playerNameByIndex.text).color = NameAnchor.GetLabelColor(character); ((Behaviour)playerNameByIndex.text).enabled = true; } } private static void RefreshDistance(int index) { PlayerName playerNameByIndex = GetPlayerNameByIndex(index); if (!((Object)(object)playerNameByIndex == (Object)null)) { ShowPlayerDistance componentInChildren = ((Component)playerNameByIndex).GetComponentInChildren(true); if ((Object)(object)componentInChildren == (Object)null) { CreateDistanceDisplay(playerNameByIndex); componentInChildren = ((Component)playerNameByIndex).GetComponentInChildren(true); } componentInChildren?.RefreshNow(); } } [HarmonyPatch("Start")] [HarmonyPostfix] private static void StartPostfix(IsLookedAt __instance) { if ((Object)(object)__instance == (Object)null || (Object)(object)GUIManager.instance?.playerNames == (Object)null || (Object)(object)ResolveCharacter(__instance) == (Object)(object)Character.localCharacter) { return; } FieldInfo fieldInfo = AccessTools.Field(typeof(IsLookedAt), "index"); if (fieldInfo == null) { return; } PlayerName playerNameByIndex = GetPlayerNameByIndex((int)fieldInfo.GetValue(__instance)); if (!((Object)(object)playerNameByIndex == (Object)null)) { SoftDependencyGuards.StripForeignDistanceDisplays(playerNameByIndex); if (!((Object)(object)((Component)playerNameByIndex).GetComponentInChildren(true) != (Object)null)) { ((MonoBehaviour)Plugin.Instance).StartCoroutine(DelayedCreateDistanceDisplay(playerNameByIndex)); } } } private static PlayerName GetPlayerNameByIndex(int index) { if (GUIManager.instance?.playerNames?.playerNameText != null && index >= 0 && index < GUIManager.instance.playerNames.playerNameText.Length) { return GUIManager.instance.playerNames.playerNameText[index]; } return null; } private static IEnumerator DelayedCreateDistanceDisplay(PlayerName originalPlayerName) { yield return (object)new WaitForSeconds(0.1f); SoftDependencyGuards.StripForeignDistanceDisplays(originalPlayerName); CreateDistanceDisplay(originalPlayerName); } internal static void CreateDistanceDisplay(PlayerName originalPlayerName) { //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_00a0: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)originalPlayerName == (Object)null) && !((Object)(object)originalPlayerName.text == (Object)null) && !((Object)(object)((Component)originalPlayerName).GetComponentInChildren(true) != (Object)null)) { SoftDependencyGuards.StripForeignDistanceDisplays(originalPlayerName); GameObject val = new GameObject("SymbioticGhost_DistanceDisplay"); RectTransform val2 = val.AddComponent(); val.AddComponent().ignoreLayout = true; ((Transform)val2).SetParent(((Component)originalPlayerName).transform, false); TextMeshProUGUI val3 = val.AddComponent(); float fontSize = ((TMP_Text)originalPlayerName.text).fontSize; ((TMP_Text)val3).text = "0.0m"; ((TMP_Text)val3).alignment = (TextAlignmentOptions)514; ((TMP_Text)val3).font = ((TMP_Text)originalPlayerName.text).font; ((TMP_Text)val3).fontSize = fontSize * 1.35f; ((Graphic)val3).color = Color.white; ((Graphic)val3).raycastTarget = false; if ((Object)(object)((TMP_Text)originalPlayerName.text).fontSharedMaterial != (Object)null) { ((TMP_Text)val3).fontSharedMaterial = ((TMP_Text)originalPlayerName.text).fontSharedMaterial; } val.AddComponent().Initialize(val3, originalPlayerName); } } } [BepInPlugin("com.youxia173.SymbioticGhost", "SymbioticGhost", "1.5.7")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public sealed class Plugin : BaseUnityPlugin { internal const string PluginGuid = "com.youxia173.SymbioticGhost"; internal const string PluginName = "SymbioticGhost"; internal const string PluginVersion = "1.5.7"; internal static ManualLogSource Log; private Harmony _harmony; private FreeSpectatorController _controller; private float _namesAutoHideAt = -1f; internal static Plugin Instance { get; private set; } internal static PingDistanceManager PingDistances { get; private set; } internal static DownedMarkerManager DownedMarkers { get; private set; } internal static bool NamesDisplayActive { get; private set; } = true; private void Awake() { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown Instance = this; Log = ((BaseUnityPlugin)this).Logger; Configuration.Initialize(((BaseUnityPlugin)this).Config); NamesDisplayActive = Configuration.NameDisplayDuration.Value <= 0f; HostBond.Ensure(); GhostFreeSync.Ensure(); SoulLinkVisual.Ensure(); ModPresence.Ensure(); GhostItemHaul.Ensure(); _controller = new FreeSpectatorController(); _harmony = new Harmony("com.youxia173.SymbioticGhost"); _harmony.PatchAll(typeof(FreeCamPatches)); _harmony.PatchAll(typeof(PlayerGhostFreeFlyPatch)); _harmony.PatchAll(typeof(GhostBackpackPatches)); _harmony.PatchAll(typeof(GhostFeedPatches)); if (SoftDependencyGuards.SkipBuiltInNames) { SoftDependencyGuards.SuppressAlwaysDisplayPlayerName(_harmony); Log.LogWarning((object)"??? AlwaysDisplayPlayerName????????????/?????????????????????????"); } _harmony.PatchAll(typeof(PlayerNamePatches)); Log.LogInfo((object)"?????????????"); if (SoftDependencyGuards.SkipBuiltInGhostPing) { Log.LogWarning((object)"??? GhostPing???????????????????????"); } else { _harmony.PatchAll(typeof(GhostPingPatches)); Log.LogInfo((object)"??????????"); } if (SoftDependencyGuards.SkipBuiltInPingDistance) { Log.LogWarning((object)"??? BetterPingDistance???????????????????????"); } else { PingDistances = new PingDistanceManager(); _harmony.PatchAll(typeof(PointPingerDistancePatches)); _harmony.PatchAll(typeof(GuiManagerPingPatches)); Log.LogInfo((object)"????????????"); } if (SoftDependencyGuards.SkipBuiltInDownedMarkers) { Log.LogWarning((object)"??? DownedAwareness????????????????????????????????????????"); } else { DownedMarkers = new DownedMarkerManager(); _harmony.PatchAll(typeof(DownedMarkerGuiPatches)); _harmony.PatchAll(typeof(DownedMarkerCharacterPatches)); Log.LogInfo((object)"???????/???????????????"); } Log.LogInfo((object)"SymbioticGhost v1.5.7 ??????????"); } private void Update() { _controller?.Update(); UpdateNameDisplayToggle(); } private void UpdateNameDisplayToggle() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (Configuration.EnableNames.Value) { KeyboardShortcut value = Configuration.NameDisplayToggle.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { HandleNameToggleKey(); } if (_namesAutoHideAt > 0f && Time.unscaledTime >= _namesAutoHideAt) { NamesDisplayActive = false; _namesAutoHideAt = -1f; } } } private void HandleNameToggleKey() { float value = Configuration.NameDisplayDuration.Value; if (value <= 0f) { NamesDisplayActive = !NamesDisplayActive; _namesAutoHideAt = -1f; } else if (NamesDisplayActive) { NamesDisplayActive = false; _namesAutoHideAt = -1f; } else { NamesDisplayActive = true; _namesAutoHideAt = Time.unscaledTime + value; } } private void OnDestroy() { _controller?.SetActive(active: false); PingDistances?.Cleanup(); DownedMarkers?.Cleanup(); Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } } internal sealed class ShowPlayerDistance : MonoBehaviour { private const float UpdateInterval = 0.1f; private const float PixelOffsetAboveName = 28f; private TextMeshProUGUI _distanceText; private PlayerName _playerName; private CanvasGroup _canvasGroup; private RectTransform _distanceRect; private IntervalTimer _mainUpdateTimer; private void Awake() { if (Configuration.ShowNameDistance != null) { Configuration.ShowNameDistance.SettingChanged += OnConfigChanged; } _mainUpdateTimer = new IntervalTimer(0.1f, OnMainUpdate); } private void OnDestroy() { if (Configuration.ShowNameDistance != null) { Configuration.ShowNameDistance.SettingChanged -= OnConfigChanged; } } private void OnConfigChanged(object sender, EventArgs e) { RefreshNow(); } internal void Initialize(TextMeshProUGUI text, PlayerName targetPlayerName) { //IL_0069: 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_009d: 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) _distanceText = text; _playerName = targetPlayerName; _canvasGroup = ((Component)_distanceText).gameObject.GetComponent(); if ((Object)(object)_canvasGroup == (Object)null) { _canvasGroup = ((Component)_distanceText).gameObject.AddComponent(); } _distanceRect = ((TMP_Text)_distanceText).rectTransform; _distanceRect.anchorMin = new Vector2(0.5f, 0.5f); _distanceRect.anchorMax = new Vector2(0.5f, 0.5f); _distanceRect.pivot = new Vector2(0.5f, 0.5f); _distanceRect.sizeDelta = new Vector2(220f, 40f); RefreshNow(); } private void Update() { _mainUpdateTimer?.Update(); } private void LateUpdate() { if (!((Object)(object)_playerName == (Object)null) && !((Object)(object)_distanceRect == (Object)null) && !((Object)(object)_distanceText == (Object)null) && IsNamePlateShowing() && Configuration.ShowNameDistance.Value && Plugin.NamesDisplayActive && !PeakCinemaCompat.ShouldHideNames()) { AlignToName(); } } private void OnMainUpdate() { try { RefreshNow(); } catch (Exception ex) { Plugin.Log.LogError((object)("ShowPlayerDistance update failed: " + ex)); SetVisible(visible: false); } } internal void RefreshNow() { //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_playerName == (Object)null || (Object)(object)_distanceText == (Object)null) { return; } if (!Configuration.ShowNameDistance.Value || !Plugin.NamesDisplayActive) { SetVisible(visible: false); return; } Character val = (((Object)(object)_playerName.characterInteractable != (Object)null) ? _playerName.characterInteractable.character : null); if ((Object)(object)val == (Object)null || (Object)(object)val == (Object)(object)Character.localCharacter) { SetVisible(visible: false); return; } if (!IsNamePlateShowing() || PeakCinemaCompat.ShouldHideNames()) { SetVisible(visible: false); return; } ((Behaviour)_distanceText).enabled = true; ((Graphic)_distanceText).color = NameAnchor.GetLabelColor(val); float num = Vector3.Distance(NameAnchor.GetViewerPosition(), NameAnchor.GetWorldPosition(val, null)); ((TMP_Text)_distanceText).text = $"{num:F1}m"; AlignToName(); SetVisible(visible: true); } private bool IsNamePlateShowing() { if ((Object)(object)_playerName == (Object)null || !((Component)_playerName).gameObject.activeInHierarchy) { return false; } if ((Object)(object)_playerName.group != (Object)null && _playerName.group.alpha < 0.05f) { return false; } if (!((Object)(object)_playerName.text == (Object)null)) { return ((Behaviour)_playerName.text).enabled; } return true; } private void AlignToName() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_playerName.text == (Object)null) && !((Object)(object)_distanceRect == (Object)null)) { Transform transform = ((Component)_playerName).transform; Vector3 position = transform.position; ((Transform)_distanceRect).SetParent(transform, false); ((Transform)_distanceRect).position = position + new Vector3(0f, 28f, 0f); } } private void SetVisible(bool visible) { if ((Object)(object)_canvasGroup != (Object)null) { _canvasGroup.alpha = (visible ? 1f : 0f); _canvasGroup.blocksRaycasts = false; _canvasGroup.interactable = false; } } } internal static class SoftDependencyGuards { internal const string AlwaysDisplayPlayerNameGuid = "com.github.yueby.AlwaysDisplayPlayerName"; internal const string BetterPingDistanceGuid = "youxia173.BetterPingDistance"; internal const string BetterPingDistanceUpstreamGuid = "lucyddemon.betterpingdistance"; internal const string GhostPingGuid = "youxia173.GhostPing"; internal const string GhostPingUpstreamGuid = "boxofbiscuits97.GhostPing"; internal const string DownedAwarenessGuid = "lucyddemon.downedawareness"; internal static bool SkipBuiltInNames => Has("com.github.yueby.AlwaysDisplayPlayerName"); internal static bool SkipBuiltInPingDistance { get { if (!Has("youxia173.BetterPingDistance")) { return Has("lucyddemon.betterpingdistance"); } return true; } } internal static bool SkipBuiltInGhostPing { get { if (!Has("youxia173.GhostPing")) { return Has("boxofbiscuits97.GhostPing"); } return true; } } internal static bool SkipBuiltInDownedMarkers => Has("lucyddemon.downedawareness"); internal static bool Has(string guid) { return Chainloader.PluginInfos.ContainsKey(guid); } internal static void SuppressAlwaysDisplayPlayerName(Harmony harmony) { if (!Has("com.github.yueby.AlwaysDisplayPlayerName")) { return; } try { Type type = AccessTools.TypeByName("AlwaysDisplayPlayerName.Patches.IsLookedAtPatches"); if (type == null) { Plugin.Log.LogWarning((object)"未找到 AlwaysDisplayPlayerName.IsLookedAtPatches,无法自动卸补丁。"); return; } MethodInfo methodInfo = AccessTools.Method(type, "IsLookAtUpdatePath", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(type, "IsLookedAtStartPatch", (Type[])null, (Type[])null); if (methodInfo != null) { harmony.Unpatch((MethodBase)AccessTools.Method(typeof(IsLookedAt), "Update", (Type[])null, (Type[])null), (HarmonyPatchType)1, "com.github.yueby.AlwaysDisplayPlayerName"); } if (methodInfo2 != null) { harmony.Unpatch((MethodBase)AccessTools.Method(typeof(IsLookedAt), "Start", (Type[])null, (Type[])null), (HarmonyPatchType)2, "com.github.yueby.AlwaysDisplayPlayerName"); } harmony.Unpatch((MethodBase)AccessTools.Method(typeof(IsLookedAt), "Update", (Type[])null, (Type[])null), (HarmonyPatchType)0, "com.github.yueby.AlwaysDisplayPlayerName"); harmony.Unpatch((MethodBase)AccessTools.Method(typeof(IsLookedAt), "Start", (Type[])null, (Type[])null), (HarmonyPatchType)0, "com.github.yueby.AlwaysDisplayPlayerName"); } catch (Exception ex) { Plugin.Log.LogWarning((object)("卸 AlwaysDisplayPlayerName 补丁失败: " + ex.Message)); } } internal static void StripForeignDistanceDisplays(PlayerName playerName) { if ((Object)(object)playerName == (Object)null) { return; } try { Transform transform = ((Component)playerName).transform; for (int num = transform.childCount - 1; num >= 0; num--) { Transform child = transform.GetChild(num); if (!((Object)(object)child == (Object)null) && IsForeignDistanceObject(((Component)child).gameObject)) { Object.Destroy((Object)(object)((Component)child).gameObject); } } if (!((Object)(object)playerName.text != (Object)null)) { return; } Transform transform2 = ((TMP_Text)playerName.text).transform; for (int num2 = transform2.childCount - 1; num2 >= 0; num2--) { Transform child2 = transform2.GetChild(num2); if ((Object)(object)child2 != (Object)null && IsForeignDistanceObject(((Component)child2).gameObject)) { Object.Destroy((Object)(object)((Component)child2).gameObject); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("清理第三方名字距离 UI 失败: " + ex.Message)); } } private static bool IsForeignDistanceObject(GameObject go) { if ((Object)(object)go == (Object)null) { return false; } if (((Object)go).name == "SymbioticGhost_DistanceDisplay" || (Object)(object)go.GetComponent() != (Object)null) { return false; } if (((Object)go).name == "DistanceDisplay") { return true; } MonoBehaviour[] components = go.GetComponents(); foreach (MonoBehaviour val in components) { if (!((Object)(object)val == (Object)null)) { string text = ((object)val).GetType().FullName ?? string.Empty; if (text.Contains("AlwaysDisplayPlayerName") && text.Contains("ShowPlayerDistance")) { return true; } } } return false; } } internal sealed class SoulLinkVisual : MonoBehaviour { private static SoulLinkVisual _instance; private static Material _lineMaterial; private readonly Dictionary _lines = new Dictionary(); internal static void Ensure() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown if (!((Object)(object)_instance != (Object)null)) { GameObject val = new GameObject("SymbioticGhost_SoulLink"); Object.DontDestroyOnLoad((Object)val); _instance = val.AddComponent(); } } private void LateUpdate() { //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) //IL_0076: 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_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_013a: 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_0144: Unknown result type (might be due to invalid IL or missing references) //IL_014a: 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_0223: Unknown result type (might be due to invalid IL or missing references) //IL_022f: 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_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) HashSet hashSet = new HashSet(); Character localCharacter = Character.localCharacter; if ((Object)(object)localCharacter != (Object)null && (Object)(object)localCharacter.data != (Object)null && localCharacter.data.fullyPassedOut) { Character val = (((Object)(object)HostBond.Instance != (Object)null) ? HostBond.Instance.Host : MainCameraMovement.specCharacter); if ((Object)(object)val != (Object)null) { Vector3 ghostFeetPosition = NameAnchor.GetGhostFeetPosition(localCharacter); Vector3 livingFeetPosition = NameAnchor.GetLivingFeetPosition(val); int instanceID = ((Object)localCharacter).GetInstanceID(); UpsertLine(instanceID, ghostFeetPosition, livingFeetPosition); hashSet.Add(instanceID); } } Character localCharacter2 = Character.localCharacter; int num = (((Object)(object)localCharacter2 != (Object)null && localCharacter2.refs != null && (Object)(object)localCharacter2.refs.view != (Object)null) ? localCharacter2.refs.view.ViewID : (-1)); if ((Object)(object)localCharacter2 != (Object)null && num >= 0) { foreach (KeyValuePair item in GhostFreeSync.EnumerateRemoteLinks()) { GhostFreeSync.RemoteLink value = item.Value; if (value.Active && value.HostViewId == num && !((Object)(object)PhotonNetwork.GetPhotonView(item.Key) == (Object)null)) { int key = item.Key; Vector3 to = value.GhostPosition + Vector3.down * 0.35f; UpsertLine(key, NameAnchor.GetLivingFeetPosition(localCharacter2), to); hashSet.Add(key); } } PlayerGhost[] array = Object.FindObjectsByType((FindObjectsSortMode)0); foreach (PlayerGhost val2 in array) { if ((Object)(object)val2 == (Object)null || (Object)(object)val2.m_target != (Object)(object)localCharacter2 || ((Object)(object)localCharacter != (Object)null && (Object)(object)val2 == (Object)(object)localCharacter.Ghost)) { continue; } int num2 = (((Object)(object)val2.m_view != (Object)null) ? val2.m_view.ViewID : ((Object)val2).GetInstanceID()); if (hashSet.Contains(num2)) { continue; } try { if ((Object)(object)val2.m_view != (Object)null && val2.m_view.Owner == null) { continue; } } catch { continue; } UpsertLine(num2, NameAnchor.GetLivingFeetPosition(localCharacter2), ((Component)val2).transform.position + Vector3.down * 0.35f); hashSet.Add(num2); } } List list = null; foreach (KeyValuePair line in _lines) { if (!hashSet.Contains(line.Key)) { if (list == null) { list = new List(); } list.Add(line.Key); } } if (list == null) { return; } foreach (int item2 in list) { if (_lines.TryGetValue(item2, out var value2) && (Object)(object)value2 != (Object)null) { Object.Destroy((Object)(object)((Component)value2).gameObject); } _lines.Remove(item2); } } private void UpsertLine(int key, Vector3 from, Vector3 to) { //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) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_010a: 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) if (!_lines.TryGetValue(key, out var value) || (Object)(object)value == (Object)null) { GameObject val = new GameObject("SoulLink_" + key); val.transform.SetParent(((Component)this).transform, false); value = val.AddComponent(); value.positionCount = 2; value.useWorldSpace = true; value.numCapVertices = 2; value.numCornerVertices = 2; value.widthMultiplier = 1f; value.startWidth = 0.018f; value.endWidth = 0.018f; ((Renderer)value).material = GetLineMaterial(); value.startColor = new Color(0.45f, 0.95f, 1f, 0.38f); value.endColor = new Color(0.7f, 0.4f, 1f, 0.38f); ((Renderer)value).shadowCastingMode = (ShadowCastingMode)0; ((Renderer)value).receiveShadows = false; _lines[key] = value; } ((Renderer)value).enabled = true; value.startWidth = 0.018f; value.endWidth = 0.018f; value.SetPosition(0, from); value.SetPosition(1, to); } private static Material GetLineMaterial() { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_lineMaterial != (Object)null) { return _lineMaterial; } Shader val = Shader.Find("Sprites/Default"); if ((Object)(object)val == (Object)null) { val = Shader.Find("Unlit/Color"); } _lineMaterial = new Material(((Object)(object)val != (Object)null) ? val : Shader.Find("Hidden/InternalErrorShader")); _lineMaterial.color = Color.white; return _lineMaterial; } private void OnDestroy() { foreach (KeyValuePair line in _lines) { if ((Object)(object)line.Value != (Object)null) { Object.Destroy((Object)(object)((Component)line.Value).gameObject); } } _lines.Clear(); } } internal static class SpectatorUiCamera { internal static Camera Get() { if ((Object)(object)MainCamera.instance != (Object)null) { if ((Object)(object)MainCamera.instance.cam != (Object)null) { return MainCamera.instance.cam; } Camera component = ((Component)MainCamera.instance).GetComponent(); if ((Object)(object)component != (Object)null) { return component; } } return Camera.main; } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }