using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("LivePOV")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("LivePOV")] [assembly: AssemblyTitle("LivePOV")] [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 LivePOV { internal sealed class LivePOVManager : MonoBehaviour { private sealed class HintMatch { internal RectTransform Rect; internal int Weight; internal HintMatch(RectTransform rect, int weight) { Rect = rect; Weight = weight; } } private sealed class HudMoveState { internal RectTransform Rect; internal Transform Parent; internal int SiblingIndex; internal Vector2 AnchorMin; internal Vector2 AnchorMax; internal Vector2 Pivot; internal Vector2 AnchoredPosition; internal Vector2 SizeDelta; internal Vector3 LocalScale; internal Quaternion LocalRotation; } private sealed class PovFeed { internal readonly RectTransform Panel; private readonly RawImage _image; private readonly Image _brightnessImage; private readonly Text _label; private readonly RenderTexture _texture; private Renderer[] _targetRenderers = (Renderer[])(object)new Renderer[0]; private bool[] _targetRendererStates = new bool[0]; private int _cachedTargetId = int.MinValue; internal Player Target { get; private set; } internal PovFeed(Player target, RectTransform panel, RawImage image, Image brightnessImage, Text label, RenderTexture texture) { Panel = panel; _image = image; _brightnessImage = brightnessImage; _label = label; _texture = texture; SetTarget(target); } internal void SetTarget(Player target) { Target = target; int num = (((Object)(object)target != (Object)null) ? ((Object)target).GetInstanceID() : int.MinValue); if (num != _cachedTargetId) { _cachedTargetId = num; RefreshTargetRenderers(); } } private void RefreshTargetRenderers() { if ((Object)(object)Target == (Object)null) { _targetRenderers = (Renderer[])(object)new Renderer[0]; _targetRendererStates = new bool[0]; return; } try { _targetRenderers = ((Component)Target).GetComponentsInChildren(true); _targetRendererStates = new bool[_targetRenderers.Length]; } catch { _targetRenderers = (Renderer[])(object)new Renderer[0]; _targetRendererStates = new bool[0]; } } internal void SetLabel(string text, bool show) { if (!((Object)(object)_label == (Object)null)) { ((Behaviour)_label).enabled = show; if (show) { _label.text = text; } } } internal void SetDisplayAdjustment(float brightness, float undergroundDarken) { //IL_0073: 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) if (!((Object)(object)_brightnessImage == (Object)null)) { float num = Mathf.Clamp(brightness, 0f, 0.15f); float num2 = Mathf.Clamp(undergroundDarken, 0f, 0.5f); float num3 = num - num2; if (num3 >= 0f) { ((Graphic)_brightnessImage).color = new Color(1f, 1f, 1f, num3); } else { ((Graphic)_brightnessImage).color = new Color(0f, 0f, 0f, 0f - num3); } } } private void HideTargetRenderers() { if (_targetRenderers == null || _targetRenderers.Length == 0) { return; } for (int i = 0; i < _targetRenderers.Length; i++) { Renderer val = _targetRenderers[i]; if (!((Object)(object)val == (Object)null)) { _targetRendererStates[i] = val.enabled; val.enabled = false; } } } private void RestoreTargetRenderers() { if (_targetRenderers == null || _targetRenderers.Length == 0) { return; } for (int i = 0; i < _targetRenderers.Length; i++) { Renderer val = _targetRenderers[i]; if (!((Object)(object)val == (Object)null)) { val.enabled = _targetRendererStates[i]; } } } internal void RenderWithGameCamera(Camera source, float forwardOffset) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004e: 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) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02d4: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: 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_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: 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_00de: 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_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: 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_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0196: Unknown result type (might be due to invalid IL or missing references) //IL_0199: Invalid comparison between Unknown and I4 //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_019e: Invalid comparison between Unknown and I4 //IL_01b8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Target == (Object)null || (Object)(object)source == (Object)null || (Object)(object)_texture == (Object)null) { return; } Transform headTransform = GetHeadTransform(Target); if ((Object)(object)headTransform == (Object)null) { return; } Vector3 position = ((Component)source).transform.position; Quaternion rotation = ((Component)source).transform.rotation; RenderTexture targetTexture = source.targetTexture; Rect rect = source.rect; int cullingMask = source.cullingMask; CameraClearFlags clearFlags = source.clearFlags; Color backgroundColor = source.backgroundColor; float nearClipPlane = source.nearClipPlane; bool useOcclusionCulling = source.useOcclusionCulling; bool allowMSAA = source.allowMSAA; Renderer val = null; bool enabled = false; Renderer[] array = (Renderer[])(object)new Renderer[0]; bool[] array2 = new bool[0]; bool flag = false; RenderTexture active = RenderTexture.active; try { float num = Mathf.Clamp(forwardOffset, 0.02f, 0.35f); Vector3 val2 = headTransform.position + headTransform.forward * num + headTransform.up * 0.02f; ((Component)source).transform.SetPositionAndRotation(val2, headTransform.rotation); source.targetTexture = _texture; source.rect = new Rect(0f, 0f, 1f, 1f); source.nearClipPlane = 0.03f; source.useOcclusionCulling = false; source.allowMSAA = false; int num2 = cullingMask; if ((Object)(object)Player.localPlayer != (Object)null) { num2 |= GetHierarchyLayerMask(((Component)Player.localPlayer).transform); } int num3 = LayerMask.NameToLayer("UI"); if (num3 >= 0) { num2 &= ~(1 << num3); } source.cullingMask = num2; if ((int)clearFlags == 3 || (int)clearFlags == 4) { source.clearFlags = (CameraClearFlags)(((Object)(object)RenderSettings.skybox != (Object)null) ? 1 : 2); source.backgroundColor = backgroundColor; } val = FindLocalBodyRenderer(); if ((Object)(object)val != (Object)null) { enabled = val.enabled; val.enabled = true; } array = GetLocalVisorRenderers(); array2 = new bool[array.Length]; for (int i = 0; i < array.Length; i++) { if (!((Object)(object)array[i] == (Object)null)) { array2[i] = array[i].enabled; array[i].enabled = true; } } HideTargetRenderers(); flag = true; source.Render(); } catch (Exception ex) { Plugin.Log.LogDebug((object)("LivePOV render skipped: " + ex.Message)); } finally { if (flag) { RestoreTargetRenderers(); } if ((Object)(object)val != (Object)null) { val.enabled = enabled; } for (int j = 0; j < array.Length; j++) { if ((Object)(object)array[j] != (Object)null) { array[j].enabled = array2[j]; } } ((Component)source).transform.SetPositionAndRotation(position, rotation); source.targetTexture = targetTexture; source.rect = rect; source.cullingMask = cullingMask; source.clearFlags = clearFlags; source.backgroundColor = backgroundColor; source.nearClipPlane = nearClipPlane; source.useOcclusionCulling = useOcclusionCulling; source.allowMSAA = allowMSAA; RenderTexture.active = active; } } internal void Dispose() { if ((Object)(object)_image != (Object)null) { _image.texture = null; } if ((Object)(object)_texture != (Object)null) { _texture.Release(); Object.Destroy((Object)(object)_texture); } if ((Object)(object)Panel != (Object)null) { Object.Destroy((Object)(object)((Component)Panel).gameObject); } } } private Plugin _plugin; private Canvas _canvas; private RectTransform _root; private readonly Dictionary _feeds = new Dictionary(); private readonly List _orderedIds = new List(); private bool _visible; private float _nextRefresh; private float _nextPovRender; private bool _renderScheduled; private float _nextHudScan; private HudMoveState _movedItemControls; private const float RefreshInterval = 0.75f; private const float HudScanInterval = 0.5f; internal void Initialize(Plugin plugin) { _plugin = plugin; _visible = plugin.EnabledAtStart.Value; CreateCanvas(); } private void CreateCanvas() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Expected O, but got Unknown //IL_00ba: 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_00da: 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) GameObject val = new GameObject("LivePOV_Canvas"); val.transform.SetParent(((Component)this).transform, false); _canvas = val.AddComponent(); _canvas.renderMode = (RenderMode)0; _canvas.sortingOrder = 5000; CanvasScaler obj = val.AddComponent(); obj.uiScaleMode = (ScaleMode)1; obj.referenceResolution = new Vector2(1920f, 1080f); obj.screenMatchMode = (ScreenMatchMode)0; obj.matchWidthOrHeight = 0.5f; GameObject val2 = new GameObject("Feeds", new Type[1] { typeof(RectTransform) }); val2.transform.SetParent(val.transform, false); _root = val2.GetComponent(); _root.anchorMin = Vector2.zero; _root.anchorMax = Vector2.one; _root.offsetMin = Vector2.zero; _root.offsetMax = Vector2.zero; ((Behaviour)_canvas).enabled = _visible; } private void Update() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_plugin == (Object)null) { return; } if (Input.GetKeyDown(_plugin.ToggleKey.Value)) { _visible = !_visible; if ((Object)(object)_canvas != (Object)null) { ((Behaviour)_canvas).enabled = _visible; } } if (_plugin.MoveItemControls.Value && Time.unscaledTime >= _nextHudScan) { _nextHudScan = Time.unscaledTime + 0.5f; TryRelocateItemControls(); } else if (!_plugin.MoveItemControls.Value && _movedItemControls != null) { RestoreItemControls(); } if (Time.unscaledTime >= _nextRefresh) { _nextRefresh = Time.unscaledTime + 0.75f; RefreshPlayers(); } } private void LateUpdate() { if (_visible && _feeds.Count != 0 && !_renderScheduled) { int num = Mathf.Clamp(_plugin.FeedFps.Value, 1, 120); float unscaledTime = Time.unscaledTime; if (!(unscaledTime < _nextPovRender)) { _nextPovRender = unscaledTime + 1f / (float)num; _renderScheduled = true; ((MonoBehaviour)this).StartCoroutine(RenderFeedsAtEndOfFrame()); } } } private IEnumerator RenderFeedsAtEndOfFrame() { yield return (object)new WaitForEndOfFrame(); try { if (!_visible || _feeds.Count == 0) { yield break; } Camera val = null; try { if ((Object)(object)MainCamera.instance != (Object)null) { val = ((Component)MainCamera.instance).GetComponent(); } } catch { } if ((Object)(object)val == (Object)null) { val = Camera.main; } if ((Object)(object)val == (Object)null) { yield break; } for (int i = 0; i < _orderedIds.Count; i++) { if (_feeds.TryGetValue(_orderedIds[i], out var value)) { value.RenderWithGameCamera(val, _plugin.CameraForwardOffset.Value); } } } finally { _renderScheduled = false; } } private void RefreshPlayers() { if ((Object)(object)_root == (Object)null) { return; } List list = new List(); try { if ((Object)(object)PlayerHandler.instance != (Object)null && PlayerHandler.instance.players != null && (Object)(object)Player.localPlayer != (Object)null) { foreach (Player player in PlayerHandler.instance.players) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player == (Object)(object)Player.localPlayer)) { list.Add(player); } } } } catch (Exception ex) { Plugin.Log.LogDebug((object)("LivePOV could not read the current player list yet: " + ex.Message)); return; } HashSet hashSet = new HashSet(); foreach (Player item in list) { hashSet.Add(((Object)item).GetInstanceID()); } List list2 = new List(); foreach (KeyValuePair feed in _feeds) { if (!hashSet.Contains(feed.Key) || (Object)(object)feed.Value.Target == (Object)null) { list2.Add(feed.Key); } } foreach (int item2 in list2) { _feeds[item2].Dispose(); _feeds.Remove(item2); } _orderedIds.Clear(); for (int i = 0; i < list.Count; i++) { Player val = list[i]; int instanceID = ((Object)val).GetInstanceID(); _orderedIds.Add(instanceID); if (!_feeds.TryGetValue(instanceID, out var value)) { value = CreateFeed(val); _feeds.Add(instanceID, value); } value.SetTarget(val); value.SetLabel(GetPlayerName(val, i + 1), _plugin.ShowNames.Value); value.SetDisplayAdjustment(_plugin.BrightnessBoost.Value, IsUndergroundScene() ? _plugin.UndergroundDarken.Value : 0f); } LayoutFeeds(); } private PovFeed CreateFeed(Player target) { //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: Expected O, but got Unknown //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: 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_0142: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0162: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01d8: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0213: Unknown result type (might be due to invalid IL or missing references) //IL_023a: 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_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0289: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02c4: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_0350: Expected O, but got Unknown int num = Mathf.Clamp(_plugin.FeedWidth.Value, 160, 960); int num2 = Mathf.Clamp(_plugin.FeedHeight.Value, 90, 540); int num3 = Mathf.Clamp(_plugin.TextureWidth.Value, 160, 1920); int num4 = Mathf.Clamp(_plugin.TextureHeight.Value, 90, 1080); GameObject val = new GameObject("LivePOV_Panel", new Type[2] { typeof(RectTransform), typeof(Image) }); val.transform.SetParent((Transform)(object)_root, false); RectTransform component = val.GetComponent(); component.sizeDelta = new Vector2((float)num, (float)num2); Image component2 = val.GetComponent(); ((Graphic)component2).color = new Color(0f, 0f, 0f, 0.92f); ((Graphic)component2).raycastTarget = false; GameObject val2 = new GameObject("View", new Type[2] { typeof(RectTransform), typeof(RawImage) }); val2.transform.SetParent(val.transform, false); RectTransform component3 = val2.GetComponent(); component3.anchorMin = Vector2.zero; component3.anchorMax = Vector2.one; component3.offsetMin = new Vector2(3f, 3f); component3.offsetMax = new Vector2(-3f, -3f); RawImage component4 = val2.GetComponent(); ((Graphic)component4).raycastTarget = false; ((Graphic)component4).color = Color.white; GameObject val3 = new GameObject("BrightnessLift", new Type[2] { typeof(RectTransform), typeof(Image) }); val3.transform.SetParent(val.transform, false); RectTransform component5 = val3.GetComponent(); component5.anchorMin = Vector2.zero; component5.anchorMax = Vector2.one; component5.offsetMin = new Vector2(3f, 3f); component5.offsetMax = new Vector2(-3f, -3f); Image component6 = val3.GetComponent(); ((Graphic)component6).color = new Color(1f, 1f, 1f, 0f); ((Graphic)component6).raycastTarget = false; GameObject val4 = new GameObject("Name", new Type[2] { typeof(RectTransform), typeof(Text) }); val4.transform.SetParent(val.transform, false); RectTransform component7 = val4.GetComponent(); component7.anchorMin = new Vector2(0f, 1f); component7.anchorMax = new Vector2(1f, 1f); component7.pivot = new Vector2(0.5f, 1f); component7.sizeDelta = new Vector2(0f, 28f); component7.anchoredPosition = new Vector2(0f, -7f); Text component8 = val4.GetComponent(); component8.font = Resources.GetBuiltinResource("Arial.ttf"); component8.fontSize = 18; component8.alignment = (TextAnchor)0; ((Graphic)component8).color = Color.white; component8.horizontalOverflow = (HorizontalWrapMode)1; component8.verticalOverflow = (VerticalWrapMode)1; ((Graphic)component8).raycastTarget = false; RenderTexture val5 = new RenderTexture(num3, num4, 24, (RenderTextureFormat)0); ((Object)val5).name = "LivePOV_RT_" + ((Object)target).GetInstanceID(); ((Texture)val5).filterMode = (FilterMode)1; ((Texture)val5).wrapMode = (TextureWrapMode)1; val5.useMipMap = false; val5.autoGenerateMips = false; val5.antiAliasing = 1; val5.Create(); component4.texture = (Texture)(object)val5; return new PovFeed(target, component, component4, component6, component8, val5); } private void LayoutFeeds() { //IL_024f: Unknown result type (might be due to invalid IL or missing references) //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0137: 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_0167: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) int count = _orderedIds.Count; if (count == 0) { return; } int num = Mathf.Clamp(_plugin.FeedWidth.Value, 160, 960); int num2 = Mathf.Clamp(_plugin.FeedHeight.Value, 90, 540); int num3 = Mathf.Clamp(_plugin.Margin.Value, 0, 200); int num4 = Mathf.Clamp(_plugin.Spacing.Value, 0, 100); if ((_plugin.FeedPosition.Value ?? "Top").Trim().Equals("TopRight", StringComparison.OrdinalIgnoreCase)) { int num5 = Mathf.Max(1, Mathf.FloorToInt((1080f - (float)num3 * 2f + (float)num4) / (float)(num2 + num4))); for (int i = 0; i < count; i++) { if (_feeds.TryGetValue(_orderedIds[i], out var value)) { int num6 = i / num5; int num7 = i % num5; value.Panel.anchorMin = new Vector2(1f, 1f); value.Panel.anchorMax = new Vector2(1f, 1f); value.Panel.pivot = new Vector2(1f, 1f); value.Panel.sizeDelta = new Vector2((float)num, (float)num2); value.Panel.anchoredPosition = new Vector2((float)(-num3 - num6 * (num + num4)), (float)(-num3 - num7 * (num2 + num4))); } } return; } int num8 = Mathf.Max(1, Mathf.FloorToInt((1920f - (float)num3 * 2f + (float)num4) / (float)(num + num4))); for (int j = 0; j < count; j++) { if (_feeds.TryGetValue(_orderedIds[j], out var value2)) { int num9 = j / num8; int num10 = j % num8; int num11 = num9 * num8; int num12 = count - num11; int num13 = Mathf.Min(num8, num12); float num14 = (0f - (float)(num13 * num + Mathf.Max(0, num13 - 1) * num4)) * 0.5f + (float)num * 0.5f; value2.Panel.anchorMin = new Vector2(0.5f, 1f); value2.Panel.anchorMax = new Vector2(0.5f, 1f); value2.Panel.pivot = new Vector2(0.5f, 1f); value2.Panel.sizeDelta = new Vector2((float)num, (float)num2); value2.Panel.anchoredPosition = new Vector2(num14 + (float)(num10 * (num + num4)), (float)(-num3 - num9 * (num2 + num4))); } } } private static Transform GetHeadTransform(Player player) { if ((Object)(object)player == (Object)null) { return null; } try { if (player.refs != null && (Object)(object)player.refs.headPos != (Object)null) { return player.refs.headPos; } } catch { } try { object memberValue = GetMemberValue(GetMemberValue(player, "refs"), "headPos"); return (Transform)((memberValue is Transform) ? memberValue : null); } catch { return null; } } private static string GetPlayerName(Player player, int fallbackIndex) { try { object memberValue = GetMemberValue(GetMemberValue(GetMemberValue(GetMemberValue(player, "refs"), "view"), "Owner"), "NickName"); if (memberValue != null) { string text = memberValue.ToString(); if (!string.IsNullOrWhiteSpace(text)) { return text; } } } catch { } return "Player " + fallbackIndex; } private static object GetMemberValue(object instance, string name) { if (instance == null) { return null; } Type type = instance.GetType(); FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field.GetValue(instance); } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { return property.GetValue(instance, null); } return null; } private static int GetHierarchyLayerMask(Transform root) { if ((Object)(object)root == (Object)null) { return 0; } int num = 0; Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren(true); foreach (Transform val in componentsInChildren) { if (!((Object)(object)val == (Object)null)) { int layer = ((Component)val).gameObject.layer; if (layer >= 0 && layer < 32) { num |= 1 << layer; } } } return num; } private static Renderer FindLocalBodyRenderer() { try { if ((Object)(object)Player.localPlayer == (Object)null) { return null; } Transform val = ((Component)Player.localPlayer).transform.Find("CharacterModel/BodyRenderer"); if ((Object)(object)val != (Object)null) { return ((Component)val).GetComponent(); } } catch { } return null; } private static Renderer[] GetLocalVisorRenderers() { try { if ((Object)(object)Player.localPlayer != (Object)null && Player.localPlayer.refs != null && (Object)(object)Player.localPlayer.refs.visor != (Object)null) { return ((Component)Player.localPlayer.refs.visor).GetComponentsInChildren(true); } } catch { } return (Renderer[])(object)new Renderer[0]; } private static bool IsUndergroundScene() { //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) try { Scene activeScene = SceneManager.GetActiveScene(); string text = ((Scene)(ref activeScene)).name ?? string.Empty; if (text.IndexOf("Factory", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Mines", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Mine", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Harbour", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Harbor", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("OldWorld", StringComparison.OrdinalIgnoreCase) >= 0 || text.IndexOf("Underground", StringComparison.OrdinalIgnoreCase) >= 0) { return true; } try { Type type = typeof(Player).Assembly.GetType("Level"); if (type != null) { return Object.FindObjectOfType(type) != (Object)null; } } catch { } return false; } catch { return false; } } private void TryRelocateItemControls() { //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0219: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_0231: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_023d: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0259: Unknown result type (might be due to invalid IL or missing references) //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_0293: Unknown result type (might be due to invalid IL or missing references) try { if (_movedItemControls != null) { if (!((Object)(object)_movedItemControls.Rect == (Object)null)) { ApplyMovedItemControlsPosition(_movedItemControls.Rect); return; } _movedItemControls = null; } Canvas[] array = Object.FindObjectsOfType(); RectTransform val = null; Canvas val2 = null; int num = 0; foreach (Canvas val3 in array) { if ((Object)(object)val3 == (Object)null || (Object)(object)val3 == (Object)(object)_canvas || !((Behaviour)val3).isActiveAndEnabled) { continue; } List list = new List(); Text[] componentsInChildren = ((Component)val3).GetComponentsInChildren(true); foreach (Text val4 in componentsInChildren) { if (!((Object)(object)val4 == (Object)null) && ((Component)val4).gameObject.activeInHierarchy) { int num2 = CountItemControlKeywords(val4.text); if (num2 > 0) { AddHintMatchIfOnRight(list, ((Graphic)val4).rectTransform, num2, val3); } } } MonoBehaviour[] componentsInChildren2 = ((Component)val3).GetComponentsInChildren(true); foreach (MonoBehaviour val5 in componentsInChildren2) { if ((Object)(object)val5 == (Object)null || !((Component)val5).gameObject.activeInHierarchy || !(((object)val5).GetType().FullName ?? string.Empty).StartsWith("TMPro.", StringComparison.Ordinal)) { continue; } int num3 = CountItemControlKeywords(GetReflectedText((Component)(object)val5)); if (num3 > 0) { RectTransform component = ((Component)val5).GetComponent(); if ((Object)(object)component != (Object)null) { AddHintMatchIfOnRight(list, component, num3, val3); } } } if (list.Count != 0) { FindBestHintContainer(val3, list, out var best, out var bestScore); if ((Object)(object)best != (Object)null && bestScore > num) { val = best; val2 = val3; num = bestScore; } } } if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && num >= 180) { _movedItemControls = new HudMoveState { Rect = val, Parent = ((Transform)val).parent, SiblingIndex = ((Transform)val).GetSiblingIndex(), AnchorMin = val.anchorMin, AnchorMax = val.anchorMax, Pivot = val.pivot, AnchoredPosition = val.anchoredPosition, SizeDelta = val.sizeDelta, LocalScale = ((Transform)val).localScale, LocalRotation = ((Transform)val).localRotation }; Rect rect = val.rect; Vector2 size = ((Rect)(ref rect)).size; ((Transform)val).SetParent(((Component)val2).transform, false); if (size.x > 1f && size.y > 1f) { val.sizeDelta = size; } ((Transform)val).SetAsLastSibling(); ApplyMovedItemControlsPosition(val); Plugin.Log.LogInfo((object)("LivePOV moved held-item control hints to the lower-left HUD area: " + ((Object)val).name)); } } catch (Exception ex) { Plugin.Log.LogDebug((object)("LivePOV HUD relocation skipped: " + ex.Message)); } } private void AddHintMatchIfOnRight(List matches, RectTransform rect, int weight, Canvas canvas) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)rect == (Object)null) && !(RectTransformUtility.WorldToScreenPoint(((int)canvas.renderMode == 0) ? null : canvas.worldCamera, ((Transform)rect).position).x < (float)Screen.width * 0.55f)) { matches.Add(new HintMatch(rect, weight)); } } private static int CountItemControlKeywords(string text) { if (string.IsNullOrEmpty(text)) { return 0; } string text2 = text.ToLowerInvariant(); string[] array = new string[15] { "drop", "use", "throw", "aim", "zoom", "record", "film", "flash", "place", "pick up", "pickup", "charge", "rotate", "switch", "toggle" }; int num = 0; for (int i = 0; i < array.Length; i++) { if (text2.IndexOf(array[i], StringComparison.Ordinal) >= 0) { num++; } } return num; } private static string GetReflectedText(Component component) { try { if ((Object)(object)component == (Object)null) { return string.Empty; } PropertyInfo property = ((object)component).GetType().GetProperty("text", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); object obj = ((property != null) ? property.GetValue(component, null) : null); return (obj != null) ? obj.ToString() : string.Empty; } catch { return string.Empty; } } private static void FindBestHintContainer(Canvas canvas, List matches, out RectTransform best, out int bestScore) { best = null; bestScore = 0; Dictionary dictionary = new Dictionary(); Dictionary dictionary2 = new Dictionary(); for (int i = 0; i < matches.Count; i++) { HintMatch hintMatch = matches[i]; RectTransform val = (RectTransform)(((Object)(object)hintMatch.Rect != (Object)null) ? /*isinst with value type is only supported in some contexts*/: null); while ((Object)(object)val != (Object)null && (Object)(object)val != (Object)(object)((Component)canvas).transform) { if (!IsExcludedHudContainer((((Object)val).name ?? string.Empty).ToLowerInvariant()) && IsReasonableHudContainer(val, canvas)) { dictionary.TryGetValue(val, out var value); value = (dictionary[val] = value + hintMatch.Weight * 100); dictionary2.TryGetValue(val, out var value2); dictionary2[val] = value2 + 1; } Transform parent = ((Transform)val).parent; val = (RectTransform)(object)((parent is RectTransform) ? parent : null); } } foreach (KeyValuePair item in dictionary) { RectTransform key = item.Key; int value3 = item.Value; int num2 = (dictionary2.ContainsKey(key) ? dictionary2[key] : 0); string text = (((Object)key).name ?? string.Empty).ToLowerInvariant(); value3 += num2 * 35; if (text.Contains("item")) { value3 += 80; } if (text.Contains("control")) { value3 += 100; } if (text.Contains("hint")) { value3 += 100; } if (text.Contains("action")) { value3 += 60; } if (text.Contains("input")) { value3 += 40; } if (value3 > bestScore || (value3 == bestScore && (Object)(object)best != (Object)null && RectArea(key) < RectArea(best))) { best = key; bestScore = value3; } } } private static bool IsExcludedHudContainer(string name) { if (!name.Contains("inventory") && !name.Contains("hotbar") && !name.Contains("oxygen") && !name.Contains("stamina") && !name.Contains("health") && !name.Contains("status") && !name.Contains("chat")) { return name.Contains("nameplate"); } return true; } private static bool IsReasonableHudContainer(RectTransform rect, Canvas canvas) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_0039: 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_0051: Unknown result type (might be due to invalid IL or missing references) try { Vector3[] array = (Vector3[])(object)new Vector3[4]; rect.GetWorldCorners(array); Camera obj = (((int)canvas.renderMode == 0) ? null : canvas.worldCamera); Vector2 val = RectTransformUtility.WorldToScreenPoint(obj, array[0]); Vector2 val2 = RectTransformUtility.WorldToScreenPoint(obj, array[2]); float num = Mathf.Abs(val2.x - val.x); float num2 = Mathf.Abs(val2.y - val.y); if (num > (float)Screen.width * 0.65f || num2 > (float)Screen.height * 0.65f) { return false; } } catch { } return true; } private static float RectArea(RectTransform rect) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)rect == (Object)null) { return float.MaxValue; } Rect rect2 = rect.rect; Vector2 size = ((Rect)(ref rect2)).size; return Mathf.Abs(size.x * size.y); } private void ApplyMovedItemControlsPosition(RectTransform rect) { //IL_000b: 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_0021: 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) if (!((Object)(object)rect == (Object)null)) { rect.anchorMin = Vector2.zero; rect.anchorMax = Vector2.zero; rect.pivot = Vector2.zero; rect.anchoredPosition = new Vector2((float)Mathf.Clamp(_plugin.ItemControlsX.Value, 0, 1800), (float)Mathf.Clamp(_plugin.ItemControlsY.Value, 0, 1000)); } } private void RestoreItemControls() { //IL_0072: 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_0094: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) HudMoveState movedItemControls = _movedItemControls; _movedItemControls = null; if (movedItemControls == null || (Object)(object)movedItemControls.Rect == (Object)null || (Object)(object)movedItemControls.Parent == (Object)null) { return; } try { ((Transform)movedItemControls.Rect).SetParent(movedItemControls.Parent, false); ((Transform)movedItemControls.Rect).SetSiblingIndex(Mathf.Clamp(movedItemControls.SiblingIndex, 0, Mathf.Max(0, movedItemControls.Parent.childCount - 1))); movedItemControls.Rect.anchorMin = movedItemControls.AnchorMin; movedItemControls.Rect.anchorMax = movedItemControls.AnchorMax; movedItemControls.Rect.pivot = movedItemControls.Pivot; movedItemControls.Rect.anchoredPosition = movedItemControls.AnchoredPosition; movedItemControls.Rect.sizeDelta = movedItemControls.SizeDelta; ((Transform)movedItemControls.Rect).localScale = movedItemControls.LocalScale; ((Transform)movedItemControls.Rect).localRotation = movedItemControls.LocalRotation; } catch { } } private void OnDestroy() { RestoreItemControls(); foreach (PovFeed value in _feeds.Values) { value.Dispose(); } _feeds.Clear(); _orderedIds.Clear(); } } [BepInPlugin("andre.livepov", "LivePOV", "0.1.8")] public sealed class Plugin : BaseUnityPlugin { public const string PluginGuid = "andre.livepov"; public const string PluginName = "LivePOV"; public const string PluginVersion = "0.1.8"; internal static ManualLogSource Log; internal ConfigEntry EnabledAtStart; internal ConfigEntry ToggleKey; internal ConfigEntry FeedWidth; internal ConfigEntry FeedHeight; internal ConfigEntry TextureWidth; internal ConfigEntry TextureHeight; internal ConfigEntry FeedFps; internal ConfigEntry CameraForwardOffset; internal ConfigEntry Margin; internal ConfigEntry Spacing; internal ConfigEntry ShowNames; internal ConfigEntry FeedPosition; internal ConfigEntry BrightnessBoost; internal ConfigEntry UndergroundDarken; internal ConfigEntry MoveItemControls; internal ConfigEntry ItemControlsX; internal ConfigEntry ItemControlsY; private void Awake() { //IL_026d: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) //IL_0278: Expected O, but got Unknown //IL_029e: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; EnabledAtStart = ((BaseUnityPlugin)this).Config.Bind("General", "EnabledAtStart", true, "Show the live POV panels automatically when a lobby is loaded."); ToggleKey = ((BaseUnityPlugin)this).Config.Bind("General", "ToggleKey", (KeyCode)287, "Toggle all LivePOV panels on/off."); FeedWidth = ((BaseUnityPlugin)this).Config.Bind("Layout", "FeedWidth", 400, "Width of each POV panel at 1920x1080 reference resolution."); FeedHeight = ((BaseUnityPlugin)this).Config.Bind("Layout", "FeedHeight", 225, "Height of each POV panel at 1920x1080 reference resolution."); Margin = ((BaseUnityPlugin)this).Config.Bind("Layout", "Margin", 18, "Distance from the edge of the screen."); Spacing = ((BaseUnityPlugin)this).Config.Bind("Layout", "Spacing", 10, "Space between POV panels."); ShowNames = ((BaseUnityPlugin)this).Config.Bind("Layout", "ShowNames", true, "Show the player's name on their POV panel."); FeedPosition = ((BaseUnityPlugin)this).Config.Bind("Layout", "Position", "TopRight", "Where POV panels are placed. Supported values: Top or TopRight. TopRight puts the feeds back in the corner."); MoveItemControls = ((BaseUnityPlugin)this).Config.Bind("HUD", "MoveItemControls", true, "Move the vanilla held-item control hints away from the top-right POV panels."); ItemControlsX = ((BaseUnityPlugin)this).Config.Bind("HUD", "ItemControlsX", 55, "Horizontal position for the moved item-control hints, measured from the bottom-left at 1920x1080 reference resolution."); ItemControlsY = ((BaseUnityPlugin)this).Config.Bind("HUD", "ItemControlsY", 190, "Vertical position for the moved item-control hints. 190 places them just above the oxygen area on the default HUD."); TextureWidth = ((BaseUnityPlugin)this).Config.Bind("Performance", "TextureWidth", 960, "Internal render width for each POV."); TextureHeight = ((BaseUnityPlugin)this).Config.Bind("Performance", "TextureHeight", 540, "Internal render height for each POV."); FeedFps = ((BaseUnityPlugin)this).Config.Bind("Performance", "FeedFPS", 30, "Maximum FPS for each mini POV. Lower this if performance drops."); CameraForwardOffset = ((BaseUnityPlugin)this).Config.Bind("Camera", "ForwardOffset", 0.18f, "Moves the POV camera slightly in front of the remote player's head to avoid seeing inside their face model."); BrightnessBoost = ((BaseUnityPlugin)this).Config.Bind("Display", "BrightnessBoost", 0f, "Optional brightness lift for the POV panels. 0 = no lift. This is mainly useful on the surface/lobby."); UndergroundDarken = ((BaseUnityPlugin)this).Config.Bind("Display", "UndergroundDarken", 0.2f, "Darkens POV panels only in Old World/underground scenes to compensate for the game camera exposure being too bright during manual POV renders. 0 = off, 0.20 = recommended."); GameObject val = new GameObject("LivePOV_Manager"); Object.DontDestroyOnLoad((Object)val); val.AddComponent().Initialize(this); ((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Press {2} to toggle POV panels.", "LivePOV", "0.1.8", ToggleKey.Value)); } } }