Decompiled source of SymbioticGhost v1.5.7
plugins/SymbioticGhost.dll
Decompiled 7 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.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<KeyCode> ToggleKey; internal static ConfigEntry<float> MoveSpeed; internal static ConfigEntry<float> MoveDamping; internal static ConfigEntry<float> LookSensitivityMultiplier; internal static ConfigEntry<float> LeashDistance; internal static ConfigEntry<float> LeashCountdownSeconds; internal static ConfigEntry<bool> EnableNames; internal static ConfigEntry<float> NameVisibleAngle; internal static ConfigEntry<bool> DisplayWhenBlind; internal static ConfigEntry<bool> ShowNameDistance; internal static ConfigEntry<KeyboardShortcut> NameDisplayToggle; internal static ConfigEntry<float> NameDisplayDuration; internal static ConfigEntry<float> PingTextDuration; internal static ConfigEntry<bool> ShowPingNameShort; internal static ConfigEntry<bool> EnableGhostPing; internal static ConfigEntry<bool> EnableGhostHaul; internal static ConfigEntry<float> MaxGhostHaulDisplayWeight; internal static ConfigEntry<KeyCode> GhostHaulKey; internal static ConfigEntry<float> GhostHaulRange; internal static ConfigEntry<bool> EnableGhostBackpack; internal static ConfigEntry<bool> EnableDownedMarkers; internal static ConfigEntry<float> 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<KeyCode>("1. Hotkeys 热键", "Free Fly Toggle 自由飞行开关", (KeyCode)284, "EN: Solo — free-fly while passed out. Multiplayer — only after fully dead.\n中文:单人 — 昏迷即可灵魂离体;多人 — 须完全死亡后才能按 F3 离体。"); MoveSpeed = config.Bind<float>("2. Camera 相机", "Move Speed 移动速度", 12f, new ConfigDescription("EN: Free-fly movement force.\n中文:自由飞行移动力度。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), Array.Empty<object>())); MoveDamping = config.Bind<float>("2. Camera 相机", "Move Damping 移动阻尼", 3f, new ConfigDescription("EN: Velocity settle damping.\n中文:自由飞行速度阻尼。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.5f, 20f), Array.Empty<object>())); LookSensitivityMultiplier = config.Bind<float>("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<float>(0.25f, 3f), Array.Empty<object>())); LeashDistance = config.Bind<float>("3. Symbiosis 共生", "Leash Distance 寄宿距离", 20f, new ConfigDescription("EN: Beyond this distance from the host, free-fly countdown starts.\n中文:超过与寄宿玩家的该直线距离后开始倒计时。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(5f, 100f), Array.Empty<object>())); LeashCountdownSeconds = config.Bind<float>("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<float>(1f, 60f), Array.Empty<object>())); EnableNames = config.Bind<bool>("4. Player Names 队友名字", "Enable Names 启用名字显示", true, "EN: Show teammate names when looking toward them.\n中文:看向队友时显示名字。"); NameVisibleAngle = config.Bind<float>("4. Player Names 队友名字", "Visible Angle 可见角度", 52f, new ConfigDescription("EN: Cone angle for name visibility.\n中文:名字显示的视角锥角。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 180f), Array.Empty<object>())); DisplayWhenBlind = config.Bind<bool>("4. Player Names 队友名字", "Display When Blind 致盲时显示", false, "EN: Force names when the target is blind.\n中文:目标致盲时是否仍显示名字。"); ShowNameDistance = config.Bind<bool>("4. Player Names 队友名字", "Show Distance 显示距离", true, "EN: Show distance under the player name.\n中文:在名字下方显示距离。"); NameDisplayToggle = config.Bind<KeyboardShortcut>("4. Player Names 队友名字", "Name Display Toggle 名字显示开关", new KeyboardShortcut((KeyCode)116, Array.Empty<KeyCode>()), "EN: Hotkey to toggle name display.\n中文:切换队友名字显示的热键。"); NameDisplayDuration = config.Bind<float>("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<float>(0f, 300f), Array.Empty<object>())); PingTextDuration = config.Bind<float>("5. Ping Distance 标记距离", "Ping Text Duration 标记距离秒数", 3f, new ConfigDescription("EN: How long ping distance text stays on screen.\n中文:标记距离文字停留秒数。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0.1f, 30f), Array.Empty<object>())); ShowPingNameShort = config.Bind<bool>("5. Ping Distance 标记距离", "Show Ping Name Short 标记名缩写", true, "EN: Show a short name after ping distance.\n中文:在标记距离后显示玩家名缩写。"); EnableGhostPing = config.Bind<bool>("6. Ghost Ping 幽灵标记", "Enable Ghost Ping 启用幽灵标记", true, "EN: Allow pinging while dead / passed out, and show no-LOS pings.\n中文:死亡/昏厥时也可标记,并显示无视线标记。"); EnableGhostHaul = config.Bind<bool>("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<bool>("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<float>("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<float>(2.5f, 20f), Array.Empty<object>())); GhostHaulKey = config.Bind<KeyCode>("7. Ghost Haul 幽灵搬运", "Haul Key 搬运按键", (KeyCode)101, "EN: Pick up / drop while spectating as a ghost.\n中文:幽灵状态下提起或放下物品的按键。"); GhostHaulRange = config.Bind<float>("7. Ghost Haul 幽灵搬运", "Haul Range 搬运距离", 4f, new ConfigDescription("EN: How far the ghost can reach to haul an item.\n中文:幽灵可提起物品的最大距离。", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1.5f, 12f), Array.Empty<object>())); EnableDownedMarkers = config.Bind<bool>("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<float>("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<float>(0f, 20f), Array.Empty<object>())); } } 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<TextMeshProUGUI>(); } } if ((Object)(object)_statusText == (Object)null) { Transform val2 = ((Component)this).transform.Find("StatusText"); if ((Object)(object)val2 != (Object)null) { _statusText = ((Component)val2).GetComponent<TextMeshProUGUI>(); } } } 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<Character, GameObject> _instances = new Dictionary<Character, GameObject>(); 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>(); 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>(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 101; CanvasScaler component = val2.GetComponent<CanvasScaler>(); 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<TextMeshProUGUI>(); ((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<TextMeshProUGUI>(); ((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<RectTransform>(); 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<TextMeshProUGUI>(); ((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<Shadow>(); 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<GameObject>(_template, ((Component)_canvas).transform); val.GetComponent<DownedMarker>().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<DownedMarker>()?.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<DownedMarker>()?.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<MainCameraMovement>.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<MainCameraMovement>.Instance?.godcam, _lookData); LookVelField?.SetValue(Singleton<MainCameraMovement>.Instance?.godcam, _lookVel); VelField?.SetValue(Singleton<MainCameraMovement>.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<MainCameraMovement>.Instance?.godcam, _lookData); LookVelField?.SetValue(Singleton<MainCameraMovement>.Instance?.godcam, _lookVel); VelField?.SetValue(Singleton<MainCameraMovement>.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<Vector2>(); } } 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<ControllerSensitivitySetting>(); if (setting != null) { return ((FloatSetting)setting).Value; } } else { MouseSensitivitySetting setting2 = val.GetSetting<MouseSensitivitySetting>(); 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<InvertYSetting>(); if (setting != null) { return ((int)((EnumSetting<OffOnMode>)(object)setting).Value == 0) ? 1 : (-1); } } else { InvertXSetting setting2 = val.GetSetting<InvertXSetting>(); if (setting2 != null) { return ((int)((EnumSetting<OffOnMode>)(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<CharacterInteractible>() : 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<CharacterInteractible>() : 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<InventorySyncData>(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<byte> 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<FixedJoint>(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<Backpack>(); 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<BackpackOnBackVisuals>(); 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<MainCameraMovement>.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<int, RemoteLink> RemoteLinks = new Dictionary<int, RemoteLink>(); private static GhostFreeSync _instance; private static float _nextSendTime; private static bool _localFreeActive; private static int _localGhostViewId = -1; private static float _nextStaleSweep; internal static IEnumerable<KeyValuePair<int, RemoteLink>> 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<GhostFreeSync>(); } } 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<int> list = null; float unscaledTime = Time.unscaledTime; foreach (KeyValuePair<int, RemoteLink> 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<int>(); } 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<int> list = null; foreach (KeyValuePair<int, RemoteLink> 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<int>(); } 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<FriendInfo> 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<GhostItemHaul>(); } } 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 res