Avoid coroutine ICE in Brutal Peeps HP patch

This commit is contained in:
2026-06-06 21:15:13 -04:00
parent e44dad8344
commit f424d6ed3c
+41 -11
View File
@@ -775,21 +775,28 @@ static std::string bb_stream_file_data_for_client(std::shared_ptr<Client> c) {
} }
asio::awaitable<void> send_brutal_peeps_hp_patch_bb(std::shared_ptr<Client> c, int64_t tier) { static std::shared_ptr<AsyncPromise<C_ExecuteCodeResult_B3>> send_brutal_peeps_hp_patch_bb_now(
std::shared_ptr<Client> c,
int64_t tier) {
if (c->version() != Version::BB_V4) { if (c->version() != Version::BB_V4) {
co_return; return nullptr;
} }
if (!c->check_flag(Client::Flag::HAS_SEND_FUNCTION_CALL) || if (!c->check_flag(Client::Flag::HAS_SEND_FUNCTION_CALL) ||
!c->check_flag(Client::Flag::SEND_FUNCTION_CALL_ACTUALLY_RUNS_CODE)) { !c->check_flag(Client::Flag::SEND_FUNCTION_CALL_ACTUALLY_RUNS_CODE)) {
c->log.warning_f("Skipping Brutal Peeps HP client patch because client does not support executable send_function_call"); c->log.warning_f("Skipping Brutal Peeps HP client patch because client does not support executable send_function_call");
co_return; return nullptr;
}
if (!c->channel->connected()) {
c->log.warning_f("Skipping Brutal Peeps HP client patch because client is disconnected");
return nullptr;
} }
try {
auto s = c->require_server_state(); auto s = c->require_server_state();
const auto* brutal_peeps_def = brutal_peeps_tier_definition(tier); const auto* brutal_peeps_def = brutal_peeps_tier_definition(tier);
if ((tier >= 0) && !brutal_peeps_def) { if ((tier >= 0) && !brutal_peeps_def) {
c->log.warning_f("Skipping Brutal Peeps HP client patch for invalid tier {}", tier); c->log.warning_f("Skipping Brutal Peeps HP client patch for invalid tier {}", tier);
co_return; return nullptr;
} }
const double mult = brutal_peeps_def ? brutal_peeps_def->enemy_hp_multiplier : 1.0; const double mult = brutal_peeps_def ? brutal_peeps_def->enemy_hp_multiplier : 1.0;
@@ -803,13 +810,13 @@ asio::awaitable<void> send_brutal_peeps_hp_patch_bb(std::shared_ptr<Client> c, i
} }
if (!bp_entry) { if (!bp_entry) {
c->log.warning_f("Skipping Brutal Peeps HP client patch: BattleParamEntry_on.dat not found in BB stream file"); c->log.warning_f("Skipping Brutal Peeps HP client patch: BattleParamEntry_on.dat not found in BB stream file");
co_return; return nullptr;
} }
if ((bp_entry->offset > s->bb_stream_file->data.size()) || if ((bp_entry->offset > s->bb_stream_file->data.size()) ||
(bp_entry->size > (s->bb_stream_file->data.size() - bp_entry->offset)) || (bp_entry->size > (s->bb_stream_file->data.size() - bp_entry->offset)) ||
(bp_entry->size < sizeof(BattleParamsIndex::Table))) { (bp_entry->size < sizeof(BattleParamsIndex::Table))) {
c->log.warning_f("Skipping Brutal Peeps HP client patch: invalid BattleParamEntry_on.dat range"); c->log.warning_f("Skipping Brutal Peeps HP client patch: invalid BattleParamEntry_on.dat range");
co_return; return nullptr;
} }
const char* vanilla_data = s->bb_stream_file->data.data() + bp_entry->offset; const char* vanilla_data = s->bb_stream_file->data.data() + bp_entry->offset;
@@ -844,7 +851,7 @@ asio::awaitable<void> send_brutal_peeps_hp_patch_bb(std::shared_ptr<Client> c, i
if (bp_entry->size < signature_size) { if (bp_entry->size < signature_size) {
c->log.warning_f("Skipping Brutal Peeps HP client patch: BattleParamEntry_on.dat too small for signature"); c->log.warning_f("Skipping Brutal Peeps HP client patch: BattleParamEntry_on.dat too small for signature");
co_return; return nullptr;
} }
std::string suffix; std::string suffix;
@@ -869,11 +876,14 @@ asio::awaitable<void> send_brutal_peeps_hp_patch_bb(std::shared_ptr<Client> c, i
suffix.push_back(static_cast<char>(hp_bytes[1])); suffix.push_back(static_cast<char>(hp_bytes[1]));
} }
try {
co_await prepare_client_for_patches(c);
auto fn = s->client_functions->get("PsoPeepsBrutalPeepsHP", c->specific_version); auto fn = s->client_functions->get("PsoPeepsBrutalPeepsHP", c->specific_version);
co_await send_function_call(
c, auto promise = std::make_shared<AsyncPromise<C_ExecuteCodeResult_B3>>();
c->function_call_response_queue.emplace_back(promise);
send_function_call(
c->channel,
c->enabled_flags,
fn, fn,
{ {
{"scan_start", scan_start}, {"scan_start", scan_start},
@@ -884,14 +894,34 @@ asio::awaitable<void> send_brutal_peeps_hp_patch_bb(std::shared_ptr<Client> c, i
suffix.data(), suffix.data(),
suffix.size()); suffix.size());
c->enabled_flags |= fn->client_flag;
c->log.info_f("Brutal Peeps HP client patch sent: tier={} mult={:g} patch_bytes={} scan={:08X}-{:08X}", c->log.info_f("Brutal Peeps HP client patch sent: tier={} mult={:g} patch_bytes={} scan={:08X}-{:08X}",
tier, mult, hp_patch_bytes, scan_start, scan_end); tier, mult, hp_patch_bytes, scan_start, scan_end);
return promise;
} catch (const std::exception& e) { } catch (const std::exception& e) {
c->log.warning_f("Failed to send Brutal Peeps HP client patch: {}", e.what()); c->log.warning_f("Failed to send Brutal Peeps HP client patch: {}", e.what());
return nullptr;
} }
} }
asio::awaitable<void> send_brutal_peeps_hp_patch_bb(std::shared_ptr<Client> c, int64_t tier) {
try {
co_await prepare_client_for_patches(c);
auto promise = send_brutal_peeps_hp_patch_bb_now(c, tier);
if (promise && c->channel->connected()) {
co_await promise->get();
}
} catch (const std::exception& e) {
c->log.warning_f("Failed to complete Brutal Peeps HP client patch: {}", e.what());
}
}
void send_stream_file_index_bb(std::shared_ptr<Client> c) { void send_stream_file_index_bb(std::shared_ptr<Client> c) {
auto s = c->require_server_state(); auto s = c->require_server_state();