diff --git a/src/Account.cc b/src/Account.cc index e6f081af..9766b580 100644 --- a/src/Account.cc +++ b/src/Account.cc @@ -415,6 +415,29 @@ void Account::delete_file() const { remove(filename.c_str()); } +string Login::str() const { + string ret = phosg::string_printf("Account:%08" PRIX32, this->account->account_id); + if (this->account_was_created) { + ret += " (new)"; + } + if (this->dc_nte_license) { + ret += phosg::string_printf(" via DC NTE serial number %s", this->dc_nte_license->serial_number.c_str()); + } else if (this->dc_license) { + ret += phosg::string_printf(" via DC serial number %08" PRIX32, this->dc_license->serial_number); + } else if (this->pc_license) { + ret += phosg::string_printf(" via PC serial number %08" PRIX32, this->pc_license->serial_number); + } else if (this->gc_license) { + ret += phosg::string_printf(" via GC serial number %010" PRIu32, this->gc_license->serial_number); + } else if (this->xb_license) { + ret += phosg::string_printf(" via XB user ID %016" PRIX64, this->xb_license->user_id); + } else if (this->bb_license) { + ret += phosg::string_printf(" via BB username %s", this->bb_license->username.c_str()); + } else { + ret += phosg::string_printf(" artificially"); + } + return ret; +} + size_t AccountIndex::count() const { shared_lock g(this->lock); return this->by_account_id.size(); diff --git a/src/Account.hh b/src/Account.hh index 976781f3..aa2ddd46 100644 --- a/src/Account.hh +++ b/src/Account.hh @@ -156,6 +156,8 @@ struct Login { std::shared_ptr gc_license; std::shared_ptr xb_license; std::shared_ptr bb_license; + + std::string str() const; }; class AccountIndex { diff --git a/src/Client.cc b/src/Client.cc index 70c7d8bc..20ffa934 100644 --- a/src/Client.cc +++ b/src/Client.cc @@ -274,10 +274,12 @@ void Client::update_channel_name() { auto player = this->character(false, false); if (player) { string name_str = player->disp.name.decode(this->language()); - this->channel.name = phosg::string_printf("C-%" PRIX64 " (%s) @ %s", this->id, name_str.c_str(), ip_str.c_str()); + size_t level = player->disp.stats.level + 1; + this->channel.name = phosg::string_printf("C-%" PRIX64 " (%s Lv.%zu) @ %s", this->id, name_str.c_str(), level, ip_str.c_str()); } else { this->channel.name = phosg::string_printf("C-%" PRIX64 " @ %s", this->id, ip_str.c_str()); } + this->log.info("Channel name updated from player data: %s", this->channel.name.c_str()); } void Client::reschedule_save_game_data_event() { @@ -479,6 +481,14 @@ void Client::suspend_timeouts() { this->log.info("Timeouts suspended"); } +void Client::set_login(shared_ptr login) { + this->login = login; + if (this->log.should_log(phosg::LogLevel::INFO)) { + string login_str = this->login->str(); + this->log.info("Login: %s", login_str.c_str()); + } +} + void Client::create_battle_overlay(shared_ptr rules, shared_ptr level_table) { this->overlay_character_data = make_shared(*this->character(true, false)); diff --git a/src/Client.hh b/src/Client.hh index 13518e2a..77057d00 100644 --- a/src/Client.hh +++ b/src/Client.hh @@ -336,8 +336,7 @@ public: void suspend_timeouts(); - const std::string& get_bb_username() const; - void set_bb_username(const std::string& bb_username); + void set_login(std::shared_ptr login); void create_battle_overlay(std::shared_ptr rules, std::shared_ptr level_table); void create_challenge_overlay(Version version, size_t template_index, std::shared_ptr level_table); diff --git a/src/PatchServer.hh b/src/PatchServer.hh index d71a04f3..b60f9776 100644 --- a/src/PatchServer.hh +++ b/src/PatchServer.hh @@ -74,9 +74,6 @@ private: static void dispatch_idle_timeout(evutil_socket_t, short, void* ctx); void idle_timeout(); - - const std::string& get_bb_username() const; - void set_bb_username(const std::string& bb_username); }; struct ListeningSocket { diff --git a/src/ProxyServer.cc b/src/ProxyServer.cc index 0d048e69..7005f15e 100644 --- a/src/ProxyServer.cc +++ b/src/ProxyServer.cc @@ -278,6 +278,14 @@ std::shared_ptr ProxyServer::UnlinkedSession::require_server_state( return this->require_server()->state; } +void ProxyServer::UnlinkedSession::set_login(std::shared_ptr login) { + this->login = login; + if (this->log.should_log(phosg::LogLevel::INFO)) { + string login_str = this->login->str(); + this->log.info("Login: %s", login_str.c_str()); + } +} + void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint32_t, std::string& data) { auto* ses = reinterpret_cast(ch.context_obj); auto server = ses->require_server(); @@ -298,7 +306,7 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3 ses->log.info("Version changed to DC_NTE"); ses->config.specific_version = SPECIFIC_VERSION_DC_NTE; const auto& cmd = check_size_t(data, sizeof(C_LoginExtended_DCNTE_8B)); - ses->login = s->account_index->from_dc_nte_credentials(cmd.serial_number.decode(), cmd.access_key.decode(), false); + ses->set_login(s->account_index->from_dc_nte_credentials(cmd.serial_number.decode(), cmd.access_key.decode(), false)); ses->sub_version = cmd.sub_version; ses->channel.language = cmd.language; ses->character_name = cmd.name.decode(ses->channel.language); @@ -310,8 +318,8 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3 ses->config.specific_version = SPECIFIC_VERSION_DC_V1_INDETERMINATE; } const auto& cmd = check_size_t(data); - ses->login = s->account_index->from_dc_credentials( - stoul(cmd.serial_number.decode(), nullptr, 16), cmd.access_key.decode(), cmd.name.decode(), false); + ses->set_login(s->account_index->from_dc_credentials( + stoul(cmd.serial_number.decode(), nullptr, 16), cmd.access_key.decode(), cmd.name.decode(), false)); ses->sub_version = cmd.sub_version; ses->channel.language = cmd.language; ses->character_name = cmd.name.decode(ses->channel.language); @@ -322,16 +330,16 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3 ses->log.info("Version changed to GC_NTE"); ses->channel.version = Version::GC_NTE; ses->config.specific_version = SPECIFIC_VERSION_GC_NTE; - ses->login = s->account_index->from_gc_credentials( - stoul(cmd.serial_number.decode(), nullptr, 16), cmd.access_key.decode(), nullptr, cmd.name.decode(), false); + ses->set_login(s->account_index->from_gc_credentials( + stoul(cmd.serial_number.decode(), nullptr, 16), cmd.access_key.decode(), nullptr, cmd.name.decode(), false)); } else { // DC V2 ses->log.info("Version changed to DC_V2"); ses->channel.version = Version::DC_V2; if (specific_version_is_indeterminate(ses->config.specific_version)) { ses->config.specific_version = SPECIFIC_VERSION_DC_V2_INDETERMINATE; } - ses->login = s->account_index->from_dc_credentials( - stoul(cmd.serial_number.decode(), nullptr, 16), cmd.access_key.decode(), cmd.name.decode(), false); + ses->set_login(s->account_index->from_dc_credentials( + stoul(cmd.serial_number.decode(), nullptr, 16), cmd.access_key.decode(), cmd.name.decode(), false)); } ses->sub_version = cmd.sub_version; ses->channel.language = cmd.language; @@ -349,8 +357,8 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3 throw runtime_error("command is not 9D"); } const auto& cmd = check_size_t(data, sizeof(C_LoginExtended_PC_9D)); - ses->login = s->account_index->from_pc_credentials( - stoul(cmd.serial_number.decode(), nullptr, 16), cmd.access_key.decode(), cmd.name.decode(), false); + ses->set_login(s->account_index->from_pc_credentials( + stoul(cmd.serial_number.decode(), nullptr, 16), cmd.access_key.decode(), cmd.name.decode(), false)); ses->sub_version = cmd.sub_version; ses->channel.language = cmd.language; ses->character_name = cmd.name.decode(ses->channel.language); @@ -363,8 +371,8 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3 // We should only get a 9E while the session is unlinked if (command == 0x9E) { const auto& cmd = check_size_t(data, sizeof(C_LoginExtended_GC_9E)); - ses->login = s->account_index->from_gc_credentials( - stoul(cmd.serial_number.decode(), nullptr, 16), cmd.access_key.decode(), nullptr, cmd.name.decode(), false); + ses->set_login(s->account_index->from_gc_credentials( + stoul(cmd.serial_number.decode(), nullptr, 16), cmd.access_key.decode(), nullptr, cmd.name.decode(), false)); ses->sub_version = cmd.sub_version; ses->channel.language = cmd.language; ses->character_name = cmd.name.decode(ses->channel.language); @@ -388,7 +396,7 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3 string xb_gamertag = cmd.serial_number.decode(); uint64_t xb_user_id = stoull(cmd.access_key.decode(), nullptr, 16); uint64_t xb_account_id = cmd.netloc.account_id; - ses->login = s->account_index->from_xb_credentials(xb_gamertag, xb_user_id, xb_account_id, false); + ses->set_login(s->account_index->from_xb_credentials(xb_gamertag, xb_user_id, xb_account_id, false)); ses->sub_version = cmd.sub_version; ses->channel.language = cmd.language; ses->character_name = cmd.name.decode(ses->channel.language); @@ -412,7 +420,7 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3 } const auto& cmd = check_size_t(data, 0xFFFF); string password = cmd.password.decode(); - ses->login = s->account_index->from_bb_credentials(cmd.username.decode(), &password, s->allow_unregistered_users); + ses->set_login(s->account_index->from_bb_credentials(cmd.username.decode(), &password, s->allow_unregistered_users)); ses->login_command_bb = std::move(data); break; } diff --git a/src/ProxyServer.hh b/src/ProxyServer.hh index 0103be02..cd48a85e 100644 --- a/src/ProxyServer.hh +++ b/src/ProxyServer.hh @@ -280,6 +280,8 @@ private: return this->channel.version; } + void set_login(std::shared_ptr login); + void receive_and_process_commands(); static void on_input(Channel& ch, uint16_t command, uint32_t flag, std::string& msg); diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index bdbae5c5..dbf8de9b 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -607,19 +607,24 @@ static void on_DB_V3(shared_ptr c, uint16_t, uint32_t, string& data) { uint32_t serial_number = stoul(cmd.serial_number.decode(), nullptr, 16); try { auto password = cmd.password.decode(); - c->login = s->account_index->from_gc_credentials( - serial_number, cmd.access_key.decode(), &password, "", s->allow_unregistered_users); + c->set_login(s->account_index->from_gc_credentials( + serial_number, cmd.access_key.decode(), &password, "", s->allow_unregistered_users)); send_command(c, 0x9A, 0x02); } catch (const AccountIndex::no_username& e) { + c->log.info("Login failed (no username)"); send_command(c, 0x9A, 0x03); } catch (const AccountIndex::incorrect_access_key& e) { + c->log.info("Login failed (incorrect access key)"); send_command(c, 0x9A, 0x03); } catch (const AccountIndex::incorrect_password& e) { + c->log.info("Login failed (incorrect password)"); send_command(c, 0x9A, 0x01); } catch (const AccountIndex::missing_account& e) { + c->log.info("Login failed (missing account)"); send_command(c, 0x9A, 0x04); } catch (const AccountIndex::account_banned& e) { + c->log.info("Login failed (account banned)"); send_command(c, 0x9A, 0x0F); } @@ -636,17 +641,21 @@ static void on_88_DCNTE(shared_ptr c, uint16_t, uint32_t, string& data) c->log.info("Game version changed to DC_NTE"); try { - c->login = s->account_index->from_dc_nte_credentials( - cmd.serial_number.decode(), cmd.access_key.decode(), s->allow_unregistered_users); + c->set_login(s->account_index->from_dc_nte_credentials( + cmd.serial_number.decode(), cmd.access_key.decode(), s->allow_unregistered_users)); send_command(c, 0x88, 0x00); } catch (const AccountIndex::no_username& e) { + c->log.info("Login failed (no username)"); send_message_box(c, "Incorrect serial number"); } catch (const AccountIndex::incorrect_access_key& e) { + c->log.info("Login failed (incorrect access key)"); send_message_box(c, "Incorrect access key"); } catch (const AccountIndex::missing_account& e) { + c->log.info("Login failed (missing account)"); send_message_box(c, "Incorrect serial number"); } catch (const AccountIndex::account_banned& e) { + c->log.info("Login failed (account banned)"); send_message_box(c, "Account is banned"); } @@ -664,14 +673,18 @@ static void on_8B_DCNTE(shared_ptr c, uint16_t, uint32_t, string& data) c->log.info("Game version changed to DC_NTE"); try { - c->login = s->account_index->from_dc_nte_credentials(cmd.serial_number.decode(), cmd.access_key.decode(), s->allow_unregistered_users); + c->set_login(s->account_index->from_dc_nte_credentials(cmd.serial_number.decode(), cmd.access_key.decode(), s->allow_unregistered_users)); } catch (const AccountIndex::no_username& e) { + c->log.info("Login failed (no username)"); send_message_box(c, "Incorrect serial number"); } catch (const AccountIndex::incorrect_access_key& e) { + c->log.info("Login failed (incorrect access key)"); send_message_box(c, "Incorrect access key"); } catch (const AccountIndex::missing_account& e) { + c->log.info("Login failed (missing account)"); send_message_box(c, "Incorrect serial number"); } catch (const AccountIndex::account_banned& e) { + c->log.info("Login failed (account banned)"); send_message_box(c, "Account is banned"); } @@ -705,20 +718,28 @@ static void on_90_DC(shared_ptr c, uint16_t, uint32_t, string& data) { uint32_t serial_number = 0; try { if (serial_number_str.size() > 8 || access_key_str.size() > 8) { - c->login = s->account_index->from_dc_nte_credentials(serial_number_str, access_key_str, s->allow_unregistered_users); + c->set_login(s->account_index->from_dc_nte_credentials(serial_number_str, access_key_str, s->allow_unregistered_users)); } else { serial_number = stoull(serial_number_str, nullptr, 16); - c->login = s->account_index->from_dc_credentials(serial_number, access_key_str, "", s->allow_unregistered_users); + c->set_login(s->account_index->from_dc_credentials(serial_number, access_key_str, "", s->allow_unregistered_users)); + } + if (c->log.should_log(phosg::LogLevel::INFO)) { + string login_str = c->login->str(); + c->log.info("Received login: %s", login_str.c_str()); } send_command(c, 0x90, 0x01); } catch (const AccountIndex::no_username& e) { + c->log.info("Login failed (no username)"); send_command(c, 0x90, 0x03); } catch (const AccountIndex::incorrect_access_key& e) { + c->log.info("Login failed (incorrect access key)"); send_command(c, 0x90, 0x03); } catch (const AccountIndex::missing_account& e) { + c->log.info("Login failed (no account)"); send_command(c, 0x90, 0x03); } catch (const AccountIndex::account_banned& e) { + c->log.info("Login failed (account banned)"); send_command(c, 0x90, 0x0F); } c->should_disconnect = !c->login; @@ -754,20 +775,28 @@ static void on_93_DC(shared_ptr c, uint16_t, uint32_t, string& data) { uint32_t serial_number = 0; try { if (serial_number_str.size() > 8 || access_key_str.size() > 8) { - c->login = s->account_index->from_dc_nte_credentials(serial_number_str, access_key_str, s->allow_unregistered_users); + c->set_login(s->account_index->from_dc_nte_credentials(serial_number_str, access_key_str, s->allow_unregistered_users)); } else { serial_number = stoull(serial_number_str, nullptr, 16); - c->login = s->account_index->from_dc_credentials( - serial_number, access_key_str, cmd.name.decode(), s->allow_unregistered_users); + c->set_login(s->account_index->from_dc_credentials( + serial_number, access_key_str, cmd.name.decode(), s->allow_unregistered_users)); + } + if (c->log.should_log(phosg::LogLevel::INFO)) { + string login_str = c->login->str(); + c->log.info("Login: %s", login_str.c_str()); } } catch (const AccountIndex::no_username& e) { + c->log.info("Login failed (no username)"); send_message_box(c, "Incorrect serial number"); } catch (const AccountIndex::incorrect_access_key& e) { + c->log.info("Login failed (incorrect access key)"); send_message_box(c, "Incorrect access key"); } catch (const AccountIndex::missing_account& e) { + c->log.info("Login failed (no account)"); send_message_box(c, "Incorrect serial number"); } catch (const AccountIndex::account_banned& e) { + c->log.info("Login failed (account banned)"); send_message_box(c, "Account is banned"); } if (!c->login) { @@ -813,8 +842,12 @@ static void on_9A(shared_ptr c, uint16_t, uint32_t, string& data) { switch (c->version()) { case Version::DC_V2: { uint32_t serial_number = stoul(cmd.serial_number.decode(), nullptr, 16); - c->login = s->account_index->from_dc_credentials( - serial_number, cmd.access_key.decode(), "", s->allow_unregistered_users); + c->set_login(s->account_index->from_dc_credentials( + serial_number, cmd.access_key.decode(), "", s->allow_unregistered_users)); + if (c->log.should_log(phosg::LogLevel::INFO)) { + string login_str = c->login->str(); + c->log.info("Login: %s", login_str.c_str()); + } break; } case Version::PC_NTE: @@ -829,12 +862,13 @@ static void on_9A(shared_ptr c, uint16_t, uint32_t, string& data) { cmd.email_address.empty()) { c->channel.version = Version::PC_NTE; c->log.info("Changed client version to PC_NTE"); - c->login = s->account_index->from_pc_nte_credentials( - cmd.guild_card_number, s->allow_unregistered_users && s->allow_pc_nte); + c->set_login(s->account_index->from_pc_nte_credentials( + cmd.guild_card_number, s->allow_unregistered_users && s->allow_pc_nte)); + } else { uint32_t serial_number = stoul(cmd.serial_number.decode(), nullptr, 16); - c->login = s->account_index->from_pc_credentials( - serial_number, cmd.access_key.decode(), "", s->allow_unregistered_users); + c->set_login(s->account_index->from_pc_credentials( + serial_number, cmd.access_key.decode(), "", s->allow_unregistered_users)); } break; } @@ -847,7 +881,7 @@ static void on_9A(shared_ptr c, uint16_t, uint32_t, string& data) { // password already, which should have created an account if needed. So // if no account exists at this point, disconnect the client even if // unregistered users are allowed. - c->login = s->account_index->from_gc_credentials(serial_number, cmd.access_key.decode(), nullptr, "", false); + c->set_login(s->account_index->from_gc_credentials(serial_number, cmd.access_key.decode(), nullptr, "", false)); break; } default: @@ -856,14 +890,19 @@ static void on_9A(shared_ptr c, uint16_t, uint32_t, string& data) { send_command(c, 0x9A, 0x02); } catch (const AccountIndex::no_username& e) { + c->log.info("Login failed (no username)"); send_command(c, 0x9A, 0x03); } catch (const AccountIndex::incorrect_access_key& e) { + c->log.info("Login failed (incorrect access key)"); send_command(c, 0x9A, 0x03); } catch (const AccountIndex::incorrect_password& e) { + c->log.info("Login failed (incorrect password)"); send_command(c, 0x9A, 0x01); } catch (const AccountIndex::missing_account& e) { + c->log.info("Login failed (missing account)"); send_command(c, 0x9A, 0x03); } catch (const AccountIndex::account_banned& e) { + c->log.info("Login failed (account banned)"); send_command(c, 0x9A, 0x0F); } @@ -881,17 +920,17 @@ static void on_9C(shared_ptr c, uint16_t, uint32_t, string& data) { try { switch (c->version()) { case Version::DC_V2: - c->login = s->account_index->from_dc_credentials(serial_number, cmd.access_key.decode(), "", false); + c->set_login(s->account_index->from_dc_credentials(serial_number, cmd.access_key.decode(), "", false)); break; case Version::PC_V2: - c->login = s->account_index->from_pc_credentials(serial_number, cmd.access_key.decode(), "", false); + c->set_login(s->account_index->from_pc_credentials(serial_number, cmd.access_key.decode(), "", false)); break; case Version::GC_NTE: case Version::GC_V3: case Version::GC_EP3_NTE: case Version::GC_EP3: { string password = cmd.password.decode(); - c->login = s->account_index->from_gc_credentials(serial_number, cmd.access_key.decode(), &password, "", false); + c->set_login(s->account_index->from_gc_credentials(serial_number, cmd.access_key.decode(), &password, "", false)); break; } default: @@ -902,12 +941,16 @@ static void on_9C(shared_ptr c, uint16_t, uint32_t, string& data) { send_command(c, 0x9C, 0x01); } catch (const AccountIndex::no_username& e) { + c->log.info("Login failed (no username)"); send_message_box(c, "Incorrect serial number"); } catch (const AccountIndex::incorrect_password& e) { + c->log.info("Login failed (incorrect password)"); send_command(c, 0x9C, 0x00); } catch (const AccountIndex::missing_account& e) { + c->log.info("Login failed (missing account)"); send_command(c, 0x9C, 0x00); } catch (const AccountIndex::account_banned& e) { + c->log.info("Login failed (account banned)"); send_message_box(c, "Account is banned"); } c->should_disconnect = !c->login; @@ -962,8 +1005,8 @@ static void on_9D_9E(shared_ptr c, uint16_t command, uint32_t, string& d switch (c->version()) { case Version::DC_V2: { uint32_t serial_number = stoul(base_cmd->serial_number.decode(), nullptr, 16); - c->login = s->account_index->from_dc_credentials( - serial_number, base_cmd->access_key.decode(), base_cmd->name.decode(), s->allow_unregistered_users); + c->set_login(s->account_index->from_dc_credentials( + serial_number, base_cmd->access_key.decode(), base_cmd->name.decode(), s->allow_unregistered_users)); break; } case Version::PC_NTE: @@ -977,12 +1020,12 @@ static void on_9D_9E(shared_ptr c, uint16_t command, uint32_t, string& d base_cmd->access_key2.empty()) { c->channel.version = Version::PC_NTE; c->log.info("Changed client version to PC_NTE"); - c->login = s->account_index->from_pc_nte_credentials( - base_cmd->guild_card_number, s->allow_unregistered_users && s->allow_pc_nte); + c->set_login(s->account_index->from_pc_nte_credentials( + base_cmd->guild_card_number, s->allow_unregistered_users && s->allow_pc_nte)); } else { uint32_t serial_number = stoul(base_cmd->serial_number.decode(), nullptr, 16); - c->login = s->account_index->from_pc_credentials( - serial_number, base_cmd->access_key.decode(), base_cmd->name.decode(), s->allow_unregistered_users); + c->set_login(s->account_index->from_pc_credentials( + serial_number, base_cmd->access_key.decode(), base_cmd->name.decode(), s->allow_unregistered_users)); } break; case Version::GC_NTE: @@ -992,8 +1035,8 @@ static void on_9D_9E(shared_ptr c, uint16_t command, uint32_t, string& d uint32_t serial_number = stoul(base_cmd->serial_number.decode(), nullptr, 16); // GC clients should have sent a DB command first which would have // created the account if needed - c->login = s->account_index->from_gc_credentials( - serial_number, base_cmd->access_key.decode(), nullptr, base_cmd->name.decode(), false); + c->set_login(s->account_index->from_gc_credentials( + serial_number, base_cmd->access_key.decode(), nullptr, base_cmd->name.decode(), false)); break; } default: @@ -1001,14 +1044,19 @@ static void on_9D_9E(shared_ptr c, uint16_t command, uint32_t, string& d } } catch (const AccountIndex::no_username& e) { + c->log.info("Login failed (no username)"); send_command(c, 0x04, 0x03); } catch (const AccountIndex::incorrect_access_key& e) { + c->log.info("Login failed (incorrect access key)"); send_command(c, 0x04, 0x03); } catch (const AccountIndex::incorrect_password& e) { + c->log.info("Login failed (incorrect password)"); send_command(c, 0x04, 0x06); } catch (const AccountIndex::missing_account& e) { + c->log.info("Login failed (missing account)"); send_command(c, 0x04, 0x04); } catch (const AccountIndex::account_banned& e) { + c->log.info("Login failed (account banned)"); send_command(c, 0x04, 0x04); } @@ -1042,29 +1090,18 @@ static void on_9E_XB(shared_ptr c, uint16_t, uint32_t, string& data) { uint64_t xb_user_id = stoull(cmd.access_key.decode(), nullptr, 16); uint64_t xb_account_id = cmd.netloc.account_id; try { - c->login = s->account_index->from_xb_credentials(xb_gamertag, xb_user_id, xb_account_id, s->allow_unregistered_users); - bool should_save = false; - if (c->login->xb_license->user_id == 0) { - c->login->xb_license->user_id = xb_user_id; - c->log.info("Set license XB user ID to %016" PRIX64, c->login->xb_license->user_id); - should_save = true; - } - if (c->login->xb_license->account_id == 0) { - c->login->xb_license->account_id = xb_account_id; - c->log.info("Set license XB account ID to %016" PRIX64, c->login->xb_license->account_id); - should_save = true; - } - if (should_save && !s->is_replay) { - c->login->account->save(); - } - + c->set_login(s->account_index->from_xb_credentials(xb_gamertag, xb_user_id, xb_account_id, s->allow_unregistered_users)); } catch (const AccountIndex::no_username& e) { + c->log.info("Login failed (no username)"); send_command(c, 0x04, 0x03); } catch (const AccountIndex::incorrect_access_key& e) { + c->log.info("Login failed (incorrect access key)"); send_command(c, 0x04, 0x03); } catch (const AccountIndex::missing_account& e) { + c->log.info("Login failed (missing account)"); send_command(c, 0x04, 0x03); } catch (const AccountIndex::account_banned& e) { + c->log.info("Login failed (account banned)"); send_command(c, 0x04, 0x04); } @@ -1093,14 +1130,18 @@ static void on_93_BB(shared_ptr c, uint16_t, uint32_t, string& data) { string password = base_cmd.password.decode(); try { - c->login = s->account_index->from_bb_credentials(username, &password, s->allow_unregistered_users); + c->set_login(s->account_index->from_bb_credentials(username, &password, s->allow_unregistered_users)); } catch (const AccountIndex::no_username& e) { + c->log.info("Login failed (no username)"); send_client_init_bb(c, 0x08); } catch (const AccountIndex::incorrect_password& e) { + c->log.info("Login failed (incorrect password)"); send_client_init_bb(c, 0x03); } catch (const AccountIndex::missing_account& e) { + c->log.info("Login failed (missing account)"); send_client_init_bb(c, 0x08); } catch (const AccountIndex::account_banned& e) { + c->log.info("Login failed (account banned)"); send_client_init_bb(c, 0x06); } if (!c->login) {