From 5ff2694ded3329d62062573d11655d8047796de0 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Sun, 29 Oct 2023 18:14:09 -0700 Subject: [PATCH] split information menu across v1+v2 / v3 --- src/ReceiveCommands.cc | 3 ++- src/ServerState.cc | 31 ++++++++++++++++++++++++++----- src/ServerState.hh | 6 ++++-- system/config.example.json | 6 +++++- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/src/ReceiveCommands.cc b/src/ReceiveCommands.cc index acc1e875..5c0ef7ea 100644 --- a/src/ReceiveCommands.cc +++ b/src/ReceiveCommands.cc @@ -1892,7 +1892,8 @@ static void on_10(shared_ptr c, uint16_t, uint32_t, string& data) { } else { try { - send_message_box(c, c->require_server_state()->information_contents->at(item_id).c_str()); + auto contents = c->require_server_state()->information_contents_for_client(c); + send_message_box(c, contents->at(item_id).c_str()); } catch (const out_of_range&) { send_message_box(c, "$C6No such information exists."); } diff --git a/src/ServerState.cc b/src/ServerState.cc index b1d28c53..43ce03b7 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -773,26 +773,41 @@ void ServerState::parse_config(const JSON& json, bool is_reload) { shared_ptr information_menu_v2(new Menu(MenuID::INFORMATION, "Information")); shared_ptr information_menu_v3(new Menu(MenuID::INFORMATION, "Information")); - shared_ptr> information_contents(new vector()); + shared_ptr> information_contents_v2(new vector()); + shared_ptr> information_contents_v3(new vector()); information_menu_v2->items.emplace_back(InformationMenuItemID::GO_BACK, "Go back", "Return to the\nmain menu", MenuItem::Flag::INVISIBLE_IN_INFO_MENU); information_menu_v3->items.emplace_back(InformationMenuItemID::GO_BACK, "Go back", "Return to the\nmain menu", MenuItem::Flag::INVISIBLE_IN_INFO_MENU); { + auto blank_json = JSON::list(); + const JSON& default_json = json.get("InformationMenuContents", blank_json); + const JSON& v2_json = json.get("InformationMenuContentsV1V2", default_json); + const JSON& v3_json = json.get("InformationMenuContentsV3", default_json); + uint32_t item_id = 0; - for (const auto& item : json.at("InformationMenuContents").as_list()) { + for (const auto& item : v2_json.as_list()) { string name = item->get_string(0); string short_desc = item->get_string(1); information_menu_v2->items.emplace_back(item_id, name, short_desc, 0); + information_contents_v2->emplace_back(item->get_string(2)); + item_id++; + } + + item_id = 0; + for (const auto& item : v3_json.as_list()) { + string name = item->get_string(0); + string short_desc = item->get_string(1); information_menu_v3->items.emplace_back(item_id, name, short_desc, MenuItem::Flag::REQUIRES_MESSAGE_BOXES); - information_contents->emplace_back(item->get_string(2)); + information_contents_v3->emplace_back(item->get_string(2)); item_id++; } } this->information_menu_v2 = information_menu_v2; this->information_menu_v3 = information_menu_v3; - this->information_contents = information_contents; + this->information_contents_v2 = information_contents_v2; + this->information_contents_v3 = information_contents_v3; auto generate_redirect_destinations_menu = [&](vector>& ret_pds, const char* key) -> shared_ptr { shared_ptr ret(new Menu(MenuID::REDIRECT_DESTINATIONS, "Other servers")); @@ -1131,7 +1146,13 @@ void ServerState::load_dol_files() { this->dol_file_index.reset(new DOLFileIndex("system/dol")); } -shared_ptr ServerState::quest_index_for_client(shared_ptr c) const { +shared_ptr> ServerState::information_contents_for_client(shared_ptr c) const { + return ((c->version() == GameVersion::DC) || (c->version() == GameVersion::PC)) + ? this->information_contents_v2 + : this->information_contents_v3; +} + +shared_ptr ServerState::quest_index_for_client(shared_ptr c) const { return (c->flags & Client::Flag::IS_EPISODE_3) ? this->ep3_download_quest_index : this->default_quest_index; diff --git a/src/ServerState.hh b/src/ServerState.hh index bc04276d..5d73b148 100644 --- a/src/ServerState.hh +++ b/src/ServerState.hh @@ -139,7 +139,8 @@ struct ServerState : public std::enable_shared_from_this { std::shared_ptr information_menu_v2; std::shared_ptr information_menu_v3; - std::shared_ptr> information_contents; + std::shared_ptr> information_contents_v2; + std::shared_ptr> information_contents_v3; std::shared_ptr redirect_destinations_menu_dc; std::shared_ptr redirect_destinations_menu_pc; std::shared_ptr redirect_destinations_menu_gc; @@ -221,7 +222,8 @@ struct ServerState : public std::enable_shared_from_this { std::shared_ptr item_parameter_table_for_version(GameVersion version) const; std::string describe_item(GameVersion version, const ItemData& item, bool include_color_codes) const; - std::shared_ptr quest_index_for_client(std::shared_ptr c) const; + std::shared_ptr> information_contents_for_client(std::shared_ptr c) const; + std::shared_ptr quest_index_for_client(std::shared_ptr c) const; void set_port_configuration(const std::vector& port_configs); diff --git a/system/config.example.json b/system/config.example.json index e7166af8..74836b98 100644 --- a/system/config.example.json +++ b/system/config.example.json @@ -250,7 +250,11 @@ // Information menu contents. Each entry is a list containing [title, // short description, full contents]. In the short description and full // contents, you can use PSO escape codes with the $ character (for example, - // $Cx for colors). + // $Cx for colors). You can show different information menus to V1/V2 clients + // and V3 clients; to do so, copy InformationMenuContents to + // InformationMenuContentsV1V2 and InformationMenuContentsV3 and edit them as + // needed. (If either the V1V2 or V3 version of the information menu is not + // defined, this default version is used instead.) "InformationMenuContents": [ ["Lobby commands", "Show commands used\nin the lobby", "These commands can be used in the lobby.\n\n$C6%sli$C7: Show basic information about the lobby\n$C6%sarrow $C7: Change your lobby arrow color\n$C6%sln [name]$C7: Change the lobby type (for you only)\n$C6%sexit$C7: Leave the current game or lobby\n$C6%spatch $C7: Run a patch on your client\n\n$C8Episode 3 only:$C7\n$C6%ssong $C7: Play a jukebox song"], ["Game commands", "Show commands used\nin games", "These commands can be used to customize games.\n\n$C8Before starting a game:$C7\n$C6%ssecid $C7: Set your override section ID\n$C6%srand $C7: Set your override random seed\n\n$C8When in a game:$C7\n$C6%sli$C7: Show basic information about the game\n$C6%swhat$C7: Describe the nearest item on the ground\n$C6%smaxlevel $C7: Set maximum level to join\n$C6%sminlevel $C7: Set minimum level to join\n$C6%spassword [password]$C7: Lock or unlock the game"],