From 2615ce46ebeabe888ee4be43d56d4ce479826549 Mon Sep 17 00:00:00 2001 From: James Osborne Date: Thu, 21 May 2026 03:08:41 -0400 Subject: [PATCH] Dispatch GC EXP before game loading --- src/ReceiveCommands.cc | 58 +++++++++++++++++++++++++++++++++++++++ src/ReceiveSubcommands.cc | 55 ------------------------------------- 2 files changed, 58 insertions(+), 55 deletions(-) diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index e042fa19..2838d522 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -33,6 +33,60 @@ const char* BATTLE_TABLE_DISCONNECT_HOOK_NAME = "battle_table_state"; const char* QUEST_BARRIER_DISCONNECT_HOOK_NAME = "quest_barrier"; const char* ADD_NEXT_CLIENT_DISCONNECT_HOOK_NAME = "add_next_game_client"; + +static void dispatch_gc_v3_exp_patch_for_lobby(shared_ptr c, shared_ptr l) { + if (c->version() != Version::GC_V3) { + return; + } + if (!c->check_flag(Client::Flag::HAS_SEND_FUNCTION_CALL)) { + return; + } + if (!c->login || !c->login->account) { + return; + } + if (!c->login->account->auto_patches_enabled.count("PsoPeepsGCEXP_enabled")) { + return; + } + if (!l || !l->is_game()) { + return; + } + + const char* episode_str = nullptr; + switch (l->episode) { + case Episode::EP1: + episode_str = "ep1"; + break; + case Episode::EP2: + episode_str = "ep2"; + break; + default: + return; + } + + auto server_state = c->require_server_state(); + + string key = "PsoPeepsGCEXP_internal_"; + key += std::to_string(server_state->psopeeps_gc_exp_multiplier); + key += "x_"; + key += episode_str; + + void* lobby_token = l.get(); + if ((c->last_psopeeps_gc_exp_lobby == lobby_token) && + (c->last_psopeeps_gc_exp_key == key)) { + return; + } + + try { + auto fn = server_state->client_functions->get(key, c->specific_version); + send_function_call(c->channel, c->enabled_flags, fn); + c->enabled_flags |= fn->client_flag; + c->last_psopeeps_gc_exp_lobby = lobby_token; + c->last_psopeeps_gc_exp_key = key; + } catch (const out_of_range&) { + c->log.warning_f("GC V3 EXP dispatcher could not find client function {}", key); + } +} + static string bb_test_taint_filename(shared_ptr c) { return c->character_filename() + ".test-tainted"; } @@ -3163,6 +3217,7 @@ static void on_10_game_menu(shared_ptr c, uint32_t item_id, const std::s } switch (game->join_error_for_client(c, &password)) { case Lobby::JoinError::ALLOWED: + dispatch_gc_v3_exp_patch_for_lobby(c, game); if (!s->change_client_lobby(c, game)) { throw logic_error("client cannot join game after all preconditions satisfied"); } @@ -5290,6 +5345,7 @@ static asio::awaitable on_C1_PC(shared_ptr c, Channel::Message& ms } auto game = create_game_generic(s, c, cmd.name.decode(c->language()), cmd.password.decode(c->language()), Episode::EP1, mode, cmd.difficulty, true); if (game) { + dispatch_gc_v3_exp_patch_for_lobby(c, game); s->change_client_lobby(c, game); c->set_flag(Client::Flag::LOADING); c->log.info_f("LOADING flag set"); @@ -5372,6 +5428,7 @@ static asio::awaitable on_0C_C1_E7_EC(shared_ptr c, Channel::Messa } if (game) { + dispatch_gc_v3_exp_patch_for_lobby(c, game); s->change_client_lobby(c, game); c->set_flag(Client::Flag::LOADING); c->log.info_f("LOADING flag set"); @@ -5428,6 +5485,7 @@ static asio::awaitable on_C1_BB(shared_ptr c, Channel::Message& ms auto game = create_game_generic(s, c, cmd.name.decode(c->language()), cmd.password.decode(c->language()), episode, mode, cmd.difficulty); if (game) { + dispatch_gc_v3_exp_patch_for_lobby(c, game); s->change_client_lobby(c, game); c->set_flag(Client::Flag::LOADING); c->log.info_f("LOADING flag set"); diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index 751b6562..eea05163 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -3672,60 +3672,6 @@ static asio::awaitable dispatch_dc_v2_exp_patch(shared_ptr c) { } -static asio::awaitable dispatch_gc_v3_exp_patch(shared_ptr c) { - if (c->version() != Version::GC_V3) { - co_return; - } - if (not c->check_flag(Client::Flag::HAS_SEND_FUNCTION_CALL)) { - co_return; - } - if (not c->login || not c->login->account) { - co_return; - } - if (not c->login->account->auto_patches_enabled.count("PsoPeepsGCEXP_enabled")) { - co_return; - } - - auto l = c->require_lobby(); - if (not l->is_game()) { - co_return; - } - - const char* episode_str = nullptr; - switch (l->episode) { - case Episode::EP1: - episode_str = "ep1"; - break; - case Episode::EP2: - episode_str = "ep2"; - break; - default: - co_return; - } - - auto server_state = c->require_server_state(); - - string key = "PsoPeepsGCEXP_internal_"; - key += std::to_string(server_state->psopeeps_gc_exp_multiplier); - key += "x_"; - key += episode_str; - - void* lobby_token = l.get(); - if ((c->last_psopeeps_gc_exp_lobby == lobby_token) && - (c->last_psopeeps_gc_exp_key == key)) { - co_return; - } - - try { - auto fn = server_state->client_functions->get(key, c->specific_version); - co_await send_function_call(c, fn); - c->last_psopeeps_gc_exp_lobby = lobby_token; - c->last_psopeeps_gc_exp_key = key; - } catch (const out_of_range&) { - c->log.warning_f("GC V3 EXP dispatcher could not find client function {}", key); - } -} - static asio::awaitable on_trigger_set_event(shared_ptr c, SubcommandMessage& msg) { auto l = c->require_lobby(); if (!l->is_game()) { @@ -3733,7 +3679,6 @@ static asio::awaitable on_trigger_set_event(shared_ptr c, Subcomma } co_await dispatch_dc_v2_exp_patch(c); - co_await dispatch_gc_v3_exp_patch(c); const auto& cmd = msg.check_size_t(); auto event_sts = l->map_state->event_states_for_id(c->version(), cmd.floor, cmd.event_id);