using 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 Loudness = new Dictionary(); 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 ActorAvatars = new Dictionary(); private static readonly HashSet SceneLoadedActors = new HashSet(); private static readonly HashSet SpawnedReadyActors = new HashSet(); private static readonly HashSet EnemyReadyActors = new HashSet(); private static readonly HashSet ReloadReadyActors = new HashSet(); 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 allTexts = new List(); 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(); } } 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(" STUCK", 18, "#F0736B") : ""); SetText(headerText, $"PLAYERS LOADED {num}/{players.Length}{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 + " (you)") : 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.renderMode = (RenderMode)0; canvas.sortingOrder = 32700; CanvasScaler val2 = val.AddComponent(); 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(); 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(); 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(); ((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(); ((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(); 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(); 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(); 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(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()); 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? 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("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 showLoadingPanel = ((BaseUnityPlugin)this).Config.Bind("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 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 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 ByActor = new Dictionary(); private static readonly Dictionary FactorByActor = new Dictionary(); private static readonly float[] SampleBuf = new float[1024]; [HarmonyPostfix] [HarmonyWrapSafe] private static void Update_Postfix(PlayerVoiceChat __instance) { PhotonView component = ((Component)__instance).GetComponent(); 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(); } } }