writecodeblocks noop clean
Feature/pc writecodeblocks noop clean
This commit is contained in:
@@ -251,6 +251,9 @@ ClientFunctionIndex::ClientFunctionIndex(const std::string& root_dir, bool raise
|
||||
add_directory(item_path);
|
||||
} else if (item_path.ends_with(".s") && std::filesystem::is_regular_file(item_path)) {
|
||||
client_functions_log.debug_f("Adding {} from {}", item_name, item_path);
|
||||
if (item_name.find("Dragon") != std::string::npos) {
|
||||
client_functions_log.warning_f("Dragon source load debug: adding {} from {}", item_name, item_path);
|
||||
}
|
||||
if (!source_files.emplace(item_name, phosg::load_file(item_path)).second) {
|
||||
throw std::runtime_error(std::format("Duplicate source filename: {}", item_name));
|
||||
}
|
||||
@@ -285,6 +288,20 @@ ClientFunctionIndex::ClientFunctionIndex(const std::string& root_dir, bool raise
|
||||
throw std::runtime_error(std::format("({} preprocessing) {}", source_filename, e.what()));
|
||||
}
|
||||
|
||||
if (source_filename.find("Dragon") != std::string::npos) {
|
||||
client_functions_log.warning_f(
|
||||
"Dragon preprocess debug: source={} produced {} version chunk(s)",
|
||||
source_filename,
|
||||
preprocessed.size());
|
||||
for (const auto& [debug_sv, debug_source] : preprocessed) {
|
||||
client_functions_log.warning_f(
|
||||
"Dragon preprocess debug: source={} sv={} chunk_size={}",
|
||||
source_filename,
|
||||
str_for_specific_version(debug_sv),
|
||||
debug_source.size());
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& [specific_version, source] : preprocessed) {
|
||||
std::shared_ptr<Function> fn = std::make_shared<Function>();
|
||||
fn->short_name = source_filename.substr(0, source_filename.size() - 2);
|
||||
@@ -444,6 +461,37 @@ ClientFunctionIndex::ClientFunctionIndex(const std::string& root_dir, bool raise
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const char* probe_name : {"DragonVisualFix", "PsoPeepsDragonVisualFixPC", "RaresInQuests"}) {
|
||||
for (uint32_t probe_sv : {0x324F4A57u, SPECIFIC_VERSION_X86_INDETERMINATE}) {
|
||||
std::string key = cache_key(probe_name, probe_sv);
|
||||
auto all_it = this->all_functions.find(key);
|
||||
auto map_it = this->functions_by_specific_version.find(probe_sv);
|
||||
bool in_version_map = false;
|
||||
if (map_it != this->functions_by_specific_version.end()) {
|
||||
in_version_map = map_it->second.count(key);
|
||||
}
|
||||
client_functions_log.warning_f(
|
||||
"Client function probe: name={} sv={} key={} all_functions={} version_map={} map_size={}",
|
||||
probe_name,
|
||||
str_for_specific_version(probe_sv),
|
||||
key,
|
||||
all_it != this->all_functions.end(),
|
||||
in_version_map,
|
||||
map_it == this->functions_by_specific_version.end() ? 0 : map_it->second.size());
|
||||
if (all_it != this->all_functions.end()) {
|
||||
const auto& fn = all_it->second;
|
||||
client_functions_log.warning_f(
|
||||
"Client function probe detail: short={} long={} visibility={} specific_version={} arch={} menu_item_id={:08X}",
|
||||
fn->short_name,
|
||||
fn->long_name,
|
||||
phosg::name_for_enum(fn->visibility),
|
||||
str_for_specific_version(fn->specific_version),
|
||||
name_for_architecture(fn->arch),
|
||||
static_cast<uint32_t>(fn->menu_item_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<const Menu> ClientFunctionIndex::patch_switches_menu(
|
||||
@@ -455,15 +503,44 @@ std::shared_ptr<const Menu> ClientFunctionIndex::patch_switches_menu(
|
||||
|
||||
auto map_it = this->functions_by_specific_version.find(specific_version);
|
||||
if (map_it != this->functions_by_specific_version.end()) {
|
||||
client_functions_log.warning_f(
|
||||
"Patch menu debug: building menu for specific_version={} with {} function entries",
|
||||
str_for_specific_version(specific_version),
|
||||
map_it->second.size());
|
||||
|
||||
for (auto [name, fn] : map_it->second) {
|
||||
if (fn->appears_in_patches_menu() && !server_auto_patches_enabled.count(fn->short_name)) {
|
||||
bool appears = fn->appears_in_patches_menu();
|
||||
bool server_auto = server_auto_patches_enabled.count(fn->short_name);
|
||||
bool client_enabled = client_auto_patches_enabled.count(fn->short_name);
|
||||
bool dragon_debug =
|
||||
(fn->short_name.find("Dragon") != std::string::npos) ||
|
||||
(fn->long_name.find("Dragon") != std::string::npos);
|
||||
|
||||
if (dragon_debug || appears) {
|
||||
client_functions_log.warning_f(
|
||||
"Patch menu debug: key={} short={} long={} visibility={} appears={} server_auto={} client_enabled={} menu_item_id={:08X}",
|
||||
name,
|
||||
fn->short_name,
|
||||
fn->long_name,
|
||||
phosg::name_for_enum(fn->visibility),
|
||||
appears,
|
||||
server_auto,
|
||||
client_enabled,
|
||||
static_cast<uint32_t>(fn->menu_item_id));
|
||||
}
|
||||
|
||||
if (appears && !server_auto) {
|
||||
std::string item_text;
|
||||
item_text.push_back(client_auto_patches_enabled.count(fn->short_name) ? '*' : '-');
|
||||
item_text.push_back(client_enabled ? '*' : '-');
|
||||
item_text += fn->long_name.empty() ? fn->short_name : fn->long_name;
|
||||
ret->items.emplace_back(
|
||||
fn->menu_item_id, item_text, fn->description, MenuItem::Flag::REQUIRES_SEND_FUNCTION_CALL_RUNS_CODE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
client_functions_log.warning_f(
|
||||
"Patch menu debug: no functions for specific_version={}",
|
||||
str_for_specific_version(specific_version));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
.meta visibility="all"
|
||||
.meta name="Dragon fix"
|
||||
.meta description="Skips the bad Dragon\nBML selector path."
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
.include WriteCodeBlocks
|
||||
|
||||
|
||||
|
||||
.versions 2OJW
|
||||
|
||||
.data 0x00420326
|
||||
.data 2
|
||||
.data 0x14EB
|
||||
|
||||
|
||||
|
||||
.all_versions
|
||||
|
||||
.data 0x00000000
|
||||
.data 0x00000000
|
||||
@@ -118,7 +118,109 @@ first_patch_header:
|
||||
|
||||
|
||||
|
||||
.versions 2OJW 2OJZ 50YJ 59NJ 59NL
|
||||
.versions 2OJW
|
||||
|
||||
start:
|
||||
push ebx
|
||||
push esi
|
||||
push edi
|
||||
sub esp, 8 # [esp] = oldProtect, [esp + 4] = tempProtect
|
||||
jmp get_patch_data_ptr
|
||||
get_patch_data_ptr_ret:
|
||||
pop ebx # ebx = patch header
|
||||
|
||||
# Resolve kernel32!VirtualProtect using pso.exe's 2OJW IAT:
|
||||
# GetModuleHandleA = 0x0064D114
|
||||
# GetProcAddress = 0x0064D128
|
||||
#
|
||||
# Build "KERNEL32.dll\0" on stack.
|
||||
sub esp, 16
|
||||
mov dword [esp], 0x4E52454B # "KERN"
|
||||
mov dword [esp + 4], 0x32334C45 # "EL32"
|
||||
mov dword [esp + 8], 0x6C6C642E # ".dll"
|
||||
mov dword [esp + 12], 0
|
||||
push esp
|
||||
call [0x0064D114] # GetModuleHandleA
|
||||
add esp, 16
|
||||
test eax, eax
|
||||
jz fail
|
||||
|
||||
mov esi, eax # esi = kernel32 module handle
|
||||
|
||||
# Build "VirtualProtect\0" on stack.
|
||||
sub esp, 16
|
||||
mov dword [esp], 0x74726956 # "Virt"
|
||||
mov dword [esp + 4], 0x506C6175 # "ualP"
|
||||
mov dword [esp + 8], 0x65746F72 # "rote"
|
||||
mov dword [esp + 12], 0x00007463 # "ct\0\0"
|
||||
push esp
|
||||
push esi
|
||||
call [0x0064D128] # GetProcAddress
|
||||
add esp, 16
|
||||
test eax, eax
|
||||
jz fail
|
||||
|
||||
mov edi, eax # edi = VirtualProtect
|
||||
|
||||
apply_next_patch:
|
||||
cmp dword [ebx + 4], 0
|
||||
jne copy_code_and_apply_again
|
||||
|
||||
add esp, 8
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
mov eax, 1
|
||||
ret
|
||||
|
||||
copy_code_and_apply_again:
|
||||
# VirtualProtect(dest, size, PAGE_EXECUTE_READWRITE, &oldProtect)
|
||||
lea eax, [esp]
|
||||
push eax
|
||||
push 0x40
|
||||
push dword [ebx + 4]
|
||||
push dword [ebx]
|
||||
call edi
|
||||
test eax, eax
|
||||
jz fail
|
||||
|
||||
xor ecx, ecx # ecx = offset
|
||||
mov edx, [ebx] # edx = dest addr
|
||||
copy_next_byte:
|
||||
mov al, [ebx + ecx + 8] # copy one byte to dest
|
||||
mov [edx + ecx], al
|
||||
inc ecx # offset++
|
||||
cmp [ebx + 4], ecx # check if all bytes have been copied
|
||||
jne copy_next_byte
|
||||
|
||||
# VirtualProtect(dest, size, oldProtect, &tempProtect)
|
||||
mov esi, [ebx + 4] # esi = size; VirtualProtect preserves esi
|
||||
mov edx, [esp] # edx = oldProtect
|
||||
lea eax, [esp + 4]
|
||||
push eax
|
||||
push edx
|
||||
push esi
|
||||
push dword [ebx]
|
||||
call edi
|
||||
|
||||
lea ebx, [ebx + esi + 8] # advance to next block
|
||||
jmp apply_next_patch
|
||||
|
||||
fail:
|
||||
add esp, 8
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebx
|
||||
xor eax, eax
|
||||
ret
|
||||
|
||||
get_patch_data_ptr:
|
||||
call get_patch_data_ptr_ret
|
||||
first_patch_header:
|
||||
|
||||
|
||||
|
||||
.versions 2OJZ 50YJ 59NJ 59NL
|
||||
|
||||
start:
|
||||
push ebx
|
||||
|
||||
Reference in New Issue
Block a user