rewrite client config; use BB state from login command

This commit is contained in:
Martin Michelsen
2023-10-30 13:15:41 -07:00
parent 47198779b7
commit 5e2e38f1b5
29 changed files with 1139 additions and 1192 deletions
+94 -75
View File
@@ -84,7 +84,7 @@ void send_command_excluding_client(shared_ptr<Lobby> l, shared_ptr<Client> c,
void send_command_if_not_loading(shared_ptr<Lobby> l,
uint16_t command, uint32_t flag, const void* data, size_t size) {
for (auto& client : l->clients) {
if (!client || (client->flags & Client::Flag::LOADING)) {
if (!client || client->config.check_flag(Client::Flag::LOADING)) {
continue;
}
send_command(client, command, flag, data, size);
@@ -246,11 +246,31 @@ void send_server_init(shared_ptr<Client> c, uint8_t flags) {
}
void send_update_client_config(shared_ptr<Client> c) {
S_UpdateClientConfig_DC_PC_V3_04 cmd;
cmd.player_tag = 0x00010000;
cmd.guild_card_number = c->license->serial_number;
cmd.cfg = c->export_config();
send_command_t(c, 0x04, 0x00, cmd);
switch (c->version()) {
case GameVersion::DC:
case GameVersion::PC: {
if (!c->config.check_flag(Client::Flag::HAS_GUILD_CARD_NUMBER)) {
c->config.set_flag(Client::Flag::HAS_GUILD_CARD_NUMBER);
S_UpdateClientConfig_DC_PC_04 cmd;
cmd.player_tag = 0x00010000;
cmd.guild_card_number = c->license->serial_number;
send_command_t(c, 0x04, 0x00, cmd);
}
break;
}
case GameVersion::GC:
case GameVersion::XB: {
c->config.set_flag(Client::Flag::HAS_GUILD_CARD_NUMBER);
S_UpdateClientConfig_V3_04 cmd;
cmd.player_tag = 0x00010000;
cmd.guild_card_number = c->license->serial_number;
c->config.serialize_into(cmd.client_config);
send_command_t(c, 0x04, 0x00, cmd);
break;
}
default:
throw logic_error("send_update_client_config called on incorrect game version");
}
}
template <typename CommandT>
@@ -325,15 +345,15 @@ void prepare_client_for_patches(shared_ptr<Client> c, std::function<void()> on_c
return;
}
if (c->version() == GameVersion::GC &&
c->specific_version == default_specific_version_for_version(GameVersion::GC, -1)) {
c->config.specific_version == default_specific_version_for_version(GameVersion::GC, -1)) {
send_function_call(c, s->function_code_index->name_to_function.at("VersionDetect"));
c->function_call_response_queue.emplace_back([wc = weak_ptr<Client>(c), on_complete](uint32_t specific_version, uint32_t) -> void {
auto c = wc.lock();
if (!c) {
return;
}
c->specific_version = specific_version;
c->log.info("Version detected as %08" PRIX32, c->specific_version);
c->config.specific_version = specific_version;
c->log.info("Version detected as %08" PRIX32, c->config.specific_version);
on_complete();
});
} else {
@@ -341,7 +361,7 @@ void prepare_client_for_patches(shared_ptr<Client> c, std::function<void()> on_c
}
};
if (!(c->flags & Client::Flag::SEND_FUNCTION_CALL_NO_CACHE_PATCH)) {
if (!c->config.check_flag(Client::Flag::SEND_FUNCTION_CALL_NO_CACHE_PATCH)) {
send_function_call(c, s->function_code_index->name_to_function.at("CacheClearFix-Phase1"), {}, "", 0x80000000, 8, 0x7F2734EC);
c->function_call_response_queue.emplace_back([s, wc = weak_ptr<Client>(c), send_version_detect](uint32_t, uint32_t header_checksum) -> void {
auto c = wc.lock();
@@ -349,8 +369,8 @@ void prepare_client_for_patches(shared_ptr<Client> c, std::function<void()> on_c
return;
}
try {
c->specific_version = specific_version_for_gc_header_checksum(header_checksum);
c->log.info("Version detected as %08" PRIX32 " from header checksum %08" PRIX32, c->specific_version, header_checksum);
c->config.specific_version = specific_version_for_gc_header_checksum(header_checksum);
c->log.info("Version detected as %08" PRIX32 " from header checksum %08" PRIX32, c->config.specific_version, header_checksum);
} catch (const out_of_range&) {
c->log.info("Could not detect specific version from header checksum %08" PRIX32, header_checksum);
}
@@ -361,7 +381,7 @@ void prepare_client_for_patches(shared_ptr<Client> c, std::function<void()> on_c
return;
}
c->log.info("Client cache behavior patched");
c->flags |= Client::Flag::SEND_FUNCTION_CALL_NO_CACHE_PATCH;
c->config.set_flag(Client::Flag::SEND_FUNCTION_CALL_NO_CACHE_PATCH);
send_update_client_config(c);
send_version_detect();
});
@@ -381,7 +401,7 @@ void send_function_call(
uint32_t override_relocations_offset) {
return send_function_call(
c->channel,
c->flags,
c->config,
code,
label_writes,
suffix,
@@ -392,17 +412,17 @@ void send_function_call(
void send_function_call(
Channel& ch,
uint64_t client_flags,
const Client::Config& client_config,
shared_ptr<CompiledFunctionCode> code,
const unordered_map<string, uint32_t>& label_writes,
const string& suffix,
uint32_t checksum_addr,
uint32_t checksum_size,
uint32_t override_relocations_offset) {
if (client_flags & Client::Flag::NO_SEND_FUNCTION_CALL) {
if (client_config.check_flag(Client::Flag::NO_SEND_FUNCTION_CALL)) {
throw logic_error("client does not support function calls");
}
if (code.get() && (client_flags & Client::Flag::SEND_FUNCTION_CALL_CHECKSUM_ONLY)) {
if (code.get() && client_config.check_flag(Client::Flag::SEND_FUNCTION_CALL_CHECKSUM_ONLY)) {
throw logic_error("client only supports checksums in send_function_call");
}
@@ -412,7 +432,7 @@ void send_function_call(
data = code->generate_client_command(label_writes, suffix, override_relocations_offset);
index = code->index;
if (client_flags & Client::Flag::ENCRYPTED_SEND_FUNCTION_CALL) {
if (client_config.check_flag(Client::Flag::ENCRYPTED_SEND_FUNCTION_CALL)) {
uint32_t key = random_object<uint32_t>();
// This format was probably never used on any little-endian system, but we
@@ -469,13 +489,13 @@ void send_pc_console_split_reconnect(shared_ptr<Client> c, uint32_t address,
send_command_t(c, 0x19, 0x00, cmd);
}
void send_client_init_bb(shared_ptr<Client> c, uint32_t error) {
void send_client_init_bb(shared_ptr<Client> c, uint32_t error_code) {
S_ClientInit_BB_00E6 cmd;
cmd.error = error;
cmd.error_code = error_code;
cmd.player_tag = 0x00010000;
cmd.guild_card_number = c->license->serial_number;
cmd.team_id = static_cast<uint32_t>(random_object<uint32_t>());
cmd.cfg = c->export_config_bb();
c->config.serialize_into(cmd.client_config);
cmd.can_create_team = 1;
cmd.episode_4_unlocked = 1;
send_command_t(c, 0x00E6, 0x00000000, cmd);
@@ -744,11 +764,11 @@ void send_message_box(shared_ptr<Client> c, const string& text) {
default:
throw logic_error("invalid game version");
}
send_text(c->channel, command, text, (c->flags & Client::Flag::IS_DC_TRIAL_EDITION) ? ColorMode::STRIP : ColorMode::ADD);
send_text(c->channel, command, text, c->config.check_flag(Client::Flag::IS_DC_TRIAL_EDITION) ? ColorMode::STRIP : ColorMode::ADD);
}
void send_ep3_timed_message_box(Channel& ch, uint32_t frames, const string& message) {
string encoded = tt_encode_marked(message, ch.language, false);
string encoded = tt_encode_marked(add_color(message), ch.language, false);
StringWriter w;
w.put<S_TimedMessageBoxHeader_GC_Ep3_EA>({frames});
w.write(encoded);
@@ -766,15 +786,15 @@ void send_lobby_name(shared_ptr<Client> c, const string& text) {
void send_quest_info(shared_ptr<Client> c, const string& text, bool is_download_quest) {
send_text(
c->channel, is_download_quest ? 0xA5 : 0xA3, text,
(c->flags & Client::Flag::IS_DC_TRIAL_EDITION) ? ColorMode::STRIP : ColorMode::ADD);
c->config.check_flag(Client::Flag::IS_DC_TRIAL_EDITION) ? ColorMode::STRIP : ColorMode::ADD);
}
void send_lobby_message_box(shared_ptr<Client> c, const string& text) {
send_header_text(c->channel, 0x01, 0, text, (c->flags & Client::Flag::IS_DC_TRIAL_EDITION) ? ColorMode::STRIP : ColorMode::ADD);
send_header_text(c->channel, 0x01, 0, text, c->config.check_flag(Client::Flag::IS_DC_TRIAL_EDITION) ? ColorMode::STRIP : ColorMode::ADD);
}
void send_ship_info(shared_ptr<Client> c, const string& text) {
send_header_text(c->channel, 0x11, 0, text, (c->flags & Client::Flag::IS_DC_TRIAL_EDITION) ? ColorMode::STRIP : ColorMode::ADD);
send_header_text(c->channel, 0x11, 0, text, c->config.check_flag(Client::Flag::IS_DC_TRIAL_EDITION) ? ColorMode::STRIP : ColorMode::ADD);
}
void send_ship_info(Channel& ch, const string& text) {
@@ -786,7 +806,7 @@ void send_text_message(Channel& ch, const string& text) {
}
void send_text_message(shared_ptr<Client> c, const string& text) {
if (!(c->flags & Client::Flag::IS_DC_TRIAL_EDITION)) {
if (!c->config.check_flag(Client::Flag::IS_DC_TRIAL_EDITION)) {
send_header_text(c->channel, 0xB0, 0, text, ColorMode::ADD);
}
}
@@ -814,7 +834,7 @@ __attribute__((format(printf, 2, 3))) void send_ep3_text_message_printf(shared_p
va_end(va);
for (auto& it : s->id_to_lobby) {
for (auto& c : it.second->clients) {
if (c && (c->flags & Client::Flag::IS_EPISODE_3)) {
if (c && c->config.check_flag(Client::Flag::IS_EPISODE_3)) {
send_text_message(c, buf);
}
}
@@ -896,7 +916,7 @@ void send_prepared_chat_message(shared_ptr<Lobby> l, uint32_t from_guild_card_nu
void send_chat_message(shared_ptr<Client> c, uint32_t from_guild_card_number, const string& from_name, const string& text, char private_flags) {
string prepared_data = prepare_chat_data(
c->version(),
c->flags & Client::Flag::IS_DC_TRIAL_EDITION,
c->config.check_flag(Client::Flag::IS_DC_TRIAL_EDITION),
c->language(),
c->lobby_client_id,
from_name,
@@ -1143,7 +1163,7 @@ void send_menu_t(shared_ptr<Client> c, shared_ptr<const Menu> menu, bool is_info
switch (c->version()) {
case GameVersion::DC:
is_visible &= !(item.flags & MenuItem::Flag::INVISIBLE_ON_DC);
if (c->flags & Client::Flag::IS_DC_TRIAL_EDITION) {
if (c->config.check_flag(Client::Flag::IS_DC_TRIAL_EDITION)) {
is_visible &= !(item.flags & MenuItem::Flag::INVISIBLE_ON_DCNTE);
}
break;
@@ -1152,7 +1172,7 @@ void send_menu_t(shared_ptr<Client> c, shared_ptr<const Menu> menu, bool is_info
break;
case GameVersion::GC:
is_visible &= !(item.flags & MenuItem::Flag::INVISIBLE_ON_GC);
if (c->flags & Client::Flag::IS_GC_TRIAL_EDITION) {
if (c->config.check_flag(Client::Flag::IS_GC_TRIAL_EDITION)) {
is_visible &= !(item.flags & MenuItem::Flag::INVISIBLE_ON_GC_TRIAL_EDITION);
}
break;
@@ -1166,13 +1186,13 @@ void send_menu_t(shared_ptr<Client> c, shared_ptr<const Menu> menu, bool is_info
throw runtime_error("menus not supported for this game version");
}
if (item.flags & MenuItem::Flag::REQUIRES_MESSAGE_BOXES) {
is_visible &= !(c->flags & Client::Flag::NO_D6);
is_visible &= !c->config.check_flag(Client::Flag::NO_D6);
}
if (item.flags & MenuItem::Flag::REQUIRES_SEND_FUNCTION_CALL) {
is_visible &= !(c->flags & Client::Flag::NO_SEND_FUNCTION_CALL);
is_visible &= !c->config.check_flag(Client::Flag::NO_SEND_FUNCTION_CALL);
}
if (item.flags & MenuItem::Flag::REQUIRES_SAVE_DISABLED) {
is_visible &= !(c->flags & Client::Flag::SAVE_ENABLED);
is_visible &= !c->config.check_flag(Client::Flag::SAVE_ENABLED);
}
if (item.flags & MenuItem::Flag::INVISIBLE_IN_INFO_MENU) {
is_visible &= !is_info_menu;
@@ -1227,8 +1247,7 @@ void send_game_menu_t(
if (!l->version_is_allowed(c->quest_version())) {
continue;
}
bool l_is_spectator_team = !!(l->flags & Lobby::Flag::IS_SPECTATOR_TEAM);
if (l_is_spectator_team != is_spectator_team_list) {
if (l->check_flag(Lobby::Flag::IS_SPECTATOR_TEAM) != is_spectator_team_list) {
continue;
}
if (show_tournaments_only && !l->tournament_match) {
@@ -1264,7 +1283,7 @@ void send_game_menu_t(
e.episode = ((c->version() == GameVersion::BB) ? (l->max_clients << 4) : 0) | episode_num;
}
if (l->is_ep3()) {
e.flags = (l->password.empty() ? 0 : 2) | ((l->flags & Lobby::Flag::BATTLE_IN_PROGRESS) ? 4 : 0);
e.flags = (l->password.empty() ? 0 : 2) | (l->check_flag(Lobby::Flag::BATTLE_IN_PROGRESS) ? 4 : 0);
} else {
e.flags = ((episode_num << 6) | (l->password.empty() ? 0 : 2));
switch (l->mode) {
@@ -1396,13 +1415,13 @@ void send_lobby_list(shared_ptr<Client> c) {
auto s = c->require_server_state();
vector<S_LobbyListEntry_83> entries;
for (shared_ptr<Lobby> l : s->all_lobbies()) {
if (!(l->flags & Lobby::Flag::DEFAULT)) {
if (!l->check_flag(Lobby::Flag::DEFAULT)) {
continue;
}
if ((l->flags & Lobby::Flag::V2_AND_LATER) && (c->flags & Client::Flag::IS_DC_V1)) {
if (l->check_flag(Lobby::Flag::V2_AND_LATER) && c->config.check_flag(Client::Flag::IS_DC_V1)) {
continue;
}
if (l->is_ep3() && !(c->flags & Client::Flag::IS_EPISODE_3)) {
if (l->is_ep3() && !c->config.check_flag(Client::Flag::IS_EPISODE_3)) {
continue;
}
auto& e = entries.emplace_back();
@@ -1442,13 +1461,13 @@ void send_player_records_t(shared_ptr<Client> c, shared_ptr<Lobby> l, shared_ptr
}
static void send_join_spectator_team(shared_ptr<Client> c, shared_ptr<Lobby> l) {
if (!(c->flags & Client::Flag::IS_EPISODE_3)) {
if (!c->config.check_flag(Client::Flag::IS_EPISODE_3)) {
throw runtime_error("lobby is not Episode 3");
}
if (!l->is_ep3()) {
throw runtime_error("lobby is not Episode 3");
}
if (!(l->flags & Lobby::Flag::IS_SPECTATOR_TEAM)) {
if (!l->check_flag(Lobby::Flag::IS_SPECTATOR_TEAM)) {
throw runtime_error("lobby is not a spectator team");
}
@@ -1474,7 +1493,7 @@ static void send_join_spectator_team(shared_ptr<Client> c, shared_ptr<Lobby> l)
auto wc_p = wc->game_data.player();
auto& p = cmd.players[z];
p.lobby_data.player_tag = 0x00010000;
p.lobby_data.guild_card = wc->license->serial_number;
p.lobby_data.guild_card_number = wc->license->serial_number;
p.lobby_data.client_id = wc->lobby_client_id;
p.lobby_data.name.encode(wc_p->disp.name.decode(wc_p->inventory.language), c->language());
p.inventory = wc_p->inventory;
@@ -1522,7 +1541,7 @@ static void send_join_spectator_team(shared_ptr<Client> c, shared_ptr<Lobby> l)
auto& e = cmd.entries[client_id];
e.player_tag = 0x00010000;
e.guild_card_number = entry.lobby_data.guild_card;
e.guild_card_number = entry.lobby_data.guild_card_number;
e.name = entry.disp.visual.name;
e.present = 1;
e.level = entry.level.load();
@@ -1542,7 +1561,7 @@ static void send_join_spectator_team(shared_ptr<Client> c, shared_ptr<Lobby> l)
auto& cmd_p = cmd.spectator_players[z - 4];
auto& cmd_e = cmd.entries[z];
cmd_p.lobby_data.player_tag = 0x00010000;
cmd_p.lobby_data.guild_card = other_c->license->serial_number;
cmd_p.lobby_data.guild_card_number = other_c->license->serial_number;
cmd_p.lobby_data.client_id = other_c->lobby_client_id;
cmd_p.lobby_data.name.encode(other_p->disp.name.decode(other_p->inventory.language), c->language());
cmd_p.inventory = other_p->inventory;
@@ -1567,7 +1586,7 @@ static void send_join_spectator_team(shared_ptr<Client> c, shared_ptr<Lobby> l)
}
void send_join_game(shared_ptr<Client> c, shared_ptr<Lobby> l) {
if (l->flags & Lobby::Flag::IS_SPECTATOR_TEAM) {
if (l->check_flag(Lobby::Flag::IS_SPECTATOR_TEAM)) {
send_join_spectator_team(c, l);
return;
}
@@ -1578,7 +1597,7 @@ void send_join_game(shared_ptr<Client> c, shared_ptr<Lobby> l) {
auto lc = l->clients[x];
if (lc) {
cmd.lobby_data[x].player_tag = 0x00010000;
cmd.lobby_data[x].guild_card = lc->license->serial_number;
cmd.lobby_data[x].guild_card_number = lc->license->serial_number;
cmd.lobby_data[x].client_id = lc->lobby_client_id;
cmd.lobby_data[x].name.encode(lc->game_data.player()->disp.name.decode(lc->language()), c->language());
player_count++;
@@ -1623,7 +1642,7 @@ void send_join_game(shared_ptr<Client> c, shared_ptr<Lobby> l) {
switch (c->version()) {
case GameVersion::DC: {
if (c->flags & Client::Flag::IS_DC_TRIAL_EDITION) {
if (c->config.check_flag(Client::Flag::IS_DC_TRIAL_EDITION)) {
S_JoinGame_DCNTE_64 cmd;
cmd.client_id = c->lobby_client_id;
cmd.leader_id = l->leader_id;
@@ -1645,7 +1664,7 @@ void send_join_game(shared_ptr<Client> c, shared_ptr<Lobby> l) {
break;
}
case GameVersion::GC: {
if (c->flags & Client::Flag::IS_EPISODE_3) {
if (c->config.check_flag(Client::Flag::IS_EPISODE_3)) {
S_JoinGame_GC_Ep3_64 cmd;
size_t player_count = populate_v3_cmd(cmd);
for (size_t x = 0; x < 4; x++) {
@@ -1692,7 +1711,7 @@ void send_join_lobby_t(shared_ptr<Client> c, shared_ptr<Lobby> l, shared_ptr<Cli
uint8_t command;
if (l->is_game()) {
if (joining_client) {
command = (l->flags & Lobby::Flag::IS_SPECTATOR_TEAM) ? 0xEB : 0x65;
command = l->check_flag(Lobby::Flag::IS_SPECTATOR_TEAM) ? 0xEB : 0x65;
} else {
throw logic_error("send_join_lobby_t should not be used for primary game join command");
}
@@ -1700,15 +1719,15 @@ void send_join_lobby_t(shared_ptr<Client> c, shared_ptr<Lobby> l, shared_ptr<Cli
command = joining_client ? 0x68 : 0x67;
}
if ((c->version() != GameVersion::DC) || !(c->flags & Client::Flag::IS_DC_V1)) {
if ((c->version() != GameVersion::DC) || !c->config.check_flag(Client::Flag::IS_DC_V1)) {
send_player_records_t<RecordsT>(c, l, joining_client);
}
uint8_t lobby_type;
if (c->options.override_lobby_number >= 0) {
lobby_type = c->options.override_lobby_number;
} else if (l->flags & Lobby::Flag::IS_OVERFLOW) {
lobby_type = (c->flags & Client::Flag::IS_EPISODE_3) ? 15 : 0;
if (c->config.override_lobby_number != 0x80) {
lobby_type = c->config.override_lobby_number;
} else if (l->check_flag(Lobby::Flag::IS_OVERFLOW)) {
lobby_type = c->config.check_flag(Client::Flag::IS_EPISODE_3) ? 15 : 0;
} else {
lobby_type = l->block - 1;
}
@@ -1716,7 +1735,7 @@ void send_join_lobby_t(shared_ptr<Client> c, shared_ptr<Lobby> l, shared_ptr<Cli
// Allow non-canonical lobby types on GC. They may work on other versions too,
// but I haven't verified which values don't crash on each version.
if (c->version() == GameVersion::GC) {
if (c->flags & Client::Flag::IS_EPISODE_3) {
if (c->config.check_flag(Client::Flag::IS_EPISODE_3)) {
if ((lobby_type > 0x14) && (lobby_type < 0xE9)) {
lobby_type = l->block - 1;
}
@@ -1758,7 +1777,7 @@ void send_join_lobby_t(shared_ptr<Client> c, shared_ptr<Lobby> l, shared_ptr<Cli
auto lp = lc->game_data.player();
auto& e = cmd.entries[used_entries++];
e.lobby_data.player_tag = 0x00010000;
e.lobby_data.guild_card = lc->license->serial_number;
e.lobby_data.guild_card_number = lc->license->serial_number;
e.lobby_data.client_id = lc->lobby_client_id;
if (UseLanguageMarkerInName) {
e.lobby_data.name.encode("\tJ" + lp->disp.name.decode(lp->inventory.language), c->language());
@@ -1808,7 +1827,7 @@ void send_join_lobby_dc_nte(shared_ptr<Client> c, shared_ptr<Lobby> l,
auto lp = lc->game_data.player();
auto& e = cmd.entries[used_entries++];
e.lobby_data.player_tag = 0x00010000;
e.lobby_data.guild_card = lc->license->serial_number;
e.lobby_data.guild_card_number = lc->license->serial_number;
e.lobby_data.client_id = lc->lobby_client_id;
e.lobby_data.name.encode(lp->disp.name.decode(lp->inventory.language), c->language());
e.inventory = lp->inventory;
@@ -1826,7 +1845,7 @@ void send_join_lobby(shared_ptr<Client> c, shared_ptr<Lobby> l) {
} else {
switch (c->version()) {
case GameVersion::DC:
if (c->flags & (Client::Flag::IS_DC_TRIAL_EDITION | Client::Flag::IS_DC_V1_PROTOTYPE)) {
if (c->config.check_flag(Client::Flag::IS_DC_TRIAL_EDITION) || c->config.check_flag(Client::Flag::IS_DC_V1_PROTOTYPE)) {
send_join_lobby_dc_nte(c, l);
} else {
send_join_lobby_t<PlayerLobbyDataDCGC, PlayerDispDataDCPCV3, PlayerRecordsEntry_DC, false>(c, l);
@@ -1851,8 +1870,8 @@ void send_join_lobby(shared_ptr<Client> c, shared_ptr<Lobby> l) {
// If the client will stop sending message box close confirmations after
// joining any lobby, set the appropriate flag and update the client config
if ((c->flags & (Client::Flag::NO_D6_AFTER_LOBBY | Client::Flag::NO_D6)) == Client::Flag::NO_D6_AFTER_LOBBY) {
c->flags |= Client::Flag::NO_D6;
if (c->config.check_flag(Client::Flag::NO_D6_AFTER_LOBBY) && !c->config.check_flag(Client::Flag::NO_D6)) {
c->config.set_flag(Client::Flag::NO_D6);
send_update_client_config(c);
}
}
@@ -1861,7 +1880,7 @@ void send_player_join_notification(shared_ptr<Client> c,
shared_ptr<Lobby> l, shared_ptr<Client> joining_client) {
switch (c->version()) {
case GameVersion::DC:
if (c->flags & (Client::Flag::IS_DC_TRIAL_EDITION | Client::Flag::IS_DC_V1_PROTOTYPE)) {
if (c->config.check_flag(Client::Flag::IS_DC_TRIAL_EDITION) || c->config.check_flag(Client::Flag::IS_DC_V1_PROTOTYPE)) {
send_join_lobby_dc_nte(c, l, joining_client);
} else {
send_join_lobby_t<PlayerLobbyDataDCGC, PlayerDispDataDCPCV3, PlayerRecordsEntry_DC, false>(c, l, joining_client);
@@ -1888,7 +1907,7 @@ void send_player_leave_notification(shared_ptr<Lobby> l, uint8_t leaving_client_
S_LeaveLobby_66_69_Ep3_E9 cmd = {leaving_client_id, l->leader_id, 1, 0};
uint8_t cmd_num;
if (l->is_game()) {
cmd_num = (l->flags & Lobby::Flag::IS_SPECTATOR_TEAM) ? 0xE9 : 0x66;
cmd_num = l->check_flag(Lobby::Flag::IS_SPECTATOR_TEAM) ? 0xE9 : 0x66;
} else {
cmd_num = 0x69;
}
@@ -1905,7 +1924,7 @@ void send_self_leave_notification(shared_ptr<Client> c) {
void send_get_player_info(shared_ptr<Client> c) {
if ((c->version() == GameVersion::DC) &&
(c->flags & Client::Flag::IS_DC_TRIAL_EDITION)) {
c->config.check_flag(Client::Flag::IS_DC_TRIAL_EDITION)) {
send_command(c, 0x8D, 0x00);
} else {
send_command(c, 0x95, 0x00);
@@ -1931,7 +1950,7 @@ void send_execute_item_trade(shared_ptr<Client> c, const vector<ItemData>& items
void send_execute_card_trade(shared_ptr<Client> c,
const vector<pair<uint32_t, uint32_t>>& card_to_count) {
if (!(c->flags & Client::Flag::IS_EPISODE_3)) {
if (!c->config.check_flag(Client::Flag::IS_EPISODE_3)) {
throw logic_error("cannot send trade cards command to non-Ep3 client");
}
@@ -1972,7 +1991,7 @@ void send_arrow_update(shared_ptr<Lobby> l) {
}
for (size_t x = 0; x < l->max_clients; x++) {
if (!l->clients[x] || (l->clients[x]->flags & Client::Flag::IS_DC_V1)) {
if (!l->clients[x] || l->clients[x]->config.check_flag(Client::Flag::IS_DC_V1)) {
continue;
}
send_command_vt(l->clients[x], 0x88, entries.size(), entries);
@@ -2233,9 +2252,9 @@ void send_quest_function_call(shared_ptr<Client> c, uint16_t function_id) {
// ep3 only commands
void send_ep3_card_list_update(shared_ptr<Client> c) {
if (!(c->flags & Client::Flag::HAS_EP3_CARD_DEFS)) {
if (!c->config.check_flag(Client::Flag::HAS_EP3_CARD_DEFS)) {
auto s = c->require_server_state();
const auto& data = (c->flags & Client::Flag::IS_EP3_TRIAL_EDITION)
const auto& data = c->config.check_flag(Client::Flag::IS_EP3_TRIAL_EDITION)
? s->ep3_card_index_trial->get_compressed_definitions()
: s->ep3_card_index->get_compressed_definitions();
@@ -2309,7 +2328,7 @@ void send_ep3_set_context_token(shared_ptr<Client> c, uint32_t context_token) {
void send_ep3_confirm_tournament_entry(
shared_ptr<Client> c,
shared_ptr<const Episode3::Tournament> tourn) {
if (c->flags & Client::Flag::IS_EP3_TRIAL_EDITION) {
if (c->config.check_flag(Client::Flag::IS_EP3_TRIAL_EDITION)) {
throw runtime_error("cannot send tournament entry command to Episode 3 Trial Edition client");
}
@@ -2426,7 +2445,7 @@ void send_ep3_tournament_details(
}
string ep3_description_for_client(shared_ptr<Client> c) {
if (!(c->flags & Client::Flag::IS_EPISODE_3)) {
if (!c->config.check_flag(Client::Flag::IS_EPISODE_3)) {
throw runtime_error("client is not Episode 3");
}
auto player = c->game_data.player();
@@ -2440,7 +2459,7 @@ string ep3_description_for_client(shared_ptr<Client> c) {
void send_ep3_game_details(shared_ptr<Client> c, shared_ptr<Lobby> l) {
shared_ptr<Lobby> primary_lobby;
if (l->flags & Lobby::Flag::IS_SPECTATOR_TEAM) {
if (l->check_flag(Lobby::Flag::IS_SPECTATOR_TEAM)) {
primary_lobby = l->watched_lobby.lock();
} else {
primary_lobby = l;
@@ -2852,7 +2871,7 @@ bool send_quest_barrier_if_all_clients_ready(shared_ptr<Lobby> l) {
if (!l->clients[x]) {
continue;
}
if (l->clients[x]->flags & Client::Flag::LOADING_QUEST) {
if (l->clients[x]->config.check_flag(Client::Flag::LOADING_QUEST)) {
break;
}
}
@@ -2886,7 +2905,7 @@ bool send_ep3_start_tournament_deck_select_if_all_clients_ready(shared_ptr<Lobby
if (!l->clients[x]) {
continue;
}
if (l->clients[x]->flags & Client::Flag::LOADING_TOURNAMENT) {
if (l->clients[x]->config.check_flag(Client::Flag::LOADING_TOURNAMENT)) {
break;
}
}
@@ -2930,7 +2949,7 @@ void send_ep3_card_auction(shared_ptr<Lobby> l) {
distribution_size += e.probability;
}
auto card_index = (l->flags & Lobby::Flag::IS_EP3_TRIAL)
auto card_index = l->check_flag(Lobby::Flag::IS_EP3_TRIAL)
? s->ep3_card_index_trial
: s->ep3_card_index;
@@ -2983,7 +3002,7 @@ void send_change_event(shared_ptr<Client> c, uint8_t new_event) {
// This command isn't supported on versions before V3, nor on Trial Edition.
if ((c->version() == GameVersion::DC) ||
(c->version() == GameVersion::PC) ||
(c->flags & Client::Flag::IS_GC_TRIAL_EDITION)) {
c->config.check_flag(Client::Flag::IS_GC_TRIAL_EDITION)) {
return;
}
send_command(c, 0xDA, new_event);