Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of PingDisplay v1.1.0
BepInEx\plugins\PingDisplay\PingDisplay.dll
Decompiled 2 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyVersion("0.0.0.0")] namespace PingDisplay; [BepInPlugin("com.peachh.pingdisplay", "PingDisplay", "1.1.0")] public class Plugin : BaseUnityPlugin { private enum UILanguage { Chinese, English } private static class Loc { public const string LabelCN = "Ping: "; public const string LabelEN = "Ping: "; public const string MaxCN = "最大: "; public const string MaxEN = "Max: "; public const string AvgCN = "均: "; public const string AvgEN = "Avg: "; public const string JitCN = "抖: "; public const string JitEN = "Jit: "; public const string LossCN = "丢: "; public const string LossEN = "Loss: "; public const string MsCN = "ms"; public const string MsEN = "ms"; public const string HostCN = "房主: "; public const string HostEN = "Host: "; public const string HostWarnCN = "⚠"; public const string HostWarnEN = "⚠"; public const string DisconnectedCN = "未连接"; public const string DisconnectedEN = "Not Connected"; public const string ConnectingCN = "连接中"; public const string ConnectingEN = "Connecting..."; public const string InLobbyCN = "大厅中"; public const string InLobbyEN = "In Lobby"; } private enum PingCorner { TopLeft, TopRight, BottomLeft, BottomRight } internal static class PluginInfo { public const string PLUGIN_GUID = "com.peachh.pingdisplay"; public const string PLUGIN_NAME = "PingDisplay"; public const string PLUGIN_VERSION = "1.1.0"; public const string PLUGIN_AUTHOR = "peachh"; } private ConfigEntry<UILanguage> _language; private ConfigEntry<PingCorner> _corner; private ConfigEntry<float> _paddingLeft; private ConfigEntry<float> _paddingRight; private ConfigEntry<float> _paddingTop; private ConfigEntry<float> _paddingBottom; private ConfigEntry<string> _fontName; private ConfigEntry<int> _fontSize; private ConfigEntry<string> _fontColor; private ConfigEntry<bool> _showMsSuffix; private ConfigEntry<bool> _showLabel; private ConfigEntry<bool> _showInMenu; private ConfigEntry<int> _greenThreshold; private ConfigEntry<int> _yellowThreshold; private ConfigEntry<int> _orangeThreshold; private ConfigEntry<bool> _showMaxPing; private ConfigEntry<int> _maxPingFontSize; private ConfigEntry<string> _maxPingColor; private ConfigEntry<int> _maxPingResetInterval; private ConfigEntry<float> _regionNotifyDuration; private ConfigEntry<bool> _showAvgPing; private ConfigEntry<bool> _showJitter; private ConfigEntry<bool> _showPacketLoss; private ConfigEntry<bool> _showHostPing; private ConfigEntry<bool> _showHostPingWarning; private ConfigEntry<int> _hostPingWarningThreshold; private Harmony _harmony; private static Plugin _instance; private static GameObject _container; private static Text _pingText; private static Text _maxPingText; private static Text _statsText; private static int _currentPing; private static float _lastPingCheck; private static float _periodStartTime; private static int _periodMaxPing; private static int[] _pingHistory; private static int _pingHistoryIdx; private static int _pingHistoryCount; private static int _pingSum; private const float PING_CHECK_INTERVAL = 1f; private const int PING_HISTORY_SIZE = 10; private static bool _wasConnected; private static float _regionNotifyTime; private static string _regionStr = ""; private static float _disconnectedSince = -1f; private const float DISCONNECT_GRACE = 2f; private static int _cachedPing = -1; private static int _cachedMaxPing = -1; private static string _cachedPingStr = ""; private static string _cachedMaxStr = ""; private static string _cachedStatsStr = ""; private Color _cachedFontColor; private Color _cachedMaxPingColor; private int _cachedFontSize; private int _cachedMaxFontSize; private int _cachedGreen; private int _cachedYellow; private int _cachedOrange; private bool _cachedShowLabel; private bool _cachedShowMs; private bool _cachedShowMax; private bool _cachedShowInMenu; private bool _cachedShowAvg; private bool _cachedShowJitter; private bool _cachedShowLoss; private bool _cachedShowHost; private bool _cachedShowHostWarning; private int _cachedHostWarningThreshold; private static readonly Dictionary<int, int> _actorPings = new Dictionary<int, int>(); private static int[] _hostPingHistory; private static int _hostPingHistoryIdx; private static int _hostPingHistoryCount; private static int _hostPingSum; private static int _lastMasterActor; private const int HOST_PING_HISTORY_SIZE = 8; private static bool _forceRefresh; private static bool _isCN; private static readonly FieldInfo _playerPingField = typeof(PlayerAvatar).GetField("playerPing", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); private void Awake() { _instance = this; _pingHistory = new int[10]; _hostPingHistory = new int[8]; BindConfig(); CacheConfig(); InitHarmony(); CreateCanvasUI(); SceneManager.sceneLoaded += OnSceneLoaded; ((BaseUnityPlugin)this).Logger.LogInfo((object)"Plugin PingDisplay v1.1.0 loaded."); } private void BindConfig() { _language = ((BaseUnityPlugin)this).Config.Bind<UILanguage>("语言 / Language", "语言 / Language", UILanguage.English, "界面语言(HUD 即时切换,菜单文字重启后生效) UI Language (HUD instant, menu text needs restart)"); _isCN = _language.Value == UILanguage.Chinese; _corner = ((BaseUnityPlugin)this).Config.Bind<PingCorner>(L("显示", "Display"), L("显示位置", "Corner"), PingCorner.TopLeft, L("显示在屏幕的哪个角", "Display corner")); _paddingLeft = ((BaseUnityPlugin)this).Config.Bind<float>(L("显示", "Display"), L("左边距", "PaddingLeft"), 80f, L("距屏幕左边距离 (1920x1080 参考)", "Padding from left (1920x1080 ref)")); _paddingRight = ((BaseUnityPlugin)this).Config.Bind<float>(L("显示", "Display"), L("右边距", "PaddingRight"), 50f, L("距屏幕右边距离", "Padding from right")); _paddingTop = ((BaseUnityPlugin)this).Config.Bind<float>(L("显示", "Display"), L("上边距", "PaddingTop"), 5f, L("距屏幕顶部距离", "Padding from top")); _paddingBottom = ((BaseUnityPlugin)this).Config.Bind<float>(L("显示", "Display"), L("下边距", "PaddingBottom"), 50f, L("距屏幕底部距离", "Padding from bottom")); _fontName = ((BaseUnityPlugin)this).Config.Bind<string>(L("显示", "Display"), L("字体", "FontName"), "Arial", L("字体名称 (Arial, Consolas 等)", "Font name (Arial, Consolas, etc.)")); _fontSize = ((BaseUnityPlugin)this).Config.Bind<int>(L("显示", "Display"), L("字体大小", "FontSize"), 22, L("Ping 文字字体大小", "Ping text font size")); _fontColor = ((BaseUnityPlugin)this).Config.Bind<string>(L("显示", "Display"), L("字体颜色", "FontColor"), "", L("自定义 HEX 颜色,留空=自动着色", "Custom HEX color, empty=auto-color")); _showMsSuffix = ((BaseUnityPlugin)this).Config.Bind<bool>(L("显示", "Display"), L("显示ms后缀", "ShowMsSuffix"), true, L("数值后显示 'ms'", "Show 'ms' suffix after value")); _showLabel = ((BaseUnityPlugin)this).Config.Bind<bool>(L("显示", "Display"), L("显示标签", "ShowLabel"), true, L("显示 'Ping:' 标签前缀", "Show 'Ping:' label prefix")); _showInMenu = ((BaseUnityPlugin)this).Config.Bind<bool>(L("显示", "Display"), L("菜单中显示", "ShowInMenu"), true, L("在菜单/大厅界面也显示", "Show in menu and lobby")); _greenThreshold = ((BaseUnityPlugin)this).Config.Bind<int>(L("颜色", "Colors"), L("绿色阈值", "GreenThreshold"), 50, L("低于此值为绿色 (ms)", "Below this → green (ms)")); _yellowThreshold = ((BaseUnityPlugin)this).Config.Bind<int>(L("颜色", "Colors"), L("黄色阈值", "YellowThreshold"), 100, L("低于此值为黄色 (ms)", "Below this → yellow (ms)")); _orangeThreshold = ((BaseUnityPlugin)this).Config.Bind<int>(L("颜色", "Colors"), L("橙色阈值", "OrangeThreshold"), 200, L("低于此值为橙色,否则红色 (ms)", "Below this → orange, else red (ms)")); _showMaxPing = ((BaseUnityPlugin)this).Config.Bind<bool>(L("最大延迟", "MaxPing"), L("显示最大延迟", "ShowMaxPing"), true, L("显示周期内最大 Ping 值", "Show max ping value in period")); _maxPingFontSize = ((BaseUnityPlugin)this).Config.Bind<int>(L("最大延迟", "MaxPing"), L("最大延迟字体大小", "MaxPingFontSize"), 14, L("最大 Ping 文字字体大小", "Max ping text font size")); _maxPingColor = ((BaseUnityPlugin)this).Config.Bind<string>(L("最大延迟", "MaxPing"), L("最大延迟颜色", "MaxPingColor"), "", L("最大 Ping HEX 颜色,留空=跟随主文字", "Max ping HEX color, empty=follow main")); _maxPingResetInterval = ((BaseUnityPlugin)this).Config.Bind<int>(L("最大延迟", "MaxPing"), L("重置间隔", "ResetInterval"), 60, L("最大 Ping 重置间隔(秒),0=不重置", "Max ping reset interval in seconds, 0=never")); _regionNotifyDuration = ((BaseUnityPlugin)this).Config.Bind<float>(L("显示", "Display"), L("地区显示时长", "RegionNotifyDuration"), 5f, L("连接后显示服务器地区的时间(秒),0=不显示", "Show region for N seconds after connect, 0=off")); _showAvgPing = ((BaseUnityPlugin)this).Config.Bind<bool>(L("统计", "Stats"), L("显示平均延迟", "ShowAvgPing"), false, L("显示平均延迟 (10秒滑动窗口)", "Show average ping (10s sliding window)")); _showJitter = ((BaseUnityPlugin)this).Config.Bind<bool>(L("统计", "Stats"), L("显示抖动", "ShowJitter"), false, L("显示网络抖动 (RTT 方差)", "Show jitter (RTT variance)")); _showPacketLoss = ((BaseUnityPlugin)this).Config.Bind<bool>(L("统计", "Stats"), L("显示丢包率", "ShowPacketLoss"), false, L("显示丢包率百分比", "Show packet loss %")); _showHostPing = ((BaseUnityPlugin)this).Config.Bind<bool>(L("统计", "Stats"), L("显示主机延迟", "ShowHostPing"), false, L("显示房主(主机)的网络延迟", "Show host (master client) ping")); _showHostPingWarning = ((BaseUnityPlugin)this).Config.Bind<bool>(L("统计", "Stats"), L("主机延迟波动警告", "ShowHostPingWarning"), true, L("主机延迟波动较大时显示警告 ⚠", "Show ⚠ warning when host ping fluctuates")); _hostPingWarningThreshold = ((BaseUnityPlugin)this).Config.Bind<int>(L("统计", "Stats"), L("波动警告阈值", "HostWarningThreshold"), 80, L("主机延迟标准差超过此值(ms)时显示警告", "Show warning when host ping stddev exceeds this (ms)")); _fontColor.SettingChanged += delegate { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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) _cachedFontColor = ParseHexColor(_fontColor.Value, Color.white); _forceRefresh = true; }; _maxPingColor.SettingChanged += delegate { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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) _cachedMaxPingColor = ParseHexColor(_maxPingColor.Value, Color.white); _forceRefresh = true; }; _fontSize.SettingChanged += delegate { _cachedFontSize = _fontSize.Value; _forceRefresh = true; }; _maxPingFontSize.SettingChanged += delegate { _cachedMaxFontSize = _maxPingFontSize.Value; _forceRefresh = true; }; _greenThreshold.SettingChanged += delegate { _cachedGreen = _greenThreshold.Value; _forceRefresh = true; }; _yellowThreshold.SettingChanged += delegate { _cachedYellow = _yellowThreshold.Value; _forceRefresh = true; }; _orangeThreshold.SettingChanged += delegate { _cachedOrange = _orangeThreshold.Value; _forceRefresh = true; }; _showLabel.SettingChanged += delegate { _cachedShowLabel = _showLabel.Value; _forceRefresh = true; }; _showMsSuffix.SettingChanged += delegate { _cachedShowMs = _showMsSuffix.Value; _forceRefresh = true; }; _showMaxPing.SettingChanged += delegate { _cachedShowMax = _showMaxPing.Value; _forceRefresh = true; }; _showInMenu.SettingChanged += delegate { _cachedShowInMenu = _showInMenu.Value; _forceRefresh = true; }; _showAvgPing.SettingChanged += delegate { _cachedShowAvg = _showAvgPing.Value; _forceRefresh = true; }; _showJitter.SettingChanged += delegate { _cachedShowJitter = _showJitter.Value; _forceRefresh = true; }; _showPacketLoss.SettingChanged += delegate { _cachedShowLoss = _showPacketLoss.Value; _forceRefresh = true; }; _showHostPing.SettingChanged += delegate { _cachedShowHost = _showHostPing.Value; _forceRefresh = true; }; _showHostPingWarning.SettingChanged += delegate { _cachedShowHostWarning = _showHostPingWarning.Value; _forceRefresh = true; }; _hostPingWarningThreshold.SettingChanged += delegate { _cachedHostWarningThreshold = _hostPingWarningThreshold.Value; _forceRefresh = true; }; _language.SettingChanged += delegate { _isCN = _language.Value == UILanguage.Chinese; _forceRefresh = true; }; _corner.SettingChanged += delegate { RepositionContainer(); }; _paddingLeft.SettingChanged += delegate { RepositionContainer(); }; _paddingRight.SettingChanged += delegate { RepositionContainer(); }; _paddingTop.SettingChanged += delegate { RepositionContainer(); }; _paddingBottom.SettingChanged += delegate { RepositionContainer(); }; } private static string L(string cn, string en) { if (!_isCN) { return en; } return cn; } private void CacheConfig() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: 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_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_0031: Unknown result type (might be due to invalid IL or missing references) _cachedFontColor = ParseHexColor(_fontColor.Value, Color.white); _cachedMaxPingColor = ParseHexColor(_maxPingColor.Value, Color.white); _cachedFontSize = _fontSize.Value; _cachedMaxFontSize = _maxPingFontSize.Value; _cachedGreen = _greenThreshold.Value; _cachedYellow = _yellowThreshold.Value; _cachedOrange = _orangeThreshold.Value; _cachedShowLabel = _showLabel.Value; _cachedShowMs = _showMsSuffix.Value; _cachedShowMax = _showMaxPing.Value; _cachedShowInMenu = _showInMenu.Value; _cachedShowAvg = _showAvgPing.Value; _cachedShowJitter = _showJitter.Value; _cachedShowLoss = _showPacketLoss.Value; _cachedShowHost = _showHostPing.Value; _cachedShowHostWarning = _showHostPingWarning.Value; _cachedHostWarningThreshold = _hostPingWarningThreshold.Value; } private void InitHarmony() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown _harmony = new Harmony("com.peachh.pingdisplay"); try { MethodInfo method = typeof(PlayerAvatar).GetMethod("Update", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { _harmony.Patch((MethodBase)method, (HarmonyMethod)null, new HarmonyMethod(typeof(Plugin), "OnPlayerUpdatePostfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)"PlayerAvatar.Update not found."); } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Harmony patch failed: " + ex.Message)); } } private void OnSceneLoaded(Scene scene, LoadSceneMode mode) { if ((Object)(object)_pingText == (Object)null || (Object)(object)((Component)_pingText).gameObject == (Object)null) { CreateCanvasUI(); } } private void RepositionContainer() { if (!((Object)(object)_container == (Object)null)) { RectTransform component = _container.GetComponent<RectTransform>(); if (!((Object)(object)component == (Object)null)) { SetupCornerPosition(component); } } } private void OnDestroy() { SceneManager.sceneLoaded -= OnSceneLoaded; } private void CreateCanvasUI() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Expected O, but got Unknown //IL_007b: 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_009b: Expected O, but got Unknown try { if (!((Object)(object)_pingText != (Object)null) || !((Object)(object)((Component)_pingText).gameObject != (Object)null)) { Font font = LoadFont(_fontName.Value); GameObject val = new GameObject("PingDisplay_Canvas"); Object.DontDestroyOnLoad((Object)(object)val); val.layer = 5; Canvas obj = val.AddComponent<Canvas>(); obj.renderMode = (RenderMode)0; obj.sortingOrder = 32767; CanvasScaler obj2 = val.AddComponent<CanvasScaler>(); obj2.uiScaleMode = (ScaleMode)1; obj2.referenceResolution = new Vector2(1920f, 1080f); val.AddComponent<GraphicRaycaster>(); _container = new GameObject("PingContainer"); _container.transform.SetParent(val.transform, false); _container.layer = 5; RectTransform rt = _container.AddComponent<RectTransform>(); SetupCornerPosition(rt); VerticalLayoutGroup obj3 = _container.AddComponent<VerticalLayoutGroup>(); PingCorner value = _corner.Value; ((LayoutGroup)obj3).childAlignment = (TextAnchor)((value != PingCorner.TopLeft && value != PingCorner.BottomLeft) ? 2 : 0); ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)obj3).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)obj3).spacing = 3f; ContentSizeFitter obj4 = _container.AddComponent<ContentSizeFitter>(); obj4.horizontalFit = (FitMode)2; obj4.verticalFit = (FitMode)2; _pingText = CreateText("PingText", font, _cachedFontSize, 300f); AddOutline(_pingText); _maxPingText = CreateText("MaxPingText", font, _cachedMaxFontSize, 260f); AddOutline(_maxPingText); _statsText = CreateText("StatsText", font, 12, 260f); AddOutline(_statsText); _periodStartTime = Time.time; _periodMaxPing = 0; } } catch (Exception ex) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("[CreateCanvasUI] Failed: " + ex.Message)); } } private void SetupCornerPosition(RectTransform rt) { //IL_0047: 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_0071: 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_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) float num; float num2; switch (_corner.Value) { case PingCorner.TopLeft: num = _paddingLeft.Value; num2 = 0f - _paddingTop.Value; rt.anchorMin = new Vector2(0f, 1f); rt.anchorMax = new Vector2(0f, 1f); rt.pivot = new Vector2(0f, 1f); break; case PingCorner.TopRight: num = 0f - _paddingRight.Value; num2 = 0f - _paddingTop.Value; rt.anchorMin = new Vector2(1f, 1f); rt.anchorMax = new Vector2(1f, 1f); rt.pivot = new Vector2(1f, 1f); break; case PingCorner.BottomLeft: num = _paddingLeft.Value; num2 = _paddingBottom.Value; rt.anchorMin = new Vector2(0f, 0f); rt.anchorMax = new Vector2(0f, 0f); rt.pivot = new Vector2(0f, 0f); break; default: num = 0f - _paddingRight.Value; num2 = _paddingBottom.Value; rt.anchorMin = new Vector2(1f, 0f); rt.anchorMax = new Vector2(1f, 0f); rt.pivot = new Vector2(1f, 0f); break; } rt.anchoredPosition = new Vector2(num, num2); rt.sizeDelta = new Vector2(300f, 80f); } private Text CreateText(string name, Font font, int size, float width) { //IL_0001: 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_001c: 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_002f: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(_container.transform, false); val.layer = 5; val.AddComponent<RectTransform>().sizeDelta = new Vector2(width, (float)(size + 4)); Text obj = val.AddComponent<Text>(); obj.font = font; obj.fontSize = size; PingCorner value = _corner.Value; obj.alignment = (TextAnchor)((value != PingCorner.TopLeft && value != PingCorner.BottomLeft) ? 2 : 0); obj.text = ""; return obj; } private static void AddOutline(Text text) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) Outline obj = ((Component)text).gameObject.AddComponent<Outline>(); ((Shadow)obj).effectColor = Color.black; ((Shadow)obj).effectDistance = new Vector2(1f, -1f); } private static Font LoadFont(string fontName) { if (string.IsNullOrEmpty(fontName)) { fontName = "Arial"; } Font val = null; try { val = Font.CreateDynamicFontFromOSFont(fontName, 16); } catch { } if ((Object)(object)val == (Object)null) { try { val = Resources.GetBuiltinResource<Font>("Arial.ttf"); } catch { } } if ((Object)(object)val == (Object)null) { try { Object builtinResource = Resources.GetBuiltinResource(typeof(Font), "LegacyRuntime.ttf"); val = (Font)(object)((builtinResource is Font) ? builtinResource : null); } catch { } } if ((Object)(object)val == (Object)null) { try { val = Font.CreateDynamicFontFromOSFont("Arial", 16); } catch { } } return val; } private static void OnPlayerUpdatePostfix(PlayerAvatar __instance) { if ((Object)(object)__instance?.photonView != (Object)null && _playerPingField != null) { _actorPings[__instance.photonView.OwnerActorNr] = (int)_playerPingField.GetValue(__instance); } _instance?.UpdatePingDisplay(); } private void UpdatePingDisplay() { //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Invalid comparison between Unknown and I4 //IL_08dc: Unknown result type (might be due to invalid IL or missing references) //IL_0233: Unknown result type (might be due to invalid IL or missing references) //IL_0429: Unknown result type (might be due to invalid IL or missing references) //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_04fb: Unknown result type (might be due to invalid IL or missing references) //IL_059e: Unknown result type (might be due to invalid IL or missing references) //IL_0592: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_pingText == (Object)null || (Object)(object)((Component)_pingText).gameObject == (Object)null) { CreateCanvasUI(); if ((Object)(object)_pingText == (Object)null) { return; } } if (SemiFunc.MenuLevel() && !_cachedShowInMenu) { _cachedPingStr = ""; _cachedMaxStr = ""; _cachedStatsStr = ""; _pingText.text = ""; _maxPingText.text = ""; _statsText.text = ""; return; } bool flag = false; if (Time.time - _lastPingCheck >= 1f) { _lastPingCheck = Time.time; int currentPing = GetCurrentPing(); if (currentPing != _currentPing) { _currentPing = currentPing; flag = true; } if (_pingHistoryCount == 10) { _pingSum -= _pingHistory[_pingHistoryIdx]; } _pingHistory[_pingHistoryIdx] = _currentPing; _pingSum += _currentPing; _pingHistoryIdx = (_pingHistoryIdx + 1) % 10; if (_pingHistoryCount < 10) { _pingHistoryCount++; } int value = _maxPingResetInterval.Value; if (value > 0 && Time.time - _periodStartTime >= (float)value) { _periodMaxPing = 0; _periodStartTime = Time.time; } if (_currentPing > _periodMaxPing) { _periodMaxPing = _currentPing; } flag = true; } ClientState networkClientState = PhotonNetwork.NetworkClientState; if (!PhotonNetwork.IsConnectedAndReady) { _wasConnected = false; bool isCN = _isCN; if (_disconnectedSince < 0f) { _disconnectedSince = Time.time; } bool flag2 = Time.time - _disconnectedSince < 2f; string text = (((int)networkClientState == 4) ? (isCN ? "大厅中" : "In Lobby") : ((!flag2) ? (isCN ? "未连接" : "Not Connected") : (isCN ? "连接中" : "Connecting..."))); if (_cachedPingStr != text) { _cachedPingStr = text; _pingText.text = text; ((Graphic)_pingText).color = new Color(0.7f, 0.7f, 0.7f); _pingText.fontSize = _cachedFontSize; _maxPingText.text = ""; _statsText.text = ""; _cachedMaxStr = ""; _cachedStatsStr = ""; } return; } if (!_wasConnected) { _wasConnected = true; _disconnectedSince = -1f; if (_regionNotifyDuration.Value > 0f) { try { _regionStr = PhotonNetwork.CloudRegion ?? ""; } catch { _regionStr = ""; } if (!string.IsNullOrEmpty(_regionStr)) { _regionNotifyTime = Time.time; } } } if (_forceRefresh) { _forceRefresh = false; _cachedPingStr = ""; _cachedMaxStr = ""; _cachedStatsStr = ""; _cachedPing = -1; _cachedMaxPing = -1; } if (!flag && !_forceRefresh && _currentPing == _cachedPing && _periodMaxPing == _cachedMaxPing) { return; } _cachedPing = _currentPing; _cachedMaxPing = _periodMaxPing; bool isCN2 = _isCN; string text2 = (isCN2 ? "ms" : "ms"); string text3 = (_cachedShowMs ? $"{_currentPing}{text2}" : $"{_currentPing}"); string text4 = (isCN2 ? "Ping: " : "Ping: "); string text5 = (_cachedShowLabel ? (text4 + text3) : text3); if (_cachedPingStr != text5 || _cachedPingStr == "") { _cachedPingStr = text5; _pingText.text = text5; _pingText.fontSize = _cachedFontSize; ((Graphic)_pingText).color = (string.IsNullOrEmpty(_fontColor.Value) ? GetAutoPingColor(_currentPing) : _cachedFontColor); } if (_regionNotifyDuration.Value > 0f && _regionNotifyTime > 0f && Time.time - _regionNotifyTime < _regionNotifyDuration.Value && !string.IsNullOrEmpty(_regionStr)) { ((Component)_maxPingText).gameObject.SetActive(true); string text6 = (isCN2 ? ("地区: " + _regionStr) : ("Region: " + _regionStr)); if (_cachedMaxStr != text6) { _cachedMaxStr = text6; _maxPingText.text = text6; _maxPingText.fontSize = _cachedMaxFontSize; ((Graphic)_maxPingText).color = new Color(0.4f, 0.8f, 1f); } } else if (_cachedShowMax) { ((Component)_maxPingText).gameObject.SetActive(true); string text7 = (isCN2 ? "最大: " : "Max: ") + _periodMaxPing + text2; if (_cachedMaxStr != text7) { _cachedMaxStr = text7; _maxPingText.text = text7; _maxPingText.fontSize = _cachedMaxFontSize; ((Graphic)_maxPingText).color = (string.IsNullOrEmpty(_maxPingColor.Value) ? ((Graphic)_pingText).color : _cachedMaxPingColor); } } else { ((Component)_maxPingText).gameObject.SetActive(false); if (_cachedMaxStr != "") { _cachedMaxStr = ""; _maxPingText.text = ""; } } if (_cachedShowAvg || _cachedShowJitter || _cachedShowLoss || _cachedShowHost) { ((Component)_statsText).gameObject.SetActive(true); List<string> list = new List<string>(4); if (_cachedShowAvg) { int num = ((_pingHistoryCount > 0) ? (_pingSum / _pingHistoryCount) : _currentPing); string arg = (isCN2 ? "均: " : "Avg: "); list.Add($"{arg}{num}{text2}"); } if (_cachedShowJitter) { int num2 = 0; try { num2 = GetPeerStat<int>("RoundTripTimeVariance"); } catch { } string arg2 = (isCN2 ? "抖: " : "Jit: "); list.Add($"{arg2}{num2}{text2}"); } if (_cachedShowLoss) { int num3 = 0; try { num3 = GetPeerStat<byte>("PacketLossByCrc"); } catch { } string arg3 = (isCN2 ? "丢: " : "Loss: "); list.Add($"{arg3}{num3}%"); } if (_cachedShowHost) { int value2 = 0; bool flag3 = false; if (PhotonNetwork.InRoom && PhotonNetwork.MasterClient != null) { int actorNumber = PhotonNetwork.MasterClient.ActorNumber; if (actorNumber != _lastMasterActor) { _lastMasterActor = actorNumber; _hostPingHistoryCount = 0; _hostPingSum = 0; } flag3 = _actorPings.TryGetValue(actorNumber, out value2); if (flag3) { if (_hostPingHistoryCount == 8) { _hostPingSum -= _hostPingHistory[_hostPingHistoryIdx]; } _hostPingHistory[_hostPingHistoryIdx] = value2; _hostPingSum += value2; _hostPingHistoryIdx = (_hostPingHistoryIdx + 1) % 8; if (_hostPingHistoryCount < 8) { _hostPingHistoryCount++; } } } string text8 = (isCN2 ? "房主: " : "Host: "); if (flag3) { string text9 = $"{text8}{value2}{text2}"; if (_cachedShowHostWarning && _hostPingHistoryCount >= 4) { double num4 = (double)_hostPingSum / (double)_hostPingHistoryCount; double num5 = 0.0; for (int i = 0; i < _hostPingHistoryCount; i++) { double num6 = (double)_hostPingHistory[i] - num4; num5 += num6 * num6; } if (Math.Sqrt(num5 / (double)_hostPingHistoryCount) >= (double)_cachedHostWarningThreshold) { text9 += (isCN2 ? "⚠" : "⚠"); } } list.Add(text9); } else { list.Add(text8 + "N/A"); } } string text10 = string.Join(" ", list); if (_cachedStatsStr != text10) { _cachedStatsStr = text10; _statsText.text = text10; _statsText.fontSize = 12; ((Graphic)_statsText).color = new Color(0.55f, 0.55f, 0.55f); } } else { ((Component)_statsText).gameObject.SetActive(false); if (_cachedStatsStr != "") { _cachedStatsStr = ""; _statsText.text = ""; } } } private static int GetCurrentPing() { try { return PhotonNetwork.GetPing(); } catch { return 0; } } private static T GetPeerStat<T>(string propertyName) { LoadBalancingPeer loadBalancingPeer = PhotonNetwork.NetworkingClient.LoadBalancingPeer; PropertyInfo property = ((object)loadBalancingPeer).GetType().BaseType.GetProperty(propertyName, BindingFlags.Instance | BindingFlags.Public); if (property != null) { return (T)property.GetValue(loadBalancingPeer); } return default(T); } private Color GetAutoPingColor(int ping) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (ping <= 0) { return new Color(0.5f, 0.5f, 0.5f); } if (ping < _cachedGreen) { return new Color(0f, 1f, 0.4f); } if (ping < _cachedYellow) { return new Color(1f, 0.9f, 0f); } if (ping < _cachedOrange) { return new Color(1f, 0.55f, 0f); } return new Color(1f, 0.2f, 0.2f); } private static Color ParseHexColor(string hex, Color fallback) { //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: 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_009a: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(hex)) { return fallback; } hex = hex.TrimStart(new char[1] { '#' }); if (hex.Length != 6 && hex.Length != 8) { return fallback; } try { return new Color((float)Convert.ToInt32(hex.Substring(0, 2), 16) / 255f, (float)Convert.ToInt32(hex.Substring(2, 2), 16) / 255f, (float)Convert.ToInt32(hex.Substring(4, 2), 16) / 255f, (hex.Length >= 8) ? ((float)Convert.ToInt32(hex.Substring(6, 2), 16) / 255f) : 1f); } catch { return fallback; } } }