From 44650179f0807ea31fb5246d69a8d454632e237a Mon Sep 17 00:00:00 2001 From: James Osborne Date: Fri, 12 Jun 2026 01:07:12 -0400 Subject: [PATCH] Route TeamSync team creation through coordinator --- src/ReceiveCommands.cc | 26 +++++++++++++++++++++++--- src/TeamSync.cc | 40 ++++++++++++++++++++++++++++++++++++---- src/TeamSync.hh | 3 ++- 3 files changed, 61 insertions(+), 8 deletions(-) diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index 2f640f12..4eda4ce4 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -6084,12 +6084,32 @@ static asio::awaitable on_EA_BB(std::shared_ptr c, Channel::Messag send_command(c, 0x02EA, 0x00000001); } else { std::string player_name = c->character_file()->disp.visual.name.decode(c->language()); - auto team = s->team_index->create(team_name, c->login->account->account_id, player_name); + std::shared_ptr team; + + if (TeamSync::relay_team_actions_enabled()) { + if (!TeamSync::enqueue_team_create(team_name, c->login->account->account_id, player_name)) { + send_command(c, 0x02EA, 0x00000001); + break; + } + + if (!co_await TeamSync::exchange_once_now()) { + send_command(c, 0x02EA, 0x00000001); + break; + } + + team = s->team_index->get_by_account_id(c->login->account->account_id); + if (!team || (team->name != team_name)) { + send_command(c, 0x02EA, 0x00000001); + break; + } + + } else { + team = s->team_index->create(team_name, c->login->account->account_id, player_name); + } + c->login->account->bb_team_id = team->team_id; c->login->account->save(); - TeamSync::enqueue_team_create(team_name, c->login->account->account_id, player_name); - send_command(c, 0x02EA, 0x00000000); send_team_metadata_change_notifications(s, team, c->login->account->account_id, TeamMetadataChange::TEAM_CREATED); } diff --git a/src/TeamSync.cc b/src/TeamSync.cc index 838cc656..f96126a7 100644 --- a/src/TeamSync.cc +++ b/src/TeamSync.cc @@ -453,13 +453,13 @@ bool relay_team_actions_enabled() { return cfg.enabled && cfg.relay_team_actions; } -void enqueue_team_create(const std::string& team_name, uint32_t creator_account_id, const std::string& creator_name) { +bool enqueue_team_create(const std::string& team_name, uint32_t creator_account_id, const std::string& creator_name) { auto cfg = get_config(); if (!cfg.enabled || !cfg.relay_team_actions) { - return; + return false; } if (team_name.empty() || creator_account_id == 0 || creator_name.empty()) { - return; + return false; } std::lock_guard g(exchange_state_mutex); @@ -468,7 +468,7 @@ void enqueue_team_create(const std::string& team_name, uint32_t creator_account_ "[TeamSync] warning outbound_event_dropped reason=queue_full source=%s team_namespace=%s type=team_create\n", source_label(cfg).c_str(), cfg.team_namespace.c_str()); - return; + return false; } OutboundEvent ev; @@ -477,6 +477,7 @@ void enqueue_team_create(const std::string& team_name, uint32_t creator_account_ ev.creator_account_id = creator_account_id; ev.creator_name = creator_name; outbound_events.emplace_back(std::move(ev)); + return true; } void set_canonical_team_state_callback(CanonicalTeamStateCallback cb) { @@ -617,6 +618,37 @@ static asio::awaitable run_empty_exchange_once(const Config& cfg) { co_return; } + +asio::awaitable exchange_once_now() { + auto cfg = get_config(); + if (!exchange_enabled(cfg) || cfg.coordinator_url.empty()) { + co_return false; + } + + try { + bool was_bootstrapped = get_exchange_state().bootstrapped; + co_await run_empty_exchange_once(cfg); + + // First exchange after startup only bootstraps cursor/seq. Run once more so + // newly queued team_create events are actually sent before the client gets + // success. + if (!was_bootstrapped) { + co_await run_empty_exchange_once(cfg); + } + + co_return true; + + } catch (const std::exception& e) { + std::fprintf(stderr, + "[TeamSync] warning exchange_once_failed source=%s team_namespace=%s error=%s\n", + source_label(cfg).c_str(), + cfg.team_namespace.c_str(), + e.what()); + co_return false; + } +} + + static asio::awaitable exchange_task() { for (;;) { auto cfg = get_config(); diff --git a/src/TeamSync.hh b/src/TeamSync.hh index 5686ff4e..ee3d33d8 100644 --- a/src/TeamSync.hh +++ b/src/TeamSync.hh @@ -34,7 +34,8 @@ bool enabled(); bool relay_team_chat_enabled(); bool relay_team_actions_enabled(); -void enqueue_team_create(const std::string& team_name, uint32_t creator_account_id, const std::string& creator_name); +bool enqueue_team_create(const std::string& team_name, uint32_t creator_account_id, const std::string& creator_name); +asio::awaitable exchange_once_now(); using CanonicalTeamStateCallback = std::function; void set_canonical_team_state_callback(CanonicalTeamStateCallback cb);