add reload config shell command

This commit is contained in:
Martin Michelsen
2023-09-09 00:06:30 -07:00
parent 901b2b78d2
commit a40d1ad851
3 changed files with 60 additions and 41 deletions
+5 -1
View File
@@ -120,7 +120,7 @@ Server commands:\n\
quests - reindex all quests\n\ quests - reindex all quests\n\
functions - recompile all client-side functions\n\ functions - recompile all client-side functions\n\
dol-files - reindex all DOL files\n\ dol-files - reindex all DOL files\n\
config - reload some fields from config.json\n\ config - reload most fields from config.json\n\
Reloading will not affect items that are in use; for example, if an Episode\n\ Reloading will not affect items that are in use; for example, if an Episode\n\
3 battle is in progress, it will continue to use the previous map and card\n\ 3 battle is in progress, it will continue to use the previous map and card\n\
definitions. Similarly, BB clients are not forced to disconnect or reload\n\ definitions. Similarly, BB clients are not forced to disconnect or reload\n\
@@ -287,6 +287,10 @@ Proxy session commands:\n\
auto config_json = this->state->load_config(); auto config_json = this->state->load_config();
this->state->load_dol_files(); this->state->load_dol_files();
this->state->create_menus(config_json); this->state->create_menus(config_json);
} else if (type == "config") {
auto config_json = this->state->load_config();
this->state->parse_config(config_json, true);
this->state->resolve_ep3_card_auction_pool();
} else { } else {
throw invalid_argument("incorrect data type"); throw invalid_argument("incorrect data type");
} }
+52 -39
View File
@@ -85,13 +85,15 @@ ServerState::ServerState(const char* config_filename, bool is_replay)
// Load all the necessary data // Load all the necessary data
auto config = this->load_config(); auto config = this->load_config();
this->collect_network_addresses(); this->collect_network_addresses();
this->parse_config(config); this->parse_config(config, false);
this->load_bb_private_keys();
this->load_licenses(); this->load_licenses();
this->load_patch_indexes(); this->load_patch_indexes();
this->load_battle_params(); this->load_battle_params();
this->load_level_table(); this->load_level_table();
this->load_item_tables(); this->load_item_tables();
this->load_ep3_data(); this->load_ep3_data();
this->resolve_ep3_card_auction_pool();
this->load_quest_index(); this->load_quest_index();
this->compile_functions(); this->compile_functions();
this->load_dol_files(); this->load_dol_files();
@@ -566,24 +568,33 @@ static vector<PortConfiguration> parse_port_configuration(const JSON& json) {
return ret; return ret;
} }
void ServerState::parse_config(const JSON& json) { void ServerState::parse_config(const JSON& json, bool is_reload) {
config_log.info("Parsing configuration"); config_log.info("Parsing configuration");
this->name = decode_sjis(json.at("ServerName").as_string()); this->name = decode_sjis(json.at("ServerName").as_string());
try { if (!is_reload) {
this->username = json.at("User").as_string(); try {
if (this->username == "$SUDO_USER") { this->username = json.at("User").as_string();
const char* user_from_env = getenv("SUDO_USER"); if (this->username == "$SUDO_USER") {
if (!user_from_env) { const char* user_from_env = getenv("SUDO_USER");
throw runtime_error("configuration specifies $SUDO_USER, but variable is not defined"); if (!user_from_env) {
throw runtime_error("configuration specifies $SUDO_USER, but variable is not defined");
}
this->username = user_from_env;
} }
this->username = user_from_env; } catch (const out_of_range&) {
} }
} catch (const out_of_range&) {
}
this->set_port_configuration(parse_port_configuration(json.at("PortConfiguration"))); this->set_port_configuration(parse_port_configuration(json.at("PortConfiguration")));
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());
}
} catch (const out_of_range&) {
}
}
auto local_address_str = json.at("LocalAddress").as_string(); auto local_address_str = json.at("LocalAddress").as_string();
try { try {
@@ -595,6 +606,7 @@ void ServerState::parse_config(const JSON& json) {
this->local_address = address_for_string(local_address_str.c_str()); this->local_address = address_for_string(local_address_str.c_str());
config_log.info("Added local address: %s", local_address_str.c_str()); config_log.info("Added local address: %s", local_address_str.c_str());
} }
this->all_addresses.erase("<local>");
this->all_addresses.emplace("<local>", this->local_address); this->all_addresses.emplace("<local>", this->local_address);
auto external_address_str = json.at("ExternalAddress").as_string(); auto external_address_str = json.at("ExternalAddress").as_string();
@@ -607,16 +619,9 @@ void ServerState::parse_config(const JSON& json) {
this->external_address = address_for_string(external_address_str.c_str()); this->external_address = address_for_string(external_address_str.c_str());
config_log.info("Added external address: %s", external_address_str.c_str()); config_log.info("Added external address: %s", external_address_str.c_str());
} }
this->all_addresses.erase("<external>");
this->all_addresses.emplace("<external>", this->external_address); this->all_addresses.emplace("<external>", this->external_address);
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());
}
} catch (const out_of_range&) {
}
this->ip_stack_debug = json.get_bool("IPStackDebug", this->ip_stack_debug); 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->allow_unregistered_users = json.get_bool("AllowUnregisteredUsers", this->allow_unregistered_users);
this->item_tracking_enabled = json.get_bool("EnableItemTracking", this->item_tracking_enabled); this->item_tracking_enabled = json.get_bool("EnableItemTracking", this->item_tracking_enabled);
@@ -702,21 +707,13 @@ void ServerState::parse_config(const JSON& json) {
set_log_levels_from_json(json.get("LogLevels", JSON::dict())); set_log_levels_from_json(json.get("LogLevels", JSON::dict()));
for (const string& filename : list_directory("system/blueburst/keys")) { if (!is_reload) {
if (!ends_with(filename, ".nsk")) { try {
continue; this->run_shell_behavior = json.at("RunInteractiveShell").as_bool()
? ServerState::RunShellBehavior::ALWAYS
: ServerState::RunShellBehavior::NEVER;
} catch (const out_of_range&) {
} }
this->bb_private_keys.emplace_back(new PSOBBEncryption::KeyFile(
load_object_file<PSOBBEncryption::KeyFile>("system/blueburst/keys/" + filename)));
config_log.info("Loaded Blue Burst key file: %s", filename.c_str());
}
config_log.info("%zu Blue Burst key file(s) loaded", this->bb_private_keys.size());
try {
this->run_shell_behavior = json.at("RunInteractiveShell").as_bool()
? ServerState::RunShellBehavior::ALWAYS
: ServerState::RunShellBehavior::NEVER;
} catch (const out_of_range&) {
} }
try { try {
@@ -745,14 +742,28 @@ void ServerState::parse_config(const JSON& json) {
this->ep3_menu_song = json.get_int("Episode3MenuSong", this->ep3_menu_song); this->ep3_menu_song = json.get_int("Episode3MenuSong", this->ep3_menu_song);
try { if (!is_reload) {
this->quest_category_index.reset(new QuestCategoryIndex(json.at("QuestCategories"))); try {
} catch (const exception& e) { this->quest_category_index.reset(new QuestCategoryIndex(json.at("QuestCategories")));
throw runtime_error(string_printf( } catch (const exception& e) {
"QuestCategories is missing or invalid in config.json (%s) - see config.example.json for an example", e.what())); throw runtime_error(string_printf(
"QuestCategories is missing or invalid in config.json (%s) - see config.example.json for an example", e.what()));
}
} }
} }
void ServerState::load_bb_private_keys() {
for (const string& filename : list_directory("system/blueburst/keys")) {
if (!ends_with(filename, ".nsk")) {
continue;
}
this->bb_private_keys.emplace_back(new PSOBBEncryption::KeyFile(
load_object_file<PSOBBEncryption::KeyFile>("system/blueburst/keys/" + filename)));
config_log.info("Loaded Blue Burst key file: %s", filename.c_str());
}
config_log.info("%zu Blue Burst key file(s) loaded", this->bb_private_keys.size());
}
void ServerState::load_licenses() { void ServerState::load_licenses() {
config_log.info("Loading license list"); config_log.info("Loading license list");
this->license_manager.reset(new LicenseManager("system/licenses.nsi")); this->license_manager.reset(new LicenseManager("system/licenses.nsi"));
@@ -872,7 +883,9 @@ void ServerState::load_ep3_data() {
this->ep3_tournament_index.reset(new Episode3::TournamentIndex( this->ep3_tournament_index.reset(new Episode3::TournamentIndex(
this->ep3_map_index, this->ep3_com_deck_index, tournament_state_filename)); this->ep3_map_index, this->ep3_com_deck_index, tournament_state_filename));
config_log.info("Loaded Episode 3 tournament state"); config_log.info("Loaded Episode 3 tournament state");
}
void ServerState::resolve_ep3_card_auction_pool() {
config_log.info("Resolving Episode 3 card auction pool"); config_log.info("Resolving Episode 3 card auction pool");
for (auto& e : this->ep3_card_auction_pool) { for (auto& e : this->ep3_card_auction_pool) {
try { try {
+3 -1
View File
@@ -187,13 +187,15 @@ struct ServerState {
JSON load_config() const; JSON load_config() const;
void collect_network_addresses(); void collect_network_addresses();
void parse_config(const JSON& config_json); void parse_config(const JSON& config_json, bool is_reload);
void load_bb_private_keys();
void load_licenses(); void load_licenses();
void load_patch_indexes(); void load_patch_indexes();
void load_battle_params(); void load_battle_params();
void load_level_table(); void load_level_table();
void load_item_tables(); void load_item_tables();
void load_ep3_data(); void load_ep3_data();
void resolve_ep3_card_auction_pool();
void load_quest_index(); void load_quest_index();
void compile_functions(); void compile_functions();
void load_dol_files(); void load_dol_files();