From 2304a17dd0cb1f9d94e424ae429f18c4bd070c99 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Wed, 30 Aug 2023 18:44:21 -0700 Subject: [PATCH] use new JSON helpers --- src/Episode3/DataIndexes.cc | 58 ++++++++++++++++---------------- src/Episode3/Tournament.cc | 30 ++++++++--------- src/Main.cc | 21 +++++------- src/PatchFileIndex.cc | 17 +++++----- src/Quest.cc | 12 +++---- src/RareItemSet.cc | 21 ++++++------ src/ServerState.cc | 67 +++++++++++++++++++------------------ 7 files changed, 110 insertions(+), 116 deletions(-) diff --git a/src/Episode3/DataIndexes.cc b/src/Episode3/DataIndexes.cc index 1126311b..733d99e5 100644 --- a/src/Episode3/DataIndexes.cc +++ b/src/Episode3/DataIndexes.cc @@ -1089,39 +1089,37 @@ Rules::Rules() { Rules::Rules(const JSON& json) { this->clear(); - - auto dict = json.as_dict(); - this->overall_time_limit = json.get("overall_time_limit", this->overall_time_limit); - this->phase_time_limit = json.get("phase_time_limit", this->phase_time_limit); + this->overall_time_limit = json.get_int("overall_time_limit", this->overall_time_limit); + this->phase_time_limit = json.get_int("phase_time_limit", this->phase_time_limit); this->allowed_cards = json.get_enum("allowed_cards", this->allowed_cards); - this->min_dice = json.get("min_dice", this->min_dice); - this->max_dice = json.get("max_dice", this->max_dice); - this->disable_deck_shuffle = json.get("disable_deck_shuffle", this->disable_deck_shuffle); - this->disable_deck_loop = json.get("disable_deck_loop", this->disable_deck_loop); - this->char_hp = json.get("char_hp", this->char_hp); + this->min_dice = json.get_int("min_dice", this->min_dice); + this->max_dice = json.get_int("max_dice", this->max_dice); + this->disable_deck_shuffle = json.get_bool("disable_deck_shuffle", this->disable_deck_shuffle); + this->disable_deck_loop = json.get_bool("disable_deck_loop", this->disable_deck_loop); + this->char_hp = json.get_int("char_hp", this->char_hp); this->hp_type = json.get_enum("hp_type", this->hp_type); - this->no_assist_cards = json.get("no_assist_cards", this->no_assist_cards); - this->disable_dialogue = json.get("disable_dialogue", this->disable_dialogue); + this->no_assist_cards = json.get_bool("no_assist_cards", this->no_assist_cards); + this->disable_dialogue = json.get_bool("disable_dialogue", this->disable_dialogue); this->dice_exchange_mode = json.get_enum("dice_exchange_mode", this->dice_exchange_mode); - this->disable_dice_boost = json.get("disable_dice_boost", this->disable_dice_boost); + this->disable_dice_boost = json.get_bool("disable_dice_boost", this->disable_dice_boost); } JSON Rules::json() const { - unordered_map dict; - dict.emplace("overall_time_limit", this->overall_time_limit); - dict.emplace("phase_time_limit", this->phase_time_limit); - dict.emplace("allowed_cards", name_for_enum(this->allowed_cards)); - dict.emplace("min_dice", this->min_dice); - dict.emplace("max_dice", this->max_dice); - dict.emplace("disable_deck_shuffle", this->disable_deck_shuffle); - dict.emplace("disable_deck_loop", this->disable_deck_loop); - dict.emplace("char_hp", this->char_hp); - dict.emplace("hp_type", name_for_enum(this->hp_type)); - dict.emplace("no_assist_cards", this->no_assist_cards); - dict.emplace("disable_dialogue", this->disable_dialogue); - dict.emplace("dice_exchange_mode", name_for_enum(this->dice_exchange_mode)); - dict.emplace("disable_dice_boost", this->disable_dice_boost); - return JSON(std::move(dict)); + return JSON::dict({ + {"overall_time_limit", this->overall_time_limit}, + {"phase_time_limit", this->phase_time_limit}, + {"allowed_cards", name_for_enum(this->allowed_cards)}, + {"min_dice", this->min_dice}, + {"max_dice", this->max_dice}, + {"disable_deck_shuffle", this->disable_deck_shuffle}, + {"disable_deck_loop", this->disable_deck_loop}, + {"char_hp", this->char_hp}, + {"hp_type", name_for_enum(this->hp_type)}, + {"no_assist_cards", this->no_assist_cards}, + {"disable_dialogue", this->disable_dialogue}, + {"dice_exchange_mode", name_for_enum(this->dice_exchange_mode)}, + {"disable_dice_boost", this->disable_dice_boost}, + }); } void Rules::set_defaults() { @@ -2004,9 +2002,9 @@ COMDeckIndex::COMDeckIndex(const string& filename) { for (const auto& def_json : json.as_list()) { auto& def = this->decks.emplace_back(new COMDeckDefinition()); def->index = this->decks.size() - 1; - def->player_name = def_json.at(0).as_string(); - def->deck_name = def_json.at(1).as_string(); - auto card_ids_json = def_json.at(2); + def->player_name = def_json->at(0).as_string(); + def->deck_name = def_json->at(1).as_string(); + auto card_ids_json = def_json->at(2); for (size_t z = 0; z < 0x1F; z++) { def->card_ids[z] = card_ids_json.at(z).as_int(); } diff --git a/src/Episode3/Tournament.cc b/src/Episode3/Tournament.cc index a4119c23..5abb991f 100644 --- a/src/Episode3/Tournament.cc +++ b/src/Episode3/Tournament.cc @@ -325,27 +325,27 @@ void Tournament::init() { vector team_index_to_rounds_cleared; bool is_registration_complete; - if (this->source_json) { - this->name = this->source_json.at("name").as_string(); - this->map = this->map_index->definition_for_number(this->source_json.at("map_number")); + if (!this->source_json.is_null()) { + this->name = this->source_json.get_string("name"); + this->map = this->map_index->definition_for_number(this->source_json.get_int("map_number")); this->rules = Rules(this->source_json.at("rules")); - this->is_2v2 = this->source_json.at("is_2v2"); - is_registration_complete = this->source_json.at("is_registration_complete"); + this->is_2v2 = this->source_json.get_bool("is_2v2"); + is_registration_complete = this->source_json.get_bool("is_registration_complete"); - for (const auto& team_json : this->source_json.at("teams").as_list()) { + for (const auto& team_json : this->source_json.get_list("teams")) { auto& team = this->teams.emplace_back(new Team( this->shared_from_this(), this->teams.size(), - team_json.at("max_players"))); - team->name = team_json.at("name").as_string(); - team->password = team_json.at("password").as_string(); - team_index_to_rounds_cleared.emplace_back(team_json.at("num_rounds_cleared")); - for (const auto& player_json : team_json.at("player_specs").as_list()) { - if (player_json.is_int()) { - team->players.emplace_back(player_json); - this->all_player_serial_numbers.emplace(player_json); + team_json->get_int("max_players"))); + team->name = team_json->get_string("name"); + team->password = team_json->get_string("password"); + team_index_to_rounds_cleared.emplace_back(team_json->get_int("num_rounds_cleared")); + for (const auto& player_json : team_json->get_list("player_specs")) { + if (player_json->is_int()) { + team->players.emplace_back(player_json->as_int()); + this->all_player_serial_numbers.emplace(player_json->as_int()); } else { - team->players.emplace_back(this->com_deck_index->deck_for_name(player_json)); + team->players.emplace_back(this->com_deck_index->deck_for_name(player_json->as_string())); } } } diff --git a/src/Main.cc b/src/Main.cc index 2730ef9c..b6ab590c 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -43,7 +43,7 @@ template vector parse_int_vector(const JSON& o) { vector ret; for (const auto& x : o.as_list()) { - ret.emplace_back(x.as_int()); + ret.emplace_back(x->as_int()); } return ret; } @@ -1400,7 +1400,7 @@ int main(int argc, char** argv) { return ret; }; - JSON::dict_type episodes_dict; + auto episodes_dict = JSON::dict(); static const array>>, 3> episodes = { make_pair(Episode::EP1, generate_table(Episode::EP1)), make_pair(Episode::EP2, generate_table(Episode::EP2)), @@ -1409,11 +1409,11 @@ int main(int argc, char** argv) { for (const auto& episode_it : episodes) { Episode episode = episode_it.first; const auto& rt_index_to_enemy_type = episode_it.second; - JSON::dict_type difficulty_dict; + auto difficulty_dict = JSON::dict(); for (uint8_t difficulty = 0; difficulty < 4; difficulty++) { - JSON::dict_type section_id_dict; + auto section_id_dict = JSON::dict(); for (uint8_t section_id = 0; section_id < 10; section_id++) { - JSON::dict_type collection_dict; + auto collection_dict = JSON::dict(); for (size_t rt_index = 0; rt_index < rt_index_to_enemy_type.size(); rt_index++) { const auto& enemy_types = rt_index_to_enemy_type[rt_index]; @@ -1428,18 +1428,17 @@ int main(int argc, char** argv) { } auto frac = reduce_fraction(spec.probability, 0x100000000); - JSON::list_type specs_list; - JSON specs_json = {JSON::list({string_printf("%" PRIu64 "/%" PRIu64, frac.first, frac.second), primary_identifier})}; + auto specs_json = JSON::list({JSON::list({string_printf("%" PRIu64 "/%" PRIu64, frac.first, frac.second), primary_identifier})}); for (const auto& enemy_type : enemy_types) { if (enemy_type_valid_for_episode(episode, enemy_type)) { - collection_dict.emplace(name_for_enum(enemy_type), specs_json); + collection_dict.emplace(name_for_enum(enemy_type), std::move(specs_json)); } } } } for (size_t area = 0; area < 0x12; area++) { - JSON::list_type area_list; + auto area_list = JSON::list(); for (const auto& spec : rs.get_box_specs(GameMode::NORMAL, episode, difficulty, section_id, area)) { uint32_t primary_identifier = (spec.item_code[0] << 16) | (spec.item_code[1] << 8) | spec.item_code[2]; @@ -1466,9 +1465,7 @@ int main(int argc, char** argv) { episodes_dict.emplace(token_name_for_episode(episode), std::move(difficulty_dict)); } - JSON::dict_type root_dict; - root_dict.emplace("Normal", std::move(episodes_dict)); - JSON root_json = std::move(root_dict); + auto root_json = JSON::dict({{"Normal", std::move(episodes_dict)}}); string json_data = root_json.serialize( JSON::SerializeOption::FORMAT | JSON::SerializeOption::HEX_INTEGERS | diff --git a/src/PatchFileIndex.cc b/src/PatchFileIndex.cc index 1bfd9993..19bd5338 100644 --- a/src/PatchFileIndex.cc +++ b/src/PatchFileIndex.cc @@ -78,9 +78,8 @@ PatchFileIndex::PatchFileIndex(const string& root_dir) JSON cache_item_json; try { cache_item_json = metadata_cache_json.at(relative_item_path); - auto cache_item = metadata_cache_json.at(relative_item_path).as_list(); - uint64_t cached_size = cache_item.at(0); - uint64_t cached_mtime = cache_item.at(1); + uint64_t cached_size = cache_item_json.get_int(0); + uint64_t cached_mtime = cache_item_json.get_int(1); if (static_cast(st.st_mtime) != cached_mtime) { throw runtime_error("file has been modified"); } @@ -88,9 +87,9 @@ PatchFileIndex::PatchFileIndex(const string& root_dir) throw runtime_error("file size has changed"); } f->size = cached_size; - f->crc32 = cache_item.at(2); - for (const auto& chunk_crc32_json : cache_item.at(3).as_list()) { - f->chunk_crcs.emplace_back(chunk_crc32_json.as_int()); + f->crc32 = cache_item_json.get_int(2); + for (const auto& chunk_crc32_json : cache_item_json.get_list(3)) { + f->chunk_crcs.emplace_back(chunk_crc32_json->as_int()); } } catch (const exception& e) { @@ -106,18 +105,18 @@ PatchFileIndex::PatchFileIndex(const string& root_dir) } // File was modified or cache item was missing; make a new cache item - vector chunk_crcs_item; + auto chunk_crcs_item = JSON::list(); for (uint32_t chunk_crc : f->chunk_crcs) { chunk_crcs_item.emplace_back(chunk_crc); } - new_metadata_cache_json.as_dict().emplace( + new_metadata_cache_json.emplace( relative_item_path, JSON::list({f->size, st.st_mtime, f->crc32, std::move(chunk_crcs_item)})); should_write_metadata_cache = true; } else { // File was not modified and cache item was valid; just use the // existing cache item - new_metadata_cache_json.as_dict().emplace( + new_metadata_cache_json.emplace( relative_item_path, std::move(cache_item_json)); } diff --git a/src/Quest.cc b/src/Quest.cc index ab0fe36b..10187f17 100644 --- a/src/Quest.cc +++ b/src/Quest.cc @@ -23,11 +23,11 @@ using namespace std; QuestCategoryIndex::Category::Category(uint32_t category_id, const JSON& json) : category_id(category_id) { - this->flags = json.at(0); - this->type = json.at(1).as_string().at(0); - this->short_token = json.at(2).as_string(); - this->name = decode_sjis(json.at(3)); - this->description = decode_sjis(json.at(4)); + this->flags = json.get_int(0); + this->type = json.get_string(1).at(0); + this->short_token = json.get_string(2); + this->name = decode_sjis(json.get_string(3)); + this->description = decode_sjis(json.get_string(4)); } bool QuestCategoryIndex::Category::matches_flags(uint8_t request) const { @@ -42,7 +42,7 @@ bool QuestCategoryIndex::Category::matches_flags(uint8_t request) const { QuestCategoryIndex::QuestCategoryIndex(const JSON& json) { uint32_t next_category_id = 1; for (const auto& it : json.as_list()) { - this->categories.emplace_back(next_category_id++, it); + this->categories.emplace_back(next_category_id++, *it); } } diff --git a/src/RareItemSet.cc b/src/RareItemSet.cc index 3f97f15e..e2f86d06 100644 --- a/src/RareItemSet.cc +++ b/src/RareItemSet.cc @@ -176,21 +176,21 @@ JSONRareItemSet::JSONRareItemSet(const JSON& json) { {{"Normal", GameMode::NORMAL}, {"Battle", GameMode::BATTLE}, {"Challenge", GameMode::CHALLENGE}, {"Solo", GameMode::SOLO}}); GameMode mode = mode_keys.at(mode_it.first); - for (const auto& episode_it : mode_it.second.as_dict()) { + for (const auto& episode_it : mode_it.second->as_dict()) { static const unordered_map episode_keys( {{"Episode1", Episode::EP1}, {"Episode2", Episode::EP2}, {"Episode4", Episode::EP4}}); Episode episode = episode_keys.at(episode_it.first); - for (const auto& difficulty_it : episode_it.second.as_dict()) { + for (const auto& difficulty_it : episode_it.second->as_dict()) { static const unordered_map difficulty_keys( {{"Normal", 0}, {"Hard", 1}, {"VeryHard", 2}, {"Ultimate", 3}}); uint8_t difficulty = difficulty_keys.at(difficulty_it.first); - for (const auto& section_id_it : difficulty_it.second.as_dict()) { + for (const auto& section_id_it : difficulty_it.second->as_dict()) { uint8_t section_id = section_id_for_name(section_id_it.first); auto& collection = this->collections[this->key_for_params(mode, episode, difficulty, section_id)]; - for (const auto& item_it : section_id_it.second.as_dict()) { + for (const auto& item_it : section_id_it.second->as_dict()) { vector* target; if (starts_with(item_it.first, "Box-")) { uint8_t area = area_for_name(item_it.first.substr(4)); @@ -206,15 +206,14 @@ JSONRareItemSet::JSONRareItemSet(const JSON& json) { target = &collection.rt_index_to_specs[index]; } - for (const auto& spec_json : item_it.second.as_list()) { - auto& spec_list = spec_json.as_list(); + for (const auto& spec_json : item_it.second->as_list()) { auto& d = target->emplace_back(); - auto prob_desc = spec_list.at(0); + auto prob_desc = spec_json->at(0); if (prob_desc.is_int()) { - d.probability = prob_desc; + d.probability = prob_desc.as_int(); } else if (prob_desc.is_string()) { - auto tokens = split(prob_desc, '/'); + auto tokens = split(prob_desc.as_string(), '/'); if (tokens.size() != 2) { throw runtime_error("invalid probability specification"); } @@ -227,9 +226,9 @@ JSONRareItemSet::JSONRareItemSet(const JSON& json) { } } - auto item_desc = spec_list.at(1); + auto item_desc = spec_json->at(1); if (item_desc.is_int()) { - uint32_t item_code = item_desc; + uint32_t item_code = item_desc.as_int(); d.item_code[0] = (item_code >> 16) & 0xFF; d.item_code[1] = (item_code >> 8) & 0xFF; d.item_code[2] = item_code & 0xFF; diff --git a/src/ServerState.cc b/src/ServerState.cc index 0183b329..01f350f7 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -398,11 +398,11 @@ void ServerState::create_menus(const JSON& json) { { uint32_t item_id = 0; for (const auto& item : json.at("InformationMenuContents").as_list()) { - u16string name = decode_sjis(item.at(0)); - u16string short_desc = decode_sjis(item.at(1)); + u16string name = decode_sjis(item->get_string(0)); + u16string short_desc = decode_sjis(item->get_string(1)); information_menu_v2->items.emplace_back(item_id, name, short_desc, 0); information_menu_v3->items.emplace_back(item_id, name, short_desc, MenuItem::Flag::REQUIRES_MESSAGE_BOXES); - information_contents->emplace_back(decode_sjis(item.at(2))); + information_contents->emplace_back(decode_sjis(item->get_string(2))); item_id++; } } @@ -417,7 +417,7 @@ void ServerState::create_menus(const JSON& json) { try { map sorted_jsons; for (const auto& it : json.at(key).as_dict()) { - sorted_jsons.emplace(it.first, it.second); + sorted_jsons.emplace(it.first, *it.second); } ret->items.emplace_back(ProxyDestinationsMenuItemID::GO_BACK, u"Go back", @@ -427,7 +427,7 @@ void ServerState::create_menus(const JSON& json) { uint32_t item_id = 0; for (const auto& item : sorted_jsons) { - const string& netloc_str = item.second; + const string& netloc_str = item.second.as_string(); const string& description = "$C7Remote server:\n$C6" + netloc_str; ret->items.emplace_back(item_id, decode_sjis(item.first), decode_sjis(description), 0); ret_pds.emplace_back(parse_netloc(netloc_str)); @@ -448,7 +448,7 @@ void ServerState::create_menus(const JSON& json) { this->proxy_destinations_xb, "ProxyDestinations-XB"); try { - const string& netloc_str = json.at("ProxyDestination-Patch"); + const string& netloc_str = json.get_string("ProxyDestination-Patch"); this->proxy_destination_patch = parse_netloc(netloc_str); config_log.info("Patch server proxy is enabled with destination %s", netloc_str.c_str()); for (auto& it : this->name_to_port_config) { @@ -461,7 +461,7 @@ void ServerState::create_menus(const JSON& json) { this->proxy_destination_patch.second = 0; } try { - const string& netloc_str = json.at("ProxyDestination-BB"); + const string& netloc_str = json.get_string("ProxyDestination-BB"); this->proxy_destination_bb = parse_netloc(netloc_str); config_log.info("BB proxy is enabled with destination %s", netloc_str.c_str()); for (auto& it : this->name_to_port_config) { @@ -474,9 +474,9 @@ void ServerState::create_menus(const JSON& json) { this->proxy_destination_bb.second = 0; } - this->welcome_message = decode_sjis(json.get("WelcomeMessage", "")); - this->pc_patch_server_message = decode_sjis(json.get("PCPatchServerMessage", "")); - this->bb_patch_server_message = decode_sjis(json.get("BBPatchServerMessage", "")); + this->welcome_message = decode_sjis(json.get_string("WelcomeMessage", "")); + this->pc_patch_server_message = decode_sjis(json.get_string("PCPatchServerMessage", "")); + this->bb_patch_server_message = decode_sjis(json.get_string("BBPatchServerMessage", "")); } shared_ptr ServerState::load_bb_file( @@ -554,12 +554,12 @@ JSON ServerState::load_config() const { static vector parse_port_configuration(const JSON& json) { vector ret; for (const auto& item_json_it : json.as_dict()) { - auto item_list = item_json_it.second.as_list(); + const auto& item_list = item_json_it.second; PortConfiguration& pc = ret.emplace_back(); pc.name = item_json_it.first; - pc.port = item_list[0]; - pc.version = version_for_name(item_list[1].as_string().c_str()); - pc.behavior = server_behavior_for_name(item_list[2].as_string().c_str()); + pc.port = item_list->at(0).as_int(); + pc.version = version_for_name(item_list->at(1).as_string().c_str()); + pc.behavior = server_behavior_for_name(item_list->at(2).as_string().c_str()); } return ret; } @@ -607,33 +607,34 @@ void ServerState::parse_config(const JSON& json) { } this->all_addresses.emplace("", this->external_address); - this->dns_server_port = json.get("DNSServerPort", this->dns_server_port); + this->dns_server_port = json.get_int("DNSServerPort", this->dns_server_port); try { for (const auto& item : json.at("IPStackListen").as_list()) { - this->ip_stack_addresses.emplace_back(item.as_string()); + this->ip_stack_addresses.emplace_back(item->as_string()); } } catch (const out_of_range&) { } - this->ip_stack_debug = json.get("IPStackDebug", this->ip_stack_debug); - this->allow_unregistered_users = json.get("AllowUnregisteredUsers", this->allow_unregistered_users); - this->item_tracking_enabled = json.get("EnableItemTracking", this->item_tracking_enabled); - this->drops_enabled = json.get("EnableDrops", this->drops_enabled); - this->episode_3_send_function_call_enabled = json.get("EnableEpisode3SendFunctionCall", this->episode_3_send_function_call_enabled); - this->catch_handler_exceptions = json.get("CatchHandlerExceptions", this->catch_handler_exceptions); - this->proxy_allow_save_files = json.get("ProxyAllowSaveFiles", this->proxy_allow_save_files); - this->proxy_enable_login_options = json.get("ProxyEnableLoginOptions", this->proxy_enable_login_options); - this->ep3_behavior_flags = json.get("Episode3BehaviorFlags", this->ep3_behavior_flags); - this->ep3_card_auction_points = json.get("CardAuctionPoints", this->ep3_card_auction_points); + this->ip_stack_debug = json.get_bool("IPStackDebug", this->ip_stack_debug); + this->allow_unregistered_users = json.get_bool("AllowUnregisteredUsers", this->allow_unregistered_users); + this->item_tracking_enabled = json.get_bool("EnableItemTracking", this->item_tracking_enabled); + this->drops_enabled = json.get_bool("EnableDrops", this->drops_enabled); + this->episode_3_send_function_call_enabled = json.get_bool("EnableEpisode3SendFunctionCall", this->episode_3_send_function_call_enabled); + this->catch_handler_exceptions = json.get_bool("CatchHandlerExceptions", this->catch_handler_exceptions); + this->ep3_infinite_meseta = json.get_bool("Episode3InfiniteMeseta", this->ep3_infinite_meseta); + this->proxy_allow_save_files = json.get_bool("ProxyAllowSaveFiles", this->proxy_allow_save_files); + this->proxy_enable_login_options = json.get_bool("ProxyEnableLoginOptions", this->proxy_enable_login_options); + this->ep3_behavior_flags = json.get_int("Episode3BehaviorFlags", this->ep3_behavior_flags); + this->ep3_card_auction_points = json.get_int("CardAuctionPoints", this->ep3_card_auction_points); try { const auto& i = json.at("CardAuctionSize"); if (i.is_int()) { - this->ep3_card_auction_min_size = i; + this->ep3_card_auction_min_size = i.as_int(); this->ep3_card_auction_max_size = this->ep3_card_auction_min_size; } else { - this->ep3_card_auction_min_size = i.at(0); - this->ep3_card_auction_max_size = i.at(1); + this->ep3_card_auction_min_size = i.at(0).as_int(); + this->ep3_card_auction_max_size = i.at(1).as_int(); } } catch (const out_of_range&) { this->ep3_card_auction_min_size = 0; @@ -643,13 +644,13 @@ void ServerState::parse_config(const JSON& json) { for (const auto& it : json.at("CardAuctionPool").as_dict()) { this->ep3_card_auction_pool.emplace_back( CardAuctionPoolEntry{ - .probability = it.second.at(0), + .probability = static_cast(it.second->at(0).as_int()), .card_id = 0, - .min_price = it.second.at(1), + .min_price = static_cast(it.second->at(1).as_int()), .card_name = it.first}); } - set_log_levels_from_json(json.get("LogLevels", JSON::dict_type())); + set_log_levels_from_json(json.get("LogLevels", JSON::dict())); for (const string& filename : list_directory("system/blueburst/keys")) { if (!ends_with(filename, ".nsk")) { @@ -692,7 +693,7 @@ void ServerState::parse_config(const JSON& json) { } catch (const out_of_range&) { } - this->ep3_menu_song = json.get("Episode3MenuSong", this->ep3_menu_song); + this->ep3_menu_song = json.get_int("Episode3MenuSong", this->ep3_menu_song); try { this->quest_category_index.reset(new QuestCategoryIndex(json.at("QuestCategories")));