From 1a477b28a0b9ca4c7baf8d5dab35842a0e09e826 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Fri, 30 Sep 2022 11:41:29 -0700 Subject: [PATCH] ensure save is enabled before sending clients to proxy server --- src/Client.cc | 1 + src/Client.hh | 1 + src/ProxyCommands.cc | 1 - src/ReceiveCommands.cc | 108 +++++++++++++++++++++++------------------ 4 files changed, 62 insertions(+), 49 deletions(-) diff --git a/src/Client.cc b/src/Client.cc index 14fa70db..89c13eab 100644 --- a/src/Client.cc +++ b/src/Client.cc @@ -37,6 +37,7 @@ Client::Client( server_behavior(server_behavior), should_disconnect(false), should_send_to_lobby_server(false), + should_send_to_proxy_server(false), proxy_destination_address(0), proxy_destination_port(0), x(0.0f), diff --git a/src/Client.hh b/src/Client.hh index fcea15b2..00c4cb46 100644 --- a/src/Client.hh +++ b/src/Client.hh @@ -84,6 +84,7 @@ struct Client { ServerBehavior server_behavior; bool should_disconnect; bool should_send_to_lobby_server; + bool should_send_to_proxy_server; uint32_t proxy_destination_address; uint16_t proxy_destination_port; diff --git a/src/ProxyCommands.cc b/src/ProxyCommands.cc index 95b84cc9..6c579bae 100644 --- a/src/ProxyCommands.cc +++ b/src/ProxyCommands.cc @@ -1037,7 +1037,6 @@ template static HandlerResult S_64(shared_ptr, ProxyServer::LinkedSession& session, uint16_t, uint32_t flag, string& data) { session.clear_lobby_players(4); - session.log.info("Cleared lobby players"); session.is_in_game = true; CmdT* cmd; diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index b10bf865..3e844180 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -64,6 +64,51 @@ vector quest_download_menu({ +static void send_client_to_lobby_server(shared_ptr s, shared_ptr c) { + static const vector version_to_port_name({ + "bb-lobby", "console-lobby", "pc-lobby", "console-lobby", "console-lobby", "bb-lobby"}); + const auto& port_name = version_to_port_name.at(static_cast(c->version())); + send_reconnect(c, s->connect_address_for_client(c), + s->name_to_port_config.at(port_name)->port); +} + +static void send_client_to_proxy_server(shared_ptr s, shared_ptr c) { + static const vector version_to_port_name({ + "", "dc-proxy", "pc-proxy", "gc-proxy", "xb-proxy", "bb-proxy"}); + const auto& port_name = version_to_port_name.at(static_cast(c->version())); + uint16_t local_port = s->name_to_port_config.at(port_name)->port; + + s->proxy_server->delete_session(c->license->serial_number); + auto session = s->proxy_server->create_licensed_session( + c->license, local_port, c->version(), c->export_config_bb()); + session->infinite_hp = c->infinite_hp; + session->infinite_tp = c->infinite_tp; + session->switch_assist = c->switch_assist; + session->save_files = c->proxy_save_files; + session->suppress_remote_login = c->proxy_suppress_remote_login; + try { + string key = string_printf("proxy_remote_guild_card_number:%" PRIX32, c->license->serial_number); + const auto& entry = client_options_cache.get_or_throw(key); + session->remote_guild_card_number = stoul(entry->data, nullptr, 10); + } catch (const out_of_range&) { } + + send_reconnect(c, s->connect_address_for_client(c), local_port); +} + +static void send_proxy_destinations_menu(shared_ptr s, shared_ptr c) { + send_menu(c, u"Proxy server", MenuID::PROXY_DESTINATIONS, + s->proxy_destinations_menu_for_version(c->version())); + try { + string key = string_printf("proxy_remote_guild_card_number:%" PRIX32, c->license->serial_number); + const auto& entry = client_options_cache.get_or_throw(key); + uint32_t proxy_remote_guild_card_number = stoul(entry->data, nullptr, 10); + string info_str = string_printf("Your remote Guild\nCard number is\noverridden as\n$C6%" PRIu32, proxy_remote_guild_card_number); + send_ship_info(c, decode_sjis(info_str)); + } catch (const out_of_range&) { } +} + + + //////////////////////////////////////////////////////////////////////////////// void on_connect(std::shared_ptr s, std::shared_ptr c) { @@ -705,11 +750,9 @@ static void on_server_time_request(shared_ptr s, shared_ptr // joining the lobby. This is why we delay the 19 command until the client // responds after saving. if (c->should_send_to_lobby_server) { - static const vector version_to_port_name({ - "bb-lobby", "console-lobby", "pc-lobby", "console-lobby", "console-lobby", "bb-lobby"}); - const auto& port_name = version_to_port_name.at(static_cast(c->version())); - send_reconnect(c, s->connect_address_for_client(c), - s->name_to_port_config.at(port_name)->port); + send_client_to_lobby_server(s, c); + } else if (c->should_send_to_proxy_server) { + send_client_to_proxy_server(s, c); } } @@ -1097,11 +1140,7 @@ static void on_menu_selection(shared_ptr s, shared_ptr c, send_command(c, 0x97, 0x01); send_update_client_config(c); } else { - static const vector version_to_port_name({ - "bb-lobby", "console-lobby", "pc-lobby", "console-lobby", "console-lobby", "bb-lobby"}); - const auto& port_name = version_to_port_name.at(static_cast(c->version())); - send_reconnect(c, s->connect_address_for_client(c), - s->name_to_port_config.at(port_name)->port); + send_client_to_lobby_server(s, c); } break; } @@ -1113,15 +1152,7 @@ static void on_menu_selection(shared_ptr s, shared_ptr c, break; case MainMenuItemID::PROXY_DESTINATIONS: - send_menu(c, u"Proxy server", MenuID::PROXY_DESTINATIONS, - s->proxy_destinations_menu_for_version(c->version())); - try { - string key = string_printf("proxy_remote_guild_card_number:%" PRIX32, c->license->serial_number); - const auto& entry = client_options_cache.get_or_throw(key); - uint32_t proxy_remote_guild_card_number = stoul(entry->data, nullptr, 10); - string info_str = string_printf("Your remote Guild\nCard number is\noverridden as\n$C6%" PRIu32, proxy_remote_guild_card_number); - send_ship_info(c, decode_sjis(info_str)); - } catch (const out_of_range&) { } + send_proxy_destinations_menu(s, c); break; case MainMenuItemID::DOWNLOAD_QUESTS: @@ -1186,8 +1217,7 @@ static void on_menu_selection(shared_ptr s, shared_ptr c, case MenuID::PROXY_OPTIONS: { switch (item_id) { case ProxyOptionsMenuItemID::GO_BACK: - send_menu(c, u"Proxy server", MenuID::PROXY_DESTINATIONS, - s->proxy_destinations_menu_for_version(c->version())); + send_proxy_destinations_menu(s, c); break; case ProxyOptionsMenuItemID::INFINITE_HP: c->infinite_hp = !c->infinite_hp; @@ -1232,35 +1262,17 @@ static void on_menu_selection(shared_ptr s, shared_ptr c, send_message_box(c, u"$C6No such destination exists."); c->should_disconnect = true; } else { - // TODO: We can probably avoid using client config and reconnecting - // the client here; it's likely we could build a way to just directly - // link the client to the proxy server instead (would have to provide - // license/char name/etc. for remote auth) - - static const vector version_to_port_name({ - "", "dc-proxy", "pc-proxy", "gc-proxy", "xb-proxy", "bb-proxy"}); - const auto& port_name = version_to_port_name.at(static_cast(c->version())); - uint16_t local_port = s->name_to_port_config.at(port_name)->port; - c->proxy_destination_address = resolve_ipv4(dest->first); c->proxy_destination_port = dest->second; - send_update_client_config(c); - - s->proxy_server->delete_session(c->license->serial_number); - auto session = s->proxy_server->create_licensed_session( - c->license, local_port, c->version(), c->export_config_bb()); - session->infinite_hp = c->infinite_hp; - session->infinite_tp = c->infinite_tp; - session->switch_assist = c->switch_assist; - session->save_files = c->proxy_save_files; - session->suppress_remote_login = c->proxy_suppress_remote_login; - try { - string key = string_printf("proxy_remote_guild_card_number:%" PRIX32, c->license->serial_number); - const auto& entry = client_options_cache.get_or_throw(key); - session->remote_guild_card_number = stoul(entry->data, nullptr, 10); - } catch (const out_of_range&) { } - - send_reconnect(c, s->connect_address_for_client(c), local_port); + if (!(c->flags & Client::Flag::SAVE_ENABLED)) { + c->should_send_to_proxy_server = true; + c->flags |= Client::Flag::SAVE_ENABLED; + send_command(c, 0x97, 0x01); + send_update_client_config(c); + } else { + send_update_client_config(c); + send_client_to_proxy_server(s, c); + } } } break;