#include"IGScript.h" namespace{ bool LucaSystemFilter1(LPVOID data, size_t *size, HookParam *) { auto text = reinterpret_cast(data); auto len = reinterpret_cast(size); StringFilter(text, len, "\x81\x94", 2); //秋&冬 官中 StringReplacer(text, len, "\x82\xa1", 2,"\xa3\xac",2);//, StringReplacer(text, len, "\x82\xa3", 2,"\xa1\xa3",2);//。 StringReplacer(text, len, "\x82\xa5", 2,"\xa1\xa2",2);//、 StringReplacer(text, len, "\x83\x48", 2,"\xa1\xb1",2);//” StringReplacer(text, len, "\x83\x44", 2,"\xa3\xbf",2);//? StringReplacer(text, len, "\x83\x42", 2,"\xa3\xa1",2);//! StringReplacer(text, len, "\x82\xa7", 2,"\xa1\xb9",2);//」 StringReplacer(text, len, "\x82\xc1", 2,"\xa1\xb7",2);//》 StringReplacer(text, len, "\x83\x46", 2,"\xa1\xaf",2);//’ return true; } template void SpecialHookigi(hook_stack* stack, HookParam *hp, uintptr_t *data, uintptr_t *split, size_t*len){ DWORD Src = stack->stack[arg]; DWORD Size = stack->stack[arg+1]; if(strlen((char*)Src)<=2)return; if(strlen((char*)Src)>=Size)return; if(strlen((char*)Src); hp.type=NO_CONTEXT; //hp.filter_fun=LucaSystemFilter1; bool succ=NewHook(hp, "IGScript"); if(insertgbk){ hp.address +=5; hp.text_fun=SpecialHookigi<5>; //仅官中适用这个过滤器。日语原版不需要过滤 hp.filter_fun=LucaSystemFilter1; succ|=NewHook(hp, "IGScript_1"); } return succ; } namespace{ bool LucaSystemFilter(LPVOID data, size_t *size, HookParam *) { auto text = reinterpret_cast(data); auto len = reinterpret_cast(size); if ( text[0] == '\x81' && text[1] == '\x94') return false; StringCharReplacer(text, len, "\x81\x90", 2, ' '); // new line //replacement from Flowers 4 config.json CharReplacer(text, len, '\xA5', ' '); CharReplacer(text, len, '\xA2', '<'); CharReplacer(text, len, '\xA3', '>'); CharReplacer(text, len, '\xA1', '\"'); CharReplacer(text, len, '\xA4', '\''); CharReplacer(text, len, '\xA7', 'à'); CharReplacer(text, len, '\xA8', 'è'); CharReplacer(text, len, '\xA9', 'é'); CharReplacer(text, len, '\xAA', 'ë'); CharReplacer(text, len, '\xAB', 'ō'); CharReplacer(text, len, '\xB0', '-'); CharReplacer(text, len, '\xBB', ' '); while(cpp_strnstr(text, " ", *len)) // Erasing all but one whitespace from strings StringCharReplacer(text, len, " ", 2, ' '); if (text[0] == ' ') ::memmove(text, text + 1, --*len); return true; } bool InsertLucaSystemHook() { /* * Sample games: * https://vndb.org/v15395 * https://vndb.org/v14267 * https://vndb.org/v18152 * https://vndb.org/r82704 */ const BYTE bytes[] = { 0xCC, // int 3 0xE9, XX4, // jmp d3d9.dll+1E420 0x56, // push esi 0x57, // push edi 0x8B, 0x7C, 0x24, 0x20, // mov edi,[esp+20] 0x8B, 0xD8, // mov ebx,eax 0x8B, 0x07 // mov eax,[edi] }; const BYTE bytes2[] = { 0xCC, // int 3 0x83, 0xEC, 0x0C, // sub esp,0C <- hook here 0x53, // push ebx 0x55, // push ebp 0x56 // push esi }; HMODULE module = GetModuleHandleW(L"Script.dll"); auto [minAddress, maxAddress] = Util::QueryModuleLimits(module); ULONG addr = MemDbg::findBytes(bytes, sizeof(bytes), minAddress, maxAddress); if (!addr) { addr = MemDbg::findBytes(bytes2, sizeof(bytes2), minAddress, maxAddress); if (!addr) { ConsoleOutput("LucaSystem: pattern not found"); return false; } } HookParam hp; hp.address = addr + 1; hp.offset =get_stack(1); hp.padding = 0x04; hp.type = USING_STRING; hp.filter_fun = LucaSystemFilter; return NewHook(hp, "LucaSystem"); } } bool IGScript::attach_function() { auto b1= IGScript1attach_function(); b1=InsertLucaSystemHook()||b1; return b1; }