Begin integrating TX

This commit is contained in:
mkrsym1 2023-08-04 22:17:31 +03:00
parent 592ce62e6b
commit 7eac309372
15 changed files with 104 additions and 20 deletions

Binary file not shown.

View File

@ -0,0 +1 @@
#define JADEITE_VERSION "@version@"

View File

@ -8,11 +8,13 @@
/* CRC-32C (iSCSI) polynomial in reversed bit order. */ /* CRC-32C (iSCSI) polynomial in reversed bit order. */
#define __POLY 0x82f63b78 #define __POLY 0x82f63b78
static inline uint32_t crc32c(uint32_t crc, const unsigned char *buf, size_t len) { static inline uint32_t crc32c(uint32_t crc, const void *buf, size_t len) {
const unsigned char *cbuf = (const unsigned char*)buf;
crc = ~crc; crc = ~crc;
while (len--) { while (len--) {
crc ^= *buf++; crc ^= *cbuf++;
for (int k = 0; k < 8; k++) { for (int k = 0; k < 8; k++) {
crc = crc & 1 ? (crc >> 1) ^ __POLY : crc >> 1; crc = crc & 1 ? (crc >> 1) ^ __POLY : crc >> 1;
} }

View File

@ -24,6 +24,7 @@ struct game_data {
enum game_id id; // Temporary enum game_id id; // Temporary
const char *base_module_name; const char *base_module_name;
const char *assembly_name; const char *assembly_name;
const char *txs_section_name;
const char *tvm_section_name; const char *tvm_section_name;
unityplayer_callback_t unityplayer_callback; unityplayer_callback_t unityplayer_callback;

View File

@ -1,5 +1,7 @@
#pragma once #pragma once
#define ISSUE_SUFFIX "Please open an issue on the jadeite repository specifying your game edition/region and version"
void unload_ctr_inc(); void unload_ctr_inc();
void unload_ctr_dec(); void unload_ctr_dec();

View File

@ -2,6 +2,6 @@
#include <windows.h> #include <windows.h>
IMAGE_SECTION_HEADER *pe_find_section(HMODULE module, const char *section); IMAGE_SECTION_HEADER *pe_find_section(const void *module, const char *section);
void *pe_find_entry_point(HMODULE module); void *pe_find_entry_point(HMODULE module);

View File

@ -0,0 +1,3 @@
#include <game.h>
void tx_table_file(struct game_data *game, wchar_t *buf);

View File

@ -12,7 +12,8 @@ sources = [
'src/hi3.c', 'src/hi3.c',
'src/hsr.c', 'src/hsr.c',
'src/utils.c', 'src/utils.c',
'src/msg.c' 'src/msg.c',
'src/tx.c'
] ]
resources = [ resources = [
'res/hi3/glb.dat', 'res/hi3/glb.dat',
@ -70,12 +71,18 @@ else
core_blob = [ 'blob/core.o' ] core_blob = [ 'blob/core.o' ]
endif endif
conf_data = configuration_data()
conf_data.set('version', meson.project_version())
conf = configure_file(input: 'include/config.h.in', output: 'config.h', configuration: conf_data)
shared_library( shared_library(
'game_payload', 'game_payload',
sources, sources,
res_header, res_header,
res_object, res_object,
core_target, core_target,
conf,
objects: core_blob, objects: core_blob,
include_directories: include_dir, include_directories: include_dir,
name_prefix: '' name_prefix: ''

View File

@ -5,6 +5,7 @@
const char *HI3_BASE_MODULE_NAME = "BH3Base.dll"; const char *HI3_BASE_MODULE_NAME = "BH3Base.dll";
const char *HI3_ASSEMBLY_NAME = "UserAssembly.dll"; const char *HI3_ASSEMBLY_NAME = "UserAssembly.dll";
const char *HI3_TXS_SECTION_NAME = ".bh3";
const char *HI3_TVM_SECTION_NAME = ".tvm0"; const char *HI3_TVM_SECTION_NAME = ".tvm0";
struct crc_id_pair { struct crc_id_pair {
@ -40,6 +41,7 @@ void hi3_fill_data(struct game_data *buf) {
buf->id = id; buf->id = id;
buf->base_module_name = HI3_BASE_MODULE_NAME; buf->base_module_name = HI3_BASE_MODULE_NAME;
buf->assembly_name = HI3_ASSEMBLY_NAME; buf->assembly_name = HI3_ASSEMBLY_NAME;
buf->txs_section_name = HI3_TXS_SECTION_NAME;
buf->tvm_section_name = HI3_TVM_SECTION_NAME; buf->tvm_section_name = HI3_TVM_SECTION_NAME;
buf->unityplayer_callback = NULL; buf->unityplayer_callback = NULL;

View File

@ -6,6 +6,7 @@
const char *HSR_BASE_MODULE_NAME = "StarRailBase.dll"; const char *HSR_BASE_MODULE_NAME = "StarRailBase.dll";
const char *HSR_ASSEMBLY_NAME = "GameAssembly.dll"; const char *HSR_ASSEMBLY_NAME = "GameAssembly.dll";
const char *HSR_TXS_SECTION_NAME = ".ace";
const char *HSR_TVM_SECTION_NAME = ".tvm0"; const char *HSR_TVM_SECTION_NAME = ".tvm0";
struct crc_id_pair { struct crc_id_pair {
@ -86,6 +87,7 @@ void hsr_fill_data(struct game_data *buf) {
buf->id = id; buf->id = id;
buf->base_module_name = HSR_BASE_MODULE_NAME; buf->base_module_name = HSR_BASE_MODULE_NAME;
buf->assembly_name = HSR_ASSEMBLY_NAME; buf->assembly_name = HSR_ASSEMBLY_NAME;
buf->txs_section_name = HSR_TXS_SECTION_NAME;
buf->tvm_section_name = HSR_TVM_SECTION_NAME; buf->tvm_section_name = HSR_TVM_SECTION_NAME;
buf->unityplayer_callback = &_unityplayer_callback; buf->unityplayer_callback = &_unityplayer_callback;

View File

@ -6,6 +6,7 @@
#include <core.h> #include <core.h>
#include <utils.h> #include <utils.h>
#include <msg.h> #include <msg.h>
#include <tx.h>
#include <main.h> #include <main.h>
@ -37,6 +38,29 @@ void request_restart() {
CloseHandle(hRestartFlag); CloseHandle(hRestartFlag);
} }
static void _run_game(struct game_data *game) {
// Create fake ACE driver files
ace_fake_driver_files();
// Load both ACE modules
HMODULE baseModule = ace_load_base_module(game);
ace_load_driver_module();
// ...magic
core_setup_patcher(game, baseModule);
// Load the UnityPlayer module and invoke the callback
HMODULE unityModule = LoadLibraryA("UnityPlayer.dll");
INVOKE_CALLBACK(game->unityplayer_callback, unityModule);
}
static void _run_tx(struct game_data *game, wchar_t *tableFile) {
request_restart();
exit(0);
}
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) {
// Only listen to attach // Only listen to attach
if (reason != DLL_PROCESS_ATTACH) { if (reason != DLL_PROCESS_ATTACH) {
@ -52,19 +76,18 @@ BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) {
struct game_data game; struct game_data game;
game_detect(&game); game_detect(&game);
// Create fake ACE driver files // Get required table file path
ace_fake_driver_files(); wchar_t tableFile[MAX_PATH];
tx_table_file(&game, tableFile);
// Load both ACE modules // Remove this
HMODULE baseModule = ace_load_base_module(&game); msg_err_w(tableFile);
ace_load_driver_module();
// ...magic if (1) {
core_setup_patcher(&game, baseModule); _run_game(&game);
} else {
// Load the UnityPlayer module and invoke the callback _run_tx(&game, tableFile);
HMODULE unityModule = LoadLibraryA("UnityPlayer.dll"); }
INVOKE_CALLBACK(game.unityplayer_callback, unityModule);
return TRUE; return TRUE;
} }

View File

@ -1,5 +1,6 @@
#include <windows.h> #include <windows.h>
#include <stdio.h> #include <stdio.h>
#include <config.h>
#include <msg.h> #include <msg.h>
@ -21,8 +22,8 @@
suffix; \ suffix; \
} }
const char *TITLE_A = "Jadeite Autopatcher"; const char *TITLE_A = "v" JADEITE_VERSION "Jadeite Autopatcher";
const wchar_t *TITLE_W = L"Jadeite Autopatcher"; const wchar_t *TITLE_W = L"v" JADEITE_VERSION "Jadeite Autopatcher";
// Error // Error
DEF_MSG_FN(msg_err_a, char, _vsnprintf, MessageBoxA, TITLE_A, MB_OK | MB_ICONERROR, exit(1)) DEF_MSG_FN(msg_err_a, char, _vsnprintf, MessageBoxA, TITLE_A, MB_OK | MB_ICONERROR, exit(1))

View File

@ -1,7 +1,7 @@
#include <pe.h> #include <pe.h>
IMAGE_SECTION_HEADER *pe_find_section(HMODULE module, const char *section) { IMAGE_SECTION_HEADER *pe_find_section(const void *module, const char *section) {
char *cModule = (char*)module; const char *cModule = (const char*)module;
IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)module; IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)module;
IMAGE_NT_HEADERS64* ntHeaders = (IMAGE_NT_HEADERS64*)(cModule + dosHeader->e_lfanew); IMAGE_NT_HEADERS64* ntHeaders = (IMAGE_NT_HEADERS64*)(cModule + dosHeader->e_lfanew);

40
game_payload/src/tx.c Normal file
View File

@ -0,0 +1,40 @@
#include <windows.h>
#include <stdio.h>
#include <crc32.h>
#include <msg.h>
#include <pe.h>
#include <main.h>
#include <config.h>
#include <tx.h>
void tx_table_file(struct game_data *game, wchar_t *buf) {
// Get temp directory path
wchar_t tempDir[MAX_PATH];
GetTempPathW(MAX_PATH, tempDir);
// Memorymap the base module
HANDLE baseFile = CreateFileA(game->base_module_name, FILE_READ_ACCESS, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (!baseFile) {
msg_err_a("Could not open file: %s", game->base_module_name);
}
HANDLE hBaseMap = CreateFileMappingA(baseFile, NULL, PAGE_READONLY, 0, 0, NULL);
char *baseMap = MapViewOfFile(hBaseMap, FILE_MAP_READ, 0, 0, 0);
if (!baseMap) {
msg_err_a("Could not create file mapping for %s", game->base_module_name);
}
// Checksum the TXS section
IMAGE_SECTION_HEADER *txsSection = pe_find_section(baseMap, game->txs_section_name);
uint32_t txsChecksum = crc32c(0, baseMap + txsSection->PointerToRawData, txsSection->SizeOfRawData);
// Format the path
wsprintfW(buf, L"%sjadeite\\" JADEITE_VERSION "\\%hs.%x.dat", tempDir, game->base_module_name, txsChecksum);
// Cleanup
UnmapViewOfFile(baseMap);
CloseHandle(hBaseMap);
CloseHandle(baseFile);
}

View File

@ -24,7 +24,7 @@ uint32_t utils_file_crc32c(const wchar_t *filePath) {
msg_err_w(L"Could not create file mapping for %ls", filePath); msg_err_w(L"Could not create file mapping for %ls", filePath);
} }
uint32_t crc = crc32c(0, (unsigned char*)map, fileSize.QuadPart); uint32_t crc = crc32c(0, map, fileSize.QuadPart);
UnmapViewOfFile(map); UnmapViewOfFile(map);
CloseHandle(hMap); CloseHandle(hMap);