using System; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using BepInEx.Logging; using Microsoft.CodeAnalysis; using On.RoR2; using RiskOfOptions; using RiskOfOptions.Components.Options; using RiskOfOptions.Options; using RoR2; using RoR2.Networking; using RoR2.UI; using TMPro; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.Networking; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("KickMenu")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+b02e883cdd2942fb4c352f00cb39621b0dac5820")] [assembly: AssemblyProduct("KickMenu")] [assembly: AssemblyTitle("KickMenu")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace KickMenu { [BepInPlugin("Bamboooz.KickMenu", "KickMenu", "1.0.4")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class KickMenuPlugin : BaseUnityPlugin { public static class ModConfig { public static ConfigEntry ConfirmKick; public static ConfigEntry BroadcastKick; public static ConfigEntry OpenMenuKey; public static void Init(ConfigFile config) { //IL_004c: 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_006f: Expected O, but got Unknown //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Expected O, but got Unknown //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown ConfirmKick = config.Bind("General", "Confirmation Dialog", true, "If enabled, a confirmation dialog will appear before kicking / banning a player.\n\nDefault: true"); BroadcastKick = config.Bind("General", "Kick / Ban Broadcast", false, "If enabled, a message will be sent to chat when a player is kicked / banned.\n\nDefault: false"); OpenMenuKey = config.Bind("General", "Open Kick Menu Key", new KeyboardShortcut((KeyCode)282, Array.Empty()), "Keybind used to open the player management menu. \n\nDefault: F1"); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(ConfirmKick)); ModSettingsManager.AddOption((BaseOption)new CheckBoxOption(BroadcastKick)); ModSettingsManager.AddOption((BaseOption)new KeyBindOption(OpenMenuKey)); } } internal static ManualLogSource Log; public const string PluginGUID = "Bamboooz.KickMenu"; public const string PluginAuthor = "Bamboooz"; public const string PluginName = "KickMenu"; public const string PluginVersion = "1.0.4"; public void Awake() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_0099: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; try { ModSettingsManager.SetModDescription("A Risk of Rain 2 mod for lobby management. Open the menu using F1."); string directoryName = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); string path = Path.Combine(directoryName, "icon.png"); if (!File.Exists(path)) { path = Path.Combine(Path.GetDirectoryName(directoryName), "icon.png"); } if (File.Exists(path)) { Texture2D val = new Texture2D(2, 2); if (ImageConversion.LoadImage(val, File.ReadAllBytes(path))) { ModSettingsManager.SetModIcon(Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f))); } } ModConfig.Init(((BaseUnityPlugin)this).Config); Menu.Init(); } catch (Exception ex) { Log.LogError((object)("Failed to initialize KickMenu: " + ex.Message)); } } public void Update() { Menu.Update(); } public void OnDestroy() { Menu.Destroy(); } } internal class Menu { [CompilerGenerated] private static class <>O { public static NetworkUserGenericDelegate <0>__OnNetworkUserDiscovered; public static hook_OnDestroy <1>__OnNetworkUserDestroyed; public static Action <2>__RefreshPlayerList; } private static GameObject buttonPrefab; private static GameObject menuPanel; private static Transform contentRoot; private static bool menuOpen = false; private static float time = 0f; private static readonly KeyboardShortcut closeKey = new KeyboardShortcut((KeyCode)27, Array.Empty()); public static void Init() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Expected O, but got Unknown //IL_0049: 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) //IL_0054: Expected O, but got Unknown buttonPrefab = Addressables.LoadAssetAsync((object)"RoR2/Base/UI/GenericMenuButton.prefab").WaitForCompletion(); object obj = <>O.<0>__OnNetworkUserDiscovered; if (obj == null) { NetworkUserGenericDelegate val = OnNetworkUserDiscovered; <>O.<0>__OnNetworkUserDiscovered = val; obj = (object)val; } NetworkUser.onNetworkUserDiscovered += (NetworkUserGenericDelegate)obj; object obj2 = <>O.<1>__OnNetworkUserDestroyed; if (obj2 == null) { hook_OnDestroy val2 = OnNetworkUserDestroyed; <>O.<1>__OnNetworkUserDestroyed = val2; obj2 = (object)val2; } NetworkUser.OnDestroy += (hook_OnDestroy)obj2; } public static void Update() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) KeyboardShortcut value = KickMenuPlugin.ModConfig.OpenMenuKey.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { ToggleMenu(); } if (menuOpen) { value = closeKey; if (((KeyboardShortcut)(ref value)).IsDown()) { menuOpen = false; menuPanel.SetActive(menuOpen); } } time += Time.deltaTime; if (time >= 1f) { if (menuOpen) { RefreshPlayerList(); } time -= 1f; } } public static void Destroy() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown object obj = <>O.<0>__OnNetworkUserDiscovered; if (obj == null) { NetworkUserGenericDelegate val = OnNetworkUserDiscovered; <>O.<0>__OnNetworkUserDiscovered = val; obj = (object)val; } NetworkUser.onNetworkUserDiscovered -= (NetworkUserGenericDelegate)obj; object obj2 = <>O.<1>__OnNetworkUserDestroyed; if (obj2 == null) { hook_OnDestroy val2 = OnNetworkUserDestroyed; <>O.<1>__OnNetworkUserDestroyed = val2; obj2 = (object)val2; } NetworkUser.OnDestroy -= (hook_OnDestroy)obj2; } private static void OnNetworkUserDiscovered(NetworkUser networkUser) { if (!((Object)(object)networkUser == (Object)null) && menuOpen) { RefreshPlayerList(); } } private static void OnNetworkUserDestroyed(orig_OnDestroy orig, NetworkUser self) { orig.Invoke(self); if (menuOpen) { RoR2Application.onNextUpdate += RefreshPlayerList; } } private static void ToggleMenu() { if ((Object)(object)menuPanel == (Object)null) { CreateMenu(); } menuOpen = !menuOpen; menuPanel.SetActive(menuOpen); if (menuOpen) { RefreshPlayerList(); } } private static void RefreshPlayerList() { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown if ((Object)(object)contentRoot == (Object)null) { return; } EventSystem current = EventSystem.current; if (current != null) { current.SetSelectedGameObject((GameObject)null); } foreach (Transform item in contentRoot) { Transform val = item; Object.Destroy((Object)(object)((Component)val).gameObject); } foreach (NetworkUser readOnlyInstances in NetworkUser.readOnlyInstancesList) { CreatePlayerEntry(readOnlyInstances); } } private static void CreateMenu() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0041: 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_0069: Expected O, but got Unknown //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fa: Expected O, but got Unknown GameObject val = new GameObject("KickMenuCanvas"); Canvas val2 = val.AddComponent(); val2.renderMode = (RenderMode)0; val2.sortingOrder = 1000; CanvasScaler val3 = val.AddComponent(); val3.uiScaleMode = (ScaleMode)1; val3.referenceResolution = new Vector2(1920f, 1080f); val.AddComponent(); Object.DontDestroyOnLoad((Object)(object)val); menuPanel = new GameObject("KickMenuPanel"); menuPanel.transform.SetParent(val.transform, false); RectTransform val4 = menuPanel.AddComponent(); val4.sizeDelta = new Vector2(750f, 0f); val4.anchoredPosition = Vector2.zero; Image val5 = menuPanel.AddComponent(); ((Graphic)val5).color = new Color(0f, 0f, 0f, 0.75f); VerticalLayoutGroup val6 = menuPanel.AddComponent(); ((LayoutGroup)val6).padding = new RectOffset(20, 20, 20, 20); ((HorizontalOrVerticalLayoutGroup)val6).spacing = 8f; ((LayoutGroup)val6).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)val6).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val6).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val6).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)val6).childForceExpandHeight = false; ContentSizeFitter val7 = menuPanel.AddComponent(); val7.verticalFit = (FitMode)2; val7.horizontalFit = (FitMode)0; contentRoot = menuPanel.transform; menuPanel.SetActive(false); } private static void CreatePlayerEntry(NetworkUser user) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Expected O, but got Unknown //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Expected O, but got Unknown //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0176: Expected O, but got Unknown GameObject val = new GameObject("PlayerRow"); val.transform.SetParent(contentRoot, false); RectTransform val2 = val.AddComponent(); val2.sizeDelta = new Vector2(700f, 50f); HorizontalLayoutGroup val3 = val.AddComponent(); ((HorizontalOrVerticalLayoutGroup)val3).spacing = 10f; ((LayoutGroup)val3).childAlignment = (TextAnchor)4; ((HorizontalOrVerticalLayoutGroup)val3).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val3).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val3).childForceExpandWidth = false; ((HorizontalOrVerticalLayoutGroup)val3).childForceExpandHeight = false; LayoutElement val4 = val.AddComponent(); val4.preferredHeight = 50f; GameObject val5 = new GameObject("PlayerName"); val5.transform.SetParent(val.transform, false); TextMeshProUGUI val6 = val5.AddComponent(); ((TMP_Text)val6).text = user.userName; ((TMP_Text)val6).fontSize = 20f; ((TMP_Text)val6).alignment = (TextAlignmentOptions)4097; ((Graphic)val6).color = Color.white; LayoutElement val7 = val5.AddComponent(); val7.flexibleWidth = 1f; val7.preferredHeight = 40f; if (Player.IsHost() && !Player.IsHost(user)) { CreateButton(val.transform, "Kick", (UnityAction)delegate { ToggleMenu(); Popup.OpenKickPopup(user); }); CreateButton(val.transform, "Ban", (UnityAction)delegate { ToggleMenu(); Popup.OpenBanPopup(user); }); } ulong userId = Steam.GetSteamId(user); GameObject val8 = CreateButton(val.transform, "Profile", (UnityAction)delegate { ToggleMenu(); Steam.OpenSteamProfile(userId); }); if (userId == 0L && (Object)(object)val8 != (Object)null) { val8.SetActive(false); } } private static GameObject CreateButton(Transform parent, string text, UnityAction action) { //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00b5: Unknown result type (might be due to invalid IL or missing references) if (!Object.op_Implicit((Object)(object)buttonPrefab)) { return null; } GameObject val = Object.Instantiate(buttonPrefab, parent); ((Object)val).name = text + "Button"; LayoutElement val2 = val.AddComponent(); val2.preferredWidth = 100f; val2.preferredHeight = 40f; TextMeshProUGUI componentInChildren = val.GetComponentInChildren(); if (Object.op_Implicit((Object)(object)componentInChildren)) { ((TMP_Text)componentInChildren).text = text; ((TMP_Text)componentInChildren).fontSize = 16f; ((TMP_Text)componentInChildren).alignment = (TextAlignmentOptions)514; } HGButton component = val.GetComponent(); if (Object.op_Implicit((Object)(object)component)) { Navigation navigation = ((Selectable)component).navigation; ((Navigation)(ref navigation)).mode = (Mode)0; ((Selectable)component).navigation = navigation; ((UnityEventBase)((Button)component).onClick).RemoveAllListeners(); ((UnityEvent)((Button)component).onClick).AddListener(action); } return val; } } internal static class Player { public static bool IsHost() { return NetworkServer.active; } public static bool IsHost(NetworkUser networkUser) { if ((Object)(object)networkUser == (Object)null) { return false; } return ((NetworkBehaviour)networkUser).isLocalPlayer; } private static NetworkConnection GetNetworkConnection(NetworkUser networkUser) { if ((Object)(object)networkUser == (Object)null) { return null; } if (!IsHost()) { return null; } if (IsHost(networkUser)) { KickMenuPlugin.Log.LogWarning((object)("Attempted to remove host (" + networkUser.userName + "). Action aborted.")); return null; } return ((NetworkBehaviour)networkUser).connectionToClient; } private static void SendRemoveMessage(string username, string message) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Expected O, but got Unknown if (KickMenuPlugin.ModConfig.BroadcastKick.Value) { SimpleChatMessage val = new SimpleChatMessage(); val.baseToken = "" + message + " player: " + username + ""; Chat.SendBroadcastChat((ChatMessageBase)(object)val); } } public static void RemovePlayer(NetworkUser networkUser, string message, Action action) { if ((Object)(object)networkUser == (Object)null) { KickMenuPlugin.Log.LogWarning((object)"No connection found for player: "); return; } string userName = networkUser.userName; NetworkConnection networkConnection = GetNetworkConnection(networkUser); if (networkConnection == null) { KickMenuPlugin.Log.LogWarning((object)("No connection found for player: " + userName)); return; } int connectionId = networkConnection.connectionId; if (!networkConnection.isReady) { KickMenuPlugin.Log.LogWarning((object)$"Client connection for {userName} is not ready (Connection ID: {connectionId}). Still attempting removal."); } try { KickMenuPlugin.Log.LogInfo((object)$"Removing player {userName} (Connection ID: {connectionId})..."); action?.Invoke(networkConnection); try { networkConnection.Disconnect(); } catch (Exception ex) { KickMenuPlugin.Log.LogDebug((object)("client.Disconnect() fallback for " + userName + " threw (connection was likely already closed): " + ex.Message)); } KickMenuPlugin.Log.LogInfo((object)$"{message} player {userName} (Connection ID: {connectionId})"); SendRemoveMessage(userName, message); } catch (Exception arg) { KickMenuPlugin.Log.LogError((object)$"Failed to remove player {userName} (Connection ID: {connectionId}): {arg}"); } } public static void Kick(NetworkUser networkUser) { RemovePlayer(networkUser, "Kicked", delegate(NetworkConnection client) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown SimpleLocalizedKickReason val = new SimpleLocalizedKickReason("KICK_REASON_KICK", Array.Empty()); NetworkManagerSystem.singleton.ServerKickClient(client, (BaseKickReason)(object)val); }); } public static void Ban(NetworkUser networkUser) { RemovePlayer(networkUser, "Banned", delegate(NetworkConnection client) { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown NetworkManagerSystem.singleton.ServerBanClient(client); SimpleLocalizedKickReason val = new SimpleLocalizedKickReason("KICK_REASON_KICK", Array.Empty()); NetworkManagerSystem.singleton.ServerKickClient(client, (BaseKickReason)(object)val); }); } } internal static class Popup { private static void OnButtonClicked(NetworkUser networkUser, string message, Action action) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0098: Expected O, but got Unknown //IL_0108: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Expected O, but got Unknown if ((Object)(object)networkUser == (Object)null || !Player.IsHost()) { return; } if (!KickMenuPlugin.ModConfig.ConfirmKick.Value) { action(networkUser); return; } SimpleDialogBox dialog = SimpleDialogBox.Create((MPEventSystem)null); ((Component)dialog).gameObject.AddComponent().escapePressed.AddListener((UnityAction)delegate { if (Object.op_Implicit((Object)(object)dialog) && Object.op_Implicit((Object)(object)dialog.rootObject)) { Object.Destroy((Object)(object)dialog.rootObject); } }); ((TMP_Text)dialog.headerLabel).text = "Confirm " + message; ((TMP_Text)dialog.descriptionLabel).text = "Are you sure you want to " + message + " " + networkUser.userName + "?"; dialog.AddActionButton((UnityAction)delegate { action(networkUser); }, "Yes", true, Array.Empty()); dialog.AddCancelButton("Cancel", Array.Empty()); } public static void OpenKickPopup(NetworkUser networkUser) { OnButtonClicked(networkUser, "kick", Player.Kick); } public static void OpenBanPopup(NetworkUser networkUser) { OnButtonClicked(networkUser, "ban", Player.Ban); } } internal static class Steam { public static ulong GetSteamId(NetworkUser networkUser) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001b: 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) if ((Object)(object)networkUser == (Object)null) { return 0uL; } NetworkUserId network_id = networkUser.Network_id; PlatformID steamId = ((NetworkUserId)(ref network_id)).steamId; return Convert.ToUInt64(((PlatformID)(ref steamId)).value); } private static string OpenSteamProfileCommand(ulong id) { if (id == 0) { return null; } return $"steam://openurl/https://steamcommunity.com/profiles/{id}"; } public static void OpenSteamProfile(ulong id) { if (id == 0) { return; } string text = OpenSteamProfileCommand(id); if (text == null) { return; } try { Process.Start(new ProcessStartInfo { FileName = text, UseShellExecute = true }); } catch (Exception ex) { KickMenuPlugin.Log.LogError((object)("Failed to open Steam profile: " + ex.Message)); } } } }