get client language from login command instead of player data

This commit is contained in:
Martin Michelsen
2023-10-22 08:55:09 -07:00
parent ba7a3fc4c6
commit d2d96d9c0a
5 changed files with 29 additions and 25 deletions
+1
View File
@@ -61,6 +61,7 @@ Client::Client(
should_send_to_proxy_server(false),
proxy_destination_address(0),
proxy_destination_port(0),
language(1),
x(0.0f),
z(0.0f),
area(0),
+1 -4
View File
@@ -150,6 +150,7 @@ struct Client : public std::enable_shared_from_this<Client> {
// Lobby/positioning
ClientOptions options;
uint8_t language;
float x;
float z;
uint32_t area;
@@ -191,10 +192,6 @@ struct Client : public std::enable_shared_from_this<Client> {
void reschedule_ping_and_timeout_events();
inline uint8_t language() const {
auto p = this->game_data.player(true, false);
return p ? p->inventory.language : 1; // English by default
}
inline GameVersion version() const {
return this->channel.version;
}
+8 -9
View File
@@ -2318,7 +2318,7 @@ void Server::handle_CAx40_map_list_request(shared_ptr<Client> sender_c, const st
}
const auto& list_data = this->options.map_index->get_compressed_list(
l->count_clients(), sender_c->language());
l->count_clients(), sender_c->language);
StringWriter w;
uint32_t subcommand_size = (list_data.size() + sizeof(G_MapList_GC_Ep3_6xB6x40) + 3) & (~3);
@@ -2347,16 +2347,15 @@ void Server::send_6xB6x41_to_all_clients() const {
if (!c) {
return;
}
uint8_t language = c->language();
if (map_commands_by_language.size() <= language) {
map_commands_by_language.resize(language + 1);
if (map_commands_by_language.size() <= c->language) {
map_commands_by_language.resize(c->language + 1);
}
if (map_commands_by_language[language].empty()) {
map_commands_by_language[language] = this->prepare_6xB6x41_map_definition(
this->last_chosen_map, language, l->flags & Lobby::Flag::IS_EP3_TRIAL);
if (map_commands_by_language[c->language].empty()) {
map_commands_by_language[c->language] = this->prepare_6xB6x41_map_definition(
this->last_chosen_map, c->language, l->flags & Lobby::Flag::IS_EP3_TRIAL);
}
this->log().info("Sending %c version of map %08" PRIX32, char_for_language_code(language), this->last_chosen_map->map_number);
send_command(c, 0x6C, 0x00, map_commands_by_language[language]);
this->log().info("Sending %c version of map %08" PRIX32, char_for_language_code(c->language), this->last_chosen_map->map_number);
send_command(c, 0x6C, 0x00, map_commands_by_language[c->language]);
};
for (const auto& c : l->clients) {
send_to_client(c);
+16 -9
View File
@@ -430,6 +430,7 @@ static void on_8B_DCNTE(shared_ptr<Client> c, uint16_t, uint32_t, const string&
c->channel.version = GameVersion::DC;
c->flags |= flags_for_version(c->version(), -1);
c->flags |= Client::Flag::IS_DC_V1 | Client::Flag::IS_DC_TRIAL_EDITION;
c->language = cmd.language;
uint32_t serial_number = stoul(cmd.serial_number, nullptr, 16);
try {
@@ -505,7 +506,8 @@ static void on_90_DC(shared_ptr<Client> c, uint16_t, uint32_t, const string& dat
}
static void on_92_DC(shared_ptr<Client> c, uint16_t, uint32_t, const string& data) {
check_size_t<C_RegisterV1_DC_92>(data);
const auto& cmd = check_size_t<C_RegisterV1_DC_92>(data);
c->language = cmd.language;
// It appears that in response to 90 01, the DCv1 prototype sends 93 rather
// than 92, so we use the presence of a 92 command to determine that the
// client is actually DCv1 and not the prototype.
@@ -518,6 +520,7 @@ static void on_93_DC(shared_ptr<Client> c, uint16_t, uint32_t, const string& dat
auto s = c->require_server_state();
set_console_client_flags(c, cmd.sub_version);
c->language = cmd.language;
uint32_t serial_number = stoul(cmd.serial_number, nullptr, 16);
try {
@@ -633,6 +636,7 @@ static void on_9C(shared_ptr<Client> c, uint16_t, uint32_t, const string& data)
auto s = c->require_server_state();
set_console_client_flags(c, cmd.sub_version);
c->language = cmd.language;
uint32_t serial_number = stoul(cmd.serial_number, nullptr, 16);
try {
@@ -740,6 +744,8 @@ static void on_9D_9E(shared_ptr<Client> c, uint16_t command, uint32_t, const str
}
set_console_client_flags(c, base_cmd->sub_version);
c->language = base_cmd->language;
// See system/ppc/Episode3USAQuestBufferOverflow.s for where this value gets
// set. We use this to determine if the client has already run the code or
// not; sending it again when the client has already run it will likely cause
@@ -1494,7 +1500,7 @@ static void on_09(shared_ptr<Client> c, uint16_t, uint32_t, const string& data)
if (!q) {
send_quest_info(c, u"$C4Quest does not\nexist.", is_download_quest);
} else {
auto vq = q->version(c->quest_version(), c->language());
auto vq = q->version(c->quest_version(), c->language);
if (!vq) {
send_quest_info(c, u"$C4Quest does not\nexist for this game\nversion.", is_download_quest);
} else {
@@ -1747,7 +1753,7 @@ static void on_10(shared_ptr<Client> c, uint16_t, uint32_t, const string& data)
if (num_ep3_categories == 1) {
auto quest_index = s->quest_index_for_client(c);
if (quest_index) {
auto quests = quest_index->filter(ep3_category_id, c->quest_version(), c->language());
auto quests = quest_index->filter(ep3_category_id, c->quest_version(), c->language);
send_quest_menu(c, MenuID::QUEST, quests, true);
} else {
send_lobby_message_box(c, u"$C6Quests are not available.");
@@ -2033,7 +2039,7 @@ static void on_10(shared_ptr<Client> c, uint16_t, uint32_t, const string& data)
break;
}
shared_ptr<Lobby> l = c->lobby.lock();
auto quests = quest_index->filter(item_id, c->quest_version(), c->language());
auto quests = quest_index->filter(item_id, c->quest_version(), c->language);
// Hack: Assume the menu to be sent is the download quest menu if the
// client is not in any lobby
@@ -2089,7 +2095,7 @@ static void on_10(shared_ptr<Client> c, uint16_t, uint32_t, const string& data)
continue;
}
auto vq = q->version(lc->quest_version(), lc->language());
auto vq = q->version(lc->quest_version(), lc->language);
if (!vq) {
send_lobby_message_box(lc, u"$C6Quest does not exist\nfor this game version.");
lc->should_disconnect = true;
@@ -2137,7 +2143,7 @@ static void on_10(shared_ptr<Client> c, uint16_t, uint32_t, const string& data)
} else {
string quest_name = encode_sjis(q->name);
auto vq = q->version(c->quest_version(), c->language());
auto vq = q->version(c->quest_version(), c->language);
if (!vq) {
send_lobby_message_box(c, u"$C6Quest does not exist\nfor this game version.");
break;
@@ -2491,7 +2497,7 @@ static void on_AC_V3_BB(shared_ptr<Client> c, uint16_t, uint32_t, const string&
(l->base_version == GameVersion::BB) &&
l->map &&
l->quest) {
auto dat_contents = prs_decompress(*l->quest->version(QuestScriptVersion::BB_V4, c->language())->dat_contents);
auto dat_contents = prs_decompress(*l->quest->version(QuestScriptVersion::BB_V4, c->language)->dat_contents);
l->map->clear();
l->map->add_enemies_from_quest_data(l->episode, l->difficulty, l->event, dat_contents.data(), dat_contents.size());
c->log.info("Replaced enemies list with quest layout (%zu entries)",
@@ -2689,6 +2695,7 @@ static void on_61_98(shared_ptr<Client> c, uint16_t command, uint32_t flag, cons
throw logic_error("player data command not implemented for version");
}
player->inventory.decode_mags(c->version());
c->language = player->inventory.language;
string name_str = remove_language_marker(encode_sjis(player->disp.name));
c->channel.name = string_printf("C-%" PRIX64 " (%s)", c->id, name_str.c_str());
@@ -3663,7 +3670,7 @@ static void on_6F(shared_ptr<Client> c, uint16_t, uint32_t, const string& data)
if (!l->quest) {
throw runtime_error("JOINABLE_QUEST_IN_PROGRESS is set, but lobby has no quest");
}
auto vq = l->quest->version(c->quest_version(), c->language());
auto vq = l->quest->version(c->quest_version(), c->language);
if (!vq) {
throw runtime_error("JOINABLE_QUEST_IN_PROGRESS is set, but lobby has no quest for client version");
}
@@ -3685,7 +3692,7 @@ static void on_6F(shared_ptr<Client> c, uint16_t, uint32_t, const string& data)
} else if (watched_lobby && watched_lobby->ep3_server) {
if (!watched_lobby->ep3_server->battle_finished) {
watched_lobby->ep3_server->send_commands_for_joining_spectator(
c->channel, c->language(), c->flags & Client::Flag::IS_EP3_TRIAL_EDITION);
c->channel, c->language, c->flags & Client::Flag::IS_EP3_TRIAL_EDITION);
}
send_ep3_update_game_metadata(watched_lobby);
}
+3 -3
View File
@@ -1279,7 +1279,7 @@ void send_quest_menu_t(
auto v = c->quest_version();
vector<EntryT> entries;
for (const auto& quest : quests) {
auto vq = quest->version(v, c->language());
auto vq = quest->version(v, c->language);
if (!vq) {
continue;
}
@@ -2390,7 +2390,7 @@ void send_ep3_tournament_details(
shared_ptr<const Episode3::Tournament> tourn) {
S_TournamentGameDetails_GC_Ep3_E3 cmd;
cmd.name = tourn->get_name();
cmd.map_name = tourn->get_map()->version(c->language())->map->name;
cmd.map_name = tourn->get_map()->version(c->language)->map->name;
cmd.rules = tourn->get_rules();
const auto& teams = tourn->all_teams();
for (size_t z = 0; z < min<size_t>(teams.size(), 0x20); z++) {
@@ -2431,7 +2431,7 @@ void send_ep3_game_details(shared_ptr<Client> c, shared_ptr<Lobby> l) {
S_TournamentGameDetails_GC_Ep3_E3 cmd;
cmd.name = encode_sjis(l->name);
cmd.map_name = tourn->get_map()->version(c->language())->map->name;
cmd.map_name = tourn->get_map()->version(c->language)->map->name;
cmd.rules = tourn->get_rules();
const auto& teams = tourn->all_teams();