using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Text; using ACNPlus.ChatBubble; using ACNPlus.MinimapReplacement; using ACNPlus.Phone; using BepInEx; using BepInEx.Configuration; using BombRushMP.Common.Networking; using BombRushMP.Common.Packets; using BombRushMP.Plugin; using BombRushMP.Plugin.Gamemodes; using CommonAPI.Phone; using HarmonyLib; using Reptile; using Reptile.Phone; using TMPro; using UnityEngine; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyCompany("ACNPlus")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("ACNPlus")] [assembly: AssemblyTitle("ACNPlus")] [assembly: AssemblyVersion("1.0.0.0")] namespace ACNPlus { public enum PrivateLobbyType { Normal, FriendsOnly, CrewOnly, Solo } [BepInPlugin("com.acn.acnplus", "ACNPlus", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class ACNPlusPlugin : BaseUnityPlugin { private static Harmony _harmony; private static string _acnPlusFolder; private static string _friendsListPath; private static string _blocklistPath; private static HashSet _friendsList = new HashSet(); private static HashSet _blocklist = new HashSet(); public static ConfigEntry BlockInvites; public static ConfigEntry BlockInvitesChatMessage; public static ConfigEntry BlockPlayersFromJoiningLobby; public static ConfigEntry FriendsOnlyLobby; public static ConfigEntry CrewOnlyLobby; public static ConfigEntry SeeWhenSomethingIsBlocked; public static ConfigEntry ChangeMiniMapToPNG; public static ConfigEntry CatWizardMiniMap; public static ConfigEntry TransparentLobbyBanner; public static ConfigEntry TransparentLobbyNameBG; public static ConfigEntry HideLobbySettings; public static ConfigEntry ShowChatBubbles; public static ConfigEntry ChatBubbleColor; public static ConfigEntry PrivateLobbyTypeConfig; private static string _texturesFolder; private static string _pluginFolder; private void Awake() { //IL_01c6: Unknown result type (might be due to invalid IL or missing references) //IL_01d0: Expected O, but got Unknown //IL_029f: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Expected O, but got Unknown BlockInvites = ((BaseUnityPlugin)this).Config.Bind("Gamemodes", "BlockInvites", false, "Automatically decline all lobby invites"); BlockInvitesChatMessage = ((BaseUnityPlugin)this).Config.Bind("Gamemodes", "BlockInvitesChatMessage", false, "Show a chat message when an invite is blocked"); BlockPlayersFromJoiningLobby = ((BaseUnityPlugin)this).Config.Bind("Gamemodes", "BlockPlayersFromJoiningLobby", false, "Automatically kick players who join your lobby (only works if you are the host)"); FriendsOnlyLobby = ((BaseUnityPlugin)this).Config.Bind("Gamemodes", "FriendsOnlyLobby", false, "Automatically kick players who aren't on your friends list (only works if you are the host)"); CrewOnlyLobby = ((BaseUnityPlugin)this).Config.Bind("Gamemodes", "CrewOnlyLobby", false, "Automatically kick players who aren't in your crew (only works if you are the host)"); SeeWhenSomethingIsBlocked = ((BaseUnityPlugin)this).Config.Bind("Blocked Users", "SeeWhenSomethingIsBlocked", true, "Show chat messages when blocked users send messages, invites, or get kicked"); ChangeMiniMapToPNG = ((BaseUnityPlugin)this).Config.Bind("Minimap", "ChangeMiniMapToPNG", false, "Replace the minimap with a custom image from ACNPlus/Textures/MiniMapPNG.png"); CatWizardMiniMap = ((BaseUnityPlugin)this).Config.Bind("Minimap", "CatWizardMiniMap", false, "An example of a custom mini map (uses backendtextures/CatMiniMap.png)"); TransparentLobbyBanner = ((BaseUnityPlugin)this).Config.Bind("Lobby Banners", "TransparentLobbyBanner", false, "Use transparent image for lobby title background (from mod folder backendtextures/transparent.png)"); TransparentLobbyNameBG = ((BaseUnityPlugin)this).Config.Bind("Lobby Banners", "TransparentLobbyNameBG", false, "Use transparent image for name row background in both normal and team mode (from mod folder backendtextures/transparent.png)"); HideLobbySettings = ((BaseUnityPlugin)this).Config.Bind("Lobby UI", "HideLobbySettings", false, "Hide the game settings text beside the lobby UI when in a lobby"); ShowChatBubbles = ((BaseUnityPlugin)this).Config.Bind("Chat", "ShowChatBubbles", false, "Show chat messages above players' heads for 5 seconds when they send a message"); ChatBubbleColor = ((BaseUnityPlugin)this).Config.Bind("Chat", "ChatBubbleColor", "FFFFFF", "Hex color for chat bubble text (e.g. FF0000 for red, FFFFFF for white)"); PrivateLobbyTypeConfig = ((BaseUnityPlugin)this).Config.Bind("Lobby Settings", "PrivateLobbyType", 0, new ConfigDescription("Private lobby type: 0=Normal, 1=FriendsOnly, 2=CrewOnly, 3=Solo", (AcceptableValueBase)(object)new AcceptableValueRange(0, 3), Array.Empty())); ApplyPrivateLobbyType(GetPrivateLobbyType()); _pluginFolder = Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location); _acnPlusFolder = Path.Combine(Paths.BepInExRootPath, "ACNPlus"); _texturesFolder = Path.Combine(_acnPlusFolder, "Textures"); _friendsListPath = Path.Combine(_acnPlusFolder, "FriendsList.txt"); _blocklistPath = Path.Combine(_acnPlusFolder, "blocklist.txt"); Directory.CreateDirectory(_acnPlusFolder); Directory.CreateDirectory(_texturesFolder); if (!File.Exists(_friendsListPath)) { File.WriteAllText(_friendsListPath, ""); } if (!File.Exists(_blocklistPath)) { File.WriteAllText(_blocklistPath, ""); } LoadFriendsList(); LoadBlocklist(); _harmony = new Harmony("com.acn.acnplus"); _harmony.PatchAll(); ACNPlus.ChatBubble.ChatBubble.InitColorCache(); AppACNPlus.Initialize(); } private void OnDestroy() { Harmony harmony = _harmony; if (harmony != null) { harmony.UnpatchSelf(); } } private static void LoadFriendsList() { _friendsList.Clear(); if (!File.Exists(_friendsListPath)) { return; } string[] array = File.ReadAllLines(_friendsListPath); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (!string.IsNullOrEmpty(text)) { _friendsList.Add(text); } } } private static void LoadBlocklist() { _blocklist.Clear(); if (!File.Exists(_blocklistPath)) { return; } string[] array = File.ReadAllLines(_blocklistPath); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (!string.IsNullOrEmpty(text)) { _blocklist.Add(text); } } } public static HashSet GetFriendsList() { return _friendsList; } public static string GetFriendsFolder() { return _acnPlusFolder; } public static string GetTexturesFolder() { return _texturesFolder; } public static HashSet GetBlocklist() { return _blocklist; } public static string GetBlocklistPath() { return _blocklistPath; } public static void ReloadBlocklist() { LoadBlocklist(); } public static string GetPluginFolder() { return _pluginFolder; } public static string GetBackendTexturesPath(string filename) { return Path.Combine(_pluginFolder, "backendtextures", filename); } public static Color GetChatBubbleColor() { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) string text = ChatBubbleColor?.Value?.Trim().TrimStart(new char[1] { '#' }) ?? "FFFFFF"; if (text.Length == 6) { text += "FF"; } Color result = default(Color); if (ColorUtility.TryParseHtmlString("#" + text, ref result)) { return result; } return Color.white; } public static void ShowFriendGuideInChat() { ChatUI instance = ChatUI.Instance; if (instance != null) { instance.AddMessage("To add a friend, have them tell you their id, which they get from the \"/AddMe\" command."); } ChatUI instance2 = ChatUI.Instance; if (instance2 != null) { instance2.AddMessage("Then you take that ID and use it in \"/AddFriend\". Example: \"/AddFriend 99\"."); } } public static void RunChatCommand(string command) { if (!string.IsNullOrEmpty(command)) { ChatUI instance = ChatUI.Instance; if (!((Object)(object)instance == (Object)null)) { ((object)instance).GetType().GetMethod("ProcessLocalCommand", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, new Type[1] { typeof(string) }, null)?.Invoke(instance, new object[1] { command }); } } } public static PrivateLobbyType GetPrivateLobbyType() { int num = PrivateLobbyTypeConfig?.Value ?? 0; if (num < 0 || num > 3) { num = 0; } return (PrivateLobbyType)num; } public static void SetPrivateLobbyType(PrivateLobbyType type) { if (PrivateLobbyTypeConfig != null) { PrivateLobbyTypeConfig.Value = (int)type; ApplyPrivateLobbyType(type); } } public static void ApplyPrivateLobbyType(PrivateLobbyType type) { switch (type) { case PrivateLobbyType.Normal: if (BlockPlayersFromJoiningLobby != null) { BlockPlayersFromJoiningLobby.Value = false; } if (FriendsOnlyLobby != null) { FriendsOnlyLobby.Value = false; } if (CrewOnlyLobby != null) { CrewOnlyLobby.Value = false; } break; case PrivateLobbyType.FriendsOnly: if (BlockPlayersFromJoiningLobby != null) { BlockPlayersFromJoiningLobby.Value = false; } if (FriendsOnlyLobby != null) { FriendsOnlyLobby.Value = true; } if (CrewOnlyLobby != null) { CrewOnlyLobby.Value = false; } break; case PrivateLobbyType.CrewOnly: if (BlockPlayersFromJoiningLobby != null) { BlockPlayersFromJoiningLobby.Value = false; } if (FriendsOnlyLobby != null) { FriendsOnlyLobby.Value = false; } if (CrewOnlyLobby != null) { CrewOnlyLobby.Value = true; } break; case PrivateLobbyType.Solo: if (BlockPlayersFromJoiningLobby != null) { BlockPlayersFromJoiningLobby.Value = true; } if (FriendsOnlyLobby != null) { FriendsOnlyLobby.Value = false; } if (CrewOnlyLobby != null) { CrewOnlyLobby.Value = false; } break; } } } public static class PluginInfo { public const string PLUGIN_GUID = "com.acn.acnplus"; public const string PLUGIN_NAME = "ACNPlus"; public const string PLUGIN_VERSION = "1.0.0"; } public static class MyPluginInfo { public const string PLUGIN_GUID = "ACNPlus"; public const string PLUGIN_NAME = "ACNPlus"; public const string PLUGIN_VERSION = "1.0.0"; } } namespace ACNPlus.Phone { public class AppACNPlus : CustomApp { public static void Initialize() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Expected O, but got Unknown //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) Sprite val = null; string backendTexturesPath = ACNPlusPlugin.GetBackendTexturesPath("AppIcon.png"); if (!string.IsNullOrEmpty(backendTexturesPath) && File.Exists(backendTexturesPath)) { try { byte[] array = File.ReadAllBytes(backendTexturesPath); Texture2D val2 = new Texture2D(2, 2); if (ImageConversion.LoadImage(val2, array)) { ((Texture)val2).wrapMode = (TextureWrapMode)1; ((Texture)val2).filterMode = (FilterMode)1; val2.Apply(); val = Sprite.Create(val2, new Rect(0f, 0f, (float)((Texture)val2).width, (float)((Texture)val2).height), new Vector2(0.5f, 0.5f)); } } catch { } } if ((Object)(object)val != (Object)null) { PhoneAPI.RegisterApp("ACNPlus", val); } else { PhoneAPI.RegisterApp("ACNPlus", (Sprite)null); } } public override void OnAppInit() { ((CustomApp)this).OnAppInit(); ((CustomApp)this).CreateIconlessTitleBar("ACNPlus", 80f); base.ScrollView = PhoneScrollView.Create((CustomApp)(object)this, 275f, 1600f); PopulateButtons(); } public override void OnAppEnable() { ((App)this).OnAppEnable(); PopulateButtons(); } private void PopulateButtons() { base.ScrollView.RemoveAllButtons(); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Friends List"); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, new Action(ShowFriendsListMenu)); base.ScrollView.AddButton((PhoneButton)(object)val); SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Crews"); ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, new Action(ShowCrewsMenu)); base.ScrollView.AddButton((PhoneButton)(object)val2); SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Players In This Stage"); ((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, new Action(ShowPlayersInStageView)); base.ScrollView.AddButton((PhoneButton)(object)val3); SimplePhoneButton val4 = PhoneUIUtility.CreateSimpleButton("Lobby Settings"); ((PhoneButton)val4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val4).OnConfirm, new Action(ShowLobbySettingsView)); base.ScrollView.AddButton((PhoneButton)(object)val4); SimplePhoneButton val5 = PhoneUIUtility.CreateSimpleButton("Chat Settings"); ((PhoneButton)val5).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val5).OnConfirm, new Action(ShowChatSettingsView)); base.ScrollView.AddButton((PhoneButton)(object)val5); SimplePhoneButton val6 = PhoneUIUtility.CreateSimpleButton("Customize"); ((PhoneButton)val6).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val6).OnConfirm, new Action(ShowCustomizeMenu)); base.ScrollView.AddButton((PhoneButton)(object)val6); SimplePhoneButton val7 = PhoneUIUtility.CreateSimpleButton("Blocked List"); ((PhoneButton)val7).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val7).OnConfirm, new Action(ShowBlockedListView)); base.ScrollView.AddButton((PhoneButton)(object)val7); SimplePhoneButton val8 = PhoneUIUtility.CreateSimpleButton("Extra"); ((PhoneButton)val8).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val8).OnConfirm, new Action(ShowExtraMenu)); base.ScrollView.AddButton((PhoneButton)(object)val8); } private void ShowExtraMenu() { base.ScrollView.RemoveAllButtons(); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Reset Props"); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { PropDisguiseController instance = PropDisguiseController.Instance; if ((Object)(object)instance != (Object)null) { instance.FreezeProps(); instance.UnfreezeProps(); } }); base.ScrollView.AddButton((PhoneButton)(object)val); SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Back"); ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, new Action(PopulateButtons)); base.ScrollView.AddButton((PhoneButton)(object)val2); } private void ShowCrewsMenu() { base.ScrollView.RemoveAllButtons(); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Crews In This Stage"); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { ACNPlusPlugin.RunChatCommand("/crews"); }); base.ScrollView.AddButton((PhoneButton)(object)val); SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("My Crew"); ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate { ACNPlusPlugin.RunChatCommand("/mycrew"); }); base.ScrollView.AddButton((PhoneButton)(object)val2); SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Back"); ((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, new Action(PopulateButtons)); base.ScrollView.AddButton((PhoneButton)(object)val3); } private void ShowBlockedListView() { base.ScrollView.RemoveAllButtons(); HashSet blocklist = ACNPlusPlugin.GetBlocklist(); if (blocklist.Count == 0) { SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Your blocklist is empty."); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { }); base.ScrollView.AddButton((PhoneButton)(object)val); } else { List list = new List(blocklist); list.Sort(StringComparer.OrdinalIgnoreCase); foreach (string item in list) { SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton(item); string capturedName = item; ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate { ShowManageBlockedPlayerView(capturedName, ShowBlockedListView); }); base.ScrollView.AddButton((PhoneButton)(object)val2); } } SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Back"); ((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, new Action(PopulateButtons)); base.ScrollView.AddButton((PhoneButton)(object)val3); } private void ShowManageBlockedPlayerView(string playerName, Action backAction) { base.ScrollView.RemoveAllButtons(); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton(playerName); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { }); base.ScrollView.AddButton((PhoneButton)(object)val); SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Unblock"); ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate { HashSet blocklist = ACNPlusPlugin.GetBlocklist(); if (blocklist.Remove(playerName)) { try { File.WriteAllLines(ACNPlusPlugin.GetBlocklistPath(), blocklist); ACNPlusPlugin.ReloadBlocklist(); } catch { } } backAction(); }); base.ScrollView.AddButton((PhoneButton)(object)val2); SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Back"); ((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, backAction); base.ScrollView.AddButton((PhoneButton)(object)val3); } private void ShowCustomizeMenu() { base.ScrollView.RemoveAllButtons(); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Mini Map"); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, new Action(ShowMiniMapMenu)); base.ScrollView.AddButton((PhoneButton)(object)val); SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Lobby"); ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, new Action(ShowLobbyMenu)); base.ScrollView.AddButton((PhoneButton)(object)val2); SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Back"); ((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, new Action(PopulateButtons)); base.ScrollView.AddButton((PhoneButton)(object)val3); } private void ShowLobbyMenu() { base.ScrollView.RemoveAllButtons(); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Transparent Lobby: " + (ACNPlusPlugin.TransparentLobbyBanner.Value ? "On" : "Off")); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { bool value = !ACNPlusPlugin.TransparentLobbyBanner.Value; ACNPlusPlugin.TransparentLobbyBanner.Value = value; ACNPlusPlugin.TransparentLobbyNameBG.Value = value; ShowLobbyMenu(); }); base.ScrollView.AddButton((PhoneButton)(object)val); SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Back"); ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, new Action(ShowCustomizeMenu)); base.ScrollView.AddButton((PhoneButton)(object)val2); } private void ShowMiniMapMenu() { base.ScrollView.RemoveAllButtons(); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Custom Mini Map Image: " + (ACNPlusPlugin.ChangeMiniMapToPNG.Value ? "On" : "Off")); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { ACNPlusPlugin.ChangeMiniMapToPNG.Value = !ACNPlusPlugin.ChangeMiniMapToPNG.Value; ShowMiniMapMenu(); }); base.ScrollView.AddButton((PhoneButton)(object)val); SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Cat Wizard Mini Map: " + (ACNPlusPlugin.CatWizardMiniMap.Value ? "On" : "Off")); ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate { ACNPlusPlugin.CatWizardMiniMap.Value = !ACNPlusPlugin.CatWizardMiniMap.Value; ShowMiniMapMenu(); }); base.ScrollView.AddButton((PhoneButton)(object)val2); SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Back"); ((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, new Action(ShowCustomizeMenu)); base.ScrollView.AddButton((PhoneButton)(object)val3); } private void ShowChatSettingsView() { base.ScrollView.RemoveAllButtons(); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Chat Bubbles: " + (ACNPlusPlugin.ShowChatBubbles.Value ? "On" : "Off")); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { ACNPlusPlugin.ShowChatBubbles.Value = !ACNPlusPlugin.ShowChatBubbles.Value; ShowChatSettingsView(); }); base.ScrollView.AddButton((PhoneButton)(object)val); SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("See When Something Is Blocked: " + (ACNPlusPlugin.SeeWhenSomethingIsBlocked.Value ? "On" : "Off")); ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate { ACNPlusPlugin.SeeWhenSomethingIsBlocked.Value = !ACNPlusPlugin.SeeWhenSomethingIsBlocked.Value; ShowChatSettingsView(); }); base.ScrollView.AddButton((PhoneButton)(object)val2); SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("See Block Invites: " + (ACNPlusPlugin.BlockInvitesChatMessage.Value ? "On" : "Off")); ((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, (Action)delegate { ACNPlusPlugin.BlockInvitesChatMessage.Value = !ACNPlusPlugin.BlockInvitesChatMessage.Value; ShowChatSettingsView(); }); base.ScrollView.AddButton((PhoneButton)(object)val3); SimplePhoneButton val4 = PhoneUIUtility.CreateSimpleButton("Back"); ((PhoneButton)val4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val4).OnConfirm, new Action(PopulateButtons)); base.ScrollView.AddButton((PhoneButton)(object)val4); } private void ShowLobbySettingsView() { base.ScrollView.RemoveAllButtons(); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Private Lobby Type: " + GetPrivateLobbyTypeLabel()); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { CyclePrivateLobbyType(); ShowLobbySettingsView(); }); base.ScrollView.AddButton((PhoneButton)(object)val); SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Block Invites: " + (ACNPlusPlugin.BlockInvites.Value ? "On" : "Off")); ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate { ACNPlusPlugin.BlockInvites.Value = !ACNPlusPlugin.BlockInvites.Value; ShowLobbySettingsView(); }); base.ScrollView.AddButton((PhoneButton)(object)val2); SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Back"); ((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, new Action(PopulateButtons)); base.ScrollView.AddButton((PhoneButton)(object)val3); } private static string GetPrivateLobbyTypeLabel() { return ACNPlusPlugin.GetPrivateLobbyType() switch { PrivateLobbyType.Normal => "Normal", PrivateLobbyType.FriendsOnly => "Friends Only", PrivateLobbyType.CrewOnly => "Crew Only", PrivateLobbyType.Solo => "Solo", _ => "Normal", }; } private static void CyclePrivateLobbyType() { ACNPlusPlugin.SetPrivateLobbyType(ACNPlusPlugin.GetPrivateLobbyType() switch { PrivateLobbyType.Normal => PrivateLobbyType.FriendsOnly, PrivateLobbyType.FriendsOnly => PrivateLobbyType.CrewOnly, PrivateLobbyType.CrewOnly => PrivateLobbyType.Solo, PrivateLobbyType.Solo => PrivateLobbyType.Normal, _ => PrivateLobbyType.Normal, }); } private void ShowPlayersInStageView() { base.ScrollView.RemoveAllButtons(); ClientController instance = ClientController.Instance; if ((Object)(object)instance == (Object)null) { SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Not connected to server."); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { }); base.ScrollView.AddButton((PhoneButton)(object)val); } else { int? num = null; if (instance.Players.TryGetValue(instance.LocalID, out var value) && value?.ClientState != null) { num = value.ClientState.Stage; } List list = new List(); foreach (MPPlayer value2 in instance.Players.Values) { if (value2?.ClientState != null && value2.ClientId != instance.LocalID && (!num.HasValue || value2.ClientState.Stage == num.Value)) { string name = value2.ClientState.Name; if (!string.IsNullOrEmpty(name)) { list.Add(name); } } } if (list.Count == 0) { SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("No players in this stage."); ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate { }); base.ScrollView.AddButton((PhoneButton)(object)val2); } else { foreach (string item in list) { SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton(item); string capturedName = item; ((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, (Action)delegate { ShowManagePlayerView(capturedName, ShowPlayersInStageView); }); base.ScrollView.AddButton((PhoneButton)(object)val3); } } } SimplePhoneButton val4 = PhoneUIUtility.CreateSimpleButton("Back"); ((PhoneButton)val4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val4).OnConfirm, new Action(PopulateButtons)); base.ScrollView.AddButton((PhoneButton)(object)val4); } private void ShowManagePlayerView(string playerName, Action backAction) { base.ScrollView.RemoveAllButtons(); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton(playerName); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { }); base.ScrollView.AddButton((PhoneButton)(object)val); SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Block Player"); ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate { BlockPlayerOnlyAndGoBack(playerName, backAction); }); base.ScrollView.AddButton((PhoneButton)(object)val2); SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Back"); ((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, backAction); base.ScrollView.AddButton((PhoneButton)(object)val3); } private void BlockPlayerOnlyAndGoBack(string playerName, Action backAction) { ClientController instance = ClientController.Instance; string text = null; if (instance?.Players != null && instance.Players.TryGetValue(instance.LocalID, out var value) && value?.ClientState != null) { text = value.ClientState.Name; } if (text != null && playerName == text) { backAction(); return; } try { if (!ACNPlusPlugin.GetBlocklist().Contains(playerName)) { File.AppendAllText(ACNPlusPlugin.GetBlocklistPath(), playerName + Environment.NewLine); ACNPlusPlugin.ReloadBlocklist(); } } catch { } backAction(); } private void ShowFriendsListMenu() { base.ScrollView.RemoveAllButtons(); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("In This Stage"); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, new Action(ShowFriendsInStageView)); base.ScrollView.AddButton((PhoneButton)(object)val); SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Full List"); ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, new Action(ShowFullFriendsListView)); base.ScrollView.AddButton((PhoneButton)(object)val2); SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Add Friend"); ((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, (Action)delegate { ACNPlusPlugin.ShowFriendGuideInChat(); }); base.ScrollView.AddButton((PhoneButton)(object)val3); SimplePhoneButton val4 = PhoneUIUtility.CreateSimpleButton("Back"); ((PhoneButton)val4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val4).OnConfirm, new Action(PopulateButtons)); base.ScrollView.AddButton((PhoneButton)(object)val4); } private void ShowFriendsInStageView() { base.ScrollView.RemoveAllButtons(); HashSet friendsList = ACNPlusPlugin.GetFriendsList(); ClientController instance = ClientController.Instance; if (friendsList.Count == 0) { SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Your friends list is empty."); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { }); base.ScrollView.AddButton((PhoneButton)(object)val); } else if ((Object)(object)instance == (Object)null) { SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Not connected to server."); ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate { }); base.ScrollView.AddButton((PhoneButton)(object)val2); } else { ClientLobbyManager clientLobbyManager = instance.ClientLobbyManager; List list = new List(); List list2 = new List(); foreach (MPPlayer value in instance.Players.Values) { if (value.ClientState == null) { continue; } string name = value.ClientState.Name; if (!friendsList.Contains(name)) { continue; } list.Add(name); foreach (Lobby value2 in clientLobbyManager.Lobbies.Values) { if (value2.LobbyState.Players.ContainsKey(value.ClientId)) { if (value2.LobbyState.InGame) { list2.Add(name); } break; } } } if (list.Count > 0) { HashSet hashSet = new HashSet(list2); foreach (string item in list) { SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton(hashSet.Contains(item) ? (item + " (in game)") : item); string capturedName = item; ((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, (Action)delegate { ShowManageFriendView(capturedName, ShowFriendsInStageView); }); base.ScrollView.AddButton((PhoneButton)(object)val3); } } else { SimplePhoneButton val4 = PhoneUIUtility.CreateSimpleButton("No friends in this stage."); ((PhoneButton)val4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val4).OnConfirm, (Action)delegate { }); base.ScrollView.AddButton((PhoneButton)(object)val4); } } SimplePhoneButton val5 = PhoneUIUtility.CreateSimpleButton("Back"); ((PhoneButton)val5).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val5).OnConfirm, new Action(ShowFriendsListMenu)); base.ScrollView.AddButton((PhoneButton)(object)val5); } private void ShowFullFriendsListView() { base.ScrollView.RemoveAllButtons(); HashSet friendsList = ACNPlusPlugin.GetFriendsList(); if (friendsList.Count == 0) { SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton("Your friends list is empty."); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { }); base.ScrollView.AddButton((PhoneButton)(object)val); } else { List list = new List(friendsList); for (int i = 0; i < list.Count; i++) { string text = list[i]; SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton($"{i + 1}. {text}"); string capturedName = text; ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate { ShowManageFriendView(capturedName, ShowFullFriendsListView); }); base.ScrollView.AddButton((PhoneButton)(object)val2); } } SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Back"); ((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, new Action(ShowFriendsListMenu)); base.ScrollView.AddButton((PhoneButton)(object)val3); } private void ShowManageFriendView(string friendName, Action backAction) { base.ScrollView.RemoveAllButtons(); SimplePhoneButton val = PhoneUIUtility.CreateSimpleButton(friendName); ((PhoneButton)val).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val).OnConfirm, (Action)delegate { }); base.ScrollView.AddButton((PhoneButton)(object)val); SimplePhoneButton val2 = PhoneUIUtility.CreateSimpleButton("Remove Friend"); ((PhoneButton)val2).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val2).OnConfirm, (Action)delegate { RemoveFriendAndGoBack(friendName, backAction); }); base.ScrollView.AddButton((PhoneButton)(object)val2); SimplePhoneButton val3 = PhoneUIUtility.CreateSimpleButton("Block Player"); ((PhoneButton)val3).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val3).OnConfirm, (Action)delegate { BlockPlayerAndGoBack(friendName, backAction); }); base.ScrollView.AddButton((PhoneButton)(object)val3); SimplePhoneButton val4 = PhoneUIUtility.CreateSimpleButton("Back"); ((PhoneButton)val4).OnConfirm = (Action)Delegate.Combine(((PhoneButton)val4).OnConfirm, backAction); base.ScrollView.AddButton((PhoneButton)(object)val4); } private void RemoveFriendAndGoBack(string friendName, Action backAction) { HashSet friendsList = ACNPlusPlugin.GetFriendsList(); string path = Path.Combine(ACNPlusPlugin.GetFriendsFolder(), "FriendsList.txt"); try { friendsList.Remove(friendName); File.WriteAllLines(path, friendsList); } catch { } backAction(); } private void BlockPlayerAndGoBack(string friendName, Action backAction) { HashSet friendsList = ACNPlusPlugin.GetFriendsList(); string path = Path.Combine(ACNPlusPlugin.GetFriendsFolder(), "FriendsList.txt"); try { friendsList.Remove(friendName); File.WriteAllLines(path, friendsList); if (!ACNPlusPlugin.GetBlocklist().Contains(friendName)) { File.AppendAllText(ACNPlusPlugin.GetBlocklistPath(), friendName + Environment.NewLine); ACNPlusPlugin.ReloadBlocklist(); } } catch { } backAction(); } } } namespace ACNPlus.Patches { [HarmonyPatch(typeof(ChatUI), "HandleServerMessage")] public class BlocklistChatPatch { [HarmonyPrefix] public static bool HandleServerMessage_Prefix(ServerChat serverMessage) { if (serverMessage == null || string.IsNullOrEmpty(serverMessage.Author)) { return true; } if (ACNPlusPlugin.GetBlocklist().Contains(serverMessage.Author)) { if (ACNPlusPlugin.SeeWhenSomethingIsBlocked.Value) { ChatUI instance = ChatUI.Instance; if (instance != null) { instance.AddMessage("Blocked message from " + serverMessage.Author + ""); } } return false; } return true; } } [HarmonyPatch(typeof(ChatUI), "HandleServerMessage")] public static class ChatBubblePatches { private static readonly Dictionary _bubbles = new Dictionary(); private static readonly Dictionary _nameToId = new Dictionary(); [HarmonyPostfix] public static void HandleServerMessage_Postfix(ServerChat serverMessage) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (!ACNPlusPlugin.ShowChatBubbles.Value || serverMessage == null || (int)serverMessage.MessageType != 0 || string.IsNullOrEmpty(serverMessage.Author)) { return; } ClientController instance = ClientController.Instance; if ((Object)(object)instance == (Object)null) { return; } MPPlayer value = null; if (_nameToId.TryGetValue(serverMessage.Author, out var value2)) { instance.Players.TryGetValue(value2, out value); if (value?.ClientState?.Name != serverMessage.Author) { _nameToId.Remove(serverMessage.Author); value = null; } } if (value == null) { foreach (MPPlayer value3 in instance.Players.Values) { if (value3.ClientState != null && value3.ClientState.Name == serverMessage.Author) { value = value3; _nameToId[serverMessage.Author] = value3.ClientId; break; } } } if (value != null && !((Object)(object)value.Player == (Object)null) && !value.Local) { ACNPlus.ChatBubble.ChatBubble orCreateBubble = GetOrCreateBubble(value); if (!((Object)(object)orCreateBubble == (Object)null)) { orCreateBubble.ShowMessage(serverMessage.Author + ": " + serverMessage.Message); } } } private static ACNPlus.ChatBubble.ChatBubble GetOrCreateBubble(MPPlayer player) { if (_bubbles.TryGetValue(player.ClientId, out var value)) { if (Object.op_Implicit((Object)(object)value)) { return value; } _bubbles.Remove(player.ClientId); } ACNPlus.ChatBubble.ChatBubble chatBubble = ACNPlus.ChatBubble.ChatBubble.Create(((Component)player.Player).transform); _bubbles[player.ClientId] = chatBubble; return chatBubble; } public static void RemoveBubble(ushort clientId) { if (_bubbles.TryGetValue(clientId, out var value)) { if (Object.op_Implicit((Object)(object)value)) { Object.Destroy((Object)(object)((Component)value).gameObject); } _bubbles.Remove(clientId); } List list = new List(); foreach (KeyValuePair item in _nameToId) { if (item.Value == clientId) { list.Add(item.Key); } } foreach (string item2 in list) { _nameToId.Remove(item2); } } } [HarmonyPatch(typeof(MPPlayer), "Delete")] public static class MPPlayerDeletePatch { [HarmonyPostfix] public static void Delete_Postfix(MPPlayer __instance) { ChatBubblePatches.RemoveBubble(__instance.ClientId); } } [HarmonyPatch(typeof(ChatUI), "ProcessLocalCommand")] public static class ChatCommandPatch { private static bool Prefix(ChatUI __instance, string message) { if (string.IsNullOrEmpty(message)) { return true; } string[] array = message.Split(new char[1] { ' ' }); switch (array[0].ToLower()) { case "/addme": HandleAddMeCommand(); return false; case "/addfriend": if (array.Length < 2) { ChatUI instance4 = ChatUI.Instance; if (instance4 != null) { instance4.AddMessage("Usage: /addfriend "); } return false; } HandleAddFriendCommand(array[1]); return false; case "/friendslist": HandleFriendsListCommand(); return false; case "/removefriend": if (array.Length < 2) { ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage("Usage: /removefriend "); } return false; } HandleRemoveFriendCommand(array[1]); return false; case "/friends": HandleFriendsCommand(); return false; case "/playershelp": HandlePlayersHelpCommand(); return false; case "/acnplushelp": HandleACNPlusHelpCommand(); return false; case "/friendguide": HandleFriendGuideCommand(); return false; case "/crews": HandleCrewsCommand(); return false; case "/mycrew": HandleMyCrewCommand(); return false; case "/listplayers": HandleListPlayersCommand(); return false; case "/block": if (array.Length < 2) { ChatUI instance2 = ChatUI.Instance; if (instance2 != null) { instance2.AddMessage("Usage: /block "); } return false; } HandleBlockCommand(array[1]); return false; case "/unblock": if (array.Length < 2) { ChatUI instance = ChatUI.Instance; if (instance != null) { instance.AddMessage("Usage: /unblock "); } return false; } HandleUnblockCommand(array[1]); return false; case "/blocklist": HandleBlocklistCommand(); return false; default: return true; } } private static void HandleAddMeCommand() { ClientController instance = ClientController.Instance; if ((Object)(object)instance == (Object)null) { ChatUI instance2 = ChatUI.Instance; if (instance2 != null) { instance2.AddMessage("Not connected to server!"); } return; } ushort localID = instance.LocalID; ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage($"Your Player ID: {localID}"); } } private static void HandleAddFriendCommand(string playerIdStr) { if (!ushort.TryParse(playerIdStr, out var result)) { ChatUI instance = ChatUI.Instance; if (instance != null) { instance.AddMessage("Invalid player ID! Must be a number."); } return; } ClientController instance2 = ClientController.Instance; if ((Object)(object)instance2 == (Object)null) { ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage("Not connected to server!"); } return; } if (result == instance2.LocalID) { ChatUI instance4 = ChatUI.Instance; if (instance4 != null) { instance4.AddMessage("You cannot add yourself as a friend!"); } return; } if (!instance2.Players.TryGetValue(result, out var value) || value.ClientState == null) { ChatUI instance5 = ChatUI.Instance; if (instance5 != null) { instance5.AddMessage($"Player with ID {result} not found!"); } return; } string name = value.ClientState.Name; HashSet friendsList = ACNPlusPlugin.GetFriendsList(); if (friendsList.Contains(name)) { ChatUI instance6 = ChatUI.Instance; if (instance6 != null) { instance6.AddMessage("" + name + " is already in your friends list!"); } return; } string path = Path.Combine(ACNPlusPlugin.GetFriendsFolder(), "FriendsList.txt"); try { File.AppendAllText(path, name + Environment.NewLine); friendsList.Add(name); ChatUI instance7 = ChatUI.Instance; if (instance7 != null) { instance7.AddMessage("Added " + name + " to your friends list!"); } } catch (Exception) { ChatUI instance8 = ChatUI.Instance; if (instance8 != null) { instance8.AddMessage("Failed to save friend to list!"); } } } private static void HandleFriendsListCommand() { HashSet friendsList = ACNPlusPlugin.GetFriendsList(); if (friendsList.Count == 0) { ChatUI instance = ChatUI.Instance; if (instance != null) { instance.AddMessage("Your friends list is empty!"); } ChatUI instance2 = ChatUI.Instance; if (instance2 != null) { instance2.AddMessage("Use /addfriend to add friends"); } return; } ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage("=== Friends List ==="); } string[] array = friendsList.ToArray(); for (int i = 0; i < array.Length; i++) { ChatUI instance4 = ChatUI.Instance; if (instance4 != null) { instance4.AddMessage($"{i + 1}. {array[i]}"); } } ChatUI instance5 = ChatUI.Instance; if (instance5 != null) { instance5.AddMessage($"Total: {friendsList.Count} friends"); } } private static void HandleRemoveFriendCommand(string numberStr) { if (!int.TryParse(numberStr, out var result) || result < 1) { ChatUI instance = ChatUI.Instance; if (instance != null) { instance.AddMessage("Invalid number! Must be a positive number."); } return; } HashSet friendsList = ACNPlusPlugin.GetFriendsList(); if (friendsList.Count == 0) { ChatUI instance2 = ChatUI.Instance; if (instance2 != null) { instance2.AddMessage("Your friends list is empty!"); } return; } if (result > friendsList.Count) { ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage($"Invalid number! You only have {friendsList.Count} friends."); } return; } string text = friendsList.ToArray()[result - 1]; string path = Path.Combine(ACNPlusPlugin.GetFriendsFolder(), "FriendsList.txt"); try { friendsList.Remove(text); File.WriteAllLines(path, friendsList); ChatUI instance4 = ChatUI.Instance; if (instance4 != null) { instance4.AddMessage("Removed " + text + " from your friends list!"); } } catch (Exception) { ChatUI instance5 = ChatUI.Instance; if (instance5 != null) { instance5.AddMessage("Failed to remove friend from list!"); } } } private static void HandleFriendsCommand() { HashSet friendsList = ACNPlusPlugin.GetFriendsList(); if (friendsList.Count == 0) { ChatUI instance = ChatUI.Instance; if (instance != null) { instance.AddMessage("Your friends list is empty!"); } return; } ClientController instance2 = ClientController.Instance; if ((Object)(object)instance2 == (Object)null) { ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage("Not connected to server!"); } return; } ClientLobbyManager clientLobbyManager = instance2.ClientLobbyManager; List list = new List(); List list2 = new List(); foreach (MPPlayer value in instance2.Players.Values) { if (value.ClientState == null) { continue; } string name = value.ClientState.Name; if (!friendsList.Contains(name)) { continue; } list.Add(name); foreach (Lobby value2 in clientLobbyManager.Lobbies.Values) { if (value2.LobbyState.Players.ContainsKey(value.ClientId)) { if (value2.LobbyState.InGame) { list2.Add(name); } break; } } } if (list.Count > 0) { string text = "Friends Online: " + string.Join(", ", list) + ""; ChatUI instance4 = ChatUI.Instance; if (instance4 != null) { instance4.AddMessage(text); } if (list2.Count > 0) { string text2 = "In Game: " + string.Join(", ", list2) + ""; ChatUI instance5 = ChatUI.Instance; if (instance5 != null) { instance5.AddMessage(text2); } } } else { ChatUI instance6 = ChatUI.Instance; if (instance6 != null) { instance6.AddMessage("No friends are currently online."); } } } private static void HandlePlayersHelpCommand() { ChatUI instance = ChatUI.Instance; if (instance != null) { instance.AddMessage("=== ACNPlus Commands ==="); } ChatUI instance2 = ChatUI.Instance; if (instance2 != null) { instance2.AddMessage("/addme - Display your player ID"); } ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage("/addfriend - Add a friend (e.g., /addfriend 51)"); } ChatUI instance4 = ChatUI.Instance; if (instance4 != null) { instance4.AddMessage("/friendslist - View all friends with numbers"); } ChatUI instance5 = ChatUI.Instance; if (instance5 != null) { instance5.AddMessage("/removefriend - Remove a friend"); } ChatUI instance6 = ChatUI.Instance; if (instance6 != null) { instance6.AddMessage("/friends - Check which friends are online"); } ChatUI instance7 = ChatUI.Instance; if (instance7 != null) { instance7.AddMessage("/crews - View all crews in your current stage"); } ChatUI instance8 = ChatUI.Instance; if (instance8 != null) { instance8.AddMessage("/mycrew - View your crew members in your stage"); } ChatUI instance9 = ChatUI.Instance; if (instance9 != null) { instance9.AddMessage("/listplayers - List all online players"); } ChatUI instance10 = ChatUI.Instance; if (instance10 != null) { instance10.AddMessage("/block - Block a player"); } ChatUI instance11 = ChatUI.Instance; if (instance11 != null) { instance11.AddMessage("/unblock - Unblock a player"); } ChatUI instance12 = ChatUI.Instance; if (instance12 != null) { instance12.AddMessage("/blocklist - View all blocked players"); } ChatUI instance13 = ChatUI.Instance; if (instance13 != null) { instance13.AddMessage("/friendguide - Show how to add friends"); } ChatUI instance14 = ChatUI.Instance; if (instance14 != null) { instance14.AddMessage("/playershelp - Show this help message"); } } private static void HandleACNPlusHelpCommand() { ChatUI instance = ChatUI.Instance; if (instance != null) { instance.AddMessage("=== ACNPlus Help ==="); } ChatUI instance2 = ChatUI.Instance; if (instance2 != null) { instance2.AddMessage("/playershelp - Show player system commands"); } ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage("/acnplushelp - Show this help message"); } } private static void HandleFriendGuideCommand() { ACNPlusPlugin.ShowFriendGuideInChat(); } private static void HandleCrewsCommand() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected I4, but got Unknown ClientController instance = ClientController.Instance; if ((Object)(object)instance == (Object)null) { ChatUI instance2 = ChatUI.Instance; if (instance2 != null) { instance2.AddMessage("Not connected to server!"); } return; } Scene activeScene = SceneManager.GetActiveScene(); int num = (int)Utility.SceneNameToStage(((Scene)(ref activeScene)).name); Dictionary dictionary = new Dictionary(); Dictionary dictionary2 = new Dictionary(); foreach (MPPlayer value in instance.Players.Values) { if (value.ClientState == null || value.ClientState.Stage != num) { continue; } bool flag = false; if (value.ClientState.User != null && value.ClientState.User.Badges != null) { if (value.ClientState.User.Badges.Contains(63)) { string key = "GCN"; if (dictionary2.ContainsKey(key)) { dictionary2[key]++; } else { dictionary2[key] = 1; } flag = true; } if (value.ClientState.User.Badges.Contains(40)) { string key2 = "Goonforce"; if (dictionary2.ContainsKey(key2)) { dictionary2[key2]++; } else { dictionary2[key2] = 1; } flag = true; } if (value.ClientState.User.Badges.Contains(52)) { string key3 = "rok"; if (dictionary2.ContainsKey(key3)) { dictionary2[key3]++; } else { dictionary2[key3] = 1; } flag = true; } if (value.ClientState.User.Badges.Contains(28)) { string key4 = "dumfuks"; if (dictionary2.ContainsKey(key4)) { dictionary2[key4]++; } else { dictionary2[key4] = 1; } flag = true; } } if (!flag) { string key5 = (string.IsNullOrEmpty(value.ClientState.CrewName) ? "No Crew" : value.ClientState.CrewName); if (dictionary.ContainsKey(key5)) { dictionary[key5]++; } else { dictionary[key5] = 1; } } } if (dictionary.Count == 0 && dictionary2.Count == 0) { ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage("No players in your current stage!"); } return; } ChatUI instance4 = ChatUI.Instance; if (instance4 != null) { instance4.AddMessage($"=== Crews in Stage {num} ==="); } if (dictionary2.Count > 0) { foreach (KeyValuePair item in dictionary2.OrderByDescending((KeyValuePair x) => x.Value)) { string arg = ((item.Value == 1) ? "member" : "members"); if (item.Key == "GCN") { ChatUI instance5 = ChatUI.Instance; if (instance5 != null) { instance5.AddMessage($" GCN: {item.Value} {arg}"); } } else if (item.Key == "Goonforce") { ChatUI instance6 = ChatUI.Instance; if (instance6 != null) { instance6.AddMessage($" Goonforce: {item.Value} {arg}"); } } else if (item.Key == "rok") { ChatUI instance7 = ChatUI.Instance; if (instance7 != null) { instance7.AddMessage($" rok: {item.Value} {arg}"); } } else if (item.Key == "dumfuks") { ChatUI instance8 = ChatUI.Instance; if (instance8 != null) { instance8.AddMessage($" dumfuks: {item.Value} {arg}"); } } } if (dictionary.Count > 0) { ChatUI instance9 = ChatUI.Instance; if (instance9 != null) { instance9.AddMessage("---"); } } } foreach (KeyValuePair item2 in dictionary.OrderByDescending((KeyValuePair x) => x.Value)) { string arg2 = ((item2.Value == 1) ? "member" : "members"); ChatUI instance10 = ChatUI.Instance; if (instance10 != null) { instance10.AddMessage($"{item2.Key}: {item2.Value} {arg2}"); } } int num2 = dictionary.Values.Sum() + dictionary2.Values.Sum(); ChatUI instance11 = ChatUI.Instance; if (instance11 != null) { instance11.AddMessage($"Total: {num2} players"); } } private static void HandleMyCrewCommand() { //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected I4, but got Unknown ClientController instance = ClientController.Instance; if ((Object)(object)instance == (Object)null) { ChatUI instance2 = ChatUI.Instance; if (instance2 != null) { instance2.AddMessage("Not connected to server!"); } return; } MPPlayer val = ((IEnumerable)instance.Players.Values).FirstOrDefault((Func)((MPPlayer p) => p.Local)); if (val == null || val.ClientState == null) { ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage("Could not find local player!"); } return; } Scene activeScene = SceneManager.GetActiveScene(); int num = (int)Utility.SceneNameToStage(((Scene)(ref activeScene)).name); string crewName = val.ClientState.CrewName; bool flag = false; string text = ""; int num2 = 0; if (val.ClientState.User != null && val.ClientState.User.Badges != null) { if (val.ClientState.User.Badges.Contains(63)) { flag = true; text = "GCN"; num2 = 63; } else if (val.ClientState.User.Badges.Contains(40)) { flag = true; text = "Goonforce"; num2 = 40; } else if (val.ClientState.User.Badges.Contains(52)) { flag = true; text = "rok"; num2 = 52; } else if (val.ClientState.User.Badges.Contains(28)) { flag = true; text = "dumfuks"; num2 = 28; } } if (!flag) { string playerDisplayName = MPUtility.GetPlayerDisplayName(val.ClientState); if (playerDisplayName.Contains("")) { flag = true; text = "GCN"; num2 = 63; } else if (playerDisplayName.Contains("")) { flag = true; text = "Goonforce"; num2 = 40; } else if (playerDisplayName.Contains("")) { flag = true; text = "rok"; num2 = 52; } else if (playerDisplayName.Contains("")) { flag = true; text = "dumfuks"; num2 = 28; } } if (!flag && string.IsNullOrEmpty(crewName)) { ChatUI instance4 = ChatUI.Instance; if (instance4 != null) { instance4.AddMessage("You are not in a crew!"); } return; } List list = new List(); foreach (MPPlayer value in instance.Players.Values) { if (value.ClientState == null || value.ClientId == instance.LocalID || value.ClientState.Stage != num) { continue; } if (flag) { bool flag2 = false; if (value.ClientState.User != null && value.ClientState.User.Badges != null && value.ClientState.User.Badges.Contains(num2)) { flag2 = true; } if (!flag2 && MPUtility.GetPlayerDisplayName(value.ClientState).Contains($"")) { flag2 = true; } if (flag2) { list.Add(value.ClientState.Name); } } else if (value.ClientState.CrewName == crewName) { list.Add(value.ClientState.Name); } } if (list.Count == 0) { if (flag) { switch (text) { case "GCN": { ChatUI instance8 = ChatUI.Instance; if (instance8 != null) { instance8.AddMessage("No other GCN crew members in your stage!"); } break; } case "Goonforce": { ChatUI instance6 = ChatUI.Instance; if (instance6 != null) { instance6.AddMessage("No other Goonforce crew members in your stage!"); } break; } case "rok": { ChatUI instance7 = ChatUI.Instance; if (instance7 != null) { instance7.AddMessage("No other rok crew members in your stage!"); } break; } case "dumfuks": { ChatUI instance5 = ChatUI.Instance; if (instance5 != null) { instance5.AddMessage("No other dumfuks crew members in your stage!"); } break; } } } else { ChatUI instance9 = ChatUI.Instance; if (instance9 != null) { instance9.AddMessage("No other " + crewName + " crew members in your stage!"); } } return; } if (flag) { switch (text) { case "GCN": { ChatUI instance13 = ChatUI.Instance; if (instance13 != null) { instance13.AddMessage($" GCN Members in Stage {num} ==="); } break; } case "Goonforce": { ChatUI instance11 = ChatUI.Instance; if (instance11 != null) { instance11.AddMessage($" Goonforce Members in Stage {num} ==="); } break; } case "rok": { ChatUI instance12 = ChatUI.Instance; if (instance12 != null) { instance12.AddMessage($" rok Members in Stage {num} ==="); } break; } case "dumfuks": { ChatUI instance10 = ChatUI.Instance; if (instance10 != null) { instance10.AddMessage($" dumfuks Members in Stage {num} ==="); } break; } } } else { ChatUI instance14 = ChatUI.Instance; if (instance14 != null) { instance14.AddMessage($"=== {crewName} Members in Stage {num} ==="); } } foreach (string item in list.OrderBy((string x) => x)) { ChatUI instance15 = ChatUI.Instance; if (instance15 != null) { instance15.AddMessage("• " + item + ""); } } string arg = ((list.Count == 1) ? "member" : "members"); ChatUI instance16 = ChatUI.Instance; if (instance16 != null) { instance16.AddMessage($"Total: {list.Count} {arg}"); } } private static void HandleListPlayersCommand() { ClientController instance = ClientController.Instance; if ((Object)(object)instance == (Object)null) { ChatUI instance2 = ChatUI.Instance; if (instance2 != null) { instance2.AddMessage("Not connected to server!"); } return; } List list = (from p in instance.Players.Values where p.ClientState != null orderby p.ClientState.Name select p).ToList(); if (list.Count == 0) { ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage("No players online!"); } return; } ChatUI instance4 = ChatUI.Instance; if (instance4 != null) { instance4.AddMessage("=== All Players ==="); } for (int i = 0; i < list.Count; i++) { MPPlayer val = list[i]; string arg = (ACNPlusPlugin.GetBlocklist().Contains(val.ClientState.Name) ? " [BLOCKED]" : ""); ChatUI instance5 = ChatUI.Instance; if (instance5 != null) { instance5.AddMessage($"{i + 1}. {val.ClientState.Name}{arg}"); } } ChatUI instance6 = ChatUI.Instance; if (instance6 != null) { instance6.AddMessage($"Total: {list.Count} players"); } } private static void HandleBlockCommand(string numberStr) { if (!int.TryParse(numberStr, out var result) || result < 1) { ChatUI instance = ChatUI.Instance; if (instance != null) { instance.AddMessage("Invalid number! Must be a positive number."); } return; } ClientController instance2 = ClientController.Instance; if ((Object)(object)instance2 == (Object)null) { ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage("Not connected to server!"); } return; } List list = (from p in instance2.Players.Values where p.ClientState != null orderby p.ClientState.Name select p).ToList(); if (result > list.Count) { ChatUI instance4 = ChatUI.Instance; if (instance4 != null) { instance4.AddMessage($"Invalid number! Only {list.Count} players online."); } return; } MPPlayer obj = list[result - 1]; string name = obj.ClientState.Name; if (obj.ClientId == instance2.LocalID) { ChatUI instance5 = ChatUI.Instance; if (instance5 != null) { instance5.AddMessage("You cannot block yourself!"); } return; } if (ACNPlusPlugin.GetBlocklist().Contains(name)) { ChatUI instance6 = ChatUI.Instance; if (instance6 != null) { instance6.AddMessage("" + name + " is already blocked!"); } return; } try { File.AppendAllText(ACNPlusPlugin.GetBlocklistPath(), name + Environment.NewLine); ACNPlusPlugin.ReloadBlocklist(); ChatUI instance7 = ChatUI.Instance; if (instance7 != null) { instance7.AddMessage("Blocked " + name + "!"); } } catch (Exception) { ChatUI instance8 = ChatUI.Instance; if (instance8 != null) { instance8.AddMessage("Failed to save to blocklist!"); } } } private static void HandleUnblockCommand(string numberStr) { if (!int.TryParse(numberStr, out var result) || result < 1) { ChatUI instance = ChatUI.Instance; if (instance != null) { instance.AddMessage("Invalid number! Must be a positive number."); } return; } HashSet blocklist = ACNPlusPlugin.GetBlocklist(); if (blocklist.Count == 0) { ChatUI instance2 = ChatUI.Instance; if (instance2 != null) { instance2.AddMessage("Your blocklist is empty!"); } return; } if (result > blocklist.Count) { ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage($"Invalid number! You only have {blocklist.Count} blocked users."); } return; } string text = blocklist.ToArray()[result - 1]; try { blocklist.Remove(text); File.WriteAllLines(ACNPlusPlugin.GetBlocklistPath(), blocklist); ACNPlusPlugin.ReloadBlocklist(); ChatUI instance4 = ChatUI.Instance; if (instance4 != null) { instance4.AddMessage("Unblocked " + text + "!"); } } catch (Exception) { ChatUI instance5 = ChatUI.Instance; if (instance5 != null) { instance5.AddMessage("Failed to update blocklist!"); } } } private static void HandleBlocklistCommand() { HashSet blocklist = ACNPlusPlugin.GetBlocklist(); if (blocklist.Count == 0) { ChatUI instance = ChatUI.Instance; if (instance != null) { instance.AddMessage("Your blocklist is empty!"); } return; } ChatUI instance2 = ChatUI.Instance; if (instance2 != null) { instance2.AddMessage("=== Blocked Players ==="); } string[] array = blocklist.ToArray(); for (int i = 0; i < array.Length; i++) { ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage($"{i + 1}. {array[i]}"); } } ChatUI instance4 = ChatUI.Instance; if (instance4 != null) { instance4.AddMessage($"Total: {blocklist.Count} blocked"); } } } public class FriendsListPatches { } public static class LobbyBannerPatches { [HarmonyPatch(typeof(LobbyUI), "UpdateUI")] private class LobbyUIUpdateUIPatch { private static void Postfix(LobbyUI __instance) { FieldInfo field = typeof(LobbyUI).GetField("_lobbySettings", BindingFlags.Instance | BindingFlags.NonPublic); if (!(field == null)) { object? value = field.GetValue(__instance); Component val = (Component)((value is Component) ? value : null); if ((Object)(object)val != (Object)null) { val.gameObject.SetActive(!ACNPlusPlugin.HideLobbySettings.Value); } } } } [HarmonyPatch(typeof(LobbyUI), "Awake")] private class LobbyUIAwakePatch { private static void Postfix(LobbyUI __instance) { //IL_00f3: Unknown result type (might be due to invalid IL or missing references) FieldInfo field = typeof(LobbyUI).GetField("_lobbySettings", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { object? value = field.GetValue(__instance); Component val = (Component)((value is Component) ? value : null); if (val != null) { val.gameObject.SetActive(!ACNPlusPlugin.HideLobbySettings.Value); } } if (!ACNPlusPlugin.TransparentLobbyBanner.Value) { return; } Sprite val2 = LoadTransparentSprite(); if ((Object)(object)val2 == (Object)null) { return; } FieldInfo field2 = typeof(LobbyUI).GetField("_canvas", BindingFlags.Instance | BindingFlags.NonPublic); if (field2 == null) { return; } object? value2 = field2.GetValue(__instance); GameObject val3 = (GameObject)((value2 is GameObject) ? value2 : null); if ((Object)(object)val3 == (Object)null) { return; } Transform val4 = val3.transform.Find("Lobby Name BG"); if ((Object)(object)val4 == (Object)null) { return; } Type type = Type.GetType("UnityEngine.UI.Image, UnityEngine.UI"); if (!(type == null)) { Component component = ((Component)val4).GetComponent(type); if ((Object)(object)component != (Object)null) { SetImageSprite(component, val2); SetImageColor(component, Color.white); } } } } [HarmonyPatch(typeof(LobbyPlayerUI), "Awake")] private class LobbyPlayerUIAwakePatch { private static void Postfix(LobbyPlayerUI __instance) { if (!ACNPlusPlugin.TransparentLobbyNameBG.Value) { return; } Sprite val = LoadTransparentSprite(); if (!((Object)(object)val == (Object)null)) { FieldInfo? field = typeof(LobbyPlayerUI).GetField("_bg", BindingFlags.Instance | BindingFlags.NonPublic); FieldInfo field2 = typeof(LobbyPlayerUI).GetField("_teamBg", BindingFlags.Instance | BindingFlags.NonPublic); object obj = field?.GetValue(__instance); object obj2 = field2?.GetValue(__instance); if (obj != null) { SetImageSprite(obj, val); } if (obj2 != null) { SetImageSprite(obj2, val); } } } } [HarmonyPatch(typeof(LobbyPlayerUI), "SetTeam")] private class LobbyPlayerUISetTeamPatch { private static void Postfix(LobbyPlayerUI __instance) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (ACNPlusPlugin.TransparentLobbyNameBG.Value) { object obj = typeof(LobbyPlayerUI).GetField("_teamBg", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance); if (obj != null) { float imageColorA = GetImageColorA(obj); SetImageColor(obj, new Color(1f, 1f, 1f, imageColorA)); } } } } [HarmonyPatch(typeof(LobbyPlayerUI), "SetPlayer")] private class LobbyPlayerUISetPlayerPatch { private static void Postfix(LobbyPlayerUI __instance) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) if (ACNPlusPlugin.TransparentLobbyNameBG.Value) { object obj = typeof(LobbyPlayerUI).GetField("_teamBg", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(__instance); if (obj != null) { float imageColorA = GetImageColorA(obj); SetImageColor(obj, new Color(1f, 1f, 1f, imageColorA)); } } } } private static Sprite _cachedTransparent; private static Sprite LoadTransparentSprite() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)_cachedTransparent != (Object)null) { return _cachedTransparent; } string backendTexturesPath = ACNPlusPlugin.GetBackendTexturesPath("transparent.png"); if (!File.Exists(backendTexturesPath)) { return null; } byte[] array = File.ReadAllBytes(backendTexturesPath); Texture2D val = new Texture2D(2, 2); if (!ImageConversion.LoadImage(val, array)) { return null; } val.Apply(); _cachedTransparent = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); return _cachedTransparent; } private static void SetImageSprite(object image, Sprite sprite) { if (image != null && !((Object)(object)sprite == (Object)null)) { image.GetType().GetProperty("sprite", BindingFlags.Instance | BindingFlags.Public)?.SetValue(image, sprite); } } private static void SetImageColor(object image, Color color) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) image?.GetType().GetProperty("color", BindingFlags.Instance | BindingFlags.Public)?.SetValue(image, color); } private static float GetImageColorA(object image) { //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_0038: Unknown result type (might be due to invalid IL or missing references) if (image == null) { return 1f; } if (image.GetType().GetProperty("color", BindingFlags.Instance | BindingFlags.Public)?.GetValue(image) is Color val) { return val.a; } return 1f; } } [HarmonyPatch(typeof(ClientController), "OnMessageReceived")] public class LobbyInvitePatches { [HarmonyPrefix] public static bool OnMessageReceived_Prefix(object sender, MessageReceivedEventArgs e) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_000f: Unknown result type (might be due to invalid IL or missing references) Packets val = (Packets)e.MessageId; if ((int)val == 27) { Packet obj = PacketFactory.PacketFromMessage(val, e.Message); ServerLobbyInvite val2 = (ServerLobbyInvite)(object)((obj is ServerLobbyInvite) ? obj : null); if (val2 != null) { ClientController instance = ClientController.Instance; if ((Object)(object)instance != (Object)null) { string text = "Unknown"; if (instance.Players.TryGetValue(val2.InviterId, out var value) && value.ClientState != null) { text = value.ClientState.Name; } if (ACNPlusPlugin.GetBlocklist().Contains(text)) { instance.ClientLobbyManager.DeclineInvite(val2.LobbyId); if (ACNPlusPlugin.SeeWhenSomethingIsBlocked.Value) { ChatUI instance2 = ChatUI.Instance; if (instance2 != null) { instance2.AddMessage("Blocked invite from " + text + ""); } } return false; } if (ACNPlusPlugin.BlockInvites.Value) { instance.ClientLobbyManager.DeclineInvite(val2.LobbyId); if (ACNPlusPlugin.BlockInvitesChatMessage.Value) { string text2 = "Unknown"; if (instance.ClientLobbyManager.Lobbies.TryGetValue(val2.LobbyId, out var _)) { text2 = instance.ClientLobbyManager.GetLobbyName(val2.LobbyId); } ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage("Blocked invite from " + text + " to " + text2 + " lobby"); } } return false; } } } } return true; } } [HarmonyPatch(typeof(MPMapUI), "Awake")] public static class MinimapReplacementPatch { private const string RawImageTypeName = "UnityEngine.UI.RawImage"; [HarmonyPostfix] public static void Awake_Postfix(MPMapUI __instance) { //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Expected O, but got Unknown string text = null; ConfigEntry catWizardMiniMap = ACNPlusPlugin.CatWizardMiniMap; if (catWizardMiniMap != null && catWizardMiniMap.Value) { text = ACNPlusPlugin.GetBackendTexturesPath("CatMiniMap.png"); } else { ConfigEntry changeMiniMapToPNG = ACNPlusPlugin.ChangeMiniMapToPNG; if (changeMiniMapToPNG != null && changeMiniMapToPNG.Value) { string texturesFolder = ACNPlusPlugin.GetTexturesFolder(); if (!string.IsNullOrEmpty(texturesFolder) && Directory.Exists(texturesFolder)) { text = Path.Combine(texturesFolder, "MiniMapPNG.png"); } } } if (text == null || !File.Exists(text)) { return; } Transform val = ((Component)__instance).transform.Find("Map Texture"); if ((Object)(object)val == (Object)null) { return; } Component val2 = null; Component[] components = ((Component)val).GetComponents(); foreach (Component val3 in components) { if ((Object)(object)val3 != (Object)null && ((object)val3).GetType().FullName == "UnityEngine.UI.RawImage") { val2 = val3; break; } } if ((Object)(object)val2 == (Object)null) { return; } try { byte[] array = File.ReadAllBytes(text); Texture2D val4 = new Texture2D(2, 2); if (ImageConversion.LoadImage(val4, array)) { ((object)val2).GetType().GetProperty("texture", BindingFlags.Instance | BindingFlags.Public)?.SetValue(val2, val4); ((Component)__instance).gameObject.AddComponent().SetTexture((Texture)(object)val4); } else { Object.Destroy((Object)(object)val4); } } catch (Exception) { } } } [HarmonyPatch(typeof(ClientLobbyManager), "OnPacketReceived")] public class PrivateLobbyPatches { private static HashSet _allowedPlayers = new HashSet(); private static bool _wasHost = false; [HarmonyPostfix] public static void OnPacketReceived_Postfix(Packets packetId, Packet packet) { //IL_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Invalid comparison between Unknown and I4 //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Invalid comparison between Unknown and I4 ClientController instance = ClientController.Instance; if ((Object)(object)instance == (Object)null) { return; } ClientLobbyManager clientLobbyManager = instance.ClientLobbyManager; Lobby currentLobby = clientLobbyManager.CurrentLobby; if (currentLobby == null) { _allowedPlayers.Clear(); _wasHost = false; return; } bool flag = currentLobby.LobbyState.HostId == instance.LocalID; if (flag && !_wasHost) { _allowedPlayers.Clear(); foreach (ushort key in currentLobby.LobbyState.Players.Keys) { _allowedPlayers.Add(key); } _wasHost = true; } else if (!flag) { _wasHost = false; _allowedPlayers.Clear(); return; } if (((int)packetId != 47 && (int)packetId != 13) || !flag) { return; } HashSet blocklist = ACNPlusPlugin.GetBlocklist(); HashSet friendsList = ACNPlusPlugin.GetFriendsList(); MPPlayer value; MPPlayer val = (instance.Players.TryGetValue(instance.LocalID, out value) ? value : null); string text = ""; int num = -1; if (val != null && val.ClientState != null) { text = val.ClientState.CrewName; if (val.ClientState.User != null && val.ClientState.User.Badges != null) { if (val.ClientState.User.Badges.Contains(63)) { num = 63; } else if (val.ClientState.User.Badges.Contains(40)) { num = 40; } else if (val.ClientState.User.Badges.Contains(52)) { num = 52; } else if (val.ClientState.User.Badges.Contains(28)) { num = 28; } } if (num == -1) { string playerDisplayName = MPUtility.GetPlayerDisplayName(val.ClientState); if (playerDisplayName.Contains("")) { num = 63; } else if (playerDisplayName.Contains("")) { num = 40; } else if (playerDisplayName.Contains("")) { num = 52; } else if (playerDisplayName.Contains("")) { num = 28; } } } foreach (ushort key2 in currentLobby.LobbyState.Players.Keys) { if (key2 == instance.LocalID) { continue; } if (instance.Players.TryGetValue(key2, out var value2) && value2.ClientState != null) { string name = value2.ClientState.Name; if (blocklist.Contains(name)) { clientLobbyManager.KickPlayer(key2); if (ACNPlusPlugin.SeeWhenSomethingIsBlocked.Value) { ChatUI instance2 = ChatUI.Instance; if (instance2 != null) { instance2.AddMessage("Auto-kicked blocked user " + name + " from your lobby"); } } continue; } if (ACNPlusPlugin.CrewOnlyLobby.Value) { bool flag2 = false; if (num != -1) { if (value2.ClientState.User != null && value2.ClientState.User.Badges != null && value2.ClientState.User.Badges.Contains(num)) { flag2 = true; } if (!flag2 && MPUtility.GetPlayerDisplayName(value2.ClientState).Contains($"")) { flag2 = true; } } else if (!string.IsNullOrEmpty(text) && value2.ClientState.CrewName == text) { flag2 = true; } if (!flag2) { clientLobbyManager.KickPlayer(key2); ChatUI instance3 = ChatUI.Instance; if (instance3 != null) { instance3.AddMessage("Auto-kicked " + name + " (not in your crew)"); } continue; } } if (ACNPlusPlugin.FriendsOnlyLobby.Value && !friendsList.Contains(name)) { clientLobbyManager.KickPlayer(key2); ChatUI instance4 = ChatUI.Instance; if (instance4 != null) { instance4.AddMessage("Auto-kicked " + name + " (not on friends list)"); } continue; } } if (ACNPlusPlugin.BlockPlayersFromJoiningLobby.Value && !_allowedPlayers.Contains(key2)) { clientLobbyManager.KickPlayer(key2); string text2 = "Unknown"; if (instance.Players.TryGetValue(key2, out var value3) && value3.ClientState != null) { text2 = value3.ClientState.Name; } ChatUI instance5 = ChatUI.Instance; if (instance5 != null) { instance5.AddMessage("Auto-kicked " + text2 + " from your lobby"); } } } } } } namespace ACNPlus.MinimapReplacement { public class MinimapTextureHolder : MonoBehaviour { private Texture _texture; public void SetTexture(Texture texture) { _texture = texture; } private void OnDestroy() { if ((Object)(object)_texture != (Object)null) { Object.Destroy((Object)(object)_texture); _texture = null; } } } } namespace ACNPlus.ChatBubble { public class ChatBubble : MonoBehaviour { private const float DisplayTime = 5f; private const float FadeTime = 0.5f; private const float HeightOffset = 2.5f; private TextMeshPro _label; private Transform _followTarget; private float _timer; private bool _active; private static Color _cachedColor = Color.white; private static bool _colorCacheValid = false; public static void InitColorCache() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) _cachedColor = ACNPlusPlugin.GetChatBubbleColor(); _colorCacheValid = true; ACNPlusPlugin.ChatBubbleColor.SettingChanged += delegate { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) _cachedColor = ACNPlusPlugin.GetChatBubbleColor(); }; } private static Color GetColor() { //IL_0017: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) if (!_colorCacheValid) { _cachedColor = ACNPlusPlugin.GetChatBubbleColor(); _colorCacheValid = true; } return _cachedColor; } public static ChatBubble Create(Transform followTarget) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown GameObject val = new GameObject("ChatBubble"); ChatBubble chatBubble = val.AddComponent(); chatBubble._followTarget = followTarget; chatBubble._label = val.AddComponent(); ((TMP_Text)chatBubble._label).fontSize = 1.6f; chatBubble._label.sortingOrder = 2; ((TMP_Text)chatBubble._label).horizontalAlignment = (HorizontalAlignmentOptions)2; ((TMP_Text)chatBubble._label).verticalAlignment = (VerticalAlignmentOptions)512; MPAssets instance = MPAssets.Instance; if (instance != null) { ((TMP_Text)chatBubble._label).spriteAsset = instance.Sprites; } val.SetActive(false); return chatBubble; } private static string WrapText(string text, int lineLength) { StringBuilder stringBuilder = new StringBuilder(); int num = 0; bool flag = false; int num2 = 0; while (num2 < text.Length) { if (text[num2] == '<') { int num3 = text.IndexOf('>', num2); if (num3 >= 0) { stringBuilder.Append(text, num2, num3 - num2 + 1); num2 = num3 + 1; continue; } } if (flag && text[num2] == ' ') { stringBuilder.Append('\n'); flag = false; num = 0; num2++; continue; } if (num > 0 && num % lineLength == 0) { flag = true; } stringBuilder.Append(text[num2]); num++; num2++; } return stringBuilder.ToString(); } public void ShowMessage(string message) { //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) int num = message.IndexOf(": "); string text = ((num >= 0) ? message.Substring(num + 2) : message); text = MPUtility.ParseMessageEmojis(text); text = WrapText(text, 15); ((TMP_Text)_label).text = text; ((Graphic)_label).color = GetColor(); ((TMP_Text)_label).outlineColor = Color32.op_Implicit(Color.black); ((TMP_Text)_label).outlineWidth = 0.2f; _timer = 5.5f; _active = true; ((Component)this).gameObject.SetActive(true); } private void LateUpdate() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) if (!_active) { return; } if ((Object)(object)_followTarget == (Object)null) { ((Component)this).gameObject.SetActive(false); _active = false; return; } ((Component)this).transform.position = _followTarget.position + Vector3.up * 2.5f; _timer -= Time.deltaTime; if (_timer <= 0f) { ((Component)this).gameObject.SetActive(false); _active = false; } else if (_timer < 0.5f) { Color color = GetColor(); float num = _timer / 0.5f; ((Graphic)_label).color = new Color(color.r, color.g, color.b, num); ((TMP_Text)_label).outlineColor = new Color32((byte)0, (byte)0, (byte)0, (byte)(num * 255f)); } } private void OnWillRenderObject() { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Camera.current != (Object)null) { ((Component)this).transform.rotation = ((Component)Camera.current).transform.rotation; } } } }