From 64b3a77c301de97e1a5640fe7bfcaf84c3d7ebb1 Mon Sep 17 00:00:00 2001 From: Tianyi Ma Date: Wed, 11 Dec 2024 17:35:45 -0800 Subject: [PATCH] Lobby QoL --- Teemaw.Calico/Config.cs | 13 ++- Teemaw.Calico/Mod.cs | 10 +-- .../LobbyIdMainMenuScriptModFactory.cs | 31 ------- .../LobbyQolEscMenuScriptModFactory.cs} | 10 ++- .../LobbyQolMainMenuScriptModFactory.cs | 74 ++++++++++++++++ .../LobbyQolSteamNetworkScriptModFactory.cs} | 88 +++++++++++++++++-- Teemaw.Calico/Util/WeaveUtil.cs | 9 ++ 7 files changed, 186 insertions(+), 49 deletions(-) delete mode 100644 Teemaw.Calico/ScriptMod/LobbyId/LobbyIdMainMenuScriptModFactory.cs rename Teemaw.Calico/ScriptMod/{LobbyId/LobbyIdEscMenuScriptModFactory.cs => LobbyQol/LobbyQolEscMenuScriptModFactory.cs} (83%) create mode 100644 Teemaw.Calico/ScriptMod/LobbyQol/LobbyQolMainMenuScriptModFactory.cs rename Teemaw.Calico/ScriptMod/{LobbyId/LobbyIdSteamNetworkScriptModFactory.cs => LobbyQol/LobbyQolSteamNetworkScriptModFactory.cs} (56%) create mode 100644 Teemaw.Calico/Util/WeaveUtil.cs diff --git a/Teemaw.Calico/Config.cs b/Teemaw.Calico/Config.cs index cfdd79c..9a13eb2 100644 --- a/Teemaw.Calico/Config.cs +++ b/Teemaw.Calico/Config.cs @@ -6,19 +6,19 @@ public class Config { [JsonInclude] public bool DynamicZonesEnabled = true; [JsonInclude] public bool LoadingWaitTimeoutEnabled = true; - [JsonInclude] public bool LobbyIdsEnabled = false; + [JsonInclude] public bool LobbyQolEnabled = true; [JsonInclude] public bool MapSoundOptimizationsEnabled = true; [JsonInclude] public bool MeshGpuInstancingEnabled = true; [JsonInclude] public bool MultiThreadNetworkingEnabled = true; [JsonInclude] public bool PlayerOptimizationsEnabled = true; [JsonInclude] public bool ReducePhysicsUpdatesEnabled = true; [JsonInclude] public bool SmoothCameraEnabled = true; - + public override string ToString() { - return $"DynamicZonesEnabled={DynamicZonesEnabled}, " + + return $"DynamicZonesEnabled={DynamicZonesEnabled}, " + $"LoadingWaitTimeoutEnabled={LoadingWaitTimeoutEnabled}, " + - $"LobbyIdsEnabled={LobbyIdsEnabled}, " + + $"LobbyQolEnabled={LobbyQolEnabled}, " + $"MapSoundOptimizationsEnabled={MapSoundOptimizationsEnabled}, " + $"MeshGpuInstancingEnabled={MeshGpuInstancingEnabled}, " + $"MultiThreadNetworkingEnabled={MultiThreadNetworkingEnabled}, " + @@ -26,4 +26,9 @@ public override string ToString() $"ReducePhysicsUpdatesEnabled={ReducePhysicsUpdatesEnabled}, " + $"SmoothCameraEnabled={SmoothCameraEnabled}"; } + + public bool AnyEnabled() => + DynamicZonesEnabled || LoadingWaitTimeoutEnabled || LobbyQolEnabled || MapSoundOptimizationsEnabled + || MeshGpuInstancingEnabled || MultiThreadNetworkingEnabled || PlayerOptimizationsEnabled + || ReducePhysicsUpdatesEnabled || SmoothCameraEnabled; } \ No newline at end of file diff --git a/Teemaw.Calico/Mod.cs b/Teemaw.Calico/Mod.cs index c5fafa1..180b79d 100644 --- a/Teemaw.Calico/Mod.cs +++ b/Teemaw.Calico/Mod.cs @@ -1,7 +1,7 @@ using System.Reflection; using GDWeave; using Teemaw.Calico.ScriptMod; -using Teemaw.Calico.ScriptMod.LobbyId; +using Teemaw.Calico.ScriptMod.LobbyQol; namespace Teemaw.Calico; @@ -71,11 +71,11 @@ public Mod(IModInterface modInterface) modInterface.RegisterScriptMod(LoadingMenuScriptModFactory.Create(modInterface)); } - if (config.LobbyIdsEnabled) + if (config.LobbyQolEnabled) { - modInterface.RegisterScriptMod(LobbyIdSteamNetworkScriptModFactory.Create(modInterface)); - modInterface.RegisterScriptMod(LobbyIdMainMenuScriptModFactory.Create(modInterface)); - modInterface.RegisterScriptMod(LobbyIdEscMenuScriptModFactory.Create(modInterface)); + modInterface.RegisterScriptMod(LobbyQolSteamNetworkScriptModFactory.Create(modInterface, config)); + modInterface.RegisterScriptMod(LobbyQolMainMenuScriptModFactory.Create(modInterface)); + modInterface.RegisterScriptMod(LobbyQolEscMenuScriptModFactory.Create(modInterface)); } } diff --git a/Teemaw.Calico/ScriptMod/LobbyId/LobbyIdMainMenuScriptModFactory.cs b/Teemaw.Calico/ScriptMod/LobbyId/LobbyIdMainMenuScriptModFactory.cs deleted file mode 100644 index 6449503..0000000 --- a/Teemaw.Calico/ScriptMod/LobbyId/LobbyIdMainMenuScriptModFactory.cs +++ /dev/null @@ -1,31 +0,0 @@ -using GDWeave; -using GDWeave.Modding; -using Teemaw.Calico.LexicalTransformer; -using static Teemaw.Calico.LexicalTransformer.Operation; -using static Teemaw.Calico.LexicalTransformer.TransformationPatternFactory; - -namespace Teemaw.Calico.ScriptMod.LobbyId; - -public static class LobbyIdMainMenuScriptModFactory -{ - public static IScriptMod Create(IModInterface mod) - { - return new TransformationRuleScriptModBuilder() - .ForMod(mod) - .Named("LobbyIdMainMenuScriptMod") - .Patching("res://Scenes/Menus/Main Menu/main_menu.gdc") - .AddRule(new TransformationRuleBuilder() - .Named("ready") - .Matching(CreateFunctionDefinitionPattern("_ready")) - .Do(Append) - .With( - """ - - code.max_length = 14 - - """, 1 - ) - ) - .Build(); - } -} \ No newline at end of file diff --git a/Teemaw.Calico/ScriptMod/LobbyId/LobbyIdEscMenuScriptModFactory.cs b/Teemaw.Calico/ScriptMod/LobbyQol/LobbyQolEscMenuScriptModFactory.cs similarity index 83% rename from Teemaw.Calico/ScriptMod/LobbyId/LobbyIdEscMenuScriptModFactory.cs rename to Teemaw.Calico/ScriptMod/LobbyQol/LobbyQolEscMenuScriptModFactory.cs index 9330d9d..5719d30 100644 --- a/Teemaw.Calico/ScriptMod/LobbyId/LobbyIdEscMenuScriptModFactory.cs +++ b/Teemaw.Calico/ScriptMod/LobbyQol/LobbyQolEscMenuScriptModFactory.cs @@ -4,15 +4,15 @@ using static Teemaw.Calico.LexicalTransformer.Operation; using static Teemaw.Calico.LexicalTransformer.TransformationPatternFactory; -namespace Teemaw.Calico.ScriptMod.LobbyId; +namespace Teemaw.Calico.ScriptMod.LobbyQol; -public static class LobbyIdEscMenuScriptModFactory +public static class LobbyQolEscMenuScriptModFactory { public static IScriptMod Create(IModInterface mod) { return new TransformationRuleScriptModBuilder() .ForMod(mod) - .Named("LobbyIdEscMenuScriptMod") + .Named("LobbyQolEscMenuScriptMod") .Patching("res://Scenes/HUD/Esc Menu/esc_menu.gdc") .AddRule(new TransformationRuleBuilder() .Named("globals") @@ -44,10 +44,14 @@ func calico_on_copy_paste_pressed(): calico_code_show = $VBoxContainer/code_show.duplicate() calico_code_show.text = "Calico: Show Lobby ID" + calico_code_show.get_node("TooltipNode").header = "Show Lobby ID" + calico_code_show.get_node("TooltipNode").body = "Shows the current game's lobby ID. Other lobbies can never have the same ID. Players with Calico can join with this ID!" calico_code_show.disconnect("pressed", self, "_on_code_pressed") calico_code_show.connect("pressed", self, "calico_on_show_code_pressed") calico_code_display = $VBoxContainer/code_display.duplicate() calico_code_display.get_node("copy_paste").disconnect("pressed", self, "_on_copy_paste_pressed") + calico_code_display.get_node("copy_paste").get_node("TooltipNode").header = "Copy Lobby ID" + calico_code_display.get_node("copy_paste").get_node("TooltipNode").body = "Copies the lobby ID to your clipboard." calico_code_display.get_node("copy_paste").connect("pressed", self, "calico_on_copy_paste_pressed") calico_code_label = calico_code_display.get_node("Panel").get_node("code") $VBoxContainer.add_child(calico_code_show) diff --git a/Teemaw.Calico/ScriptMod/LobbyQol/LobbyQolMainMenuScriptModFactory.cs b/Teemaw.Calico/ScriptMod/LobbyQol/LobbyQolMainMenuScriptModFactory.cs new file mode 100644 index 0000000..8102a97 --- /dev/null +++ b/Teemaw.Calico/ScriptMod/LobbyQol/LobbyQolMainMenuScriptModFactory.cs @@ -0,0 +1,74 @@ +using GDWeave; +using GDWeave.Godot; +using GDWeave.Modding; +using Teemaw.Calico.LexicalTransformer; +using static GDWeave.Godot.TokenType; +using static Teemaw.Calico.LexicalTransformer.Operation; +using static Teemaw.Calico.LexicalTransformer.TransformationPatternFactory; + +namespace Teemaw.Calico.ScriptMod.LobbyQol; + +public static class LobbyQolMainMenuScriptModFactory +{ + public static IScriptMod Create(IModInterface mod) + { + return new TransformationRuleScriptModBuilder() + .ForMod(mod) + .Named("LobbyQolMainMenuScriptMod") + .Patching("res://Scenes/Menus/Main Menu/main_menu.gdc") + .AddRule(new TransformationRuleBuilder() + .Named("globals") + .Matching(CreateGlobalsPattern()) + .Do(Append) + .With( + """ + + var calico_most_players + + func calico_sort_lobbies_desc(a, b): + return Steam.getNumLobbyMembers(a) > Steam.getNumLobbyMembers(b) + + """ + ) + ) + .AddRule(new TransformationRuleBuilder() + .Named("ready") + .Matching(CreateFunctionDefinitionPattern("_ready")) + .Do(Append) + .With( + """ + + code.max_length = 14 + calico_most_players = $"%hidenames".duplicate() + calico_most_players.text = "MOST USERS" + var calico_tt = $"%hidenames".get_parent().get_node("Label").get_node("TooltipNode").duplicate() + calico_tt.header = "Calico: Most Users" + calico_tt.body = "Sorts the lobby list by user count." + calico_most_players.add_child(calico_tt) + $"%hidenames".get_parent().add_child(calico_most_players) + + """, 1 + ) + ) + .AddRule(new TransformationRuleBuilder() + .Named("lobby_list") + .Matching(CreateFunctionDefinitionPattern("_lobby_list_returned", ["lobbies"])) + .Do(Append) + .With( + """ + + if calico_most_players.pressed: + lobbies.sort_custom(self, "calico_sort_lobbies_desc") + + """, 1 + ) + ) + .AddRule(new TransformationRuleBuilder() + .Named("lobby_list_cap") + .Matching(CreateGdSnippetPattern("if created_lobbies.has(lobby): return")) + .Do(ReplaceLast) + .With(new Token(CfContinue)) + ) + .Build(); + } +} \ No newline at end of file diff --git a/Teemaw.Calico/ScriptMod/LobbyId/LobbyIdSteamNetworkScriptModFactory.cs b/Teemaw.Calico/ScriptMod/LobbyQol/LobbyQolSteamNetworkScriptModFactory.cs similarity index 56% rename from Teemaw.Calico/ScriptMod/LobbyId/LobbyIdSteamNetworkScriptModFactory.cs rename to Teemaw.Calico/ScriptMod/LobbyQol/LobbyQolSteamNetworkScriptModFactory.cs index 219e689..b295193 100644 --- a/Teemaw.Calico/ScriptMod/LobbyId/LobbyIdSteamNetworkScriptModFactory.cs +++ b/Teemaw.Calico/ScriptMod/LobbyQol/LobbyQolSteamNetworkScriptModFactory.cs @@ -4,15 +4,15 @@ using static Teemaw.Calico.LexicalTransformer.Operation; using static Teemaw.Calico.LexicalTransformer.TransformationPatternFactory; -namespace Teemaw.Calico.ScriptMod.LobbyId; +namespace Teemaw.Calico.ScriptMod.LobbyQol; -public static class LobbyIdSteamNetworkScriptModFactory +public static class LobbyQolSteamNetworkScriptModFactory { - public static IScriptMod Create(IModInterface mod) + public static IScriptMod Create(IModInterface mod, Config config) { return new TransformationRuleScriptModBuilder() .ForMod(mod) - .Named("LobbyIdSteamNetworkScriptMod") + .Named("LobbyQolSteamNetworkScriptMod") .Patching("res://Scenes/Singletons/SteamNetwork.gdc") .AddRule(new TransformationRuleBuilder() .Named("globals") @@ -74,7 +74,8 @@ func calico_base36_to_decimal(base36_str): .With( """ - CALICO_LOBBY_ID = calico_decimal_to_base36(lobby_id) + CALICO_LOBBY_ID = calico_decimal_to_base36(int(lobby_id)) + print(CALICO_LOBBY_ID) """, 1 ) @@ -87,6 +88,7 @@ func calico_base36_to_decimal(base36_str): """ CALICO_LOBBY_ID = calico_decimal_to_base36(lobby_id) + print(CALICO_LOBBY_ID) """, 2 ) @@ -100,13 +102,22 @@ func calico_base36_to_decimal(base36_str): """ var calicode = code - if code.find("-") != -1: + var use_calicode = false + if code.count("-") == 3: calicode = calico_base36_to_decimal(code) + use_calicode = true print("[calico] Calicode decoded as ", calicode) """, 1 ) ) + .AddRule(new TransformationRuleBuilder() + .Named("search_for_lobby_skip_code") + .ScopedTo(CreateFunctionDefinitionPattern("_search_for_lobby", ["code"])) + .Matching(CreateGdSnippetPattern("if lobbies.size() > 0:")) + .Do(ReplaceAll) + .With("if lobbies.size() > 0 && !use_calicode:") + ) .AddRule(new TransformationRuleBuilder() .Named("search_for_lobby_calicode") .ScopedTo(CreateFunctionDefinitionPattern("_search_for_lobby", ["code"])) @@ -135,6 +146,71 @@ func calico_base36_to_decimal(base36_str): """, 1 ) ) + .AddRule(new TransformationRuleBuilder() + .Named("send_p2p_packet_ignore_banned") + .ScopedTo(CreateGdSnippetPattern( + config.MultiThreadNetworkingEnabled + ? "func _calico_send_P2P_packet_on_thread(packet):" + : "func _send_P2P_Packet(packet_data, target = \"all\", type = 0, channel = 0):")) + .Matching(CreateGdSnippetPattern( + """ + for MEMBER in LOBBY_MEMBERS: + Steam.sendP2PPacket(MEMBER["steam_id"], PACKET_DATA, SEND_TYPE, CHANNEL) + """, 2 + )) + .Do(ReplaceAll) + .With( + """ + for MEMBER in LOBBY_MEMBERS: + if !FORCE_DISCONNECT_PLAYERS.has(MEMBER["steam_id"]): + Steam.sendP2PPacket(MEMBER["steam_id"], PACKET_DATA, SEND_TYPE, CHANNEL) + """, 2 + ) + ) + .AddRule(new TransformationRuleBuilder() + .Named("lobby_chat_update_join") + .ScopedTo(CreateFunctionDefinitionPattern("_on_Lobby_Chat_Update", + ["lobby_id", "changed_id", "making_change_id", "chat_state"])) + .Matching(CreateGdSnippetPattern( + """ + _delayed_chat_update_message(making_change_id, "%u joined the game.", 1.5) + emit_signal("_user_connected", making_change_id) + """, 2 + )) + .Do(ReplaceAll) + .With( + """ + + if !FORCE_DISCONNECT_PLAYERS.has(int(making_change_id)): + _delayed_chat_update_message(making_change_id, "%u joined the game.", 1.5) + emit_signal("_user_connected", making_change_id) + + """, 2 + ) + ) + .AddRule(new TransformationRuleBuilder() + .Named("lobby_chat_update_leave") + .ScopedTo(CreateFunctionDefinitionPattern("_on_Lobby_Chat_Update", + ["lobby_id", "changed_id", "making_change_id", "chat_state"])) + .Matching(CreateGdSnippetPattern( + """ + _recieve_safe_message(making_change_id, "ffeed5", "%u left the game.", false) + emit_signal("_user_disconnected", making_change_id) + + Steam.closeP2PSessionWithUser(making_change_id) + """, 2 + )) + .Do(ReplaceAll) + .With( + """ + + if Steam.closeP2PSessionWithUser(making_change_id): + _recieve_safe_message(making_change_id, "ffeed5", "%u left the game.", false) + emit_signal("_user_disconnected", making_change_id) + + """, 2 + ) + ) .Build(); } } \ No newline at end of file diff --git a/Teemaw.Calico/Util/WeaveUtil.cs b/Teemaw.Calico/Util/WeaveUtil.cs new file mode 100644 index 0000000..7ee82f6 --- /dev/null +++ b/Teemaw.Calico/Util/WeaveUtil.cs @@ -0,0 +1,9 @@ +using GDWeave; + +namespace Teemaw.Calico.Util; + +public static class WeaveUtil +{ + public static bool IsModLoaded(IModInterface modInterface, string modName) => + modInterface.LoadedMods.Contains(modName); +} \ No newline at end of file