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<Renderer>(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<int, PovFeed> _feeds = new Dictionary<int, PovFeed>();
private readonly List<int> _orderedIds = new List<int>();
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>();
_canvas.renderMode = (RenderMode)0;
_canvas.sortingOrder = 5000;
CanvasScaler obj = val.AddComponent<CanvasScaler>();
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<RectTransform>();
_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<Camera>();
}
}
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<Player> list = new List<Player>();
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<int> hashSet = new HashSet<int>();
foreach (Player item in list)
{
hashSet.Add(((Object)item).GetInstanceID());
}
List<int> list2 = new List<int>();
foreach (KeyValuePair<int, PovFeed> 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<RectTransform>();
component.sizeDelta = new Vector2((float)num, (float)num2);
Image component2 = val.GetComponent<Image>();
((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<RectTransform>();
component3.anchorMin = Vector2.zero;
component3.anchorMax = Vector2.one;
component3.offsetMin = new Vector2(3f, 3f);
component3.offsetMax = new Vector2(-3f, -3f);
RawImage component4 = val2.GetComponent<RawImage>();
((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<RectTransform>();
component5.anchorMin = Vector2.zero;
component5.anchorMax = Vector2.one;
component5.offsetMin = new Vector2(3f, 3f);
component5.offsetMax = new Vector2(-3f, -3f);
Image component6 = val3.GetComponent<Image>();
((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<RectTransform>();
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<Text>();
component8.font = Resources.GetBuiltinResource<Font>("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<Transform>(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<Renderer>();
}
}
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<Renderer>(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<Canvas>();
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<HintMatch> list = new List<HintMatch>();
Text[] componentsInChildren = ((Component)val3).GetComponentsInChildren<Text>(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<MonoBehaviour>(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<RectTransform>();
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<HintMatch> 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<HintMatch> matches, out RectTransform best, out int bestScore)
{
best = null;
bestScore = 0;
Dictionary<RectTransform, int> dictionary = new Dictionary<RectTransform, int>();
Dictionary<RectTransform, int> dictionary2 = new Dictionary<RectTransform, int>();
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<RectTransform, int> 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<bool> EnabledAtStart;
internal ConfigEntry<KeyCode> ToggleKey;
internal ConfigEntry<int> FeedWidth;
internal ConfigEntry<int> FeedHeight;
internal ConfigEntry<int> TextureWidth;
internal ConfigEntry<int> TextureHeight;
internal ConfigEntry<int> FeedFps;
internal ConfigEntry<float> CameraForwardOffset;
internal ConfigEntry<int> Margin;
internal ConfigEntry<int> Spacing;
internal ConfigEntry<bool> ShowNames;
internal ConfigEntry<string> FeedPosition;
internal ConfigEntry<float> BrightnessBoost;
internal ConfigEntry<float> UndergroundDarken;
internal ConfigEntry<bool> MoveItemControls;
internal ConfigEntry<int> ItemControlsX;
internal ConfigEntry<int> 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<bool>("General", "EnabledAtStart", true, "Show the live POV panels automatically when a lobby is loaded.");
ToggleKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "ToggleKey", (KeyCode)287, "Toggle all LivePOV panels on/off.");
FeedWidth = ((BaseUnityPlugin)this).Config.Bind<int>("Layout", "FeedWidth", 400, "Width of each POV panel at 1920x1080 reference resolution.");
FeedHeight = ((BaseUnityPlugin)this).Config.Bind<int>("Layout", "FeedHeight", 225, "Height of each POV panel at 1920x1080 reference resolution.");
Margin = ((BaseUnityPlugin)this).Config.Bind<int>("Layout", "Margin", 18, "Distance from the edge of the screen.");
Spacing = ((BaseUnityPlugin)this).Config.Bind<int>("Layout", "Spacing", 10, "Space between POV panels.");
ShowNames = ((BaseUnityPlugin)this).Config.Bind<bool>("Layout", "ShowNames", true, "Show the player's name on their POV panel.");
FeedPosition = ((BaseUnityPlugin)this).Config.Bind<string>("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<bool>("HUD", "MoveItemControls", true, "Move the vanilla held-item control hints away from the top-right POV panels.");
ItemControlsX = ((BaseUnityPlugin)this).Config.Bind<int>("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<int>("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<int>("Performance", "TextureWidth", 960, "Internal render width for each POV.");
TextureHeight = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "TextureHeight", 540, "Internal render height for each POV.");
FeedFps = ((BaseUnityPlugin)this).Config.Bind<int>("Performance", "FeedFPS", 30, "Maximum FPS for each mini POV. Lower this if performance drops.");
CameraForwardOffset = ((BaseUnityPlugin)this).Config.Bind<float>("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<float>("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<float>("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<LivePOVManager>().Initialize(this);
((BaseUnityPlugin)this).Logger.LogInfo((object)string.Format("{0} {1} loaded. Press {2} to toggle POV panels.", "LivePOV", "0.1.8", ToggleKey.Value));
}
}
}