From 0c3949811c2b8aec1fc922134f7b09174b764733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=81=8D=E5=85=AE=E6=83=9A=E5=85=AE?= <1173718158@qq.com> Date: Thu, 28 Nov 2024 16:59:08 +0800 Subject: [PATCH] . --- cpp/LunaHook/LunaHook/engine64/Ryujinx.cpp | 2 +- cpp/LunaHook/LunaHook/engine64/rpcs3.cpp | 4 +- cpp/LunaHook/LunaHook/engine64/vita3k.cpp | 3 +- cpp/LunaHook/LunaHook/engine64/yuzu.cpp | 46 ++++++++---- .../LunaHook/engines/ppsspp/ppsspp.cpp | 70 ++++++++++++++++--- .../LunaHook/engines/ppsspp/specialgames.hpp | 14 ++-- cpp/LunaHook/LunaHook/hookfinder.cc | 2 +- cpp/LunaHook/LunaHook/main.cc | 15 +--- cpp/LunaHook/LunaHook/main.h | 5 +- cpp/LunaHook/LunaHook/stackoffset.hpp | 2 + cpp/LunaHook/LunaHost/GUI/LunaHost.cpp | 16 +++-- cpp/LunaHook/LunaHost/GUI/LunaHost.h | 2 +- cpp/LunaHook/LunaHost/LunaHostDll.cpp | 13 ++-- cpp/LunaHook/LunaHost/host.cpp | 66 ++++++++++------- cpp/LunaHook/LunaHost/host.h | 7 +- cpp/LunaHook/include/const.h | 7 +- cpp/LunaHook/include/types.h | 13 ++-- cpp/shareddllproxy/aspatch.cpp | 12 ++-- cpp/version.cmake | 4 +- py/LunaTranslator/gui/selecthook.py | 45 +++++++----- py/LunaTranslator/textsource/texthook.py | 18 ++--- 21 files changed, 223 insertions(+), 143 deletions(-) diff --git a/cpp/LunaHook/LunaHook/engine64/Ryujinx.cpp b/cpp/LunaHook/LunaHook/engine64/Ryujinx.cpp index b7d6d6af..484fcfa5 100644 --- a/cpp/LunaHook/LunaHook/engine64/Ryujinx.cpp +++ b/cpp/LunaHook/LunaHook/engine64/Ryujinx.cpp @@ -67,7 +67,7 @@ struct passinfo }; bool Ryujinx::attach_function() { - WarningOutput("not support ryuujinx, please use yuzu/sudachi instead."); + HostInfo(HOSTINFO::Warning, "not support ryuujinx, please use yuzu/sudachi instead."); return true; /* UnsafeJitFunction diff --git a/cpp/LunaHook/LunaHook/engine64/rpcs3.cpp b/cpp/LunaHook/LunaHook/engine64/rpcs3.cpp index 8f72f365..c7e92861 100644 --- a/cpp/LunaHook/LunaHook/engine64/rpcs3.cpp +++ b/cpp/LunaHook/LunaHook/engine64/rpcs3.cpp @@ -16,8 +16,6 @@ namespace } uintptr_t getDoJitAddress() { auto DoJitPtr=getDoJitAddress_(); - - ConsoleOutput("DoJitPtr %p",DoJitPtr); if(!DoJitPtr)return 0; //<--DoJitPtr //0f85 1b050000 // jbe 0x00 ; long jump @@ -242,7 +240,7 @@ bool rpcs3::attach_function() if (DoJitPtr == 0) return false; unsafeinithooks(); - spDefault.jittype = JITTYPE::RPCS3; + spDefault.isjithook = true; spDefault.minAddress = 0; spDefault.maxAddress = -1; HookParam hp; diff --git a/cpp/LunaHook/LunaHook/engine64/vita3k.cpp b/cpp/LunaHook/LunaHook/engine64/vita3k.cpp index 59439b38..f683b877 100644 --- a/cpp/LunaHook/LunaHook/engine64/vita3k.cpp +++ b/cpp/LunaHook/LunaHook/engine64/vita3k.cpp @@ -63,8 +63,7 @@ bool vita3k::attach_function() auto DoJitPtr = getDoJitAddress(); if (DoJitPtr == 0) return false; - ConsoleOutput("DoJitPtr %p", DoJitPtr); - spDefault.jittype = JITTYPE::VITA3K; + spDefault.isjithook = true; spDefault.minAddress = 0; spDefault.maxAddress = -1; HookParam hp; diff --git a/cpp/LunaHook/LunaHook/engine64/yuzu.cpp b/cpp/LunaHook/LunaHook/engine64/yuzu.cpp index 1cc0810c..22c0ad60 100644 --- a/cpp/LunaHook/LunaHook/engine64/yuzu.cpp +++ b/cpp/LunaHook/LunaHook/engine64/yuzu.cpp @@ -122,13 +122,16 @@ bool Hook_Network_RoomMember_SendGameInfo() // Network::RoomMember *this, // const AnnounceMultiplayerRoom::GameInfo *game_info) game_info = *(GameInfo *)stack->rdx; - std::stringstream num; - num << std::uppercase - << std::hex - << std::setw(16) - << std::setfill('0') - << game_info.id; - ConsoleOutput("%s %s %s", game_info.name.c_str(), num.str().c_str(), game_info.version.c_str()); + if (game_info.id) + { + std::stringstream num; + num << std::uppercase + << std::hex + << std::setw(16) + << std::setfill('0') + << game_info.id; + HostInfo(HOSTINFO::EmuGameName, "%s %s %s", game_info.name.c_str(), num.str().c_str(), game_info.version.c_str()); + } jitaddrclear(); }; return NewHook(hp, "yuzuGameInfo"); @@ -137,15 +140,14 @@ bool Hook_Network_RoomMember_SendGameInfo() } bool yuzu::attach_function() { - Hook_Network_RoomMember_SendGameInfo(); ConsoleOutput("[Compatibility] Yuzu 1616+"); auto DoJitPtr = getDoJitAddress(); - if (DoJitPtr == 0) + if (!DoJitPtr) return false; - spDefault.jittype = JITTYPE::YUZU; + Hook_Network_RoomMember_SendGameInfo(); + spDefault.isjithook = true; spDefault.minAddress = 0; spDefault.maxAddress = -1; - ConsoleOutput("DoJitPtr %p", DoJitPtr); HookParam hp; hp.address = DoJitPtr; hp.text_fun = [](hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split) @@ -310,7 +312,7 @@ namespace s = std::regex_replace(s, std::regex(R"(#[^\]]*\])"), ""); s = std::regex_replace(s, std::regex(R"(#[^n]*n)"), ""); s = std::regex_replace(s, std::regex(u8" "), ""); - s = std::regex_replace(s, std::regex(u8R"(Save(.|\s)*データ)"), ""); + s = std::regex_replace(s, std::regex(u8R"(Save[\s\S]*データ)"), ""); buffer->from(s); } @@ -676,6 +678,16 @@ namespace strReplace(s, R"(\n)", ""); buffer->from(s); } + template + void F010053F0128DC000(TextBuffer *buffer, HookParam *hp) + { + CharFilter(buffer, '\n'); + auto s = buffer->strA(); + char __[] = "$1"; + __[1] += _1 - 1; + s = std::regex_replace(s, std::regex(R"((.*?)([\s\S]*))"), __); + buffer->from(s); + } namespace { static std::string F0100FB50156E6000; @@ -1062,7 +1074,7 @@ namespace { auto s = buffer->strA(); s = std::regex_replace(s, std::regex(R"(\[~\])"), "\n"); - s = std::regex_replace(s, std::regex(R"(rom:(.|\s)*$)"), ""); + s = std::regex_replace(s, std::regex(R"(rom:[\s\S]*$)"), ""); s = std::regex_replace(s, std::regex(R"(\[[\w\d]*\[[\w\d]*\].*?\[\/[\w\d]*\]\])"), ""); s = std::regex_replace(s, std::regex(R"(\[.*?\])"), ""); static std::string last; @@ -1204,7 +1216,6 @@ namespace template void F010027401A2A2000(TextBuffer *buffer, HookParam *hp) { - auto s = buffer->strW(); s = std::regex_replace(s, std::wregex(L"\\[dic.*?text="), L""); s = std::regex_replace(s, std::wregex(L"\\[|'.*?\\]"), L""); @@ -1561,7 +1572,7 @@ namespace { auto s = buffer->strW(); - s = std::regex_replace(s, std::wregex(LR"((.|\s)*$)"), L""); + s = std::regex_replace(s, std::wregex(LR"([\s\S]*$)"), L""); s = std::regex_replace(s, std::wregex(L"\n+"), L" "); s = std::regex_replace(s, std::wregex(L"\\s"), L""); s = std::regex_replace(s, std::wregex(L"[＀븅]"), L""); @@ -3443,6 +3454,11 @@ namespace // 神凪ノ杜 {0x8205e150, {CODEC_UTF16, 0, 0x14, 0, F0100B5801D7CE000, "0100B5801D7CE000", "1.0.0"}}, {0x820e2e6c, {CODEC_UTF16, 0, 0x14, 0, 0, "0100B5801D7CE000", "1.0.0"}}, + // シェルノサージュ ~失われた星へ捧ぐ詩~ DX + {0x801A1140, {CODEC_UTF8, 1, 0, 0, F010053F0128DC000<1>, "010053F0128DC000", "1.0.0"}}, + {0x801A10A4, {CODEC_UTF8, 1, 0, 0, F010053F0128DC000<2>, "010053F0128DC000", "1.0.0"}}, + {0x801A04F4, {CODEC_UTF8, 1, 0, 0, F010053F0128DC000<1>, "010053F0128DC000", "1.0.1"}}, + {0x801A0590, {CODEC_UTF8, 1, 0, 0, F010053F0128DC000<2>, "010053F0128DC000", "1.0.1"}}, }; return 1; diff --git a/cpp/LunaHook/LunaHook/engines/ppsspp/ppsspp.cpp b/cpp/LunaHook/LunaHook/engines/ppsspp/ppsspp.cpp index 540e7216..fab7fa64 100644 --- a/cpp/LunaHook/LunaHook/engines/ppsspp/ppsspp.cpp +++ b/cpp/LunaHook/LunaHook/engines/ppsspp/ppsspp.cpp @@ -65,7 +65,7 @@ struct PPSSPPFunction namespace { - uintptr_t findleapushaddr(uintptr_t addr) + uintptr_t findleapushalignfuncaddr(uintptr_t addr) { #ifndef _WIN64 addr = MemDbg::findPushAddress(addr, processStartAddress, processStopAddress); @@ -148,7 +148,7 @@ bool InsertPPSSPPHLEHooks() auto addr = MemDbg::findBytes(function.pattern, ::strlen(function.pattern), processStartAddress, processStopAddress); if (!addr) continue; - addr = findleapushaddr(addr); + addr = findleapushalignfuncaddr(addr); if (!addr) continue; @@ -268,13 +268,23 @@ uintptr_t getDoJitAddress() namespace ppsspp { - + struct GameInfo + { + std::string DISC_ID{""}; + std::string TITLE{""}; + } game_info; bool checkiscurrentgame(const emfuncinfo &em) { auto wininfos = get_proc_windows(); for (auto &&info : wininfos) { - if (std::regex_search(info.title, std::wregex(acastw(em._id)))) + if (game_info.DISC_ID.size()) + { + std::smatch match; + if (std::regex_match(game_info.DISC_ID, match, std::regex(em._id))) + return true; + } + else if (std::regex_search(info.title, std::wregex(acastw(em._id)))) return true; } return false; @@ -476,17 +486,61 @@ namespace ppsspp } return true; } + + void Load_PSP_ISO_StringFromFormat() + { + /* + bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string) { + // Mounting stuff relocated to InitMemoryForGameISO due to HD Remaster restructuring of code. + + std::string sfoPath("disc0:/PSP_GAME/PARAM.SFO"); + PSPFileInfo fileInfo = pspFileSystem.GetFileInfo(sfoPath.c_str()); + if (fileInfo.exists) { + std::vector paramsfo; + pspFileSystem.ReadEntireFile(sfoPath, paramsfo); + if (g_paramSFO.ReadSFO(paramsfo)) { + std::string title = StringFromFormat("%s : %s", g_paramSFO.GetValueString("DISC_ID").c_str(), g_paramSFO.GetValueString("TITLE").c_str()); + INFO_LOG(Log::Loader, "%s", title.c_str()); + System_SetWindowTitle(title); + } + } + + ------>StringFromFormat + */ + BYTE sig[] = { +#ifndef _WIN64 + 0x55, 0x8B, 0xEC, 0x6A, 0xFF, 0x68, XX4, 0x64, 0xA1, 0x00, 0x00, 0x00, 0x00, 0x50, 0x64, 0x89, 0x25, 0x00, 0x00, 0x00, 0x00, 0x83, 0xEC, 0x14, 0x56, 0x8B, 0x75, 0x08, 0x0F, 0x57, 0xC0, 0xC7, 0x45, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x8D, 0x46, 0x10, 0x57, 0x89, 0x45, 0xF0, 0x0F, 0x11, 0x06, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x46, 0x14, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x46, 0x14, 0x0F, 0x00, 0x00, 0x00, 0xC6, 0x06, 0x00, 0xC7, 0x45, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xC7, 0x45, 0xE8, 0x01, 0x00, 0x00, 0x00, 0xE8, XX4, 0x8B, 0xC8, 0x8D, 0x45, 0x10, 0x50, 0x6A, 0x00, 0xFF, 0x75, 0x0C, 0x8B, 0x01, 0x6A, 0x00, 0x6A, 0x00, 0xFF, 0x71, 0x04, 0x83, 0xC8, 0x02, 0x89, 0x4D, 0xE0, 0x50, 0xE8, XX4 +#else + 0x48, 0x8B, 0xC4, 0x48, 0x89, 0x50, 0x10, 0x48, 0x89, 0x48, 0x08, 0x4C, 0x89, 0x40, 0x18, 0x4C, 0x89, 0x48, 0x20, 0x53, 0x55, 0x56, 0x57, 0x41, 0x56, 0x41, 0x57, 0x48, 0x83, 0xEC, 0x48, 0x48, 0x8B, 0xDA, 0x48, 0x8B, 0xF9, 0x33, 0xED, 0x89, 0x68, 0xB8, 0x0F, 0x57, 0xC0, 0x0F, 0x11, 0x01, 0x48, 0x89, 0x69, 0x10, 0x48, 0xC7, 0x41, 0x18, 0x0F, 0x00, 0x00, 0x00, 0x40, 0x88, 0x29, 0xC7, 0x40, 0xB8, 0x01, 0x00, 0x00, 0x00, 0x4C, 0x8D, 0x70, 0x18, 0xE8, XX4, 0x48, 0x8B, 0xF0, 0x48, 0x8B, 0x08, 0x48, 0x83, 0xC9, 0x02, 0x4C, 0x89, 0x74, 0x24, 0x28, 0x48, 0x89, 0x6C, 0x24, 0x20, 0x4C, 0x8B, 0xCB, 0x45, 0x33, 0xC0, 0x33, 0xD2, 0xE8, XX4 +#endif + }; + auto addr = MemDbg::findBytes(sig, sizeof(sig), processStartAddress, processStopAddress); + if (!addr) + return; + HookParam hp; + hp.address = addr; + hp.text_fun = [](hook_stack *stack, HookParam *hp, auto *buff, auto *split) + { + if (strcmp((char *)stack->ARG2, "%s : %s") != 0) + return; + game_info.DISC_ID = (char *)stack->ARG3; + game_info.TITLE = (char *)stack->ARG4; + HostInfo(HOSTINFO::EmuGameName, "%s %s", stack->ARG3, stack->ARG4); + jitaddrclear(); + }; + NewHook(hp, "PPSSPPGameInfo"); + } bool hookPPSSPPDoJit() { auto DoJitPtr = getDoJitAddress(); - if (DoJitPtr == 0) + if (!DoJitPtr) return false; - spDefault.jittype = JITTYPE::PPSSPP; + Load_PSP_ISO_StringFromFormat(); + spDefault.isjithook = true; spDefault.minAddress = 0; spDefault.maxAddress = -1; HookParam hp; hp.address = DoJitPtr; // Jit::DoJit - ConsoleOutput("DoJitPtr %p", DoJitPtr); hp.user_value = (uintptr_t) new uintptr_t; hp.text_fun = [](hook_stack *stack, HookParam *hp, auto *, auto *) { @@ -529,7 +583,7 @@ namespace auto addr = MemDbg::findBytes(GetPointer, sizeof(GetPointer), processStartAddress, processStopAddress); if (!addr) return nullptr; - addr = findleapushaddr(addr); + addr = findleapushalignfuncaddr(addr); return (void *)addr; } bool Replace_memcpy() diff --git a/cpp/LunaHook/LunaHook/engines/ppsspp/specialgames.hpp b/cpp/LunaHook/LunaHook/engines/ppsspp/specialgames.hpp index 460f8ca9..fdd5e2ba 100644 --- a/cpp/LunaHook/LunaHook/engines/ppsspp/specialgames.hpp +++ b/cpp/LunaHook/LunaHook/engines/ppsspp/specialgames.hpp @@ -168,7 +168,7 @@ namespace ppsspp return s; } } - + void ULJM05428(hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split) { auto address = PPSSPP::emu_arg(stack)[1]; @@ -177,14 +177,6 @@ namespace ppsspp *split = haveNamve; buffer->from(s); } - void ULJM05054(hook_stack *stack, HookParam *hp, TextBuffer *buffer, uintptr_t *split) - { - auto address = PPSSPP::emu_arg(stack)[1]; - bool haveNamve; - auto s = Corda::readBinaryString(address, &haveNamve); - *split = haveNamve; - buffer->from(s); - } void ULJM05943F(TextBuffer *buffer, HookParam *hp) { @@ -426,10 +418,12 @@ namespace ppsspp {0x0891D72C, {CODEC_UTF8, 0, 0, 0, ULJM06119_filter, "ULJM06119"}}, // Princess Evangile {0x88506d0, {CODEC_UTF16, 2, 0, 0, ULJM06036_filter, "ULJM06036"}}, // [0x88506d0(2)...0x088507C0(?)] // name text text (line doubled) + // 金色のコルダ3 + {0x896C3B8, {0, 0, 0, ULJM05428, 0, "ULJM05624"}}, // 金色のコルダ2 f {0x89b59dc, {0, 0, 0, ULJM05428, 0, "ULJM05428"}}, // 金色のコルダ - {0x886162c, {0, 0, 0, ULJM05054, 0, "ULJM05054"}}, // dialogue: 0x886162c (x1), 0x889d5fc-0x889d520(a2) fullLine + {0x886162c, {0, 0, 0, ULJM05428, 0, "ULJM05054"}}, // dialogue: 0x886162c (x1), 0x889d5fc-0x889d520(a2) fullLine {0x8899e90, {0, 0, 0x3c, 0, 0, "ULJM05054"}}, // name 0x88da57c, 0x8899ca4 (x0, oneTime), 0x8899e90 // Sol Trigger {0x8952cfc, {CODEC_UTF8, 0, 0, 0, NPJH50619F, "NPJH50619"}}, // dialog diff --git a/cpp/LunaHook/LunaHook/hookfinder.cc b/cpp/LunaHook/LunaHook/hookfinder.cc index d4f8bb67..ac5ac253 100644 --- a/cpp/LunaHook/LunaHook/hookfinder.cc +++ b/cpp/LunaHook/LunaHook/hookfinder.cc @@ -335,7 +335,7 @@ void SearchForHooks(SearchParam spUser) initrecords(); std::vector addresses; - if( sp.jittype==JITTYPE::PC) + if( !sp.isjithook) { if (*sp.boundaryModule) { auto [minaddr,maxaddr]=Util::QueryModuleLimits(GetModuleHandleW(sp.boundaryModule)); diff --git a/cpp/LunaHook/LunaHook/main.cc b/cpp/LunaHook/LunaHook/main.cc index f40192a1..8f869a4f 100644 --- a/cpp/LunaHook/LunaHook/main.cc +++ b/cpp/LunaHook/LunaHook/main.cc @@ -105,21 +105,12 @@ void TextOutput(const ThreadParam &tp, const HookParam &hp, TextOutput_T *buffer memcpy(&buffer->hp, &hp, sizeof(hp)); WriteFile(hookPipe, buffer, sizeof(TextOutput_T) + len, DUMMY, nullptr); } - -void ConsoleOutput(LPCSTR text, ...) +void HostInfo(HOSTINFO type, LPCSTR text, ...) { - ConsoleOutputNotif buffer; - va_list args; - va_start(args, text); - vsnprintf(buffer.message, MESSAGE_SIZE, text, args); - WriteFile(hookPipe, &buffer, sizeof(buffer), DUMMY, nullptr); -} - -void WarningOutput(LPCSTR text, ...) -{ - WarningNotif buffer; + HostInfoNotif buffer; va_list args; va_start(args, text); + buffer.type = type; vsnprintf(buffer.message, MESSAGE_SIZE, text, args); WriteFile(hookPipe, &buffer, sizeof(buffer), DUMMY, nullptr); } diff --git a/cpp/LunaHook/LunaHook/main.h b/cpp/LunaHook/LunaHook/main.h index 5ebab40e..5455aceb 100644 --- a/cpp/LunaHook/LunaHook/main.h +++ b/cpp/LunaHook/LunaHook/main.h @@ -5,8 +5,8 @@ // Branch: ITH/IHF_DLL.h, rev 66 void TextOutput(const ThreadParam &tp, const HookParam &hp, TextOutput_T(*buffer), int len); -void ConsoleOutput(LPCSTR text, ...); -void WarningOutput(LPCSTR text, ...); +void HostInfo(HOSTINFO type, LPCSTR text, ...); +#define ConsoleOutput(text, ...) HostInfo(HOSTINFO::Console, text, ##__VA_ARGS__, -1) void NotifyHookFound(HookParam hp, wchar_t *text); void NotifyHookRemove(uint64_t addr, LPCSTR name); bool NewHook(HookParam hp, LPCSTR name); @@ -15,7 +15,6 @@ bool NewHookJit(HookParam hp, LPCSTR name); void RemoveHook(uint64_t addr, int maxOffset = 9); std::string LoadResData(LPCWSTR pszResID, LPCWSTR _type); inline SearchParam spDefault; - // EOF int HookStrLen(HookParam *, BYTE *data); diff --git a/cpp/LunaHook/LunaHook/stackoffset.hpp b/cpp/LunaHook/LunaHook/stackoffset.hpp index 78e0f272..ab03fab5 100644 --- a/cpp/LunaHook/LunaHook/stackoffset.hpp +++ b/cpp/LunaHook/LunaHook/stackoffset.hpp @@ -113,6 +113,7 @@ inline uintptr_t regof(regs reg, hook_stack *stack) #define ARG1 stack[1] #define ARG2 stack[2] #define ARG3 stack[3] +#define ARG4 stack[4] #define LASTRETVAL eax #define THISCALL __thiscall #define THISCALLTHIS ecx @@ -125,6 +126,7 @@ inline uintptr_t regof(regs reg, hook_stack *stack) #define ARG1 rcx #define ARG2 rdx #define ARG3 r8 +#define ARG4 r9 #define LASTRETVAL rax #define THISCALLTHIS rcx #define THISCALLARG1 rdx diff --git a/cpp/LunaHook/LunaHost/GUI/LunaHost.cpp b/cpp/LunaHook/LunaHost/GUI/LunaHost.cpp index d24836d5..f1464ad2 100644 --- a/cpp/LunaHook/LunaHost/GUI/LunaHost.cpp +++ b/cpp/LunaHook/LunaHost/GUI/LunaHost.cpp @@ -260,10 +260,11 @@ LunaHost::LunaHost() std::bind(&LunaHost::on_thread_create, this, std::placeholders::_1), std::bind(&LunaHost::on_thread_delete, this, std::placeholders::_1), std::bind(&LunaHost::on_text_recv, this, std::placeholders::_1, std::placeholders::_2), + true, + [=](HOSTINFO type, const std::wstring &output) + { on_info(type, output); }, {}, - {}, - {}, - std::bind(&LunaHost::on_warning, this, std::placeholders::_1)); + {}); mainlayout = new gridlayout(); mainlayout->addcontrol(g_selectprocessbutton, 0, 0); @@ -411,9 +412,14 @@ bool LunaHost::on_text_recv(TextThread &thread, std::wstring &output) } return true; } -void LunaHost::on_warning(const std::wstring &warning) +void LunaHost::on_info(HOSTINFO type, const std::wstring &warning) { - MessageBoxW(winId, warning.c_str(), L"warning", 0); + switch (type) + { + case HOSTINFO::Warning: + MessageBoxW(winId, warning.c_str(), L"warning", 0); + break; + } } void LunaHost::on_thread_create(TextThread &thread) { diff --git a/cpp/LunaHook/LunaHost/GUI/LunaHost.h b/cpp/LunaHook/LunaHost/GUI/LunaHost.h index d17c4f5e..f4682aa8 100644 --- a/cpp/LunaHook/LunaHost/GUI/LunaHost.h +++ b/cpp/LunaHook/LunaHost/GUI/LunaHost.h @@ -116,7 +116,7 @@ class LunaHost : public mainwindow void on_thread_delete(TextThread &thread); void on_proc_connect(DWORD pid); void on_proc_disconnect(DWORD pid); - void on_warning(const std::wstring &); + void on_info(HOSTINFO type, const std::wstring &); void showtext(const std::wstring &text, bool clear); void updatelisttext(const std::wstring &text, LONG_PTR data); diff --git a/cpp/LunaHook/LunaHost/LunaHostDll.cpp b/cpp/LunaHook/LunaHost/LunaHostDll.cpp index 5ffafa5f..3865625b 100644 --- a/cpp/LunaHook/LunaHost/LunaHostDll.cpp +++ b/cpp/LunaHook/LunaHost/LunaHostDll.cpp @@ -19,7 +19,7 @@ typedef void (*ProcessEvent)(DWORD pid); typedef void (*ThreadEvent_maybe_embed)(const wchar_t *hookcode, const char *hookname, ThreadParam, bool isembedable); typedef void (*ThreadEvent)(const wchar_t *hookcode, const char *hookname, ThreadParam); typedef bool (*OutputCallback)(const wchar_t *hookcode, const char *hookname, ThreadParam, const wchar_t *text); -typedef void (*ConsoleHandler)(const wchar_t *log); +typedef void (*HostInfoHandler)(HOSTINFO type, const wchar_t *log); typedef void (*HookInsertHandler)(DWORD pid, uint64_t address, const wchar_t *hookcode); typedef void (*EmbedCallback)(const wchar_t *text, ThreadParam); typedef void (*findhookcallback_t)(wchar_t *hookcode, const wchar_t *text); @@ -30,7 +30,7 @@ std::optional checkoption(bool check, T &&t) return std::move(t); return {}; } -C_LUNA_API void Luna_Start(ProcessEvent Connect, ProcessEvent Disconnect, ThreadEvent_maybe_embed Create, ThreadEvent Destroy, OutputCallback Output, ConsoleHandler console, HookInsertHandler hookinsert, EmbedCallback embed, ConsoleHandler Warning) +C_LUNA_API void Luna_Start(ProcessEvent Connect, ProcessEvent Disconnect, ThreadEvent_maybe_embed Create, ThreadEvent Destroy, OutputCallback Output, HostInfoHandler hostinfo, HookInsertHandler hookinsert, EmbedCallback embed) { Host::StartEx( checkoption(Connect, std::function(Connect)), @@ -41,14 +41,13 @@ C_LUNA_API void Luna_Start(ProcessEvent Connect, ProcessEvent Disconnect, Thread { Destroy(thread.hp.hookcode, thread.hp.name, thread.tp); }), checkoption(Output, [=](const TextThread &thread, std::wstring &output) { return Output(thread.hp.hookcode, thread.hp.name, thread.tp, output.c_str()); }), - checkoption(console, [=](const std::wstring &output) - { console(output.c_str()); }), + false, + checkoption(hostinfo, [=](HOSTINFO type, const std::wstring &output) + { hostinfo(type, output.c_str()); }), checkoption(hookinsert, [=](DWORD pid, uint64_t addr, const std::wstring &hookcode) { hookinsert(pid, addr, hookcode.c_str()); }), checkoption(embed, [=](const std::wstring &output, const ThreadParam &tp) - { embed(output.c_str(), tp); }), - checkoption(Warning, [=](const std::wstring &output) - { Warning(output.c_str()); })); + { embed(output.c_str(), tp); })); } C_LUNA_API void Luna_Inject(DWORD pid, LPCWSTR basepath) { diff --git a/cpp/LunaHook/LunaHost/host.cpp b/cpp/LunaHook/LunaHost/host.cpp index 9a56aba4..7aabddd4 100644 --- a/cpp/LunaHook/LunaHost/host.cpp +++ b/cpp/LunaHook/LunaHost/host.cpp @@ -49,8 +49,8 @@ namespace Host::ProcessEventHandler OnConnect, OnDisconnect; Host::ThreadEventHandler OnCreate, OnDestroy; - Host::ConsoleHandler OnConsole = 0; - Host::ConsoleHandler OnWarning = 0; + Host::HostInfoHandler OnHostInfo = 0; + bool has_consolethread = false; Host::HookInsertHandler HookInsert = 0; Host::EmbedCallback embedcallback = 0; void RemoveThreads(std::function removeIf) @@ -104,7 +104,7 @@ namespace WORD hookversion[4]; if( ReadFile(hookPipe, hookversion, sizeof(hookversion), &bytesRead, nullptr)){ if(memcmp(hookversion,LUNA_VERSION,sizeof(hookversion))!=0) - Host::Warning(UNMATCHABLEVERSION); + Host::InfoOutput(HOSTINFO::Warning, UNMATCHABLEVERSION); } while (ReadFile(hookPipe, buffer, PIPE_BUFFER_SIZE, &bytesRead, nullptr)) @@ -150,14 +150,8 @@ namespace break; case HOST_NOTIFICATION_TEXT: { - auto info = *(ConsoleOutputNotif*)buffer; - Host::AddConsoleOutput(StringToWideString(info.message)); - } - break; - case HOST_NOTIFICATION_WARNING: - { - auto info = *(WarningNotif*)buffer; - Host::Warning(StringToWideString(info.message)); + auto info = *(HostInfoNotif*)buffer; + Host::InfoOutput(info.type, StringToWideString(info.message)); } break; default: @@ -225,20 +219,27 @@ namespace Host { OnCreate(textThreadsByParams->try_emplace(console, console, HookParam{}, CONSOLE).first->second); Host::AddConsoleOutput(ProjectHomePage); + has_consolethread = true; } // CreatePipe(); } - void StartEx(std::optional Connect, std::optional Disconnect, std::optional Create, std::optional Destroy, std::optional Output, std::optional console, std::optional hookinsert, std::optional embed, std::optional warning) + void StartEx(std::optional Connect, + std::optional Disconnect, + std::optional Create, + std::optional Destroy, + std::optional Output, + bool consolethread, + std::optional hostinfo, + std::optional hookinsert, + std::optional embed) { Start(Connect.value_or([](auto) {}), Disconnect.value_or([](auto) {}), Create.value_or([](auto &) {}), Destroy.value_or([](auto &) {}), Output.value_or([](auto &, auto &) { return false; }), - !console); - if (warning) - OnWarning = warning.value(); - if (console) - OnConsole = [=](auto &&...args) - {std::lock_guard _(outputmutex);console.value()(std::forward(args)...); }; + consolethread); + if (hostinfo) + OnHostInfo = [=](auto &&...args) + {std::lock_guard _(outputmutex);hostinfo.value()(std::forward(args)...); }; if (hookinsert) HookInsert = [=](auto &&...args) {std::lock_guard _(threadmutex);hookinsert.value()(std::forward(args)...); }; @@ -403,16 +404,29 @@ namespace Host } void AddConsoleOutput(std::wstring text) { - if (OnConsole) - OnConsole(std::move(text)); - else - GetThread(console).AddSentence(std::move(text)); + InfoOutput(HOSTINFO::Console, text); } - void Warning(std::wstring text) + void InfoOutput(HOSTINFO type, std::wstring text) { - if (OnWarning) - OnWarning(text); - AddConsoleOutput(L"[Warning] " + text); + if (OnHostInfo) + OnHostInfo(type, std::move(text)); + + if (has_consolethread || (type != HOSTINFO::Console)) + { + switch (type) + { + case HOSTINFO::Warning: + text = L"[Warning] " + text; + break; + case HOSTINFO::EmuGameName: + text = L"[Game] " + text; + break; + } + if (has_consolethread) + GetThread(console).AddSentence(std::move(text)); + else if (type != HOSTINFO::Console) + OnHostInfo(HOSTINFO::Console, std::move(text)); + } } bool CheckIsUsingEmbed(ThreadParam tp) { diff --git a/cpp/LunaHook/LunaHost/host.h b/cpp/LunaHook/LunaHost/host.h index 1efe63a7..4a83f77d 100644 --- a/cpp/LunaHook/LunaHost/host.h +++ b/cpp/LunaHook/LunaHost/host.h @@ -3,14 +3,14 @@ #include "textthread.h" namespace Host { - using ConsoleHandler = std::function; + using HostInfoHandler = std::function; using ProcessEventHandler = std::function; using ThreadEventHandler = std::function; using HookEventHandler = std::function; using HookInsertHandler = std::function; using EmbedCallback = std::function; void Start(ProcessEventHandler Connect, ProcessEventHandler Disconnect, ThreadEventHandler Create, ThreadEventHandler Destroy, TextThread::OutputCallback Output, bool createconsole = true); - void StartEx(std::optional Connect, std::optional Disconnect, std::optional Create, std::optional Destroy, std::optional Output, std::optional console, std::optional hookinsert, std::optional embed, std::optional warning); + void StartEx(std::optional Connect, std::optional Disconnect, std::optional Create, std::optional Destroy, std::optional Output, bool consolethread, std::optional hostinfo, std::optional hookinsert, std::optional embed); void InjectProcess(DWORD processId, const std::wstring locationX = L""); bool CreatePipeAndCheck(DWORD processId); @@ -23,9 +23,8 @@ namespace Host CommonSharedMem *GetCommonSharedMem(DWORD pid); TextThread *GetThread(int64_t handle); TextThread &GetThread(ThreadParam tp); - + void InfoOutput(HOSTINFO type, std::wstring text); void AddConsoleOutput(std::wstring text); - void Warning(std::wstring text); inline int defaultCodepage = SHIFT_JIS; diff --git a/cpp/LunaHook/include/const.h b/cpp/LunaHook/include/const.h index aedcbb27..9dc8ebd6 100644 --- a/cpp/LunaHook/include/const.h +++ b/cpp/LunaHook/include/const.h @@ -36,7 +36,12 @@ enum HostNotificationType HOST_NOTIFICATION_RMVHOOK, HOST_NOTIFICATION_INSERTING_HOOK, HOST_SETTEXTTHREADTYPE, - HOST_NOTIFICATION_WARNING +}; +enum class HOSTINFO +{ + Console, + Warning, + EmuGameName }; #define NEXT_MASK(x) \ DUMMY1_##x, \ diff --git a/cpp/LunaHook/include/types.h b/cpp/LunaHook/include/types.h index 7d10db55..047b4b46 100644 --- a/cpp/LunaHook/include/types.h +++ b/cpp/LunaHook/include/types.h @@ -155,7 +155,7 @@ struct SearchParam wchar_t boundaryModule[MAX_MODULE_SIZE] = {}; // hook all functions within this module (middle priority) wchar_t exportModule[MAX_MODULE_SIZE] = {}; // hook the exports of this module (highest priority) wchar_t text[PATTERN_SIZE] = {}; // text to search for - JITTYPE jittype; + bool isjithook; }; struct InsertPCHooksCmd { @@ -183,16 +183,11 @@ struct FindHookCmd // From host SearchParam sp; }; -struct ConsoleOutputNotif // From dll +struct HostInfoNotif // From dll { - ConsoleOutputNotif(std::string message = "") { strncpy_s(this->message, message.c_str(), MESSAGE_SIZE - 1); } + HostInfoNotif(std::string message = "") { strncpy_s(this->message, message.c_str(), MESSAGE_SIZE - 1); } HostNotificationType command = HOST_NOTIFICATION_TEXT; - char message[MESSAGE_SIZE] = {}; -}; -struct WarningNotif // From dll -{ - WarningNotif(std::string message = "") { strncpy_s(this->message, message.c_str(), MESSAGE_SIZE - 1); } - HostNotificationType command = HOST_NOTIFICATION_WARNING; + HOSTINFO type; char message[MESSAGE_SIZE] = {}; }; diff --git a/cpp/shareddllproxy/aspatch.cpp b/cpp/shareddllproxy/aspatch.cpp index 52ad1512..2dbab915 100644 --- a/cpp/shareddllproxy/aspatch.cpp +++ b/cpp/shareddllproxy/aspatch.cpp @@ -83,13 +83,14 @@ struct ThreadParam uint64_t ctx; // The context of the hook: by default the first value on stack, usually the return address uint64_t ctx2; // The subcontext of the hook: 0 by default, generated in a method specific to the hook }; -typedef void (*ProcessEvent)(DWORD); -typedef void (*HookInsertHandler)(DWORD, uint64_t, const wchar_t *); -typedef void (*EmbedCallback)(const wchar_t *, ThreadParam); + +typedef void (*ProcessEvent)(DWORD pid); +typedef void (*HookInsertHandler)(DWORD pid, uint64_t address, const wchar_t *hookcode); +typedef void (*EmbedCallback)(const wchar_t *text, ThreadParam); nlohmann::json config; std::map translation; std::unordered_set connectedpids; -void (*Luna_Start)(ProcessEvent Connect, ProcessEvent Disconnect, void *, void *, void *, void *, HookInsertHandler hookinsert, EmbedCallback embed, void *); +void (*Luna_Start)(ProcessEvent Connect, ProcessEvent Disconnect, void *, void *, void *, void *, HookInsertHandler hookinsert, EmbedCallback embed); void (*Luna_Inject)(DWORD pid, LPCWSTR basepath); void (*Luna_EmbedSettings)(DWORD pid, UINT32 waittime, UINT8 fontCharSet, bool fontCharSetEnabled, wchar_t *fontFamily, UINT32 keeprawtext, bool fastskipignore); void (*Luna_useembed)(ThreadParam, bool use); @@ -150,8 +151,7 @@ public: std::wstring text = output; auto trans = findtranslation(text); Luna_embedcallback(tp, output, trans.c_str()); - }, - 0); + }); } void run() { diff --git a/cpp/version.cmake b/cpp/version.cmake index e3bd97d8..7e1c79d4 100644 --- a/cpp/version.cmake +++ b/cpp/version.cmake @@ -1,7 +1,7 @@ set(VERSION_MAJOR 6) -set(VERSION_MINOR 6) -set(VERSION_PATCH 10) +set(VERSION_MINOR 7) +set(VERSION_PATCH 0) set(VERSION_REVISION 0) set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}") add_library(VERSION_DEF ${CMAKE_CURRENT_LIST_DIR}/version_def.cpp) diff --git a/py/LunaTranslator/gui/selecthook.py b/py/LunaTranslator/gui/selecthook.py index ee6291d9..e37183ab 100644 --- a/py/LunaTranslator/gui/selecthook.py +++ b/py/LunaTranslator/gui/selecthook.py @@ -29,6 +29,12 @@ from gui.dynalang import ( ) +class HOSTINFO: + Console = 0 + Warning = 1 + EmuGameName = 2 + + def getformlayoutw(w=None, cls=LFormLayout, hide=False): if w is None: _w = QWidget() @@ -155,7 +161,7 @@ class searchhookparam(LDialog): usestruct.boundaryModule = dumpvalues["module"][:120] usestruct.address_method = self.search_addr_range.idx() usestruct.search_method = self.search_method.idx() - usestruct.jittype = dumpvalues["jittype"] + usestruct.isjithook = bool(dumpvalues["isjithook"]) if self.search_addr_range.idx() == 0: usestruct.minAddress = self.safehex( dumpvalues["startaddr"], usestruct.minAddress @@ -336,7 +342,7 @@ class searchhookparam(LDialog): self.layoutsettings.addRow("搜索方式", _typelayout) _jitcombo = FocusCombo() - _jitcombo.addItems(["PC", "YUZU", "PPSSPP", "VITA3K", "RPCS3"]) + _jitcombo.addItems(["PC", "JIT"]) self.search_method = QButtonGroup_switch_widegt(self) _jitcombo.currentIndexChanged.connect( lambda idx: [ @@ -344,7 +350,7 @@ class searchhookparam(LDialog): self.resize(self.width(), 1), ] ) - self.regists["jittype"] = lambda: _jitcombo.currentIndex() + self.regists["isjithook"] = lambda: bool(_jitcombo.currentIndex()) _typelayout.addRow("类型", _jitcombo) @@ -384,11 +390,10 @@ class searchhookparam(LDialog): class hookselect(closeashidewindow): addnewhooksignal = pyqtSignal(tuple, bool, bool) getnewsentencesignal = pyqtSignal(str) - sysmessagesignal = pyqtSignal(str) + sysmessagesignal = pyqtSignal(int, str) removehooksignal = pyqtSignal(tuple) getfoundhooksignal = pyqtSignal(dict) update_item_new_line = pyqtSignal(tuple, str) - warning = pyqtSignal(str) SaveTextThreadRole = Qt.ItemDataRole.UserRole + 1 @@ -402,17 +407,9 @@ class hookselect(closeashidewindow): self.sysmessagesignal.connect(self.sysmessage) self.update_item_new_line.connect(self.update_item_new_line_function) self.getfoundhooksignal.connect(self.getfoundhook) - self.warning.connect(self.warningf) self.setWindowTitle("选择文本") self.changeprocessclear() - def warningf(self, text): - getQMessageBox( - self, - "警告", - text, - ) - def querykeyofrow(self, row): if isinstance(row, QModelIndex): row = row.row() @@ -557,7 +554,9 @@ class hookselect(closeashidewindow): self.widget = QWidget() self.setCentralWidget(self.widget) - self.setWindowIcon(qtawesome.icon(globalconfig["toolbutton"]["buttons"]["selecttext"]["icon"])) + self.setWindowIcon( + qtawesome.icon(globalconfig["toolbutton"]["buttons"]["selecttext"]["icon"]) + ) self.hboxlayout = QHBoxLayout() self.widget.setLayout(self.hboxlayout) self.vboxlayout = QVBoxLayout() @@ -861,11 +860,19 @@ class hookselect(closeashidewindow): if atBottom: scrollbar.setValue(scrollbar.maximum()) - def sysmessage(self, sentence): - - self.textbrowappendandmovetoend( - self.sysOutput, get_time_stamp() + " " + sentence - ) + def sysmessage(self, info, sentence): + if info == HOSTINFO.Console: + self.textbrowappendandmovetoend( + self.sysOutput, get_time_stamp() + " " + sentence + ) + elif info == HOSTINFO.Warning: + getQMessageBox( + self, + "警告", + sentence, + ) + elif info == HOSTINFO.EmuGameName: + gobject.baseobject.displayinfomessage(sentence, "") def getnewsentence(self, sentence): if self.at1 == 2: diff --git a/py/LunaTranslator/textsource/texthook.py b/py/LunaTranslator/textsource/texthook.py index 6c348743..17f638ee 100644 --- a/py/LunaTranslator/textsource/texthook.py +++ b/py/LunaTranslator/textsource/texthook.py @@ -85,7 +85,7 @@ class SearchParam(Structure): ("boundaryModule", c_wchar * 120), ("exportModule", c_wchar * 120), ("text", c_wchar * 30), - ("jittype", c_int), + ("isjithook", c_bool), ] @@ -94,7 +94,7 @@ ProcessEvent = CFUNCTYPE(None, DWORD) ThreadEvent_maybe_embed = CFUNCTYPE(None, c_wchar_p, c_char_p, ThreadParam, c_bool) ThreadEvent = CFUNCTYPE(None, c_wchar_p, c_char_p, ThreadParam) OutputCallback = CFUNCTYPE(c_bool, c_wchar_p, c_char_p, ThreadParam, c_wchar_p) -ConsoleHandler = CFUNCTYPE(None, c_wchar_p) +HostInfoHandler = CFUNCTYPE(None, c_int, c_wchar_p) HookInsertHandler = CFUNCTYPE(None, DWORD, c_uint64, c_wchar_p) EmbedCallback = CFUNCTYPE(None, c_wchar_p, ThreadParam) QueryHistoryCallback = CFUNCTYPE(None, c_wchar_p) @@ -206,7 +206,6 @@ class texthook(basetext): c_void_p, c_void_p, c_void_p, - c_void_p, ) self.Luna_Inject = LunaHost.Luna_Inject self.Luna_Inject.argtypes = DWORD, LPCWSTR @@ -252,10 +251,9 @@ class texthook(basetext): ThreadEvent_maybe_embed(self.onnewhook), ThreadEvent(self.onremovehook), OutputCallback(self.handle_output), - ConsoleHandler(gobject.baseobject.hookselectdialog.sysmessagesignal.emit), + HostInfoHandler(gobject.baseobject.hookselectdialog.sysmessagesignal.emit), HookInsertHandler(self.newhookinsert), EmbedCallback(self.getembedtext), - ConsoleHandler(gobject.baseobject.hookselectdialog.warning.emit), ] self.keepref += procs ptrs = [cast(_, c_void_p).value for _ in procs] @@ -342,7 +340,9 @@ class texthook(basetext): self.gameuid = gameuid self.detachall() _filename, _ = os.path.splitext(os.path.basename(gamepath)) - sqlitef = gobject.gettranslationrecorddir("{}_{}.sqlite".format(_filename, gameuid)) + sqlitef = gobject.gettranslationrecorddir( + "{}_{}.sqlite".format(_filename, gameuid) + ) if os.path.exists(sqlitef) == False: md5 = getfilemd5(gamepath) f2 = gobject.gettranslationrecorddir("{}_{}.sqlite".format(_filename, md5)) @@ -396,7 +396,9 @@ class texthook(basetext): injectpids.append(pid) if len(injectpids): arch = ["32", "64"][self.is64bit] - dll = os.path.abspath("./files/plugins/LunaHook/LunaHook{}.dll".format(arch)) + dll = os.path.abspath( + "./files/plugins/LunaHook/LunaHook{}.dll".format(arch) + ) injectdll(injectpids, arch, dll) @threader @@ -605,7 +607,7 @@ class texthook(basetext): usestruct.maxRecords = 100000 usestruct.codepage = self.codepage() usestruct.boundaryModule = os.path.basename(self.gamepath) - usestruct.jittype = 0 + usestruct.isjithook = False return usestruct @threader