From 37b8f1cffa5e2b8b5200228a48383e0a6f0fb284 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Fri, 1 Apr 2022 21:21:46 -0700 Subject: [PATCH] move flags enums into the structs they're scoped to --- src/ChatCommands.cc | 16 +++++----- src/Client.hh | 32 +++++++++++++++++++ src/Lobby.cc | 6 +--- src/Lobby.hh | 26 ++++++++------- src/Main.cc | 12 ++++--- src/Menu.hh | 23 ++++++++------ src/ProxyServer.cc | 6 ++-- src/ReceiveCommands.cc | 66 +++++++++++++++++++-------------------- src/ReceiveSubcommands.cc | 16 +++++----- src/SendCommands.cc | 34 ++++++++++---------- src/ServerState.cc | 10 +++--- src/Version.cc | 18 +++++------ src/Version.hh | 30 ------------------ 13 files changed, 152 insertions(+), 143 deletions(-) diff --git a/src/ChatCommands.cc b/src/ChatCommands.cc index 75f39ebd..277e03f0 100644 --- a/src/ChatCommands.cc +++ b/src/ChatCommands.cc @@ -363,7 +363,7 @@ static void check_is_game(shared_ptr l, bool is_game) { } static void check_is_ep3(shared_ptr c, bool is_ep3) { - if (!!(c->flags & ClientFlag::EPISODE_3_GAMES) != is_ep3) { + if (!!(c->flags & Client::Flag::EPISODE_3) != is_ep3) { throw precondition_failed(is_ep3 ? u"$C6This command can only\nbe used in Episode 3." : u"$C6This command cannot\nbe used in Episode 3."); @@ -371,7 +371,7 @@ static void check_is_ep3(shared_ptr c, bool is_ep3) { } static void check_cheats_enabled(shared_ptr l) { - if (!(l->flags & LobbyFlag::CHEATS_ENABLED)) { + if (!(l->flags & Lobby::Flag::CHEATS_ENABLED)) { throw precondition_failed(u"$C6This command can\nonly be used in\ncheat mode."); } } @@ -406,7 +406,7 @@ static void command_lobby_info(shared_ptr, shared_ptr l, "$C6Game ID: %08X\n%s\nSection ID: %s\nCheat mode: %s", l->lobby_id, level_string.c_str(), name_for_section_id(l->section_id).c_str(), - (l->flags & LobbyFlag::CHEATS_ENABLED) ? "on" : "off"); + (l->flags & Lobby::Flag::CHEATS_ENABLED) ? "on" : "off"); } else { size_t num_clients = l->count_clients(); @@ -446,12 +446,12 @@ static void command_cheat(shared_ptr, shared_ptr l, check_is_game(l, true); check_is_leader(l, c); - l->flags ^= LobbyFlag::CHEATS_ENABLED; + l->flags ^= Lobby::Flag::CHEATS_ENABLED; send_text_message_printf(l, "Cheat mode %s", - (l->flags & LobbyFlag::CHEATS_ENABLED) ? "enabled" : "disabled"); + (l->flags & Lobby::Flag::CHEATS_ENABLED) ? "enabled" : "disabled"); // if cheat mode was disabled, turn off all the cheat features that were on - if (!(l->flags & LobbyFlag::CHEATS_ENABLED)) { + if (!(l->flags & Lobby::Flag::CHEATS_ENABLED)) { for (size_t x = 0; x < l->max_clients; x++) { auto c = l->clients[x]; if (!c) { @@ -491,7 +491,7 @@ static void command_lobby_event_all(shared_ptr s, shared_ptr } for (auto l : s->all_lobbies()) { - if (l->is_game() || !(l->flags & LobbyFlag::DEFAULT)) { + if (l->is_game() || !(l->flags & Lobby::Flag::DEFAULT)) { continue; } @@ -512,7 +512,7 @@ static void command_lobby_type(shared_ptr, shared_ptr l, } l->type = new_type; - if (l->type < ((l->flags & LobbyFlag::EPISODE_3) ? 20 : 15)) { + if (l->type < ((l->flags & Lobby::Flag::EPISODE_3_ONLY) ? 20 : 15)) { l->type = l->block - 1; } diff --git a/src/Client.hh b/src/Client.hh index 05b25c46..52883029 100644 --- a/src/Client.hh +++ b/src/Client.hh @@ -42,6 +42,38 @@ struct ClientConfigBB { } __attribute__((packed)); struct Client { + enum Flag { + // For patch server clients, client is Blue Burst rather than PC + BB_PATCH = 0x0001, + // After joining a lobby, client will no longer send D6 commands when they + // close message boxes + NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN = 0x0002, + // Client has the above flag and has already joined a lobby, or is Blue Burst + // (BB never sends D6 commands) + NO_MESSAGE_BOX_CLOSE_CONFIRMATION = 0x0004, + // Client is Episode 3, should be able to see CARD lobbies, and should only be + // able to see/join games with the IS_EPISODE_3 flag + EPISODE_3 = 0x0008, + // Client is DC v1 (disables some features) + DCV1 = 0x0010, + // Client is loading into a game + LOADING = 0x0020, + // Client is in the information menu (login server only) + IN_INFORMATION_MENU = 0x0040, + // Client is at the welcome message (login server only) + AT_WELCOME_MESSAGE = 0x0080, + + // Note: There isn't a good way to detect Episode 3 until the player data is + // sent (via a 61 command), so the IS_EPISODE_3 flag is set in that handler + DEFAULT_V1 = DCV1, + DEFAULT_V2_DC = 0x0000, + DEFAULT_V2_PC = 0x0000, + DEFAULT_V3_GC = 0x0000, + DEFAULT_V3_GC_PLUS = NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN, + DEFAULT_V3_GC_EP3 = NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN | EPISODE_3, + DEFAULT_V4_BB = NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN | NO_MESSAGE_BOX_CLOSE_CONFIRMATION, + }; + // License & account std::shared_ptr license; GameVersion version; diff --git a/src/Lobby.cc b/src/Lobby.cc index 88c8372f..040fe3c6 100644 --- a/src/Lobby.cc +++ b/src/Lobby.cc @@ -23,10 +23,6 @@ Lobby::Lobby() : lobby_id(0), min_level(0), max_level(0xFFFFFFFF), memset(&this->next_drop_item, 0, sizeof(this->next_drop_item)); } -bool Lobby::is_game() const { - return this->flags & LobbyFlag::IS_GAME; -} - void Lobby::reassign_leader_on_client_departure(size_t leaving_client_index) { for (size_t x = 0; x < this->max_clients; x++) { if (x == leaving_client_index) { @@ -45,7 +41,7 @@ bool Lobby::any_client_loading() const { if (!this->clients[x].get()) { continue; } - if (this->clients[x]->flags & ClientFlag::LOADING) { + if (this->clients[x]->flags & Client::Flag::LOADING) { return true; } } diff --git a/src/Lobby.hh b/src/Lobby.hh index 3d8db9ad..146c6e69 100644 --- a/src/Lobby.hh +++ b/src/Lobby.hh @@ -9,18 +9,18 @@ #include "Map.hh" #include "RareItemSet.hh" -enum LobbyFlag { - IS_GAME = 0x01, - CHEATS_ENABLED = 0x02, // game only - PUBLIC = 0x04, // lobby only - EPISODE_3 = 0x08, // lobby & game - QUEST_IN_PROGRESS = 0x10, // game only - JOINABLE_QUEST_IN_PROGRESS = 0x20, // game only - DEFAULT = 0x40, // lobby only; not set for games and private lobbies - PERSISTENT = 0x80, // if not set, lobby is deleted when empty -}; - struct Lobby { + enum Flag { + GAME = 0x01, + CHEATS_ENABLED = 0x02, // game only + PUBLIC = 0x04, // lobby only + EPISODE_3_ONLY = 0x08, // lobby & game + QUEST_IN_PROGRESS = 0x10, // game only + JOINABLE_QUEST_IN_PROGRESS = 0x20, // game only + DEFAULT = 0x40, // lobby only; not set for games and private lobbies + PERSISTENT = 0x80, // if not set, lobby is deleted when empty + }; + uint32_t lobby_id; uint32_t min_level; @@ -59,7 +59,9 @@ struct Lobby { Lobby(); - bool is_game() const; + inline bool is_game() const { + return this->flags & Flag::GAME; + } void reassign_leader_on_client_departure(size_t leaving_client_id); size_t count_clients() const; diff --git a/src/Main.cc b/src/Main.cc index 7a3a0543..5d8eb351 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -107,7 +107,7 @@ void populate_state_from_config(shared_ptr s, for (const auto& item : d.at("InformationMenuContents")->as_list()) { auto& v = item->as_list(); information_menu->emplace_back(item_id, decode_sjis(v.at(0)->as_string()), - decode_sjis(v.at(1)->as_string()), MenuItemFlag::REQUIRES_MESSAGE_BOXES); + decode_sjis(v.at(1)->as_string()), MenuItem::Flag::REQUIRES_MESSAGE_BOXES); information_contents->emplace_back(decode_sjis(v.at(2)->as_string())); item_id++; } @@ -131,10 +131,14 @@ void populate_state_from_config(shared_ptr s, s->main_menu.emplace_back(MAIN_MENU_GO_TO_LOBBY, u"Go to lobby", u"Join the lobby", 0); s->main_menu.emplace_back(MAIN_MENU_INFORMATION, u"Information", - u"View server information", MenuItemFlag::REQUIRES_MESSAGE_BOXES); - if (!s->proxy_destinations.empty()) { + u"View server information", MenuItem::Flag::REQUIRES_MESSAGE_BOXES); + if (!s->proxy_destinations_pc.empty()) { s->main_menu.emplace_back(MAIN_MENU_PROXY_DESTINATIONS, u"Proxy server", - u"Connect to another\nserver", 0); + u"Connect to another\nserver", MenuItem::Flag::PC_ONLY); + } + if (!s->proxy_destinations_gc.empty()) { + s->main_menu.emplace_back(MAIN_MENU_PROXY_DESTINATIONS, u"Proxy server", + u"Connect to another\nserver", MenuItem::Flag::GC_ONLY); } s->main_menu.emplace_back(MAIN_MENU_DOWNLOAD_QUESTS, u"Download quests", u"Download quests", 0); diff --git a/src/Menu.hh b/src/Menu.hh index cbff8efe..0e2fa7f4 100644 --- a/src/Menu.hh +++ b/src/Menu.hh @@ -24,16 +24,21 @@ -enum MenuItemFlag { - INVISIBLE_ON_DC = 0x01, - INVISIBLE_ON_PC = 0x02, - INVISIBLE_ON_GC = 0x04, - INVISIBLE_ON_GC_EPISODE_3 = 0x08, - INVISIBLE_ON_BB = 0x10, - REQUIRES_MESSAGE_BOXES = 0x20, -}; - struct MenuItem { + enum Flag { + INVISIBLE_ON_DC = 0x01, + INVISIBLE_ON_PC = 0x02, + INVISIBLE_ON_GC = 0x04, + INVISIBLE_ON_GC_EPISODE_3 = 0x08, + INVISIBLE_ON_BB = 0x10, + DC_ONLY = INVISIBLE_ON_PC | INVISIBLE_ON_GC | INVISIBLE_ON_GC_EPISODE_3 | INVISIBLE_ON_BB, + PC_ONLY = INVISIBLE_ON_DC | INVISIBLE_ON_GC | INVISIBLE_ON_GC_EPISODE_3 | INVISIBLE_ON_BB, + GC_ONLY = INVISIBLE_ON_DC | INVISIBLE_ON_PC | INVISIBLE_ON_GC_EPISODE_3 | INVISIBLE_ON_BB, + GC_EPISODE_3_ONLY = INVISIBLE_ON_DC | INVISIBLE_ON_PC | INVISIBLE_ON_GC | INVISIBLE_ON_BB, + BB_ONLY = INVISIBLE_ON_DC | INVISIBLE_ON_PC | INVISIBLE_ON_GC | INVISIBLE_ON_GC_EPISODE_3, + REQUIRES_MESSAGE_BOXES = 0x00010000, + }; + uint32_t item_id; std::u16string name; std::u16string description; diff --git a/src/ProxyServer.cc b/src/ProxyServer.cc index a4061292..7c5c629a 100644 --- a/src/ProxyServer.cc +++ b/src/ProxyServer.cc @@ -771,7 +771,7 @@ void ProxyServer::LinkedSession::on_server_input() { // If the client has the no-close-confirmation flag set in its // newserv client config, send a fake confirmation to the remote // server immediately. - if (this->newserv_client_config.flags & ClientFlag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION) { + if (this->newserv_client_config.flags & Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION) { send_command(this->server_bev.get(), this->version, this->server_output_crypt.get(), 0xD6, 0x00, "", 0, name.c_str()); @@ -899,8 +899,8 @@ void ProxyServer::LinkedSession::on_server_input() { // this behavior in the client config, so if it happens during a // proxy session, update the client config that we'll restore if the // client uses the change ship or change block command. - if (this->newserv_client_config.flags & ClientFlag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN) { - this->newserv_client_config.flags |= ClientFlag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION; + if (this->newserv_client_config.flags & Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN) { + this->newserv_client_config.flags |= Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION; } [[fallthrough]]; diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index dea467e9..8ce179cc 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -65,8 +65,8 @@ vector quest_categories_menu({ MenuItem(static_cast(QuestCategory::EXTERMINATION), u"Extermination", u"$E$C6Quests that involve\ndestroying all\nmonsters", 0), MenuItem(static_cast(QuestCategory::EVENT), u"Events", u"$E$C6Quests that are part\nof an event", 0), MenuItem(static_cast(QuestCategory::SHOP), u"Shops", u"$E$C6Quests that contain\nshops", 0), - MenuItem(static_cast(QuestCategory::VR), u"Virtual Reality", u"$E$C6Quests that are\ndone in a simulator", MenuItemFlag::INVISIBLE_ON_DC | MenuItemFlag::INVISIBLE_ON_PC), - MenuItem(static_cast(QuestCategory::TOWER), u"Control Tower", u"$E$C6Quests that take\nplace at the Control\nTower", MenuItemFlag::INVISIBLE_ON_DC | MenuItemFlag::INVISIBLE_ON_PC), + MenuItem(static_cast(QuestCategory::VR), u"Virtual Reality", u"$E$C6Quests that are\ndone in a simulator", MenuItem::Flag::INVISIBLE_ON_DC | MenuItem::Flag::INVISIBLE_ON_PC), + MenuItem(static_cast(QuestCategory::TOWER), u"Control Tower", u"$E$C6Quests that take\nplace at the Control\nTower", MenuItem::Flag::INVISIBLE_ON_DC | MenuItem::Flag::INVISIBLE_ON_PC), }); vector quest_battle_menu({ @@ -92,8 +92,8 @@ vector quest_download_menu({ MenuItem(static_cast(QuestCategory::EXTERMINATION), u"Extermination", u"$E$C6Quests that involve\ndestroying all\nmonsters", 0), MenuItem(static_cast(QuestCategory::EVENT), u"Events", u"$E$C6Quests that are part\nof an event", 0), MenuItem(static_cast(QuestCategory::SHOP), u"Shops", u"$E$C6Quests that contain\nshops", 0), - MenuItem(static_cast(QuestCategory::VR), u"Virtual Reality", u"$E$C6Quests that are\ndone in a simulator", MenuItemFlag::INVISIBLE_ON_DC | MenuItemFlag::INVISIBLE_ON_PC), - MenuItem(static_cast(QuestCategory::TOWER), u"Control Tower", u"$E$C6Quests that take\nplace at the Control\nTower", MenuItemFlag::INVISIBLE_ON_DC | MenuItemFlag::INVISIBLE_ON_PC), + MenuItem(static_cast(QuestCategory::VR), u"Virtual Reality", u"$E$C6Quests that are\ndone in a simulator", MenuItem::Flag::INVISIBLE_ON_DC | MenuItem::Flag::INVISIBLE_ON_PC), + MenuItem(static_cast(QuestCategory::TOWER), u"Control Tower", u"$E$C6Quests that take\nplace at the Control\nTower", MenuItem::Flag::INVISIBLE_ON_DC | MenuItem::Flag::INVISIBLE_ON_PC), MenuItem(static_cast(QuestCategory::DOWNLOAD), u"Download", u"$E$C6Quests to download\nto your Memory Card", 0), }); @@ -134,15 +134,15 @@ void process_login_complete(shared_ptr s, shared_ptr c) { if (c->server_behavior == ServerBehavior::LOGIN_SERVER) { // on the login server, send the ep3 updates and the main menu or welcome // message - if (c->flags & ClientFlag::EPISODE_3_GAMES) { + if (c->flags & Client::Flag::EPISODE_3) { send_ep3_card_list_update(c); send_ep3_rank_update(c); } if (s->welcome_message.empty() || - (c->flags & ClientFlag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION) || - !(c->flags & ClientFlag::AT_WELCOME_MESSAGE)) { - c->flags &= ~ClientFlag::AT_WELCOME_MESSAGE; + (c->flags & Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION) || + !(c->flags & Client::Flag::AT_WELCOME_MESSAGE)) { + c->flags &= ~Client::Flag::AT_WELCOME_MESSAGE; send_menu(c, s->name.c_str(), MAIN_MENU_ID, s->main_menu, false); } else { send_message_box(c, s->welcome_message.c_str()); @@ -339,12 +339,12 @@ void process_login_d_e_pc_gc(shared_ptr s, shared_ptr c, } catch (const invalid_argument&) { // If we can't import the config, assume that the client was not connected // to newserv before, so we should show the welcome message. - c->flags |= ClientFlag::AT_WELCOME_MESSAGE; + c->flags |= Client::Flag::AT_WELCOME_MESSAGE; c->bb_game_state = 0; c->bb_player_index = 0; } - if ((c->flags & ClientFlag::EPISODE_3_GAMES) && (s->ep3_menu_song >= 0)) { + if ((c->flags & Client::Flag::EPISODE_3) && (s->ep3_menu_song >= 0)) { send_ep3_change_music(c, s->ep3_menu_song); } @@ -438,7 +438,7 @@ void process_ep3_jukebox(shared_ptr s, shared_ptr c, S_Meseta_GC_Ep3_BA out_cmd = {1000000, 0x80E8, in_cmd.unknown_token}; auto l = s->find_lobby(c->lobby_id); - if (!l || !(l->flags & LobbyFlag::EPISODE_3)) { + if (!l || !(l->flags & Lobby::Flag::EPISODE_3_ONLY)) { return; } @@ -459,7 +459,7 @@ void process_ep3_server_data_request(shared_ptr s, shared_ptr(data.data()); auto l = s->find_lobby(c->lobby_id); - if (!l || !(l->flags & LobbyFlag::EPISODE_3) || !l->is_game()) { + if (!l || !(l->flags & Lobby::Flag::EPISODE_3_ONLY) || !l->is_game()) { c->should_disconnect = true; return; } @@ -562,11 +562,11 @@ void process_ep3_tournament_control(shared_ptr, shared_ptr void process_message_box_closed(shared_ptr s, shared_ptr c, uint16_t, uint32_t, const string& data) { // D6 check_size(data.size(), 0); - if (c->flags & ClientFlag::IN_INFORMATION_MENU) { + if (c->flags & Client::Flag::IN_INFORMATION_MENU) { send_menu(c, u"Information", INFORMATION_MENU_ID, *s->information_menu, false); - } else if (c->flags & ClientFlag::AT_WELCOME_MESSAGE) { + } else if (c->flags & Client::Flag::AT_WELCOME_MESSAGE) { send_menu(c, s->name.c_str(), MAIN_MENU_ID, s->main_menu, false); - c->flags &= ~ClientFlag::AT_WELCOME_MESSAGE; + c->flags &= ~Client::Flag::AT_WELCOME_MESSAGE; send_update_client_config(c); } } @@ -668,7 +668,7 @@ void process_menu_selection(shared_ptr s, shared_ptr c, case MAIN_MENU_INFORMATION: send_menu(c, u"Information", INFORMATION_MENU_ID, *s->information_menu, false); - c->flags |= ClientFlag::IN_INFORMATION_MENU; + c->flags |= Client::Flag::IN_INFORMATION_MENU; break; case MAIN_MENU_PROXY_DESTINATIONS: @@ -693,7 +693,7 @@ void process_menu_selection(shared_ptr s, shared_ptr c, case INFORMATION_MENU_ID: { if (cmd.item_id == INFORMATION_MENU_GO_BACK) { - c->flags &= ~ClientFlag::IN_INFORMATION_MENU; + c->flags &= ~Client::Flag::IN_INFORMATION_MENU; send_menu(c, s->name.c_str(), MAIN_MENU_ID, s->main_menu, false); } else { @@ -756,11 +756,11 @@ void process_menu_selection(shared_ptr s, shared_ptr c, break; } if ((game->version != c->version) || - (!(game->flags & LobbyFlag::EPISODE_3) != !(c->flags & LobbyFlag::EPISODE_3))) { + (!(game->flags & Lobby::Flag::EPISODE_3_ONLY) != !(c->flags & Client::Flag::EPISODE_3))) { send_lobby_message_box(c, u"$C6You cannot join this\ngame because it is\nfor a different\nversion of PSO."); break; } - if (game->flags & LobbyFlag::QUEST_IN_PROGRESS) { + if (game->flags & Lobby::Flag::QUEST_IN_PROGRESS) { send_lobby_message_box(c, u"$C6You cannot join this\ngame because a\nquest is already\nin progress."); break; } @@ -800,7 +800,7 @@ void process_menu_selection(shared_ptr s, shared_ptr c, } s->change_client_lobby(c, game); - c->flags |= ClientFlag::LOADING; + c->flags |= Client::Flag::LOADING; if (c->version == GameVersion::BB) { game->assign_item_ids_for_player(c->lobby_client_id, c->player.inventory); } @@ -814,7 +814,7 @@ void process_menu_selection(shared_ptr s, shared_ptr c, } shared_ptr l = c->lobby_id ? s->find_lobby(c->lobby_id) : nullptr; auto quests = s->quest_index->filter(c->version, - c->flags & ClientFlag::IS_DCV1, + c->flags & Client::Flag::DCV1, static_cast(cmd.item_id & 0xFF), l.get() ? (l->episode - 1) : -1); if (quests.empty()) { @@ -857,9 +857,9 @@ void process_menu_selection(shared_ptr s, shared_ptr c, if (l) { if (q->joinable) { - l->flags |= LobbyFlag::JOINABLE_QUEST_IN_PROGRESS; + l->flags |= Lobby::Flag::JOINABLE_QUEST_IN_PROGRESS; } else { - l->flags |= LobbyFlag::QUEST_IN_PROGRESS; + l->flags |= Lobby::Flag::QUEST_IN_PROGRESS; } l->loading_quest_id = q->quest_id; for (size_t x = 0; x < l->max_clients; x++) { @@ -874,7 +874,7 @@ void process_menu_selection(shared_ptr s, shared_ptr c, send_quest_file(l->clients[x], bin_basename, *bin_contents, false, false); send_quest_file(l->clients[x], dat_basename, *dat_contents, false, false); - l->clients[x]->flags |= ClientFlag::LOADING; + l->clients[x]->flags |= Client::Flag::LOADING; } } else { @@ -908,7 +908,7 @@ void process_change_lobby(shared_ptr s, shared_ptr c, return; } - if ((new_lobby->flags & LobbyFlag::EPISODE_3) && !(c->flags & ClientFlag::EPISODE_3_GAMES)) { + if ((new_lobby->flags & Lobby::Flag::EPISODE_3_ONLY) && !(c->flags & Client::Flag::EPISODE_3)) { send_lobby_message_box(c, u"$C6Can't change lobby\n\n$C7The lobby is for\nEpisode 3 only."); return; } @@ -992,7 +992,7 @@ void process_quest_ready(shared_ptr s, shared_ptr c, return; } - c->flags &= ~ClientFlag::LOADING; + c->flags &= ~Client::Flag::LOADING; // check if any client is still loading // TODO: we need to handle clients disconnecting while loading. probably @@ -1002,7 +1002,7 @@ void process_quest_ready(shared_ptr s, shared_ptr c, if (!l->clients[x]) { continue; } - if (l->clients[x]->flags & ClientFlag::LOADING) { + if (l->clients[x]->flags & Client::Flag::LOADING) { break; } } @@ -1518,7 +1518,7 @@ shared_ptr create_game_generic(shared_ptr s, game->event = Lobby::game_event_for_lobby_event(current_lobby->event); game->block = 0xFF; game->max_clients = 4; - game->flags = (is_ep3 ? LobbyFlag::EPISODE_3 : 0) | LobbyFlag::IS_GAME; + game->flags = (is_ep3 ? Lobby::Flag::EPISODE_3_ONLY : 0) | Lobby::Flag::GAME; game->min_level = min_level; game->max_level = 0xFFFFFFFF; @@ -1603,7 +1603,7 @@ void process_create_game_pc(shared_ptr s, shared_ptr c, s->add_lobby(game); s->change_client_lobby(c, game); - c->flags |= ClientFlag::LOADING; + c->flags |= Client::Flag::LOADING; } void process_create_game_dc_gc(shared_ptr s, shared_ptr c, @@ -1611,7 +1611,7 @@ void process_create_game_dc_gc(shared_ptr s, shared_ptr c, const auto& cmd = check_size_t(data); // only allow EC from Ep3 clients - bool client_is_ep3 = c->flags & ClientFlag::EPISODE_3_GAMES; + bool client_is_ep3 = c->flags & Client::Flag::EPISODE_3; if ((command == 0xEC) && !client_is_ep3) { return; } @@ -1632,7 +1632,7 @@ void process_create_game_dc_gc(shared_ptr s, shared_ptr c, s->add_lobby(game); s->change_client_lobby(c, game); - c->flags |= ClientFlag::LOADING; + c->flags |= Client::Flag::LOADING; } void process_create_game_bb(shared_ptr s, shared_ptr c, @@ -1645,7 +1645,7 @@ void process_create_game_bb(shared_ptr s, shared_ptr c, s->add_lobby(game); s->change_client_lobby(c, game); - c->flags |= ClientFlag::LOADING; + c->flags |= Client::Flag::LOADING; game->assign_item_ids_for_player(c->lobby_client_id, c->player.inventory); } @@ -1669,7 +1669,7 @@ void process_client_ready(shared_ptr s, shared_ptr c, // go home client; you're drunk throw invalid_argument("ready command cannot be sent outside game"); } - c->flags &= (~ClientFlag::LOADING); + c->flags &= (~Client::Flag::LOADING); send_resume_game(l, c); send_server_time(c); diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index 7ec9ee02..9aee9a3a 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -62,7 +62,7 @@ void forward_subcommand(shared_ptr l, shared_ptr c, // if the command is an Ep3-only command, make sure an Ep3 client sent it bool command_is_ep3 = (command & 0xF0) == 0xC0; - if (command_is_ep3 && !(c->flags & ClientFlag::EPISODE_3_GAMES)) { + if (command_is_ep3 && !(c->flags & Client::Flag::EPISODE_3)) { return; } @@ -74,7 +74,7 @@ void forward_subcommand(shared_ptr l, shared_ptr c, if (!target) { return; } - if (command_is_ep3 && !(target->flags & ClientFlag::EPISODE_3_GAMES)) { + if (command_is_ep3 && !(target->flags & Client::Flag::EPISODE_3)) { return; } send_command(target, command, flag, p, count * 4); @@ -82,7 +82,7 @@ void forward_subcommand(shared_ptr l, shared_ptr c, } else { if (command_is_ep3) { for (auto& target : l->clients) { - if (!target || (target == c) || !(target->flags & ClientFlag::EPISODE_3_GAMES)) { + if (!target || (target == c) || !(target->flags & Client::Flag::EPISODE_3)) { continue; } send_command(target, command, flag, p, count * 4); @@ -182,7 +182,7 @@ static void process_subcommand_hit_by_monster(shared_ptr, return; } forward_subcommand(l, c, command, flag, p, count); - if ((l->flags & LobbyFlag::CHEATS_ENABLED) && c->infinite_hp) { + if ((l->flags & Lobby::Flag::CHEATS_ENABLED) && c->infinite_hp) { send_player_stats_change(l, c, PlayerStatsChange::ADD_HP, 1020); } } @@ -195,7 +195,7 @@ static void process_subcommand_use_technique(shared_ptr, return; } forward_subcommand(l, c, command, flag, p, count); - if ((l->flags & LobbyFlag::CHEATS_ENABLED) && c->infinite_tp) { + if ((l->flags & Lobby::Flag::CHEATS_ENABLED) && c->infinite_tp) { send_player_stats_change(l, c, PlayerStatsChange::ADD_TP, 255); } } @@ -208,7 +208,7 @@ static void process_subcommand_switch_state_changed(shared_ptr, } forward_subcommand(l, c, command, flag, p, count); if ((count == 3) && (p[2].byte[3] == 1)) { // If this is a switch enable command - if ((l->flags & LobbyFlag::CHEATS_ENABLED) && c->switch_assist && + if ((l->flags & Lobby::Flag::CHEATS_ENABLED) && c->switch_assist && (c->last_switch_enabled_subcommand[0].byte[0] == 0x05)) { log(INFO, "[Switch assist] Replaying previous enable command"); forward_subcommand(l, c, command, flag, c->last_switch_enabled_subcommand, 3); @@ -381,7 +381,7 @@ static void process_subcommand_use_item(shared_ptr, static void process_subcommand_open_shop_or_ep3_unknown(shared_ptr s, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const PSOSubcommand* p, size_t count) { - if (l->flags & LobbyFlag::EPISODE_3) { + if (l->flags & Lobby::Flag::EPISODE_3_ONLY) { check_size(count, 2, 0xFFFF); forward_subcommand(l, c, command, flag, p, count); @@ -896,7 +896,7 @@ static void process_subcommand_forward_check_size_game(shared_ptr, static void process_subcommand_forward_check_size_ep3_lobby(shared_ptr, shared_ptr l, shared_ptr c, uint8_t command, uint8_t flag, const PSOSubcommand* p, size_t count) { - if (!(l->flags & LobbyFlag::EPISODE_3) || l->is_game() || (p->byte[1] != count)) { + if (l->is_game() || !(l->flags & Lobby::Flag::EPISODE_3_ONLY) || (p->byte[1] != count)) { return; } forward_subcommand(l, c, command, flag, p, count); diff --git a/src/SendCommands.cc b/src/SendCommands.cc index 1c11b5be..fcbee3c2 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -666,12 +666,12 @@ void send_menu_t( } for (const auto& item : items) { - if (((c->version == GameVersion::DC) && (item.flags & MenuItemFlag::INVISIBLE_ON_DC)) || - ((c->version == GameVersion::PC) && (item.flags & MenuItemFlag::INVISIBLE_ON_PC)) || - ((c->version == GameVersion::GC) && (item.flags & MenuItemFlag::INVISIBLE_ON_GC)) || - ((c->version == GameVersion::BB) && (item.flags & MenuItemFlag::INVISIBLE_ON_BB)) || - ((c->flags & ClientFlag::EPISODE_3_GAMES) && (item.flags & MenuItemFlag::INVISIBLE_ON_GC_EPISODE_3)) || - ((item.flags & MenuItemFlag::REQUIRES_MESSAGE_BOXES) && (c->flags & ClientFlag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION))) { + if (((c->version == GameVersion::DC) && (item.flags & MenuItem::Flag::INVISIBLE_ON_DC)) || + ((c->version == GameVersion::PC) && (item.flags & MenuItem::Flag::INVISIBLE_ON_PC)) || + ((c->version == GameVersion::GC) && (item.flags & MenuItem::Flag::INVISIBLE_ON_GC)) || + ((c->version == GameVersion::BB) && (item.flags & MenuItem::Flag::INVISIBLE_ON_BB)) || + ((c->flags & Client::Flag::EPISODE_3) && (item.flags & MenuItem::Flag::INVISIBLE_ON_GC_EPISODE_3)) || + ((item.flags & MenuItem::Flag::REQUIRES_MESSAGE_BOXES) && (c->flags & Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION))) { continue; } auto& e = entries.emplace_back(); @@ -714,8 +714,8 @@ void send_game_menu_t(shared_ptr c, shared_ptr s) { if (!l->is_game() || (l->version != c->version)) { continue; } - bool l_is_ep3 = !!(l->flags & LobbyFlag::EPISODE_3); - bool c_is_ep3 = !!(c->flags & ClientFlag::EPISODE_3_GAMES); + bool l_is_ep3 = !!(l->flags & Lobby::Flag::EPISODE_3_ONLY); + bool c_is_ep3 = !!(c->flags & Client::Flag::EPISODE_3); if (l_is_ep3 != c_is_ep3) { continue; } @@ -726,7 +726,7 @@ void send_game_menu_t(shared_ptr c, shared_ptr s) { e.difficulty_tag = (l_is_ep3 ? 0x0A : (l->difficulty + 0x22)); e.num_players = l->count_clients(); e.episode = ((c->version == GameVersion::BB) ? (l->max_clients << 4) : 0) | l->episode; - if (l->flags & LobbyFlag::EPISODE_3) { + if (l->flags & Lobby::Flag::EPISODE_3_ONLY) { e.flags = (l->password.empty() ? 0 : 2); } else { e.flags = ((l->episode << 6) | ((l->mode % 3) << 4) | (l->password.empty() ? 0 : 2)) | ((l->mode == 3) ? 4 : 0); @@ -816,10 +816,10 @@ void send_lobby_list(shared_ptr c, shared_ptr s) { vector entries; for (shared_ptr l : s->all_lobbies()) { - if (!(l->flags & LobbyFlag::DEFAULT)) { + if (!(l->flags & Lobby::Flag::DEFAULT)) { continue; } - if ((l->flags & LobbyFlag::EPISODE_3) && !(c->flags & ClientFlag::EPISODE_3_GAMES)) { + if ((l->flags & Lobby::Flag::EPISODE_3_ONLY) && !(c->flags & Client::Flag::EPISODE_3)) { continue; } auto& e = entries.emplace_back(); @@ -851,7 +851,7 @@ void send_join_game_t(shared_ptr c, shared_ptr l) { cmd.lobby_data[x].ip_address = 0x7F000001; cmd.lobby_data[x].client_id = c->lobby_client_id; cmd.lobby_data[x].name = l->clients[x]->player.disp.name; - if (l->flags & LobbyFlag::EPISODE_3) { + if (l->flags & Lobby::Flag::EPISODE_3_ONLY) { cmd.players_ep3[x].inventory = l->clients[x]->player.inventory; cmd.players_ep3[x].disp = convert_player_disp_data( l->clients[x]->player.disp); @@ -879,7 +879,7 @@ void send_join_game_t(shared_ptr c, shared_ptr l) { // Player data is only sent in Episode III games; in other versions, the // players send each other their data using 62/6D commands during loading - size_t data_size = (l->flags & LobbyFlag::EPISODE_3) + size_t data_size = (l->flags & Lobby::Flag::EPISODE_3_ONLY) ? sizeof(cmd) : (sizeof(cmd) - sizeof(cmd.players_ep3)); send_command(c, 0x64, player_count, &cmd, data_size); } @@ -901,7 +901,7 @@ void send_join_lobby_t(shared_ptr c, shared_ptr l, uint8_t lobby_type = (l->type > 14) ? (l->block - 1) : l->type; // Allow non-canonical lobby types on GC if (c->version == GameVersion::GC) { - if (c->flags & ClientFlag::EPISODE_3_GAMES) { + if (c->flags & Client::Flag::EPISODE_3) { if ((l->type > 0x14) && (l->type < 0xE9)) { lobby_type = l->block - 1; } @@ -983,9 +983,9 @@ void send_join_lobby(shared_ptr c, shared_ptr 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 & (ClientFlag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN | ClientFlag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION)) - == ClientFlag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN) { - c->flags |= ClientFlag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION; + if ((c->flags & (Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN | Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION)) + == Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN) { + c->flags |= Client::Flag::NO_MESSAGE_BOX_CLOSE_CONFIRMATION; send_update_client_config(c); } } diff --git a/src/ServerState.cc b/src/ServerState.cc index 2b70dcca..d4b70c19 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -29,8 +29,8 @@ ServerState::ServerState() bool is_ep3_only = (x > 14); shared_ptr l(new Lobby()); - l->flags |= LobbyFlag::PUBLIC | LobbyFlag::DEFAULT | LobbyFlag::PERSISTENT | - (is_ep3_only ? LobbyFlag::EPISODE_3 : 0); + l->flags |= Lobby::Flag::PUBLIC | Lobby::Flag::DEFAULT | Lobby::Flag::PERSISTENT | + (is_ep3_only ? Lobby::Flag::EPISODE_3_ONLY : 0); l->block = x + 1; l->type = x; l->name = lobby_name; @@ -52,7 +52,7 @@ ServerState::ServerState() } void ServerState::add_client_to_available_lobby(shared_ptr c) { - const auto& search_order = (c->flags & ClientFlag::EPISODE_3_GAMES) + const auto& search_order = (c->flags & Client::Flag::EPISODE_3) ? this->public_lobby_search_order_ep3 : this->public_lobby_search_order; @@ -77,7 +77,7 @@ void ServerState::add_client_to_available_lobby(shared_ptr c) { void ServerState::remove_client_from_lobby(shared_ptr c) { auto l = this->id_to_lobby.at(c->lobby_id); l->remove_client(c); - if (!(l->flags & LobbyFlag::PERSISTENT) && (l->count_clients() == 0)) { + if (!(l->flags & Lobby::Flag::PERSISTENT) && (l->count_clients() == 0)) { this->remove_lobby(l->lobby_id); } else { send_player_leave_notification(l, c->lobby_client_id); @@ -100,7 +100,7 @@ void ServerState::change_client_lobby(shared_ptr c, shared_ptr ne } if (current_lobby) { - if (!(current_lobby->flags & LobbyFlag::PERSISTENT) && (current_lobby->count_clients() == 0)) { + if (!(current_lobby->flags & Lobby::Flag::PERSISTENT) && (current_lobby->count_clients() == 0)) { this->remove_lobby(current_lobby->lobby_id); } else { send_player_leave_notification(current_lobby, old_lobby_client_id); diff --git a/src/Version.cc b/src/Version.cc index 1fdbffc1..d37bd052 100644 --- a/src/Version.cc +++ b/src/Version.cc @@ -13,34 +13,34 @@ uint16_t flags_for_version(GameVersion version, uint8_t sub_version) { case 0x00: // initial check (before 9E recognition) switch (version) { case GameVersion::DC: - return ClientFlag::DEFAULT_V2_DC; + return Client::Flag::DEFAULT_V2_DC; case GameVersion::GC: - return ClientFlag::DEFAULT_V3_GC; + return Client::Flag::DEFAULT_V3_GC; case GameVersion::PC: - return ClientFlag::DEFAULT_V2_PC; + return Client::Flag::DEFAULT_V2_PC; case GameVersion::PATCH: - return ClientFlag::DEFAULT_V2_PC; + return Client::Flag::DEFAULT_V2_PC; case GameVersion::BB: - return ClientFlag::DEFAULT_V3_BB; + return Client::Flag::DEFAULT_V4_BB; } break; case 0x29: // PSO PC - return ClientFlag::DEFAULT_V2_PC; + return Client::Flag::DEFAULT_V2_PC; case 0x30: // ??? case 0x31: // PSO Ep1&2 US10, US11, EU10, JP10 case 0x33: // PSO Ep1&2 EU50HZ case 0x34: // PSO Ep1&2 JP11 - return ClientFlag::DEFAULT_V3_GC; + return Client::Flag::DEFAULT_V3_GC; case 0x32: // PSO Ep1&2 US12, JP12 case 0x35: // PSO Ep1&2 US12, JP12 case 0x36: // PSO Ep1&2 US12, JP12 case 0x39: // PSO Ep1&2 US12, JP12 - return ClientFlag::DEFAULT_V3_GC_PLUS; + return Client::Flag::DEFAULT_V3_GC_PLUS; case 0x40: // PSO Ep3 trial case 0x41: // PSO Ep3 US case 0x42: // PSO Ep3 JP case 0x43: // PSO Ep3 UK - return ClientFlag::DEFAULT_V4; + return Client::Flag::DEFAULT_V3_GC_EP3; } return 0; } diff --git a/src/Version.hh b/src/Version.hh index 7987a01d..9be1931c 100644 --- a/src/Version.hh +++ b/src/Version.hh @@ -12,36 +12,6 @@ enum class GameVersion { BB, }; -enum ClientFlag { - // After joining a lobby, client will no longer send D6 commands when they close message boxes - NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN = 0x0004, - // Client has the above flag and has already joined a lobby - NO_MESSAGE_BOX_CLOSE_CONFIRMATION = 0x0008, - // Client can see Ep3 lobbies - CAN_SEE_EPISODE_3_LOBBIES = 0x0010, - // Client is episode 3 and should use its game mechanic - EPISODE_3_GAMES = 0x0020, - // Client is DC v1 (disables some features) - IS_DCV1 = 0x0040, - // Client is loading into a game - LOADING = 0x0080, - - // Client is in the information menu (login server only) - IN_INFORMATION_MENU = 0x0100, - // Client is at the welcome message (login server only) - AT_WELCOME_MESSAGE = 0x0200, - - // Note: There isn't a good way to detect Episode 3 until the player data is - // sent (via a 61 command), so the Episode3Games flag is set in that handler - DEFAULT_V1 = IS_DCV1, - DEFAULT_V2_DC = 0x0000, - DEFAULT_V2_PC = 0x0000, - DEFAULT_V3_GC = 0x0000, - DEFAULT_V3_GC_PLUS = NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN, - DEFAULT_V3_BB = NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN | NO_MESSAGE_BOX_CLOSE_CONFIRMATION, - DEFAULT_V4 = NO_MESSAGE_BOX_CLOSE_CONFIRMATION_AFTER_LOBBY_JOIN | EPISODE_3_GAMES | CAN_SEE_EPISODE_3_LOBBIES, -}; - uint16_t flags_for_version(GameVersion version, uint8_t sub_version); const char* name_for_version(GameVersion version); GameVersion version_for_name(const char* name);