using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.RegularExpressions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using TMPro;
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("BetterPlayerDistance")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("High Performance Distance Display")]
[assembly: AssemblyFileVersion("0.1.15.0")]
[assembly: AssemblyInformationalVersion("0.1.15+1ab1609b58ebf16f635f7263a765678f8834176e")]
[assembly: AssemblyProduct("BetterPlayerDistance")]
[assembly: AssemblyTitle("BetterPlayerDistance")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.1.15.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.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 BetterPlayerDistance
{
public enum TriggerModeEnum
{
Toggle,
Hold,
AlwaysOn
}
public static class Configuration
{
public static ConfigEntry<bool> ShowName;
public static ConfigEntry<bool> ShowDistance;
public static ConfigEntry<KeyCode> ToggleKey;
public static ConfigEntry<TriggerModeEnum> TriggerMode;
public static ConfigEntry<float> ToggleDuration;
public static ConfigEntry<float> HoldKeepDuration;
public static ConfigEntry<float> MinDistance;
public static ConfigEntry<float> MaxDistance;
public static ConfigEntry<float> NameFontSize;
public static ConfigEntry<float> DistFontSize;
public static ConfigEntry<float> GlobalOpacity;
public const float FixedShadowSpread = 1.5f;
public const float FixedShadowAlpha = 0.8f;
public const bool FixedHighQuality = false;
public static readonly Color FixedShadowColor = new Color(0.267f, 0.275f, 0.216f, 1f);
public static ConfigEntry<bool> DebugMode;
public static ConfigEntry<KeyCode> DebugMenuKey;
public static ConfigEntry<bool> DisableTMPWarnings;
private const string CAT_BASIC = "1. 基础 (Basic)";
private const string CAT_UI = "2. 界面 (UI)";
private const string CAT_DEBUG = "3. 调试 (Debug)";
public static void Initialize(ConfigFile config)
{
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_003d: Expected O, but got Unknown
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Expected O, but got Unknown
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00ad: Expected O, but got Unknown
//IL_0111: Unknown result type (might be due to invalid IL or missing references)
//IL_011b: Expected O, but got Unknown
//IL_0149: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Expected O, but got Unknown
//IL_0181: Unknown result type (might be due to invalid IL or missing references)
//IL_018b: Expected O, but got Unknown
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
//IL_01c3: Expected O, but got Unknown
//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
//IL_01fb: Expected O, but got Unknown
ToggleKey = config.Bind<KeyCode>("1. 基础 (Basic)", "快捷键 (Hotkey)", (KeyCode)99, "显示/隐藏玩家标签的按键(常显模式下忽略)。\nToggle player labels on/off (ignored in AlwaysOn mode).");
TriggerMode = config.Bind<TriggerModeEnum>("1. 基础 (Basic)", "显示模式 (Display Mode)", TriggerModeEnum.Hold, new ConfigDescription("Hold=按住显示;Toggle=切换开关;AlwaysOn=常显(始终显示所有在场玩家)。\nHold = press to show; Toggle = press to switch; AlwaysOn = always display every in-game player.", (AcceptableValueBase)null, Array.Empty<object>()));
ToggleDuration = config.Bind<float>("1. 基础 (Basic)", "切换显示时长 (Toggle Duration)", 10f, new ConfigDescription("Toggle 模式下按一次后保持显示的秒数。\nHow many seconds labels stay visible after a single press in Toggle mode.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(10f, 9999f), Array.Empty<object>()));
HoldKeepDuration = config.Bind<float>("1. 基础 (Basic)", "松手保持时长 (Hold Release Linger)", 1f, new ConfigDescription("Hold 模式下松开按键后继续显示的秒数。\nHow many extra seconds labels linger after the key is released in Hold mode.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10f), Array.Empty<object>()));
ShowName = config.Bind<bool>("2. 界面 (UI)", "显示名称 (Show Name)", true, "是否显示玩家名字。\nWhether to display the player name.");
ShowDistance = config.Bind<bool>("2. 界面 (UI)", "显示距离 (Show Distance)", true, "是否显示距离数值。\nWhether to display the distance number.");
MinDistance = config.Bind<float>("2. 界面 (UI)", "最小显示距离 (Min Display Distance)", 15f, new ConfigDescription("小于此距离不显示(米)。\nPlayers closer than this distance are hidden (meters).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 50f), Array.Empty<object>()));
MaxDistance = config.Bind<float>("2. 界面 (UI)", "最大显示距离 (Max Display Distance)", 1000f, new ConfigDescription("超过此距离不显示(米)。\nPlayers farther than this distance are hidden (meters).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(50f, 1500f), Array.Empty<object>()));
NameFontSize = config.Bind<float>("2. 界面 (UI)", "名字字号 (Name Font Size)", 16f, new ConfigDescription("玩家名字字体大小。\nFont size for the player name.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(9f, 60f), Array.Empty<object>()));
DistFontSize = config.Bind<float>("2. 界面 (UI)", "距离字号 (Distance Font Size)", 17f, new ConfigDescription("距离数值字体大小。\nFont size for the distance number.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(9f, 60f), Array.Empty<object>()));
GlobalOpacity = config.Bind<float>("2. 界面 (UI)", "整体透明度 (Global Opacity)", 0.85f, new ConfigDescription("整体不透明度 (0-1)。\nOverall opacity (0-1).", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 1f), Array.Empty<object>()));
DebugMode = config.Bind<bool>("3. 调试 (Debug)", "启用调试工具 (Enable Debug Tools)", true, "Insert 键呼出调试控制台。\nPress Insert to summon the debug console.");
DebugMenuKey = config.Bind<KeyCode>("3. 调试 (Debug)", "调试菜单键 (Debug Menu Key)", (KeyCode)277, "打开调试控制台的按键。\nKey used to open the debug console.");
DisableTMPWarnings = config.Bind<bool>("3. 调试 (Debug)", "禁用全局TMP缺字警告 (Disable TMP Missing-Glyph Warnings)", true, "开启后将禁止 TextMeshPro 向控制台输出缺字警告,可显著解决特殊字符导致的掉帧问题(开发者请关闭)。\nWhen on, suppresses TextMeshPro missing-glyph warnings to avoid console spam and frame drops (developers should disable this).");
}
}
public class OverlayManager
{
private Canvas _canvas;
private GameObject _labelPrefab;
private Transform _canvasTransform;
private List<TMP_FontAsset> _availableFonts = new List<TMP_FontAsset>();
private int _currentFontIndex;
private TMP_FontAsset _currentFont;
private readonly Dictionary<int, PlayerLabel> _activeLabels = new Dictionary<int, PlayerLabel>();
private bool _shouldShowLabels;
private float _hideTimeTimestamp;
private bool _initialized;
private float _lastGlobalOpacity = -1f;
private bool _lastDisableWarnings = true;
private TriggerModeEnum _lastTriggerMode;
private float _nextFontCheckTime;
private bool _isUsingFallbackFont;
public int ActiveCount => _activeLabels.Count;
public string CurrentFontName
{
get
{
if (!((Object)(object)_currentFont != (Object)null))
{
return "None";
}
return ((Object)_currentFont).name;
}
}
public OverlayManager()
{
SceneManager.sceneLoaded += OnSceneLoaded;
}
public void Dispose()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
ClearAllLabels();
if ((Object)(object)_canvas != (Object)null)
{
Object.Destroy((Object)(object)((Component)_canvas).gameObject);
}
}
public void TryInitialize()
{
if (_initialized)
{
return;
}
try
{
CreateCanvasSystem();
_initialized = true;
Plugin.Log.LogInfo((object)"OverlayManager: Initialized.");
}
catch (Exception arg)
{
Plugin.Log.LogError((object)$"Init Failed: {arg}");
}
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
ClearAllLabels();
_availableFonts.Clear();
_initialized = false;
}
private void ClearAllLabels()
{
foreach (PlayerLabel value in _activeLabels.Values)
{
value.Destroy();
}
_activeLabels.Clear();
}
public void UpdateInput()
{
if (!_initialized || (Object)(object)_canvas == (Object)null)
{
TryInitialize();
}
else
{
HandleInput();
}
}
public void LateUpdate()
{
if (Configuration.ShowName == null || Configuration.ShowDistance == null)
{
return;
}
if (!Configuration.ShowName.Value && !Configuration.ShowDistance.Value)
{
if (_activeLabels.Count > 0)
{
ClearAllLabels();
}
}
else
{
if (!_initialized || (Object)(object)_canvas == (Object)null)
{
return;
}
if (Configuration.DisableTMPWarnings != null && _lastDisableWarnings != Configuration.DisableTMPWarnings.Value)
{
ApplyTMPSettings();
_lastDisableWarnings = Configuration.DisableTMPWarnings.Value;
}
if (_isUsingFallbackFont && Time.time > _nextFontCheckTime)
{
_nextFontCheckTime = Time.time + 1f;
TryFindBetterFont();
}
bool flag = Mathf.Abs(_lastGlobalOpacity - Configuration.GlobalOpacity.Value) > 0.01f;
foreach (int item in _activeLabels.Keys.ToList())
{
PlayerLabel playerLabel = _activeLabels[item];
if (!playerLabel.IsValid())
{
playerLabel.SetVisible(visible: false);
continue;
}
if (flag)
{
playerLabel.RefreshStyle();
}
playerLabel.UpdateState(_shouldShowLabels);
}
if (flag)
{
_lastGlobalOpacity = Configuration.GlobalOpacity.Value;
}
}
}
public void RegisterCharacter(Character c)
{
if (!_initialized)
{
TryInitialize();
}
if (!((Object)(object)c == (Object)null) && !((Object)(object)c == (Object)(object)Character.localCharacter))
{
string text = Tracking.ExtractDisplayName(((Object)c).name);
if (!(text == "Bot"))
{
Transform val = ((Component)c).transform.Find("Scout/Misc/CharacterLight");
Transform trackTarget = (((Object)(object)val != (Object)null) ? val : ((Component)c).transform);
RegisterGenericTarget(((Component)c).gameObject, trackTarget, text);
}
}
}
public void RegisterFakeTarget(GameObject root, string customName)
{
if (!_initialized)
{
TryInitialize();
}
if (!((Object)(object)root == (Object)null))
{
Transform val = root.transform.Find("Scout/Misc/CharacterLight");
Transform trackTarget = (((Object)(object)val != (Object)null) ? val : root.transform);
RegisterGenericTarget(root, trackTarget, customName);
}
}
private void RegisterGenericTarget(GameObject owner, Transform trackTarget, string displayName)
{
int instanceID = ((Object)owner).GetInstanceID();
if (!_activeLabels.ContainsKey(instanceID))
{
if ((Object)(object)_currentFont == (Object)null)
{
InitializeFonts();
}
GameObject val = Object.Instantiate<GameObject>(_labelPrefab, _canvasTransform);
val.SetActive(true);
SetLayerRecursively(val, 5);
PlayerLabel value = new PlayerLabel(trackTarget, val, _currentFont, displayName);
_activeLabels.Add(instanceID, value);
}
}
public void UnregisterCharacter(GameObject owner)
{
if (!((Object)(object)owner == (Object)null))
{
int instanceID = ((Object)owner).GetInstanceID();
if (_activeLabels.TryGetValue(instanceID, out var value))
{
value.Destroy();
_activeLabels.Remove(instanceID);
}
}
}
public void UnregisterTarget(GameObject owner)
{
UnregisterCharacter(owner);
}
public void CycleFont(int direction)
{
if (_availableFonts.Count == 0)
{
InitializeFonts();
}
if (_availableFonts.Count == 0)
{
return;
}
_currentFontIndex += direction;
if (_currentFontIndex >= _availableFonts.Count)
{
_currentFontIndex = 0;
}
if (_currentFontIndex < 0)
{
_currentFontIndex = _availableFonts.Count - 1;
}
_currentFont = _availableFonts[_currentFontIndex];
_isUsingFallbackFont = false;
foreach (PlayerLabel value in _activeLabels.Values)
{
value.SetFont(_currentFont);
}
Plugin.Log.LogInfo((object)("Switched Font to: " + ((Object)_currentFont).name));
}
private void HandleInput()
{
//IL_006a: Unknown result type (might be due to invalid IL or missing references)
//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
//IL_0115: Unknown result type (might be due to invalid IL or missing references)
if (Configuration.TriggerMode == null)
{
return;
}
TriggerModeEnum value = Configuration.TriggerMode.Value;
if (value != _lastTriggerMode)
{
_hideTimeTimestamp = 0f;
_shouldShowLabels = false;
_lastTriggerMode = value;
Plugin.Log.LogInfo((object)$"Mode changed to {value}, state reset.");
}
switch (value)
{
case TriggerModeEnum.AlwaysOn:
_shouldShowLabels = true;
return;
case TriggerModeEnum.Toggle:
if (Configuration.ToggleKey != null && Input.GetKeyDown(Configuration.ToggleKey.Value))
{
float num = ((Configuration.ToggleDuration != null) ? Configuration.ToggleDuration.Value : 10f);
if (Time.time < _hideTimeTimestamp)
{
_hideTimeTimestamp = Time.time;
}
else
{
_hideTimeTimestamp = Time.time + num;
}
}
_shouldShowLabels = Time.time < _hideTimeTimestamp;
return;
}
float num2 = ((Configuration.HoldKeepDuration != null) ? Configuration.HoldKeepDuration.Value : 1f);
if (Configuration.ToggleKey != null)
{
if (Input.GetKey(Configuration.ToggleKey.Value))
{
_hideTimeTimestamp = Time.time + num2 + 0.1f;
}
else if (Input.GetKeyUp(Configuration.ToggleKey.Value))
{
_hideTimeTimestamp = Time.time + num2;
}
}
_shouldShowLabels = Time.time < _hideTimeTimestamp;
}
private void CreateCanvasSystem()
{
//IL_0020: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Expected O, but got Unknown
//IL_0072: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)_canvas != (Object)null))
{
ApplyTMPSettings();
InitializeFonts();
GameObject val = new GameObject("DistanceDisplayCanvas");
Object.DontDestroyOnLoad((Object)(object)val);
val.layer = 5;
_canvas = val.AddComponent<Canvas>();
_canvas.renderMode = (RenderMode)0;
_canvas.sortingOrder = 999;
CanvasScaler obj = val.AddComponent<CanvasScaler>();
obj.uiScaleMode = (ScaleMode)1;
obj.referenceResolution = new Vector2(1920f, 1080f);
val.AddComponent<GraphicRaycaster>();
_canvasTransform = val.transform;
CreateLabelPrefab();
}
}
private void ApplyTMPSettings()
{
if (Configuration.DisableTMPWarnings == null || !Configuration.DisableTMPWarnings.Value)
{
return;
}
try
{
TMP_Settings val = Resources.Load<TMP_Settings>("TMP Settings");
if ((Object)(object)val == (Object)null)
{
val = Resources.FindObjectsOfTypeAll<TMP_Settings>().FirstOrDefault();
}
if (!((Object)(object)val != (Object)null))
{
return;
}
FieldInfo field = typeof(TMP_Settings).GetField("m_warningsDisabled", BindingFlags.Instance | BindingFlags.NonPublic);
if (field != null)
{
field.SetValue(val, true);
Plugin.Log.LogInfo((object)"TMP Warnings disabled (Reflection).");
return;
}
PropertyInfo property = typeof(TMP_Settings).GetProperty("warningsDisabled", BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
if (property != null && property.CanWrite)
{
property.SetValue(val, true);
}
}
catch (Exception)
{
}
}
private void InitializeFonts()
{
_availableFonts.Clear();
try
{
TMP_FontAsset[] array = Resources.FindObjectsOfTypeAll<TMP_FontAsset>();
if (array != null)
{
TMP_FontAsset[] array2 = array;
foreach (TMP_FontAsset val in array2)
{
if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(((Object)val).name) && (Object)(object)val.atlasTexture != (Object)null)
{
_availableFonts.Add(val);
}
}
}
_availableFonts.Sort((TMP_FontAsset a, TMP_FontAsset b) => string.Compare(((Object)a).name, ((Object)b).name));
}
catch
{
}
if (_availableFonts.Count > 0)
{
TMP_FontAsset val2 = ((IEnumerable<TMP_FontAsset>)_availableFonts).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name.IndexOf("Daruma", StringComparison.OrdinalIgnoreCase) >= 0)) ?? ((IEnumerable<TMP_FontAsset>)_availableFonts).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name.IndexOf("Noto", StringComparison.OrdinalIgnoreCase) >= 0)) ?? ((IEnumerable<TMP_FontAsset>)_availableFonts).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => ((Object)f).name.IndexOf("Liberation", StringComparison.OrdinalIgnoreCase) >= 0));
if ((Object)(object)val2 != (Object)null)
{
_currentFont = val2;
_currentFontIndex = _availableFonts.IndexOf(val2);
}
else
{
_currentFont = _availableFonts[0];
_currentFontIndex = 0;
}
if (((Object)_currentFont).name.IndexOf("Daruma", StringComparison.OrdinalIgnoreCase) >= 0)
{
_isUsingFallbackFont = false;
}
else
{
_isUsingFallbackFont = true;
}
}
}
private void TryFindBetterFont()
{
try
{
TMP_FontAsset val = ((IEnumerable<TMP_FontAsset>)Resources.FindObjectsOfTypeAll<TMP_FontAsset>()).FirstOrDefault((Func<TMP_FontAsset, bool>)((TMP_FontAsset f) => (Object)(object)f != (Object)null && ((Object)f).name.IndexOf("Daruma", StringComparison.OrdinalIgnoreCase) >= 0 && (Object)(object)f.atlasTexture != (Object)null));
if (!((Object)(object)val != (Object)null))
{
return;
}
if (!_availableFonts.Contains(val))
{
_availableFonts.Add(val);
}
_availableFonts.Sort((TMP_FontAsset a, TMP_FontAsset b) => string.Compare(((Object)a).name, ((Object)b).name));
_currentFont = val;
_currentFontIndex = _availableFonts.IndexOf(val);
_isUsingFallbackFont = false;
foreach (PlayerLabel value in _activeLabels.Values)
{
value.SetFont(_currentFont);
}
Plugin.Log.LogInfo((object)("Auto-recovered Font to: " + ((Object)val).name));
}
catch
{
}
}
private void CreateLabelPrefab()
{
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_0010: Expected O, but got Unknown
_labelPrefab = new GameObject("LabelPrefab");
_labelPrefab.transform.SetParent(_canvasTransform);
_labelPrefab.layer = 5;
_labelPrefab.SetActive(false);
CanvasGroup obj = _labelPrefab.AddComponent<CanvasGroup>();
obj.alpha = 0f;
obj.blocksRaycasts = false;
obj.interactable = false;
}
private void SetLayerRecursively(GameObject obj, int newLayer)
{
//IL_0025: Unknown result type (might be due to invalid IL or missing references)
//IL_002b: Expected O, but got Unknown
if ((Object)(object)obj == (Object)null)
{
return;
}
obj.layer = newLayer;
foreach (Transform item in obj.transform)
{
Transform val = item;
if ((Object)(object)val != (Object)null)
{
SetLayerRecursively(((Component)val).gameObject, newLayer);
}
}
}
}
public class PlayerLabel
{
private Transform _targetPoint;
private GameObject _rootObj;
private RectTransform _rootRect;
private CanvasGroup _canvasGroup;
private TextMeshProUGUI _mainText;
private List<TextMeshProUGUI> _shadowTexts = new List<TextMeshProUGUI>();
private string _displayName;
private Camera _mainCam;
private const float FADE_TIME = 0.4f;
private static readonly Regex ColorTagRegex = new Regex("<color=.*?>|<\\/color>", RegexOptions.IgnoreCase);
private readonly Vector2[] _offsets = (Vector2[])(object)new Vector2[8]
{
new Vector2(0f, 1f),
new Vector2(0f, -1f),
new Vector2(-1f, 0f),
new Vector2(1f, 0f),
new Vector2(-1f, 1f),
new Vector2(1f, 1f),
new Vector2(-1f, -1f),
new Vector2(1f, -1f)
};
public PlayerLabel(Transform target, GameObject rootUiObj, TMP_FontAsset font, string name)
{
//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)
//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_004a: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007b: Unknown result type (might be due to invalid IL or missing references)
//IL_008c: Unknown result type (might be due to invalid IL or missing references)
//IL_0091: Unknown result type (might be due to invalid IL or missing references)
//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00b8: Unknown result type (might be due to invalid IL or missing references)
//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
//IL_0124: Unknown result type (might be due to invalid IL or missing references)
//IL_0129: Unknown result type (might be due to invalid IL or missing references)
//IL_013f: Unknown result type (might be due to invalid IL or missing references)
//IL_016d: Unknown result type (might be due to invalid IL or missing references)
//IL_0173: Expected O, but got Unknown
_targetPoint = target;
_rootObj = rootUiObj;
_rootRect = _rootObj.GetComponent<RectTransform>();
_canvasGroup = _rootObj.GetComponent<CanvasGroup>();
_displayName = name;
_mainCam = Camera.main;
for (int i = 0; i < 8; i++)
{
GameObject val = new GameObject($"Shadow_{i}");
val.transform.SetParent(_rootObj.transform);
val.layer = 5;
TextMeshProUGUI val2 = val.AddComponent<TextMeshProUGUI>();
SetupTextCommon(val2, font);
_shadowTexts.Add(val2);
}
GameObject val3 = new GameObject("MainText");
val3.transform.SetParent(_rootObj.transform);
val3.layer = 5;
_mainText = val3.AddComponent<TextMeshProUGUI>();
SetupTextCommon(_mainText, font);
RefreshStyle();
}
private void SetupTextCommon(TextMeshProUGUI tmp, TMP_FontAsset font)
{
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
((TMP_Text)tmp).alignment = (TextAlignmentOptions)514;
((Graphic)tmp).raycastTarget = false;
((TMP_Text)tmp).overflowMode = (TextOverflowModes)0;
((TMP_Text)tmp).enableWordWrapping = false;
((TMP_Text)tmp).richText = true;
if ((Object)(object)font != (Object)null)
{
((TMP_Text)tmp).font = font;
}
((TMP_Text)tmp).rectTransform.anchoredPosition = Vector2.zero;
}
public bool IsValid()
{
if ((Object)(object)_targetPoint != (Object)null)
{
return ((Component)_targetPoint).gameObject.activeInHierarchy;
}
return false;
}
public void SetFont(TMP_FontAsset font)
{
if ((Object)(object)_mainText != (Object)null)
{
((TMP_Text)_mainText).font = font;
}
foreach (TextMeshProUGUI shadowText in _shadowTexts)
{
((TMP_Text)shadowText).font = font;
}
}
public void RefreshStyle()
{
//IL_0000: Unknown result type (might be due to invalid IL or missing references)
//IL_0006: Unknown result type (might be due to invalid IL or missing references)
//IL_000b: 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_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0076: Unknown result type (might be due to invalid IL or missing references)
//IL_007c: Unknown result type (might be due to invalid IL or missing references)
_ = Configuration.FixedShadowColor;
Color fixedShadowColor = Configuration.FixedShadowColor;
fixedShadowColor.a = 0.8f;
Color color = default(Color);
((Color)(ref color))..ctor(0.875f, 0.855f, 0.761f, 1f);
((Graphic)_mainText).color = color;
float num = 1.5f;
for (int i = 0; i < 8 && i < _shadowTexts.Count; i++)
{
TextMeshProUGUI obj = _shadowTexts[i];
((Graphic)obj).color = fixedShadowColor;
((TMP_Text)obj).rectTransform.anchoredPosition = _offsets[i] * num;
}
}
public void UpdateState(bool globalShow)
{
//IL_0070: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0084: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Unknown result type (might be due to invalid IL or missing references)
//IL_0095: Unknown result type (might be due to invalid IL or missing references)
//IL_00a0: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00e8: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_010f: Unknown result type (might be due to invalid IL or missing references)
//IL_011c: Unknown result type (might be due to invalid IL or missing references)
//IL_01b9: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
//IL_01bf: Unknown result type (might be due to invalid IL or missing references)
//IL_01cc: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_rootObj == (Object)null || (Object)(object)_canvasGroup == (Object)null)
{
return;
}
if ((Object)(object)_mainCam == (Object)null)
{
_mainCam = Camera.main;
}
if ((Object)(object)_mainCam == (Object)null || (Object)(object)_targetPoint == (Object)null)
{
_canvasGroup.alpha = 0f;
SetVisible(visible: false);
return;
}
Vector3 val = _targetPoint.position + Vector3.up * 1.2f;
float num = Vector3.Distance(((Component)_mainCam).transform.position, _targetPoint.position);
Vector3 val2 = _mainCam.WorldToViewportPoint(val);
bool flag = globalShow;
if (Configuration.MinDistance != null && num < Configuration.MinDistance.Value)
{
flag = false;
}
else if (Configuration.MaxDistance != null && num > Configuration.MaxDistance.Value)
{
flag = false;
}
if (val2.z <= 0f || val2.x < 0f || val2.x > 1f || val2.y < 0f || val2.y > 1f)
{
_canvasGroup.alpha = 0f;
SetVisible(visible: false);
return;
}
float num2 = 2.5f;
float num3 = ((Configuration.GlobalOpacity != null && flag) ? Configuration.GlobalOpacity.Value : 0f);
float num4 = Mathf.MoveTowards(_canvasGroup.alpha, num3, num2 * Time.deltaTime);
bool flag2 = flag || num4 > 0.01f;
SetVisible(flag2);
_canvasGroup.alpha = num4;
if (!flag2)
{
return;
}
Vector3 position = _mainCam.WorldToScreenPoint(val);
_rootObj.transform.position = position;
string text = "";
if (Configuration.NameFontSize != null)
{
float value = Configuration.NameFontSize.Value;
float value2 = Configuration.DistFontSize.Value;
bool value3 = Configuration.ShowName.Value;
bool value4 = Configuration.ShowDistance.Value;
if (value3)
{
text += $"<size={value}>{_displayName}</size>";
}
if (value3 && value4)
{
text += "\n";
}
if (value4)
{
text += $"<size={value2}>{num:F0}m</size>";
}
}
((TMP_Text)_mainText).text = text;
string text2 = ColorTagRegex.Replace(text, string.Empty);
foreach (TextMeshProUGUI shadowText in _shadowTexts)
{
((TMP_Text)shadowText).text = text2;
}
}
public void SetVisible(bool visible)
{
if (!((Object)(object)_rootObj == (Object)null) && _rootObj.activeSelf != visible)
{
_rootObj.SetActive(visible);
}
}
public void Destroy()
{
if ((Object)(object)_rootObj != (Object)null)
{
Object.Destroy((Object)(object)_rootObj);
}
}
}
[BepInPlugin("com.AiAe.betterplayerdistance", "Better Player Distance", "0.1.15")]
public class Plugin : BaseUnityPlugin
{
public static Plugin Instance;
public static ManualLogSource Log;
public static OverlayManager Overlay;
private Harmony _harmony;
private bool _showDebugMenu;
private string _debugNameInput = "测试员01";
private List<GameObject> _fakePlayers = new List<GameObject>();
private Rect _debugWindowRect = new Rect(20f, 20f, 350f, 500f);
private bool _hasLoggedError;
private bool _isConfigLoaded;
private void Awake()
{
//IL_004b: Unknown result type (might be due to invalid IL or missing references)
//IL_0055: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
try
{
Configuration.Initialize(((BaseUnityPlugin)this).Config);
_isConfigLoaded = true;
}
catch (Exception arg)
{
Log.LogError((object)$"Config Init Failed: {arg}");
_isConfigLoaded = false;
}
try
{
_harmony = new Harmony("com.AiAe.betterplayerdistance");
_harmony.PatchAll();
}
catch
{
}
Overlay = new OverlayManager();
Log.LogInfo((object)"BetterPlayerDistance v0.1.15 (AIAE) Loaded.");
}
private void Start()
{
if (Overlay != null)
{
Overlay.TryInitialize();
}
}
private void Update()
{
//IL_0005: Unknown result type (might be due to invalid IL or missing references)
if (Input.GetKeyDown(Configuration.DebugMenuKey.Value))
{
_showDebugMenu = !_showDebugMenu;
if (_showDebugMenu)
{
Cursor.visible = true;
Cursor.lockState = (CursorLockMode)0;
}
}
if (Overlay == null)
{
return;
}
try
{
Overlay.UpdateInput();
}
catch (Exception arg)
{
if (!_hasLoggedError)
{
Log.LogError((object)$"Overlay Input Error: {arg}");
_hasLoggedError = true;
}
}
}
private void LateUpdate()
{
if (Overlay == null)
{
return;
}
try
{
Overlay.LateUpdate();
}
catch (Exception arg)
{
if (!_hasLoggedError)
{
Log.LogError((object)$"Overlay Render Error: {arg}");
_hasLoggedError = true;
}
}
}
private void OnDestroy()
{
Harmony harmony = _harmony;
if (harmony != null)
{
harmony.UnpatchSelf();
}
Overlay?.Dispose();
}
private void OnGUI()
{
//IL_003d: 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_005a: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Expected O, but got Unknown
//IL_0064: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
if (!_showDebugMenu || !Configuration.DebugMode.Value)
{
return;
}
if (_showDebugMenu)
{
Cursor.visible = true;
Cursor.lockState = (CursorLockMode)0;
}
GUI.backgroundColor = new Color(0.1f, 0.1f, 0.1f, 0.95f);
try
{
_debugWindowRect = GUI.Window(888, _debugWindowRect, new WindowFunction(DrawDebugWindow), "调试控制台 / Debug Console [Insert]");
}
catch
{
}
}
private void DrawDebugWindow(int windowID)
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
GUI.DragWindow(new Rect(0f, 0f, 10000f, 20f));
GUILayout.BeginVertical(Array.Empty<GUILayoutOption>());
GUILayout.Label("BetterPlayerDistance (AIAE) <color=yellow>v0.1.15</color>", Array.Empty<GUILayoutOption>());
if (!_isConfigLoaded)
{
GUILayout.Label("<color=red>严重错误 / Fatal: 配置文件加载失败!Config init failed.</color>", Array.Empty<GUILayoutOption>());
GUILayout.Label("请删除 BepInEx/config 下的 .cfg 文件并重启。\nDelete the .cfg under BepInEx/config and restart.", Array.Empty<GUILayoutOption>());
}
else
{
string text = ((Configuration.TriggerMode != null) ? Configuration.TriggerMode.Value.ToString() : "Error");
GUILayout.Label("当前模式 / Mode: <color=cyan>" + text + "</color>", Array.Empty<GUILayoutOption>());
}
GUILayout.Label(string.Format("状态 / State: {0} | 标签数 / Labels: {1}", (Overlay != null) ? "Active" : "Null", Overlay?.ActiveCount ?? 0), Array.Empty<GUILayoutOption>());
GUILayout.Label("字体 / Font: " + (Overlay?.CurrentFontName ?? "Unknown"), Array.Empty<GUILayoutOption>());
GUILayout.Space(5f);
GUILayout.Label("--- 性能 / Performance ---", Array.Empty<GUILayoutOption>());
if (Configuration.DisableTMPWarnings != null)
{
string text2 = (Configuration.DisableTMPWarnings.Value ? "开启 / On" : "关闭 / Off");
if (GUILayout.Button("禁用TMP警告 / Disable TMP Warnings: [" + text2 + "]", Array.Empty<GUILayoutOption>()))
{
Configuration.DisableTMPWarnings.Value = !Configuration.DisableTMPWarnings.Value;
}
}
else
{
GUILayout.Label("<color=red>Config Error: DisableTMPWarnings is NULL</color>", Array.Empty<GUILayoutOption>());
}
GUILayout.Space(5f);
GUILayout.Label("--- 假人测试 / Fake Players ---", Array.Empty<GUILayoutOption>());
_debugNameInput = GUILayout.TextField(_debugNameInput, 20, Array.Empty<GUILayoutOption>());
GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>());
if (GUILayout.Button("生成-前方 / Spawn (Front)", Array.Empty<GUILayoutOption>()))
{
SpawnFakeSafe(_debugNameInput, isColorful: false);
}
if (GUILayout.Button("生成-彩名 / Spawn (Colored)", Array.Empty<GUILayoutOption>()))
{
SpawnFakeSafe(_debugNameInput, isColorful: true);
}
GUILayout.EndHorizontal();
if (GUILayout.Button("清除所有假人 / Clear All Fakes", Array.Empty<GUILayoutOption>()))
{
ClearFakePlayers();
}
GUILayout.Space(5f);
GUILayout.Label("--- 工具 / Tools ---", Array.Empty<GUILayoutOption>());
if (GUILayout.Button("扫描全图实体 / Scan Entities (see console)", Array.Empty<GUILayoutOption>()))
{
ScanAllCharacters();
}
GUILayout.Space(5f);
GUILayout.Label("--- 实时预览 / Live Preview ---", Array.Empty<GUILayoutOption>());
if (GUILayout.Button("切换字体 / Cycle Font (Preview)", Array.Empty<GUILayoutOption>()))
{
Overlay.CycleFont(1);
}
GUILayout.EndVertical();
}
private void ScanAllCharacters()
{
//IL_0047: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)Camera.main == (Object)null))
{
Character[] array = Object.FindObjectsOfType<Character>();
Log.LogInfo((object)$"--- 扫描开始: 发现 {array.Length} 个 Character 对象 ---");
Character[] array2 = array;
foreach (Character val in array2)
{
float num = Vector3.Distance(((Component)Camera.main).transform.position, ((Component)val).transform.position);
string name = ((Object)val).name;
string text = Tracking.ExtractDisplayName(((Object)val).name);
bool activeInHierarchy = ((Component)val).gameObject.activeInHierarchy;
Log.LogInfo((object)$"[实体] ObjName: {name} | Display: {text} | Dist: {num:F1}m | Active: {activeInHierarchy}");
}
Log.LogInfo((object)"--- 扫描结束 ---");
}
}
private void SpawnFakeSafe(string nickName, bool isColorful)
{
//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_0083: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_005e: Unknown result type (might be due to invalid IL or missing references)
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_009a: Unknown result type (might be due to invalid IL or missing references)
//IL_00b5: Unknown result type (might be due to invalid IL or missing references)
//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
//IL_00c6: Expected O, but got Unknown
//IL_00de: 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_00f4: Expected O, but got Unknown
//IL_010e: Unknown result type (might be due to invalid IL or missing references)
//IL_011d: Unknown result type (might be due to invalid IL or missing references)
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_0149: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)Camera.main == (Object)null))
{
GameObject val = GameObject.CreatePrimitive((PrimitiveType)1);
int num = Random.Range(100, 999);
((Object)val).name = $"Fake_{num}";
Vector3 position = (isColorful ? (((Component)Camera.main).transform.position + Random.insideUnitSphere * 10f) : (((Component)Camera.main).transform.position + ((Component)Camera.main).transform.forward * 20f));
position.y = ((Component)Camera.main).transform.position.y - 1f;
val.transform.position = position;
GameObject val2 = new GameObject("Scout");
val2.transform.SetParent(val.transform, false);
val2.transform.localPosition = Vector3.zero;
GameObject val3 = new GameObject("Misc");
val3.transform.SetParent(val2.transform, false);
val3.transform.localPosition = Vector3.zero;
GameObject val4 = new GameObject("CharacterLight");
val4.transform.SetParent(val3.transform, false);
val4.transform.localPosition = new Vector3(0f, 1.8f, 0f);
string text = nickName;
text = ((!isColorful) ? $"{nickName}:{num}" : $"<color=#FF5555>彩</color><color=#55FF55>色</color><color=#5555FF>名</color><color=#FFFF55>字</color>:{num}");
Overlay.RegisterFakeTarget(val, text);
_fakePlayers.Add(val);
}
}
private void ClearFakePlayers()
{
foreach (GameObject fakePlayer in _fakePlayers)
{
if ((Object)(object)fakePlayer != (Object)null)
{
Overlay.UnregisterCharacter(fakePlayer);
Object.Destroy((Object)(object)fakePlayer);
}
}
_fakePlayers.Clear();
}
}
public static class Tracking
{
public static string ExtractDisplayName(string objName)
{
if (string.IsNullOrEmpty(objName))
{
return "Unknown";
}
int num = objName.IndexOf('[');
int num2 = objName.LastIndexOf(':');
if (num != -1 && num2 != -1 && num2 > num)
{
return objName.Substring(num + 1, num2 - num - 1).Trim();
}
return objName;
}
}
[HarmonyPatch(typeof(Character))]
public static class CharacterPatches
{
[HarmonyPatch("Awake")]
[HarmonyPostfix]
public static void Awake_Postfix(Character __instance)
{
Plugin.Overlay?.RegisterCharacter(__instance);
}
[HarmonyPatch("OnDestroy")]
[HarmonyPostfix]
public static void OnDestroy_Postfix(Character __instance)
{
Plugin.Overlay?.UnregisterCharacter(((Component)__instance).gameObject);
}
}
}