Begin integrating TX
This commit is contained in:
parent
592ce62e6b
commit
7eac309372
Binary file not shown.
1
game_payload/include/config.h.in
Normal file
1
game_payload/include/config.h.in
Normal file
@ -0,0 +1 @@
|
|||||||
|
#define JADEITE_VERSION "@version@"
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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();
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
3
game_payload/include/tx.h
Normal file
3
game_payload/include/tx.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#include <game.h>
|
||||||
|
|
||||||
|
void tx_table_file(struct game_data *game, wchar_t *buf);
|
@ -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: ''
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
|
@ -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
40
game_payload/src/tx.c
Normal 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);
|
||||||
|
}
|
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user