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 Feris Mod Menu v1.2.0
FerisModMenuLite.dll
Decompiled 5 hours agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; 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 System.Threading; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using Photon.Realtime; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("FerisModMenuLite")] [assembly: AssemblyConfiguration("Lite")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("FerisModMenuLite")] [assembly: AssemblyTitle("FerisModMenuLite")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.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.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace HostTools { internal static class AutoStart { private static float startAt = -1f; private static float nextAnnounce; private static bool forPlayers; private static bool restartPending; private static bool startWhenReady; public static void Reset() { startAt = -1f; restartPending = false; } public static void StartWhenReady() { startWhenReady = true; } public static void Force(int seconds) { Begin(seconds, becauseOfPlayers: false); } private static void Begin(int seconds, bool becauseOfPlayers) { startAt = Time.time + (float)seconds; nextAnnounce = ((seconds > 15) ? (startAt - 10f) : 0f); forPlayers = becauseOfPlayers; Runner.Say($"Starting in {seconds} seconds!"); } public static void Tick() { if (!SemiFunc.RunIsLobbyMenu() || (Object)(object)MenuPageLobby.instance == (Object)null) { startAt = -1f; return; } if (startWhenReady && Runner.InGameplay && (Object)(object)PlayerAvatar.instance != (Object)null) { startWhenReady = false; startAt = Time.time + 1.5f; nextAnnounce = 0f; forPlayers = false; Plugin.Log.LogInfo((object)"New lobby: starting the run right away"); return; } bool flag = PhotonNetwork.CurrentRoom.PlayerCount >= Plugin.AutoStartMinPlayers.Value; if (startAt < 0f) { if (Plugin.AutoStartEnabled.Value && flag) { Begin(Plugin.AutoStartSeconds.Value, becauseOfPlayers: true); } return; } if (forPlayers && (!flag || !Plugin.AutoStartEnabled.Value) && startAt - Time.time > 6f) { startAt = -1f; Runner.Say(flag ? "Auto start cancelled." : "Not enough players, auto start cancelled."); return; } if (nextAnnounce > 0f && Time.time >= nextAnnounce) { nextAnnounce = 0f; Runner.Say("Starting in 10 seconds!"); } if (Time.time >= startAt && !MenuPageLobby.instance.joiningPlayer) { startAt = -1f; MenuPageLobby.instance.ButtonStart(); } } } internal static class GhostLog { private class Repeat { public float Last = -999f; public int Count; } private class Listener : ILogListener, IDisposable { public void LogEvent(object sender, LogEventArgs e) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0045: Invalid comparison between Unknown and I4 if (!quiet && (object)e.Source == Plugin.Log && e.Data != null) { string text = e.Data.ToString(); Write("*", ((int)e.Level > 4) ? "HT" : (((int)e.Level <= 2) ? "ERROR" : "WARN"), text); } } public void Dispose() { } } [CompilerGenerated] private static class <>O { public static LogCallback <0>__OnUnityLog; } private const int KeepFiles = 8; private const long MaxFileBytes = 209715200L; private static StreamWriter writer; private static string stamp; private static int part = 1; private static long bytes; private static float nextFlush; private static bool broken; private static Listener listener; private static readonly StringBuilder line = new StringBuilder(512); internal static string Level = "-"; private static int mainThread = -1; private static bool quiet; private const string FilePrefix = "hosttools-"; private static readonly Dictionary<string, Repeat> repeats = new Dictionary<string, Repeat>(); internal static string Folder => Path.Combine(Paths.BepInExRootPath, "FerisModMenu-logs"); internal static bool On { get { if (!broken && Plugin.GhostLogEnabled != null) { return Plugin.GhostLogEnabled.Value; } return false; } } public static void World(string kind, string text) { Write("*", kind, text); } internal static void Init() { mainThread = Thread.CurrentThread.ManagedThreadId; } private static void Write(string who, string kind, string text) { if (!On || Thread.CurrentThread.ManagedThreadId != mainThread) { return; } try { if (writer == null) { Open(); } line.Clear(); line.Append(DateTime.Now.ToString("HH:mm:ss.fff", CultureInfo.InvariantCulture)).Append(" t=").Append(Time.time.ToString("0.00", CultureInfo.InvariantCulture)) .Append(" | ") .Append(Level) .Append(" | ") .Append((who ?? "?").PadRight(8)) .Append(" | ") .Append(kind.PadRight(8)) .Append(" | ") .Append(text); string text2 = line.ToString(); writer.WriteLine(text2); bytes += text2.Length + 2; if (bytes > 209715200) { part++; CloseFile(); } } catch (Exception ex) { broken = true; CloseFile(); Plugin.Log.LogWarning((object)(UiMetrics.ModName + " log stopped: " + ex.Message)); } } private static void Open() { //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0134: Expected O, but got Unknown //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Expected O, but got Unknown Directory.CreateDirectory(Folder); if (stamp == null) { stamp = DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss", CultureInfo.InvariantCulture); } string text = Path.Combine(Folder, (part == 1) ? ("hosttools-" + stamp + ".log") : string.Format("{0}{1}-part{2}.log", "hosttools-", stamp, part)); writer = new StreamWriter(text, append: true, new UTF8Encoding(encoderShouldEmitUTF8Identifier: false), 65536); bytes = 0L; writer.WriteLine($"# {UiMetrics.ModName} log, {DateTime.Now:yyyy-MM-dd HH:mm:ss}. Game {Application.version}, Unity {Application.unityVersion}."); writer.WriteLine("# " + UiMetrics.Byline + " - " + UiMetrics.Label); writer.WriteLine("# real time | t=game seconds | level | * | kind | details"); writer.WriteLine("# Kinds: LEVEL LOOT HT (mod log line) WARN ERROR UNITY (game warnings/errors)"); Cleanup(text); object obj = <>O.<0>__OnUnityLog; if (obj == null) { LogCallback val = OnUnityLog; <>O.<0>__OnUnityLog = val; obj = (object)val; } Application.logMessageReceived -= (LogCallback)obj; object obj2 = <>O.<0>__OnUnityLog; if (obj2 == null) { LogCallback val2 = OnUnityLog; <>O.<0>__OnUnityLog = val2; obj2 = (object)val2; } Application.logMessageReceived += (LogCallback)obj2; if (listener == null) { listener = new Listener(); Logger.Listeners.Add((ILogListener)(object)listener); } } private static void Cleanup(string current) { foreach (FileInfo item in (from f in new DirectoryInfo(Folder).GetFiles("hosttools-*.log") where f.FullName != current orderby f.LastWriteTimeUtc descending select f).Skip(7)) { try { item.Delete(); } catch { } } } public static void Tick() { if (!On) { if (writer != null || listener != null) { World("LOG", "diagnostic log switched off"); Close(); } } else if (writer != null && Time.realtimeSinceStartup >= nextFlush) { nextFlush = Time.realtimeSinceStartup + 2f; Flush(); } } public static void Flush() { try { writer?.Flush(); } catch { } } public static void Close() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown object obj = <>O.<0>__OnUnityLog; if (obj == null) { LogCallback val = OnUnityLog; <>O.<0>__OnUnityLog = val; obj = (object)val; } Application.logMessageReceived -= (LogCallback)obj; if (listener != null) { Logger.Listeners.Remove((ILogListener)(object)listener); listener = null; } CloseFile(); } private static void CloseFile() { try { writer?.Flush(); writer?.Dispose(); } catch { } writer = null; } private static bool Throttle(string key, float window, out int skipped) { if (!repeats.TryGetValue(key, out var value)) { value = (repeats[key] = new Repeat()); if (repeats.Count > 2000) { repeats.Clear(); repeats[key] = value; } } float realtimeSinceStartup = Time.realtimeSinceStartup; if (realtimeSinceStartup - value.Last < window) { value.Count++; skipped = 0; return false; } skipped = value.Count; value.Count = 0; value.Last = realtimeSinceStartup; return true; } private unsafe static void OnUnityLog(string message, string stack, LogType type) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Invalid comparison between Unknown and I4 //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Invalid comparison between Unknown and I4 if ((int)type != 3 && message != null && Throttle("unity|" + ((object)(*(LogType*)(&type))/*cast due to .constrained prefix*/).ToString() + "|" + ((message.Length > 120) ? message.Substring(0, 120) : message), 10f, out var skipped)) { string arg = ((skipped > 0) ? $" (x{skipped + 1} in the last while)" : ""); bool flag = (int)type == 4 || (int)type == 0 || (int)type == 1; Write("*", "UNITY", $"{type}: {message}{arg}" + ((flag && !string.IsNullOrEmpty(stack)) ? ("\n" + Indent(stack, 8)) : "")); } } public static void SettingChanged(ConfigEntryBase entry) { if (entry != null && !(entry.Definition.Section == "Panel")) { string text = entry.BoxedValue?.ToString(); World("SETTING", entry.Definition.Section + "." + entry.Definition.Key + " = " + text); } } public static string V(Vector3 v) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) return string.Format(CultureInfo.InvariantCulture, "({0:0.0},{1:0.0},{2:0.0})", v.x, v.y, v.z); } public static string F(float f) { return f.ToString("0.0", CultureInfo.InvariantCulture); } public static string Name(Object o) { if (!(o == (Object)null)) { return o.name.Replace("(Clone)", "").Trim(); } return "-"; } private static string Indent(string text, int maxLines) { return string.Join("\n", from l in (from l in (text ?? "").Split('\n') where l.Trim().Length > 0 select l).Take(maxLines) select " " + l.TrimEnd()); } } internal static class LobbyNameMemory { [HarmonyPatch(typeof(MenuPageServerListCreateNew), "Update")] internal static class PrefillPatch { private static void Prefix(MenuPageServerListCreateNew __instance) { if ((Object)(object)__instance == (Object)null || !filled.Add(((Object)__instance).GetInstanceID())) { return; } MenuTextInput menuTextInput = __instance.menuTextInput; string text = Clean(Plugin.LastLobbyName.Value); if (!((Object)(object)menuTextInput == (Object)null) && !string.IsNullOrEmpty(text) && string.IsNullOrEmpty(menuTextInput.textCurrent)) { if (text.Length > menuTextInput.maxLength) { text = text.Substring(0, menuTextInput.maxLength); } menuTextInput.textCurrent = text; menuTextInput.textPrevious = text; } } } [HarmonyPatch(typeof(MenuPageServerListCreateNew), "ButtonConfirm")] internal static class RememberPatch { [HarmonyPriority(800)] private static void Prefix(MenuPageServerListCreateNew __instance) { MenuTextInput val = (((Object)(object)__instance != (Object)null) ? __instance.menuTextInput : null); if ((Object)(object)val == (Object)null || string.IsNullOrWhiteSpace(val.textCurrent)) { return; } string text = Clean(val.textCurrent); if (text.Length != 0) { val.textCurrent = text; if (Plugin.LastLobbyName.Value != text) { Plugin.LastLobbyName.Value = text; Plugin.Log.LogInfo((object)("Lobby name: remembered \"" + text + "\" for next time")); } } } } private static readonly Regex LateJoinTag = new Regex("\\[\\s*(late\\s*-?\\s*join|中途加入)[^\\]]*\\]\\s*", RegexOptions.IgnoreCase); private static readonly HashSet<int> filled = new HashSet<int>(); internal static string Clean(string name) { if (!string.IsNullOrEmpty(name)) { return LateJoinTag.Replace(name, "").Trim(); } return name ?? ""; } } internal static class Panel { private struct TabDef { public string Name; public Color Color; public Action Draw; public string Tip; public bool Locked; } private struct PopFx { public Rect Rect; public float Start; public bool InScroll; public Color Color; } [CompilerGenerated] private static class <>O { public static WindowFunction <0>__DrawWindow; public static Action <1>__LobbyTab; } public static bool Open; private static int tab; private static Rect window; private static bool windowLoaded; private static float maxHeight; private static float contentHeight; private static float chromeHeight = 130f; private static bool resizing; private static Vector2 scroll; private static string pendingKey; private static float pendingUntil; private static GUIStyle header; private static string welcomeBuffer; private static string styleBuffer; private static string keyBuffer; private static GUIStyle tipStyle; private static GUIStyle sectionStyle; private static readonly Dictionary<string, bool> openSections = new Dictionary<string, bool>(); private const int FontSize = 15; private static TabDef[] tabs; private static readonly Color LockedYellow = new Color(1f, 0.84f, 0.12f); private static GUIStyle tabStyle; private static readonly List<int> savedSizes = new List<int>(); private static Color savedLabel; private static Color savedToggle; private static Color savedToggleOn; private static Color savedToggleHover; private static Color savedToggleOnHover; private static GUIStyle windowStyle; private static Texture2D bgTex; private static Color[] bgPixels; private const int BgW = 8; private const int BgH = 64; private static readonly (string name, string hex)[] Swatches = new(string, string)[8] { ("Midnight", "1C2340"), ("Purple", "35204F"), ("Crimson", "4A1820"), ("Forest", "17392A"), ("Ocean", "103A4A"), ("Charcoal", "232428"), ("Gold", "4A3A12"), ("Rose", "4A1E3A") }; private static readonly List<PopFx> pops = new List<PopFx>(); private static bool drawingScroll; private static Texture2D white; internal static float Scale => Mathf.Max(1f, (float)Screen.height / 900f); private static TabDef[] TabList { get { object obj = tabs; if (obj == null) { obj = new TabDef[9] { T("Lobby", "3D8BFF", LobbyTab), L("Players", "Kick and ban players, a ban list, auto-kick AFK players."), L("Run", "Difficulty presets, haul goal that keeps growing, random events, loot respawn, team map upgrade, quick revive, catching players who fall off the map, skip the Arena."), L("Bots", "AI bot teammates that explore, carry loot, open extractions and revive each other, plus the rainbow Reviver: no game over while anyone's dead."), L("Watch", "Watch any bot, and a cinematic camera that films whoever has the most going on."), L("You", "Autopilot, field of view, third person, noclip, lights on, monster dots on the map, monster respawn timers, hear your own mic, mute everyone."), L("Control", "God mode and more per player, set upgrades, pick maps, rules (no traps, weak monsters...), spawn items and monsters, kill monsters, bring everyone to you."), L("Stats", "Session stats: who joined, played, got kicked."), L("Menu", "Window colours and animated backgrounds.") }; tabs = (TabDef[])obj; } return (TabDef[])obj; } } private static Color Accent => TabList[Mathf.Clamp(tab, 0, TabList.Length - 1)].Color; public static void Update() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = Plugin.PanelKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { Open = !Open; if (Open) { welcomeBuffer = (styleBuffer = null); keyBuffer = ""; } else { Close(); } } if (Open) { Cursor.lockState = (CursorLockMode)0; Cursor.visible = true; if ((Object)(object)InputManager.instance != (Object)null) { InputManager.instance.DisableMovement(0.2f); InputManager.instance.DisableAiming(0.2f); InputManager.instance.DisableControlsExcept(0.2f, new List<InputKey>()); } } } internal static void Close() { Open = false; Save(); if ((Object)(object)CursorManager.instance != (Object)null) { CursorManager.instance.Unlock(0.05f); } } private static void Load() { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) windowLoaded = true; float result; float[] array = (from s in Plugin.PanelWindow.Value.Split(',') select (!float.TryParse(s, NumberStyles.Float, CultureInfo.InvariantCulture, out result)) ? (-1f) : result).ToArray(); window = ((array.Length == 4 && array.All((float f) => f >= 0f)) ? new Rect(array[0], array[1], array[2], array[3]) : new Rect(40f, 80f, 460f, 560f)); maxHeight = ((Rect)(ref window)).height; } public static void Save() { if (windowLoaded) { string text = string.Join(",", new float[4] { ((Rect)(ref window)).x, ((Rect)(ref window)).y, ((Rect)(ref window)).width, maxHeight }.Select((float f) => Mathf.Round(f).ToString(CultureInfo.InvariantCulture))); if (text != Plugin.PanelWindow.Value) { Plugin.PanelWindow.Value = text; } } } public static void Draw() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Expected O, but got Unknown //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0164: 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_017d: Unknown result type (might be due to invalid IL or missing references) //IL_01b1: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Expected O, but got Unknown if (Open) { if (!windowLoaded) { Load(); } float scale = Scale; Matrix4x4 matrix = GUI.matrix; GUI.matrix = Matrix4x4.Scale(new Vector3(scale, scale, 1f)); if (header == null) { header = new GUIStyle(GUI.skin.label) { fontStyle = (FontStyle)1, fontSize = 15 }; } float num = (float)Screen.width / scale; float num2 = (float)Screen.height / scale; ((Rect)(ref window)).width = Mathf.Clamp(((Rect)(ref window)).width, 360f, num); maxHeight = Mathf.Clamp(maxHeight, 260f, num2); float num3 = Mathf.Clamp((contentHeight > 0f) ? (chromeHeight + contentHeight + 6f) : maxHeight, 200f, maxHeight); if (Mathf.Abs(num3 - ((Rect)(ref window)).height) > 3f) { ((Rect)(ref window)).height = num3; } ((Rect)(ref window)).x = Mathf.Clamp(((Rect)(ref window)).x, 0f, num - ((Rect)(ref window)).width); ((Rect)(ref window)).y = Mathf.Clamp(((Rect)(ref window)).y, 0f, num2 - ((Rect)(ref window)).height); FontsOn(); header.normal.textColor = Color.Lerp(Accent, Color.white, 0.12f); Rect val = window; object obj = <>O.<0>__DrawWindow; if (obj == null) { WindowFunction val2 = DrawWindow; <>O.<0>__DrawWindow = val2; obj = (object)val2; } window = GUI.Window(16471, val, (WindowFunction)obj, $"{UiMetrics.ModName} - {UiMetrics.Label} ({Plugin.PanelKey.Value} to close)", WindowStyle()); FontsOff(); GUI.matrix = matrix; } } private static void DrawWindow(int id) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) FontsOn(); header.normal.textColor = Color.Lerp(Accent, Color.white, 0.12f); try { DrawWindowContent(); } finally { FontsOff(); } } private static void DrawWindowContent() { //IL_00d4: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f4: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Invalid comparison between Unknown and I4 //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Invalid comparison between Unknown and I4 //IL_0130: Unknown result type (might be due to invalid IL or missing references) //IL_0135: 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_016f: Unknown result type (might be due to invalid IL or missing references) //IL_01c0: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: 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_01a7: Expected O, but got Unknown //IL_022d: Unknown result type (might be due to invalid IL or missing references) if (Time.time > pendingUntil) { pendingKey = null; } GUILayout.Space(4f); TabDef[] tabList = TabList; tab = ColorTabs(Mathf.Clamp(tab, 0, tabList.Length - 1), tabList.Select((TabDef t) => t.Name).ToArray(), tabList.Select((TabDef t) => t.Color).ToArray(), ((Rect)(ref window)).width - 16f, tabList.Select((TabDef t) => t.Tip).ToArray()); GUILayout.Space(4f); scroll = GUILayout.BeginScrollView(scroll, false, true, GUIStyle.none, GUI.skin.verticalScrollbar, Array.Empty<GUILayoutOption>()); drawingScroll = true; GUILayout.BeginVertical(Array.Empty<GUILayoutOption>()); tabList[tab].Draw(); GUILayout.EndVertical(); Rect lastRect; if ((int)Event.current.type == 7) { lastRect = GUILayoutUtility.GetLastRect(); contentHeight = ((Rect)(ref lastRect)).height; } DrawPops(inScroll: true); drawingScroll = false; GUILayout.EndScrollView(); if ((int)Event.current.type == 7) { float height = ((Rect)(ref window)).height; lastRect = GUILayoutUtility.GetLastRect(); chromeHeight = height - ((Rect)(ref lastRect)).height; } if (tipStyle == null) { tipStyle = new GUIStyle(GUI.skin.label) { wordWrap = true, fontSize = 15 }; } tipStyle.normal.textColor = new Color(0.85f, 0.85f, 0.85f); GUILayout.Label(string.IsNullOrEmpty(GUI.tooltip) ? "Hover a setting for details." : GUI.tooltip, tipStyle, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Height(40f) }); GUILayout.Space(8f); DrawPops(inScroll: false); ResizeHandle(); GUI.DragWindow(new Rect(0f, 0f, ((Rect)(ref window)).width, 20f)); } private static void ResizeHandle() { //IL_0031: 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_004d: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Invalid comparison between Unknown and I4 //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Invalid comparison between Unknown and I4 //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref window)).width - 20f, ((Rect)(ref window)).height - 20f, 20f, 20f); GUI.Label(val, "//"); Event current = Event.current; if ((int)current.type == 0 && ((Rect)(ref val)).Contains(current.mousePosition)) { resizing = true; current.Use(); } else if (resizing && (int)current.type == 3) { ((Rect)(ref window)).width = ((Rect)(ref window)).width + current.delta.x; maxHeight = ((Rect)(ref window)).height + current.delta.y; ((Rect)(ref window)).height = maxHeight; current.Use(); } else if (resizing && (int)current.rawType == 1) { resizing = false; Save(); } } private static void LobbyTab() { //IL_01da: Unknown result type (might be due to invalid IL or missing references) //IL_01f7: Expected O, but got Unknown //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_03e5: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Expected O, but got Unknown bool isHost = Runner.IsHost; string text = (PhotonNetwork.InRoom ? $"{PhotonNetwork.CurrentRoom.PlayerCount}/{PhotonNetwork.CurrentRoom.MaxPlayers} players | {Runner.Phase()}" : "Not in a lobby"); GUILayout.Label(isHost ? text : (text + " | you're not the host"), header, Array.Empty<GUILayoutOption>()); if (Section("Lobby name", Plugin.LobbyNameStyle.Value)) { if (isHost && PhotonNetwork.InRoom && ((Dictionary<object, object>)(object)((RoomInfo)PhotonNetwork.CurrentRoom).CustomProperties).TryGetValue((object)"server_name", out object value) && value is string text2) { GUILayout.Label("This lobby: " + text2, Array.Empty<GUILayoutOption>()); } if (styleBuffer == null) { styleBuffer = Plugin.LobbyNameStyle.Value; } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); styleBuffer = GUILayout.TextField(styleBuffer, 150, Array.Empty<GUILayoutOption>()); GUI.enabled = styleBuffer != Plugin.LobbyNameStyle.Value && styleBuffer.Contains("{name}"); if (Btn(new GUIContent("Save", "{name} = what you type when creating the lobby, e.g. \"[EN] {name} | chill\". Used for the next public lobby: the game's server locks a lobby's name once it exists."), GUILayout.Width(70f))) { Plugin.LobbyNameStyle.Value = styleBuffer; Runner.Toast("Saved. It's used for the next public lobby you create."); } GUI.enabled = true; GUILayout.EndHorizontal(); } if (Section("Players and maps", $"max {Plugin.EffectiveMaxPlayers}" + (Plugin.PublicVanillaMaps.Value ? ", game maps only" : ""))) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(new GUIContent($"Max players: {Plugin.EffectiveMaxPlayers}", "Changes this lobby right away (if you're the host) and the next one you create. 20 is the most the game allows."), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(150f) }); GUI.enabled = Plugin.EffectiveMaxPlayers > 1; if (Btn("-", GUILayout.Width(30f))) { Actions.SetMaxPlayers(Plugin.EffectiveMaxPlayers - 1); } GUI.enabled = Plugin.EffectiveMaxPlayers < 20; if (Btn("+", GUILayout.Width(30f))) { Actions.SetMaxPlayers(Plugin.EffectiveMaxPlayers + 1); } GUI.enabled = true; GUILayout.EndHorizontal(); Toggle(Plugin.PublicVanillaMaps, "Public lobbies: game's own maps only", "Modded maps hang loading for players who don't have the map mod."); } if (Section("Welcome message", Plugin.WelcomeEnabled.Value ? "on" : "off")) { Toggle(Plugin.WelcomeEnabled, "Greet players when they join", "{name} in the message = the player's name."); if (welcomeBuffer == null) { welcomeBuffer = Plugin.WelcomeMessage.Value; } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); welcomeBuffer = GUILayout.TextField(welcomeBuffer, 120, Array.Empty<GUILayoutOption>()); GUI.enabled = welcomeBuffer != Plugin.WelcomeMessage.Value; if (Btn("Save", GUILayout.Width(70f))) { Plugin.WelcomeMessage.Value = welcomeBuffer; Runner.Toast("Welcome message saved"); } GUI.enabled = true; GUILayout.EndHorizontal(); } string text3 = ResumeRun.Describe(); if (Section("Continue last run", (!Plugin.ResumePublicRun.Value) ? "off" : (text3 ?? "no saved run"))) { Toggle(Plugin.ResumePublicRun, "Save public runs and continue the last one", "When you create a public server, it picks up the last public run (the game only saves private ones)."); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label((text3 != null) ? ("Saved run: " + text3) : "No saved run yet", Array.Empty<GUILayoutOption>()); GUI.enabled = text3 != null && !PhotonNetwork.InRoom; if (Btn(new GUIContent("Start fresh", "Deletes the saved run: your next public server starts a new one."), GUILayout.Width(100f))) { ResumeRun.Forget(); Runner.Toast("Saved run deleted: your next public server starts a new run"); } GUI.enabled = true; GUILayout.EndHorizontal(); } if (Section("Starting the run", Plugin.AutoStartEnabled.Value ? $"auto at {Plugin.AutoStartMinPlayers.Value}+ players" : null)) { Toggle(Plugin.StartOnCreate, "Start right away after creating a lobby"); Toggle(Plugin.AutoStartEnabled, $"Auto-start at {Plugin.AutoStartMinPlayers.Value}+ players", $"{Plugin.AutoStartSeconds.Value}s countdown once enough players are in."); GUI.enabled = isHost && SemiFunc.RunIsLobbyMenu(); if (Btn("Start run now (5s)")) { AutoStart.Force(5); } GUI.enabled = true; } } private static bool Section(string title, string summary = null) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown //IL_009b: 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_00a1: 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_00f1: Unknown result type (might be due to invalid IL or missing references) if (sectionStyle == null) { sectionStyle = new GUIStyle(GUI.skin.button) { alignment = (TextAnchor)3, fontStyle = (FontStyle)1 }; } sectionStyle.fontSize = 15; sectionStyle.clipping = (TextClipping)1; string key = title.Split('(')[0].Trim(); openSections.TryGetValue(key, out var value); GUILayout.Space(3f); string text = (value ? "- " : "+ ") + title + ((!value && !string.IsNullOrEmpty(summary)) ? (" " + summary) : ""); Color backgroundColor = GUI.backgroundColor; GUI.backgroundColor = Accent * (value ? 1.5f : 1.1f); bool num = Btn(text, sectionStyle, GUILayout.Width(Mathf.Max(100f, ((Rect)(ref window)).width - 46f))); GUI.backgroundColor = backgroundColor; if (num) { value = !value; openSections[key] = value; } return value; } private static string Secs(float s) { if (!(s >= 60f)) { return $"{s:0}s"; } return $"{Mathf.FloorToInt(s / 60f)}:{Mathf.FloorToInt(s % 60f):00}"; } private static void WaitRow(ConfigEntry<bool> on, ConfigEntry<float> wait, string label, float min, float max, string tip) { //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Expected O, but got Unknown GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); Toggle(on, label, tip); GUI.enabled = on.Value; GUILayout.Label(new GUIContent("wait " + Secs(wait.Value), tip), (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(80f) }); float value = wait.Value; if (Btn("-", GUILayout.Width(30f))) { float num = ((value > 120f) ? 60f : ((value > 30f) ? 15f : 5f)); wait.Value = Mathf.Max(min, value - num); } if (Btn("+", GUILayout.Width(30f))) { float num2 = ((value >= 120f) ? 60f : ((value >= 30f) ? 15f : 5f)); wait.Value = Mathf.Min(max, value + num2); } GUI.enabled = true; GUILayout.EndHorizontal(); } private static void Toggle(ConfigEntry<bool> entry, string label, string tip = null) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) bool flag = GUILayout.Toggle(entry.Value, new GUIContent(" " + label, tip), Array.Empty<GUILayoutOption>()); if (flag != entry.Value) { entry.Value = flag; Pop(GUILayoutUtility.GetLastRect()); } } private static void ConfirmButton(string key, string label, Action action, float width = 70f) { bool flag = pendingKey == key; string text = (flag ? "Sure? Click again" : label); if ((width > 0f) ? Btn(flag ? "Sure?" : label, GUILayout.Width(width)) : Btn(text)) { if (flag) { pendingKey = null; action(); } else { pendingKey = key; pendingUntil = Time.time + 3f; } } } private static TabDef T(string name, string hex, Action draw) { //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) return new TabDef { Name = name, Color = Hex(hex), Draw = draw }; } private static TabDef L(string name, string features) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Unknown result type (might be due to invalid IL or missing references) return new TabDef { Name = name, Color = LockedYellow, Locked = true, Tip = "Not in this version. Get it on my Patreon: " + UiMetrics.Label, Draw = delegate { LockedTab(name, features); } }; } private static void LockedTab(string name, string features) { //IL_002f: 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) GUILayout.Label(name + " isn't in this version", header, Array.Empty<GUILayoutOption>()); GUILayout.Label(features, Array.Empty<GUILayoutOption>()); GUILayout.Space(6f); Color contentColor = GUI.contentColor; GUI.contentColor = LockedYellow; GUILayout.Label("Get it on my Patreon: " + UiMetrics.Label, header, Array.Empty<GUILayoutOption>()); GUI.contentColor = contentColor; } private static int ColorTabs(int current, string[] names, Color[] colors, float width, string[] tips = null) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0047: 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_004d: 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_0036: Expected O, but got Unknown //IL_026a: Unknown result type (might be due to invalid IL or missing references) //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: 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_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_012c: 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_014d: Invalid comparison between Unknown and I4 //IL_0152: Unknown result type (might be due to invalid IL or missing references) //IL_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0159: 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) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_016f: 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_01c8: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: 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_0244: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Max(1, Mathf.Min(names.Length, Mathf.FloorToInt(width / 74f))); if (tabStyle == null) { tabStyle = new GUIStyle(GUI.skin.button); } tabStyle.fontSize = 15; Color backgroundColor = GUI.backgroundColor; Color contentColor = GUI.contentColor; for (int i = 0; i < names.Length; i++) { if (i % num == 0) { if (i > 0) { GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); } bool flag = i == current; tabStyle.fontStyle = (FontStyle)(flag ? 1 : 0); Color val = colors[i] * 0.45f; val.a = 1f; GUI.backgroundColor = (flag ? (colors[i] * 2.2f) : val); string text = ((tips != null && i < tips.Length) ? tips[i] : null); GUI.contentColor = (Color)(flag ? Color.white : ((text != null) ? colors[i] : new Color(0.62f, 0.62f, 0.62f))); if (GUILayout.Button(new GUIContent(names[i], text), tabStyle, Array.Empty<GUILayoutOption>())) { current = i; Pop(GUILayoutUtility.GetLastRect(), colors[i]); } if (flag && (int)Event.current.type == 7) { Rect lastRect = GUILayoutUtility.GetLastRect(); Color color = GUI.color; GUI.color = Color.Lerp(colors[i], Color.white, 0.2f); GUI.DrawTexture(new Rect(((Rect)(ref lastRect)).x + 2f, ((Rect)(ref lastRect)).yMax - 5f, ((Rect)(ref lastRect)).width - 4f, 4f), (Texture)(object)Texture2D.whiteTexture); GUI.color = new Color(1f, 1f, 1f, 0.8f); GUI.DrawTexture(new Rect(((Rect)(ref lastRect)).x, ((Rect)(ref lastRect)).y, ((Rect)(ref lastRect)).width, 1.5f), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref lastRect)).x, ((Rect)(ref lastRect)).y, 1.5f, ((Rect)(ref lastRect)).height), (Texture)(object)Texture2D.whiteTexture); GUI.DrawTexture(new Rect(((Rect)(ref lastRect)).xMax - 1.5f, ((Rect)(ref lastRect)).y, 1.5f, ((Rect)(ref lastRect)).height), (Texture)(object)Texture2D.whiteTexture); GUI.color = color; } } GUILayout.EndHorizontal(); GUI.backgroundColor = backgroundColor; GUI.contentColor = contentColor; return current; } private static List<GUIStyle> AllStyles() { GUISkin skin = GUI.skin; List<GUIStyle> list = new List<GUIStyle> { skin.label, skin.button, skin.toggle, skin.textField, skin.textArea, skin.box, skin.window, skin.horizontalSlider, skin.verticalSlider, skin.scrollView }; if (skin.customStyles != null) { list.AddRange(skin.customStyles); } return list; } private static void FontsOn() { //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_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_00ff: 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_0105: 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_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_018a: 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_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01b0: Unknown result type (might be due to invalid IL or missing references) //IL_01ba: Unknown result type (might be due to invalid IL or missing references) savedSizes.Clear(); foreach (GUIStyle item in AllStyles()) { savedSizes.Add((item != null) ? item.fontSize : 0); if (item != null) { item.fontSize = 15; } } savedLabel = GUI.skin.label.normal.textColor; savedToggle = GUI.skin.toggle.normal.textColor; savedToggleOn = GUI.skin.toggle.onNormal.textColor; savedToggleHover = GUI.skin.toggle.hover.textColor; savedToggleOnHover = GUI.skin.toggle.onHover.textColor; Color textColor = Color.Lerp(Accent, Color.white, 0.5f); Color val = Color.Lerp(Accent, Color.white, 0.35f); Color val2 = Color.Lerp(Accent, new Color(0.6f, 0.6f, 0.6f), 0.55f); GUI.skin.label.normal.textColor = textColor; GUIStyleState normal = GUI.skin.toggle.normal; Color textColor2 = (GUI.skin.toggle.hover.textColor = val2); normal.textColor = textColor2; GUIStyleState onNormal = GUI.skin.toggle.onNormal; textColor2 = (GUI.skin.toggle.onHover.textColor = val); onNormal.textColor = textColor2; if (header != null) { header.normal.textColor = Color.Lerp(Accent, Color.white, 0.12f); } } private static void FontsOff() { //IL_0053: 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_0085: 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_00b7: Unknown result type (might be due to invalid IL or missing references) List<GUIStyle> list = AllStyles(); for (int i = 0; i < list.Count && i < savedSizes.Count; i++) { if (list[i] != null) { list[i].fontSize = savedSizes[i]; } } GUI.skin.label.normal.textColor = savedLabel; GUI.skin.toggle.normal.textColor = savedToggle; GUI.skin.toggle.onNormal.textColor = savedToggleOn; GUI.skin.toggle.hover.textColor = savedToggleHover; GUI.skin.toggle.onHover.textColor = savedToggleOnHover; } private static GUIStyle WindowStyle() { //IL_00a6: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Invalid comparison between Unknown and I4 //IL_0041: 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) //IL_0055: Expected O, but got Unknown //IL_005a: Expected O, but got Unknown //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Unknown result type (might be due to invalid IL or missing references) //IL_0125: 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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_00f6: 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_0145: 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_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Unknown result type (might be due to invalid IL or missing references) string value = Plugin.PanelBackground.Value; if (value != "Color" && value != "Animated") { return GUI.skin.window; } if (windowStyle == null) { windowStyle = new GUIStyle(GUI.skin.window) { border = new RectOffset(0, 0, 0, 0) }; bgTex = new Texture2D(8, 64, (TextureFormat)4, false) { wrapMode = (TextureWrapMode)1, filterMode = (FilterMode)1 }; bgPixels = (Color[])(object)new Color[512]; } windowStyle.fontSize = 15; GUIStyleState normal = windowStyle.normal; Color textColor = (windowStyle.onNormal.textColor = Color.white); normal.textColor = textColor; if ((int)Event.current.type == 7) { Color val2; Color val3; if (value == "Animated") { float num = Time.realtimeSinceStartup * 0.016f % 1f; val2 = Color.HSVToRGB(num, 0.6f, 0.42f); val3 = Color.HSVToRGB((num + 0.18f) % 1f, 0.7f, 0.2f); } else { Color val4 = Hex(Plugin.PanelBackgroundColor.Value); val2 = Color.Lerp(val4, Color.white, 0.08f); val3 = val4 * 0.7f; } for (int i = 0; i < 64; i++) { Color val5 = Color.Lerp(val3, val2, (float)i / 63f); val5.a = 0.95f; for (int j = 0; j < 8; j++) { bgPixels[i * 8 + j] = val5; } } bgTex.SetPixels(bgPixels); bgTex.Apply(); } GUIStyleState normal2 = windowStyle.normal; Texture2D background = (windowStyle.onNormal.background = bgTex); normal2.background = background; return windowStyle; } private static void Pop(Rect r, Color? color = null) { //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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_003a: 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) pops.Add(new PopFx { Rect = r, Start = Time.realtimeSinceStartup, InScroll = drawingScroll, Color = (Color)(((??)color) ?? Accent) }); } private static void DrawPops(bool inScroll) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Invalid comparison between Unknown and I4 //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) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_00fe: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_01b2: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: 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) if (pops.Count == 0 || (int)Event.current.type != 7) { return; } if (white == null) { white = Texture2D.whiteTexture; } float realtimeSinceStartup = Time.realtimeSinceStartup; Color color = GUI.color; Rect val = default(Rect); for (int num = pops.Count - 1; num >= 0; num--) { PopFx popFx = pops[num]; float num2 = (realtimeSinceStartup - popFx.Start) / 0.3f; if (num2 >= 1f) { pops.RemoveAt(num); } else if (popFx.InScroll == inScroll) { float num3 = 2f + 7f * num2; ((Rect)(ref val))..ctor(((Rect)(ref popFx.Rect)).x - num3, ((Rect)(ref popFx.Rect)).y - num3, ((Rect)(ref popFx.Rect)).width + num3 * 2f, ((Rect)(ref popFx.Rect)).height + num3 * 2f); Color color2 = Color.Lerp(popFx.Color, Color.white, 0.4f); color2.a = (1f - num2) * 0.55f; GUI.color = color2; float num4 = 2f; GUI.DrawTexture(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y, ((Rect)(ref val)).width, num4), (Texture)(object)white); GUI.DrawTexture(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).yMax - num4, ((Rect)(ref val)).width, num4), (Texture)(object)white); GUI.DrawTexture(new Rect(((Rect)(ref val)).x, ((Rect)(ref val)).y, num4, ((Rect)(ref val)).height), (Texture)(object)white); GUI.DrawTexture(new Rect(((Rect)(ref val)).xMax - num4, ((Rect)(ref val)).y, num4, ((Rect)(ref val)).height), (Texture)(object)white); color2.a = (1f - num2) * 0.18f; GUI.color = color2; GUI.DrawTexture(popFx.Rect, (Texture)(object)white); } } GUI.color = color; } private static bool Btn(string text, params GUILayoutOption[] options) { return Popped(GUILayout.Button(text, options)); } private static bool Btn(GUIContent content, params GUILayoutOption[] options) { return Popped(GUILayout.Button(content, options)); } private static bool Btn(string text, GUIStyle style, params GUILayoutOption[] options) { return Popped(GUILayout.Button(text, style, options)); } private static bool Popped(bool clicked) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) if (clicked) { Pop(GUILayoutUtility.GetLastRect()); } return clicked; } private static void MenuTab() { //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Expected O, but got Unknown //IL_01ae: Unknown result type (might be due to invalid IL or missing references) //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01ef: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) GUILayout.Label("Background", header, Array.Empty<GUILayoutOption>()); GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); (string, string)[] array = new(string, string)[3] { ("Classic", "The game's own grey window."), ("Color", "A colour you pick below."), ("Animated", "Slowly shifting colours.") }; for (int i = 0; i < array.Length; i++) { (string, string) tuple = array[i]; string item = tuple.Item1; string item2 = tuple.Item2; GUI.enabled = Plugin.PanelBackground.Value != item; if (Btn(new GUIContent((item == "Color") ? "Solid color" : item, item2))) { Plugin.PanelBackground.Value = item; } } GUI.enabled = true; GUILayout.EndHorizontal(); if (!(Plugin.PanelBackground.Value == "Color")) { return; } GUILayout.Space(6f); GUILayout.Label("Pick a colour", header, Array.Empty<GUILayoutOption>()); Color backgroundColor = GUI.backgroundColor; for (int j = 0; j < Swatches.Length; j++) { if (j % 4 == 0) { if (j > 0) { GUILayout.EndHorizontal(); } GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); } GUI.backgroundColor = Hex(Swatches[j].hex) * 2.2f; if (Btn(Swatches[j].name)) { Plugin.PanelBackgroundColor.Value = Swatches[j].hex; } } GUILayout.EndHorizontal(); GUI.backgroundColor = backgroundColor; Color val = Hex(Plugin.PanelBackgroundColor.Value); float num = Channel("Red", val.r); float num2 = Channel("Green", val.g); float num3 = Channel("Blue", val.b); string text = ColorUtility.ToHtmlStringRGB(new Color(num, num2, num3)); if (text != Plugin.PanelBackgroundColor.Value.ToUpperInvariant()) { Plugin.PanelBackgroundColor.Value = text; } } private static float Channel(string name, float value) { GUILayout.BeginHorizontal(Array.Empty<GUILayoutOption>()); GUILayout.Label(name, (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(55f) }); value = GUILayout.HorizontalSlider(value, 0f, 0.6f, Array.Empty<GUILayoutOption>()); GUILayout.Label(Mathf.RoundToInt(value / 0.6f * 100f) + "%", (GUILayoutOption[])(object)new GUILayoutOption[1] { GUILayout.Width(45f) }); GUILayout.EndHorizontal(); return value; } private static Color Hex(string hex) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) if (hex == null || hex.Length < 6 || !uint.TryParse(hex.Substring(0, 6), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var result)) { return new Color(0.11f, 0.14f, 0.25f); } return new Color((float)((result >> 16) & 0xFF) / 255f, (float)((result >> 8) & 0xFF) / 255f, (float)(result & 0xFF) / 255f); } } internal static class Actions { public static void SetMaxPlayers(int n) { n = Mathf.Clamp(n, 1, 20); Plugin.MaxPlayers.Value = n; if ((Object)(object)GameManager.instance != (Object)null) { GameManager.instance.SetMaxPlayers(n); } } } [HarmonyPatch(typeof(RunManager), "Update")] internal static class KeepRunnerAlivePatch { private static void Postfix() { Runner.Get(); } } [HarmonyPatch(typeof(RunManager), "SetRunLevel")] internal static class VanillaMapsPatch { private static bool listLogged; [HarmonyPriority(0)] private static void Postfix(RunManager __instance) { if (!Plugin.PublicVanillaMaps.Value || !SemiFunc.IsMultiplayer() || !SemiFunc.IsMasterClient() || (Object)(object)GameManager.instance == (Object)null || !GameManager.instance.connectRandom) { return; } HashSet<Level> modded = ModdedLevels(); if (!listLogged && modded.Count > 0) { listLogged = true; Plugin.Log.LogInfo((object)("Modded maps (skipped in public lobbies): " + string.Join(", ", modded.Select((Level l) => ((Object)l).name)))); } Level levelCurrent = __instance.levelCurrent; if (!((Object)(object)levelCurrent == (Object)null) && modded.Contains(levelCurrent)) { List<Level> list = __instance.levels.Where((Level l) => (Object)(object)l != (Object)null && !modded.Contains(l)).ToList(); List<Level> list2 = list.Where((Level l) => (Object)(object)l != (Object)(object)__instance.previousRunLevel).ToList(); if (list2.Count == 0) { list2 = list; } if (list2.Count != 0) { __instance.levelCurrent = list2[Random.Range(0, list2.Count)]; Plugin.Log.LogInfo((object)("Public lobby: skipped modded map " + ((Object)levelCurrent).name + ", going to " + ((Object)__instance.levelCurrent).name + " instead")); } } } private static HashSet<Level> ModdedLevels() { HashSet<Level> hashSet = new HashSet<Level>(); if ((AccessTools.TypeByName("REPOLib.Modules.Levels")?.GetProperty("RegisteredLevels"))?.GetValue(null) is IEnumerable enumerable) { foreach (object item in enumerable) { Level val = (Level)((item is Level) ? item : null); if (val != null && (Object)(object)val != (Object)null) { hashSet.Add(val); } } } return hashSet; } } [HarmonyPatch(typeof(GameManager), "SetMaxPlayers")] internal static class MaxPlayersPatch { private static void Prefix(ref int _target) { _target = Plugin.EffectiveMaxPlayers; } } [HarmonyPatch(typeof(NetworkConnect), "OnConnectedToMaster")] internal static class LobbyCreatePatch { private static string lastStyled; [HarmonyPriority(0)] private static void Prefix() { if ((Object)(object)GameManager.instance != (Object)null) { GameManager.instance.SetMaxPlayers(Plugin.EffectiveMaxPlayers); } DataDirector instance = DataDirector.instance; if ((Object)(object)instance != (Object)null && (Object)(object)GameManager.instance != (Object)null && GameManager.instance.connectRandom && !string.IsNullOrEmpty(instance.networkServerName)) { string text = LobbyNameMemory.Clean(instance.networkServerName); if (text.Length > 0 && text != instance.networkServerName) { Plugin.Log.LogInfo((object)("Lobby name: took the late-join tag off \"" + instance.networkServerName + "\"")); instance.networkServerName = text; } } string value = Plugin.LobbyNameStyle.Value; if ((Object)(object)instance != (Object)null && (Object)(object)GameManager.instance != (Object)null && GameManager.instance.connectRandom && !string.IsNullOrEmpty(instance.networkServerName) && instance.networkServerName != lastStyled && value.Contains("{name}") && value != "{name}") { instance.networkServerName = value.Replace("{name}", instance.networkServerName); lastStyled = instance.networkServerName; Plugin.Log.LogInfo((object)("Creating lobby as: " + instance.networkServerName)); } } } [HarmonyPatch(typeof(NetworkConnect), "OnCreatedRoom")] internal static class StartOnCreatePatch { private static void Postfix() { if (Plugin.StartOnCreate.Value) { AutoStart.StartWhenReady(); } } } [HarmonyPatch(typeof(PlayerAvatar), "AddToStatsManagerRPC")] internal static class PlayerJoinPatch { private static void Postfix(PlayerAvatar __instance, string _playerName, string _steamID) { if (!Runner.IsHost) { return; } if ((Object)(object)EnemyDirector.instance != (Object)null) { foreach (EnemyParent item in EnemyDirector.instance.enemiesSpawned) { if ((Object)(object)item != (Object)null && (Object)(object)item.Enemy != (Object)null) { item.Enemy.PlayerAdded(__instance.photonView.ViewID); } } } if (!__instance.isLocal && Plugin.WelcomeEnabled.Value && Runner.Welcomed.Add(__instance.photonView.OwnerActorNr)) { Runner.Say(Plugin.WelcomeMessage.Value.Replace("{name}", _playerName)); } } } [BepInPlugin("repo.hosttools", "Feris Mod Menu", "1.0.0")] public class Plugin : BaseUnityPlugin { public const string Guid = "repo.hosttools"; internal static ManualLogSource Log; internal static string ConfigDir; internal static ConfigEntry<bool> WelcomeEnabled; internal static ConfigEntry<string> WelcomeMessage; internal static ConfigEntry<string> LobbyNameStyle; internal static ConfigEntry<string> LastLobbyName; internal static ConfigEntry<bool> AutoStartEnabled; internal static ConfigEntry<int> AutoStartMinPlayers; internal static ConfigEntry<int> AutoStartSeconds; private const bool On = false; internal static ConfigFile Cfg; internal static ConfigEntry<bool> GhostLogEnabled; internal static ConfigEntry<int> MaxPlayers; internal static ConfigEntry<bool> PublicVanillaMaps; internal static ConfigEntry<KeyboardShortcut> PanelKey; internal static ConfigEntry<bool> ResumePublicRun; internal static ConfigEntry<string> PanelWindow; internal static ConfigEntry<string> PanelBackground; internal static ConfigEntry<string> PanelBackgroundColor; internal static ConfigEntry<bool> StartOnCreate; internal static int EffectiveMaxPlayers => Mathf.Min(WantedMaxPlayers, ((Object)(object)GameManager.instance != (Object)null) ? GameManager.instance.maxPlayersPhoton : 20); private static int WantedMaxPlayers { get { if (MaxPlayers.Value > 0) { return MaxPlayers.Value; } ConfigEntry<int> val = default(ConfigEntry<int>); if (Chainloader.PluginInfos.TryGetValue("zelofi.MorePlayers", out var value) && (Object)(object)value.Instance != (Object)null && value.Instance.Config.TryGetEntry<int>("General", "MaxPlayers", ref val) && val.Value > 0) { return val.Value; } return 10; } } private void Awake() { //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Expected O, but got Unknown //IL_02b7: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; ConfigDir = Paths.ConfigPath; Cfg = ((BaseUnityPlugin)this).Config; GhostLog.Init(); WelcomeEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Welcome", "Enabled", false, "Your character greets players in chat when they join."); WelcomeMessage = ((BaseUnityPlugin)this).Config.Bind<string>("Welcome", "Message", "We have a new player that just joined, welcome {name}!", "What to say. {name} = the player's name."); LobbyNameStyle = ((BaseUnityPlugin)this).Config.Bind<string>("LobbyName", "Style", "{name}", "Applied when you create a public lobby. {name} = what you typed, e.g. \"[EN] {name} | chill\". (The game's server doesn't allow renaming a lobby after it's created.)"); LastLobbyName = ((BaseUnityPlugin)this).Config.Bind<string>("LobbyName", "LastName", "", "The name you typed for your last public server. It's filled in for you next time (clear it to start empty)."); AutoStartEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("AutoStart", "Enabled", false, "Start the run automatically from the lobby menu once enough players are in."); AutoStartMinPlayers = ((BaseUnityPlugin)this).Config.Bind<int>("AutoStart", "MinPlayers", 4, "Players needed (including you) before the countdown starts."); AutoStartSeconds = ((BaseUnityPlugin)this).Config.Bind<int>("AutoStart", "Seconds", 60, "Countdown length in seconds."); StartOnCreate = ((BaseUnityPlugin)this).Config.Bind<bool>("AutoStart", "StartOnCreate", false, "Start the run right away after you create a lobby (skips waiting on the lobby screen). People can still late-join."); PanelKey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Panel", "Key", new KeyboardShortcut((KeyCode)289, Array.Empty<KeyCode>()), "Opens and closes the Feris Mod Menu window."); PanelBackground = ((BaseUnityPlugin)this).Config.Bind<string>("Panel", "Background", "Classic", new ConfigDescription("F8 window background: Classic (the game's), Color (PanelBackgroundColor) or Animated.", (AcceptableValueBase)(object)new AcceptableValueList<string>(new string[3] { "Classic", "Color", "Animated" }), Array.Empty<object>())); PanelBackgroundColor = ((BaseUnityPlugin)this).Config.Bind<string>("Panel", "BackgroundColor", "1C2340", "F8 window background colour (hex RGB) for the Color background."); PanelWindow = ((BaseUnityPlugin)this).Config.Bind<string>("Panel", "Window", "40,80,460,560", "Window position and size (x,y,width,height). Saved automatically."); MaxPlayers = ((BaseUnityPlugin)this).Config.Bind<int>("Lobby", "MaxPlayers", 0, "Max players for lobbies you host, public ones included (game limit 20). 0 = use MorePlayers' setting, or 10 without it."); ResumePublicRun = ((BaseUnityPlugin)this).Config.Bind<bool>("Lobby", "ContinueLastPublicRun", false, "Save your public runs (the game only saves private ones) and continue the last one when you create a public server: after quitting to the menu, closing the game or a crash. One save slot, so it never fills the game's 10-save limit. A run that ended in a wipe is deleted by the game and starts fresh."); PublicVanillaMaps = ((BaseUnityPlugin)this).Config.Bind<bool>("Lobby", "PublicVanillaMapsOnly", false, "In public lobbies, only play the game's own maps. Modded maps (Backrooms, Minecraft, Wesley's...) need every player to have the mod; random players don't, and the loading screen hangs. Private/friends lobbies keep all maps."); GhostLogEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("Diagnostics", "Log", false, "Write a log of what Feris Mod Menu does (loot top-ups, haul goal, errors) to BepInEx/FerisModMenu-logs, for working out problems later. One file per game launch; the newest 8 are kept."); ((BaseUnityPlugin)this).Config.SettingChanged += delegate(object _, SettingChangedEventArgs e) { GhostLog.SettingChanged(e.ChangedSetting); }; Harmony.UnpatchID("repo.hosttools"); Runner.DestroyOld(); new Harmony("repo.hosttools").PatchAll(); Log.LogInfo((object)("Loaded - " + UiMetrics.Byline + " - " + UiMetrics.Label)); } private void RemoveOldSettings() { try { IDictionary dictionary = (IDictionary)AccessTools.Property(typeof(ConfigFile), "OrphanedEntries").GetValue(((BaseUnityPlugin)this).Config); if (dictionary != null && dictionary.Count > 0) { Log.LogInfo((object)$"Removing {dictionary.Count} unused old setting(s) from the config file"); dictionary.Clear(); ((BaseUnityPlugin)this).Config.Save(); } } catch (Exception ex) { Log.LogWarning((object)("Couldn't tidy the config file: " + ex.Message)); } } } internal static class ResumeRun { [HarmonyPatch(typeof(MenuPageServerListCreateNew), "ButtonConfirm")] internal static class CreatePublicPatch { private static void Prefix(MenuPageServerListCreateNew __instance, out bool __state) { __state = false; if (Plugin.ResumePublicRun.Value && __instance.saveFileName == null && HasSave) { __instance.saveFileName = "REPO_SAVE_HOSTTOOLS_PUBLIC"; __state = true; Plugin.Log.LogInfo((object)("Resume: continuing your last public run (" + Describe() + ")")); } } private static void Postfix(MenuPageServerListCreateNew __instance, bool __state) { if (Plugin.ResumePublicRun.Value && !((Object)(object)StatsManager.instance == (Object)null)) { if (__state) { Runner.Toast("Continuing your last run: " + Describe()); __instance.saveFileName = null; } else if (!string.IsNullOrEmpty(__instance.menuTextInput?.textCurrent)) { StatsManager.instance.saveFileCurrent = "REPO_SAVE_HOSTTOOLS_PUBLIC"; } } } } [HarmonyPatch(typeof(StatsManager), "SaveFileSave")] internal static class SavePublicPatch { private static void Postfix(StatsManager __instance) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 if (Plugin.ResumePublicRun.Value && !((Object)(object)GameManager.instance == (Object)null) && (int)GameManager.instance.lobbyType == 1 && SemiFunc.IsMasterClientOrSingleplayer() && !(__instance.saveFileCurrent != "REPO_SAVE_HOSTTOOLS_PUBLIC")) { __instance.SaveGame("REPO_SAVE_HOSTTOOLS_PUBLIC"); Plugin.Log.LogInfo((object)("Resume: public run saved (" + Describe() + ")")); } } } internal const string SaveName = "REPO_SAVE_HOSTTOOLS_PUBLIC"; private static string SaveFile => Path.Combine(Application.persistentDataPath, "saves", "REPO_SAVE_HOSTTOOLS_PUBLIC", "REPO_SAVE_HOSTTOOLS_PUBLIC.es3"); internal static bool HasSave => File.Exists(SaveFile); internal static string Describe() { if (!HasSave || (Object)(object)StatsManager.instance == (Object)null) { return null; } try { int.TryParse(StatsManager.instance.SaveFileGetRunLevel("REPO_SAVE_HOSTTOOLS_PUBLIC", (string)null), out var result); int.TryParse(StatsManager.instance.SaveFileGetRunCurrency("REPO_SAVE_HOSTTOOLS_PUBLIC", (string)null), out var result2); return $"Level {result + 1}, ${result2}k in the bank"; } catch { return "saved run"; } } internal static void Forget() { if (HasSave && (Object)(object)StatsManager.instance != (Object)null) { StatsManager.instance.SaveFileDelete("REPO_SAVE_HOSTTOOLS_PUBLIC"); Plugin.Log.LogInfo((object)"Resume: saved public run deleted, the next public server starts fresh"); } } } internal class Runner : MonoBehaviour { private static Runner instance; private string currentRoom; internal static readonly HashSet<int> Welcomed = new HashSet<int>(); private readonly Queue<string> messages = new Queue<string>(); private float nextMessageTime; private static string toast; private static float toastUntil; private GUIStyle toastStyle; internal static bool IsHost { get { if (PhotonNetwork.InRoom) { return PhotonNetwork.IsMasterClient; } return false; } } internal static bool InGameplay { get { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 if ((Object)(object)GameDirector.instance != (Object)null) { return (int)GameDirector.instance.currentState == 2; } return false; } } public static Runner Get() { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0017: 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_0025: Expected O, but got Unknown if ((Object)(object)instance == (Object)null) { GameObject val = new GameObject("HostToolsRunner") { hideFlags = (HideFlags)61 }; Object.DontDestroyOnLoad((Object)val); instance = val.AddComponent<Runner>(); Plugin.Log.LogInfo((object)"Runner started"); } return instance; } internal static void DestroyOld() { foreach (GameObject item in from g in Resources.FindObjectsOfTypeAll<GameObject>() where ((Object)g).name == "HostToolsRunner" select g) { Object.Destroy((Object)(object)item); } } private void OnEnable() { } private void OnDestroy() { Panel.Save(); GhostLog.World("LOG", "closing (game quitting or mod reloaded)"); GhostLog.Close(); } private void Update() { string text = (PhotonNetwork.InRoom ? PhotonNetwork.CurrentRoom.Name : null); if (text != currentRoom) { currentRoom = text; Welcomed.Clear(); if (PhotonNetwork.InRoom) { Player[] playerListOthers = PhotonNetwork.PlayerListOthers; foreach (Player val in playerListOthers) { Welcomed.Add(val.ActorNumber); } } AutoStart.Reset(); messages.Clear(); } Panel.Update(); GhostLog.Tick(); _ = UiMetrics.Ready; if (IsHost) { UpdateAnnouncer(); AutoStart.Tick(); } } internal static void Say(string message) { if (!((Object)(object)instance == (Object)null) && !string.IsNullOrWhiteSpace(message) && !instance.messages.Contains(message)) { instance.messages.Enqueue(message); while (instance.messages.Count > 4) { instance.messages.Dequeue(); } } } private void UpdateAnnouncer() { if (messages.Count != 0 && !(Time.time < nextMessageTime) && !((Object)(object)PlayerAvatar.instance == (Object)null) && InGameplay) { string text = messages.Dequeue(); Plugin.Log.LogInfo((object)("Say: " + text)); PlayerAvatar.instance.ChatMessageSend(text); nextMessageTime = Time.time + 2f + (float)text.Length * 0.06f; } } internal static string Phase() { if ((Object)(object)RunManager.instance == (Object)null) { return ""; } if (SemiFunc.RunIsLobbyMenu()) { return "Lobby"; } if (SemiFunc.RunIsLobby()) { return "Truck"; } if (SemiFunc.RunIsShop()) { return "Shop"; } if (SemiFunc.RunIsArena()) { return "Arena"; } if (SemiFunc.RunIsLevel()) { return "Level " + (RunManager.instance.levelsCompleted + 1); } return ""; } internal static void Toast(string text, float seconds = 5f) { toast = text; toastUntil = Time.realtimeSinceStartup + seconds; Plugin.Log.LogInfo((object)text); } private void OnGUI() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Expected O, but got Unknown UiMetrics.Draw(); Panel.Draw(); if (toast != null && !(Time.realtimeSinceStartup > toastUntil)) { if (toastStyle == null) { toastStyle = new GUIStyle(GUI.skin.box) { fontSize = 18, alignment = (TextAnchor)0, wordWrap = true }; } toastStyle.normal.textColor = Color.yellow; float scale = Panel.Scale; Matrix4x4 matrix = GUI.matrix; GUI.matrix = Matrix4x4.Scale(new Vector3(scale, scale, 1f)); GUIContent val = new GUIContent("[" + UiMetrics.ModName + "] " + toast); GUI.Box(new Rect(20f, 20f, 520f, toastStyle.CalcHeight(val, 520f)), val, toastStyle); GUI.matrix = matrix; } } } internal static class SceneMemo { private const string RootName = "HostToolsMemo"; private static int LevelId { get { if (!((Object)(object)LevelGenerator.Instance != (Object)null)) { return 0; } return ((Object)LevelGenerator.Instance).GetInstanceID(); } } public static string Get(string key) { //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown GameObject val = GameObject.Find("HostToolsMemo"); if ((Object)(object)val == (Object)null) { return null; } string text = $"{key}@{LevelId}="; foreach (Transform item in val.transform) { Transform val2 = item; if (((Object)val2).name.StartsWith(text)) { return ((Object)val2).name.Substring(text.Length); } } return null; } public static void Set(string key, string value) { //IL_0013: 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_0049: Expected O, but got Unknown //IL_0095: Unknown result type (might be due to invalid IL or missing references) GameObject val = (GameObject)(((object)GameObject.Find("HostToolsMemo")) ?? ((object)new GameObject("HostToolsMemo"))); string text = $"{key}@{LevelId}="; foreach (Transform item in val.transform) { Transform val2 = item; if (((Object)val2).name.StartsWith(key + "@")) { ((Object)val2).name = text + value; return; } } new GameObject(text + value).transform.SetParent(val.transform, false); } public static float? GetFloat(string key) { if (!float.TryParse(Get(key), NumberStyles.Float, CultureInfo.InvariantCulture, out var result)) { return null; } return result; } public static void SetFloat(string key, float value) { Set(key, value.ToString("R", CultureInfo.InvariantCulture)); } } internal static class UiMetrics { private static readonly byte[] p2 = new byte[16] { 217, 217, 217, 37, 211, 218, 215, 214, 153, 221, 222, 211, 158, 34, 215, 223 }; private const uint Sig = 1394378038u; private static readonly byte[] q2 = new byte[31] { 208, 208, 208, 204, 218, 211, 222, 223, 97, 202, 35, 97, 222, 221, 34, 214, 97, 206, 215, 222, 54, 97, 221, 208, 54, 97, 204, 218, 211, 222, 63 }; private const uint Sig2 = 221695761u; private static readonly byte[] LensTable = new byte[4] { 138, 128, 254, 175 }; private static readonly byte[] GaitTable = new byte[4] { 2, 52, 56, 46 }; private static readonly byte[] FloorBias = new byte[4] { 94, 95, 84, 97 }; private static readonly byte[] PulseTable = new byte[16] { 1, 61, 31, 23, 0, 36, 84, 69, 91, 16, 136, 179, 133, 137, 209, 239 }; private static readonly byte[] SpotSeed = new byte[4] { 3, 30, 10, 99 }; private static readonly byte[] PriceSteps = new byte[15] { 15, 53, 33, 151, 216, 212, 176, 229, 147, 139, 133, 172, 173, 90, 87 }; private static string label; private static string byline; private static GUIStyle style; private static GUIStyle shadow; private static int drawnFrame = -1; internal static bool Ready { get { if (Hash(Label) == 1394378038 && Hash(Byline) == 221695761) { if (drawnFrame >= 0) { return Time.frameCount - drawnFrame < 600; } return Time.frameCount < 3000; } return false; } } internal static string Label => label ?? (label = Build()); internal static string Byline => byline ?? (byline = BuildByline()); private static int CreditStart { get { string text = Byline; int num = text.Length; for (int i = 0; i < 3; i++) { if (num <= 0) { break; } num = text.LastIndexOf(' ', num - 1); } return num; } } internal static string ModName { get { if (CreditStart <= 0) { return Byline; } return Byline.Substring(0, CreditStart); } } internal static string MadeBy { get { if (CreditStart <= 0) { return ""; } return Byline.Substring(CreditStart + 1); } } private static string BuildByline() { byte[][] array = new byte[2][] { PulseTable, PriceSteps }; byte[] array2 = new byte[2] { 78, 183 }; char[] array3 = new char[array[0].Length + array[1].Length]; int num = 0; for (int i = 0; i < 2; i++) { int num2 = 0; while (num2 < array[i].Length) { array3[num] = (char)(array[i][num2] ^ array2[i] ^ ((num * 13 + 9) & 0xFF)); num2++; num++; } } string text = new string(array3); if (Hash(text) == 221695761) { return text; } char[] array4 = new char[q2.Length]; for (int j = 0; j < q2.Length; j++) { array4[q2.Length - 1 - j] = (char)(((q2[j] ^ 0x5C) - 29) & 0xFF); } return new string(array4); } private static string Build() { byte[][] array = new byte[4][] { SpotSeed, LensTable, GaitTable, FloorBias }; byte[] array2 = new byte[4] { 107, 210, 57, 164 }; char[] array3 = new char[16]; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { int num = i * 4 + j; array3[num] = (char)(array[i][j] ^ array2[i] ^ ((num * 11 + 5) & 0xFF)); } } string text = new string(array3); if (Hash(text) == 1394378038) { return text; } char[] array4 = new char[p2.Length]; for (int k = 0; k < p2.Length; k++) { array4[p2.Length - 1 - k] = (char)(((p2[k] ^ 0xA5) - 13) & 0xFF); } return new string(array4); } private static uint Hash(string s) { uint num = 2166136261u; foreach (char c in s) { num ^= c; num *= 16777619; } return num; } public static void Draw() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_009d: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00f1: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0153: 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_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown if (style == null) { style = new GUIStyle(GUI.skin.label) { fontSize = 19, fontStyle = (FontStyle)1, alignment = (TextAnchor)8 }; } if (shadow == null) { shadow = new GUIStyle(style); } style.normal.textColor = new Color(1f, 0.85f, 0.1f, 0.95f); shadow.normal.textColor = new Color(0f, 0f, 0f, 0.75f); float scale = Panel.Scale; Matrix4x4 matrix = GUI.matrix; GUI.matrix = Matrix4x4.Scale(new Vector3(scale, scale, 1f)); float num = (float)Screen.width / scale; float num2 = (float)Screen.height / scale; drawnFrame = Time.frameCount; Line(ModName, new Rect(num - 420f, num2 - 114f, 410f, 28f)); Line(MadeBy, new Rect(num - 420f, num2 - 88f, 410f, 28f)); Line(Label, new Rect(num - 420f, num2 - 62f, 410f, 28f)); Line($"Press {Plugin.PanelKey.Value} for the menu", new Rect(num - 420f, num2 - 36f, 410f, 28f)); GUI.matrix = matrix; } private static void Line(string text, Rect r) { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Unknown result type (might be due to invalid IL or missing references) GUI.Label(new Rect(((Rect)(ref r)).x + 1.5f, ((Rect)(ref r)).y + 1.5f, ((Rect)(ref r)).width, ((Rect)(ref r)).height), text, shadow); GUI.Label(r, text, style); } } } namespace System.Runtime.CompilerServices { [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)] internal sealed class IgnoresAccessChecksToAttribute : Attribute { public IgnoresAccessChecksToAttribute(string assemblyName) { } } }