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 LobbyCompatibility v1.5.1
BepInEx/plugins/LobbyCompatibility/BMX.LobbyCompatibility.dll
Decompiled 11 months ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Cryptography; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using LobbyCompatibility.Attributes; using LobbyCompatibility.Behaviours; using LobbyCompatibility.Configuration; using LobbyCompatibility.Enums; using LobbyCompatibility.Features; using LobbyCompatibility.Models; using LobbyCompatibility.Pooling; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using Newtonsoft.Json.Converters; using Steamworks; using Steamworks.Data; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Pool; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: IgnoresAccessChecksTo("AmazingAssets.TerrainToMesh")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp-firstpass")] [assembly: IgnoresAccessChecksTo("Assembly-CSharp")] [assembly: IgnoresAccessChecksTo("ClientNetworkTransform")] [assembly: IgnoresAccessChecksTo("DissonanceVoip")] [assembly: IgnoresAccessChecksTo("Facepunch Transport for Netcode for GameObjects")] [assembly: IgnoresAccessChecksTo("Facepunch.Steamworks.Win64")] [assembly: IgnoresAccessChecksTo("Unity.AI.Navigation")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging")] [assembly: IgnoresAccessChecksTo("Unity.Animation.Rigging.DocCodeExamples")] [assembly: IgnoresAccessChecksTo("Unity.Burst")] [assembly: IgnoresAccessChecksTo("Unity.Burst.Unsafe")] [assembly: IgnoresAccessChecksTo("Unity.Collections")] [assembly: IgnoresAccessChecksTo("Unity.Collections.LowLevel.ILSupport")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem")] [assembly: IgnoresAccessChecksTo("Unity.InputSystem.ForUI")] [assembly: IgnoresAccessChecksTo("Unity.Jobs")] [assembly: IgnoresAccessChecksTo("Unity.Mathematics")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.Common")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.MetricTypes")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStats")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Component")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsMonitor.Implementation")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetStatsReporting")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkProfiler.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Multiplayer.Tools.NetworkSolutionInterface")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Components")] [assembly: IgnoresAccessChecksTo("Unity.Netcode.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.Networking.Transport")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Csg")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.KdTree")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Poly2Tri")] [assembly: IgnoresAccessChecksTo("Unity.ProBuilder.Stl")] [assembly: IgnoresAccessChecksTo("Unity.Profiling.Core")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.Core.ShaderLibrary")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Config.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.HighDefinition.Runtime")] [assembly: IgnoresAccessChecksTo("Unity.RenderPipelines.ShaderGraph.ShaderGraphLibrary")] [assembly: IgnoresAccessChecksTo("Unity.Services.Authentication")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Analytics")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Configuration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Device")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Environments.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Internal")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Networking")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Registration")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Scheduler")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Telemetry")] [assembly: IgnoresAccessChecksTo("Unity.Services.Core.Threading")] [assembly: IgnoresAccessChecksTo("Unity.Services.QoS")] [assembly: IgnoresAccessChecksTo("Unity.Services.Relay")] [assembly: IgnoresAccessChecksTo("Unity.TextMeshPro")] [assembly: IgnoresAccessChecksTo("Unity.Timeline")] [assembly: IgnoresAccessChecksTo("Unity.VisualEffectGraph.Runtime")] [assembly: IgnoresAccessChecksTo("UnityEngine.ARModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.NVIDIAModule")] [assembly: IgnoresAccessChecksTo("UnityEngine.UI")] [assembly: AssemblyCompany("MaxWasUnavailable;legoandmars;xilophor")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyDescription("Towards a future with fewer lobby incompatibility errors.")] [assembly: AssemblyFileVersion("1.5.1.0")] [assembly: AssemblyInformationalVersion("1.5.1+0db7c2daf4648d202bd7e77a9f94672d67ffce05")] [assembly: AssemblyProduct("LobbyCompatibility")] [assembly: AssemblyTitle("BMX.LobbyCompatibility")] [assembly: AssemblyMetadata("RepositoryUrl", "https://github.com/MaxWasUnavailable/LobbyCompatibility")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace LobbyCompatibility { [LobbyCompatibility(CompatibilityLevel.ClientOnly, VersionStrictness.Minor)] [BepInPlugin("BMX.LobbyCompatibility", "LobbyCompatibility", "1.5.1")] public class LobbyCompatibilityPlugin : BaseUnityPlugin { private bool _isPatched; private Harmony? Harmony { get; set; } internal static ManualLogSource? Logger { get; private set; } public static LobbyCompatibilityPlugin? Instance { get; private set; } public static Config? Config { get; private set; } private void Awake() { Instance = this; Logger = ((BaseUnityPlugin)this).Logger; Config = new Config(((BaseUnityPlugin)this).Config); PatchAll(); Logger.LogInfo((object)"Plugin BMX.LobbyCompatibility is loaded!"); } public void PatchAll() { //IL_0040: 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_0047: Expected O, but got Unknown //IL_004c: Expected O, but got Unknown if (_isPatched) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogWarning((object)"Already patched!"); } return; } ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogDebug((object)"Patching..."); } if (Harmony == null) { Harmony val = new Harmony("BMX.LobbyCompatibility"); Harmony val2 = val; Harmony = val; } Harmony.PatchAll(); _isPatched = true; ManualLogSource? logger3 = Logger; if (logger3 != null) { logger3.LogDebug((object)"Patched!"); } } public void UnpatchAll() { if (!_isPatched) { ManualLogSource? logger = Logger; if (logger != null) { logger.LogWarning((object)"Already unpatched!"); } return; } ManualLogSource? logger2 = Logger; if (logger2 != null) { logger2.LogDebug((object)"Unpatching..."); } Harmony.UnpatchSelf(); _isPatched = false; ManualLogSource? logger3 = Logger; if (logger3 != null) { logger3.LogDebug((object)"Unpatched!"); } } } public static class PluginInfo { public const string PLUGIN_GUID = "BMX.LobbyCompatibility"; public const string PLUGIN_NAME = "LobbyCompatibility"; public const string PLUGIN_VERSION = "1.5.1"; } } namespace LobbyCompatibility.Pooling { internal class PluginCategorySlotPool : MonoBehaviour { private PluginCategorySlot? _template; private Transform? _container; private IObjectPool<PluginCategorySlot>? _pool; public void InitializeUsingTemplate(PluginCategorySlot template, Transform container) { _container = container; _template = template; _pool = (IObjectPool<PluginCategorySlot>?)(object)new ObjectPool<PluginCategorySlot>((Func<PluginCategorySlot>)CreatePooledItem, (Action<PluginCategorySlot>)OnTakeFromPool, (Action<PluginCategorySlot>)OnReturnedToPool, (Action<PluginCategorySlot>)OnDestroyPoolObject, false, 10, 10000); } public PluginCategorySlot? Spawn(PluginDiffResult pluginDiffResult) { PluginCategorySlot pluginCategorySlot = SpawnInternal(); pluginCategorySlot?.SetPluginDiffResult(pluginDiffResult); return pluginCategorySlot; } public void Release(PluginCategorySlot pluginCategorySlot) { if (!((Object)(object)pluginCategorySlot == (Object)null) && _pool != null) { _pool.Release(pluginCategorySlot); } } private PluginCategorySlot? SpawnInternal() { if ((Object)(object)_template == (Object)null || (Object)(object)_container == (Object)null || _pool == null) { ManualLogSource? logger = LobbyCompatibilityPlugin.Logger; if (logger != null) { logger.LogInfo((object)"PluginCategorySlotPool tried to spawn an item, but was not initialized properly."); } return null; } return _pool.Get(); } private PluginCategorySlot CreatePooledItem() { if ((Object)(object)_template == (Object)null || (Object)(object)_container == (Object)null) { throw new NullReferenceException("Template is missing! Did it get destroyed?"); } PluginCategorySlot pluginCategorySlot = Object.Instantiate<PluginCategorySlot>(_template, _container); ((Component)pluginCategorySlot).gameObject.SetActive(true); return pluginCategorySlot; } private void OnTakeFromPool(PluginCategorySlot pluginCategorySlot) { ((Component)pluginCategorySlot).gameObject.SetActive(true); ((Component)pluginCategorySlot).transform.SetAsLastSibling(); } private void OnReturnedToPool(PluginCategorySlot pluginCategorySlot) { ((Component)pluginCategorySlot).gameObject.SetActive(false); } private void OnDestroyPoolObject(PluginCategorySlot pluginCategorySlot) { Object.Destroy((Object)(object)((Component)pluginCategorySlot).gameObject); } } internal class PluginDiffSlotPool : MonoBehaviour { private PluginDiffSlot? _template; private Transform? _container; private IObjectPool<PluginDiffSlot>? _pool; public void InitializeUsingTemplate(PluginDiffSlot template, Transform container) { _container = container; _template = template; _pool = (IObjectPool<PluginDiffSlot>?)(object)new ObjectPool<PluginDiffSlot>((Func<PluginDiffSlot>)CreatePooledItem, (Action<PluginDiffSlot>)OnTakeFromPool, (Action<PluginDiffSlot>)OnReturnedToPool, (Action<PluginDiffSlot>)OnDestroyPoolObject, false, 20, 10000); } public PluginDiffSlot? Spawn(PluginDiff pluginDiff, bool lobbyCompatibilityPresent) { PluginDiffSlot pluginDiffSlot = SpawnInternal(); pluginDiffSlot?.SetPluginDiff(pluginDiff, lobbyCompatibilityPresent); return pluginDiffSlot; } public PluginDiffSlot? Spawn(string pluginNameText, string clientVersionText, string serverVersionText, Color color) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) PluginDiffSlot pluginDiffSlot = SpawnInternal(); pluginDiffSlot?.SetText(pluginNameText, clientVersionText, serverVersionText, color); return pluginDiffSlot; } public void Release(PluginDiffSlot pluginDiffSlot) { if (!((Object)(object)pluginDiffSlot == (Object)null) && _pool != null) { _pool.Release(pluginDiffSlot); } } private PluginDiffSlot? SpawnInternal() { if ((Object)(object)_template == (Object)null || (Object)(object)_container == (Object)null || _pool == null) { ManualLogSource? logger = LobbyCompatibilityPlugin.Logger; if (logger != null) { logger.LogInfo((object)"PluginDiffSlotPool tried to spawn an item, but was not initialized properly."); } return null; } return _pool.Get(); } private PluginDiffSlot CreatePooledItem() { if ((Object)(object)_template == (Object)null || (Object)(object)_container == (Object)null) { throw new NullReferenceException("Template is missing! Did it get destroyed?"); } PluginDiffSlot pluginDiffSlot = Object.Instantiate<PluginDiffSlot>(_template, _container); ((Component)pluginDiffSlot).gameObject.SetActive(true); return pluginDiffSlot; } private void OnTakeFromPool(PluginDiffSlot pluginDiffSlot) { ((Component)pluginDiffSlot).gameObject.SetActive(true); ((Component)pluginDiffSlot).transform.SetAsLastSibling(); } private void OnReturnedToPool(PluginDiffSlot pluginDiffSlot) { ((Component)pluginDiffSlot).gameObject.SetActive(false); } private void OnDestroyPoolObject(PluginDiffSlot pluginDiffSlot) { Object.Destroy((Object)(object)((Component)pluginDiffSlot).gameObject); } } } namespace LobbyCompatibility.Patches { [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyPriority(0)] [HarmonyWrapSafe] internal class ES3SettingsConstructorPrefix { [HarmonyPrefix] private static void FileSettings(ref string path) { path = ((path == "LCChallengeFile") ? "LCModdedChallengeFile" : path); } } [HarmonyPatch(typeof(ISteamUserStats), "FindOrCreateLeaderboard")] [HarmonyPriority(0)] [HarmonyWrapSafe] internal class FindOrCreateLeaderboardPrefix { [HarmonyPrefix] private static void Prefix(ref string pchLeaderboardName) { pchLeaderboardName = (pchLeaderboardName.StartsWith("challenge") ? ("modded_" + pchLeaderboardName) : pchLeaderboardName); } } [HarmonyPatch] [HarmonyPriority(0)] [HarmonyWrapSafe] internal static class GetLeaderboardForChallengeTranspiler { [HarmonyTargetMethod] private static MethodBase? TargetMethod() { return AccessTools.Method(typeof(MenuManager), "GetLeaderboardForChallenge", (Type[])null, (Type[])null).GetCustomAttribute<AsyncStateMachineAttribute>().StateMachineType.GetMethod("MoveNext", BindingFlags.Instance | BindingFlags.NonPublic); } [HarmonyTranspiler] private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) return new CodeMatcher(instructions, (ILGenerator)null).SearchForward((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.OperandIs(instruction, (object)" Results"))).ThrowIfInvalid("Could not find leaderboard results text").SetOperandAndAdvance((object)" Results (Modded)") .InstructionEnumeration(); } } [HarmonyPatch] [HarmonyPriority(800)] [HarmonyWrapSafe] internal class LoadLobbyListAndFilterTranspiler { [HarmonyPatch(/*Could not decode attribute arguments.*/)] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0088: 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_00ac: Expected O, but got Unknown //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Expected O, but got Unknown //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Expected O, but got Unknown //IL_010a: Unknown result type (might be due to invalid IL or missing references) //IL_0110: Expected O, but got Unknown //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Expected O, but got Unknown //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown //IL_016e: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Expected O, but got Unknown //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0191: Expected O, but got Unknown //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Expected O, but got Unknown //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01cd: Expected O, but got Unknown //IL_01e6: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Expected O, but got Unknown //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Expected O, but got Unknown //IL_0202: Unknown result type (might be due to invalid IL or missing references) //IL_0208: Expected O, but got Unknown FieldInfo fieldInfo = AccessTools.Field(typeof(SteamLobbyManager), "currentLobbyList"); FieldInfo fieldInfo2 = AccessTools.Field(typeof(LobbySlot), "thisLobby"); FieldInfo fieldInfo3 = AccessTools.Field(typeof(SteamLobbyManager), "levelListContainer"); MethodInfo methodInfo = AccessTools.Method(typeof(LoadLobbyListAndFilterTranspiler), "InitializeLobbySlot", (Type[])null, (Type[])null); MethodInfo methodInfo2 = AccessTools.Method(typeof(Lobby), "GetData", (Type[])null, (Type[])null); MethodInfo methodInfo3 = AccessTools.Method(typeof(LoadLobbyListAndFilterTranspiler), "ReplaceLobbyName", (Type[])null, (Type[])null); return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[2] { new CodeMatch((OpCode?)OpCodes.Ldstr, (object)"name", (string)null), new CodeMatch((OpCode?)OpCodes.Call, (object)methodInfo2, (string)null) }).ThrowIfNotMatch("Unable to find Lobby.GetData(name) line.", Array.Empty<CodeMatch>()).Advance(2) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)methodInfo3) }) .MatchForward(false, (CodeMatch[])(object)new CodeMatch[6] { new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction inst) => inst.opcode == OpCodes.Ldfld), (string)null), new CodeMatch((OpCode?)OpCodes.Ldarg_0, (object)null, (string)null), new CodeMatch((Func<CodeInstruction, bool>)((CodeInstruction inst) => inst.opcode == OpCodes.Ldfld), (string)null), new CodeMatch((OpCode?)OpCodes.Ldelem, (object)typeof(Lobby), (string)null), new CodeMatch((OpCode?)OpCodes.Stfld, (object)fieldInfo2, (string)null) }) .ThrowIfNotMatch("Unable to find LobbySlot.thisLobby line.", Array.Empty<CodeMatch>()) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Dup, (object)null) }) .Advance(6) .InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[3] { new CodeInstruction(OpCodes.Ldloc_1, (object)null), new CodeInstruction(OpCodes.Ldfld, (object)fieldInfo3), new CodeInstruction(OpCodes.Call, (object)methodInfo) }) .InstructionEnumeration(); } private static void InitializeLobbySlot(LobbySlot lobbySlot, Transform levelListContainer) { ModdedLobbySlot moddedLobbySlot = ((Component)lobbySlot).gameObject.AddComponent<ModdedLobbySlot>(); moddedLobbySlot.Setup(lobbySlot); moddedLobbySlot.SetParentContainer(levelListContainer.parent); } private static string ReplaceLobbyName(string lobbyName) { if (lobbyName.Length == 0) { return lobbyName; } return lobbyName.Replace("[MOD]", ""); } } [HarmonyPatch] [HarmonyPriority(800)] [HarmonyWrapSafe] internal class LoadServerListTranspiler { [HarmonyTargetMethod] private static MethodBase? TargetMethod() { return HarmonyHelper.GetAsyncInfo(typeof(SteamLobbyManager), "LoadServerList"); } [HarmonyTranspiler] private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions, ILGenerator ilGenerator) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Expected O, but got Unknown //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Expected O, but got Unknown //IL_00e3: 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_00ea: Expected O, but got Unknown //IL_00eb: Expected O, but got Unknown //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown MethodInfo searchCoroutineMethod = AccessTools.Method(typeof(MonoBehaviour), "StartCoroutine", new Type[1] { typeof(IEnumerator) }, (Type[])null); MethodInfo methodInfo = AccessTools.Method(typeof(LoadServerListTranspiler), "LoadListPostfix", (Type[])null, (Type[])null); Label label = default(Label); CodeMatcher obj = new CodeMatcher(instructions, ilGenerator).SearchForward((Func<CodeInstruction, bool>)((CodeInstruction inst) => CodeInstructionExtensions.Calls(inst, searchCoroutineMethod))).ThrowIfInvalid("Unable to find StartCoroutine.").Advance(1) .SetInstruction(new CodeInstruction(OpCodes.Nop, (object)null)) .CreateLabel(ref label) .Advance(-7) .SetInstructionAndAdvance(new CodeInstruction(OpCodes.Br, (object)label)) .SearchForward((Func<CodeInstruction, bool>)((CodeInstruction inst) => inst.opcode == OpCodes.Leave)) .ThrowIfInvalid("Unable to find leave instruction."); CodeInstruction[] array = new CodeInstruction[2]; CodeInstruction val = new CodeInstruction(OpCodes.Ldloc_1, (object)null); CodeInstruction val2 = val; array[0] = val; array[1] = new CodeInstruction(OpCodes.Call, (object)methodInfo); CodeMatcher val3 = obj.InsertAndAdvance((CodeInstruction[])(object)array); CodeInstructionExtensions.MoveLabelsTo(val3.Instruction, val2); return val3.InstructionEnumeration(); } internal static async void LoadListPostfix(SteamLobbyManager steamLobbyManager) { LobbyQuery lobbyList = SteamMatchmaking.LobbyList; lobbyList.stringFilters = LobbyHelper.LatestLobbyRequestStringFilters; lobbyList.distance = LobbyHelper.LatestLobbyRequestDistanceFilter; bool flag = !lobbyList.stringFilters.ContainsKey("tag") || lobbyList.stringFilters["tag"] != "none"; ModdedLobbyFilter currentFilter = (((Object)(object)ModdedLobbyFilterDropdown.Instance != (Object)null) ? ModdedLobbyFilterDropdown.Instance.LobbyFilter : ModdedLobbyFilter.All); if (flag) { currentFilter = ModdedLobbyFilter.All; } Lobby[] filteredLobbies = null; if (currentFilter != ModdedLobbyFilter.VanillaAndUnknownOnly && !flag) { if (PluginHelper.Checksum != "" && (currentFilter == ModdedLobbyFilter.CompatibleFirst || currentFilter == ModdedLobbyFilter.CompatibleOnly)) { if (lobbyList.stringFilters.ContainsKey("checksum")) { lobbyList.stringFilters.Remove("checksum"); } else { ((LobbyQuery)(ref lobbyList)).WithKeyValue("checksum", PluginHelper.Checksum); } } if (lobbyList.stringFilters.ContainsKey("tag")) { lobbyList.stringFilters["tag"] = "modded"; } filteredLobbies = await ((LobbyQuery)(ref lobbyList)).RequestAsync(); } Lobby[] source = LobbyHelper.FilterLobbies((Lobby[])(((object)steamLobbyManager.currentLobbyList) ?? ((object)new Lobby[0])), filteredLobbies, currentFilter); steamLobbyManager.currentLobbyList = source.ToArray(); if (!source.Any()) { ((TMP_Text)steamLobbyManager.serverListBlankText).text = LobbyHelper.GetEmptyLobbyListString(currentFilter); } else { steamLobbyManager.loadLobbyListCoroutine = ((MonoBehaviour)steamLobbyManager).StartCoroutine(steamLobbyManager.loadLobbyListAndFilter(steamLobbyManager.currentLobbyList)); } } } [HarmonyPatch(typeof(GameNetworkManager), "LobbyDataIsJoinable")] [HarmonyPriority(0)] [HarmonyWrapSafe] internal static class LobbyDataIsJoinablePostfix { [HarmonyPostfix] private static bool Postfix(bool isJoinable, ref Lobby lobby) { //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) LobbyHelper.LatestLobbyData = ((Lobby)(ref lobby)).Data; if (!isJoinable) { return false; } if (((Lobby)(ref lobby)).GetData("modded") != "true" && !PluginHelper.CanJoinVanillaLobbies()) { Object.FindObjectOfType<MenuManager>().SetLoadingScreen(false, (RoomEnter)3, "You are using mods which aren't strictly client-side, but the lobby is not modded."); return PluginHelper.CanJoinVanillaLobbies() && isJoinable; } string text = GeneralExtensions.Join<char>((IEnumerable<char>)LobbyHelper.GetLobbyPlugins(lobby), (Func<char, string>)null, string.Empty); LobbyHelper.GetLobbyDiff(lobby, text); if (string.IsNullOrEmpty(text)) { ManualLogSource? logger = LobbyCompatibilityPlugin.Logger; if (logger != null) { logger.LogWarning((object)"Lobby is modded but does not have any plugin information."); } return isJoinable; } bool flag = PluginHelper.MatchesTargetRequirements(LobbyHelper.ParseLobbyPluginsMetadata(text)); if (!flag) { ManualLogSource? logger2 = LobbyCompatibilityPlugin.Logger; if (logger2 != null) { logger2.LogWarning((object)"You are missing required plugins to join this lobby."); } Object.FindObjectOfType<MenuManager>().SetLoadingScreen(false, (RoomEnter)5, "You are missing required mods to join this lobby."); } return flag; } } [HarmonyPatch(typeof(GameNetworkManager), "LobbyDataIsJoinable")] [HarmonyPriority(0)] [HarmonyWrapSafe] internal static class LobbyDataIsJoinableTranspiler { [HarmonyTranspiler] private static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { //IL_0002: 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_0064: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).SearchForward((Func<CodeInstruction, bool>)((CodeInstruction instruction) => CodeInstructionExtensions.OperandIs(instruction, (object)"joinable"))).ThrowIfInvalid("Could not find joinable").RemoveInstructions(4) .Insert((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(LobbyDataIsJoinableTranspiler), "IsJoinable", (Type[])null, (Type[])null)) }) .InstructionEnumeration(); } private static bool IsJoinable(ref Lobby lobby) { if (!(((Lobby)(ref lobby)).GetData("_joinable") == "true")) { return ((Lobby)(ref lobby)).GetData("joinable") == "true"; } return true; } } [HarmonyPatch(typeof(MenuManager), "Start")] [HarmonyPriority(0)] [HarmonyWrapSafe] internal static class MenuManagerPostfix { [HarmonyPrefix] private static void Prefix(MenuManager __instance) { //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown if (__instance.isInitScene) { return; } Transform val = __instance.serverListUIContainer.transform.Find("ListPanel"); Transform val2 = (((Object)(object)val != (Object)null) ? val.Find("Scroll View") : null); TextMeshProUGUI privatePublicDescription = __instance.privatePublicDescription; if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)privatePublicDescription == (Object)null)) { ManualLogSource? logger = LobbyCompatibilityPlugin.Logger; if (logger != null) { logger.LogInfo((object)"Initializing menu UI."); } Transform parent = __instance.menuNotification.transform.parent; GameObject val3 = Object.Instantiate<GameObject>(__instance.menuNotification, parent); val3.AddComponent<ModListTooltipPanel>(); val3.SetActive(true); GameObject panel = Object.Instantiate<GameObject>(__instance.menuNotification, parent); GameObject val4 = new GameObject("ModListPanel Handler"); val4.transform.SetParent(parent); ModListPanel modListPanel = val4.AddComponent<ModListPanel>(); modListPanel.SetupPanel(panel, val2, privatePublicDescription); } } [HarmonyPostfix] private static void Postfix(MenuManager __instance) { //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) if (__instance.isInitScene) { return; } Transform val = __instance.serverListUIContainer.transform.Find("ListPanel"); if (!((Object)(object)val == (Object)null)) { ((TMP_Text)__instance.leaderboardHeaderText).rectTransform.offsetMax = new Vector2(2000f, ((TMP_Text)__instance.leaderboardHeaderText).rectTransform.offsetMax.y); Transform obj = val.Find("RefreshButton"); Button val2 = ((obj != null) ? ((Component)obj).GetComponent<Button>() : null); if ((Object)(object)val2 != (Object)null) { UIHelper.ReskinRefreshButton(val2); } if (!Object.op_Implicit((Object)(object)GameNetworkManager.Instance) || !GameNetworkManager.Instance.disableSteam) { UIHelper.AddCustomFilterToLobbyList(val); } } } } [HarmonyPatch(typeof(LobbyQuery), "RequestAsync")] [HarmonyPriority(0)] [HarmonyWrapSafe] internal static class RequestAsyncPrefix { [HarmonyPrefix] private static void Prefix(LobbyQuery __instance) { //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_0002: 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) LobbyHelper.LatestLobbyRequestStringFilters = __instance.stringFilters ?? new Dictionary<string, string>(); LobbyHelper.LatestLobbyRequestDistanceFilter = __instance.distance; } } [HarmonyPatch(typeof(MenuManager), "SetLoadingScreen")] [HarmonyPriority(800)] [HarmonyWrapSafe] internal static class SetLoadingScreenPrefix { [HarmonyPrefix] private static bool Prefix(bool isLoading, RoomEnter result, MenuManager __instance) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if (isLoading) { return true; } if ((int)result != 5) { return true; } ManualLogSource? logger = LobbyCompatibilityPlugin.Logger; if (logger != null) { logger.LogDebug((object)GeneralExtensions.Join<KeyValuePair<string, string>>(LobbyHelper.LatestLobbyData, (Func<KeyValuePair<string, string>, string>)null, ", ")); } ManualLogSource? logger2 = LobbyCompatibilityPlugin.Logger; if (logger2 != null) { IEnumerable<PluginInfoRecord> allPluginInfo = PluginHelper.GetAllPluginInfo(); IEnumerable<KeyValuePair<string, string>> latestLobbyData = LobbyHelper.LatestLobbyData; logger2.LogDebug((object)GeneralExtensions.Join<PluginInfoRecord>((IEnumerable<PluginInfoRecord>)allPluginInfo.CalculateCompatibilityLevel(null, latestLobbyData), (Func<PluginInfoRecord, string>)null, ", ")); } if (!string.IsNullOrEmpty(GameNetworkManager.Instance.disconnectionReasonMessage)) { return true; } __instance.MenuAudio.volume = 0.5f; __instance.menuButtons.SetActive(true); __instance.loadingScreen.SetActive(false); __instance.serverListUIContainer.SetActive(false); if ((Object)(object)ModListPanel.Instance != (Object)null) { ModListPanel.Instance.DisplayNotification(LobbyHelper.LatestLobbyDiff, "Error while joining..."); } return false; } } [HarmonyPatch(typeof(MenuManager), "StartAClient")] [HarmonyPriority(0)] [HarmonyWrapSafe] internal static class StartAClientPostfix { [HarmonyPrefix] private static void Prefix() { LobbyHelper.GetLobbyDiff((Lobby?)null); } } [HarmonyPatch(typeof(GameNetworkManager), "SteamMatchmaking_OnLobbyCreated")] [HarmonyPriority(0)] [HarmonyWrapSafe] internal static class SteamMatchmakingOnLobbyCreatedPostfix { [HarmonyPostfix] private static void Postfix(Result result, ref Lobby lobby) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_000b: 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) if ((int)result != 1) { return; } List<PluginInfoRecord> list = PluginHelper.GetAllPluginInfo().CalculateCompatibilityLevel(lobby); ((Lobby)(ref lobby)).SetData("modded", "true"); string lobbyPluginsMetadata = LobbyHelper.GetLobbyPluginsMetadata(list); ((Lobby)(ref lobby)).SetData("plugins0", lobbyPluginsMetadata); ((Lobby)(ref lobby)).SetData("_joinable", ((Lobby)(ref lobby)).GetData("joinable")); ((Lobby)(ref lobby)).SetData("checksum", PluginHelper.Checksum); if (list.Any(delegate(PluginInfoRecord plugin) { CompatibilityLevel? compatibilityLevel = plugin.CompatibilityLevel; if (compatibilityLevel.HasValue) { CompatibilityLevel valueOrDefault = compatibilityLevel.GetValueOrDefault(); if ((uint)(valueOrDefault - 1) <= 2u) { return true; } } return false; }) && !LobbyHelper.LobbyNameContainsModIdentifier(lobby) && LobbyCompatibilityPlugin.Config.ChangeLobbyName.Value) { ((Lobby)(ref lobby)).SetData("name", "[MOD]" + ((Lobby)(ref lobby)).GetData("name")); } if (list.Any((PluginInfoRecord plugin) => plugin.CompatibilityLevel == CompatibilityLevel.Everyone)) { ManualLogSource? logger = LobbyCompatibilityPlugin.Logger; if (logger != null) { logger.LogWarning((object)"You are hosting a lobby with required plugins. Disabling vanilla clients from joining."); } ((Lobby)(ref lobby)).SetData("joinable", "false"); if (((Lobby)(ref lobby)).GetData("tag") == "none") { ((Lobby)(ref lobby)).SetData("tag", "modded"); } } ManualLogSource? logger2 = LobbyCompatibilityPlugin.Logger; if (logger2 != null) { logger2.LogDebug((object)GeneralExtensions.Join<KeyValuePair<string, string>>(((Lobby)(ref lobby)).Data, (Func<KeyValuePair<string, string>, string>)null, ", ")); } } } } namespace LobbyCompatibility.Models { public record LobbyDiff(List<PluginDiff> PluginDiffs, bool LobbyCompatibilityPresent = true) { private LobbyDiffResult? _cachedResult; public string GetDisplayText(bool shortened = false) { LobbyDiffResult moddedLobbyType = GetModdedLobbyType(); string text = ((moddedLobbyType != LobbyDiffResult.PresumedCompatible) ? moddedLobbyType.ToString() : (shortened ? "Compatible?" : "Presumed Compatible")); return "Mod Status: " + text; } internal LobbyDiffResult GetModdedLobbyType() { if (_cachedResult.HasValue) { return _cachedResult.Value; } LobbyDiffResult? lobbyDiffResult; if (!LobbyCompatibilityPresent) { lobbyDiffResult = (_cachedResult = LobbyDiffResult.Unknown); return lobbyDiffResult.Value; } bool flag = PluginDiffs.Any((PluginDiff pluginDiff) => pluginDiff.PluginDiffResult == PluginDiffResult.Unknown); if (PluginDiffs.Any((PluginDiff pluginDiff) => pluginDiff.PluginDiffResult != 0 && pluginDiff.PluginDiffResult != PluginDiffResult.Unknown)) { lobbyDiffResult = (_cachedResult = LobbyDiffResult.Incompatible); return lobbyDiffResult.Value; } if (flag) { lobbyDiffResult = (_cachedResult = LobbyDiffResult.PresumedCompatible); return lobbyDiffResult.Value; } lobbyDiffResult = (_cachedResult = LobbyDiffResult.Compatible); return lobbyDiffResult.Value; } [CompilerGenerated] protected virtual bool PrintMembers(StringBuilder builder) { RuntimeHelpers.EnsureSufficientExecutionStack(); builder.Append("PluginDiffs = "); builder.Append(PluginDiffs); builder.Append(", LobbyCompatibilityPresent = "); builder.Append(LobbyCompatibilityPresent.ToString()); return true; } } public record PluginDiff(PluginDiffResult PluginDiffResult, string GUID, Version? ClientVersion, Version? ServerVersion) { public string GetDisplayText() { string text = GUID ?? ""; if (ClientVersion != null) { text += $"-v{ClientVersion}"; } if (PluginDiffResult == PluginDiffResult.ModVersionMismatch && ServerVersion != null) { text += $" — v{ServerVersion} was required"; } return text; } public Color GetTextColor() { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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_0044: 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_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) switch (PluginDiffResult) { case PluginDiffResult.Compatible: return LobbyCompatibilityPlugin.Config?.CompatibleColor.Value ?? Config.DefaultCompatibleColor; case PluginDiffResult.ServerMissingMod: case PluginDiffResult.ClientMissingMod: case PluginDiffResult.ModVersionMismatch: return LobbyCompatibilityPlugin.Config?.IncompatibleColor.Value ?? Config.DefaultIncompatibleColor; default: return LobbyCompatibilityPlugin.Config?.UnknownColor.Value ?? Config.DefaultUnknownColor; } } } [Serializable] public record PluginInfoRecord([property: JsonProperty("i")] string GUID, [property: JsonProperty("v"), JsonConverter(typeof(VersionConverter))] Version Version, [property: JsonProperty("c")] CompatibilityLevel? CompatibilityLevel, [property: JsonProperty("s")] VersionStrictness? VersionStrictness, [property: JsonIgnore] VariableCompatibilityCheckDelegate? VariableCompatibilityCheck = null) : IComparable<PluginInfoRecord> { [JsonIgnore] public int JsonLength { get { int valueOrDefault = _jsonLength.GetValueOrDefault(); if (!_jsonLength.HasValue) { valueOrDefault = 25 + GUID.Length + Version.ToString().Length + (CompatibilityLevel.HasValue ? 1 : 4) + (VersionStrictness.HasValue ? 1 : 4); _jsonLength = valueOrDefault; return valueOrDefault; } return valueOrDefault; } } [JsonIgnore] private int? _jsonLength; public int CompareTo(PluginInfoRecord other) { if (CompatibilityLevel != other.CompatibilityLevel) { if (!CompatibilityLevel.HasValue) { return 1; } if (!other.CompatibilityLevel.HasValue) { return -1; } return other.CompatibilityLevel.GetValueOrDefault() - CompatibilityLevel.GetValueOrDefault(); } if (VersionStrictness != other.VersionStrictness) { if (!VersionStrictness.HasValue) { return 1; } if (!other.VersionStrictness.HasValue) { return -1; } return other.VersionStrictness.GetValueOrDefault() - VersionStrictness.GetValueOrDefault(); } return string.Compare(GUID, other.GUID, StringComparison.Ordinal); } [CompilerGenerated] protected virtual bool PrintMembers(StringBuilder builder) { RuntimeHelpers.EnsureSufficientExecutionStack(); builder.Append("GUID = "); builder.Append((object?)GUID); builder.Append(", Version = "); builder.Append(Version); builder.Append(", CompatibilityLevel = "); builder.Append(CompatibilityLevel.ToString()); builder.Append(", VersionStrictness = "); builder.Append(VersionStrictness.ToString()); builder.Append(", VariableCompatibilityCheck = "); builder.Append(VariableCompatibilityCheck); builder.Append(", JsonLength = "); builder.Append(JsonLength.ToString()); return true; } } } namespace LobbyCompatibility.Features { internal static class HarmonyHelper { public static MethodInfo? GetAsyncInfo(Type type, string method) { return AccessTools.Method(type, method, (Type[])null, (Type[])null).GetCustomAttribute<AsyncStateMachineAttribute>().StateMachineType.GetMethod("MoveNext", BindingFlags.Instance | BindingFlags.NonPublic); } } public static class LobbyHelper { public static readonly Regex ModdedLobbyIdentifierRegex = new Regex("(\\bmod(s|ded)?\\b)", RegexOptions.IgnoreCase); public static Dictionary<string, string> LatestLobbyRequestStringFilters = new Dictionary<string, string>(); public static LobbyDistanceFilter? LatestLobbyRequestDistanceFilter; private static List<PluginInfoRecord>? _clientPlugins; private const int MaxPluginMetadataLength = 7800; private const int AveragePluginJsonLength = 60; public static LobbyDiff LatestLobbyDiff { get; private set; } = new LobbyDiff(new List<PluginDiff>()); public static IEnumerable<KeyValuePair<string, string>>? LatestLobbyData { get; internal set; } private static Dictionary<ulong, LobbyDiff> LobbyDiffCache { get; } = new Dictionary<ulong, LobbyDiff>(); public static int CurrentMaxPluginMetadataLength { get; private set; } = 7800; private static int AverageMaxLobbyMetadataModCount => CurrentMaxPluginMetadataLength / 60; public static LobbyDiff GetLobbyDiff(Lobby? lobby) { return GetLobbyDiff(lobby, null); } public static LobbyDiff GetLobbyDiff(IEnumerable<KeyValuePair<string, string>> lobbyData) { return GetLobbyDiff(null, null, lobbyData); } public static void ReserveLobbyMetadataSpace(int length) { CurrentMaxPluginMetadataLength -= length; } internal static LobbyDiff GetLobbyDiff(Lobby? lobby, string? lobbyPluginString, IEnumerable<KeyValuePair<string, string>>? lobbyData = null) { //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_0019: 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_0464: Unknown result type (might be due to invalid IL or missing references) //IL_0469: Unknown result type (might be due to invalid IL or missing references) //IL_046d: Unknown result type (might be due to invalid IL or missing references) Lobby value; if (lobby.HasValue) { Dictionary<ulong, LobbyDiff> lobbyDiffCache = LobbyDiffCache; value = lobby.Value; if (lobbyDiffCache.TryGetValue(SteamId.op_Implicit(((Lobby)(ref value)).Id), out LobbyDiff value2)) { LatestLobbyDiff = value2; return value2; } } List<KeyValuePair<string, string>> list = lobbyData?.ToList(); List<PluginInfoRecord> list2 = ParseLobbyPluginsMetadata(lobbyPluginString ?? (lobby.HasValue ? GetLobbyPlugins(lobby.Value) : ((list != null) ? GetLobbyPlugins(list) : string.Empty))).ToList(); _clientPlugins = PluginHelper.GetAllPluginInfo().CalculateCompatibilityLevel(lobby, list); List<PluginDiff> list3 = new List<PluginDiff>(); foreach (PluginInfoRecord lobbyPlugin in list2) { PluginInfoRecord pluginInfoRecord = _clientPlugins.FirstOrDefault((PluginInfoRecord plugin) => plugin.GUID == lobbyPlugin.GUID); if (!lobbyPlugin.CompatibilityLevel.HasValue || !lobbyPlugin.VersionStrictness.HasValue) { Version version = pluginInfoRecord?.Version; list3.Add(new PluginDiff((!(version == lobbyPlugin.Version)) ? PluginDiffResult.Unknown : PluginDiffResult.Compatible, lobbyPlugin.GUID, version, lobbyPlugin.Version)); } else if (pluginInfoRecord == null) { if (lobbyPlugin.CompatibilityLevel == CompatibilityLevel.Everyone) { list3.Add(new PluginDiff(PluginDiffResult.ClientMissingMod, lobbyPlugin.GUID, null, lobbyPlugin.Version)); } else { list3.Add(new PluginDiff(PluginDiffResult.Compatible, lobbyPlugin.GUID, null, lobbyPlugin.Version)); } } else if (pluginInfoRecord.CompatibilityLevel != lobbyPlugin.CompatibilityLevel) { list3.Add(new PluginDiff(PluginDiffResult.ModVersionMismatch, lobbyPlugin.GUID, pluginInfoRecord.Version, lobbyPlugin.Version)); } else if (pluginInfoRecord.CompatibilityLevel != CompatibilityLevel.ClientOnly && !PluginHelper.MatchesVersion(pluginInfoRecord, lobbyPlugin)) { list3.Add(new PluginDiff(PluginDiffResult.ModVersionMismatch, lobbyPlugin.GUID, pluginInfoRecord.Version, lobbyPlugin.Version)); } else { list3.Add(new PluginDiff(PluginDiffResult.Compatible, lobbyPlugin.GUID, pluginInfoRecord.Version, lobbyPlugin.Version)); } } foreach (PluginInfoRecord clientPlugin in _clientPlugins) { PluginInfoRecord pluginInfoRecord2 = list2.FirstOrDefault((PluginInfoRecord plugin) => plugin.GUID == clientPlugin.GUID); if (!clientPlugin.CompatibilityLevel.HasValue || !clientPlugin.VersionStrictness.HasValue) { Version version2 = pluginInfoRecord2?.Version; if (version2 != clientPlugin.Version) { list3.Add(new PluginDiff(PluginDiffResult.Unknown, clientPlugin.GUID, clientPlugin.Version, version2)); } continue; } if (pluginInfoRecord2 != null) { continue; } CompatibilityLevel? compatibilityLevel = clientPlugin.CompatibilityLevel; bool flag; if (compatibilityLevel.HasValue) { CompatibilityLevel valueOrDefault = compatibilityLevel.GetValueOrDefault(); if ((uint)(valueOrDefault - 2) <= 1u) { flag = true; goto IL_03d3; } } flag = false; goto IL_03d3; IL_03d3: if (flag) { list3.Add(new PluginDiff(PluginDiffResult.ServerMissingMod, clientPlugin.GUID, clientPlugin.Version, null)); } else { list3.Add(new PluginDiff(PluginDiffResult.Compatible, clientPlugin.GUID, clientPlugin.Version, null)); } } bool lobbyCompatibilityPresent = list2.Any(); LatestLobbyDiff = new LobbyDiff(list3, lobbyCompatibilityPresent); if (lobby.HasValue) { Dictionary<ulong, LobbyDiff> lobbyDiffCache2 = LobbyDiffCache; value = lobby.Value; lobbyDiffCache2.Add(SteamId.op_Implicit(((Lobby)(ref value)).Id), LatestLobbyDiff); } return LatestLobbyDiff; } internal static string GetLobbyPlugins(Lobby lobby) { if (Object.op_Implicit((Object)(object)GameNetworkManager.Instance) && !GameNetworkManager.Instance.disableSteam) { return ((Lobby)(ref lobby)).GetData("plugins0"); } return string.Empty; } internal static string GetLobbyPlugins(List<KeyValuePair<string, string>> lobbyData) { List<string> list = new List<string>(); if (Object.op_Implicit((Object)(object)GameNetworkManager.Instance)) { int i = 0; do { list.Insert(i, lobbyData.FirstOrDefault<KeyValuePair<string, string>>((KeyValuePair<string, string> x) => x.Key == string.Format("{0}{1}", "plugins", i)).Value); } while (list[i++].Contains("@")); } return GeneralExtensions.Join<string>((IEnumerable<string>)list, (Func<string, string>)null, string.Empty).Replace("@", string.Empty); } internal static string GetLobbyPluginsMetadata(List<PluginInfoRecord>? plugins = null) { //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Expected O, but got Unknown //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Expected O, but got Unknown if (plugins == null) { plugins = PluginHelper.GetAllPluginInfo().ToList(); } plugins.Sort(); List<PluginInfoRecord> list = plugins.Take(AverageMaxLobbyMetadataModCount).ToList(); if (list.Sum((PluginInfoRecord record) => record.JsonLength) + 1 + list.Count > CurrentMaxPluginMetadataLength) { while (list.Sum((PluginInfoRecord record) => record.JsonLength) + 1 + list.Count > CurrentMaxPluginMetadataLength) { list.RemoveAt(list.Count - 1); } return JsonConvert.SerializeObject((object)list, (JsonConverter[])(object)new JsonConverter[1] { (JsonConverter)new VersionConverter() }); } while (list.Count < plugins.Count) { list.Add(plugins[list.Count]); if (list.Sum((PluginInfoRecord record) => record.JsonLength) + 1 + list.Count > CurrentMaxPluginMetadataLength) { list.RemoveAt(list.Count - 1); break; } } return JsonConvert.SerializeObject((object)list, (JsonConverter[])(object)new JsonConverter[1] { (JsonConverter)new VersionConverter() }); } internal static IEnumerable<PluginInfoRecord> ParseLobbyPluginsMetadata(string json) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown try { return JsonConvert.DeserializeObject<List<PluginInfoRecord>>(json, (JsonConverter[])(object)new JsonConverter[1] { (JsonConverter)new VersionConverter() }) ?? new List<PluginInfoRecord>(); } catch (Exception ex) { ManualLogSource? logger = LobbyCompatibilityPlugin.Logger; if (logger != null) { logger.LogError((object)"Failed to parse lobby plugins metadata."); } ManualLogSource? logger2 = LobbyCompatibilityPlugin.Logger; if (logger2 != null) { logger2.LogDebug((object)ex); } throw; } } public static string GetCompatibilityHeader(PluginDiffResult pluginDiffResult) { return pluginDiffResult switch { PluginDiffResult.Compatible => "Compatible", PluginDiffResult.ClientMissingMod => "Missing lobby-required mods", PluginDiffResult.ServerMissingMod => "Incompatible with lobby", PluginDiffResult.ModVersionMismatch => "Incompatible mod versions", _ => "Unknown", }; } public static Lobby[] FilterLobbies(Lobby[] normalLobbies, Lobby[]? filteredLobbies, ModdedLobbyFilter currentFilter) { Lobby[] filteredLobbies2 = filteredLobbies; List<Lobby> list = new List<Lobby>(); if (filteredLobbies2 != null) { normalLobbies = normalLobbies.Where((Lobby lobby) => !filteredLobbies2.Any((Lobby check) => ((object)(Lobby)(ref lobby)).Equals((object?)check))).ToArray(); } if (currentFilter == ModdedLobbyFilter.VanillaAndUnknownOnly) { list.AddRange(FilterLobbiesByDiffResult(normalLobbies, LobbyDiffResult.Unknown)); } else { bool flag = filteredLobbies2 != null; bool flag2 = flag; if (flag2) { bool flag3 = (uint)currentFilter <= 1u; flag2 = flag3; } if (flag2) { var (collection, lobbies) = SplitLobbiesByDiffResult(filteredLobbies2, LobbyDiffResult.Compatible); var (collection2, enumerable) = SplitLobbiesByDiffResult(normalLobbies, LobbyDiffResult.Compatible); list.AddRange(collection); list.AddRange(collection2); if (currentFilter == ModdedLobbyFilter.CompatibleFirst) { var (collection3, collection4) = SplitLobbiesByDiffResult(lobbies, LobbyDiffResult.PresumedCompatible); var (collection5, collection6) = SplitLobbiesByDiffResult(normalLobbies, LobbyDiffResult.PresumedCompatible); list.AddRange(collection3); list.AddRange(collection5); list.AddRange(collection4); list.AddRange(collection6); } } else if (filteredLobbies2 != null || currentFilter != 0) { list = ((filteredLobbies2 != null || currentFilter != ModdedLobbyFilter.CompatibleOnly) ? normalLobbies.ToList() : new List<Lobby>()); } else { var (collection7, enumerable2) = SplitLobbiesByDiffResult(normalLobbies, LobbyDiffResult.Compatible); var (collection8, collection9) = SplitLobbiesByDiffResult(normalLobbies, LobbyDiffResult.PresumedCompatible); list.AddRange(collection7); list.AddRange(collection8); list.AddRange(collection9); } } return list.ToArray(); } private static (IEnumerable<Lobby> matchedLobbies, IEnumerable<Lobby> unmatchedLobbies) SplitLobbiesByDiffResult(IEnumerable<Lobby> lobbies, LobbyDiffResult filteredLobbyDiffResult) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: 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) List<Lobby> list = new List<Lobby>(); List<Lobby> list2 = new List<Lobby>(); foreach (Lobby lobby in lobbies) { LobbyDiffResult moddedLobbyType = GetLobbyDiff(lobby).GetModdedLobbyType(); if (moddedLobbyType == filteredLobbyDiffResult) { list.Add(lobby); } else { list2.Add(lobby); } } return (list, list2); } private static IEnumerable<Lobby> FilterLobbiesByDiffResult(IEnumerable<Lobby> lobbies, LobbyDiffResult filteredLobbyDiffResult) { return SplitLobbiesByDiffResult(lobbies, filteredLobbyDiffResult).matchedLobbies; } public static string GetEmptyLobbyListString(ModdedLobbyFilter moddedLobbyFilter) { return moddedLobbyFilter switch { ModdedLobbyFilter.CompatibleOnly => "No available compatible\nservers to join.", ModdedLobbyFilter.VanillaAndUnknownOnly => "No available vanilla or unknown\nservers to join.", _ => "No available servers to join.", }; } public static bool LobbyNameContainsModIdentifier(Lobby lobby) { return ModdedLobbyIdentifierRegex.IsMatch(((Lobby)(ref lobby)).GetData("name")); } } public delegate CompatibilityLevel VariableCompatibilityCheckDelegate(IEnumerable<KeyValuePair<string, string>> lobbyData); public static class PluginHelper { private static readonly List<PluginInfoRecord> RegisteredPluginInfoRecords = new List<PluginInfoRecord>(); private static string? _cachedChecksum; internal static string Checksum { get { return _cachedChecksum ?? GetRequiredPluginsChecksum(); } set { _cachedChecksum = value; } } public static void RegisterPlugin(string guid, Version version, CompatibilityLevel compatibilityLevel, VersionStrictness versionStrictness) { RegisterPlugin(guid, version, compatibilityLevel, versionStrictness, null); } public static void RegisterPlugin(string guid, Version version, CompatibilityLevel compatibilityLevel, VersionStrictness versionStrictness, VariableCompatibilityCheckDelegate? variableCompatibilityCheck) { RegisteredPluginInfoRecords.Add(new PluginInfoRecord(guid, version, compatibilityLevel, versionStrictness, variableCompatibilityCheck)); _cachedChecksum = null; } private static bool HasCompatibilityAttribute(BaseUnityPlugin plugin) { return ((object)plugin)?.GetType().GetCustomAttributes(typeof(LobbyCompatibilityAttribute), inherit: false).Any() ?? false; } private static IEnumerable<PluginInfo> GetCompatibilityPlugins() { return from plugin in Chainloader.PluginInfos where HasCompatibilityAttribute(plugin.Value.Instance) select plugin.Value; } private static LobbyCompatibilityAttribute? GetCompatibilityAttribute(BaseUnityPlugin plugin) { return (LobbyCompatibilityAttribute)((object)plugin).GetType().GetCustomAttributes(typeof(LobbyCompatibilityAttribute), inherit: false).FirstOrDefault(); } internal static IEnumerable<PluginInfoRecord> GetAllPluginInfo() { List<PluginInfoRecord> list = new List<PluginInfoRecord>(); List<PluginInfo> list2 = GetCompatibilityPlugins().ToList(); List<PluginInfo> list3 = (from plugin in Chainloader.PluginInfos.Values where plugin.Instance != null && !HasCompatibilityAttribute(plugin.Instance) select (plugin)).ToList(); list2.RemoveAll((PluginInfo plugin) => RegisteredPluginInfoRecords.Any((PluginInfoRecord record) => record.GUID == plugin.Metadata.GUID)); list3.RemoveAll((PluginInfo plugin) => RegisteredPluginInfoRecords.Any((PluginInfoRecord record) => record.GUID == plugin.Metadata.GUID)); list.AddRange(list2.Select((PluginInfo plugin) => new PluginInfoRecord(plugin.Metadata.GUID, plugin.Metadata.Version, GetCompatibilityAttribute(plugin.Instance)?.CompatibilityLevel, GetCompatibilityAttribute(plugin.Instance)?.VersionStrictness))); list.AddRange(list3.Select((PluginInfo plugin) => new PluginInfoRecord(plugin.Metadata.GUID, plugin.Metadata.Version, null, null))); return list.Concat(RegisteredPluginInfoRecords); } internal static bool MatchesVersion(PluginInfoRecord source, PluginInfoRecord target) { if (source.VersionStrictness == VersionStrictness.None) { return true; } if (source.VersionStrictness == VersionStrictness.Major) { if (target.Version.Major != source.Version.Major) { return false; } } else if (source.VersionStrictness == VersionStrictness.Minor) { if (target.Version.Major != source.Version.Major || target.Version.Minor != source.Version.Minor) { return false; } } else if (source.VersionStrictness == VersionStrictness.Patch && target.Version != source.Version) { return false; } return true; } internal static bool MatchesTargetRequirements(IEnumerable<PluginInfoRecord> targetPluginInfo) { List<PluginInfoRecord> list = GetAllPluginInfo().ToList(); List<PluginInfoRecord> list2 = targetPluginInfo.ToList(); bool flag; foreach (PluginInfoRecord clientPlugin2 in list) { CompatibilityLevel? compatibilityLevel = clientPlugin2.CompatibilityLevel; if (compatibilityLevel.HasValue) { CompatibilityLevel valueOrDefault = compatibilityLevel.GetValueOrDefault(); if ((uint)(valueOrDefault - 2) <= 1u) { flag = true; goto IL_005c; } } flag = false; goto IL_005c; IL_005c: if (!flag || list2.Any((PluginInfoRecord serverPlugin) => serverPlugin.GUID == clientPlugin2.GUID && MatchesVersion(clientPlugin2, serverPlugin))) { continue; } flag = false; goto IL_010a; } foreach (PluginInfoRecord serverPlugin2 in list2) { CompatibilityLevel? compatibilityLevel = serverPlugin2.CompatibilityLevel; if (!compatibilityLevel.HasValue || compatibilityLevel.GetValueOrDefault() != CompatibilityLevel.Everyone || list.Any((PluginInfoRecord clientPlugin) => clientPlugin.GUID == serverPlugin2.GUID && MatchesVersion(serverPlugin2, clientPlugin))) { continue; } flag = false; goto IL_010a; } return true; IL_010a: return flag; } public static List<PluginInfoRecord> CalculateCompatibilityLevel(this IEnumerable<PluginInfoRecord> pluginInfoRecords, Lobby? lobby = null, IEnumerable<KeyValuePair<string, string>>? lobbyData = null) { IEnumerable<KeyValuePair<string, string>> lobbyData2 = lobbyData; return pluginInfoRecords.Select(delegate(PluginInfoRecord plugin) { CompatibilityLevel? compatibilityLevel2 = plugin.CompatibilityLevel; return (!compatibilityLevel2.HasValue || compatibilityLevel2.GetValueOrDefault() != CompatibilityLevel.Variable) ? plugin : VariableCompat(plugin); }).ToList(); PluginInfoRecord VariableCompat(PluginInfoRecord plugin) { //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) VariableCompatibilityCheckDelegate? variableCompatibilityCheck = plugin.VariableCompatibilityCheck; int num; if (variableCompatibilityCheck == null) { num = 0; } else { ref Lobby? reference = ref lobby; object obj; if (!reference.HasValue) { obj = null; } else { Lobby valueOrDefault = reference.GetValueOrDefault(); obj = ((Lobby)(ref valueOrDefault)).Data; } if (obj == null) { IEnumerable<KeyValuePair<string, string>> enumerable = lobbyData2; obj = enumerable; } if (obj == null) { obj = Array.Empty<KeyValuePair<string, string>>(); } num = (int)variableCompatibilityCheck((IEnumerable<KeyValuePair<string, string>>)obj); } CompatibilityLevel compatibilityLevel = (CompatibilityLevel)num; compatibilityLevel = ((compatibilityLevel != CompatibilityLevel.Variable) ? compatibilityLevel : CompatibilityLevel.ClientOnly); ManualLogSource? logger = LobbyCompatibilityPlugin.Logger; if (logger != null) { logger.LogDebug((object)$"({plugin.GUID}) Variable Compatibility level: {compatibilityLevel}"); } return plugin with { CompatibilityLevel = compatibilityLevel }; } } internal static bool CanJoinVanillaLobbies() { return true; } public static IEnumerable<PluginDiff> FilterPluginDiffs(IEnumerable<PluginDiff> pluginDiffs, ModListFilter modListFilter) { return modListFilter switch { ModListFilter.Compatible => pluginDiffs.Where((PluginDiff x) => x.PluginDiffResult == PluginDiffResult.Compatible), ModListFilter.Incompatible => pluginDiffs.Where((PluginDiff x) => x.PluginDiffResult == PluginDiffResult.ServerMissingMod || x.PluginDiffResult == PluginDiffResult.ClientMissingMod || x.PluginDiffResult == PluginDiffResult.ModVersionMismatch), ModListFilter.Unknown => pluginDiffs.Where((PluginDiff x) => x.PluginDiffResult == PluginDiffResult.Unknown), _ => pluginDiffs, }; } private static string GetRequiredPluginsChecksum() { List<PluginInfoRecord> list = GetAllPluginInfo().Where(delegate(PluginInfoRecord plugin) { CompatibilityLevel? compatibilityLevel = plugin.CompatibilityLevel; return compatibilityLevel.HasValue && compatibilityLevel.GetValueOrDefault() == CompatibilityLevel.Everyone; }).OrderBy<PluginInfoRecord, string>((PluginInfoRecord plugin) => plugin.GUID, StringComparer.Ordinal).ToList(); if (!list.Any()) { return _cachedChecksum = ""; } string text = ""; foreach (PluginInfoRecord item in list) { text += item.GUID; switch (item.VersionStrictness) { case VersionStrictness.Major: text += new Version(item.Version.Major, 0).ToString(); break; case VersionStrictness.Minor: text += new Version(item.Version.Major, item.Version.Minor).ToString(); break; case VersionStrictness.Patch: text += item.Version.ToString(); break; } } byte[] array = SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(text)); StringBuilder stringBuilder = new StringBuilder(); byte[] array2 = array; foreach (byte b in array2) { stringBuilder.Append(b.ToString("X2")); } _cachedChecksum = stringBuilder.ToString(); ManualLogSource? logger = LobbyCompatibilityPlugin.Logger; if (logger != null) { logger.LogDebug((object)_cachedChecksum); } return _cachedChecksum; } } internal static class TextureHelper { internal static Dictionary<string, Sprite?> SpriteCache = new Dictionary<string, Sprite>(); public static Sprite? FindSpriteInAssembly(string path, Assembly? assembly = null) { if (SpriteCache.ContainsKey(path)) { return SpriteCache[path]; } if (assembly == null) { assembly = Assembly.GetExecutingAssembly(); } if (assembly == null) { return null; } Sprite val = null; try { if (assembly.GetManifestResourceNames().Contains(path)) { val = LoadSpriteRaw(GetResource(assembly, path)); } } catch (Exception ex) { ManualLogSource? logger = LobbyCompatibilityPlugin.Logger; if (logger != null) { logger.LogError((object)("Unable to find texture in assembly! Exception: " + ex)); } } SpriteCache.Add(path, val); return val; } public static byte[] GetResource(Assembly assembly, string resource) { using Stream stream = assembly.GetManifestResourceStream(resource) ?? throw new FileNotFoundException(resource); using MemoryStream memoryStream = new MemoryStream(new byte[stream.Length], writable: true); stream.CopyTo(memoryStream); return memoryStream.ToArray(); } public static Sprite? LoadSpriteRaw(byte[] image, float pixelsPerUnit = 100f) { Texture2D val = LoadTextureRaw(image); if (!((Object)(object)val == (Object)null)) { return LoadSpriteFromTexture(val, pixelsPerUnit); } return null; } public static Texture2D? LoadTextureRaw(byte[] file) { //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Expected O, but got Unknown if (file.Length != 0) { Texture2D val = new Texture2D(0, 0, (TextureFormat)4, false, false); if (ImageConversion.LoadImage(val, file)) { return val; } } return null; } public static Sprite? LoadSpriteFromTexture(Texture2D spriteTexture, float pixelsPerUnit = 100f) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)spriteTexture == (Object)null) { return null; } Sprite val = Sprite.Create(spriteTexture, new Rect(0f, 0f, (float)((Texture)spriteTexture).width, (float)((Texture)spriteTexture).height), new Vector2(0f, 0f), pixelsPerUnit); ((Object)val).name = ((Object)spriteTexture).name; return val; } } internal static class UIHelper { public static bool TryMultiplySizeDelta(Transform? transform, Vector2 multiplier) { //IL_001e: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)transform == (Object)null) { return false; } RectTransform component = ((Component)transform).GetComponent<RectTransform>(); if ((Object)(object)component == (Object)null) { return false; } MultiplySizeDelta(component, multiplier); return true; } private static void MultiplySizeDelta(RectTransform rectTransform, Vector2 multiplier) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: 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: 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) Vector2 sizeDelta = rectTransform.sizeDelta; rectTransform.sizeDelta = new Vector2(sizeDelta.x * multiplier.x, sizeDelta.y * multiplier.y); } public static void AddToAnchoredPosition(Transform? transform, Vector2 addition) { //IL_0027: 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_0039: 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_004a: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)transform == (Object)null)) { RectTransform val = (RectTransform)(object)((transform is RectTransform) ? transform : null); if (val == null) { val = ((Component)transform).GetComponent<RectTransform>(); } if (!((Object)(object)val == (Object)null)) { val.anchoredPosition = new Vector2(val.anchoredPosition.x + addition.x, val.anchoredPosition.y + addition.y); } } } public static TextMeshProUGUI SetupTextAsTemplate(TextMeshProUGUI template, Transform parent, Color color, Vector2 size, float maxFontSize, float minFontSize, HorizontalAlignmentOptions alignment = 2, Vector2? defaultPosition = null) { //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI val = Object.Instantiate<TextMeshProUGUI>(template, parent); ((TMP_Text)val).rectTransform.anchoredPosition = (Vector2)(((??)defaultPosition) ?? new Vector2(0f, 0f)); ((TMP_Text)val).rectTransform.sizeDelta = size; ((TMP_Text)val).horizontalAlignment = alignment; ((TMP_Text)val).enableAutoSizing = true; ((TMP_Text)val).fontSizeMax = maxFontSize; ((TMP_Text)val).fontSizeMin = minFontSize; ((TMP_Text)val).enableWordWrapping = false; ((Graphic)val).color = color; ((Component)val).gameObject.SetActive(false); return val; } public static RectTransform ApplyParentSize(GameObject uiElement, Transform parent) { //IL_0029: 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_0053: Unknown result type (might be due to invalid IL or missing references) //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_0065: 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_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007d: 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) RectTransform val = uiElement.GetComponent<RectTransform>(); if ((Object)(object)val == (Object)null) { val = uiElement.AddComponent<RectTransform>(); } ((Transform)val).SetParent(parent); val.anchorMin = new Vector2(0f, 1f); val.anchorMax = new Vector2(1f, 1f); val.pivot = new Vector2(0.5f, 0.5f); RectTransform obj = val; Vector2 offsetMin = (val.offsetMax = Vector2.zero); obj.offsetMin = offsetMin; ((Transform)val).localRotation = Quaternion.identity; ((Transform)val).localScale = Vector3.one; ((Transform)val).localPosition = Vector3.zero; return val; } public static TextMeshProUGUI CreateTextFromTemplate(TextMeshProUGUI template, string content, float yPosition, Color? overrideColor = null) { //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_001e: Unknown result type (might be due to invalid IL or missing references) TextMeshProUGUI val = Object.Instantiate<TextMeshProUGUI>(template, ((TMP_Text)template).transform.parent); if (overrideColor.HasValue) { ((Graphic)val).color = overrideColor.Value; } ((TMP_Text)val).rectTransform.anchoredPosition = new Vector2(((TMP_Text)val).rectTransform.anchoredPosition.x, yPosition); ((TMP_Text)val).text = content; ((Component)val).gameObject.SetActive(true); return val; } public static (List<PluginDiffSlot?> pluginDiffSlots, List<PluginCategorySlot?> pluginCategorySlots) GenerateDiffSlotsFromLobbyDiff(LobbyDiff lobbyDiff, PluginDiffSlotPool pluginDiffSlotPool, PluginCategorySlotPool pluginCategorySlotPool, ModListFilter? modListFilter = null, int? maxLines = null) { //IL_0218: Unknown result type (might be due to invalid IL or missing references) //IL_020c: Unknown result type (might be due to invalid IL or missing references) List<PluginDiffSlot> list = new List<PluginDiffSlot>(); List<PluginCategorySlot> list2 = new List<PluginCategorySlot>(); IEnumerable<PluginDiff> enumerable; if (!modListFilter.HasValue) { IEnumerable<PluginDiff> pluginDiffs = lobbyDiff.PluginDiffs; enumerable = pluginDiffs; } else { enumerable = PluginHelper.FilterPluginDiffs(lobbyDiff.PluginDiffs, modListFilter.Value); } IEnumerable<PluginDiff> source = enumerable; int num = 0; int num2 = 0; foreach (PluginDiffResult compatibilityResult in Enum.GetValues(typeof(PluginDiffResult)).Cast<PluginDiffResult>()) { List<PluginDiff> list3 = source.Where((PluginDiff pluginDiff) => pluginDiff.PluginDiffResult == compatibilityResult).ToList(); if (list3.Count == 0) { continue; } if (maxLines.HasValue && num >= maxLines - 1) { break; } PluginCategorySlot item = pluginCategorySlotPool.Spawn(compatibilityResult); list2.Add(item); num++; foreach (PluginDiff item2 in list3) { PluginDiffSlot pluginDiffSlot = pluginDiffSlotPool.Spawn(item2, lobbyDiff.LobbyCompatibilityPresent); if (!((Object)(object)pluginDiffSlot == (Object)null)) { list.Add(pluginDiffSlot); num++; num2++; if (maxLines.HasValue && num >= maxLines) { break; } } } } int num3 = lobbyDiff.PluginDiffs.Count - num2; if (maxLines.HasValue && num >= maxLines && num3 > 0) { string pluginNameText = string.Format("{0} more mod{1}...", num3, (num3 == 1) ? "" : "s"); PluginDiffSlot pluginDiffSlot2 = pluginDiffSlotPool.Spawn(pluginNameText, "", "", LobbyCompatibilityPlugin.Config?.UnknownColor.Value ?? Color.gray); if ((Object)(object)pluginDiffSlot2 != (Object)null) { list.Add(pluginDiffSlot2); } } return (list, list2); } public static void ClearSpawnedDiffSlots(PluginDiffSlotPool pluginDiffSlotPool, PluginCategorySlotPool pluginCategorySlotPool, ref List<PluginDiffSlot?> existingPluginDiffSlots, ref List<PluginCategorySlot?> existingPluginCategorySlots) { foreach (PluginDiffSlot existingPluginDiffSlot in existingPluginDiffSlots) { if (!((Object)(object)existingPluginDiffSlot == (Object)null)) { pluginDiffSlotPool.Release(existingPluginDiffSlot); } } foreach (PluginCategorySlot existingPluginCategorySlot in existingPluginCategorySlots) { if (!((Object)(object)existingPluginCategorySlot == (Object)null)) { pluginCategorySlotPool.Release(existingPluginCategorySlot); } } existingPluginDiffSlots.Clear(); existingPluginCategorySlots.Clear(); } public static void AddVerticalLayoutGroup(GameObject gameObject, bool addContentSizeFitter = true) { VerticalLayoutGroup val = gameObject.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val).childControlHeight = false; ((HorizontalOrVerticalLayoutGroup)val).childForceExpandHeight = false; if (addContentSizeFitter) { ContentSizeFitter val2 = ((Component)val).gameObject.AddComponent<ContentSizeFitter>(); val2.verticalFit = (FitMode)2; } } public static void ReskinRefreshButton(Button refreshButton) { //IL_0083: 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_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: 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_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) object obj; if (refreshButton == null) { obj = null; } else { Transform obj2 = ((Component)refreshButton).transform.Find("Text (TMP)"); obj = ((obj2 != null) ? ((Component)obj2).GetComponent<TextMeshProUGUI>() : null); } TextMeshProUGUI val = (TextMeshProUGUI)obj; object obj3; if (refreshButton == null) { obj3 = null; } else { Transform obj4 = ((Component)refreshButton).transform.Find("SelectionHighlight"); obj3 = ((obj4 != null) ? ((Component)obj4).GetComponent<RectTransform>() : null); } RectTransform val2 = (RectTransform)obj3; Image val3 = ((val2 != null) ? ((Component)val2).GetComponent<Image>() : null); if (!((Object)(object)refreshButton == (Object)null) && !((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null)) { val2.anchoredPosition = new Vector2(140f, 17.5f); val2.sizeDelta = new Vector2(34f, 43.5f); RectTransform val4 = Object.Instantiate<RectTransform>(val2, ((TMP_Text)val).transform.parent, false); Image component = ((Component)val4).GetComponent<Image>(); ((Transform)val4).SetSiblingIndex(0); Color color = ((Graphic)component).color; ((Graphic)component).color = new Color(color.r, color.g, color.b, 1f); component.sprite = TextureHelper.FindSpriteInAssembly("LobbyCompatibility.Resources.Refresh.png"); val3.sprite = TextureHelper.FindSpriteInAssembly("LobbyCompatibility.Resources.InvertedRefresh.png"); ((Behaviour)val).enabled = false; } } public static void AddCustomFilterToLobbyList(Transform listPanel, float adjustment = -40f) { //IL_007a: 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_0097: 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_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Expected O, but got Unknown //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Expected O, but got Unknown //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Expected O, but got Unknown //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_016d: Expected O, but got Unknown Transform val = listPanel.Find("Dropdown"); Transform val2 = listPanel.Find("ToggleChallengeSort"); Transform obj = listPanel.Find("ServerTagInputField"); RectTransform val3 = ((obj != null) ? ((Component)obj).GetComponent<RectTransform>() : null); object obj2; if (val3 == null) { obj2 = null; } else { Transform obj3 = ((Transform)val3).Find("Text Area/Placeholder"); obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent<TextMeshProUGUI>() : null); } TextMeshProUGUI val4 = (TextMeshProUGUI)obj2; if (!((Object)(object)val == (Object)null) && !((Object)(object)val2 == (Object)null) && !((Object)(object)val3 == (Object)null) && !((Object)(object)val4 == (Object)null)) { AddToAnchoredPosition(val, new Vector2(adjustment, 0f)); AddToAnchoredPosition(val2, new Vector2(adjustment, 0f)); val3.offsetMax = new Vector2(val3.offsetMax.x + adjustment, val3.offsetMax.y); ((TMP_Text)val4).text = "Server tag..."; Transform val5 = Object.Instantiate<Transform>(val, val.parent, false); TMP_Dropdown component = ((Component)val5).GetComponent<TMP_Dropdown>(); RectTransform component2 = ((Component)val5).GetComponent<RectTransform>(); component2.anchoredPosition = new Vector2(adjustment, component2.anchoredPosition.y); component.captionText.fontSize = 10f; component.itemText.fontSize = 10f; component.ClearOptions(); component.AddOptions(new List<OptionData> { new OptionData("Mods: Compatible first"), new OptionData("Mods: Compatible only"), new OptionData("Mods: Vanilla and Unknown only"), new OptionData("Mods: All") }); ModdedLobbyFilterDropdown moddedLobbyFilterDropdown = ((Component)component).gameObject.AddComponent<ModdedLobbyFilterDropdown>(); moddedLobbyFilterDropdown.SetDropdown(component); ((UnityEventBase)component.onValueChanged).m_PersistentCalls.Clear(); ((UnityEvent<int>)(object)component.onValueChanged).AddListener((UnityAction<int>)moddedLobbyFilterDropdown.ChangeFilterType); } } } } namespace LobbyCompatibility.Enums { public enum CompatibilityLevel { ClientOnly, ServerOnly, Everyone, ClientOptional, Variable } public enum LobbyDiffResult { Compatible, Incompatible, PresumedCompatible, Unknown } public static class LobbyMetadata { public const string Name = "name"; public const string Tag = "tag"; public const string Version = "vers"; public const string Joinable = "joinable"; public const string Modded = "modded"; public const string JoinableModded = "_joinable"; public const string Plugins = "plugins"; public const string RequiredChecksum = "checksum"; public const string ModdedLobbyPrefix = "[MOD]"; } public enum ModdedLobbyFilter { CompatibleFirst, CompatibleOnly, VanillaAndUnknownOnly, All } public enum ModListFilter { All, Compatible, Incompatible, Unknown } public enum PluginDiffResult { Compatible, ServerMissingMod, ClientMissingMod, ModVersionMismatch, Unknown } public enum VersionStrictness { None, Major, Minor, Patch } } namespace LobbyCompatibility.Configuration { public class Config { public static readonly Color DefaultCompatibleColor = Color.green; public static readonly Color DefaultIncompatibleColor = Color.red; public static readonly Color DefaultUnknownColor = Color.gray; public ConfigEntry<ModdedLobbyFilter> DefaultModdedLobbyFilter; public ConfigEntry<ModListFilter> DefaultModListTab; public ConfigEntry<bool> ChangeLobbyName; public ConfigEntry<Color> CompatibleColor; public ConfigEntry<Color> IncompatibleColor; public ConfigEntry<Color> UnknownColor; public Config(ConfigFile configFile) { //IL_0066: 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_00a6: Unknown result type (might be due to invalid IL or missing references) DefaultModdedLobbyFilter = configFile.Bind<ModdedLobbyFilter>("General", "Default Lobby Filter Type", ModdedLobbyFilter.CompatibleFirst, "The default filter to apply when searching for a public lobby"); DefaultModListTab = configFile.Bind<ModListFilter>("General", "Default ModList Tab", ModListFilter.All, "The default tab to use when viewing a lobby's mod list"); ChangeLobbyName = configFile.Bind<bool>("General", "Change Lobby Name", true, "Whether to add [MOD] to the lobby name"); CompatibleColor = configFile.Bind<Color>("Visual", "Compatible Plugin Color", DefaultCompatibleColor, "The color used to respresent compatible plugins"); IncompatibleColor = configFile.Bind<Color>("Visual", "Incompatible Plugin Color", DefaultIncompatibleColor, "The color used to respresent incompatible plugins"); UnknownColor = configFile.Bind<Color>("Visual", "Unknown Plugin Color", DefaultUnknownColor, "The color used to respresent unknown plugins"); } } } namespace LobbyCompatibility.Behaviours { public class ButtonEventHandler : MonoBehaviour, IPointerEnterHandler, IEventSystemHandler, IPointerExitHandler, IPointerClickHandler { private Color? _highlightedColor; private Sprite? _highlightedSprite; private Image? _image; private Color? _normalColor; private Sprite? _normalSprite; public event Action<bool>? OnHoverStateChanged; public event Action? OnClick; public void OnPointerClick(PointerEventData eventData) { this.OnClick?.Invoke(); } public void OnPointerEnter(PointerEventData eventData) { this.OnHoverStateChanged?.Invoke(obj: true); SetHighlighted(highlighted: true); } public void OnPointerExit(PointerEventData eventData) { this.OnHoverStateChanged?.Invoke(obj: false); SetHighlighted(highlighted: false); } public void SetButtonImageData(Image image, Sprite normalSprite, Sprite highlightedSprite, Color normalColor, Color highlightedColor) { //IL_0016: 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) _image = image; _normalSprite = normalSprite; _highlightedSprite = highlightedSprite; SetColor(normalColor, highlightedColor); SetHighlighted(highlighted: false); } public void SetColor(Color normalColor, Color highlightedColor) { //IL_0001: 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) _normalColor = normalColor; _highlightedColor = highlightedColor; SetHighlighted(highlighted: false); } private void SetHighlighted(bool highlighted) { //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)_image == (Object)null)) { _image.sprite = (highlighted ? _highlightedSprite : _normalSprite); Color? val = (highlighted ? _highlightedColor : _normalColor); if (val.HasValue) { ((Graphic)_image).color = val.Value; } } } } internal class ModdedLobbyFilterDropdown : MonoBehaviour { private TMP_Dropdown? _dropdown; private SteamLobbyManager? _steamLobbyManager; public ModdedLobbyFilter LobbyFilter { get; private set; } public static ModdedLobbyFilterDropdown? Instance { get; private set; } public void Awake() { UpdateLobbyFilter(LobbyCompatibilityPlugin.Config?.DefaultModdedLobbyFilter.Value ?? ModdedLobbyFilter.CompatibleFirst); if ((Object)(object)_dropdown != (Object)null) { _dropdown.SetValueWithoutNotify((int)LobbyFilter); } Instance = this; _steamLobbyManager = Object.FindObjectOfType<SteamLobbyManager>(); } public void SetDropdown(TMP_Dropdown dropdown) { _dropdown = dropdown; } public void ChangeFilterType(int index) { UpdateLobbyFilter((ModdedLobbyFilter)index); if ((Object)(object)_steamLobbyManager != (Object)null) { _steamLobbyManager.RefreshServerListButton(); } } private void UpdateLobbyFilter(ModdedLobbyFilter lobbyFilter) { LobbyFilter = lobbyFilter; } } public class ModdedLobbySlot : MonoBehaviour { private List<ButtonEventHandler> _buttonEventHandlers = new List<ButtonEventHandler>(); private RectTransform? _buttonTransform; private Button? _joinButton; private LobbyDiff? _lobbyDiff; private LobbySlot? _lobbySlot; private Transform? _parentContainer; internal void Setup(LobbySlot lobbySlot) { //IL_0034: 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_00cf: 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_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: 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) _lobbySlot = lobbySlot; if (_lobbyDiff == null || !Object.op_Implicit((Object)(object)GameNetworkManager.Instance) || !GameNetworkManager.Instance.disableSteam) { _lobbyDiff = LobbyHelper.GetLobbyDiff(_lobbySlot.thisLobby); } TextMeshProUGUI playerCount = _lobbySlot.playerCount; if ((Object)(object)playerCount == (Object)null) { return; } _joinButton = ((Component)this).GetComponentInChildren<Button>(); if (!((Object)(object)_joinButton == (Object)null)) { Sprite lobbySprite = GetLobbySprite(_lobbyDiff.GetModdedLobbyType()); Sprite lobbySprite2 = GetLobbySprite(_lobbyDiff.GetModdedLobbyType(), inverted: true); if ((Object)(object)lobbySprite != (Object)null && (Object)(object)lobbySprite2 != (Object)null && (Object)(object)_lobbySlot.LobbyName != (Object)null) { Vector3 localPosition = ((TMP_Text)playerCount).transform.localPosition; ((TMP_Text)playerCount).transform.localPosition = new Vector3(32f, localPosition.y, localPosition.z); CreateModListButton(_joinButton, lobbySprite, lobbySprite2, ((Graphic)_lobbySlot.LobbyName).color, ((TMP_Text)playerCount).transform); } } } private void Start() { Button? joinButton = _joinButton; TextMeshProUGUI buttonText = ((joinButton != null) ? ((Component)joinButton).GetComponentInChildren<TextMeshProUGUI>() : null); LobbyDiffResult? lobbyDiffResult = _lobbyDiff?.GetModdedLobbyType(); if (lobbyDiffResult.HasValue && !((Object)(object)_joinButton == (Object)null) && !((Object)(object)buttonText == (Object)null) && (lobbyDiffResult == LobbyDiffResult.Incompatible || lobbyDiffResult == LobbyDiffResult.Unknown)) { _buttonEventHandlers.ForEach(delegate(ButtonEventHandler handler) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) handler.SetColor(((Graphic)buttonText).color, ((Graphic)buttonText).color); }); if (lobbyDiffResult == LobbyDiffResult.Incompatible) { ((Selectable)_joinButton).interactable = false; SetupModListButtonEvents(_joinButton); } } } private void OnDestroy() { if (_buttonEventHandlers.Count == 0) { return; } foreach (ButtonEventHandler buttonEventHandler in _buttonEventHandlers) { if (!((Object)(object)buttonEventHandler == (Object)null)) { buttonEventHandler.OnHoverStateChanged -= OnModListHoverStateChanged; buttonEventHandler.OnClick -= OnModListClick; } } _buttonEventHandlers.Clear(); } public void SetParentContainer(Transform parentTransform) { _parentContainer = parentTransform; } private Button? CreateModListButton(Button original, Sprite sprite, Sprite invertedSprite, Color color, Transform parent) { //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) if (_lobbyDiff == null) { return null; } Button val = Object.Instantiate<Button>(original, parent); _buttonTransform = ((Component)val).GetComponent<RectTransform>(); Transform obj = ((Component)val).transform.Find("SelectionHighlight"); RectTransform val2 = ((obj != null) ? ((Component)obj).GetComponent<RectTransform>() : null); Image val3 = ((val2 != null) ? ((Component)val2).GetComponent<Image>() : null); if ((Object)(object)_buttonTransform == (Object)null || (Object)(object)val2 == (Object)null || (Object)(object)val3 == (Object)null) { return null; } TextMeshProUGUI componentInChildren = ((Component)val).GetComponentInChildren<TextMeshProUGUI>(); if ((Object)(object)componentInChildren != (Object)null) { ((Behaviour)componentInChildren).enabled = false; } ((UnityEventBase)val.onClick).m_PersistentCalls.Clear(); ((Selectable)val).transition = (Transition)0; ((Behaviour)((Selectable)val).animator).enabled = false; SetupButtonPositioning(_buttonTransform); SetupButtonImage(val2, val3); ButtonEventHandler buttonEventHandler = SetupModListButtonEvents(val); buttonEventHandler.SetButtonImageData(val3, sprite, invertedSprite, color, color); return val; } private void OnModListClick() { if (!(_lobbyDiff == null) && !((Object)(object)ModListPanel.Instance == (Object)null)) { ModListPanel.Instance.DisplayNotification(_lobbyDiff); } } private void OnModListHoverStateChanged(bool hovered) { if (!(_lobbyDiff == null) && !((Object)(object)_buttonTransform == (Object)null) && !((Object)(object)_parentContainer == (Object)null) && !((Object)(object)ModListTooltipPanel.Instance == (Object)null)) { if (hovered) { ModListTooltipPanel.Instance.DisplayNotification(_lobbyDiff, _buttonTransform, _parentContainer); } else { ModListTooltipPanel.Instance.HideNotification(); } } } private ButtonEventHandler SetupModListButtonEvents(Button button) { ButtonEventHandler buttonEventHandler = ((Component)button).gameObject.AddComponent<ButtonEventHandler>(); buttonEventHandler.OnHoverStateChanged += OnModListHoverStateChanged; buttonEventHandler.OnClick += OnModListClick; _buttonEventHandlers.Add(buttonEventHandler); return buttonEventHandler; } private void SetupButtonPositioning(RectTransform buttonTransform) { //IL_000b: 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) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004a: 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_007e: Unknown result type (might be due to invalid IL or missing references) buttonTransform.sizeDelta = new Vector2(30f, 30f); buttonTransform.offsetMin = new Vector2(-37f, -37f); buttonTransform.offsetMax = new Vector2(-9.3f, -7f); buttonTransform.anchoredPosition = new Vector2(-85f, -7f); ((Transform)buttonTransform).localPosition = new Vector3(-5.5f, 1.25f, 0f); ((Transform)buttonTransform).localScale = new Vector3(0.6f, 0.6f, 0.6f); } private void SetupButtonImage(RectTransform buttonImageTransform, Image buttonImage) { //IL_000b: 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) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) buttonImageTransform.sizeDelta = new Vector2(31.5f, 30f); buttonImageTransform.offsetMin = new Vector2(0f, 0f); buttonImageTransform.offsetMax = new Vector2(31.5f, 30f); buttonImageTransform.anchoredPosition = new Vector2(14f, 15f); ((Transform)buttonImageTransform).localScale = Vector3.one; ((Behaviour)buttonImage).enabled = true; } private Sprite? GetLobbySprite(LobbyDiffResult lobbyDiffResult, bool inverted = false) { string text = "LobbyCompatibility.Resources."; if (inverted) { text += "Inverted"; } switch (lobbyDiffResult) { case LobbyDiffResult.Compatible: case LobbyDiffResult.PresumedCompatible: text += "ModSettings"; break; case LobbyDiffResult.Incompatible: text += "ModSettingsExclamationPoint"; break; default: text += "ModSettingsQuestionMark"; break; } return TextureHelper.FindSpriteInAssembly(text + ".png"); } } public class ModListPanel : MonoBehaviour { public static ModListPanel? Instance; private static readonly Vector2 NotificationWidth = new Vector2(1.6f, 1.75f); private static readonly float TabPadding = 3f; private List<PluginDiffSlot?> _spawnedPluginDiffSlots = new List<PluginDiffSlot>(); private List<PluginCategorySlot?> _spawnedPluginCategorySlots = new List<PluginCategorySlot>(); private RectTransform? _panelTransform; private ScrollRect? _scrollRect; private TextMeshProUGUI? _titleText; private TextMeshProUGUI? _descriptionText; private List<ModListTab> _tabs = new List<ModListTab>(); private ModListFilter _currentTab; private LobbyDiff? _lobbyDiff; private PluginDiffSlotPool? _pluginDiffSlotPool; private PluginCategorySlotPool? _pluginCategorySlotPool; private void Awake() { Instance = this; } public void SetupPanel(GameObject panel, Transform scrollViewTemplate, TextMeshProUGUI privatePublicDescription) { //IL_00f7: 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_0157: Unknown result type (might be due to invalid IL or missing references) //IL_0161: 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_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01c7: Unknown result type (might be due to invalid IL or missing references) //IL_01d2: 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) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_0228: Unknown result type (might be due to invalid IL or missing references) //IL_0235: 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) //IL_026b: Unknown result type (might be due to invalid IL or missing references) //IL_0275: Expected O, but got Unknown Transform obj = panel.transform.Find("Panel"); Image val = ((obj != null) ? ((Component)obj).GetComponent<Image>() : null); _panelTransform = ((val != null) ? ((Graphic)val).rectTransform : null); RectTransform? panelTransform = _panelTransform; object obj2; if (panelTransform == null) { obj2 = null; } else { Transform obj3 = ((Transform)panelTransform).Find("Image"); obj2 = ((obj3 != null) ? ((Component)obj3).GetComponent<Image>() : null); } Image val2 = (Image)obj2; if ((Object)(object)val == (Object)null || (Object)(object)_panelTransform == (Object)null || (Object)(object)val2 == (Object)null) { return; } Transform obj4 = ((Transform)_panelTransform).Find("ResponseButton"); Button val3 = ((obj4 != null) ? ((Component)obj4).GetComponent<Button>() : null); RectTransform val4 = ((val3 != null) ? ((Component)val3).GetComponent<RectTransform>() : null); if ((Object)(object)val3 == (Object)null || (Object)(object)val4 == (Object)null) { return; } Transform obj5 = ((Transform)_panelTransform).Find("NotificationText"); _titleText = ((obj5 != null) ? ((Component)obj5).GetComponent<TextMeshProUGUI>() : null); if ((Object)(object)_titleText == (Object)null) { return; } ((TMP_Text)_titleText).rectTransform.anchoredPosition = new Vector2(-2f, 155f); _descriptionText = Object.Instantiate<TextMeshProUGUI>(privatePublicDescription, ((TMP_Text)_titleText).transform.parent); ((TMP_Text)_descriptionText).rectTransform.anchoredPosition = new Vector2(-3f, -60f); ((TMP_Text)_descriptionText).rectTransform.sizeDelta = new Vector2(400f, ((TMP_Text)_descriptionText).rectTransform.sizeDelta.y); ((TMP_Text)_descriptionText).text = ""; _scrollRect = SetupScrollRect(_panelTransform, scrollViewTemplate, ((Graphic)_titleText).color); if (!((Object)(object)_scrollRect == (Object)null)) { SetupModListSlots(_panelTransform, _scrollRect, ((Graphic)_titleText).color); ((Graphic)