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 LoadingWidgetREPO v1.1.0
LoadingWidgetREPO.dll
Decompiled 16 hours agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using SharePermissions.Api; 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: IgnoresAccessChecksTo("")] [assembly: AssemblyCompany("RED")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0+f24bd4d21a83945fba67665512fa40eae241bd04")] [assembly: AssemblyProduct("LoadingWidgetREPO")] [assembly: AssemblyTitle("LoadingWidgetREPO")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.1.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 LoadingWidget { internal interface IPanelBackend { bool ShowLoadingPanel { get; } bool LocalCanModerate { get; } bool PendingLobbyReturn { get; } bool IsMasterOrSingleplayer { get; } float VolumeMax { get; } int RoleTier(Player? player); float VoiceAmplitude(int actorNumber); float VolumeFactor(int actorNumber); void SetVolume(int actorNumber, float factor); string SanitizeName(string? name, string? fallback = "Unknown"); bool CanKick(PlayerAvatar target); bool CanKickActor(Player target); void Kick(PlayerAvatar target, bool ban); void KickGhost(Player ghost, bool ban); void BackToLobby(); void ForceLobbyReload(); void Tick(); void ResetSession(); } internal static class Bridge { private sealed class InertBackend : IPanelBackend { public bool ShowLoadingPanel => false; public bool LocalCanModerate => false; public bool PendingLobbyReturn => false; public bool IsMasterOrSingleplayer => false; public float VolumeMax => 2f; public int RoleTier(Player? player) { return 0; } public float VoiceAmplitude(int actorNumber) { return 0f; } public float VolumeFactor(int actorNumber) { return 1f; } public void SetVolume(int actorNumber, float factor) { } public string SanitizeName(string? name, string? fallback = "Unknown") { return name ?? fallback ?? ""; } public bool CanKick(PlayerAvatar target) { return false; } public bool CanKickActor(Player target) { return false; } public void Kick(PlayerAvatar target, bool ban) { } public void KickGhost(Player ghost, bool ban) { } public void BackToLobby() { } public void ForceLobbyReload() { } public void Tick() { } public void ResetSession() { } } private static IPanelBackend active = new InertBackend(); internal static bool ShowLoadingPanel => active.ShowLoadingPanel; internal static bool LocalCanModerate => active.LocalCanModerate; internal static bool PendingLobbyReturn => active.PendingLobbyReturn; internal static bool IsMasterOrSingleplayer => active.IsMasterOrSingleplayer; internal static float VolumeMax => active.VolumeMax; internal static void Select(IPanelBackend backend) { active = backend; } internal static int RoleTier(Player? player) { return active.RoleTier(player); } internal static float VoiceAmplitude(int actorNumber) { return active.VoiceAmplitude(actorNumber); } internal static float VolumeFactor(int actorNumber) { return active.VolumeFactor(actorNumber); } internal static void SetVolume(int actorNumber, float factor) { active.SetVolume(actorNumber, factor); } internal static string SanitizeName(string? name, string? fallback = "Unknown") { return active.SanitizeName(name, fallback); } internal static bool CanKick(PlayerAvatar target) { return active.CanKick(target); } internal static bool CanKickActor(Player target) { return active.CanKickActor(target); } internal static void Kick(PlayerAvatar target, bool ban) { active.Kick(target, ban); } internal static void KickGhost(Player ghost, bool ban) { active.KickGhost(ghost, ban); } internal static void BackToLobby() { active.BackToLobby(); } internal static void ForceLobbyReload() { active.ForceLobbyReload(); } internal static void Tick() { active.Tick(); } internal static void ResetSession() { active.ResetSession(); } } [HarmonyPatch(typeof(NetworkConnect), "OnDisconnected")] internal static class DisconnectReset { [HarmonyPostfix] [HarmonyWrapSafe] private static void OnDisconnected_Postfix() { LoadingPanel.ResetSession(); Bridge.ResetSession(); } } internal sealed class LoadingPanel : MonoBehaviour { private enum LoadState { Loading, Generating, Loaded, Ready } private sealed class TextButton { internal readonly GameObject Go; internal readonly RectTransform Rect; private readonly TMP_Text tmp; private float clickFlashUntil; private string label = ""; internal bool Danger; internal string Label { get { return label; } set { if (label != value) { label = value; tmp.text = value; } } } internal TextButton(GameObject go, TMP_Text tmp) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown Go = go; Rect = (RectTransform)go.transform; this.tmp = tmp; } internal void SetVisible(bool visible) { SetActiveIfChanged(Go, visible); } internal bool Tick(ref bool anyHover, Image? hoverFill) { //IL_0027: 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_0065: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) bool hovered; bool flashing; bool result = TickHit(Go, Rect, ref clickFlashUntil, ref anyHover, hoverFill, out hovered, out flashing); if (flashing) { ((Graphic)tmp).color = LoadingWidgetStyle.NativeBtnClick; } else if (hovered) { ((Graphic)tmp).color = (Danger ? LoadingWidgetStyle.DangerTextHover : LoadingWidgetStyle.NativeBtnHover); } else { ((Graphic)tmp).color = (Danger ? LoadingWidgetStyle.DangerText : LoadingWidgetStyle.NativeBtnIdle); } return result; } } private sealed class IconButton { internal readonly GameObject Go; internal readonly RectTransform Rect; private readonly GameObject kebab; private readonly GameObject close; private readonly Image[] kebabParts; private readonly Image[] closeParts; private float clickFlashUntil; private bool expanded; internal IconButton(GameObject go, GameObject kebab, Image[] kebabParts, GameObject close, Image[] closeParts) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Expected O, but got Unknown Go = go; Rect = (RectTransform)go.transform; this.kebab = kebab; this.kebabParts = kebabParts; this.close = close; this.closeParts = closeParts; SetExpanded(value: false); } internal void SetVisible(bool visible) { SetActiveIfChanged(Go, visible); } internal void SetExpanded(bool value) { expanded = value; SetActiveIfChanged(kebab, !value); SetActiveIfChanged(close, value); } internal bool Tick(ref bool anyHover, Image? hoverFill) { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_002b: 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) //IL_0062: Unknown result type (might be due to invalid IL or missing references) bool hovered; bool flashing; bool result = TickHit(Go, Rect, ref clickFlashUntil, ref anyHover, hoverFill, out hovered, out flashing); Color color = (flashing ? LoadingWidgetStyle.NativeBtnClick : (hovered ? LoadingWidgetStyle.NativeBtnHover : LoadingWidgetStyle.NativeBtnIdle)); Image[] array = (expanded ? closeParts : kebabParts); Image[] array2 = array; foreach (Image val in array2) { ((Graphic)val).color = color; } return result; } } private sealed class RowWidget { internal const float BarW = 130f; internal const float BarH = 12f; internal GameObject Go; internal RectTransform Rect; internal readonly GameObject?[] RoleIcons = (GameObject?[])(object)new GameObject[4]; internal TMP_Text State; internal TMP_Text Name; internal Image BarTrack; internal Image BarFill; internal IconButton More; private int lastTier = -1; internal float LastY = float.NaN; internal float LastBarW; internal int LastNameActor = -1; internal string? LastRawName; internal bool LastIsLocal; internal void SetVisible(bool visible) { SetActiveIfChanged(Go, visible); } internal void SetTier(int tier) { if (tier == lastTier) { return; } lastTier = tier; for (int i = 0; i < RoleIcons.Length; i++) { GameObject val = RoleIcons[i]; if ((Object)(object)val != (Object)null) { SetActiveIfChanged(val, i == tier); } } } } private sealed class ExpansionWidget { internal const float TrackW = 220f; internal const float TrackH = 10f; internal GameObject Go; internal RectTransform Rect; internal TextButton Kick; internal TextButton Ban; internal Image SliderTrack; internal Image SliderFill; internal RectTransform SliderHit; internal RectTransform Thumb; internal TMP_Text Percent; internal float LastFill = -1f; internal int LastPercent = -1; internal void SetVisible(bool visible) { SetActiveIfChanged(Go, visible); } } private static LoadingPanel? instance; private const float LobbyArmSeconds = 3f; private const float LoudnessScale = 5f; private const float SmoothSpeed = 12f; private const float ClickFlashSeconds = 0.12f; private const float ReloadSearchSeconds = 0.25f; private const float FontRetrySeconds = 0.5f; private const float PanelStuckSeconds = 35f; private const int MaxRows = 20; private const float PanelW = 620f; private const float RowH = 42f; private const float HeaderH = 52f; private const float Pad = 16f; private const float FontHeader = 30f; private const float FontRow = 24f; private const float FontSmall = 18f; private static bool windowOpen; private static readonly Dictionary<int, float> Loudness = new Dictionary<int, float>(); private static int expandedActor = -1; private static float lobbyArmedUntil; private static int lastBailMode; private static int sliderDragActor = -1; private static int lastHeaderLoaded = -1; private static int lastHeaderTotal = -1; private static bool lastHeaderStuck; private static readonly Dictionary<int, PlayerAvatar> ActorAvatars = new Dictionary<int, PlayerAvatar>(); private static readonly HashSet<int> SceneLoadedActors = new HashSet<int>(); private static readonly HashSet<int> SpawnedReadyActors = new HashSet<int>(); private static readonly HashSet<int> EnemyReadyActors = new HashSet<int>(); private static readonly HashSet<int> ReloadReadyActors = new HashSet<int>(); private static bool levelGeneratorPresent; private static bool levelGenerated; private static bool levelHasEnemies; private static bool gameStuck; private static bool loadStuck; private static float windowOpenSince = -1f; private static bool reloadScenePresent; private static bool outroInFlight; private static bool inReloadGap; private static ReloadScene? reloadSceneCache; private static float nextReloadSearchTime; private GameObject? root; private Canvas? canvas; private RectTransform? panelRect; private TMP_Text? headerText; private TextButton? lobbyButton; private Image? hoverFill; private RectTransform? cursorRect; private readonly RowWidget[] rows = new RowWidget[20]; private readonly LoadState[] frameStates = new LoadState[20]; private ExpansionWidget? expansion; private static TMP_FontAsset? gameFont; private static float nextFontAttemptTime; private readonly List<TMP_Text> allTexts = new List<TMP_Text>(); private static bool updateFaulted; private static float nextDiagTime; private static int outroEndValue; private static int outroEndWaitValue; private static bool outroEnumResolved; private static bool outroTierAlive; internal static void Init() { //IL_0013: 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_0021: Expected O, but got Unknown if (!((Object)(object)instance != (Object)null)) { GameObject val = new GameObject("LoadingWidgetPanel") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)(object)val); instance = val.AddComponent<LoadingPanel>(); } } private void Awake() { BuildUi(); } private void Update() { Bridge.Tick(); try { UpdateCore(); } catch (Exception arg) { if ((Object)(object)root != (Object)null && root.activeSelf) { root.SetActive(false); } if ((Object)(object)cursorRect != (Object)null && ((Component)cursorRect).gameObject.activeSelf) { ((Component)cursorRect).gameObject.SetActive(false); } if (!updateFaulted) { updateFaulted = true; Plugin.Logger.LogWarning((object)$"LoadingPanel update failed (bridge or game drift?) - panel hidden: {arg}"); } } } private void UpdateCore() { bool flag = Bridge.ShowLoadingPanel && IsLevelLoading(); if ((Object)(object)root == (Object)null) { return; } SetActiveIfChanged(root, flag); if ((Object)(object)cursorRect != (Object)null) { SetActiveIfChanged(((Component)cursorRect).gameObject, flag); } if (!flag) { sliderDragActor = -1; lobbyArmedUntil = 0f; expandedActor = -1; windowOpenSince = -1f; Loudness.Clear(); return; } try { CursorUnlockRaw(); } catch { } try { DisablePlayerInputRaw(); } catch { } EnsureFont(); ActorAvatars.Clear(); try { BuildActorAvatarMap(); } catch { } BuildLoadSnapshot(); Player[] playerList = PhotonNetwork.PlayerList; SmoothLoudness(playerList); SyncAndDraw(playerList); UpdateCursor(); } private void SmoothLoudness(Player[] players) { float num = Time.deltaTime * 12f; foreach (Player val in players) { float num2 = Mathf.Clamp01(Bridge.VoiceAmplitude(val.ActorNumber) * 5f); Loudness.TryGetValue(val.ActorNumber, out var value); Loudness[val.ActorNumber] = Mathf.Lerp(value, num2, num); } } private void SyncAndDraw(Player[] players) { //IL_02c2: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_034d: Unknown result type (might be due to invalid IL or missing references) //IL_0396: Unknown result type (might be due to invalid IL or missing references) bool anyHover = false; LogDiagnostics(players); int num = 0; for (int i = 0; i < players.Length; i++) { LoadState loadState = StateOf(players[i].ActorNumber); if (i < 20) { frameStates[i] = loadState; } if (loadState == LoadState.Loaded || loadState == LoadState.Ready) { num++; } } if (num != lastHeaderLoaded || players.Length != lastHeaderTotal || loadStuck != lastHeaderStuck) { lastHeaderLoaded = num; lastHeaderTotal = players.Length; lastHeaderStuck = loadStuck; string text = (loadStuck ? "#F0736B" : "#FF8500"); string text2 = (loadStuck ? string.Format(" <size={0}><color={1}>STUCK</color></size>", 18, "#F0736B") : ""); SetText(headerText, $"PLAYERS LOADED <color={text}>{num}/{players.Length}</color>{text2}"); } if (lobbyButton != null) { bool localCanModerate = Bridge.LocalCanModerate; lobbyButton.SetVisible(localCanModerate); if (!localCanModerate) { lobbyArmedUntil = 0f; } else { bool pendingLobbyReturn = Bridge.PendingLobbyReturn; int num2 = ((pendingLobbyReturn && Bridge.IsMasterOrSingleplayer) ? 1 : (pendingLobbyReturn ? 2 : 0)); if (num2 != lastBailMode) { lobbyArmedUntil = 0f; lastBailMode = num2; } bool flag = num2 != 2 && Time.time < lobbyArmedUntil; if (!flag) { lobbyArmedUntil = 0f; } lobbyButton.Danger = num2 == 1 || flag || loadStuck; TextButton textButton = lobbyButton; textButton.Label = num2 switch { 1 => flag ? "FORCE?" : "FORCE", 2 => "QUEUED", _ => flag ? "LOBBY?" : "LOBBY", }; if (lobbyButton.Tick(ref anyHover, hoverFill) && num2 != 2) { if (!flag) { lobbyArmedUntil = Time.time + 3f; } else { lobbyArmedUntil = 0f; if (num2 == 1) { Bridge.ForceLobbyReload(); } else { Bridge.BackToLobby(); } } } } } int num3 = Mathf.Min(players.Length, 20); bool flag2 = false; int num4 = -1; for (int j = 0; j < num3; j++) { if (players[j].ActorNumber == expandedActor) { flag2 = true; num4 = j; break; } } if (!flag2) { expandedActor = -1; } float num5 = 68f + (float)num3 * 42f + (flag2 ? 42f : 0f) + 16f; if ((Object)(object)panelRect != (Object)null && !Mathf.Approximately(panelRect.sizeDelta.y, num5)) { panelRect.sizeDelta = new Vector2(620f, num5); } float num6 = -68f; for (int k = 0; k < 20; k++) { RowWidget rowWidget = rows[k]; bool flag3 = k < num3; rowWidget.SetVisible(flag3); if (flag3) { Player p = players[k]; bool flag4 = k == num4; if (rowWidget.LastY != num6) { rowWidget.LastY = num6; rowWidget.Rect.anchoredPosition = new Vector2(0f, num6); } DrawRow(rowWidget, p, frameStates[k], flag4, ref anyHover); num6 -= 42f; if (flag4 && expansion != null) { expansion.Rect.anchoredPosition = new Vector2(0f, num6); DrawExpansion(p, ref anyHover); num6 -= 42f; } } } expansion?.SetVisible(flag2); if (!anyHover && (Object)(object)hoverFill != (Object)null) { ((Behaviour)hoverFill).enabled = false; } } private void DrawRow(RowWidget row, Player p, LoadState state, bool expanded, ref bool anyHover) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Unknown result type (might be due to invalid IL or missing references) int actorNumber = p.ActorNumber; ActorAvatars.TryGetValue(actorNumber, out PlayerAvatar value); row.SetTier(Bridge.RoleTier(p)); SetText(row.State, StateLabel(state)); ((Graphic)row.State).color = StateColor(state, loadStuck && IsBlocking(state)); string text = NameOf(value, p); if (row.LastNameActor != actorNumber || row.LastIsLocal != p.IsLocal || row.LastRawName != text) { row.LastNameActor = actorNumber; row.LastIsLocal = p.IsLocal; row.LastRawName = text; string text2 = Bridge.SanitizeName(text, $"Player_{actorNumber}"); SetText(row.Name, p.IsLocal ? (text2 + " <color=#9aa4ad>(you)</color>") : text2); } ((Behaviour)row.BarTrack).enabled = !expanded; ((Behaviour)row.BarFill).enabled = !expanded; if (!expanded) { Loudness.TryGetValue(actorNumber, out var value2); if (value2 < 0.005f) { value2 = 0f; } float num = 130f * Mathf.Clamp01(value2); if (row.LastBarW != num) { row.LastBarW = num; ((Graphic)row.BarFill).rectTransform.sizeDelta = new Vector2(num, 12f); } ((Graphic)row.BarFill).color = ((value2 > 0.02f) ? LoadingWidgetStyle.GetVolumeColor(value2) : Color.clear); } row.More.SetVisible(!p.IsLocal); row.More.SetExpanded(expanded); if (!p.IsLocal && row.More.Tick(ref anyHover, hoverFill)) { expandedActor = (expanded ? (-1) : actorNumber); } } private void DrawExpansion(Player p, ref bool anyHover) { //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: 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_0104: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_011e: 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) if (expansion == null) { return; } int actorNumber = p.ActorNumber; ActorAvatars.TryGetValue(actorNumber, out PlayerAvatar value); bool flag = (((Object)(object)value != (Object)null) ? Bridge.CanKick(value) : Bridge.CanKickActor(p)); expansion.Kick.SetVisible(flag); expansion.Ban.SetVisible(flag); if (flag) { if (expansion.Kick.Tick(ref anyHover, hoverFill)) { DoKick(p, value, ban: false); } if (expansion.Ban.Tick(ref anyHover, hoverFill)) { DoKick(p, value, ban: true); } } float num = Bridge.VolumeFactor(actorNumber); RectTransform rectTransform = ((Graphic)expansion.SliderTrack).rectTransform; if (Input.GetMouseButtonDown(0) && Hovered(expansion.SliderHit)) { sliderDragActor = actorNumber; } if (sliderDragActor == actorNumber) { Vector2 val = default(Vector2); if (!Input.GetMouseButton(0)) { sliderDragActor = -1; } else if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rectTransform, Vector2.op_Implicit(Input.mousePosition), (Camera)null, ref val)) { float x = val.x; Rect rect = rectTransform.rect; float num2 = x - ((Rect)(ref rect)).xMin; rect = rectTransform.rect; float num3 = Mathf.Clamp01(num2 / ((Rect)(ref rect)).width); num = num3 * Bridge.VolumeMax; Bridge.SetVolume(actorNumber, num); } } float num4 = Mathf.Clamp01(num / Bridge.VolumeMax); if (expansion.LastFill != num4) { expansion.LastFill = num4; ((Graphic)expansion.SliderFill).rectTransform.sizeDelta = new Vector2(220f * num4, 10f); expansion.Thumb.anchoredPosition = new Vector2(220f * num4, 0f); } int num5 = Mathf.RoundToInt(num * 100f); if (expansion.LastPercent != num5) { expansion.LastPercent = num5; SetText(expansion.Percent, $"{num5}%"); } } private static void DoKick(Player p, PlayerAvatar? avatar, bool ban) { expandedActor = -1; if ((Object)(object)avatar != (Object)null) { Bridge.Kick(avatar, ban); } else { Bridge.KickGhost(p, ban); } } private void UpdateCursor() { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)cursorRect == (Object)null)) { float num = (((Object)(object)canvas != (Object)null) ? canvas.scaleFactor : 1f); cursorRect.anchoredPosition = Vector2.op_Implicit(Input.mousePosition) / num; } } private static bool Hovered(RectTransform rt) { //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) return RectTransformUtility.RectangleContainsScreenPoint(rt, Vector2.op_Implicit(Input.mousePosition), (Camera)null); } private static void SetActiveIfChanged(GameObject go, bool value) { if (go.activeSelf != value) { go.SetActive(value); } } private static bool TickHit(GameObject go, RectTransform rect, ref float clickFlashUntil, ref bool anyHover, Image? hoverFill, out bool hovered, out bool flashing) { //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_007e: 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_008f: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) hovered = go.activeSelf && Hovered(rect); bool flag = hovered && Input.GetMouseButtonDown(0); if (flag) { clickFlashUntil = Time.unscaledTime + 0.12f; } flashing = Time.unscaledTime < clickFlashUntil; if (hovered && (Object)(object)hoverFill != (Object)null) { anyHover = true; ((Behaviour)hoverFill).enabled = true; RectTransform rectTransform = ((Graphic)hoverFill).rectTransform; ((Transform)rectTransform).position = ((Transform)rect).position; rectTransform.sizeDelta = rect.sizeDelta + new Vector2(8f, 4f); rectTransform.anchoredPosition += new Vector2(-4f, 2f); } return flag; } private void BuildUi() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown //IL_005e: 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: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_0100: 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_0119: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_01af: Unknown result type (might be due to invalid IL or missing references) //IL_01be: 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_0215: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Expected O, but got Unknown //IL_022e: 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_0234: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_024d: 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_0286: Unknown result type (might be due to invalid IL or missing references) //IL_02a1: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("Canvas"); val.transform.SetParent(((Component)this).transform, false); canvas = val.AddComponent<Canvas>(); canvas.renderMode = (RenderMode)0; canvas.sortingOrder = 32700; CanvasScaler val2 = val.AddComponent<CanvasScaler>(); val2.uiScaleMode = (ScaleMode)1; val2.referenceResolution = new Vector2(1920f, 1080f); val2.matchWidthOrHeight = 1f; root = new GameObject("Panel"); root.transform.SetParent(val.transform, false); panelRect = root.AddComponent<RectTransform>(); panelRect.sizeDelta = new Vector2(620f, 200f); MakeImage(root, new Color(0f, 0f, 0f, 0.35f)); hoverFill = MakeImage(Child(root, "HoverFill", new Vector2(0f, 0f), new Vector2(10f, 10f)), LoadingWidgetStyle.NativeHoverFill); ((Behaviour)hoverFill).enabled = false; headerText = MakeText(Child(root, "Header", TopLeft(20f, -16f), new Vector2(455f, 52f)), 30f, (TextAlignmentOptions)4097); ((Graphic)headerText).color = Color.white; headerText.characterSpacing = 4f; lobbyButton = MakeButton(root, "Lobby", TopLeft(484f, -22f), new Vector2(120f, 34f), 20f); for (int i = 0; i < 20; i++) { rows[i] = BuildRow(i); } expansion = BuildExpansion(); GameObject val3 = Child(val, "Cursor", Vector2.zero, new Vector2(14f, 14f)); RectTransform val4 = (RectTransform)val3.transform; Vector2 anchorMin = (val4.anchorMax = Vector2.zero); val4.anchorMin = anchorMin; val4.pivot = new Vector2(0.5f, 0.5f); ((Transform)val4).localRotation = Quaternion.Euler(0f, 0f, 45f); MakeImage(val3, new Color(0f, 0f, 0f, 0.9f)); GameObject go = Child(val3, "Inner", new Vector2(3f, -3f), new Vector2(8f, 8f)); MakeImage(go, Color.white); cursorRect = val4; val3.SetActive(false); root.SetActive(false); } private RowWidget BuildRow(int index) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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) //IL_005b: Expected O, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: 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_00a0: 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_00c0: 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_00e0: 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_0146: Unknown result type (might be due to invalid IL or missing references) //IL_016a: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_01de: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Unknown result type (might be due to invalid IL or missing references) //IL_021b: 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_023b: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Expected O, but got Unknown //IL_024c: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_0279: Unknown result type (might be due to invalid IL or missing references) //IL_0288: Unknown result type (might be due to invalid IL or missing references) RowWidget rowWidget = new RowWidget(); rowWidget.Go = Child(root, $"Row{index}", TopLeft(0f, 0f), new Vector2(620f, 42f)); rowWidget.Rect = (RectTransform)rowWidget.Go.transform; Vector2 center = default(Vector2); ((Vector2)(ref center))..ctor(31f, -21f); rowWidget.RoleIcons[0] = BuildRoleIcon(rowWidget.Go, center, 9f, LoadingWidgetStyle.RoleNone, pip: false); rowWidget.RoleIcons[1] = BuildRoleIcon(rowWidget.Go, center, 13f, LoadingWidgetStyle.RoleModUser, pip: false); rowWidget.RoleIcons[2] = BuildRoleIcon(rowWidget.Go, center, 16f, LoadingWidgetStyle.RoleModerator, pip: false); rowWidget.RoleIcons[3] = BuildRoleIcon(rowWidget.Go, center, 19f, LoadingWidgetStyle.RoleHost, pip: true); GameObject[] roleIcons = rowWidget.RoleIcons; foreach (GameObject val in roleIcons) { if ((Object)(object)val != (Object)null) { val.SetActive(false); } } rowWidget.Name = MakeText(Child(rowWidget.Go, "Name", TopLeft(48f, 0f), new Vector2(230f, 42f)), 24f, (TextAlignmentOptions)4097); ((Graphic)rowWidget.Name).color = Color.white; rowWidget.State = MakeText(Child(rowWidget.Go, "State", TopLeft(280f, 0f), new Vector2(130f, 42f)), 18f, (TextAlignmentOptions)4097); rowWidget.State.characterSpacing = 2f; rowWidget.BarTrack = MakeImage(Child(rowWidget.Go, "BarTrack", TopLeft(420f, -15f), new Vector2(130f, 12f)), LoadingWidgetStyle.BarTrack); GameObject val2 = Child(rowWidget.Go, "BarFill", TopLeft(420f, -15f), new Vector2(0f, 12f)); RectTransform val3 = (RectTransform)val2.transform; val3.pivot = new Vector2(0f, 1f); rowWidget.BarFill = MakeImage(val2, Color.clear); rowWidget.More = BuildIconButton(rowWidget.Go, TopLeft(568f, -4f), new Vector2(36f, 34f)); return rowWidget; } private ExpansionWidget BuildExpansion() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown //IL_0066: 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_00b5: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: 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_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_016e: 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_0186: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) //IL_01b4: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01ce: Expected O, but got Unknown //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01f0: 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_0212: Unknown result type (might be due to invalid IL or missing references) //IL_023b: Unknown result type (might be due to invalid IL or missing references) //IL_024a: 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_0263: Expected O, but got Unknown //IL_027a: 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_02ad: Unknown result type (might be due to invalid IL or missing references) //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02dd: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Unknown result type (might be due to invalid IL or missing references) ExpansionWidget expansionWidget = new ExpansionWidget(); expansionWidget.Go = Child(root, "Expansion", TopLeft(0f, 0f), new Vector2(620f, 42f)); expansionWidget.Rect = (RectTransform)expansionWidget.Go.transform; TMP_Text val = MakeText(Child(expansionWidget.Go, "VolLabel", TopLeft(46f, 0f), new Vector2(100f, 42f)), 18f, (TextAlignmentOptions)4097); val.text = "VOLUME"; val.characterSpacing = 2f; ((Graphic)val).color = new Color(0.55f, 0.6f, 0.64f); float y = -16f; expansionWidget.SliderTrack = MakeImage(Child(expansionWidget.Go, "Track", TopLeft(160f, y), new Vector2(220f, 10f)), LoadingWidgetStyle.BarTrack); GameObject val2 = Child(((Component)expansionWidget.SliderTrack).gameObject, "Fill", Vector2.zero, new Vector2(0f, 10f)); RectTransform val3 = (RectTransform)val2.transform; val3.anchorMin = new Vector2(0f, 0.5f); val3.anchorMax = new Vector2(0f, 0.5f); val3.pivot = new Vector2(0f, 0.5f); val3.anchoredPosition = Vector2.zero; expansionWidget.SliderFill = MakeImage(val2, LoadingWidgetStyle.NativeAccent); GameObject val4 = Child(((Component)expansionWidget.SliderTrack).gameObject, "Thumb", Vector2.zero, new Vector2(12f, 20f)); RectTransform val5 = (RectTransform)val4.transform; val5.anchorMin = new Vector2(0f, 0.5f); val5.anchorMax = new Vector2(0f, 0.5f); val5.pivot = new Vector2(0.5f, 0.5f); MakeImage(val4, Color.white); expansionWidget.Thumb = val5; expansionWidget.SliderHit = (RectTransform)Child(expansionWidget.Go, "TrackHit", TopLeft(160f, 0f), new Vector2(220f, 42f)).transform; expansionWidget.Percent = MakeText(Child(expansionWidget.Go, "Percent", TopLeft(392f, 0f), new Vector2(70f, 42f)), 18f, (TextAlignmentOptions)4097); ((Graphic)expansionWidget.Percent).color = Color.white; expansionWidget.Kick = MakeButton(expansionWidget.Go, "KICK", TopLeft(460f, -4f), new Vector2(70f, 34f), 18f); expansionWidget.Kick.Danger = true; expansionWidget.Ban = MakeButton(expansionWidget.Go, "BAN", TopLeft(536f, -4f), new Vector2(60f, 34f), 18f); expansionWidget.Ban.Danger = true; expansionWidget.Go.SetActive(false); return expansionWidget; } private static Vector2 TopLeft(float x, float y) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return new Vector2(x, y); } private static GameObject Child(GameObject parent, string name, Vector2 pos, Vector2 size) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0067: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent.transform, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.anchorMin = new Vector2(0f, 1f); val2.anchorMax = new Vector2(0f, 1f); val2.pivot = new Vector2(0f, 1f); val2.anchoredPosition = pos; val2.sizeDelta = size; return val; } private static Image MakeImage(GameObject go, Color color) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) Image val = go.AddComponent<Image>(); ((Graphic)val).color = color; ((Graphic)val).raycastTarget = false; return val; } private TMP_Text MakeText(GameObject go, float size, TextAlignmentOptions align) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI val = go.AddComponent<TextMeshProUGUI>(); ((TMP_Text)val).fontSize = size; ((TMP_Text)val).alignment = align; ((TMP_Text)val).richText = true; ((Graphic)val).raycastTarget = false; ((TMP_Text)val).enableWordWrapping = false; ((TMP_Text)val).overflowMode = (TextOverflowModes)1; if ((Object)(object)gameFont != (Object)null) { ((TMP_Text)val).font = gameFont; } allTexts.Add((TMP_Text)(object)val); return (TMP_Text)(object)val; } private TextButton MakeButton(GameObject parent, string label, Vector2 pos, Vector2 size, float fontSize) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000d: Unknown result type (might be due to invalid IL or missing references) GameObject go = Child(parent, "Btn_" + label, pos, size); TMP_Text tmp = MakeText(go, fontSize, (TextAlignmentOptions)4098); return new TextButton(go, tmp) { Label = label }; } private static GameObject CenteredChild(GameObject parent, string name, Vector2 center, Vector2 size) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0067: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent.transform, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.anchorMin = new Vector2(0f, 1f); val2.anchorMax = new Vector2(0f, 1f); val2.pivot = new Vector2(0.5f, 0.5f); val2.anchoredPosition = center; val2.sizeDelta = size; return val; } private static GameObject InnerGlyph(GameObject parent, string name, Vector2 offset, Vector2 size) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0055: 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_0067: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent.transform, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.anchorMin = new Vector2(0.5f, 0.5f); val2.anchorMax = new Vector2(0.5f, 0.5f); val2.pivot = new Vector2(0.5f, 0.5f); val2.anchoredPosition = offset; val2.sizeDelta = size; return val; } private static GameObject FillChild(GameObject parent, string name) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Expected O, but got Unknown //IL_0021: 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_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent.transform, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; val2.pivot = new Vector2(0.5f, 0.5f); return val; } private GameObject BuildRoleIcon(GameObject parent, Vector2 center, float size, Color color, bool pip) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_0029: 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_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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) GameObject val = CenteredChild(parent, "RoleIcon", center, new Vector2(size, size)); val.transform.localRotation = Quaternion.Euler(0f, 0f, 45f); MakeImage(val, color); if (pip) { GameObject go = InnerGlyph(val, "Pip", Vector2.zero, new Vector2(size * 0.42f, size * 0.42f)); MakeImage(go, new Color(1f, 1f, 1f, 0.92f)); } return val; } private IconButton BuildIconButton(GameObject parent, Vector2 pos, Vector2 size) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: 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_00e5: 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) GameObject val = Child(parent, "Btn_More", pos, size); GameObject val2 = FillChild(val, "Kebab"); Image[] array = (Image[])(object)new Image[3]; for (int i = 0; i < 3; i++) { GameObject go = InnerGlyph(val2, $"Dot{i}", new Vector2(0f, (float)(1 - i) * 7f), new Vector2(5f, 5f)); array[i] = MakeImage(go, LoadingWidgetStyle.NativeBtnIdle); } GameObject val3 = FillChild(val, "Close"); Image[] array2 = (Image[])(object)new Image[2]; for (int j = 0; j < 2; j++) { GameObject val4 = InnerGlyph(val3, $"Bar{j}", Vector2.zero, new Vector2(18f, 3f)); val4.transform.localRotation = Quaternion.Euler(0f, 0f, (j == 0) ? 45f : (-45f)); array2[j] = MakeImage(val4, LoadingWidgetStyle.NativeBtnIdle); } return new IconButton(val, val2, array, val3, array2); } private static void SetText(TMP_Text? tmp, string text) { if ((Object)(object)tmp != (Object)null && tmp.text != text) { tmp.text = text; } } private void EnsureFont() { if ((Object)(object)gameFont != (Object)null || Time.unscaledTime < nextFontAttemptTime) { return; } nextFontAttemptTime = Time.unscaledTime + 0.5f; try { gameFont = ResolveFontRaw(); } catch { } if ((Object)(object)gameFont == (Object)null) { try { gameFont = ResolveFontFallbackRaw(); } catch { } } if ((Object)(object)gameFont == (Object)null) { return; } foreach (TMP_Text allText in allTexts) { if ((Object)(object)allText != (Object)null) { allText.font = gameFont; } } } [MethodImpl(MethodImplOptions.NoInlining)] private static TMP_FontAsset? ResolveFontRaw() { LoadingUI val = LoadingUI.instance; if ((Object)(object)val == (Object)null) { return null; } if ((Object)(object)val.levelNumberText != (Object)null && (Object)(object)((TMP_Text)val.levelNumberText).font != (Object)null) { return ((TMP_Text)val.levelNumberText).font; } if ((Object)(object)val.levelNameText != (Object)null && (Object)(object)((TMP_Text)val.levelNameText).font != (Object)null) { return ((TMP_Text)val.levelNameText).font; } return null; } [MethodImpl(MethodImplOptions.NoInlining)] private static TMP_FontAsset? ResolveFontFallbackRaw() { MenuManager val = MenuManager.instance; if ((Object)(object)val == (Object)null || val.menuPages == null) { return null; } foreach (MenuPages menuPage in val.menuPages) { if (menuPage != null && !((Object)(object)menuPage.menuPage == (Object)null)) { TMP_Text componentInChildren = menuPage.menuPage.GetComponentInChildren<TMP_Text>(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.font != (Object)null) { return componentInChildren.font; } } } return null; } [MethodImpl(MethodImplOptions.NoInlining)] private static void CursorUnlockRaw() { SemiFunc.CursorUnlock(0.1f); } [MethodImpl(MethodImplOptions.NoInlining)] private static bool RunIsLobbyMenuRaw() { return SemiFunc.RunIsLobbyMenu(); } [MethodImpl(MethodImplOptions.NoInlining)] private static bool MenuLevelRaw() { return SemiFunc.MenuLevel(); } [MethodImpl(MethodImplOptions.NoInlining)] private static void DisablePlayerInputRaw() { PlayerController val = PlayerController.instance; if ((Object)(object)val != (Object)null) { val.InputDisableTimer = 0.1f; } } private static LoadState StateOf(int actor) { if (reloadScenePresent) { if (!ReloadReadyActors.Contains(actor)) { return LoadState.Loading; } return LoadState.Loaded; } ActorAvatars.TryGetValue(actor, out PlayerAvatar value); if (!SceneLoadedActors.Contains(actor) && !((Object)(object)value != (Object)null)) { return LoadState.Loading; } if (outroInFlight && (Object)(object)value != (Object)null) { try { if (!AvatarOutroDone(value)) { return LoadState.Loading; } } catch { } } try { if ((Object)(object)value != (Object)null && AvatarReady(value)) { return LoadState.Ready; } } catch { } if (levelGeneratorPresent && !levelGenerated) { if (!SpawnedReadyActors.Contains(actor)) { return LoadState.Generating; } if (levelHasEnemies && !EnemyReadyActors.Contains(actor)) { return LoadState.Generating; } } return LoadState.Loaded; } private static bool IsBlocking(LoadState s) { if (!reloadScenePresent && !outroInFlight) { return s != LoadState.Ready; } return s == LoadState.Loading; } private static Color StateColor(LoadState s, bool stuckBlocker) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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) //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) if (stuckBlocker) { return LoadingWidgetStyle.NativeAccent; } return (Color)(s switch { LoadState.Ready => Color.white, LoadState.Loaded => new Color(0.78f, 0.8f, 0.82f), LoadState.Generating => LoadingWidgetStyle.StateGenerating, _ => LoadingWidgetStyle.NativeAccent, }); } private static string StateLabel(LoadState s) { return s switch { LoadState.Ready => "READY", LoadState.Loaded => "LOADED", LoadState.Generating => "BUILDING", _ => "LOADING", }; } private static string NameOf(PlayerAvatar? avatar, Player p) { if ((Object)(object)avatar != (Object)null) { try { return AvatarName(avatar); } catch { } } return p.NickName; } private void LogDiagnostics(Player[] players) { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) if (Plugin.StateDiagnostics == null || !Plugin.StateDiagnostics.Value || Time.unscaledTime < nextDiagTime) { return; } nextDiagTime = Time.unscaledTime + 2f; try { Scene activeScene = SceneManager.GetActiveScene(); string name = ((Scene)(ref activeScene)).name; Plugin.Logger.LogInfo((object)($"[LoadPanel diag] scene={name} gap={inReloadGap} reloadPresent={reloadScenePresent} outro={outroInFlight} " + $"stuck={loadStuck}(game={gameStuck}) lgPresent={levelGeneratorPresent} generated={levelGenerated} hasEnemies={levelHasEnemies} " + "sceneLoaded=[" + string.Join(",", SceneLoadedActors) + "] spawnedReady=[" + string.Join(",", SpawnedReadyActors) + "] enemyReady=[" + string.Join(",", EnemyReadyActors) + "] reloadReady=[" + string.Join(",", ReloadReadyActors) + "] " + $"queued={Bridge.PendingLobbyReturn}")); foreach (Player val in players) { ActorAvatars.TryGetValue(val.ActorNumber, out PlayerAvatar value); string arg = "n/a"; if ((Object)(object)value != (Object)null) { try { arg = AvatarOutroDone(value).ToString(); } catch { arg = "err"; } } Plugin.Logger.LogInfo((object)($"[LoadPanel diag] actor={val.ActorNumber} name={Bridge.SanitizeName(val.NickName)} " + $"avatar={(Object)(object)value != (Object)null} outroDone={arg} state={StateOf(val.ActorNumber)}")); } } catch { } } private static void BuildLoadSnapshot() { if (windowOpenSince < 0f) { windowOpenSince = Time.unscaledTime; } SceneLoadedActors.Clear(); SpawnedReadyActors.Clear(); EnemyReadyActors.Clear(); ReloadReadyActors.Clear(); try { SnapshotSceneLoaded(); } catch { } try { levelGeneratorPresent = SnapshotLevelProgress(); } catch { levelGeneratorPresent = false; levelHasEnemies = false; levelGenerated = false; } try { gameStuck = LoadingStuckRaw(); } catch { gameStuck = false; } bool flag = Time.unscaledTime - windowOpenSince >= 35f; loadStuck = gameStuck || flag; outroInFlight = OutroNow(); reloadScenePresent = false; if (inReloadGap) { try { reloadScenePresent = SnapshotReloadReady(); } catch { } } } [MethodImpl(MethodImplOptions.NoInlining)] private static void ResolveOutroEnumRaw() { outroEndValue = Convert.ToInt32(Enum.Parse(typeof(gameState), "End")); outroEndWaitValue = Convert.ToInt32(Enum.Parse(typeof(gameState), "EndWait")); } [MethodImpl(MethodImplOptions.NoInlining)] private static bool OutroInFlightRaw() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Expected I4, but got Unknown GameDirector val = GameDirector.instance; if ((Object)(object)val == (Object)null) { return false; } int num = (int)val.currentState; if (num != outroEndValue) { return num == outroEndWaitValue; } return true; } private static void EnsureOutroEnum() { if (outroEnumResolved) { return; } outroEnumResolved = true; try { ResolveOutroEnumRaw(); outroTierAlive = true; } catch { outroTierAlive = false; } } private static bool OutroNow() { EnsureOutroEnum(); if (!outroTierAlive) { return false; } try { return OutroInFlightRaw(); } catch { return false; } } [MethodImpl(MethodImplOptions.NoInlining)] private static bool SnapshotReloadReady() { ReloadScene val = reloadSceneCache; if ((Object)(object)val == (Object)null) { if (Time.unscaledTime < nextReloadSearchTime) { return false; } val = (reloadSceneCache = Object.FindObjectOfType<ReloadScene>()); if ((Object)(object)val == (Object)null) { nextReloadSearchTime = Time.unscaledTime + 0.25f; return false; } } if (val.PlayersReadyList == null) { return false; } foreach (Player playersReady in val.PlayersReadyList) { if (playersReady != null) { ReloadReadyActors.Add(playersReady.ActorNumber); } } return true; } [MethodImpl(MethodImplOptions.NoInlining)] private static bool AvatarOutroDone(PlayerAvatar a) { return a.outroDone; } [MethodImpl(MethodImplOptions.NoInlining)] private static void SnapshotSceneLoaded() { NetworkManager val = NetworkManager.instance; if ((Object)(object)val == (Object)null || val.instantiatedPlayerAvatarsList == null) { return; } foreach (Player instantiatedPlayerAvatars in val.instantiatedPlayerAvatarsList) { if (instantiatedPlayerAvatars != null) { SceneLoadedActors.Add(instantiatedPlayerAvatars.ActorNumber); } } } [MethodImpl(MethodImplOptions.NoInlining)] private static bool SnapshotLevelProgress() { LevelGenerator val = LevelGenerator.Instance; if ((Object)(object)val == (Object)null) { levelHasEnemies = false; levelGenerated = false; return false; } levelGenerated = val.Generated; levelHasEnemies = (Object)(object)val.Level != (Object)null && val.Level.HasEnemies; if (val.SpawnedReadyPlayerList != null) { foreach (Player spawnedReadyPlayer in val.SpawnedReadyPlayerList) { if (spawnedReadyPlayer != null) { SpawnedReadyActors.Add(spawnedReadyPlayer.ActorNumber); } } } if (val.EnemyReadyPlayerList != null) { foreach (Player enemyReadyPlayer in val.EnemyReadyPlayerList) { if (enemyReadyPlayer != null) { EnemyReadyActors.Add(enemyReadyPlayer.ActorNumber); } } } return true; } [MethodImpl(MethodImplOptions.NoInlining)] private static bool AvatarReady(PlayerAvatar a) { return a.levelAnimationCompleted; } [MethodImpl(MethodImplOptions.NoInlining)] private static string AvatarName(PlayerAvatar a) { return a.playerName; } [MethodImpl(MethodImplOptions.NoInlining)] private static void BuildActorAvatarMap() { GameDirector val = GameDirector.instance; if ((Object)(object)val == (Object)null || val.PlayerList == null) { return; } foreach (PlayerAvatar player in val.PlayerList) { if (!((Object)(object)player == (Object)null)) { PhotonView photonView = player.photonView; if ((Object)(object)photonView != (Object)null && photonView.Owner != null) { ActorAvatars[photonView.Owner.ActorNumber] = player; } } } } private static bool IsLevelLoading() { try { if (!PhotonNetwork.InRoom) { ResetWindow(); return false; } int num; try { num = LoadingScreenStateRaw(); } catch { ResetWindow(); return false; } bool flag; try { flag = RunIsLobbyMenuRaw(); } catch { flag = false; } bool flag2; try { flag2 = MenuLevelRaw() && !flag; } catch { flag2 = false; } if (flag2) { ResetWindow(); return false; } if (num == 1) { if (flag && !windowOpen && !OutroNow()) { return false; } inReloadGap = false; windowOpen = true; return true; } if (!windowOpen) { return false; } if (num == -1) { if (PhotonNetwork.InRoom) { inReloadGap = true; return true; } ResetWindow(); return false; } ResetWindow(); return false; } catch { return false; } } [MethodImpl(MethodImplOptions.NoInlining)] private static bool LoadingStuckRaw() { LoadingUI val = LoadingUI.instance; if ((Object)(object)val != (Object)null) { return val.stuckActive; } return false; } [MethodImpl(MethodImplOptions.NoInlining)] private static int LoadingScreenStateRaw() { LoadingUI val = LoadingUI.instance; if ((Object)(object)val == (Object)null) { return -1; } return ((Component)val).gameObject.activeInHierarchy ? 1 : 0; } internal static void ResetSession() { ResetWindow(); } private static void ResetWindow() { windowOpen = false; windowOpenSince = -1f; inReloadGap = false; reloadSceneCache = null; nextReloadSearchTime = 0f; lobbyArmedUntil = 0f; Loudness.Clear(); expandedActor = -1; sliderDragActor = -1; lastHeaderLoaded = -1; lastHeaderTotal = -1; lastHeaderStuck = false; gameStuck = false; loadStuck = false; } private void OnDestroy() { Loudness.Clear(); } } internal static class LoadingWidgetStyle { internal static readonly Color RoleHost = Hex(16765514); internal static readonly Color RoleModerator = Hex(6730495); internal static readonly Color RoleModUser = Hex(10211706); internal static readonly Color RoleNone = Hex(9085104); internal const string DimTimeHex = "#9aa4ad"; internal const string NativeAccentHex = "#FF8500"; internal const string DangerTextHex = "#F0736B"; internal static readonly Color StateGenerating = new Color(0.98f, 0.82f, 0.25f); internal static readonly Color BarTrack = new Color(1f, 1f, 1f, 0.1f); internal static readonly Color DangerText = new Color(0.94f, 0.45f, 0.42f); internal static readonly Color DangerTextHover = new Color(1f, 0.62f, 0.58f); internal static readonly Color NativeBtnIdle = Color.gray; internal static readonly Color NativeBtnHover = Color.white; internal static readonly Color NativeBtnClick = new Color(1f, 0.55f, 0f); internal static readonly Color NativeHoverFill = new Color(0.08f, 0.2f, 0.4f, 0.75f); internal static readonly Color NativeAccent = new Color(1f, 0.522f, 0f); internal static Color GetVolumeColor(float volume) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: 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_0008: 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_002e: Unknown result type (might be due to invalid IL or missing references) if (!(volume < 0.5f)) { return Color.Lerp(Color.yellow, new Color(1f, 0.3f, 0.3f), (volume - 0.5f) * 2f); } return Color.Lerp(new Color(0.3f, 1f, 0.3f), Color.yellow, volume * 2f); } private static Color Hex(int rgb) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) return new Color((float)((rgb >> 16) & 0xFF) / 255f, (float)((rgb >> 8) & 0xFF) / 255f, (float)(rgb & 0xFF) / 255f); } } [BepInPlugin("RED.LoadingWidget", "LoadingWidget", "1.1.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { private Harmony? harmony; internal static ManualLogSource Logger { get; private set; } internal static ConfigEntry<bool>? StateDiagnostics { get; private set; } private void Awake() { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown Logger = ((BaseUnityPlugin)this).Logger; StateDiagnostics = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "StateDiagnostics", false, "Log the [LoadPanel diag] per-player load-state signals every 2s while the panel is visible (for diagnosing wrong LOADING/BUILDING/LOADED/READY states in the field)."); bool standalone; IPanelBackend panelBackend = ResolveBackend(out standalone); if (panelBackend == null) { return; } Bridge.Select(panelBackend); LoadingPanel.Init(); harmony = new Harmony("RED.LoadingWidget"); try { harmony.PatchAll(typeof(DisconnectReset)); } catch (Exception ex) { Logger.LogWarning((object)("DisconnectReset patch failed (game update?): " + ex.Message + " - session reset on disconnect disabled, panel unaffected.")); } if (standalone) { try { harmony.PatchAll(typeof(StandaloneVoice)); } catch (Exception ex2) { Logger.LogWarning((object)("Voice plumbing unavailable (" + ex2.GetType().Name + ") - talking bars and volume disabled")); } } Logger.LogInfo((object)("RED.LoadingWidget v1.1.0 has loaded (" + (standalone ? "standalone" : "SharePermissions bridge") + " mode)!")); } private IPanelBackend? ResolveBackend(out bool standalone) { standalone = false; if (Chainloader.PluginInfos.TryGetValue("RED.SharePermissions", out var value)) { Version version = value.Metadata.Version; if (version < new Version("1.17.0")) { Logger.LogInfo((object)($"SharePermissions {version} found, but its loading panel moved here only in " + "1.17.0 - staying dormant so the panel is not drawn twice. Update SharePermissions (or uninstall it) to activate LoadingWidget.")); return null; } try { SharePermissionsBackend result = SharePermissionsBackend.Create(); Logger.LogInfo((object)$"SharePermissions {version} detected - full integration active"); return result; } catch (Exception ex) { Logger.LogWarning((object)($"SharePermissions {version} is installed but its LoadingWidgetBridge failed to load " + "(" + ex.GetType().Name + ") - falling back to standalone mode")); } } standalone = true; ConfigEntry<bool> showLoadingPanel = ((BaseUnityPlugin)this).Config.Bind<bool>("UI", "ShowLoadingPanel", true, "Show the loading-screen panel during multiplayer level loads (every player running the mod sees it; moderation actions are host-only in standalone mode). When SharePermissions v1.17.0+ is installed, its own UI / ShowLoadingPanel setting governs instead and this entry is ignored."); return new StandaloneBackend(showLoadingPanel); } private void OnDestroy() { Harmony? obj = harmony; if (obj != null) { obj.UnpatchSelf(); } } } internal static class PluginInfo { internal const string Guid = "RED.LoadingWidget"; internal const string Name = "LoadingWidget"; internal const string Version = "1.1.0"; internal const string SharePermissionsGuid = "RED.SharePermissions"; internal const string SharePermissionsMinVersion = "1.17.0"; } internal sealed class SharePermissionsBackend : IPanelBackend { public bool ShowLoadingPanel => LoadingWidgetBridge.ShowLoadingPanel; public bool LocalCanModerate => LoadingWidgetBridge.LocalCanModerate; public bool PendingLobbyReturn => LoadingWidgetBridge.PendingLobbyReturn; public bool IsMasterOrSingleplayer => LoadingWidgetBridge.IsMasterOrSingleplayer; public float VolumeMax => LoadingWidgetBridge.VolumeMax; private SharePermissionsBackend() { } internal static SharePermissionsBackend Create() { ProbeBridgeRaw(); return new SharePermissionsBackend(); } [MethodImpl(MethodImplOptions.NoInlining)] private static void ProbeBridgeRaw() { _ = LoadingWidgetBridge.VolumeMax; } public int RoleTier(Player? player) { return LoadingWidgetBridge.RoleTier(player); } public float VoiceAmplitude(int actorNumber) { return LoadingWidgetBridge.VoiceAmplitude(actorNumber); } public float VolumeFactor(int actorNumber) { return LoadingWidgetBridge.VolumeFactor(actorNumber); } public void SetVolume(int actorNumber, float factor) { LoadingWidgetBridge.SetVolume(actorNumber, factor); } public string SanitizeName(string? name, string? fallback = "Unknown") { return LoadingWidgetBridge.SanitizeName(name, fallback); } public bool CanKick(PlayerAvatar target) { return LoadingWidgetBridge.CanKick(target); } public bool CanKickActor(Player target) { return LoadingWidgetBridge.CanKickActor(target); } public void Kick(PlayerAvatar target, bool ban) { LoadingWidgetBridge.Kick(target, ban); } public void KickGhost(Player ghost, bool ban) { LoadingWidgetBridge.KickGhost(ghost, ban); } public void BackToLobby() { LoadingWidgetBridge.BackToLobby(); } public void ForceLobbyReload() { StandaloneLobby.ForceLobbyReload(); } public void Tick() { } public void ResetSession() { } } internal sealed class StandaloneBackend : IPanelBackend { private readonly ConfigEntry<bool> showLoadingPanel; public bool ShowLoadingPanel => showLoadingPanel.Value; public bool LocalCanModerate { get { try { return IsMasterClientRaw(); } catch { return false; } } } public bool PendingLobbyReturn => StandaloneLobby.PendingLobbyReturn; public bool IsMasterOrSingleplayer { get { try { return IsMasterOrSingleplayerRaw(); } catch { return false; } } } public float VolumeMax => 2f; internal StandaloneBackend(ConfigEntry<bool> showLoadingPanel) { this.showLoadingPanel = showLoadingPanel; } public int RoleTier(Player? player) { if (player == null || !player.IsMasterClient) { return 0; } return 3; } public float VoiceAmplitude(int actorNumber) { return StandaloneVoice.AmplitudeFor(actorNumber); } public float VolumeFactor(int actorNumber) { return StandaloneVoice.FactorFor(actorNumber); } public void SetVolume(int actorNumber, float factor) { StandaloneVoice.SetFactor(actorNumber, factor); } public string SanitizeName(string? name, string? fallback = "Unknown") { if (string.IsNullOrWhiteSpace(name)) { return fallback ?? ""; } string text = Regex.Replace(name, "<[^>]*>", string.Empty); StringBuilder stringBuilder = new StringBuilder(text.Length); string text2 = text; foreach (char c in text2) { if (!char.IsControl(c)) { stringBuilder.Append(c); } } string text3 = stringBuilder.ToString().Trim(); if (string.IsNullOrWhiteSpace(text3)) { return fallback ?? ""; } if (text3.Length > 32) { text3 = text3.Substring(0, 32) + "..."; } return text3; } public bool CanKick(PlayerAvatar target) { if ((Object)(object)target == (Object)null || !LocalCanModerate) { return false; } try { return !AvatarIsLocalRaw(target); } catch { return false; } } public bool CanKickActor(Player target) { if (target != null && !target.IsLocal && !target.IsMasterClient) { return LocalCanModerate; } return false; } public void Kick(PlayerAvatar target, bool ban) { if (!CanKick(target)) { return; } try { KickAvatarRaw(target, ban); } catch (Exception ex) { Plugin.Logger.LogWarning((object)("Kick failed (" + ex.GetType().Name + ")")); } } public void KickGhost(Player ghost, bool ban) { if (!CanKickActor(ghost)) { return; } try { KickByActorRaw(ghost, ban); } catch (Exception ex) { Plugin.Logger.LogWarning((object)("Ghost kick failed (" + ex.GetType().Name + ")")); } } public void BackToLobby() { StandaloneLobby.ReturnToLobby(); } public void ForceLobbyReload() { StandaloneLobby.ForceLobbyReload(); } public void Tick() { StandaloneLobby.Tick(); } public void ResetSession() { StandaloneVoice.Clear(); StandaloneLobby.Reset(); } [MethodImpl(MethodImplOptions.NoInlining)] private static bool IsMasterClientRaw() { return SemiFunc.IsMasterClient(); } [MethodImpl(MethodImplOptions.NoInlining)] private static bool IsMasterOrSingleplayerRaw() { return SemiFunc.IsMasterClientOrSingleplayer(); } [MethodImpl(MethodImplOptions.NoInlining)] private static bool AvatarIsLocalRaw(PlayerAvatar avatar) { return avatar.isLocal; } [MethodImpl(MethodImplOptions.NoInlining)] private static void KickAvatarRaw(PlayerAvatar target, bool ban) { NetworkManager instance = NetworkManager.instance; if (!((Object)(object)instance == (Object)null)) { if (ban) { instance.BanPlayer(target); } else { instance.KickPlayer(target); } } } [MethodImpl(MethodImplOptions.NoInlining)] private static void KickByActorRaw(Player ghost, bool ban) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001a: 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_0022: Expected O, but got Unknown //IL_002e: Unknown result type (might be due to invalid IL or missing references) object[] array = new object[1] { ghost.ActorNumber }; RaiseEventOptions val = new RaiseEventOptions { Receivers = (ReceiverGroup)1 }; PhotonNetwork.RaiseEvent((byte)(ban ? 124u : 123u), (object)array, val, SendOptions.SendReliable); try { if (PhotonNetwork.IsMasterClient) { PhotonNetwork.CloseConnection(ghost); } } catch { } } } internal static class StandaloneLobby { internal static bool PendingLobbyReturn; internal static void ReturnToLobby() { try { ReturnToLobbyRaw(); } catch (Exception ex) { Plugin.Logger.LogWarning((object)("BackToLobby failed (" + ex.GetType().Name + ")")); } } internal static void ForceLobbyReload() { try { ForceLobbyReloadRaw(); } catch (Exception ex) { Plugin.Logger.LogWarning((object)("ForceLobbyReload failed (" + ex.GetType().Name + ")")); } } internal static void Tick() { if (!PendingLobbyReturn) { return; } try { TickRaw(); } catch { PendingLobbyReturn = false; } } internal static void Reset() { PendingLobbyReturn = false; } [MethodImpl(MethodImplOptions.NoInlining)] private static void ReturnToLobbyRaw() { if (SemiFunc.MenuLevel()) { Plugin.Logger.LogWarning((object)"BackToLobby ignored - not in a run"); return; } RunManager instance = RunManager.instance; if ((Object)(object)instance == (Object)null) { return; } if (!instance.restarting) { ChangeLevelToLobbyRaw(instance); return; } if (!instance.restartingDone) { try { if (RetargetInFlightToLobbyRaw(instance)) { return; } } catch (Exception ex) { Plugin.Logger.LogWarning((object)("BackToLobby retarget failed (" + ex.GetType().Name + ") - queuing instead")); } } PendingLobbyReturn = true; Plugin.Logger.LogInfo((object)"BackToLobby queued - will run once the in-flight load completes"); } [MethodImpl(MethodImplOptions.NoInlining)] private static void TickRaw() { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Invalid comparison between Unknown and I4 if (!SemiFunc.IsMasterClientOrSingleplayer()) { PendingLobbyReturn = false; return; } RunManager instance = RunManager.instance; if ((Object)(object)instance == (Object)null) { return; } if (SemiFunc.RunIsLobbyMenu() || SemiFunc.MenuLevel()) { PendingLobbyReturn = false; } else if (!instance.restarting) { GameDirector instance2 = GameDirector.instance; if (!((Object)(object)instance2 == (Object)null) && (int)instance2.currentState == 2) { PendingLobbyReturn = false; Plugin.Logger.LogInfo((object)"BackToLobby: running queued lobby return"); ReturnToLobbyRaw(); } } } [MethodImpl(MethodImplOptions.NoInlining)] private static void ChangeLevelToLobbyRaw(RunManager rm) { int num = (SemiFunc.IsLevelShop(rm.levelCurrent) ? 1 : (SemiFunc.RunIsLobby() ? 2 : 0)); rm.ChangeLevel(true, SemiFunc.RunIsArena(), (ChangeLevelType)3); SemiFunc.StatSetSaveLevel(num); rm.loadLevel = num; StatsManager.instance.SaveFileSave(); } [MethodImpl(MethodImplOptions.NoInlining)] private static bool RetargetInFlightToLobbyRaw(RunManager rm) { if (!TrySyncLobbyDestinationRaw(rm)) { return false; } int saveLevel = rm.saveLevel; SemiFunc.StatSetSaveLevel(saveLevel); rm.loadLevel = saveLevel; StatsManager.instance.SaveFileSave(); PendingLobbyReturn = true; Plugin.Logger.LogInfo((object)"BackToLobby: retargeted the in-flight load to the lobby menu"); return true; } [MethodImpl(MethodImplOptions.NoInlining)] private static bool TrySyncLobbyDestinationRaw(RunManager rm) { if ((Object)(object)rm.levelCurrent == (Object)(object)rm.levelLobbyMenu) { return true; } if (!GameManager.Multiplayer()) { rm.levelCurrent = rm.levelLobbyMenu; return true; } RunManagerPUN runManagerPUN = rm.runManagerPUN; if ((Object)(object)runManagerPUN == (Object)null || (Object)(object)runManagerPUN.photonView == (Object)null) { return false; } runManagerPUN.photonView.RPC("UpdateLevelRPC", (RpcTarget)4, new object[3] { ((Object)rm.levelLobbyMenu).name, rm.levelsCompleted, false }); rm.levelCurrent = rm.levelLobbyMenu; return true; } [MethodImpl(MethodImplOptions.NoInlining)] private static void ForceLobbyReloadRaw() { //IL_0095: 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) if (!SemiFunc.IsMasterClientOrSingleplayer()) { return; } RunManager instance = RunManager.instance; if ((Object)(object)instance == (Object)null) { return; } bool flag = false; try { flag = TrySyncLobbyDestinationRaw(instance); } catch { } instance.waitToChangeScene = false; instance.lobbyJoin = false; instance.restarting = false; instance.restartingDone = false; instance.gameOver = false; instance.allPlayersDead = false; instance.allPlayersDeadCheckDisabled = true; try { StatsManager instance2 = StatsManager.instance; if ((Object)(object)instance2 != (Object)null) { instance2.SaveFileSave(); } } catch { } try { NetworkManager instance3 = NetworkManager.instance; if ((Object)(object)instance3 != (Object)null) { instance3.DestroyAll(); } } catch { } PendingLobbyReturn = true; Scene activeScene = SceneManager.GetActiveScene(); string text = ((((Scene)(ref activeScene)).name == "Reload") ? "Main" : "Reload"); if (GameManager.Multiplayer() && PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient) { PhotonNetwork.AutomaticallySyncScene = true; PhotonNetwork.LoadLevel(text); } else { SceneManager.LoadSceneAsync(text); } Plugin.Logger.LogInfo((object)$"ForceLobbyReload: wedged transition pipeline restarted room-wide (forced scene: {text}, lobby synced: {flag})"); } } [HarmonyPatch(typeof(PlayerVoiceChat), "Update")] internal static class StandaloneVoice { internal const float VolumeMin = 0f; internal const float VolumeMax = 2f; private static readonly Dictionary<int, PlayerVoiceChat> ByActor = new Dictionary<int, PlayerVoiceChat>(); private static readonly Dictionary<int, float> FactorByActor = new Dictionary<int, float>(); private static readonly float[] SampleBuf = new float[1024]; [HarmonyPostfix] [HarmonyWrapSafe] private static void Update_Postfix(PlayerVoiceChat __instance) { PhotonView component = ((Component)__instance).GetComponent<PhotonView>(); if (!((Object)(object)component == (Object)null) && component.Owner != null) { int actorNumber = component.Owner.ActorNumber; ByActor[actorNumber] = __instance; float num = FactorFor(actorNumber); if (num != 1f) { ApplyVolumeFactor(__instance, num); } } } [MethodImpl(MethodImplOptions.NoInlining)] private static void ApplyVolumeFactor(PlayerVoiceChat pvc, float factor) { if ((Object)(object)pvc.lowPassLogic != (Object)null) { AudioLowPassLogic lowPassLogic = pvc.lowPassLogic; lowPassLogic.Volume *= factor; } if ((Object)(object)pvc.lowPassLogicTTS != (Object)null && (Object)(object)pvc.playerAvatar != (Object)null) { AudioLowPassLogic lowPassLogicTTS = pvc.lowPassLogicTTS; lowPassLogicTTS.Volume *= factor; } } internal static float FactorFor(int actorNumber) { if (!FactorByActor.TryGetValue(actorNumber, out var value)) { return 1f; } return value; } internal static void SetFactor(int actorNumber, float factor) { float num = Mathf.Clamp(factor, 0f, 2f); if (num == 1f) { FactorByActor.Remove(actorNumber); } else { FactorByActor[actorNumber] = num; } } internal static float AmplitudeFor(int actorNumber) { if (!ByActor.TryGetValue(actorNumber, out PlayerVoiceChat value) || (Object)(object)value == (Object)null) { return 0f; } try { AudioSource audioSource = value.audioSource; if ((Object)(object)audioSource == (Object)null || (Object)(object)audioSource.clip == (Object)null || !audioSource.isPlaying) { return 0f; } audioSource.clip.GetData(SampleBuf, audioSource.timeSamples); float num = 0f; for (int i = 0; i < SampleBuf.Length; i++) { num += Mathf.Abs(SampleBuf[i]); } return num / (float)SampleBuf.Length; } catch { return 0f; } } internal static void Clear() { ByActor.Clear(); FactorByActor.Clear(); } } }