Decompiled source of InvisibleTeammates v1.1.0

InvisibleTeammates.dll

Decompiled a day ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using HarmonyLib;
using InvisibleTeammates;
using MelonLoader;
using MelonLoader.Preferences;
using Microsoft.CodeAnalysis;
using Mimic.Actors;
using Mimic.Animation;
using Mimic.InputSystem;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Controls;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: MelonInfo(typeof(InvisibleTeammatesMod), "Invisible Teammates", "1.1.0", "DeepSeek Harness", null)]
[assembly: MelonGame("ReLUGames", "MIMESIS")]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("InvisibleTeammates")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("InvisibleTeammates")]
[assembly: AssemblyTitle("InvisibleTeammates")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace InvisibleTeammates
{
	public sealed class InvisibleTeammatesMod : MelonMod
	{
		private static readonly PropertyInfo HubCameramanProperty = typeof(Hub).GetProperty("cameraman", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private static readonly PropertyInfo HubInputmanProperty = typeof(Hub).GetProperty("inputman", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);

		private readonly Dictionary<int, TeammateHider> _hiders = new Dictionary<int, TeammateHider>();

		private readonly List<int> _staleHiderIds = new List<int>();

		private readonly Dictionary<int, List<FootstepAudioPlayer>> _mutedFootsteps = new Dictionary<int, List<FootstepAudioPlayer>>();

		private readonly Dictionary<FootstepAudioPlayer, bool> _footstepOriginalEnabled = new Dictionary<FootstepAudioPlayer, bool>();

		private readonly List<int> _staleFootstepIds = new List<int>();

		private Harmony _harmony;

		private GameObject _panelObject;

		private float _nextTick;

		private Key _panelKey = (Key)102;

		private bool _panelOpen;

		private bool _captureBefore;

		private int _loggedErrors;

		internal static InvisibleTeammatesMod Instance { get; private set; }

		public override void OnInitializeMelon()
		{
			//IL_001c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0026: Expected O, but got Unknown
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			Instance = this;
			ModPreferences.Initialize();
			ParsePanelKey();
			MelonPreferences.Save();
			_panelObject = new GameObject("InvisibleTeammates_SettingsPanel");
			Object.DontDestroyOnLoad((Object)(object)_panelObject);
			_panelObject.AddComponent<SettingsPanel>();
			_harmony = new Harmony("com.invisibleteammates.mimesis");
			_harmony.PatchAll(typeof(InputCapturePatch));
			if (TeammateHider.HasMissingReflectionTargets)
			{
				((MelonBase)this).LoggerInstance.Warning("Some private game fields were not found (game update?). Body/inventory hiding still works; nameplate hiding may be limited.");
			}
			((MelonBase)this).LoggerInstance.Msg("Invisible Teammates v1.1.0 loaded. Press F9 to open the settings panel.");
		}

		public override void OnUpdate()
		{
			HandlePanelHotkey();
			if (_panelOpen)
			{
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
			}
			if (ModPreferences.Enabled.Value)
			{
				ReassertBodyHidden();
			}
			if (Time.unscaledTime < _nextTick)
			{
				return;
			}
			_nextTick = Time.unscaledTime + 0.2f;
			try
			{
				Tick();
			}
			catch (Exception ex)
			{
				if (_loggedErrors++ < 5)
				{
					((MelonBase)this).LoggerInstance.Warning("[InvisibleTeammates] Tick exception: " + ex);
				}
			}
		}

		public override void OnDeinitializeMelon()
		{
			RestoreAll();
			if ((Object)(object)_panelObject != (Object)null)
			{
				Object.Destroy((Object)(object)_panelObject);
			}
			if (_harmony != null)
			{
				_harmony.UnpatchSelf();
			}
		}

		private void Tick()
		{
			GameMainBase main = Hub.Main;
			if ((Object)(object)main == (Object)null)
			{
				RestoreAll();
				return;
			}
			bool value = ModPreferences.Enabled.Value;
			bool flag = value && ModPreferences.HideTeammates.Value;
			bool flag2 = value && ModPreferences.HideMimics.Value;
			if (value && ModPreferences.HideOnlyInDungeon.Value && !(main is GamePlayScene))
			{
				flag = false;
				flag2 = false;
			}
			if (value && ModPreferences.ShowTeammatesWhileSpectating.Value && IsSpectating())
			{
				flag = false;
				flag2 = false;
			}
			HashSet<int> hashSet = new HashSet<int>();
			foreach (KeyValuePair<int, ProtoActor> item in main.GetProtoActorMap())
			{
				ProtoActor value2 = item.Value;
				if ((Object)(object)value2 == (Object)null)
				{
					continue;
				}
				int instanceID = ((Object)value2).GetInstanceID();
				hashSet.Add(instanceID);
				if (value2.AmIAvatar())
				{
					RestoreHider(instanceID);
					continue;
				}
				bool flag3 = value2.IsMimic();
				if ((flag && value2.IsPlayer() && !flag3) || (flag2 && flag3))
				{
					if (!_hiders.TryGetValue(instanceID, out var value3) || (Object)(object)value3.Actor == (Object)null)
					{
						value3 = new TeammateHider(value2);
						_hiders[instanceID] = value3;
					}
					value3.Hide(ModPreferences.HideNameplates.Value, ModPreferences.HideHeldItems.Value, ModPreferences.HideFlashlight.Value);
				}
				else
				{
					RestoreHider(instanceID);
				}
			}
			_staleHiderIds.Clear();
			foreach (KeyValuePair<int, TeammateHider> hider in _hiders)
			{
				if (!hashSet.Contains(hider.Key) || (Object)(object)hider.Value.Actor == (Object)null)
				{
					_staleHiderIds.Add(hider.Key);
				}
			}
			for (int i = 0; i < _staleHiderIds.Count; i++)
			{
				RestoreHider(_staleHiderIds[i]);
			}
			UpdateFootsteps(main, value, flag2);
		}

		private void UpdateFootsteps(GameMainBase main, bool enabled, bool hideMimics)
		{
			bool flag = enabled && ModPreferences.HideFootsteps.Value && (!ModPreferences.HideOnlyInDungeon.Value || main is GamePlayScene);
			HashSet<int> hashSet = new HashSet<int>();
			foreach (KeyValuePair<int, ProtoActor> item in main.GetProtoActorMap())
			{
				ProtoActor value = item.Value;
				if ((Object)(object)value == (Object)null || value.AmIAvatar())
				{
					continue;
				}
				bool flag2 = value.IsMimic();
				if ((value.IsPlayer() && !flag2) || (hideMimics && flag2))
				{
					int instanceID = ((Object)value).GetInstanceID();
					hashSet.Add(instanceID);
					if (flag)
					{
						MuteFootsteps(value, instanceID);
					}
					else
					{
						UnmuteFootsteps(instanceID);
					}
				}
			}
			_staleFootstepIds.Clear();
			foreach (int key in _mutedFootsteps.Keys)
			{
				if (!hashSet.Contains(key))
				{
					_staleFootstepIds.Add(key);
				}
			}
			for (int i = 0; i < _staleFootstepIds.Count; i++)
			{
				UnmuteFootsteps(_staleFootstepIds[i]);
			}
		}

		private void MuteFootsteps(ProtoActor actor, int id)
		{
			if (!_mutedFootsteps.TryGetValue(id, out var value))
			{
				value = new List<FootstepAudioPlayer>();
				_mutedFootsteps[id] = value;
			}
			FootstepAudioPlayer[] componentsInChildren = ((Component)actor).GetComponentsInChildren<FootstepAudioPlayer>(true);
			foreach (FootstepAudioPlayer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null))
				{
					if (!_footstepOriginalEnabled.ContainsKey(val))
					{
						_footstepOriginalEnabled[val] = ((Behaviour)val).enabled;
						value.Add(val);
					}
					if (((Behaviour)val).enabled)
					{
						((Behaviour)val).enabled = false;
					}
				}
			}
		}

		private void UnmuteFootsteps(int id)
		{
			if (!_mutedFootsteps.TryGetValue(id, out var value))
			{
				return;
			}
			bool value2 = default(bool);
			for (int i = 0; i < value.Count; i++)
			{
				FootstepAudioPlayer val = value[i];
				if ((Object)(object)val != (Object)null && _footstepOriginalEnabled.TryGetValue(val, out value2) && value2 && !((Behaviour)val).enabled)
				{
					((Behaviour)val).enabled = true;
				}
			}
			for (int j = 0; j < value.Count; j++)
			{
				if ((Object)(object)value[j] != (Object)null)
				{
					_footstepOriginalEnabled.Remove(value[j]);
				}
			}
			_mutedFootsteps.Remove(id);
		}

		private void RestoreHider(int id)
		{
			if (_hiders.TryGetValue(id, out var value))
			{
				value.Restore();
				_hiders.Remove(id);
			}
		}

		private void RestoreAll()
		{
			foreach (KeyValuePair<int, TeammateHider> hider in _hiders)
			{
				hider.Value.Restore();
			}
			_hiders.Clear();
			List<int> list = new List<int>(_mutedFootsteps.Keys);
			for (int i = 0; i < list.Count; i++)
			{
				UnmuteFootsteps(list[i]);
			}
			_mutedFootsteps.Clear();
			_footstepOriginalEnabled.Clear();
		}

		private void HandlePanelHotkey()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			if ((int)_panelKey == 0)
			{
				return;
			}
			Keyboard current = Keyboard.current;
			if (current != null)
			{
				KeyControl val = current[_panelKey];
				if (val != null && ((ButtonControl)val).wasPressedThisFrame)
				{
					TogglePanel();
				}
			}
		}

		private void TogglePanel()
		{
			if (_panelOpen)
			{
				ClosePanel();
			}
			else
			{
				OpenPanel();
			}
		}

		private void OpenPanel()
		{
			_panelOpen = true;
			SettingsPanel.IsOpen = true;
			InputManager inputManager = GetInputManager();
			_captureBefore = (Object)(object)inputManager != (Object)null && inputManager.IsCapturing();
			if ((Object)(object)inputManager != (Object)null)
			{
				inputManager.SetCapturing(false);
			}
			Cursor.visible = true;
			Cursor.lockState = (CursorLockMode)0;
		}

		internal void ClosePanel()
		{
			if (_panelOpen)
			{
				_panelOpen = false;
				SettingsPanel.IsOpen = false;
				InputManager inputManager = GetInputManager();
				if ((Object)(object)inputManager != (Object)null)
				{
					inputManager.SetCapturing(_captureBefore);
				}
				Cursor.visible = !_captureBefore;
				if (_captureBefore)
				{
					Cursor.lockState = (CursorLockMode)1;
				}
				MelonPreferences.Save();
			}
		}

		private static InputManager GetInputManager()
		{
			Hub s = Hub.s;
			if ((Object)(object)s == (Object)null || HubInputmanProperty == null)
			{
				return null;
			}
			object? value = HubInputmanProperty.GetValue(s, null);
			return (InputManager)((value is InputManager) ? value : null);
		}

		private static bool IsSpectating()
		{
			Hub s = Hub.s;
			if ((Object)(object)s == (Object)null || HubCameramanProperty == null)
			{
				return false;
			}
			object? value = HubCameramanProperty.GetValue(s, null);
			CameraManager val = (CameraManager)((value is CameraManager) ? value : null);
			if ((Object)(object)val != (Object)null)
			{
				return val.IsSpectatorMode;
			}
			return false;
		}

		private void ReassertBodyHidden()
		{
			foreach (KeyValuePair<int, TeammateHider> hider in _hiders)
			{
				hider.Value.ReassertBodyHidden();
			}
		}

		internal void ParsePanelKey()
		{
			//IL_0015: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: 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_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)
			string value = ModPreferences.ToggleKey.Value;
			if (string.IsNullOrWhiteSpace(value))
			{
				_panelKey = (Key)0;
				return;
			}
			string text = value.Trim();
			if ((!Enum.TryParse<Key>(text, ignoreCase: true, out Key result) || (int)result == 0) && (!Enum.TryParse<Key>(text.Replace("BackQuote", "Backquote").Replace("Alpha", "Digit"), ignoreCase: true, out result) || (int)result == 0))
			{
				((MelonBase)this).LoggerInstance.Warning("Unrecognized ToggleKey \"" + value + "\". Use Input System Key names (F9, F10, LeftAlt, Backquote, KeyA). Panel hotkey disabled.");
				_panelKey = (Key)0;
			}
			else
			{
				_panelKey = result;
			}
		}
	}
	[HarmonyPatch(typeof(InputManager), "IsCapturing")]
	internal static class InputCapturePatch
	{
		private static bool Prefix(ref bool __result)
		{
			if (!SettingsPanel.IsOpen)
			{
				return true;
			}
			__result = false;
			return false;
		}
	}
	internal static class ModPreferences
	{
		internal static MelonPreferences_Category Category;

		internal static MelonPreferences_Entry<bool> Enabled;

		internal static MelonPreferences_Entry<bool> HideTeammates;

		internal static MelonPreferences_Entry<bool> HideNameplates;

		internal static MelonPreferences_Entry<bool> HideHeldItems;

		internal static MelonPreferences_Entry<bool> HideFootsteps;

		internal static MelonPreferences_Entry<bool> HideMimics;

		internal static MelonPreferences_Entry<bool> HideFlashlight;

		internal static MelonPreferences_Entry<bool> ShowTeammatesWhileSpectating;

		internal static MelonPreferences_Entry<bool> HideOnlyInDungeon;

		internal static MelonPreferences_Entry<string> ToggleKey;

		internal static void Initialize()
		{
			Category = MelonPreferences.CreateCategory("InvisibleTeammates", "队友隐形 (Invisible Teammates)");
			Enabled = Category.CreateEntry<bool>("Enabled", true, "启用 Mod", "总开关。关闭后所有隐藏效果立即撤销。", false, false, (ValueValidator)null, (string)null);
			HideTeammates = Category.CreateEntry<bool>("HideTeammates", true, "隐藏队友", "把真人队友从你的画面里隐藏(模型、配件、手持物)。只影响你本机。", false, false, (ValueValidator)null, (string)null);
			HideNameplates = Category.CreateEntry<bool>("HideNameplates", true, "隐藏队友名字/说话图标", "隐藏队友头顶的名字、说话图标和交互提示。", false, false, (ValueValidator)null, (string)null);
			HideHeldItems = Category.CreateEntry<bool>("HideHeldItems", true, "隐藏队友手持物品", "隐藏队友手里物品/配件/特效的渲染,不销毁、不改变物品本身:队友仍能正常使用、丢弃,其他玩家照常看见。", false, false, (ValueValidator)null, (string)null);
			HideFootsteps = Category.CreateEntry<bool>("HideFootsteps", true, "隐藏队友/伪人脚步声", "被隐形的角色(真人队友,以及开启“隐藏伪人”后的伪人)不播放走路/跑步脚步声。语音、开枪等其它声音不受影响。", false, false, (ValueValidator)null, (string)null);
			HideMimics = Category.CreateEntry<bool>("HideMimics", false, "隐藏伪人", "把伪人(MonsterType.Mimic)也一起隐藏,只能靠声音和行为判断真假。普通怪物不受影响。", false, false, (ValueValidator)null, (string)null);
			HideFlashlight = Category.CreateEntry<bool>("HideFlashlight", false, "隐藏手电光", "隐藏被你隐形的角色身上的手电筒/挂灯灯光。", false, false, (ValueValidator)null, (string)null);
			ShowTeammatesWhileSpectating = Category.CreateEntry<bool>("ShowTeammatesWhileSpectating", true, "观战时恢复显示", "你死亡进入观战镜头时临时显示队友,避免观战目标看不见。", false, false, (ValueValidator)null, (string)null);
			HideOnlyInDungeon = Category.CreateEntry<bool>("HideOnlyInDungeon", false, "仅地牢内生效", "开启后只在正式关卡里隐藏队友,电车和维护室保持原版显示。", false, false, (ValueValidator)null, (string)null);
			ToggleKey = Category.CreateEntry<string>("ToggleKey", "F9", "设置面板热键", "游戏内按此键打开/关闭设置面板。使用 Input System 的 Key 名称,例如 F9、F10、LeftAlt、Backquote。", false, false, (ValueValidator)null, (string)null);
		}

		internal static void ResetToDefaults()
		{
			Enabled.Value = true;
			HideTeammates.Value = true;
			HideNameplates.Value = true;
			HideHeldItems.Value = true;
			HideFootsteps.Value = true;
			HideMimics.Value = false;
			HideFlashlight.Value = false;
			ShowTeammatesWhileSpectating.Value = true;
			HideOnlyInDungeon.Value = false;
			ToggleKey.Value = "F9";
			MelonPreferences.Save();
		}
	}
	public sealed class SettingsPanel : MonoBehaviour
	{
		internal static bool IsOpen;

		private bool _stylesReady;

		private Font _font;

		private Texture2D _background;

		private Texture2D _rowBackground;

		private Texture2D _rowHover;

		private GUIStyle _titleStyle;

		private GUIStyle _subtitleStyle;

		private GUIStyle _sectionStyle;

		private GUIStyle _rowStyle;

		private GUIStyle _buttonStyle;

		private void Update()
		{
			if (IsOpen)
			{
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
			}
		}

		private void OnGUI()
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0041: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: 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_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_035a: Unknown result type (might be due to invalid IL or missing references)
			if (IsOpen)
			{
				Cursor.visible = true;
				Cursor.lockState = (CursorLockMode)0;
				EnsureStyles();
				Matrix4x4 matrix = GUI.matrix;
				float num = Mathf.Clamp((float)Screen.height / 1080f, 0.8f, 1.5f);
				GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, new Vector3(num, num, 1f));
				float num2 = (float)Screen.width / num;
				float num3 = (float)Screen.height / num;
				Rect val = default(Rect);
				((Rect)(ref val))..ctor((num2 - 470f) * 0.5f, (num3 - 620f) * 0.5f, 470f, 620f);
				int depth = GUI.depth;
				GUI.depth = -1000;
				GUI.DrawTexture(val, (Texture)(object)_background, (ScaleMode)0);
				GUILayout.BeginArea(new Rect(((Rect)(ref val)).x + 24f, ((Rect)(ref val)).y + 18f, ((Rect)(ref val)).width - 48f, ((Rect)(ref val)).height - 36f));
				GUILayout.Label("Invisible Teammates", _titleStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Label("点击选项切换 · 按 F9 关闭", _subtitleStyle, Array.Empty<GUILayoutOption>());
				GUILayout.Space(10f);
				ModPreferences.Enabled.Value = DrawToggle(ModPreferences.Enabled.Value, "启用 Mod");
				GUILayout.Space(8f);
				GUILayout.Label("真人队友", _sectionStyle, Array.Empty<GUILayoutOption>());
				ModPreferences.HideTeammates.Value = !DrawToggle(!ModPreferences.HideTeammates.Value, "看见队友模型");
				ModPreferences.HideNameplates.Value = !DrawToggle(!ModPreferences.HideNameplates.Value, "看见队友名字 / 说话图标");
				ModPreferences.HideHeldItems.Value = !DrawToggle(!ModPreferences.HideHeldItems.Value, "看见队友手持物品");
				ModPreferences.HideFootsteps.Value = !DrawToggle(!ModPreferences.HideFootsteps.Value, "听见队友 / 伪人脚步声");
				GUILayout.Space(8f);
				GUILayout.Label("伪人 / 灯光", _sectionStyle, Array.Empty<GUILayoutOption>());
				ModPreferences.HideMimics.Value = !DrawToggle(!ModPreferences.HideMimics.Value, "看见伪人(拟态怪)");
				ModPreferences.HideFlashlight.Value = !DrawToggle(!ModPreferences.HideFlashlight.Value, "看见队友手电光");
				GUILayout.Space(8f);
				GUILayout.Label("其他", _sectionStyle, Array.Empty<GUILayoutOption>());
				ModPreferences.ShowTeammatesWhileSpectating.Value = DrawToggle(ModPreferences.ShowTeammatesWhileSpectating.Value, "死亡观战时看见队友");
				ModPreferences.HideOnlyInDungeon.Value = DrawToggle(ModPreferences.HideOnlyInDungeon.Value, "仅地牢内生效");
				GUILayout.FlexibleSpace();
				GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
				if (GUILayout.Button("恢复默认", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) }))
				{
					ModPreferences.ResetToDefaults();
					InvisibleTeammatesMod.Instance.ParsePanelKey();
				}
				if (GUILayout.Button("关闭 (F9)", _buttonStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(34f) }))
				{
					InvisibleTeammatesMod.Instance.ClosePanel();
				}
				GUILayout.EndHorizontal();
				GUILayout.Label("设置立即生效,关闭面板时自动保存。", _subtitleStyle, Array.Empty<GUILayoutOption>());
				GUILayout.EndArea();
				GUI.depth = depth;
				GUI.matrix = matrix;
			}
		}

		private bool DrawToggle(bool value, string label)
		{
			if (GUILayout.Button((value ? "<color=#79E0A3>✓</color>" : "<color=#8892A4>✗</color>") + "   " + label, _rowStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(30f) }))
			{
				return !value;
			}
			return value;
		}

		private void EnsureStyles()
		{
			//IL_007e: 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_00c6: 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_00f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f9: 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_010c: Expected O, but got Unknown
			//IL_0126: Unknown result type (might be due to invalid IL or missing references)
			//IL_013b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_014c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0154: Unknown result type (might be due to invalid IL or missing references)
			//IL_0160: Expected O, but got Unknown
			//IL_017a: Unknown result type (might be due to invalid IL or missing references)
			//IL_018f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0194: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Expected O, but got Unknown
			//IL_01ce: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e8: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fc: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0210: Unknown result type (might be due to invalid IL or missing references)
			//IL_021a: Expected O, but got Unknown
			//IL_021f: Expected O, but got Unknown
			//IL_027b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0290: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_02bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d8: Expected O, but got Unknown
			if (!_stylesReady)
			{
				_stylesReady = true;
				_font = Font.CreateDynamicFontFromOSFont(new string[5] { "Microsoft YaHei UI", "Microsoft YaHei", "SimHei", "Noto Sans CJK SC", "Arial" }, 16);
				if ((Object)(object)_font == (Object)null)
				{
					_font = GUI.skin.font;
				}
				_background = CreateTexture(new Color(0.035f, 0.045f, 0.065f, 0.96f));
				_rowBackground = CreateTexture(new Color(0.07f, 0.09f, 0.13f, 0.65f));
				_rowHover = CreateTexture(new Color(0.15f, 0.21f, 0.29f, 0.95f));
				_titleStyle = new GUIStyle(GUI.skin.label)
				{
					font = _font,
					fontSize = 24,
					fontStyle = (FontStyle)1,
					alignment = (TextAnchor)4
				};
				_titleStyle.normal.textColor = new Color(0.82f, 0.9f, 1f);
				_subtitleStyle = new GUIStyle(GUI.skin.label)
				{
					font = _font,
					fontSize = 13,
					alignment = (TextAnchor)4
				};
				_subtitleStyle.normal.textColor = new Color(0.62f, 0.68f, 0.78f);
				_sectionStyle = new GUIStyle(GUI.skin.label)
				{
					font = _font,
					fontSize = 14,
					fontStyle = (FontStyle)1
				};
				_sectionStyle.normal.textColor = new Color(0.55f, 0.75f, 0.95f);
				_rowStyle = new GUIStyle(GUI.skin.button)
				{
					font = _font,
					fontSize = 16,
					alignment = (TextAnchor)3,
					richText = true,
					padding = new RectOffset(12, 8, 4, 4)
				};
				_rowStyle.normal.background = _rowBackground;
				_rowStyle.hover.background = _rowHover;
				_rowStyle.active.background = _rowHover;
				_rowStyle.normal.textColor = new Color(0.86f, 0.9f, 0.96f);
				_rowStyle.hover.textColor = Color.white;
				_rowStyle.active.textColor = Color.white;
				_buttonStyle = new GUIStyle(GUI.skin.button)
				{
					font = _font,
					fontSize = 15
				};
			}
		}

		private static Texture2D CreateTexture(Color color)
		{
			//IL_0004: Unknown result type (might be due to invalid IL or missing references)
			//IL_0009: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_0019: Expected O, but got Unknown
			Texture2D val = new Texture2D(1, 1, (TextureFormat)4, false);
			val.SetPixel(0, 0, color);
			val.Apply();
			return val;
		}

		private void OnDestroy()
		{
			if ((Object)(object)_background != (Object)null)
			{
				Object.Destroy((Object)(object)_background);
			}
			if ((Object)(object)_rowBackground != (Object)null)
			{
				Object.Destroy((Object)(object)_rowBackground);
			}
			if ((Object)(object)_rowHover != (Object)null)
			{
				Object.Destroy((Object)(object)_rowHover);
			}
		}
	}
	internal sealed class TeammateHider
	{
		private static readonly FieldInfo BillboardField = FindField(typeof(ProtoActor), "_billboard_Canvas");

		private static readonly FieldInfo SpeakIconField = FindField(typeof(ProtoActor), "_mimicSpeaking");

		private static readonly FieldInfo NameTagField = FindField(typeof(ProtoActor), "nameTag");

		private static readonly FieldInfo PuppetRenderersField = FindField(typeof(PuppetScript), "_renderers");

		private readonly ProtoActor _actor;

		private PuppetScript _puppet;

		private HashSet<Renderer> _bodyRenderers;

		private GameObject _billboard;

		private GameObject _speakIcon;

		private GameObject _nameTagObject;

		private bool _uiCaptured;

		private bool _billboardWasActive;

		private bool _speakIconWasActive;

		private bool _nameTagWasActive;

		private readonly Dictionary<Renderer, bool> _hiddenRenderers = new Dictionary<Renderer, bool>();

		private readonly Dictionary<Light, bool> _hiddenLights = new Dictionary<Light, bool>();

		private readonly List<Renderer> _removedRenderers = new List<Renderer>();

		private readonly List<Light> _removedLights = new List<Light>();

		private float _nextScan;

		internal static bool HasMissingReflectionTargets
		{
			get
			{
				if (!(BillboardField == null) && !(SpeakIconField == null) && !(NameTagField == null))
				{
					return PuppetRenderersField == null;
				}
				return true;
			}
		}

		internal ProtoActor Actor => _actor;

		internal TeammateHider(ProtoActor actor)
		{
			_actor = actor;
		}

		internal void Hide(bool hideNameplates, bool hideHeldItems, bool hideFlashlight)
		{
			if (!((Object)(object)_actor == (Object)null))
			{
				EnsurePuppet();
				if ((Object)(object)_puppet != (Object)null)
				{
					_puppet.SetRenderersForceHidden(true);
				}
				if (hideNameplates)
				{
					HideNameplateObjects();
				}
				else
				{
					ShowNameplateObjects();
				}
				if (hideHeldItems || hideFlashlight)
				{
					ScanAttached();
				}
				if (!hideHeldItems)
				{
					RestoreAttachedRenderers();
				}
				if (!hideFlashlight)
				{
					RestoreLights();
				}
			}
		}

		internal void ReassertBodyHidden()
		{
			if (!((Object)(object)_actor == (Object)null))
			{
				EnsurePuppet();
				if ((Object)(object)_puppet != (Object)null)
				{
					_puppet.SetRenderersForceHidden(true);
				}
			}
		}

		internal void Restore()
		{
			if ((Object)(object)_puppet != (Object)null)
			{
				_puppet.SetRenderersForceHidden(false);
			}
			RestoreAttachedRenderers();
			RestoreLights();
			ShowNameplateObjects();
		}

		private void EnsurePuppet()
		{
			if (!((Object)(object)_puppet != (Object)null))
			{
				_puppet = ((Component)_actor).GetComponentInChildren<PuppetScript>(true);
				_bodyRenderers = null;
			}
		}

		private void HideNameplateObjects()
		{
			if (!_uiCaptured)
			{
				_uiCaptured = true;
				_billboard = (GameObject)((BillboardField != null) ? /*isinst with value type is only supported in some contexts*/: null);
				_speakIcon = (GameObject)((SpeakIconField != null) ? /*isinst with value type is only supported in some contexts*/: null);
				Component val = (Component)((NameTagField != null) ? /*isinst with value type is only supported in some contexts*/: null);
				_nameTagObject = (((Object)(object)val != (Object)null) ? val.gameObject : null);
				_billboardWasActive = (Object)(object)_billboard != (Object)null && _billboard.activeSelf;
				_speakIconWasActive = (Object)(object)_speakIcon != (Object)null && _speakIcon.activeSelf;
				_nameTagWasActive = (Object)(object)_nameTagObject != (Object)null && _nameTagObject.activeSelf;
			}
			SetInactive(_billboard);
			SetInactive(_speakIcon);
			SetInactive(_nameTagObject);
		}

		private void ShowNameplateObjects()
		{
			if (_uiCaptured)
			{
				if ((Object)(object)_billboard != (Object)null)
				{
					_billboard.SetActive(_billboardWasActive);
				}
				if ((Object)(object)_speakIcon != (Object)null)
				{
					_speakIcon.SetActive(_speakIconWasActive);
				}
				if ((Object)(object)_nameTagObject != (Object)null)
				{
					_nameTagObject.SetActive(_nameTagWasActive);
				}
				_uiCaptured = false;
			}
		}

		private static void SetInactive(GameObject target)
		{
			if ((Object)(object)target != (Object)null && target.activeSelf)
			{
				target.SetActive(false);
			}
		}

		private void ScanAttached()
		{
			if (Time.unscaledTime < _nextScan)
			{
				return;
			}
			_nextScan = Time.unscaledTime + 0.2f;
			HashSet<Renderer> bodyRenderers = GetBodyRenderers();
			HashSet<Renderer> hashSet = new HashSet<Renderer>();
			Renderer[] componentsInChildren = ((Component)_actor).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (!((Object)(object)val == (Object)null) && !bodyRenderers.Contains(val))
				{
					hashSet.Add(val);
					if (!_hiddenRenderers.ContainsKey(val))
					{
						_hiddenRenderers[val] = val.enabled;
					}
					if (val.enabled)
					{
						val.enabled = false;
					}
				}
			}
			_removedRenderers.Clear();
			foreach (KeyValuePair<Renderer, bool> hiddenRenderer in _hiddenRenderers)
			{
				if ((Object)(object)hiddenRenderer.Key == (Object)null || !hashSet.Contains(hiddenRenderer.Key))
				{
					_removedRenderers.Add(hiddenRenderer.Key);
				}
			}
			for (int j = 0; j < _removedRenderers.Count; j++)
			{
				Renderer val2 = _removedRenderers[j];
				if ((Object)(object)val2 != (Object)null && _hiddenRenderers[val2] && !val2.enabled)
				{
					val2.enabled = true;
				}
				_hiddenRenderers.Remove(val2);
			}
			HashSet<Light> hashSet2 = new HashSet<Light>();
			Light[] componentsInChildren2 = ((Component)_actor).GetComponentsInChildren<Light>(true);
			foreach (Light val3 in componentsInChildren2)
			{
				if (!((Object)(object)val3 == (Object)null))
				{
					hashSet2.Add(val3);
					if (!_hiddenLights.ContainsKey(val3))
					{
						_hiddenLights[val3] = ((Behaviour)val3).enabled;
					}
					if (((Behaviour)val3).enabled)
					{
						((Behaviour)val3).enabled = false;
					}
				}
			}
			_removedLights.Clear();
			foreach (KeyValuePair<Light, bool> hiddenLight in _hiddenLights)
			{
				if ((Object)(object)hiddenLight.Key == (Object)null || !hashSet2.Contains(hiddenLight.Key))
				{
					_removedLights.Add(hiddenLight.Key);
				}
			}
			for (int l = 0; l < _removedLights.Count; l++)
			{
				Light val4 = _removedLights[l];
				if ((Object)(object)val4 != (Object)null && _hiddenLights[val4] && !((Behaviour)val4).enabled)
				{
					((Behaviour)val4).enabled = true;
				}
				_hiddenLights.Remove(val4);
			}
		}

		private void RestoreAttachedRenderers()
		{
			foreach (KeyValuePair<Renderer, bool> hiddenRenderer in _hiddenRenderers)
			{
				Renderer key = hiddenRenderer.Key;
				if ((Object)(object)key != (Object)null && hiddenRenderer.Value && !key.enabled)
				{
					key.enabled = true;
				}
			}
			_hiddenRenderers.Clear();
		}

		private void RestoreLights()
		{
			foreach (KeyValuePair<Light, bool> hiddenLight in _hiddenLights)
			{
				Light key = hiddenLight.Key;
				if ((Object)(object)key != (Object)null && hiddenLight.Value && !((Behaviour)key).enabled)
				{
					((Behaviour)key).enabled = true;
				}
			}
			_hiddenLights.Clear();
		}

		private HashSet<Renderer> GetBodyRenderers()
		{
			if (_bodyRenderers != null)
			{
				return _bodyRenderers;
			}
			_bodyRenderers = new HashSet<Renderer>();
			if (PuppetRenderersField == null || (Object)(object)_puppet == (Object)null)
			{
				return _bodyRenderers;
			}
			if (!(PuppetRenderersField.GetValue(_puppet) is Renderer[] array))
			{
				return _bodyRenderers;
			}
			for (int i = 0; i < array.Length; i++)
			{
				if ((Object)(object)array[i] != (Object)null)
				{
					_bodyRenderers.Add(array[i]);
				}
			}
			return _bodyRenderers;
		}

		private static FieldInfo FindField(Type type, string name)
		{
			return type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
		}
	}
}