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 BifrostGateway v1.0.1
BifrostGateway.dll
Decompiled 2 weeks agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("BifrostGateway")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.1.0")] [assembly: AssemblyInformationalVersion("1.0.1+901b84ab23f2f10926b13865f9b40bb283490874")] [assembly: AssemblyProduct("BifrostGateway")] [assembly: AssemblyTitle("BifrostGateway")] [assembly: AssemblyVersion("1.0.1.0")] [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 BifrostGateway { [BepInPlugin("com.dfg.bifrostgateway", "Bifrost Gateway", "1.0.1")] [BepInProcess("valheim.exe")] public class BifrostGatewayPlugin : BaseUnityPlugin { public const string Guid = "com.dfg.bifrostgateway"; public const string Version = "1.0.1"; internal static ManualLogSource Log; private readonly List<GatewayServer> _servers = new List<GatewayServer>(); private bool _loaded; internal static BifrostGatewayPlugin Instance { get; private set; } internal GatewaySettings Settings { get; private set; } private void Awake() { //IL_004e: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Instance = this; Settings = new GatewaySettings(((BaseUnityPlugin)this).Config); _servers.AddRange(GatewayStore.Load(out var warning)); _loaded = true; if (warning != null) { Log.LogWarning((object)warning); } new Harmony("com.dfg.bifrostgateway").PatchAll(typeof(BifrostGatewayPlugin).Assembly); Log.LogInfo((object)("Bifrost Gateway 1.0.1 ready with " + _servers.Count + " server(s). Automatic passwords: " + (GatewayJoin.CanSupplyPassword ? "available" : "UNAVAILABLE, the game will prompt") + ". Character-select flow: " + (GatewayJoin.CanSelectCharacter ? "available" : "unavailable, rows will join directly") + ".")); if (!GatewayJoin.CanSupplyPassword) { Log.LogWarning((object)"FejdStartup.set_ServerPassword was not found on this build. Servers with a saved password will still connect, but the game will ask for it by hand."); } } private void OnDestroy() { if ((Object)(object)Instance == (Object)(object)this) { Instance = null; } } private void OnGUI() { if (!_loaded || Settings == null || !Settings.Enabled.Value) { return; } FejdStartup instance = FejdStartup.instance; if (!((Object)(object)instance == (Object)null) && !((Object)(object)ZNet.instance != (Object)null)) { bool num = (Object)(object)instance.m_mainMenu != (Object)null && instance.m_mainMenu.activeSelf; bool flag = (Object)(object)instance.m_characterSelectScreen != (Object)null && instance.m_characterSelectScreen.activeSelf; if (num || flag) { GatewayPanel.Draw(this, _servers); } } } } internal sealed class GatewaySettings { internal ConfigEntry<bool> Enabled; internal ConfigEntry<float> RefreshSeconds; internal ConfigEntry<float> PanelWidth; internal ConfigEntry<float> PanelLeft; internal ConfigEntry<float> PanelTop; internal GatewaySettings(ConfigFile config) { Enabled = config.Bind<bool>("General", "Enabled", true, "Show the Bifrost Gateway panel on the main menu."); RefreshSeconds = config.Bind<float>("General", "RefreshSeconds", 30f, "How often, in seconds, to re-read player counts for every listed server. Minimum 5."); PanelWidth = config.Bind<float>("Layout", "PanelWidth", 460f, "Width of the panel in pixels."); PanelLeft = config.Bind<float>("Layout", "PanelLeft", 40f, "Distance of the panel from the left edge, in pixels."); PanelTop = config.Bind<float>("Layout", "PanelTop", 60f, "Distance of the panel from the top of the screen, in pixels."); } } internal static class JoinFactory { internal static ServerJoinData Dedicated(string address, int port) { //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) return new ServerJoinData(new ServerJoinDataDedicated((address ?? "").Trim(), (ushort)port)); } } internal static class GatewayJoin { private static readonly MethodInfo SetServerPassword = AccessTools.Method(typeof(FejdStartup), "set_ServerPassword", (Type[])null, (Type[])null); private static readonly MethodInfo ProceedJoinRequest = AccessTools.Method(typeof(FejdStartup), "ProceedJoinRequest", (Type[])null, (Type[])null); private static bool s_passwordSetterWarned; private static bool s_proceedJoinWarned; private static string s_pendingEndpoint; internal static bool CanSupplyPassword => SetServerPassword != null; internal static bool CanSelectCharacter => ProceedJoinRequest != null; internal static string PendingEndpoint => s_pendingEndpoint; internal static bool Connect(GatewayServer server, Action<string, bool> feedback) { //IL_0074: 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_007b: 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) if (server == null) { feedback?.Invoke("No server selected.", arg2: true); return false; } if (!server.IsUsable(out var problem)) { feedback?.Invoke(problem, arg2: true); return false; } FejdStartup instance = FejdStartup.instance; if ((Object)(object)instance == (Object)null) { feedback?.Invoke("Not at the main menu.", arg2: true); return false; } if (!SupplyPassword(server.Password)) { feedback?.Invoke("Cannot set the join password on this build; the game will ask for it.", arg2: true); } try { ServerJoinData val = JoinFactory.Dedicated(server.Address, server.SafePort); bool flag = TryProceedWithCharacterSelect(instance, val); if (!flag) { instance.SetServerToJoin(val); instance.JoinServer(); } s_pendingEndpoint = server.Endpoint; if (feedback != null) { string text = (string.IsNullOrEmpty(server.Password) ? "" : " with its saved password"); if (flag) { feedback("Select your character to join " + server.DisplayName + text + "...", arg2: false); } else { feedback("Connecting to " + server.DisplayName + text + "...", arg2: false); } } return true; } catch (Exception ex) { s_pendingEndpoint = null; feedback?.Invoke("Could not start the connection: " + ex.Message, arg2: true); BifrostGatewayPlugin.Log.LogError((object)("Join failed for " + server.Endpoint + ": " + ex)); return false; } } private static bool TryProceedWithCharacterSelect(FejdStartup startup, ServerJoinData join) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) if (ProceedJoinRequest == null) { if (!s_proceedJoinWarned) { s_proceedJoinWarned = true; BifrostGatewayPlugin.Log.LogWarning((object)"FejdStartup.ProceedJoinRequest not found on this build. Rows will join immediately without the character-selection prompt. Re-run verify_api.ps1 after a game update."); } return false; } try { ProceedJoinRequest.Invoke(startup, new object[1] { join }); return true; } catch (Exception ex) { if (!s_proceedJoinWarned) { s_proceedJoinWarned = true; BifrostGatewayPlugin.Log.LogError((object)("Could not invoke FejdStartup.ProceedJoinRequest: " + ex.Message)); } return false; } } private static bool SupplyPassword(string password) { if (SetServerPassword == null) { if (!s_passwordSetterWarned) { s_passwordSetterWarned = true; BifrostGatewayPlugin.Log.LogWarning((object)"FejdStartup.set_ServerPassword not found. Saved passwords will not be applied automatically and the game will prompt. Re-run verify_api.ps1 after a game update."); } return false; } try { SetServerPassword.Invoke(null, new object[1] { password ?? "" }); return true; } catch (Exception ex) { if (!s_passwordSetterWarned) { s_passwordSetterWarned = true; BifrostGatewayPlugin.Log.LogError((object)("Could not set the join password: " + ex.Message)); } return false; } } } [HarmonyPatch] internal static class PasswordCleanupPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(ZNet), "RPC_ClientHandshake", (Type[])null, (Type[])null); } private static void Postfix() { try { MethodInfo methodInfo = AccessTools.Method(typeof(FejdStartup), "set_ServerPassword", (Type[])null, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(null, new object[1] { "" }); } } catch (Exception ex) { BifrostGatewayPlugin.Log.LogWarning((object)("Could not clear the saved join password: " + ex.Message)); } } } [HarmonyPatch] internal static class CharacterSelectBackPatch { private static MethodBase TargetMethod() { return AccessTools.Method(typeof(FejdStartup), "OnSelelectCharacterBack", (Type[])null, (Type[])null); } private static void Postfix() { try { MethodInfo methodInfo = AccessTools.Method(typeof(FejdStartup), "set_ServerPassword", (Type[])null, (Type[])null); if (methodInfo != null) { methodInfo.Invoke(null, new object[1] { "" }); } } catch (Exception ex) { BifrostGatewayPlugin.Log.LogWarning((object)("Could not clear the saved join password on character-select back: " + ex.Message)); } } } internal static class GatewayPanel { private const float DefaultPanelWidth = 460f; private const float DefaultPanelLeft = 40f; private const float DefaultPanelTop = 60f; private const float HeaderHeight = 64f; private const float RowHeight = 46f; private const float FooterHeight = 44f; private const float MessageHeight = 20f; private const float Pad = 12f; private const float RowEditWidth = 26f; private static readonly List<ServerStatus> Statuses = new List<ServerStatus>(); private static Vector2 Scroll; private static DateTime s_nextProbeUtc = DateTime.MinValue; private static int s_probedCount = -1; private static bool s_editing; private static int s_editIndex = -1; private static GatewayServer s_draft; private static string s_portText = "2480"; private static bool s_portDirty; private static string s_message; private static bool s_messageIsError; private static bool s_loggedGate; internal static void Draw(BifrostGatewayPlugin plugin, List<GatewayServer> servers) { //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0175: Unknown result type (might be due to invalid IL or missing references) //IL_0216: Unknown result type (might be due to invalid IL or missing references) //IL_0218: 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_0243: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_02f7: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_036f: Unknown result type (might be due to invalid IL or missing references) Cursor.visible = true; Cursor.lockState = (CursorLockMode)0; if (servers == null) { servers = new List<GatewayServer>(); } RefreshIfDue(servers, plugin); float num = Mathf.Clamp(plugin.Settings.PanelWidth.Value, 300f, 900f); float num2 = Mathf.Max(0f, plugin.Settings.PanelLeft.Value); float num3 = Mathf.Max(0f, plugin.Settings.PanelTop.Value); float num4 = (string.IsNullOrEmpty(s_message) ? 0f : 20f); float num5 = 120f + (float)servers.Count * 46f + (s_editing ? 190f : 0f) + 96f + num4; float num6 = Mathf.Min(Mathf.Max((float)Screen.height - num3 * 2f, 240f), num5); num6 = Mathf.Max(num6, Mathf.Min(320f, Mathf.Max((float)Screen.height - num3 * 2f, 240f))); Rect rect = default(Rect); ((Rect)(ref rect))..ctor(num2, num3, num, num6); GatewayTheme.DrawFrame(rect); Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref rect)).x + 12f, ((Rect)(ref rect)).y + 12f, ((Rect)(ref rect)).width - 24f, ((Rect)(ref rect)).height - 24f); float y = ((Rect)(ref val)).y; y = DrawHeader(new Rect(((Rect)(ref val)).x, y, ((Rect)(ref val)).width, 64f)); Rect rect2 = default(Rect); ((Rect)(ref rect2))..ctor(((Rect)(ref val)).x, ((Rect)(ref rect)).yMax - 12f - 44f, ((Rect)(ref val)).width, 44f); float num7 = ((Rect)(ref rect2)).y - 4f - y - num4; Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref val)).x, y, ((Rect)(ref val)).width, Mathf.Max(num7, 24f)); float num8 = (float)servers.Count * 46f; if (s_editing) { num8 += 182f; } bool flag = num8 > ((Rect)(ref val2)).height; if (flag) { Scroll = GUI.BeginScrollView(val2, Scroll, new Rect(((Rect)(ref val2)).x, ((Rect)(ref val2)).y, ((Rect)(ref val2)).width, num8), GUIStyle.none, GUIStyle.none); } float num9 = ((Rect)(ref val2)).y; for (int i = 0; i < servers.Count; i++) { ServerStatus status = ((i < Statuses.Count) ? Statuses[i] : default(ServerStatus)); DrawRow(new Rect(((Rect)(ref val2)).x, num9, ((Rect)(ref val2)).width, 42f), i, servers[i], status); num9 += 46f; } if (servers.Count == 0) { GatewayTheme.Label(new Rect(((Rect)(ref val2)).x + 12f, num9 + 12f, ((Rect)(ref val2)).width - 24f, 40f), "No servers yet. Add one below.", 15, bold: false, (TextAnchor)0, GatewayTheme.MutedText); } if (s_editing) { DrawEditor(new Rect(((Rect)(ref val2)).x, num9 + 6f, ((Rect)(ref val2)).width, 178f), plugin, servers); } if (flag) { GUI.EndScrollView(); } DrawFooter(rect2, plugin, servers); if (num4 > 0f) { DrawMessage(new Rect(((Rect)(ref val)).x, ((Rect)(ref rect2)).y - num4, ((Rect)(ref val)).width, num4)); } } private static float DrawHeader(Rect rect) { //IL_001a: 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_004f: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) GatewayTheme.DrawRect(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, 30f), GatewayTheme.HeaderBg); GatewayTheme.RichLabel(new Rect(((Rect)(ref rect)).x + 12f, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width - 24f, 30f), "<b><color=#FFD760>BIFROST GATEWAY</color></b>", 19, bold: true, (TextAnchor)3); GatewayTheme.Label(new Rect(((Rect)(ref rect)).x + 12f, ((Rect)(ref rect)).y + 28f, ((Rect)(ref rect)).width - 24f, 24f), "Click a realm, then pick your character. Passwords supplied for you.", 13, bold: false, (TextAnchor)3, GatewayTheme.MutedText); return ((Rect)(ref rect)).yMax; } private static void DrawRow(Rect rect, int index, GatewayServer server, ServerStatus status) { //IL_0007: 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_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003f: 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) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_0130: 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_0169: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: 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_0232: Unknown result type (might be due to invalid IL or missing references) //IL_0248: Unknown result type (might be due to invalid IL or missing references) //IL_0241: Unknown result type (might be due to invalid IL or missing references) //IL_0252: Unknown result type (might be due to invalid IL or missing references) bool flag = ((Rect)(ref rect)).Contains(Event.current.mousePosition) && !s_editing; GatewayTheme.DrawRect(rect, flag ? GatewayTheme.CardBgHover : GatewayTheme.CardBg); GatewayTheme.DrawBorder(rect, flag ? GatewayTheme.CardBorderHover : GatewayTheme.CardBorder, 1f); if (s_editing && s_editIndex == index) { GatewayTheme.DrawRect(new Rect(((Rect)(ref rect)).x + 1f, ((Rect)(ref rect)).y + 1f, 3f, ((Rect)(ref rect)).height - 2f), GatewayTheme.WindowBorder); } float num = ((Rect)(ref rect)).x + 12f + 4f; float num2 = 92f; float num3 = (s_editing ? 0f : 26f); float num4 = ((Rect)(ref rect)).width - num2 - num3 - 24f - 4f; GatewayTheme.RichLabel(richText: "<color=#EAF2FA>" + Escape(server.DisplayName) + "</color>", rect: new Rect(num, ((Rect)(ref rect)).y + 4f, num4, 20f), fontSize: 16, bold: true, anchor: (TextAnchor)3); GatewayTheme.Label(new Rect(num, ((Rect)(ref rect)).y + 22f, num4, 18f), server.Endpoint, 12, bold: false, (TextAnchor)3, GatewayTheme.MutedText); DrawCounts(new Rect(((Rect)(ref rect)).xMax - num2 - num3, ((Rect)(ref rect)).y, num2 - 12f, ((Rect)(ref rect)).height), server, status); Rect val = default(Rect); ((Rect)(ref val))..ctor(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width - num3, ((Rect)(ref rect)).height); if (!s_editing && GUI.Button(val, GUIContent.none, GUIStyle.none)) { s_message = null; GatewayJoin.Connect(server, Say); } if (!s_editing) { Rect val2 = default(Rect); ((Rect)(ref val2))..ctor(((Rect)(ref rect)).xMax - 26f - 2f, ((Rect)(ref rect)).y + 8f, 26f, ((Rect)(ref rect)).height - 16f); bool flag2 = ((Rect)(ref val2)).Contains(Event.current.mousePosition); GatewayTheme.Label(val2, "✎", 16, bold: false, (TextAnchor)4, flag2 ? GatewayTheme.GoldText : GatewayTheme.MutedText); if (GUI.Button(val2, GUIContent.none, GUIStyle.none)) { s_draft = server.Copy(); s_portText = s_draft.Port.ToString(); s_portDirty = false; s_editIndex = index; s_editing = true; s_message = null; } } } private static void DrawCounts(Rect rect, GatewayServer server, ServerStatus status) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: 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_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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_0132: Unknown result type (might be due to invalid IL or missing references) //IL_013c: 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_0111: Unknown result type (might be due to invalid IL or missing references) //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_0177: Unknown result type (might be due to invalid IL or missing references) //IL_0190: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01dd: Unknown result type (might be due to invalid IL or missing references) string text; Color color; if (!status.Probed) { text = ((status.Detail == null) ? "unknown" : status.Detail); color = GatewayTheme.MutedText; } else if (!status.Online) { text = "offline"; color = GatewayTheme.RedText; } else if (status.Limit != 0 && status.Players >= status.Limit) { text = status.Players + "/" + status.Limit + " full"; color = GatewayTheme.RedText; } else if (status.Limit != 0 && status.Players != 0) { text = status.Players + "/" + status.Limit; color = GatewayTheme.GreenText; } else { text = ((status.Limit != 0) ? ("0/" + status.Limit) : "online"); color = GatewayTheme.CyanText; } if (!string.IsNullOrEmpty(server.Password)) { text = "● " + text; color = GatewayTheme.GoldText; } GatewayTheme.Label(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + 6f, ((Rect)(ref rect)).width, 18f), text, 14, bold: false, (TextAnchor)5, color); if (status.VersionMismatch && !string.IsNullOrEmpty(status.Version)) { GatewayTheme.Label(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + 23f, ((Rect)(ref rect)).width, 16f), "⚠ v" + status.Version, 11, bold: true, (TextAnchor)5, GatewayTheme.RedText); } else if (!GatewayJoin.CanSupplyPassword && !string.IsNullOrEmpty(server.Password)) { GatewayTheme.Label(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y + 23f, ((Rect)(ref rect)).width, 16f), "password unsupported", 11, bold: false, (TextAnchor)5, GatewayTheme.RedText); } } private static void DrawEditor(Rect rect, BifrostGatewayPlugin plugin, List<GatewayServer> servers) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_01aa: Unknown result type (might be due to invalid IL or missing references) //IL_01b8: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022f: Unknown result type (might be due to invalid IL or missing references) //IL_0263: Unknown result type (might be due to invalid IL or missing references) //IL_026e: Unknown result type (might be due to invalid IL or missing references) //IL_02bb: Unknown result type (might be due to invalid IL or missing references) //IL_02c6: Unknown result type (might be due to invalid IL or missing references) GatewayTheme.DrawRect(rect, GatewayTheme.HeaderBg); GatewayTheme.DrawBorder(rect, GatewayTheme.WindowBorder, 1f); float num = ((Rect)(ref rect)).y + 8f; float num2 = 74f; float num3 = ((Rect)(ref rect)).x + num2 + 8f; float num4 = ((Rect)(ref rect)).width - num2 - 16f; GatewayTheme.Label(new Rect(((Rect)(ref rect)).x + 8f, num, num2, 20f), "Name", 13, bold: false, (TextAnchor)3, GatewayTheme.MutedText); s_draft.Name = GatewayTheme.TextField(new Rect(num3, num, num4, 22f), s_draft.Name, 14); num += 26f; GatewayTheme.Label(new Rect(((Rect)(ref rect)).x + 8f, num, num2, 20f), "Address", 13, bold: false, (TextAnchor)3, GatewayTheme.MutedText); s_draft.Address = GatewayTheme.TextField(new Rect(num3, num, num4, 22f), s_draft.Address, 14); num += 26f; GatewayTheme.Label(new Rect(((Rect)(ref rect)).x + 8f, num, num2, 20f), "Port", 13, bold: false, (TextAnchor)3, GatewayTheme.MutedText); string text = GatewayTheme.TextField(new Rect(num3, num, 80f, 22f), s_portText, 14); if (text != s_portText) { s_portText = text; s_portDirty = true; } if (!s_portDirty && int.TryParse(s_portText, out var result)) { s_draft.Port = result; } num += 26f; GatewayTheme.Label(new Rect(((Rect)(ref rect)).x + 8f, num, num2, 20f), "Password", 13, bold: false, (TextAnchor)3, GatewayTheme.MutedText); s_draft.Password = GatewayTheme.TextField(new Rect(num3, num, num4, 22f), s_draft.Password, 14); float num5 = ((Rect)(ref rect)).yMax - 32f; float num6 = (((Rect)(ref rect)).width - 20f) / 3f; if (GatewayTheme.Button(new Rect(((Rect)(ref rect)).x + 8f, num5, num6, 24f), "Save", enabled: true, GatewayTheme.GoldText, 14)) { Save(plugin, servers); } if (GatewayTheme.Button(new Rect(((Rect)(ref rect)).x + 8f + num6 + 4f, num5, num6, 24f), "Cancel", enabled: true, GatewayTheme.MutedText, 14)) { CloseEditor(); } if (s_editIndex >= 0 && s_editIndex < servers.Count && GatewayTheme.Button(new Rect(((Rect)(ref rect)).x + 8f + (num6 + 4f) * 2f, num5, num6, 24f), "Delete", enabled: true, GatewayTheme.RedText, 14)) { Remove(plugin, servers, s_editIndex); } } private static void DrawFooter(Rect rect, BifrostGatewayPlugin plugin, List<GatewayServer> servers) { //IL_0032: 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_0093: 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_00ca: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_0159: Unknown result type (might be due to invalid IL or missing references) float num = 8f; float num2 = (((Rect)(ref rect)).width - num * 3f) / 4f; float y = ((Rect)(ref rect)).y; if (GatewayTheme.Button(new Rect(((Rect)(ref rect)).x, y, num2, 28f), "Add server", enabled: true, GatewayTheme.GoldText, 14)) { s_draft = new GatewayServer(); s_portText = s_draft.Port.ToString(); s_portDirty = false; s_editIndex = -1; s_editing = true; s_message = null; } if (GatewayTheme.Button(new Rect(((Rect)(ref rect)).x + (num2 + num), y, num2, 28f), "Refresh", enabled: true, GatewayTheme.CyanText, 14)) { ForceRefresh(servers); } if (GatewayTheme.Button(new Rect(((Rect)(ref rect)).x + (num2 + num) * 2f, y, num2, 28f), "Edit first", enabled: true, GatewayTheme.WhiteText, 14)) { if (servers.Count > 0) { s_draft = servers[0].Copy(); s_portText = s_draft.Port.ToString(); s_portDirty = false; s_editIndex = 0; s_editing = true; s_message = null; } else { Say("Nothing to edit yet.", isError: true); } } if (GatewayTheme.Button(new Rect(((Rect)(ref rect)).x + (num2 + num) * 3f, y, num2, 28f), "Close editor", enabled: true, GatewayTheme.MutedText, 14)) { CloseEditor(); } } private static void DrawMessage(Rect rect) { //IL_000d: 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_001e: Unknown result type (might be due to invalid IL or missing references) if (!string.IsNullOrEmpty(s_message)) { GatewayTheme.Label(rect, s_message, 13, bold: false, (TextAnchor)3, s_messageIsError ? GatewayTheme.RedText : GatewayTheme.GreenText); } } private static void Save(BifrostGatewayPlugin plugin, List<GatewayServer> servers) { if (int.TryParse(s_portText, out var result)) { s_draft.Port = result; } if (!s_draft.IsUsable(out var problem)) { Say(problem, isError: true); return; } if (s_editIndex >= 0 && s_editIndex < servers.Count) { servers[s_editIndex] = s_draft.Copy(); Say("Saved " + s_draft.DisplayName + ".", isError: false); } else { servers.Add(s_draft.Copy()); Say("Added " + s_draft.DisplayName + ".", isError: false); } if (!GatewayStore.Save(servers, out problem)) { Say("Added, but could not write bifrost_config.json: " + problem, isError: true); return; } CloseEditor(); ForceRefresh(servers); } private static void Remove(BifrostGatewayPlugin plugin, List<GatewayServer> servers, int index) { if (index >= 0 && index < servers.Count) { string displayName = servers[index].DisplayName; servers.RemoveAt(index); if (!GatewayStore.Save(servers, out var error)) { Say("Removed, but could not write bifrost_config.json: " + error, isError: true); } else { Say("Removed " + displayName + ".", isError: false); } CloseEditor(); ForceRefresh(servers); } } private static void CloseEditor() { s_editing = false; s_editIndex = -1; s_draft = null; s_portText = "2480"; s_portDirty = false; } internal static void Say(string message, bool isError) { s_message = message; s_messageIsError = isError; if (isError) { BifrostGatewayPlugin.Log.LogWarning((object)("Bifrost Gateway: " + message)); } else { BifrostGatewayPlugin.Log.LogInfo((object)("Bifrost Gateway: " + message)); } } private static void RefreshIfDue(List<GatewayServer> servers, BifrostGatewayPlugin plugin) { if (servers.Count != s_probedCount) { s_probedCount = servers.Count; s_nextProbeUtc = DateTime.MinValue; } if (!(DateTime.UtcNow < s_nextProbeUtc)) { s_nextProbeUtc = DateTime.UtcNow.AddSeconds(Mathf.Max(5f, plugin.Settings.RefreshSeconds.Value)); Statuses.Clear(); for (int i = 0; i < servers.Count; i++) { Statuses.Add(ServerProbe.Probe(servers[i])); } if (!s_loggedGate) { s_loggedGate = true; BifrostGatewayPlugin.Log.LogInfo((object)("Gateway panel shown on the main menu with " + servers.Count + " server(s). Automatic passwords: " + (GatewayJoin.CanSupplyPassword ? "available" : "UNAVAILABLE") + ".")); } } } private static void ForceRefresh(List<GatewayServer> servers) { s_nextProbeUtc = DateTime.MinValue; s_probedCount = -1; BifrostGatewayPlugin instance = BifrostGatewayPlugin.Instance; if (!((Object)(object)instance == (Object)null)) { RefreshIfDue(servers, instance); } } private static string Escape(string value) { return (value ?? "").Replace("<", "<").Replace(">", ">"); } } internal sealed class GatewayServer { public string Name = ""; public string Address = ""; public int Port = 2480; public string Password = ""; internal int SafePort { get { if (Port >= 1 && Port <= 65535) { return Port; } return 2480; } } internal string Endpoint => (Address ?? "").Trim() + ":" + SafePort; internal string DisplayName { get { if (!string.IsNullOrWhiteSpace(Name)) { return Name; } return Endpoint; } } internal bool IsUsable(out string problem) { if (string.IsNullOrWhiteSpace(Address)) { problem = "Address is required."; return false; } if (Port < 1 || Port > 65535) { problem = "Port must be between 1 and 65535."; return false; } problem = null; return true; } internal GatewayServer Copy() { return new GatewayServer { Name = (Name ?? ""), Address = (Address ?? ""), Port = Port, Password = (Password ?? "") }; } } internal sealed class GatewayFile { public List<GatewayServer> Servers = new List<GatewayServer>(); } internal static class GatewayStore { internal const string FileName = "bifrost_config.json"; internal static string FilePath => Path.Combine(Paths.PluginPath, "BifrostGateway", "bifrost_config.json"); internal static List<GatewayServer> Load(out string warning) { warning = null; try { string filePath = FilePath; if (!File.Exists(filePath)) { return new List<GatewayServer>(); } GatewayFile gatewayFile = JsonConvert.DeserializeObject<GatewayFile>(File.ReadAllText(filePath)); List<GatewayServer> list = new List<GatewayServer>(); if (gatewayFile?.Servers != null) { foreach (GatewayServer server in gatewayFile.Servers) { if (server != null && server.IsUsable(out var _)) { list.Add(server); } } } return list; } catch (Exception ex) when (ex is IOException || ex is JsonException || ex is UnauthorizedAccessException) { warning = "Could not read bifrost_config.json: " + ex.Message; return new List<GatewayServer>(); } } internal static bool Save(List<GatewayServer> servers, out string error) { error = null; try { string filePath = FilePath; string directoryName = Path.GetDirectoryName(filePath); if (!string.IsNullOrEmpty(directoryName)) { Directory.CreateDirectory(directoryName); } GatewayFile gatewayFile = new GatewayFile { Servers = (servers ?? new List<GatewayServer>()) }; string text = filePath + ".tmp"; File.WriteAllText(text, JsonConvert.SerializeObject((object)gatewayFile, (Formatting)1)); if (File.Exists(filePath)) { File.Delete(filePath); } File.Move(text, filePath); return true; } catch (Exception ex) when (ex is IOException || ex is UnauthorizedAccessException) { error = ex.Message; return false; } } } internal static class GatewayTheme { internal static readonly Color Backdrop = new Color(0f, 0f, 0f, 0.76f); internal static readonly Color WindowBg = new Color(0.08f, 0.1f, 0.14f, 0.98f); internal static readonly Color WindowBorder = new Color(0.74f, 0.58f, 0.28f, 1f); internal static readonly Color WindowBorderInner = new Color(0.18f, 0.23f, 0.32f, 0.85f); internal static readonly Color CardBg = new Color(0.09f, 0.11f, 0.16f, 0.96f); internal static readonly Color CardBgHover = new Color(0.14f, 0.17f, 0.24f, 0.98f); internal static readonly Color CardBorder = new Color(0.22f, 0.28f, 0.38f, 0.85f); internal static readonly Color CardBorderHover = new Color(0.74f, 0.58f, 0.28f, 1f); internal static readonly Color HeaderBg = new Color(0.12f, 0.16f, 0.22f, 1f); internal static readonly Color FieldBg = new Color(0.05f, 0.06f, 0.09f, 0.95f); internal static readonly Color GoldText = new Color(1f, 0.84f, 0.38f, 1f); internal static readonly Color WhiteText = new Color(0.92f, 0.95f, 0.98f, 1f); internal static readonly Color MutedText = new Color(0.6f, 0.66f, 0.75f, 1f); internal static readonly Color CyanText = new Color(0.4f, 0.8f, 1f, 1f); internal static readonly Color GreenText = new Color(0.38f, 0.88f, 0.48f, 1f); internal static readonly Color AmberText = new Color(0.95f, 0.7f, 0.28f, 1f); internal static readonly Color RedText = new Color(0.95f, 0.38f, 0.38f, 1f); private static readonly Dictionary<string, GUIStyle> TextStyles = new Dictionary<string, GUIStyle>(); private static readonly Dictionary<string, GUIStyle> FieldStyles = new Dictionary<string, GUIStyle>(); private static Texture2D s_white; internal static Texture2D White { get { //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_0021: 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_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0043: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)s_white == (Object)null) { s_white = new Texture2D(1, 1, (TextureFormat)4, false) { name = "BifrostGateway.White", hideFlags = (HideFlags)61, filterMode = (FilterMode)0, wrapMode = (TextureWrapMode)1 }; s_white.SetPixel(0, 0, Color.white); s_white.Apply(); } return s_white; } } internal static void DrawRect(Rect rect, Color color) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (!(((Rect)(ref rect)).width <= 0f) && !(((Rect)(ref rect)).height <= 0f)) { Color color2 = GUI.color; GUI.color = color; GUI.DrawTexture(rect, (Texture)(object)White); GUI.color = color2; } } internal static void DrawBorder(Rect rect, Color color, float thickness) { //IL_003b: 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_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) if (!(((Rect)(ref rect)).width <= 0f) && !(((Rect)(ref rect)).height <= 0f) && !(thickness <= 0f)) { DrawRect(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, ((Rect)(ref rect)).width, thickness), color); DrawRect(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).yMax - thickness, ((Rect)(ref rect)).width, thickness), color); DrawRect(new Rect(((Rect)(ref rect)).x, ((Rect)(ref rect)).y, thickness, ((Rect)(ref rect)).height), color); DrawRect(new Rect(((Rect)(ref rect)).xMax - thickness, ((Rect)(ref rect)).y, thickness, ((Rect)(ref rect)).height), color); } } internal static void DrawFrame(Rect rect) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) DrawRect(rect, WindowBg); DrawBorder(rect, WindowBorder, 2f); DrawBorder(new Rect(((Rect)(ref rect)).x + 4f, ((Rect)(ref rect)).y + 4f, ((Rect)(ref rect)).width - 8f, ((Rect)(ref rect)).height - 8f), WindowBorderInner, 1f); } internal static bool Button(Rect rect, string label, bool enabled, Color textColor, int fontSize = 15) { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_0058: 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) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0073: 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_0084: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: 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_00ee: 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) if (!enabled) { DrawRect(rect, new Color(CardBg.r, CardBg.g, CardBg.b, 0.5f)); DrawBorder(rect, new Color(CardBorder.r, CardBorder.g, CardBorder.b, 0.4f), 1f); Label(rect, label, fontSize, bold: true, (TextAnchor)4, new Color(textColor.r, textColor.g, textColor.b, 0.4f)); return false; } bool flag = ((Rect)(ref rect)).Contains(Event.current.mousePosition); DrawRect(rect, flag ? CardBgHover : CardBg); DrawBorder(rect, flag ? CardBorderHover : CardBorder, 1f); bool num = GUI.Button(rect, GUIContent.none, GUIStyle.none); if (num) { Event.current.Use(); } GUI.Label(rect, label, Text(fontSize, bold: true, (TextAnchor)4, textColor)); return num; } internal static void Label(Rect rect, string text, int fontSize, bool bold, TextAnchor anchor, Color color) { //IL_0000: 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) //IL_000f: Unknown result type (might be due to invalid IL or missing references) GUI.Label(rect, text ?? "", Text(fontSize, bold, anchor, color)); } internal static void RichLabel(Rect rect, string richText, int fontSize, bool bold, TextAnchor anchor) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0004: 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) GUI.Label(rect, richText, Text(fontSize, bold, anchor, Color.white)); } internal static string TextField(Rect rect, string value, int fontSize) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0010: 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) Color color = GUI.color; GUI.color = Color.white; string result = GUI.TextField(rect, value ?? "", Field(fontSize)); GUI.color = color; return result; } private unsafe static GUIStyle Text(int fontSize, bool bold, TextAnchor anchor, Color color) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0074: 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_0080: 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_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0094: 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_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00aa: Expected O, but got Unknown //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) //IL_00d4: 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_00ec: Unknown result type (might be due to invalid IL or missing references) string key = fontSize + "|" + (bold ? "b" : "n") + "|" + ((object)(*(TextAnchor*)(&anchor))/*cast due to .constrained prefix*/).ToString() + "|" + Hex(color); if (TextStyles.TryGetValue(key, out var value)) { return value; } value = new GUIStyle(GUI.skin.label) { fontSize = fontSize, fontStyle = (FontStyle)(bold ? 1 : 0), alignment = anchor, richText = true, wordWrap = false, clipping = (TextClipping)1 }; value.normal.textColor = color; value.hover.textColor = color; value.active.textColor = color; value.onNormal.textColor = color; value.onHover.textColor = color; value.onActive.textColor = color; TextStyles[key] = value; return value; } private static GUIStyle Field(int fontSize) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown string key = fontSize.ToString(); if (FieldStyles.TryGetValue(key, out var value)) { return value; } value = new GUIStyle(GUI.skin.textField) { fontSize = fontSize, alignment = (TextAnchor)3, richText = false }; FieldStyles[key] = value; return value; } internal static string Hex(Color color) { //IL_0000: 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_003a: Unknown result type (might be due to invalid IL or missing references) int num = Mathf.Clamp(Mathf.RoundToInt(color.r * 255f), 0, 255); int num2 = Mathf.Clamp(Mathf.RoundToInt(color.g * 255f), 0, 255); int num3 = Mathf.Clamp(Mathf.RoundToInt(color.b * 255f), 0, 255); return num.ToString("X2") + num2.ToString("X2") + num3.ToString("X2"); } } internal struct ServerStatus { internal bool Probed; internal bool Online; internal uint Players; internal uint Limit; internal bool PasswordProtected; internal string ServerName; internal string Version; internal bool VersionMismatch; internal string Detail; } internal static class ServerProbe { internal unsafe static ServerStatus Probe(GatewayServer server) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0078: 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_0097: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_00de: 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_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0106: Unknown result type (might be due to invalid IL or missing references) //IL_010b: 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_0118: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_0131: 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_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014a: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) ServerStatus result = default(ServerStatus); if (server == null) { result.Detail = "no server"; return result; } if (!server.IsUsable(out var problem)) { result.Detail = problem; return result; } if ((Object)(object)MultiBackendMatchmaking.Instance == (Object)null) { result.Detail = "matchmaking not ready"; return result; } try { ServerJoinData val = JoinFactory.Dedicated(server.Address, server.SafePort); if (!((ServerJoinData)(ref val)).IsValid) { result.Detail = "address not accepted"; return result; } ServerMatchmakingData serverMatchmakingData = MultiBackendMatchmaking.GetServerMatchmakingData(val, DateTime.MinValue); result.Probed = true; result.Online = ((ServerMatchmakingData)(ref serverMatchmakingData)).IsValid && OnlineStatusExtentions.IsOnline(serverMatchmakingData.m_onlineStatus); result.Players = serverMatchmakingData.m_playerCount; result.Limit = serverMatchmakingData.m_playerLimit; result.PasswordProtected = serverMatchmakingData.m_isPasswordProtected; result.ServerName = serverMatchmakingData.m_serverName; GameVersion gameVersion = serverMatchmakingData.m_gameVersion; result.Version = (((object)gameVersion == null) ? null : ((object)(*(GameVersion*)(&gameVersion))/*cast due to .constrained prefix*/).ToString()); GameVersion currentVersion = Version.CurrentVersion; result.VersionMismatch = (object)gameVersion != null && (object)currentVersion != null && ((GameVersion)(ref gameVersion)).IsValid() && (gameVersion.m_major != currentVersion.m_major || gameVersion.m_minor != currentVersion.m_minor || gameVersion.m_patch != currentVersion.m_patch); if (((ServerMatchmakingData)(ref serverMatchmakingData)).IsValid && !result.Online) { result.Detail = "offline"; } return result; } catch (Exception ex) { result.Probed = false; result.Detail = ex.Message; return result; } } } }