Skip to content

Commit

Permalink
Minor optimizations and fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
zero318 committed Jun 14, 2024
1 parent 373eeff commit 274900f
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 60 deletions.
4 changes: 2 additions & 2 deletions thcrap/src/ntdll.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ extern "C++" {
#define read_teb_member(member) read_teb_value<decltype(TEB::member),offsetof(TEB,member)>()
#define write_teb_member(member, data) write_teb_value<decltype(TEB::member),offsetof(TEB,member)>(data)

template<typename T, size_t offset>
static inline auto read_teb_value() {
template<typename T, size_t offset, typename R = std::conditional_t<sizeof(T) == sizeof(uint8_t) || sizeof(T) == sizeof(uint16_t) || sizeof(T) == sizeof(uint32_t) || sizeof(T) == sizeof(uint64_t), T, T&>>
static inline R read_teb_value() {
if constexpr (sizeof(T) == sizeof(uint8_t)) {
uint8_t temp = read_teb_byte(offset);
return *(T*)&temp;
Expand Down
47 changes: 31 additions & 16 deletions thcrap/src/patchfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ struct patchhook_t
const char *wildcard;
func_patch_t patch_func;
func_patch_size_t patch_size_func;

constexpr patchhook_t(const char* wildcard, func_patch_t patch_func, func_patch_size_t patch_size_func)
: wildcard(wildcard),
patch_func(patch_func),
patch_size_func(patch_size_func) {}
};

std::vector<patchhook_t> patchhooks;
Expand All @@ -28,6 +33,16 @@ HANDLE file_stream(const char *fn)
);
}

size_t file_stream_size(HANDLE stream) {
#ifndef TH_X64
return GetFileSize(stream, NULL);
#else
DWORD ret_high;
size_t ret = GetFileSize(stream, &ret_high);
return ret | (size_t)ret_high << 32;
#endif
}

void* file_stream_read(HANDLE stream, size_t *file_size_out)
{
#ifndef TH_X64
Expand Down Expand Up @@ -581,7 +596,7 @@ void patchhook_register(const char *wildcard, func_patch_t patch_func, func_patc
// pointers here! Some game support code might only want to hook
// [patch_size_func] to e.g. conveniently run some generic, non-
// file-related code as early as possible.
patchhooks.emplace_back(patchhook_t{ wildcard_normalized, patch_func, patch_size_func });
patchhooks.emplace_back(wildcard_normalized, patch_func, patch_size_func);
}

patchhook_t *patchhooks_build(const char *fn)
Expand All @@ -596,8 +611,8 @@ patchhook_t *patchhooks_build(const char *fn)
patchhook_t *last = std::copy_if(patchhooks.begin(), patchhooks.end(), hooks, [fn_normalized](const patchhook_t& hook) {
return PathMatchSpecU(fn_normalized, hook.wildcard);
});
last->wildcard = nullptr;
VLA_FREE(fn_normalized);
last->wildcard = nullptr;

if (hooks[0].wildcard == nullptr) {
free(hooks);
Expand All @@ -620,8 +635,8 @@ json_t *patchhooks_load_diff(const patchhook_t *hook_array, const char *fn, size
if (size) {
*size = 0;
for (size_t i = 0; hook_array[i].wildcard; i++) {
if (hook_array[i].patch_size_func) {
*size += hook_array[i].patch_size_func(fn, patch, diff_size);
if (auto func = hook_array[i].patch_size_func) {
*size += func(fn, patch, diff_size);
}
else {
*size += diff_size;
Expand All @@ -634,23 +649,23 @@ json_t *patchhooks_load_diff(const patchhook_t *hook_array, const char *fn, size

int patchhooks_run(const patchhook_t *hook_array, void *file_inout, size_t size_out, size_t size_in, const char *fn, json_t *patch)
{
int ret;

// We don't check [patch] here - hooks should be run even if there is no
// dedicated patch file.
if(!file_inout) {
if unexpected(!file_inout) {
return -1;
}
ret = 0;
for (size_t i = 0; hook_array && hook_array[i].wildcard; i++) {
func_patch_t func = hook_array[i].patch_func;
if(func) {
if (func(file_inout, size_out, size_in, fn, patch) > 0) {
const char *patched_files_dump = runconfig_patched_files_dump_get();
if (patched_files_dump) {
DumpDatFile(patched_files_dump, fn, file_inout, size_out);
int ret = 0;
if (hook_array) {
for (size_t i = 0; hook_array[i].wildcard; i++) {
func_patch_t func = hook_array[i].patch_func;
if (func) {
if (func(file_inout, size_out, size_in, fn, patch) > 0) {
const char *patched_files_dump = runconfig_patched_files_dump_get();
if unexpected(patched_files_dump) {
DumpDatFile(patched_files_dump, fn, file_inout, size_out);
}
ret = 1;
}
ret = 1;
}
}
}
Expand Down
17 changes: 10 additions & 7 deletions thcrap/src/patchfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,29 +100,32 @@ typedef struct
} patch_t;

// Parses and error checks patch options from game_id.js
void patch_opts_from_json(json_t *opts);
THCRAP_API void patch_opts_from_json(json_t *opts);


patch_value_type_t TH_FASTCALL patch_parse_type(const char* type);
THCRAP_API patch_value_type_t TH_FASTCALL patch_parse_type(const char* type);

bool TH_FASTCALL patch_opt_from_raw(patch_value_type_t type, const char* name, void* value);
THCRAP_API bool TH_FASTCALL patch_opt_from_raw(patch_value_type_t type, const char* name, void* value);

void patch_opts_clear_all();

// Obtains the value of a patch option
patch_val_t* patch_opt_get(const char *name);
THCRAP_API patch_val_t* patch_opt_get(const char *name);

patch_val_t* patch_opt_get_len(const char* name, size_t length);
THCRAP_API patch_val_t* patch_opt_get_len(const char* name, size_t length);

// Opens the file [fn] for read operations. Just a lightweight wrapper around
// CreateFile(): Returns INVALID_HANDLE_VALUE on failure, and the caller must
// call CloseHandle() on the returned value.
THCRAP_API HANDLE file_stream(const char *fn);
TH_CALLER_CLOSE_HANDLE THCRAP_API HANDLE file_stream(const char *fn);

THCRAP_API size_t file_stream_size(HANDLE stream);

// Reads the given file [stream] into a newly created buffer and optionally
// returns its [file_size]. If given, [file_size] is guaranteed to be set
// to 0 on failure. The returned buffer has to be free()d by the caller!
void* file_stream_read(HANDLE stream, size_t *file_size);
// Closes [stream] after reading.
TH_CALLER_FREE THCRAP_API void* file_stream_read(HANDLE stream, size_t *file_size);

// Combines file_stream() and file_stream_read().
TH_DEPRECATED_EXPORT void* (file_read)(const char *fn, size_t *file_size);
Expand Down
22 changes: 12 additions & 10 deletions thcrap/src/stack.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -149,12 +149,13 @@ json_t* stack_json_resolve_chain(char **chain, size_t *file_size)
json_t* stack_json_resolve(const char *fn, size_t *file_size)
{
json_t *ret = NULL;
char **chain = resolve_chain(fn);
if(chain && chain[0]) {
log_printf("(JSON) Resolving %s... ", fn);
ret = stack_json_resolve_chain(chain, file_size);
if (char** chain = resolve_chain(fn)) {
if (chain[0]) {
log_printf("(JSON) Resolving %s... ", fn);
ret = stack_json_resolve_chain(chain, file_size);
}
chain_free(chain);
}
chain_free(chain);
return ret;
}

Expand Down Expand Up @@ -200,12 +201,13 @@ char* stack_fn_resolve_chain(char **chain)
HANDLE stack_game_file_stream(const char *fn)
{
HANDLE ret = INVALID_HANDLE_VALUE;
char **chain = resolve_chain_game(fn);
if (chain && chain[0]) {
log_printf("(Data) Resolving %s... ", chain[0]);
ret = stack_file_resolve_chain(chain);
if (char** chain = resolve_chain_game(fn)) {
if (chain[0]) {
log_printf("(Data) Resolving %s... ", chain[0]);
ret = stack_file_resolve_chain(chain);
}
chain_free(chain);
}
chain_free(chain);
return ret;
}

Expand Down
1 change: 1 addition & 0 deletions thcrap/src/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define TH_CALLER_FREE TH_CALLER_CLEANUP(free)
#define TH_CALLER_DELETE TH_CALLER_CLEANUP(delete)
#define TH_CALLER_DELETEA TH_CALLER_CLEANUP(delete[])
#define TH_CALLER_CLOSE_HANDLE TH_CALLER_CLEANUP(CloseHandle)
#define TH_CHECK_RET TH_NODISCARD_REASON("Return value must be checked to determine validity of other outputs!")

#define TH_DEPRECATED_EXPORT TH_DEPRECATED_REASON("Exported function is only kept for backwards compatibility") THCRAP_API
Expand Down
1 change: 1 addition & 0 deletions thcrap/thcrap_x64.def
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ EXPORTS
; Patch files
; -----------
file_stream
file_stream_size
file_stream_read
file_read
file_write
Expand Down
1 change: 1 addition & 0 deletions thcrap/thcrap_x86.def
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ EXPORTS
; Patch files
; -----------
file_stream
file_stream_size
file_stream_read
file_read
file_write
Expand Down
2 changes: 1 addition & 1 deletion thcrap_tasofro/src/files_list.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
struct Th135File : public TasofroFile
{
// XOR key
DWORD key[4];
DWORD key[4] = {};
};

extern "C" {
Expand Down
1 change: 0 additions & 1 deletion thcrap_tasofro/src/nsml.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,6 @@ extern "C" int BP_th105_replaceReadFile(x86_reg_t *regs, json_t *bp_info)
}
TasofroFile& fr = it->second;

ReadFileStack *stack = (ReadFileStack*)(regs->esp + sizeof(void*));
int ret = fr.replace_ReadFile(regs, game_xor, game_xor);

LeaveCriticalSection(&cs);
Expand Down
52 changes: 30 additions & 22 deletions thcrap_tasofro/src/th155_bmp_font.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,10 @@ size_t get_bmp_font_size(const char *fn, json_t *patch, size_t)

memcpy(fn_buf + fn_len, ".bin", sizeof(".bin"));

size_t bin_size;
void *bin_data = stack_game_file_resolve(fn_buf, &bin_size);
if (bin_data) {
free(bin_data);
size += bin_size;
HANDLE stream = stack_game_file_stream(fn_buf);
if (stream != INVALID_HANDLE_VALUE) {
size += file_stream_size(stream);
CloseHandle(stream);
}

VLA_FREE(fn_buf);
Expand All @@ -68,15 +67,16 @@ void add_json_file(char *chars_list, int& chars_list_count, json_t *file)
}
else if (json_is_string(file)) {
const char *str = json_string_value(file);
WCHAR_T_DEC(str);
WCHAR_T_CONV(str);
for (int i = 0; str_w[i]; i++) {
if (!chars_list[str_w[i]]) {
chars_list[str_w[i]] = 1;
chars_list_count++;
}
size_t str_len = json_string_length(file) + 1;
VLA(wchar_t, str_w, str_len);
int wchar_count = StringToUTF16(str_w, str, str_len) - 1;
wchar_t* str_w_read = str_w;
while (wchar_count-- > 0) {
wchar_t c = *str_w_read++;
chars_list_count += !chars_list[c];
chars_list[c] = true;
}
WCHAR_T_FREE(str);
VLA_FREE(str_w);
}
json_decref(file);
}
Expand Down Expand Up @@ -104,20 +104,28 @@ static void add_files_in_directory(char *chars_list, int& chars_list_count, std:

do
{
if (strcmp(ffd.cFileName, ".") == 0 || strcmp(ffd.cFileName, "..") == 0) {
if (ffd.cFileName[0] == '.' && (
ffd.cFileName[1] == '\0' ||
(ffd.cFileName[1] == '.' && ffd.cFileName[2] == '\0')
)
) {
// Do nothing
}
else if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
if (recurse) {
std::string dirname = basedir + "\\" + ffd.cFileName;
std::string dirname = basedir + '\\' + ffd.cFileName;
add_files_in_directory(chars_list, chars_list_count, dirname, recurse);
}
}
else if (strcmp(PathFindExtensionA(ffd.cFileName), ".js") == 0 ||
strcmp(PathFindExtensionA(ffd.cFileName), ".jdiff") == 0) {
std::string filename = basedir + "\\" + ffd.cFileName;
log_printf(" + %s\n", filename.c_str());
add_json_file(chars_list, chars_list_count, filename);
else {
char* extension = PathFindExtensionA(ffd.cFileName);
if (strcmp(extension, ".js") == 0 ||
strcmp(extension, ".jdiff") == 0
) {
std::string filename = basedir + '\\' + ffd.cFileName;
log_printf(" + %s\n", filename.c_str());
add_json_file(chars_list, chars_list_count, filename);
}
}
} while (FindNextFile(hFind, &ffd));

Expand Down Expand Up @@ -185,14 +193,14 @@ int fill_chars_list_from_files(char *chars_list, json_t *files)
if (!fn) {
// Do nothing
}
else if (strcmp(fn, "*") == 0) {
else if (fn[0] == '*' && fn[1] == '\0') {
log_print("(Font) Searching in every js file for characters...\n");
stack_foreach_cpp([&](const patch_t *patch) {
if (patch->archive) {
add_files_in_directory(chars_list, chars_list_count, patch->archive, false);
const char *game = runconfig_game_get();
if (game) {
add_files_in_directory(chars_list, chars_list_count, std::string(patch->archive) + "\\" + game, true);
add_files_in_directory(chars_list, chars_list_count, std::string(patch->archive) + '\\' + game, true);
}
}
});
Expand Down
2 changes: 1 addition & 1 deletion thcrap_tasofro/src/th175_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ int patch_th175_json(void *file_inout, size_t size_out, size_t size_in, const ch

size_t new_size = json_dumpb(json, (char*)file_inout, size_out, JSON_COMPACT);
if (new_size > size_out) {
log_printf("[th175_json] Error: %s: buffer too small (need %u, have %u)", fn, new_size, size_out);
log_printf("[th175_json] Error: %s: buffer too small (need %zu, have %zu)", fn, new_size, size_out);
memcpy(file_inout, "{}", 3);
return 0;
}
Expand Down

0 comments on commit 274900f

Please # to comment.