get client language from login command instead of player data
This commit is contained in:
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user