From 7bbda900d46ee21c8d3dab841c87322f31cac0d6 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: Tue, 17 Dec 2024 01:22:33 +0800 Subject: [PATCH] . --- cpp/LunaHook/LunaHook/embed_util.cc | 4 + cpp/LunaHook/LunaHook/engine32/XUSE.cpp | 176 ++++++++++---- .../LunaHook/engines/ppsspp/ppsspp.cpp | 33 ++- .../LunaHook/engines/ppsspp/specialgames.hpp | 219 +++++++++++++++++- cpp/LunaHook/LunaHook/hijackfuns.cc | 50 ++-- cpp/LunaHook/LunaHook/hijackfuns.h | 1 + cpp/LunaHook/include/const.h | 1 + cpp/version.cmake | 2 +- py/LunaTranslator/tts/basettsclass.py | 3 + 9 files changed, 395 insertions(+), 94 deletions(-) diff --git a/cpp/LunaHook/LunaHook/embed_util.cc b/cpp/LunaHook/LunaHook/embed_util.cc index b5795f6d..fbf1fb22 100644 --- a/cpp/LunaHook/LunaHook/embed_util.cc +++ b/cpp/LunaHook/LunaHook/embed_util.cc @@ -116,6 +116,10 @@ void detachall() } void solvefont(HookParam hp) { + if (hp.embed_hook_font & DISABLE_FONT_SWITCH) + { + Hijack::Disable_Font_Switch = true; + } if (hp.embed_hook_font) { attachFunction(hp.embed_hook_font); diff --git a/cpp/LunaHook/LunaHook/engine32/XUSE.cpp b/cpp/LunaHook/LunaHook/engine32/XUSE.cpp index 0cc69d93..feafb4ae 100644 --- a/cpp/LunaHook/LunaHook/engine32/XUSE.cpp +++ b/cpp/LunaHook/LunaHook/engine32/XUSE.cpp @@ -1,65 +1,157 @@ -#include"XUSE.h" +#include "XUSE.h" + +bool InsertXUSEHook2() +{ + // 最果てのイマ -COMPLETE- -bool InsertXUSEHook2() { - //最果てのイマ -COMPLETE- - ConsoleOutput("maybe XUSE2"); - BYTE bytes[] = { - 0x68,0x34,0x01,0x00,0x00 - //v39 = v16; - //v40 = v15; <----- v15 ,eax - //v41 = (const char*)operator new(0x134u); + 0x68, 0x34, 0x01, 0x00, 0x00 + // v39 = v16; + // v40 = v15; <----- v15 ,eax + // v41 = (const char*)operator new(0x134u); }; - auto succ=false; + auto succ = false; auto addrs = Util::SearchMemory(bytes, sizeof(bytes), PAGE_EXECUTE, processStartAddress, processStopAddress); - for (auto addr : addrs) { + for (auto addr : addrs) + { HookParam hp; - hp.address = addr ; - hp.offset=regoffset(eax); - hp.type = CODEC_ANSI_BE|NO_CONTEXT | USING_SPLIT; + hp.address = addr; + hp.offset = regoffset(eax); + hp.type = CODEC_ANSI_BE | NO_CONTEXT | USING_SPLIT; hp.split = 0; - ConsoleOutput("XUSE2 %p", addr); - - succ|=NewHook(hp, "XUSE2"); + succ |= NewHook(hp, "XUSE2"); } return succ; - } -bool InsertXUSEHook() { - //詩乃先生の誘惑授業 - //憂ちゃんの新妻だいあり~ - ConsoleOutput("maybe XUSE"); +bool InsertXUSEHook() +{ + // 詩乃先生の誘惑授業 + // 憂ちゃんの新妻だいあり~ BYTE bytes[] = { - 0x6a,0x00, - XX, - 0x6a,0x05, - XX, - XX, - 0xff,0x15,XX4, - 0x8b,0xf0, - 0x83,0xfe,0xff + 0x6a, 0x00, + XX, + 0x6a, 0x05, + XX, + XX, + 0xff, 0x15, XX4, + 0x8b, 0xf0, + 0x83, 0xfe, 0xff }; - auto succ=false; + auto succ = false; auto addrs = Util::SearchMemory(bytes, sizeof(bytes), PAGE_EXECUTE, processStartAddress, processStopAddress); - for(auto addr : addrs){ + for (auto addr : addrs) + { HookParam hp; hp.address = addr + 7; - hp.offset=regoffset(edi); + hp.offset = regoffset(edi); hp.type = CODEC_ANSI_BE | NO_CONTEXT | USING_SPLIT; hp.split = stackoffset(3); - - ConsoleOutput("XUSE %p", addr); - - succ|=NewHook(hp, "XUSE"); + succ |= NewHook(hp, "XUSE"); } return succ; - } -bool XUSE::attach_function() { - - return InsertXUSEHook() || InsertXUSEHook2(); -} \ No newline at end of file +bool xuse_2(DWORD addr) +{ + // 久遠の絆 -THE ORIGIN- + // 加壳了没有导入表 + auto refs = findxref_reverse_checkcallop(addr, processStartAddress, processStopAddress, 0xe8); + if (refs.size() != 2) + return false; + auto a1 = MemDbg::findEnclosingAlignedFunction(refs[0]); + auto a2 = MemDbg::findEnclosingAlignedFunction(refs[1]); + if (a1 != a2) + return false; + if (!a1) + return false; + refs = findxref_reverse_checkcallop(a1, processStartAddress, processStopAddress, 0xe8); + if (refs.size() != 3) + return false; + addr = refs[refs.size() - 1]; + addr = MemDbg::findEnclosingAlignedFunction(addr); + if (!addr) + return false; + HookParam hp; + hp.address = addr; + hp.offset = stackoffset(8); + hp.type = USING_STRING | EMBED_ABLE | EMBED_AFTER_NEW | EMBED_DYNA_SJIS; + hp.embed_hook_font = F_GetGlyphOutlineA | DISABLE_FONT_SWITCH; // 修改字体会卡死 + return NewHook(hp, "XUSE"); +} +bool xuse_1(DWORD xaddr) +{ + auto import = Util::FindImportEntry(processStartAddress, (DWORD)IsDBCSLeadByteEx); + if (!import) + return xuse_2(xaddr); + BYTE bytes[] = { + 0x51, 0x68, 0xA4, 0x03, 0x00, 0x00, 0xFF, 0x15, XX4, 0x85, 0xC0}; + *(int *)(bytes + 8) = import; + auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress); + if (!addr) + return false; + addr = MemDbg::findEnclosingAlignedFunction(addr); + if (!addr) + return false; + HookParam hp; + hp.address = addr; + hp.offset = stackoffset(8); + hp.type = USING_STRING | EMBED_ABLE | EMBED_AFTER_NEW | EMBED_DYNA_SJIS; + hp.embed_hook_font = F_GetGlyphOutlineA | DISABLE_FONT_SWITCH; // 修改字体会卡死 + return NewHook(hp, "XUSE"); +} +bool xusex() +{ + // 久遠の絆 再臨詔 + /* + char __cdecl sub_5BC9C0(int a1, int a2, int a3, HDC a4, UINT a5, unsigned int a6, __int64 a7) +{ + if ( a6 >= 7 ) + a6 = 6; + if ( a6 >= 4 ) + return sub_5BC590(a1, a2, a3, a4, a5, a6 - 3, a7); + else + return sub_5BC120(a1, a2, a3, a4, a5, a6, a7, (struct _GLYPHMETRICS *)HIDWORD(a7)); +} + +sub_5BC590 +if ( a5 == 33167 ) + { + v21 = GetGlyphOutlineW; + a5 = 10084; + GlyphOutlineW = GetGlyphOutlineW(a4, 10084, v16, (LPGLYPHMETRICS)&v24, 0, 0, (const MAT2 *)&v17); + } + else + { + v21 = GetGlyphOutlineA; + GlyphOutlineW = GetGlyphOutlineA(a4, a5, v16, (LPGLYPHMETRICS)&v24, 0, 0, (const MAT2 *)&v17); + } + */ + + const BYTE bytes[] = { + 0x55, 0x8b, 0xec, + 0x83, 0x7d, 0x1c, 0x07, + 0x72, 0x07, + 0xc7, 0x45, 0x1c, 0x06, 0x00, 0x00, 0x00, + 0x83, 0x7d, 0x1c, 0x04, + 0x73, 0x2c, + 0x8b, 0x45, 0x24, + // …… + }; + auto addr = MemDbg::findBytes(bytes, sizeof(bytes), processStartAddress, processStopAddress); + if (!addr) + return false; + if (xuse_1(addr)) + return true; + HookParam hp; + hp.address = addr; + hp.offset = stackoffset(5); + hp.type = USING_CHAR | CODEC_ANSI_BE; + return NewHook(hp, "XUSE"); +} +bool XUSE::attach_function() +{ + return xusex() || InsertXUSEHook() || InsertXUSEHook2(); +} \ No newline at end of file diff --git a/cpp/LunaHook/LunaHook/engines/ppsspp/ppsspp.cpp b/cpp/LunaHook/LunaHook/engines/ppsspp/ppsspp.cpp index ea9b8a1b..67bdc665 100644 --- a/cpp/LunaHook/LunaHook/engines/ppsspp/ppsspp.cpp +++ b/cpp/LunaHook/LunaHook/engines/ppsspp/ppsspp.cpp @@ -109,16 +109,16 @@ bool InsertPPSSPPHLEHooks() auto functions = std::vector{ // https://github.com/hrydgard/ppsspp/blob/master/Core/HLE/sceCcc.cpp - {"sceCccStrlenSJIS", GETARG1, USING_STRING, 0, "sceCccStrlenSJIS("}, - {"sceCccStrlenUTF8", GETARG1, CODEC_UTF8 | USING_STRING, 0, "sceCccStrlenUTF8("}, - {"sceCccStrlenUTF16", GETARG1, CODEC_UTF16 | USING_STRING, 0, "sceCccStrlenUTF16("}, + // {"sceCccStrlenSJIS", GETARG1, USING_STRING, 0, "sceCccStrlenSJIS("}, + // {"sceCccStrlenUTF8", GETARG1, CODEC_UTF8 | USING_STRING, 0, "sceCccStrlenUTF8("}, + // {"sceCccStrlenUTF16", GETARG1, CODEC_UTF16 | USING_STRING, 0, "sceCccStrlenUTF16("}, - {"sceCccSJIStoUTF8", GETARG3, USING_STRING, 0, "sceCccSJIStoUTF8("}, - {"sceCccSJIStoUTF16", GETARG3, USING_STRING, 0, "sceCccSJIStoUTF16("}, - {"sceCccUTF8toSJIS", GETARG3, CODEC_UTF8 | USING_STRING, 0, "sceCccUTF8toSJIS("}, - {"sceCccUTF8toUTF16", GETARG3, CODEC_UTF8 | USING_STRING, 0, "sceCccUTF8toUTF16("}, - {"sceCccUTF16toSJIS", GETARG3, CODEC_UTF16 | USING_STRING, 0, "sceCccUTF16toSJIS("}, - {"sceCccUTF16toUTF8", GETARG3, CODEC_UTF16 | USING_STRING, 0, "sceCccUTF16toUTF8("}, + // {"sceCccSJIStoUTF8", GETARG3, USING_STRING, 0, "sceCccSJIStoUTF8("}, + // {"sceCccSJIStoUTF16", GETARG3, USING_STRING, 0, "sceCccSJIStoUTF16("}, + // {"sceCccUTF8toSJIS", GETARG3, CODEC_UTF8 | USING_STRING, 0, "sceCccUTF8toSJIS("}, + // {"sceCccUTF8toUTF16", GETARG3, CODEC_UTF8 | USING_STRING, 0, "sceCccUTF8toUTF16("}, + // {"sceCccUTF16toSJIS", GETARG3, CODEC_UTF16 | USING_STRING, 0, "sceCccUTF16toSJIS("}, + // {"sceCccUTF16toUTF8", GETARG3, CODEC_UTF16 | USING_STRING, 0, "sceCccUTF16toUTF8("}, // https://github.com/hrydgard/ppsspp/blob/master/Core/HLE/sceFont.cpp {"sceFontGetCharInfo", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetCharInfo("}, @@ -126,20 +126,15 @@ bool InsertPPSSPPHLEHooks() {"sceFontGetCharImageRect", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetCharImageRect("}, {"sceFontGetShadowImageRect", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetShadowImageRect("}, {"sceFontGetCharGlyphImage", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetCharGlyphImage("}, - {"sceFontGetCharGlyphImage_Clip", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetCharGlyphImage_Clip("}, + //{"sceFontGetCharGlyphImage_Clip", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetCharGlyphImage_Clip("}, {"sceFontGetShadowGlyphImage", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetShadowGlyphImage("}, - {"sceFontGetShadowGlyphImage_Clip", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetShadowGlyphImage_Clip("}, + //{"sceFontGetShadowGlyphImage_Clip", GETARG2, CODEC_UTF16, GETARG1, "sceFontGetShadowGlyphImage_Clip("}, // https://github.com/hrydgard/ppsspp/blob/master/Core/HLE/sceKernelInterrupt.cpp - {"sysclib_strcat", GETARG2, USING_STRING, 0, "Untested sysclib_strcat("}, - {"sysclib_strcpy", GETARG2, USING_STRING, 0, "Untested sysclib_strcpy("}, - {"sysclib_strlen", GETARG1, USING_STRING, 0, "Untested sysclib_strlen("} + // {"sysclib_strcat", GETARG2, USING_STRING, 0, "Untested sysclib_strcat("}, + // {"sysclib_strcpy", GETARG2, USING_STRING, 0, "Untested sysclib_strcpy("}, + // {"sysclib_strlen", GETARG1, USING_STRING, 0, "Untested sysclib_strlen("} - // Disabled as I am not sure how to deal with the source string - //, { "sceCccEncodeSJIS", 2, USING_STRING, 0, "sceCccEncodeSJIS(" } - //, { "sceCccEncodeUTF8", 2, CODEC_UTF8, 0, "sceCccEncodeUTF8(" } - //, { "sceCccEncodeUTF16", 2, CODEC_UTF16, 0, "sceCccEncodeUTF16(" } - //, { "sysclib_strcmp", 2, USING_STRING, 0, "Untested sysclib_strcmp(" } }; auto succ = false; for (auto &&function : functions) diff --git a/cpp/LunaHook/LunaHook/engines/ppsspp/specialgames.hpp b/cpp/LunaHook/LunaHook/engines/ppsspp/specialgames.hpp index 338cd5ee..ca33da08 100644 --- a/cpp/LunaHook/LunaHook/engines/ppsspp/specialgames.hpp +++ b/cpp/LunaHook/LunaHook/engines/ppsspp/specialgames.hpp @@ -161,6 +161,19 @@ namespace ppsspp buffer->from(s); CharFilter(buffer, '\n'); } + void NPJH50754(TextBuffer *buffer, HookParam *hp) + { + std::string s = buffer->strA(); + s = std::regex_replace(s, std::regex(R"((.*?))"), "$2"); // {みす/御簾} + buffer->from(s); + } + void ULJM06378(TextBuffer *buffer, HookParam *hp) + { + auto ws = StringToWideString(buffer->viewA(), 932).value(); + strReplace(ws, L"\\", L""); + strReplace(ws, L"$", L""); + buffer->from(WideStringToString(ws, 932)); + } void NPJH50215(TextBuffer *buffer, HookParam *hp) { auto ws = StringToWideString(buffer->viewA(), 932).value(); @@ -187,7 +200,6 @@ namespace ppsspp } buffer->from(WideStringToString(ws, 932)); } - void ULJM06119_filter(TextBuffer *buffer, HookParam *hp) { std::string s = buffer->strA(); @@ -197,7 +209,6 @@ namespace ppsspp s = std::regex_replace(s, std::regex(R"(/\n+)"), " "); buffer->from(s); } - void ULJM06036_filter(TextBuffer *buffer, HookParam *hp) { std::wstring result = buffer->strW(); @@ -205,7 +216,6 @@ namespace ppsspp result = std::regex_replace(result, std::wregex(LR"(<[A-Z]+>)"), L""); buffer->from(result); } - namespace Corda { std::string readBinaryString(uintptr_t address, bool *haveName) @@ -324,6 +334,35 @@ namespace ppsspp std::string s = (char *)PPSSPP::emu_arg(context)[1]; buffer->from(ULJM06143Code(s)); } + void NPJH50902(hook_context *context, HookParam *hp, TextBuffer *buffer, uintptr_t *split) + { + auto cs = (char *)PPSSPP::emu_arg(context)[3]; + while (*(WORD *)(cs - 1)) + cs -= 1; + cs += 1; + std::string ws; + while (*(char *)cs) + { + std::string s = cs; + for (int i = 0; i < s.size();) + { + if ((BYTE)s[i] == 0x87) + { + if (((BYTE)s[i + 1] == 0x86) || (BYTE)s[i + 1] == 0x85) + ws += "\x81\x5b"; + i += 2; + } + else + { + ws += s[i]; + i += 1; + } + } + cs += s.size() + 1; + } + strReplace(ws, "\n", ""); + buffer->from(ws); + } void ULJM06220(TextBuffer *buffer, HookParam *hp) { auto s = buffer->strA(); @@ -369,6 +408,13 @@ namespace ppsspp return buffer->clear(); ULJM05943F(buffer, hp); } + void ULJM05276(TextBuffer *buffer, HookParam *hp) + { + StringFilter(buffer, "@y", 2); + StringFilter(buffer, "@w", 2); + StringFilter(buffer, "\\c", 2); + StringFilter(buffer, "\\n", 2); + } void ULJM06289(TextBuffer *buffer, HookParam *hp) { StringFilter(buffer, "\x81\x40", 2); @@ -629,6 +675,13 @@ namespace ppsspp last = ws; buffer->from(WideStringToString(ws, 932)); } + void ULJM06397(TextBuffer *buffer, HookParam *hp) + { + auto ws = StringToWideString(buffer->viewA(), 932).value(); + ws = std::regex_replace(ws, std::wregex(LR"(<(.*?),(.*?)>)"), L"$1"); + strReplace(ws, L"^", L""); + buffer->from(WideStringToString(ws, 932)); + } void ULJM06129(TextBuffer *buffer, HookParam *hp) { auto s = buffer->strA(); @@ -727,6 +780,11 @@ namespace ppsspp return; buffer->from(addr + 0x20, *(DWORD *)(addr + 0x14) * 2); } + void NPJH50908(TextBuffer *buffer, HookParam *hp) + { + CharFilter(buffer, L'\n'); + CharFilter(buffer, L' '); + } void ULJM05433(TextBuffer *buffer, HookParam *hp) { auto s = buffer->strA(); @@ -752,6 +810,13 @@ namespace ppsspp StringFilter(buffer, "%K", 2); StringFilter(buffer, "%P", 2); } + void ULJM05954(TextBuffer *buffer, HookParam *hp) + { + StringFilter(buffer, "%K", 2); + StringFilter(buffer, "%N", 2); + StringFilter(buffer, "%P", 2); + StringFilter(buffer, "\x81\x40", 2); + } void ULJM06070(TextBuffer *buffer, HookParam *hp) { StringFilterBetween(buffer, "[", 1, "]", 1); @@ -773,6 +838,25 @@ namespace ppsspp s = std::regex_replace(s, std::regex(R"(\{(.*?)\}\[(.*?)\])"), "$1"); buffer->from(s); } + void NPJH00122(TextBuffer *buffer, HookParam *hp) + { + auto s = buffer->viewA(); + buffer->from(s.substr(14, s.size() - 15)); + } + void ULJM05249(TextBuffer *buffer, HookParam *hp) + { + auto s = buffer->viewA(); + buffer->from(s.substr(0, s.find("\x81\x75"))); + } + void ULJM05203(TextBuffer *buffer, HookParam *hp) + { + CharFilter(buffer, L'\n'); + static std::wstring last; + auto s = buffer->viewW(); + if (s == last) + return buffer->clear(); + last = s; + } void ULJM05282(TextBuffer *buffer, HookParam *hp) { static std::wstring last; @@ -810,6 +894,38 @@ namespace ppsspp }; buffer->from(remap(s)); } + void ULJM05758(TextBuffer *buffer, HookParam *hp) + { + auto s = buffer->strA(); + static auto katakanaMap = std::map{ + {L"「", L"「"}, {L"」", L"」"}, {L"ァ", L"ぁ"}, {L"ィ", L"ぃ"}, {L"ゥ", L"ぅ"}, {L"ェ", L"ぇ"}, {L"ォ", L"ぉ"}, {L"ャ", L"ゃ"}, {L"ュ", L"ゅ"}, {L"ョ", L"ょ"}, {L"ア", L"あ"}, {L"イ", L"い"}, {L"ウ", L"う"}, {L"エ", L"え"}, {L"オ", L"お"}, {L"カ", L"か"}, {L"キ", L"き"}, {L"ク", L"く"}, {L"ケ", L"け"}, {L"コ", L"こ"}, {L"サ", L"さ"}, {L"シ", L"し"}, {L"ス", L"す"}, {L"セ", L"せ"}, {L"ソ", L"そ"}, {L"タ", L"た"}, {L"チ", L"ち"}, {L"ツ", L"つ"}, {L"テ", L"て"}, {L"ト", L"と"}, {L"ナ", L"な"}, {L"ニ", L"に"}, {L"ヌ", L"ぬ"}, {L"ネ", L"ね"}, {L"ノ", L"の"}, {L"ハ", L"は"}, {L"ヒ", L"ひ"}, {L"フ", L"ふ"}, {L"ヘ", L"へ"}, {L"ホ", L"ほ"}, {L"マ", L"ま"}, {L"ミ", L"み"}, {L"ム", L"む"}, {L"メ", L"め"}, {L"モ", L"も"}, {L"ヤ", L"や"}, {L"ユ", L"ゆ"}, {L"ヨ", L"よ"}, {L"ラ", L"ら"}, {L"リ", L"り"}, {L"ル", L"る"}, {L"レ", L"れ"}, {L"ロ", L"ろ"}, {L"ワ", L"わ"}, {L"ヲ", L"を"}, {L"ン", L"ん"}, {L"ー", L"ー"}, {L"ッ", L"っ"}, {L"、", L"、"}, {L"゚", L"?"}, {L"゙", L"!"}, {L"・", L"…"}, {L"?", L"?"}, {L"。", L"。"}}; + auto remap = [](std::string &s) + { + std::wstring result; + auto ws = StringToWideString(s, 932).value(); + for (auto _c : ws) + { + std::wstring c; + c.push_back(_c); + if (katakanaMap.find(c) != katakanaMap.end()) + { + result += katakanaMap[c]; + } + else + result += c; + } + return WideStringToString(result, 932); + }; + buffer->from(remap(s)); + } + void ULJM05634(TextBuffer *buffer, HookParam *hp) + { + static std::string last; + auto s = buffer->strA(); + if (s == last) + return buffer->clear(); + last = s; + } void ULJS00169(TextBuffer *buffer, HookParam *hp) { CharFilter(buffer, '\n'); @@ -916,10 +1032,25 @@ namespace ppsspp } last = s; } + void ULJM05741(TextBuffer *buffer, HookParam *hp) + { + auto s = buffer->viewA(); + s = s.substr(0, s.size() - 2); + if (s.find('#') != s.npos) + return buffer->clear(); + buffer->from(s); + } + void ULJM05109(TextBuffer *buffer, HookParam *hp) + { + StringFilter(buffer, "$$", 2); + } void ULJM06258_2(TextBuffer *buffer, HookParam *hp) { auto s = buffer->strA(); - buffer->from(strSplit(s, "\n")[1]); + auto _ = strSplit(s, "\n"); + if (_.size() < 2) + return buffer->clear(); + buffer->from(_[1]); } void ULJM06258(TextBuffer *buffer, HookParam *hp) { @@ -956,7 +1087,22 @@ namespace ppsspp } buffer->from(s); } + void ULJM06200(TextBuffer *buffer, HookParam *hp) + { + NPJH50899(buffer, hp); + auto s = buffer->strA(); + s = s.substr(0, 2) + std::regex_replace(s.substr(2, s.size() - 4), std::regex(R"(\x81\x77(.*?)\x81\x78)"), "$1") + s.substr(s.size() - 2); + buffer->from(s); + } std::unordered_map emfunctionhooks = { + // Solomon's Ring ~地の章~ ULJM06204 + // Solomon's Ring ~水の章~ ULJM06203 + // Solomon's Ring ~風の章~ ULJM06202 + {0x88052C0, {0, 2, 0, 0, ULJM06200, "ULJM0620[234]"}}, + // Solomon's Ring ~火の章~ + {0x88061B0, {0, 2, 0, 0, ULJM06200, "ULJM06200"}}, + // 神なる君と + {0x888F054, {0, 0, 0, 0, ULJM06289, "ULJM05975"}}, // DEARDROPS DISTORTION {0x8814110, {USING_CHAR | DATA_INDIRECT, 4, 0, 0, 0, "ULJM05819"}}, // 流行り神PORTABLE @@ -974,8 +1120,6 @@ namespace ppsspp {0x8850b2c, {0, 0, 0, 0, NPJH50909_filter, "ULJM05878"}}, // onscreen toast // Dunamis15 {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 AnotherSky feat.神南 {0x883C940, {0, 0, 0, ULJM05428, 0, "NPJH50845"}}, // 金色のコルダ3 フルボイス Special @@ -1007,6 +1151,8 @@ namespace ppsspp // 神々の悪戯 InFinite {0x088630f8, {0, 0, 0, QNPJH50909, 0, "NPJH50909"}}, // text, choice (debounce trailing 400ms), TODO: better hook {0x0887813c, {0, 3, 4, 0, 0, "NPJH50909"}}, // Question YN + // アンジェリーク ルトゥール + {0x88A4970, {CODEC_UTF16, 1, 0, 0, NPJH50908, "NPJH50908"}}, // 月華繚乱ROMANCE {0x88eeba4, {0, 0, 0, 0, ULJM05943F, "ULJM05943"}}, // a0 - monologue text {0x8875e0c, {0, 1, 6, 0, ULJM05943F, "ULJM05943"}}, // a1 - dialogue text @@ -1155,6 +1301,9 @@ namespace ppsspp {0x881BECC, {0, 0, 0, 0, 0, "ULJM05444"}}, // のーふぇいと! ~only the power of will~ {0x889A888, {0, 0, 0, 0, ULJM05610, "ULJM05610"}}, + // 薄桜鬼 黎明録 ポータブル + {0x88AA0FC, {0, 0, 0, 0, ULJM05943F, "ULJM05917"}}, + {0x88ABC14, {0, 0, 0, 0, ULJM05823_2, "ULJM05917"}}, // 薄桜鬼 遊戯録 {0x8850720, {0, 0, 0, 0, ULJM05943F, "ULJM05663"}}, {0x884AB78, {0, 0, 0, 0, ULJM05823_2, "ULJM05663"}}, @@ -1242,6 +1391,8 @@ namespace ppsspp {0x88750C0, {0, 1, 0, 0, NPJH50899, "NPJH50899"}}, // 里見八犬伝~浜路姫之記~ {0x886C750, {0, 1, 0, 0, NPJH50899, "NPJH50885"}}, + // 大正鬼譚~言ノ葉櫻~ + {0x88851E8, {0, 1, 0, 0, 0, "NPJH50886"}}, // 白華の檻~緋色の欠片4~ {0x88FE8C0, {0, 0, 0, 0, ULJM05823_2, "ULJM06167"}}, {0x894672C, {0, 4, 0, 0, ULJM06167, "ULJM06167"}}, @@ -1278,6 +1429,8 @@ namespace ppsspp {0x8812600, {0, 1, 0, 0, ULJS00124, "ULJM06359"}}, // フォトカノ {0x88F2030, {0, 1, 0, 0, ULJS00124, "ULJS00378"}}, + // マーメイド・ゴシック + {0x888557C, {0, 1, 0, 0, 0, "NPJH50892"}}, // your diary+ {0x884D740, {0, 1, 0, 0, NPJH50831, "NPJH50831"}}, {0x8829364, {0, 1, 0, 0, NPJH50831_1, "NPJH50831"}}, @@ -1311,11 +1464,65 @@ namespace ppsspp {0x882C010, {0, 4, 0, 0, ULJS00579, "ULJS00579"}}, // リアルロデ PORTABLE {0x886A92C, {0, 0, 0, 0, ULJM05657, "ULJM05657"}}, + // Princess Evangile + {0x88506d0, {CODEC_UTF16, 2, 0, 0, ULJM06036_filter, "ULJM06036"}}, // Princess Arthur {0x8841D10, {0, 0xE, 0, 0, ULJM06258_2, "ULJM06258"}}, // name+text,显示完后 {0x88A844C, {0, 1, 0, 0, ULJM06258, "ULJM06258"}}, // text // アルコバレーノ!ポータブル {0x88AFECC, {0, 4, 0, 0, ULJM05943F, "ULJM05609"}}, + // ヒイロノカケラ 新玉依姫伝承 ポータブル + {0x883FA7C, {0, 4, 0, 0, ULJM05943F, "ULJM05741"}}, + {0x8813130, {0, 0xc, 0, 0, ULJM05741, "ULJM05741"}}, + // 十三支演義 ~偃月三国伝~ + {0x891BC1C, {0, 0, 0, 0, ULJM06289, "ULJM06090"}}, + // さくらさくら-HARU URARA- + {0x8817C98, {0, 1, 0, 0, ULJM05758, "ULJM05758"}}, + // どきどきすいこでん + {0x88A8FC8, {0, 1, 0, 0, ULJS00124, "ULJS00380"}}, + // Jewelic Nightmare + {0x888BF24, {0, 0, 0, 0, ULJM06289, "ULJM06326"}}, + // 怪盗アプリコット ポータブル + {0x8823474, {0, 1, 0, 0, 0, "ULJM05276"}}, + {0x8823DF0, {0, 1, 0, 0, ULJM05276, "ULJM05276"}}, + // EtudePrologue ポータブル + {0x881D160, {0, 0, 0, 0, ULJM05276, "ULJM05252"}}, + {0x8822894, {0, 0, 0, 0, ULJM05276, "ULJM05252"}}, + {0x881CA64, {0, 6, 0, 0, ULJM05276, "ULJM05252"}}, + // for Symphony ポータブル + {0x8821B50, {0, 1, 0, 0, ULJM05276, "ULJM05258"}}, + {0x881C354, {0, 0, 0, 0, ULJM05276, "ULJM05258"}}, + {0x881BC74, {0, 1, 0, 0, ULJM05276, "ULJM05258"}}, + // Kanon + {0x880B6E8, {CODEC_UTF16, 0, 0, 0, ULJM05203, "ULJM05203"}}, + // Little Aid ポータブル + {0x8822B6C, {0, 1, 0, 0, 0, "ULJM05249"}}, + {0x8823314, {0, 1, 0, 0, ULJM05249, "ULJM05249"}}, + // とびたて!超時空トラぶる花札大作戦 + {0x8842E48, {0, 2, 0, 0, NPJH00122, "NPJH00122"}}, + // ふしぎ遊戯 玄武開伝 外伝 鏡の巫女 + {0x884FC48, {0, 0, 0, 0, ULJM05823_2, "ULJM05175"}}, + {0x889B8D4, {0, 0, 0, 0, ULJM06258, "ULJM05175"}}, + // サクラ大戦1&2 + {0x8A7F814, {0, 6, 0, 0, ULJM05109, "ULJM05109"}}, // 其一。不支持其二 + // 白銀のカルと蒼空の女王 + {0x8859358, {0, 3, 0, 0, ULJM05954, "ULJM05954"}}, + {0x884F338, {0, 0, 0, 0, ULJM05954, "ULJM05954"}}, + // カレイドイヴ + {0x8837E98, {0, 3, 0, 0, ULJM06397, "ULJM06397"}}, + // 天神乱漫 Happy Go Lucky !! + {0x885C730, {0, 0xe, 0, 0, ULJM05634, "ULJM05634"}}, + // 学園K -Wonderful School Days- + {0x887F838, {0, 1, 0, 0, ULJM06378, "ULJM06378"}}, + // 学☆王 -THE ROYAL SEVEN STARS- +METEOR + {0x880E458, {0, 0, 0, 0, NPJH50754, "NPJH50754"}}, + // 黒雪姫~スノウ・マジック~ + {0x8886480, {0, 1, 0, 0, 0, "NPJH50888"}}, + // ロミオVSジュリエット + {0x887B4A4, {0, 1, 0, 0, 0, "ULJM06318"}}, + // うたの☆プリンスさまっ♪All Star After Secret + {0x885F3C0, {0, 3, 0, NPJH50902, 0, "NPJH50902"}}, + }; } \ No newline at end of file diff --git a/cpp/LunaHook/LunaHook/hijackfuns.cc b/cpp/LunaHook/LunaHook/hijackfuns.cc index 59226edd..571b5e3f 100644 --- a/cpp/LunaHook/LunaHook/hijackfuns.cc +++ b/cpp/LunaHook/LunaHook/hijackfuns.cc @@ -37,7 +37,13 @@ DEF_FUN(WideCharToMultiByte) #undef DEF_FUN /** Helper */ - +namespace +{ + inline const wchar_t *maybe_disabled_fontFamily() + { + return Hijack::Disable_Font_Switch ? L"" : commonsharedmem->fontFamily; + } +} namespace { // unnamed UINT8 systemCharSet() @@ -45,21 +51,14 @@ namespace enum CodePage { NullCodePage = 0, - Utf8CodePage = 65001 // UTF-8 - , - Utf16CodePage = 1200 // UTF-16 - , - SjisCodePage = 932 // SHIFT-JIS - , - GbkCodePage = 936 // GB2312 - , - KscCodePage = 949 // EUC-KR - , - Big5CodePage = 950 // BIG5 - , - TisCodePage = 874 // TIS-620 - , - Koi8CodePage = 866 // KOI8-R + Utf8CodePage = 65001, // UTF-8 + Utf16CodePage = 1200, // UTF-16 + SjisCodePage = 932, // SHIFT-JIS + GbkCodePage = 936, // GB2312 + KscCodePage = 949, // EUC-KR + Big5CodePage = 950, // BIG5 + TisCodePage = 874, // TIS-620 + Koi8CodePage = 866 // KOI8-R }; auto systemCodePage = ::GetACP(); switch (systemCodePage) @@ -131,11 +130,10 @@ namespace { customizeLogFontA((LOGFONTA *)lplf); - std::wstring s = commonsharedmem->fontFamily; + std::wstring s = maybe_disabled_fontFamily(); if (!s.empty()) { lplf->lfFaceName[s.size()] = 0; - // s->fontFamily.toWCharArray(lplf->lfFaceName); memcpy(lplf->lfFaceName, s.c_str(), s.size()); } } @@ -217,7 +215,7 @@ namespace } bool isFontCustomized() { - return commonsharedmem->fontCharSetEnabled || wcslen(commonsharedmem->fontFamily); + return commonsharedmem->fontCharSetEnabled || wcslen(maybe_disabled_fontFamily()); } DCFontSwitcher::DCFontSwitcher(HDC hdc) : hdc_(hdc), oldFont_(nullptr), newFont_(nullptr), newfontname(L"") @@ -247,18 +245,18 @@ namespace customizeLogFontW(&lf); - if (std::wstring(commonsharedmem->fontFamily).empty()) + if (std::wstring(maybe_disabled_fontFamily()).empty()) ::GetTextFaceW(hdc_, LF_FACESIZE, lf.lfFaceName); else { - wcscpy(lf.lfFaceName, commonsharedmem->fontFamily); + wcscpy(lf.lfFaceName, maybe_disabled_fontFamily()); } newFont_ = fonts_.get(lf); - if ((!newFont_) || (newfontname != std::wstring(commonsharedmem->fontFamily))) + if ((!newFont_) || (newfontname != std::wstring(maybe_disabled_fontFamily()))) { newFont_ = Hijack::oldCreateFontIndirectW(&lf); fonts_.add(newFont_, lf); - newfontname = std::wstring(commonsharedmem->fontFamily); + newfontname = std::wstring(maybe_disabled_fontFamily()); } oldFont_ = (HFONT)SelectObject(hdc_, newFont_); } @@ -275,7 +273,7 @@ HFONT WINAPI Hijack::newCreateFontIndirectA(const LOGFONTA *lplf) // DOUT("width:" << lplf->lfWidth << ", height:" << lplf->lfHeight << ", weight:" << lplf->lfWeight); // if (auto p = HijackHelper::instance()) { // auto s = p->settings(); - std::wstring fontFamily = commonsharedmem->fontFamily; + std::wstring fontFamily = maybe_disabled_fontFamily(); if (lplf && isFontCustomized()) { union @@ -340,7 +338,7 @@ HFONT WINAPI Hijack::newCreateFontA(int nHeight, int nWidth, int nEscapement, in nHeight *= s->fontScale; } */ - std::wstring fontFamily = commonsharedmem->fontFamily; + std::wstring fontFamily = maybe_disabled_fontFamily(); if (!fontFamily.empty()) { if (all_ascii(fontFamily.c_str(), fontFamily.size())) @@ -378,7 +376,7 @@ HFONT WINAPI Hijack::newCreateFontW(int nHeight, int nWidth, int nEscapement, in nWidth *= s->fontScale; nHeight *= s->fontScale; }*/ - if (!std::wstring(commonsharedmem->fontFamily).empty()) + if (!std::wstring(maybe_disabled_fontFamily()).empty()) lpszFace = (LPCWSTR)commonsharedmem; } return oldCreateFontW(CREATE_FONT_ARGS); diff --git a/cpp/LunaHook/LunaHook/hijackfuns.h b/cpp/LunaHook/LunaHook/hijackfuns.h index 4f5077d4..19492624 100644 --- a/cpp/LunaHook/LunaHook/hijackfuns.h +++ b/cpp/LunaHook/LunaHook/hijackfuns.h @@ -2,6 +2,7 @@ namespace Hijack { + inline bool Disable_Font_Switch = false; #define DEF_FUN(_fun, _return, ...) \ typedef _return(WINAPI *_fun##_fun_t)(__VA_ARGS__); \ diff --git a/cpp/LunaHook/include/const.h b/cpp/LunaHook/include/const.h index b71b0aa2..4bf26c45 100644 --- a/cpp/LunaHook/include/const.h +++ b/cpp/LunaHook/include/const.h @@ -98,6 +98,7 @@ enum HookParamType : uint64_t enum HookFontType : unsigned { DECLARE_VALUE(NOT_HOOK_FONT, 0), + NEXT_MASK(DISABLE_FONT_SWITCH), NEXT_MASK(F_CreateFontA), NEXT_MASK(F_CreateFontW), NEXT_MASK(F_CreateFontIndirectA), diff --git a/cpp/version.cmake b/cpp/version.cmake index 53fa3674..e6e81b93 100644 --- a/cpp/version.cmake +++ b/cpp/version.cmake @@ -1,6 +1,6 @@ set(VERSION_MAJOR 6) -set(VERSION_MINOR 12) +set(VERSION_MINOR 13) set(VERSION_PATCH 0) set(VERSION_REVISION 0) set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}") diff --git a/py/LunaTranslator/tts/basettsclass.py b/py/LunaTranslator/tts/basettsclass.py index f67dd11b..933cf9ad 100644 --- a/py/LunaTranslator/tts/basettsclass.py +++ b/py/LunaTranslator/tts/basettsclass.py @@ -38,6 +38,9 @@ class TTSbase: @property def voice(self): _v = self.privateconfig["voice"] + if isinstance(self.voicelist[0], tuple): + # vits的tuple在json.load后变成list了 + _v = tuple(_v) if _v not in self.voicelist: _v = self.voicelist[0] return _v