diff --git a/src/CommandFormats.hh b/src/CommandFormats.hh index 4d8fbd1f..b484de4e 100644 --- a/src/CommandFormats.hh +++ b/src/CommandFormats.hh @@ -1431,7 +1431,10 @@ struct C_Login_DC_PC_GC_9D { ptext access_key2; // On XB, this is the XBL user ID ptext name; }; -struct C_LoginExtended_DC_PC_GC_9D : C_Login_DC_PC_GC_9D { +struct C_LoginExtended_DC_GC_9D : C_Login_DC_PC_GC_9D { + C_Login_MeetUserExtension extension; +}; +struct C_LoginExtended_PC_9D : C_Login_DC_PC_GC_9D { C_Login_MeetUserExtension extension; }; diff --git a/src/ProxyServer.cc b/src/ProxyServer.cc index e674d2fe..c4d3bfb6 100644 --- a/src/ProxyServer.cc +++ b/src/ProxyServer.cc @@ -280,7 +280,7 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3 client_config.cfg.flags |= Client::Flag::DCV1; } else if (command == 0x9D) { const auto& cmd = check_size_t( - data, sizeof(C_Login_DC_PC_GC_9D), sizeof(C_LoginExtended_DC_PC_GC_9D)); + data, sizeof(C_Login_DC_PC_GC_9D), sizeof(C_LoginExtended_DC_GC_9D)); license = session->server->state->license_manager->verify_pc( stoul(cmd.serial_number, nullptr, 16), cmd.access_key); sub_version = cmd.sub_version; @@ -297,7 +297,7 @@ 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_Login_DC_PC_GC_9D), sizeof(C_LoginExtended_DC_PC_GC_9D)); + data, sizeof(C_Login_DC_PC_GC_9D), sizeof(C_LoginExtended_PC_9D)); license = session->server->state->license_manager->verify_pc( stoul(cmd.serial_number, nullptr, 16), cmd.access_key); sub_version = cmd.sub_version; @@ -307,6 +307,7 @@ void ProxyServer::UnlinkedSession::on_input(Channel& ch, uint16_t command, uint3 } else if (session->version == GameVersion::GC) { // We should only get a 9E while the session is unlinked; if we get // anything else, disconnect + // TODO: GCTE will send 9D; we should presumably handle that too, sigh if (command != 0x9E) { throw runtime_error("command is not 9E"); } diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index e883a7a4..f446bf39 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -415,11 +415,18 @@ void process_login_d_e_dc_pc_v3(shared_ptr s, shared_ptr c, const C_Login_DC_PC_GC_9D* base_cmd; if (command == 0x9D) { base_cmd = &check_size_t(data, - sizeof(C_Login_DC_PC_GC_9D), sizeof(C_LoginExtended_DC_PC_GC_9D)); + sizeof(C_Login_DC_PC_GC_9D), sizeof(C_LoginExtended_PC_9D)); if (base_cmd->is_extended) { - const auto& cmd = check_size_t(data); - if (cmd.extension.menu_id == MenuID::LOBBY) { - c->preferred_lobby_id = cmd.extension.preferred_lobby_id; + if (c->version() == GameVersion::PC) { + const auto& cmd = check_size_t(data); + if (cmd.extension.menu_id == MenuID::LOBBY) { + c->preferred_lobby_id = cmd.extension.preferred_lobby_id; + } + } else { + const auto& cmd = check_size_t(data); + if (cmd.extension.menu_id == MenuID::LOBBY) { + c->preferred_lobby_id = cmd.extension.preferred_lobby_id; + } } } diff --git a/src/ReplaySession.cc b/src/ReplaySession.cc index 3c9afbba..016e57c2 100644 --- a/src/ReplaySession.cc +++ b/src/ReplaySession.cc @@ -106,7 +106,7 @@ void ReplaySession::check_for_password(shared_ptr ev) const { check_pw(cmd.password); } else if (header.command == 0x9D) { const auto& cmd = check_size_t(cmd_data, cmd_size, - sizeof(C_Login_DC_PC_GC_9D), sizeof(C_LoginExtended_DC_PC_GC_9D)); + sizeof(C_Login_DC_PC_GC_9D), sizeof(C_LoginExtended_PC_9D)); check_ak(cmd.v1_access_key); check_ak(cmd.access_key); check_ak(cmd.access_key2); @@ -139,7 +139,7 @@ void ReplaySession::check_for_password(shared_ptr ev) const { check_pw(cmd.password); } else if (header.command == 0x9D) { const auto& cmd = check_size_t(cmd_data, cmd_size, - sizeof(C_Login_DC_PC_GC_9D), sizeof(C_LoginExtended_DC_PC_GC_9D)); + sizeof(C_Login_DC_PC_GC_9D), sizeof(C_LoginExtended_DC_GC_9D)); check_ak(cmd.v1_access_key); check_ak(cmd.access_key); check_ak(cmd.access_key2);