From fa9b4d7f61cb4afb31c8168337be20dbf50b951c Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Fri, 22 Dec 2023 20:21:43 -0800 Subject: [PATCH] implement $ping on proxy server --- README.md | 2 +- src/ChatCommands.cc | 11 ++++++++++- src/ProxyCommands.cc | 37 ++++++++++++++++++++++++++++--------- src/ProxyServer.hh | 2 ++ 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 1dc21f4b..34647008 100644 --- a/README.md +++ b/README.md @@ -283,7 +283,7 @@ Some commands only work on the game server and not on the proxy server. The chat * Information commands * `$li`: Shows basic information about the lobby or game you're in. If you're on the proxy server, shows information about your connection instead (remote Guild Card number, client ID, etc.). - * `$ping` (game server only): Shows round-trip ping time from the server to you. + * `$ping`: Shows round-trip ping time from the server to you. On the proxy server, shows the ping time from you to the proxy and from the proxy to the server. * `$matcount` (game server only): Shows how many of each type of material you've used. * `$what` (game server only): Shows the type, name, and stats of the nearest item on the ground. * `$where` (game server only): Shows your current floor number and coordinates. Mainly useful for debugging. diff --git a/src/ChatCommands.cc b/src/ChatCommands.cc index 08dee740..1c2d1b3f 100644 --- a/src/ChatCommands.cc +++ b/src/ChatCommands.cc @@ -168,6 +168,15 @@ static void server_command_ping(shared_ptr c, const std::string&) { send_command(c, 0x1D, 0x00); } +static void proxy_command_ping(shared_ptr ses, const std::string&) { + ses->client_ping_start_time = now(); + ses->server_ping_start_time = now(); + + C_GuildCardSearch_40 cmd = {0x00010000, ses->remote_guild_card_number, ses->remote_guild_card_number}; + ses->client_channel.send(0x1D, 0x00); + ses->server_channel.send(0x40, 0x00, &cmd, sizeof(cmd)); +} + static void proxy_command_lobby_info(shared_ptr ses, const std::string&) { string msg; // On non-masked-GC sessions (BB), there is no remote Guild Card number, so we @@ -1883,7 +1892,7 @@ static const unordered_map chat_commands({ {"$password", {server_command_password, nullptr}}, {"$patch", {server_command_patch, proxy_command_patch}}, {"$persist", {server_command_persist, nullptr}}, - {"$ping", {server_command_ping, nullptr}}, + {"$ping", {server_command_ping, proxy_command_ping}}, {"$playrec", {server_command_playrec, nullptr}}, {"$qcall", {server_command_qcall, proxy_command_qcall}}, {"$qcheck", {server_command_qcheck, nullptr}}, diff --git a/src/ProxyCommands.cc b/src/ProxyCommands.cc index 970c5644..69bd0d4c 100644 --- a/src/ProxyCommands.cc +++ b/src/ProxyCommands.cc @@ -119,6 +119,12 @@ static HandlerResult C_05(shared_ptr ses, uint16_t, } static HandlerResult C_1D(shared_ptr ses, uint16_t, uint32_t, string&) { + if (ses->client_ping_start_time) { + uint64_t ping_usecs = now() - ses->client_ping_start_time; + ses->client_ping_start_time = 0; + double ping_ms = static_cast(ping_usecs) / 1000.0; + send_text_message_printf(ses->client_channel, "To proxy: %gms", ping_ms); + } return ses->config.check_flag(Client::Flag::PROXY_SUPPRESS_CLIENT_PINGS) ? HandlerResult::Type::SUPPRESS : HandlerResult::Type::FORWARD; @@ -566,19 +572,32 @@ static HandlerResult S_V123_06(shared_ptr ses, uint1 template static HandlerResult S_41(shared_ptr ses, uint16_t, uint32_t, string& data) { - bool modified = false; if (ses->license) { auto& cmd = check_size_t(data); - if (cmd.searcher_guild_card_number == ses->remote_guild_card_number) { - cmd.searcher_guild_card_number = ses->license->serial_number; - modified = true; - } - if (cmd.result_guild_card_number == ses->remote_guild_card_number) { - cmd.result_guild_card_number = ses->license->serial_number; - modified = true; + if ((cmd.searcher_guild_card_number == ses->remote_guild_card_number) && + (cmd.result_guild_card_number == ses->remote_guild_card_number) && + ses->server_ping_start_time) { + uint64_t ping_usecs = now() - ses->server_ping_start_time; + ses->server_ping_start_time = 0; + double ping_ms = static_cast(ping_usecs) / 1000.0; + send_text_message_printf(ses->client_channel, "To server: %gms", ping_ms); + return HandlerResult::Type::SUPPRESS; + + } else { + bool modified = false; + if (cmd.searcher_guild_card_number == ses->remote_guild_card_number) { + cmd.searcher_guild_card_number = ses->license->serial_number; + modified = true; + } + if (cmd.result_guild_card_number == ses->remote_guild_card_number) { + cmd.result_guild_card_number = ses->license->serial_number; + modified = true; + } + return modified ? HandlerResult::Type::MODIFIED : HandlerResult::Type::FORWARD; } + } else { + return HandlerResult::Type::FORWARD; } - return modified ? HandlerResult::Type::MODIFIED : HandlerResult::Type::FORWARD; } constexpr on_command_t S_DGX_41 = &S_41; diff --git a/src/ProxyServer.hh b/src/ProxyServer.hh index 62dbcbad..b74e7e42 100644 --- a/src/ProxyServer.hh +++ b/src/ProxyServer.hh @@ -91,6 +91,8 @@ public: bool is_in_game; bool is_in_quest; uint8_t difficulty; + uint64_t client_ping_start_time = 0; + uint64_t server_ping_start_time = 0; std::shared_ptr detector_crypt;