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 PlayerCountFixed v1.1.0
PlayerCountFixed.dll
Decompiled 2 weeks agousing 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 HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using TMPro; using UnityEngine; 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("PlayerCountFixed")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("PlayerCountFixed")] [assembly: AssemblyTitle("PlayerCountFixed")] [assembly: AssemblyVersion("1.0.0.0")] [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.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 PlayerCountFixed { [BepInPlugin("local.playercountfixed", "PlayerCountFixed", "1.0.0")] public sealed class Plugin : BaseUnityPlugin { [HarmonyPatch(typeof(MenuPageLobby), "Awake")] private static class MenuPageLobbyAwakePatch { private static void Postfix(MenuPageLobby __instance) { TryAttachLobbyCounter(__instance); } } [HarmonyPatch(typeof(MenuPageLobby), "Start")] private static class MenuPageLobbyStartPatch { private static void Postfix(MenuPageLobby __instance) { TryAttachLobbyCounter(__instance); } } private sealed class PlayerCountFixedUpdater : MonoBehaviour { [CompilerGenerated] private sealed class <RefreshLoop>d__7 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public PlayerCountFixedUpdater <>4__this; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RefreshLoop>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { int num = <>1__state; PlayerCountFixedUpdater playerCountFixedUpdater = <>4__this; if (num != 0) { if (num != 1) { return false; } <>1__state = -1; } else { <>1__state = -1; } playerCountFixedUpdater.RefreshOnce(); <>2__current = playerCountFixedUpdater._refreshDelay; <>1__state = 1; return true; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private TextMeshProUGUI? _text; private Coroutine? _refreshCoroutine; private string? _lastText; private readonly WaitForSeconds _refreshDelay = new WaitForSeconds(0.25f); internal void SetText(TextMeshProUGUI text) { _text = text; if (_refreshCoroutine == null && ((Behaviour)this).isActiveAndEnabled) { _refreshCoroutine = ((MonoBehaviour)this).StartCoroutine(RefreshLoop()); } } private void OnEnable() { if ((Object)(object)_text != (Object)null && _refreshCoroutine == null) { _refreshCoroutine = ((MonoBehaviour)this).StartCoroutine(RefreshLoop()); } } private void OnDisable() { if (_refreshCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_refreshCoroutine); _refreshCoroutine = null; } } [IteratorStateMachine(typeof(<RefreshLoop>d__7))] private IEnumerator RefreshLoop() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <RefreshLoop>d__7(0) { <>4__this = this }; } internal void RefreshNow() { _lastText = null; RefreshOnce(); } private void RefreshOnce() { try { if ((Object)(object)_text == (Object)null) { return; } string text = string.Empty; Room currentRoom = PhotonNetwork.CurrentRoom; if (PhotonNetwork.InRoom && currentRoom != null) { if ((Object)(object)Instance == (Object)null || Instance.UseNewColorMode()) { string arg = ((currentRoom.PlayerCount == currentRoom.MaxPlayers) ? "#FF0000" : "#00FF00"); text = $"Players: <color={arg}>{currentRoom.PlayerCount}</color><color=#FFFFFF>/</color><color=#FF0000>{currentRoom.MaxPlayers}</color>"; } else { text = $"Players: {currentRoom.PlayerCount}/{currentRoom.MaxPlayers}"; } } if (!string.Equals(_lastText, text, StringComparison.Ordinal)) { ((TMP_Text)_text).text = text; _lastText = text; } } catch (Exception ex) { Instance?.LogUpdateFailureOnce(ex); } } } public const string PluginGuid = "local.playercountfixed"; public const string PluginName = "PlayerCountFixed"; public const string PluginVersion = "1.0.0"; private const string LobbyTextObjectName = "PlayerCountFixedTextLobby"; private const float DefaultPositionX1080 = 240f; private const float DefaultPositionY1080 = 30f; private const float DefaultFontSize = 22f; private const float MinFontSize = 1f; private const float MaxFontSize = 200f; private const float MinPosition = 0f; private const float MaxPosition = 10000f; private Harmony? _harmony; private ConfigEntry<float>? _positionX1080; private ConfigEntry<float>? _positionY1080; private ConfigEntry<float>? _fontSize; private ConfigEntry<string>? _colorMode; private bool _loggedUiAttached; private bool _loggedUiAttachFailure; private bool _loggedUiConfigFailure; private bool _loggedUpdateFailure; internal static Plugin? Instance { get; private set; } private void Awake() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown Instance = this; BindConfig(); _harmony = new Harmony("local.playercountfixed"); _harmony.PatchAll(typeof(Plugin).Assembly); ((BaseUnityPlugin)this).Logger.LogInfo((object)"PlayerCountFixed loaded."); } private void OnDestroy() { UnsubscribeUiConfigChanged(); Harmony? harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } internal static void TryAttachLobbyCounter(MenuPageLobby lobby) { Instance?.AttachLobbyCounter(lobby); } private void AttachLobbyCounter(MenuPageLobby lobby) { //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_0141: 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) try { if ((Object)(object)lobby == (Object)null) { return; } Transform transform = ((Component)lobby).transform; Transform val = transform.Find("Panel"); Transform val2 = val ?? transform; Transform val3 = FindExistingCounter(transform); if ((Object)(object)val3 != (Object)null) { if ((Object)(object)val != (Object)null && (Object)(object)val3.parent != (Object)(object)val) { val3.SetParent(val, false); } ApplyUiConfig(val3, ((Component)val3).GetComponent<TextMeshProUGUI>()); EnsureUpdater(((Component)val3).gameObject, ((Component)val3).GetComponent<TextMeshProUGUI>()); return; } TextMeshProUGUI val4 = FindReferenceText(transform); GameObject val5 = new GameObject("PlayerCountFixedTextLobby"); val5.transform.SetParent(val2, false); RectTransform obj = val5.AddComponent<RectTransform>(); obj.anchorMin = new Vector2(0f, 1f); obj.anchorMax = new Vector2(0f, 1f); obj.pivot = new Vector2(0f, 1f); obj.sizeDelta = new Vector2(240f, 30f); TextMeshProUGUI val6 = val5.AddComponent<TextMeshProUGUI>(); if ((Object)(object)val4 != (Object)null) { ((TMP_Text)val6).font = ((TMP_Text)val4).font; ((TMP_Text)val6).fontSharedMaterial = ((TMP_Text)val4).fontSharedMaterial; ((TMP_Text)val6).fontStyle = ((TMP_Text)val4).fontStyle; } ((TMP_Text)val6).alignment = (TextAlignmentOptions)513; ((Graphic)val6).color = Color.yellow; ((Graphic)val6).raycastTarget = false; ((TMP_Text)val6).text = string.Empty; ApplyUiConfig(val5.transform, val6); EnsureUpdater(val5, val6); if (!_loggedUiAttached) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Lobby player count UI attached."); _loggedUiAttached = true; } } catch (Exception ex) { LogUiAttachFailureOnce(ex); } } private void BindConfig() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Expected O, but got Unknown //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Expected O, but got Unknown _positionX1080 = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "Position X (1080p)", 240f, new ConfigDescription("Horizontal RectTransform anchored-position UI offset from the top-left anchor, in UI units. Values are clamped to a safe non-negative range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10000f), Array.Empty<object>())); _positionY1080 = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "Position Y (1080p)", 30f, new ConfigDescription("Vertical RectTransform anchored-position UI offset from the top-left anchor, in UI units. Values are clamped to a safe non-negative range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 10000f), Array.Empty<object>())); _fontSize = ((BaseUnityPlugin)this).Config.Bind<float>("UI", "Font Size", 22f, new ConfigDescription("Lobby counter TextMeshPro font size. Values are clamped to a safe positive range.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 200f), Array.Empty<object>())); _colorMode = ((BaseUnityPlugin)this).Config.Bind<string>("UI", "Color Mode", "new", new ConfigDescription("Lobby counter color style. Use 'new' for colored player counts or 'old' for the plain all-yellow display.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[2] { "new", "old" }), Array.Empty<object>())); SubscribeUiConfigChanged(); } private void SubscribeUiConfigChanged() { ((BaseUnityPlugin)this).Config.ConfigReloaded += OnUiConfigChanged; if (_positionX1080 != null) { _positionX1080.SettingChanged += OnUiConfigChanged; } if (_positionY1080 != null) { _positionY1080.SettingChanged += OnUiConfigChanged; } if (_fontSize != null) { _fontSize.SettingChanged += OnUiConfigChanged; } if (_colorMode != null) { _colorMode.SettingChanged += OnUiConfigChanged; } } private void UnsubscribeUiConfigChanged() { ((BaseUnityPlugin)this).Config.ConfigReloaded -= OnUiConfigChanged; if (_positionX1080 != null) { _positionX1080.SettingChanged -= OnUiConfigChanged; } if (_positionY1080 != null) { _positionY1080.SettingChanged -= OnUiConfigChanged; } if (_fontSize != null) { _fontSize.SettingChanged -= OnUiConfigChanged; } if (_colorMode != null) { _colorMode.SettingChanged -= OnUiConfigChanged; } } private void OnUiConfigChanged(object sender, EventArgs args) { try { MenuPageLobby instance = MenuPageLobby.instance; if (!((Object)(object)instance == (Object)null)) { Transform val = FindExistingCounter(((Component)instance).transform); if (!((Object)(object)val == (Object)null)) { ApplyUiConfig(val, ((Component)val).GetComponent<TextMeshProUGUI>()); ((Component)val).GetComponent<PlayerCountFixedUpdater>()?.RefreshNow(); } } } catch (Exception ex) { LogUiConfigFailureOnce(ex); } } private void ApplyUiConfig(Transform transform, TextMeshProUGUI? text) { //IL_0075: Unknown result type (might be due to invalid IL or missing references) RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val != null) { float num = ClampConfigValue(_positionX1080?.Value, 240f, 0f, 10000f); float num2 = ClampConfigValue(_positionY1080?.Value, 30f, 0f, 10000f); val.anchoredPosition = new Vector2(num, num2); } if ((Object)(object)text != (Object)null) { ((TMP_Text)text).fontSize = ClampConfigValue(_fontSize?.Value, 22f, 1f, 200f); ((TMP_Text)text).richText = true; } } private static float ClampConfigValue(float? value, float fallback, float min, float max) { float num = value.GetValueOrDefault(fallback); if (float.IsNaN(num) || float.IsInfinity(num)) { num = fallback; } return Mathf.Clamp(num, min, max); } private bool UseNewColorMode() { return !string.Equals(_colorMode?.Value, "old", StringComparison.OrdinalIgnoreCase); } private static TextMeshProUGUI? FindReferenceText(Transform root) { Transform val = root.Find("Menu Button - Leave/ButtonText") ?? root.Find("Menu Button - Settings/ButtonText"); if (!((Object)(object)val != (Object)null)) { return null; } return ((Component)val).GetComponent<TextMeshProUGUI>(); } private static Transform? FindExistingCounter(Transform root) { Transform[] componentsInChildren = ((Component)root).GetComponentsInChildren<Transform>(true); foreach (Transform val in componentsInChildren) { if ((Object)(object)val != (Object)null && string.Equals(((Object)val).name, "PlayerCountFixedTextLobby", StringComparison.Ordinal)) { return val; } } return null; } private static void EnsureUpdater(GameObject go, TextMeshProUGUI? text) { if (!((Object)(object)go == (Object)null) && !((Object)(object)text == (Object)null)) { (go.GetComponent<PlayerCountFixedUpdater>() ?? go.AddComponent<PlayerCountFixedUpdater>()).SetText(text); } } internal void LogUpdateFailureOnce(Exception ex) { if (!_loggedUpdateFailure) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Player count update failed; suppressing further update errors. " + ex.GetType().Name + ": " + ex.Message)); _loggedUpdateFailure = true; } } private void LogUiAttachFailureOnce(Exception ex) { if (!_loggedUiAttachFailure) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Lobby player count UI attach failed; suppressing further attach errors. " + ex.GetType().Name + ": " + ex.Message)); _loggedUiAttachFailure = true; } } private void LogUiConfigFailureOnce(Exception ex) { if (!_loggedUiConfigFailure) { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Lobby player count UI config reload failed; suppressing further config reload errors. " + ex.GetType().Name + ": " + ex.Message)); _loggedUiConfigFailure = true; } } } }