write assemble-all-patches action
This commit is contained in:
@@ -223,6 +223,7 @@ FunctionCodeIndex::FunctionCodeIndex(const string& directory) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
code->specific_version = specific_version;
|
code->specific_version = specific_version;
|
||||||
|
code->source_path = path;
|
||||||
code->short_name = short_name;
|
code->short_name = short_name;
|
||||||
this->name_to_function.emplace(name, code);
|
this->name_to_function.emplace(name, code);
|
||||||
if (is_patch) {
|
if (is_patch) {
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ struct CompiledFunctionCode {
|
|||||||
std::vector<uint16_t> relocation_deltas;
|
std::vector<uint16_t> relocation_deltas;
|
||||||
std::unordered_map<std::string, uint32_t> label_offsets;
|
std::unordered_map<std::string, uint32_t> label_offsets;
|
||||||
uint32_t entrypoint_offset_offset;
|
uint32_t entrypoint_offset_offset;
|
||||||
|
std::string source_path; // Path to source file from newserv root
|
||||||
std::string short_name; // Based on filename
|
std::string short_name; // Based on filename
|
||||||
std::string long_name; // From .meta name directive
|
std::string long_name; // From .meta name directive
|
||||||
std::string description; // From .meta description directive
|
std::string description; // From .meta description directive
|
||||||
|
|||||||
+44
@@ -31,6 +31,7 @@
|
|||||||
#include "Loggers.hh"
|
#include "Loggers.hh"
|
||||||
#include "NetworkAddresses.hh"
|
#include "NetworkAddresses.hh"
|
||||||
#include "PSOGCObjectGraph.hh"
|
#include "PSOGCObjectGraph.hh"
|
||||||
|
#include "PSOProtocol.hh"
|
||||||
#include "ProxyServer.hh"
|
#include "ProxyServer.hh"
|
||||||
#include "Quest.hh"
|
#include "Quest.hh"
|
||||||
#include "QuestScript.hh"
|
#include "QuestScript.hh"
|
||||||
@@ -1092,6 +1093,49 @@ Action a_assemble_quest_script(
|
|||||||
write_output_data(args, result.data(), result.size(), compress ? "bin" : "bind");
|
write_output_data(args, result.data(), result.size(), compress ? "bin" : "bind");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Action a_assemble_all_patches(
|
||||||
|
"assemble-all-patches", "\
|
||||||
|
assemble-all-patches\n\
|
||||||
|
Assemble all patches in the system/ppc directory, and produce two compiled\n\
|
||||||
|
.bin files for each patch (one unencrypted, for most PSO versions, and one\n\
|
||||||
|
encrypted, for PSO JP v1.04, JP Ep3, and Ep3 Trial Edition). The output\n\
|
||||||
|
files are written to the system/ppc directory.\n",
|
||||||
|
+[](Arguments&) {
|
||||||
|
ServerState s;
|
||||||
|
s.load_objects_and_upstream_dependents("functions");
|
||||||
|
|
||||||
|
auto process_code = +[](shared_ptr<const CompiledFunctionCode> code,
|
||||||
|
uint32_t checksum_addr,
|
||||||
|
uint32_t checksum_size,
|
||||||
|
uint32_t override_start_addr) -> void {
|
||||||
|
for (uint8_t encrypted = 0; encrypted < 2; encrypted++) {
|
||||||
|
StringWriter w;
|
||||||
|
string data = prepare_send_function_call_data(code, {}, "", checksum_addr, checksum_size, override_start_addr, encrypted);
|
||||||
|
w.put(PSOCommandHeaderDCV3{.command = 0xB2, .flag = code->index, .size = data.size() + 4});
|
||||||
|
w.write(data);
|
||||||
|
string out_path = code->source_path + (encrypted ? ".enc.bin" : ".std.bin");
|
||||||
|
save_file(out_path, w.str());
|
||||||
|
fprintf(stderr, "... %s\n", out_path.c_str());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& it : s.function_code_index->name_and_specific_version_to_patch_function) {
|
||||||
|
process_code(it.second, 0, 0, 0);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
process_code(s.function_code_index->name_to_function.at("VersionDetect"), 0, 0, 0);
|
||||||
|
} catch (const out_of_range&) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
process_code(s.function_code_index->name_to_function.at("CacheClearFix-Phase1"), 0x80000000, 8, 0x7F2734EC);
|
||||||
|
} catch (const out_of_range&) {
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
process_code(s.function_code_index->name_to_function.at("CacheClearFix-Phase2"), 0, 0, 0);
|
||||||
|
} catch (const out_of_range&) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
void a_extract_archive_fn(Arguments& args) {
|
void a_extract_archive_fn(Arguments& args) {
|
||||||
string output_prefix = args.get<string>(2, false);
|
string output_prefix = args.get<string>(2, false);
|
||||||
if (output_prefix == "-") {
|
if (output_prefix == "-") {
|
||||||
|
|||||||
+48
-38
@@ -402,48 +402,19 @@ void prepare_client_for_patches(shared_ptr<Client> c, function<void()> on_comple
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_function_call(
|
string prepare_send_function_call_data(
|
||||||
shared_ptr<Client> c,
|
shared_ptr<const CompiledFunctionCode> code,
|
||||||
shared_ptr<CompiledFunctionCode> code,
|
|
||||||
const unordered_map<string, uint32_t>& label_writes,
|
const unordered_map<string, uint32_t>& label_writes,
|
||||||
const string& suffix,
|
const string& suffix,
|
||||||
uint32_t checksum_addr,
|
uint32_t checksum_addr,
|
||||||
uint32_t checksum_size,
|
uint32_t checksum_size,
|
||||||
uint32_t override_relocations_offset) {
|
uint32_t override_relocations_offset,
|
||||||
return send_function_call(
|
bool use_encrypted_format) {
|
||||||
c->channel,
|
|
||||||
c->config,
|
|
||||||
code,
|
|
||||||
label_writes,
|
|
||||||
suffix,
|
|
||||||
checksum_addr,
|
|
||||||
checksum_size,
|
|
||||||
override_relocations_offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
void send_function_call(
|
|
||||||
Channel& ch,
|
|
||||||
const Client::Config& client_config,
|
|
||||||
shared_ptr<CompiledFunctionCode> code,
|
|
||||||
const unordered_map<string, uint32_t>& label_writes,
|
|
||||||
const string& suffix,
|
|
||||||
uint32_t checksum_addr,
|
|
||||||
uint32_t checksum_size,
|
|
||||||
uint32_t override_relocations_offset) {
|
|
||||||
if (client_config.check_flag(Client::Flag::NO_SEND_FUNCTION_CALL)) {
|
|
||||||
throw logic_error("client does not support function calls");
|
|
||||||
}
|
|
||||||
if (code.get() && client_config.check_flag(Client::Flag::SEND_FUNCTION_CALL_CHECKSUM_ONLY)) {
|
|
||||||
throw logic_error("client only supports checksums in send_function_call");
|
|
||||||
}
|
|
||||||
|
|
||||||
string data;
|
string data;
|
||||||
uint32_t index = 0;
|
|
||||||
if (code.get()) {
|
if (code.get()) {
|
||||||
data = code->generate_client_command(label_writes, suffix, override_relocations_offset);
|
data = code->generate_client_command(label_writes, suffix, override_relocations_offset);
|
||||||
index = code->index;
|
|
||||||
|
|
||||||
if (client_config.check_flag(Client::Flag::ENCRYPTED_SEND_FUNCTION_CALL)) {
|
if (use_encrypted_format) {
|
||||||
uint32_t key = random_object<uint32_t>();
|
uint32_t key = random_object<uint32_t>();
|
||||||
|
|
||||||
// This format was probably never used on any little-endian system, but we
|
// This format was probably never used on any little-endian system, but we
|
||||||
@@ -473,13 +444,52 @@ void send_function_call(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
S_ExecuteCode_B2 header = {data.size(), checksum_addr, checksum_size};
|
|
||||||
|
|
||||||
StringWriter w;
|
StringWriter w;
|
||||||
w.put(header);
|
w.put(S_ExecuteCode_B2{data.size(), checksum_addr, checksum_size});
|
||||||
w.write(data);
|
w.write(data);
|
||||||
|
return std::move(w.str());
|
||||||
|
}
|
||||||
|
|
||||||
ch.send(0xB2, index, w.str());
|
void send_function_call(
|
||||||
|
shared_ptr<Client> c,
|
||||||
|
shared_ptr<const CompiledFunctionCode> code,
|
||||||
|
const unordered_map<string, uint32_t>& label_writes,
|
||||||
|
const string& suffix,
|
||||||
|
uint32_t checksum_addr,
|
||||||
|
uint32_t checksum_size,
|
||||||
|
uint32_t override_relocations_offset) {
|
||||||
|
return send_function_call(
|
||||||
|
c->channel,
|
||||||
|
c->config,
|
||||||
|
code,
|
||||||
|
label_writes,
|
||||||
|
suffix,
|
||||||
|
checksum_addr,
|
||||||
|
checksum_size,
|
||||||
|
override_relocations_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void send_function_call(
|
||||||
|
Channel& ch,
|
||||||
|
const Client::Config& client_config,
|
||||||
|
shared_ptr<const CompiledFunctionCode> code,
|
||||||
|
const unordered_map<string, uint32_t>& label_writes,
|
||||||
|
const string& suffix,
|
||||||
|
uint32_t checksum_addr,
|
||||||
|
uint32_t checksum_size,
|
||||||
|
uint32_t override_relocations_offset) {
|
||||||
|
if (client_config.check_flag(Client::Flag::NO_SEND_FUNCTION_CALL)) {
|
||||||
|
throw logic_error("client does not support function calls");
|
||||||
|
}
|
||||||
|
if (code.get() && client_config.check_flag(Client::Flag::SEND_FUNCTION_CALL_CHECKSUM_ONLY)) {
|
||||||
|
throw logic_error("client only supports checksums in send_function_call");
|
||||||
|
}
|
||||||
|
|
||||||
|
string data = prepare_send_function_call_data(
|
||||||
|
code, label_writes, suffix, checksum_addr, checksum_size, override_relocations_offset,
|
||||||
|
client_config.check_flag(Client::Flag::ENCRYPTED_SEND_FUNCTION_CALL));
|
||||||
|
|
||||||
|
ch.send(0xB2, code ? code->index : 0x00, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void send_reconnect(shared_ptr<Client> c, uint32_t address, uint16_t port) {
|
void send_reconnect(shared_ptr<Client> c, uint32_t address, uint16_t port) {
|
||||||
|
|||||||
+10
-2
@@ -134,10 +134,18 @@ void empty_function_call_response_handler(uint32_t, uint32_t);
|
|||||||
|
|
||||||
void send_quest_buffer_overflow(std::shared_ptr<Client> c);
|
void send_quest_buffer_overflow(std::shared_ptr<Client> c);
|
||||||
void prepare_client_for_patches(std::shared_ptr<Client> c, std::function<void()> on_complete);
|
void prepare_client_for_patches(std::shared_ptr<Client> c, std::function<void()> on_complete);
|
||||||
|
std::string prepare_send_function_call_data(
|
||||||
|
std::shared_ptr<const CompiledFunctionCode> code,
|
||||||
|
const std::unordered_map<std::string, uint32_t>& label_writes,
|
||||||
|
const std::string& suffix,
|
||||||
|
uint32_t checksum_addr,
|
||||||
|
uint32_t checksum_size,
|
||||||
|
uint32_t override_relocations_offset,
|
||||||
|
bool use_encrypted_format);
|
||||||
void send_function_call(
|
void send_function_call(
|
||||||
Channel& ch,
|
Channel& ch,
|
||||||
const Client::Config& client_config,
|
const Client::Config& client_config,
|
||||||
std::shared_ptr<CompiledFunctionCode> code,
|
std::shared_ptr<const CompiledFunctionCode> code,
|
||||||
const std::unordered_map<std::string, uint32_t>& label_writes = {},
|
const std::unordered_map<std::string, uint32_t>& label_writes = {},
|
||||||
const std::string& suffix = "",
|
const std::string& suffix = "",
|
||||||
uint32_t checksum_addr = 0,
|
uint32_t checksum_addr = 0,
|
||||||
@@ -145,7 +153,7 @@ void send_function_call(
|
|||||||
uint32_t override_relocations_offset = 0);
|
uint32_t override_relocations_offset = 0);
|
||||||
void send_function_call(
|
void send_function_call(
|
||||||
std::shared_ptr<Client> c,
|
std::shared_ptr<Client> c,
|
||||||
std::shared_ptr<CompiledFunctionCode> code,
|
std::shared_ptr<const CompiledFunctionCode> code,
|
||||||
const std::unordered_map<std::string, uint32_t>& label_writes = {},
|
const std::unordered_map<std::string, uint32_t>& label_writes = {},
|
||||||
const std::string& suffix = "",
|
const std::string& suffix = "",
|
||||||
uint32_t checksum_addr = 0,
|
uint32_t checksum_addr = 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user