add tests for quest indexes and function compiler
This commit is contained in:
+10
-3
@@ -218,7 +218,8 @@ static vector<shared_ptr<CompiledFunctionCode>> compile_function_code(
|
||||
const string& function_directory,
|
||||
const string& system_directory,
|
||||
const string& name,
|
||||
const string& text) {
|
||||
const string& text,
|
||||
bool raise_on_any_failure) {
|
||||
unordered_set<string> get_include_stack;
|
||||
function<string(const string&)> get_include = [&](const string& name) -> string {
|
||||
const char* arch_name_token;
|
||||
@@ -335,6 +336,9 @@ static vector<shared_ptr<CompiledFunctionCode>> compile_function_code(
|
||||
|
||||
} catch (const exception& e) {
|
||||
string version_str = specific_version ? (" (" + str_for_specific_version(specific_version) + ")") : "";
|
||||
if (raise_on_any_failure) {
|
||||
throw;
|
||||
}
|
||||
function_compiler_log.warning_f("Failed to compile function {}{}: {}", name, version_str, e.what());
|
||||
}
|
||||
}
|
||||
@@ -342,7 +346,7 @@ static vector<shared_ptr<CompiledFunctionCode>> compile_function_code(
|
||||
return ret;
|
||||
}
|
||||
|
||||
FunctionCodeIndex::FunctionCodeIndex(const string& directory) {
|
||||
FunctionCodeIndex::FunctionCodeIndex(const string& directory, bool raise_on_any_failure) {
|
||||
string system_dir_path = directory.ends_with("/") ? (directory + "System") : (directory + "/System");
|
||||
|
||||
uint32_t next_menu_item_id = 1;
|
||||
@@ -404,7 +408,7 @@ FunctionCodeIndex::FunctionCodeIndex(const string& directory) {
|
||||
|
||||
string path = subdir_path + "/" + filename;
|
||||
string text = phosg::load_file(path);
|
||||
for (auto code : compile_function_code(arch, subdir_path, system_dir_path, name, text)) {
|
||||
for (auto code : compile_function_code(arch, subdir_path, system_dir_path, name, text, raise_on_any_failure)) {
|
||||
if (code->specific_version == 0) {
|
||||
code->specific_version = specific_version;
|
||||
}
|
||||
@@ -425,6 +429,9 @@ FunctionCodeIndex::FunctionCodeIndex(const string& directory) {
|
||||
}
|
||||
|
||||
} catch (const exception& e) {
|
||||
if (raise_on_any_failure) {
|
||||
throw runtime_error(format("({}) {}", filename, e.what()));
|
||||
}
|
||||
function_compiler_log.warning_f("Failed to compile function {}: {}", filename, e.what());
|
||||
}
|
||||
};
|
||||
|
||||
@@ -54,7 +54,7 @@ const char* name_for_architecture(CompiledFunctionCode::Architecture arch);
|
||||
|
||||
struct FunctionCodeIndex {
|
||||
FunctionCodeIndex() = default;
|
||||
explicit FunctionCodeIndex(const std::string& directory);
|
||||
FunctionCodeIndex(const std::string& directory, bool raise_on_any_failure);
|
||||
|
||||
std::unordered_map<std::string, std::shared_ptr<CompiledFunctionCode>> name_to_function;
|
||||
std::unordered_map<uint8_t, std::shared_ptr<CompiledFunctionCode>> index_to_function;
|
||||
|
||||
+11
-2
@@ -1720,7 +1720,7 @@ Action a_assemble_all_patches(
|
||||
versions, and one encrypted, for PSO GC JP v1.4, JP Ep3, and Ep3 Trial\n\
|
||||
Edition). The output files are saved in system/client-functions.\n",
|
||||
+[](phosg::Arguments& args) {
|
||||
auto fci = make_shared<FunctionCodeIndex>("system/client-functions");
|
||||
auto fci = make_shared<FunctionCodeIndex>("system/client-functions", false);
|
||||
|
||||
bool skip_encrypted = args.get<bool>("skip-encrypted");
|
||||
auto process_code = [&](shared_ptr<const CompiledFunctionCode> code,
|
||||
@@ -3038,7 +3038,16 @@ Action a_check_quests(
|
||||
s->load_patch_indexes();
|
||||
s->load_set_data_tables();
|
||||
s->load_maps();
|
||||
s->load_quest_index();
|
||||
s->load_quest_index(true);
|
||||
phosg::fwrite_fmt(stdout, "All quests indexed\n");
|
||||
});
|
||||
|
||||
Action a_check_client_functions(
|
||||
"check-client-functions", nullptr,
|
||||
+[](phosg::Arguments&) {
|
||||
set_all_log_levels(phosg::LogLevel::L_DEBUG);
|
||||
FunctionCodeIndex fci("system/client-functions", true);
|
||||
phosg::fwrite_fmt(stdout, "All client functions compiled\n");
|
||||
});
|
||||
|
||||
Action a_parse_object_graph(
|
||||
|
||||
+8
-1
@@ -436,7 +436,8 @@ QuestIndex::QuestIndex(
|
||||
const string& directory,
|
||||
shared_ptr<const QuestCategoryIndex> category_index,
|
||||
const unordered_map<string, shared_ptr<const CommonItemSet>>& common_item_sets,
|
||||
const unordered_map<string, shared_ptr<const RareItemSet>>& rare_item_sets)
|
||||
const unordered_map<string, shared_ptr<const RareItemSet>>& rare_item_sets,
|
||||
bool raise_on_any_failure)
|
||||
: directory(directory),
|
||||
category_index(category_index) {
|
||||
|
||||
@@ -585,6 +586,9 @@ QuestIndex::QuestIndex(
|
||||
}
|
||||
|
||||
} catch (const exception& e) {
|
||||
if (raise_on_any_failure) {
|
||||
throw runtime_error(format("({}) {}", filename, e.what()));
|
||||
}
|
||||
static_game_data_log.warning_f("({}) Failed to load quest file: ({})", filename, e.what());
|
||||
}
|
||||
}
|
||||
@@ -803,6 +807,9 @@ QuestIndex::QuestIndex(
|
||||
vq->meta.joinable ? "joinable" : "not joinable");
|
||||
}
|
||||
} catch (const exception& e) {
|
||||
if (raise_on_any_failure) {
|
||||
throw runtime_error(format("({}) {}", basename, e.what()));
|
||||
}
|
||||
static_game_data_log.warning_f("({}) Failed to index quest file: {}", basename, e.what());
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -136,7 +136,8 @@ struct QuestIndex {
|
||||
const std::string& directory,
|
||||
std::shared_ptr<const QuestCategoryIndex> category_index,
|
||||
const std::unordered_map<std::string, std::shared_ptr<const CommonItemSet>>& common_item_sets,
|
||||
const std::unordered_map<std::string, std::shared_ptr<const RareItemSet>>& rare_item_sets);
|
||||
const std::unordered_map<std::string, std::shared_ptr<const RareItemSet>>& rare_item_sets,
|
||||
bool raise_on_any_failure);
|
||||
phosg::JSON json() const;
|
||||
|
||||
std::shared_ptr<const Quest> get(uint32_t quest_number) const;
|
||||
|
||||
+7
-2
@@ -4019,7 +4019,7 @@ AssembledQuestScript assemble_quest_script(
|
||||
wrap_exceptions_with_line_ref(line, [&]() -> void {
|
||||
if (line.text[0] == '.') {
|
||||
if (line.text.starts_with(".include ")) {
|
||||
// Nothing to do
|
||||
// Nothing to do (see above)
|
||||
} else if (line.text.starts_with(".version ")) {
|
||||
string name = line.text.substr(9);
|
||||
phosg::strip_leading_whitespace(name);
|
||||
@@ -4268,7 +4268,12 @@ AssembledQuestScript assemble_quest_script(
|
||||
}
|
||||
|
||||
auto line_tokens = phosg::split(line.text, ' ', 1);
|
||||
const auto& opcode_def = opcodes.at(phosg::tolower(line_tokens.at(0)));
|
||||
const QuestScriptOpcodeDefinition* opcode_def;
|
||||
try {
|
||||
opcode_def = opcodes.at(phosg::tolower(line_tokens.at(0)));
|
||||
} catch (const out_of_range&) {
|
||||
throw std::runtime_error(std::format("invalid opcode name: {}", line_tokens.at(0)));
|
||||
}
|
||||
|
||||
bool use_args = version_has_args && (opcode_def->flags & F_ARGS);
|
||||
if (!use_args) {
|
||||
|
||||
+4
-4
@@ -2161,15 +2161,15 @@ void ServerState::load_ep3_tournament_state() {
|
||||
this->ep3_tournament_index->link_all_clients(this->shared_from_this());
|
||||
}
|
||||
|
||||
void ServerState::load_quest_index() {
|
||||
void ServerState::load_quest_index(bool raise_on_any_failure) {
|
||||
config_log.info_f("Collecting quests");
|
||||
this->quest_index = make_shared<QuestIndex>(
|
||||
"system/quests", this->quest_category_index, this->common_item_sets, this->rare_item_sets);
|
||||
"system/quests", this->quest_category_index, this->common_item_sets, this->rare_item_sets, raise_on_any_failure);
|
||||
}
|
||||
|
||||
void ServerState::compile_functions() {
|
||||
void ServerState::compile_functions(bool raise_on_any_failure) {
|
||||
config_log.info_f("Compiling client functions");
|
||||
this->function_code_index = make_shared<FunctionCodeIndex>("system/client-functions");
|
||||
this->function_code_index = make_shared<FunctionCodeIndex>("system/client-functions", raise_on_any_failure);
|
||||
}
|
||||
|
||||
void ServerState::load_dol_files() {
|
||||
|
||||
+2
-2
@@ -440,8 +440,8 @@ struct ServerState : public std::enable_shared_from_this<ServerState> {
|
||||
void load_ep3_cards();
|
||||
void load_ep3_maps();
|
||||
void load_ep3_tournament_state();
|
||||
void load_quest_index();
|
||||
void compile_functions();
|
||||
void load_quest_index(bool raise_on_any_failure = false);
|
||||
void compile_functions(bool raise_on_any_failure = false);
|
||||
void load_dol_files();
|
||||
|
||||
void load_all(bool enable_thread_pool);
|
||||
|
||||
@@ -14,7 +14,7 @@ start:
|
||||
|
||||
.data <VERS 0x802AB424 0x802AC2CC 0x802AD3F8 0x802AD1AC 0x802ABDE0 0x802ABE24 0x802AD360 0x802ACAF4>
|
||||
.data 0x00000004
|
||||
li r4, 0xFF00
|
||||
li r4, -0x100
|
||||
|
||||
.data <VERS 0x804A1F38 0x804A5658 0x804A7AF8 0x804A78B8 0x804A26E8 0x804A2BC8 0x804A7188 0x804A7608>
|
||||
.data 0x0000000C
|
||||
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
EXECUTABLE="$1"
|
||||
if [ -z "$EXECUTABLE" ]; then
|
||||
EXECUTABLE="./newserv"
|
||||
fi
|
||||
|
||||
$EXECUTABLE --config=tests/config.json check-client-functions
|
||||
Executable
+10
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
EXECUTABLE="$1"
|
||||
if [ -z "$EXECUTABLE" ]; then
|
||||
EXECUTABLE="./newserv"
|
||||
fi
|
||||
|
||||
$EXECUTABLE --config=tests/config.json check-quests
|
||||
Reference in New Issue
Block a user