mirror of
https://git.chinosk6.cn/chinosk/gkms-localify-dmm.git
synced 2026-03-22 08:10:09 +07:00
初始适配
This commit is contained in:
151
src/main.cpp
Normal file
151
src/main.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
#include <stdinclude.hpp>
|
||||
|
||||
#include <minizip/unzip.h>
|
||||
#include <TlHelp32.h>
|
||||
|
||||
#include <unordered_set>
|
||||
#include <charconv>
|
||||
#include <cassert>
|
||||
#include <format>
|
||||
#include <cpprest/uri.h>
|
||||
#include <cpprest/http_listener.h>
|
||||
#include <ranges>
|
||||
#include <windows.h>
|
||||
#include "windowsPlatform.hpp"
|
||||
|
||||
extern void start_console();
|
||||
|
||||
const auto CONSOLE_TITLE = L"Gakumas Localify";
|
||||
|
||||
std::filesystem::path gakumasLocalPath = "./gakumas-local";
|
||||
std::filesystem::path ProgramConfigJson = gakumasLocalPath / "config.json";
|
||||
std::filesystem::path ConfigJson = gakumasLocalPath / "localizationConfig.json";
|
||||
|
||||
bool g_has_config_file = false;
|
||||
bool g_enable_console = true;
|
||||
bool g_confirm_every_times = false;
|
||||
std::vector<std::string> g_pluginPath{};
|
||||
|
||||
namespace
|
||||
{
|
||||
void create_debug_console()
|
||||
{
|
||||
AllocConsole();
|
||||
|
||||
// open stdout stream
|
||||
auto _ = freopen("CONOUT$", "w+t", stdout);
|
||||
_ = freopen("CONOUT$", "w", stderr);
|
||||
_ = freopen("CONIN$", "r", stdin);
|
||||
|
||||
SetConsoleTitleW(CONSOLE_TITLE);
|
||||
|
||||
// set this to avoid turn japanese texts into question mark
|
||||
SetConsoleOutputCP(65001);
|
||||
std::locale::global(std::locale(""));
|
||||
|
||||
wprintf(L"%ls Loaded! - By chinosk\n", CONSOLE_TITLE);
|
||||
}
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
void readProgramConfig()
|
||||
{
|
||||
std::vector<std::string> dicts{};
|
||||
std::ifstream config_stream{ ProgramConfigJson };
|
||||
|
||||
if (!config_stream.is_open())
|
||||
return;
|
||||
|
||||
rapidjson::IStreamWrapper wrapper{ config_stream };
|
||||
rapidjson::Document document;
|
||||
|
||||
document.ParseStream(wrapper);
|
||||
|
||||
if (!document.HasParseError())
|
||||
{
|
||||
g_has_config_file = true;
|
||||
if (document.HasMember("enableConsole")) {
|
||||
g_enable_console = document["enableConsole"].GetBool();
|
||||
}
|
||||
}
|
||||
config_stream.close();
|
||||
}
|
||||
}
|
||||
|
||||
LONG WINAPI AddressExceptionHandler(EXCEPTION_POINTERS* ExceptionInfo) {
|
||||
// Check if the exception is an access violation
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION) {
|
||||
// Check if the violation address is above 0x7FFFFFFFFFFF
|
||||
if (ExceptionInfo->ExceptionRecord->ExceptionAddress > (PVOID)0x7FFFFFFFFFFF) {
|
||||
// Return EXCEPTION_CONTINUE_EXECUTION to ignore the exception and continue
|
||||
return EXCEPTION_CONTINUE_EXECUTION;
|
||||
}
|
||||
}
|
||||
// For other exceptions or addresses, use the default exception handler
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
|
||||
int __stdcall DllMain(HINSTANCE dllModule, DWORD reason, LPVOID)
|
||||
{
|
||||
if (reason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
AddVectoredExceptionHandler(1, AddressExceptionHandler);
|
||||
// the DMM Launcher set start path to system32 wtf????
|
||||
std::string module_name;
|
||||
module_name.resize(MAX_PATH);
|
||||
module_name.resize(GetModuleFileName(nullptr, module_name.data(), MAX_PATH));
|
||||
|
||||
std::filesystem::path module_path(module_name);
|
||||
|
||||
// check name
|
||||
if (module_path.filename() != "gakumas.exe")
|
||||
return 1;
|
||||
|
||||
std::filesystem::current_path(
|
||||
module_path.parent_path()
|
||||
);
|
||||
|
||||
readProgramConfig();
|
||||
|
||||
if (g_enable_console)
|
||||
create_debug_console();
|
||||
|
||||
std::thread init_thread([] {
|
||||
|
||||
if (g_enable_console)
|
||||
{
|
||||
start_console();
|
||||
printf("Command: %s\n", GetCommandLineA());
|
||||
}
|
||||
|
||||
loadConfig(ConfigJson);
|
||||
initHook();
|
||||
|
||||
std::mutex mutex;
|
||||
std::condition_variable cond;
|
||||
std::atomic<bool> hookIsReady(false);
|
||||
|
||||
// 依赖检查游戏版本的指针加载,因此在 hook 完成后再加载翻译数据
|
||||
std::unique_lock lock(mutex);
|
||||
cond.wait(lock, [&] {
|
||||
return hookIsReady.load(std::memory_order_acquire);
|
||||
});
|
||||
if (g_enable_console)
|
||||
{
|
||||
auto _ = freopen("CONOUT$", "w+t", stdout);
|
||||
_ = freopen("CONOUT$", "w", stderr);
|
||||
_ = freopen("CONIN$", "r", stdin);
|
||||
}
|
||||
|
||||
});
|
||||
init_thread.detach();
|
||||
}
|
||||
else if (reason == DLL_PROCESS_DETACH)
|
||||
{
|
||||
RemoveVectoredExceptionHandler(AddressExceptionHandler);
|
||||
unInitHook();
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
Reference in New Issue
Block a user