mirror of
https://github.com/HIllya51/LunaHook.git
synced 2024-12-24 04:04:14 +08:00
renpy2&3内嵌翻译
This commit is contained in:
parent
12963a053b
commit
3682ccebe9
@ -8,14 +8,10 @@
|
||||
#include"defs.h"
|
||||
DynamicShiftJISCodec *dynamiccodec=new DynamicShiftJISCodec(932);
|
||||
|
||||
std::wstring cast_a2w(HookParam hp,void*data ,size_t len){
|
||||
if(hp.type&CODEC_UTF16)
|
||||
return std::wstring((wchar_t*)(data),len/2);
|
||||
return StringToWideString(std::string((char*)data,len),hp.codepage?hp.codepage:embedsharedmem->codepage).value();
|
||||
}
|
||||
|
||||
void cast_back(HookParam hp,void*data ,size_t *len,std::wstring trans,bool normal){
|
||||
if(hp.type&CODEC_UTF16){
|
||||
void cast_back(const HookParam& hp,void*data ,size_t *len,const std::wstring& trans,bool normal){
|
||||
|
||||
if((hp.type&EMBED_CODEC_UTF16)||(hp.type&CODEC_UTF16)){//renpy
|
||||
wcscpy((wchar_t*)data,trans.c_str());
|
||||
*len=trans.size()*2;
|
||||
}
|
||||
@ -25,8 +21,7 @@ void cast_back(HookParam hp,void*data ,size_t *len,std::wstring trans,bool norma
|
||||
astr=dynamiccodec->encodeSTD(trans,0);
|
||||
}
|
||||
else{
|
||||
astr=WideStringToString(trans,hp.codepage?hp.codepage:embedsharedmem->codepage);
|
||||
|
||||
astr=WideStringToString(trans,hp.codepage?hp.codepage:((hp.type&CODEC_UTF8)?CP_UTF8:embedsharedmem->codepage));
|
||||
}
|
||||
strcpy((char*)data,astr.c_str());
|
||||
*len=astr.size();
|
||||
@ -207,11 +202,14 @@ bool waitforevent(UINT32 timems,const ThreadParam& tp,const std::wstring &origin
|
||||
return false;
|
||||
}
|
||||
bool TextHook::waitfornotify(TextOutput_T* buffer,void*data ,size_t*len,ThreadParam tp){
|
||||
|
||||
auto origin=cast_a2w(hp,data,*len);
|
||||
std::wstring origin;
|
||||
if (auto t=commonparsestring(data,*len,&hp,embedsharedmem->codepage)) origin=t.value();
|
||||
else return false;
|
||||
if(origin.size()>1000)return false;
|
||||
if(hp.newlineseperator)strReplace(origin,hp.newlineseperator,L"\n");
|
||||
cast_back(hp,data,len,origin,true);
|
||||
if(hp.newlineseperator){
|
||||
strReplace(origin,hp.newlineseperator,L"\n");
|
||||
cast_back(hp,data,len,origin,true);
|
||||
}
|
||||
TextOutput(tp, buffer, *len);
|
||||
|
||||
std::wstring translate;
|
||||
|
@ -215,8 +215,7 @@ bool InsertCatSystem2Hook()
|
||||
HookParam hp;
|
||||
hp.address = addr;
|
||||
hp.offset=get_reg(regs::eax);
|
||||
hp.codepage = 65001;
|
||||
hp.type = USING_STRING;
|
||||
hp.type = USING_STRING|CODEC_UTF8;
|
||||
ConsoleOutput("INSERT CatSystem2new");
|
||||
|
||||
return NewHook(hp, "CatSystem2new");
|
||||
|
@ -53,6 +53,12 @@ namespace {
|
||||
auto fmtcnt = PyUnicode_GET_SIZE(uformat);
|
||||
return {fmt,fmtcnt};
|
||||
}
|
||||
|
||||
typedef PyObject* (*PyUnicode_FromUnicode_t)(
|
||||
const Py_UNICODE *u, /* Unicode buffer */
|
||||
Py_ssize_t size /* size of buffer */
|
||||
);
|
||||
PyUnicode_FromUnicode_t PyUnicode_FromUnicode;
|
||||
}
|
||||
|
||||
bool InsertRenpyHook(){
|
||||
@ -66,11 +72,26 @@ bool InsertRenpyHook(){
|
||||
if (HMODULE module = GetModuleHandleW(name))
|
||||
{
|
||||
PyUnicode_FromObject=(PyUnicode_FromObject_t)GetProcAddress(module, "PyUnicodeUCS2_FromObject");
|
||||
PyUnicode_FromUnicode=(PyUnicode_FromUnicode_t)GetProcAddress(module, "PyUnicodeUCS2_FromUnicode");
|
||||
auto f1=[=](){
|
||||
HookParam hp;
|
||||
hp.address = (uintptr_t)GetProcAddress(module, "PyUnicodeUCS2_Format");
|
||||
if (!hp.address) return false;
|
||||
|
||||
hp.hook_after=[](hook_stack* stack,void* data, size_t len)
|
||||
{
|
||||
#ifndef _WIN64
|
||||
auto format=(PyObject *)stack->stack[1];
|
||||
#else
|
||||
auto format=(PyObject *)stack->rcx;
|
||||
#endif
|
||||
if(format==NULL)return;
|
||||
#ifndef _WIN64
|
||||
stack->stack[1]=
|
||||
#else
|
||||
stack->rcx=
|
||||
#endif
|
||||
(uintptr_t)PyUnicode_FromUnicode((Py_UNICODE *)data,len/2);
|
||||
};
|
||||
hp.text_fun = [](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len)
|
||||
{
|
||||
#ifndef _WIN64
|
||||
@ -87,6 +108,8 @@ bool InsertRenpyHook(){
|
||||
|
||||
};
|
||||
hp.type = USING_STRING | CODEC_UTF16 | NO_CONTEXT;
|
||||
if(PyUnicode_FromUnicode)
|
||||
hp.type|=EMBED_ABLE|EMBED_BEFORE_SIMPLE;
|
||||
return NewHook(hp, "Ren'py");
|
||||
}();
|
||||
|
||||
|
@ -104,7 +104,12 @@ enum PyUnicode_Kind {
|
||||
) \
|
||||
))
|
||||
|
||||
|
||||
typedef PyObject* (*PyUnicode_FromString_t)(const char *u);
|
||||
PyUnicode_FromString_t PyUnicode_FromString;
|
||||
typedef PyObject* (*PyUnicode_FromKindAndData_t)(int kind,
|
||||
const void *buffer,
|
||||
Py_ssize_t size);
|
||||
PyUnicode_FromKindAndData_t PyUnicode_FromKindAndData;
|
||||
}
|
||||
#ifdef _WIN64
|
||||
|
||||
@ -123,7 +128,20 @@ bool InsertRenpy3Hook()
|
||||
uintptr_t addr = (uintptr_t)GetProcAddress(module, "PyUnicode_Format");
|
||||
if (addr) {
|
||||
HookParam hp;
|
||||
PyUnicode_FromString=(PyUnicode_FromString_t)GetProcAddress(module, "PyUnicode_FromString");
|
||||
PyUnicode_FromKindAndData=(PyUnicode_FromKindAndData_t)GetProcAddress(module, "PyUnicode_FromKindAndData");
|
||||
hp.address = addr;
|
||||
if(PyUnicode_FromKindAndData)
|
||||
{
|
||||
hp.type=EMBED_ABLE|EMBED_BEFORE_SIMPLE|EMBED_CODEC_UTF16;
|
||||
hp.hook_after=[](hook_stack* stack,void* data, size_t len)
|
||||
{
|
||||
auto format=(PyObject *)stack->rcx;
|
||||
if (format == NULL )
|
||||
return;
|
||||
stack->rcx=(uintptr_t)PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND,data,len/2);
|
||||
};
|
||||
}
|
||||
hp.text_fun = [](hook_stack* stack, HookParam* hp, uintptr_t* data, uintptr_t* split, size_t* len)
|
||||
{
|
||||
auto format=(PyObject *)stack->rcx;
|
||||
@ -141,19 +159,21 @@ bool InsertRenpy3Hook()
|
||||
}
|
||||
|
||||
*data=(uintptr_t)fmtdata;
|
||||
if(PyUnicode_FromString)
|
||||
hp->type=EMBED_ABLE|EMBED_BEFORE_SIMPLE|EMBED_CODEC_UTF16;
|
||||
switch (fmtkind)
|
||||
{
|
||||
case PyUnicode_WCHAR_KIND:
|
||||
case PyUnicode_2BYTE_KIND:
|
||||
hp->type=CODEC_UTF16|USING_STRING|NO_CONTEXT;
|
||||
hp->type|=CODEC_UTF16|USING_STRING|NO_CONTEXT;
|
||||
*len=fmtcnt*sizeof(Py_UCS2);
|
||||
break;
|
||||
case PyUnicode_1BYTE_KIND:
|
||||
hp->type=CODEC_UTF8|USING_STRING|NO_CONTEXT;
|
||||
hp->type|=CODEC_UTF8|USING_STRING|NO_CONTEXT;
|
||||
*len=fmtcnt*sizeof(Py_UCS1);
|
||||
break;
|
||||
case PyUnicode_4BYTE_KIND://Py_UCS4,utf32
|
||||
hp->type=CODEC_UTF32|USING_STRING|NO_CONTEXT;
|
||||
hp->type|=CODEC_UTF32|USING_STRING|NO_CONTEXT;
|
||||
*len=fmtcnt*sizeof(Py_UCS4);
|
||||
}
|
||||
};
|
||||
|
@ -172,7 +172,6 @@ bool NewHook(HookParam hp, LPCSTR lpname)
|
||||
ConsoleOutput(INSERTING_HOOK, hp.name);
|
||||
RemoveHook(hp.address, 0);
|
||||
|
||||
if (hp.type & CODEC_UTF8) hp.codepage = CP_UTF8;
|
||||
wcscpy_s(hp.hookcode,HOOKCODE_LEN,HookCode::Generate(hp, GetCurrentProcessId()).c_str());
|
||||
if (!(*hooks)[currentHook].Insert(hp))
|
||||
{
|
||||
|
@ -99,7 +99,6 @@ bool TextHook::Insert(HookParam hp)
|
||||
local_buffer=new BYTE[PIPE_BUFFER_SIZE];
|
||||
{
|
||||
std::scoped_lock lock(viewMutex);
|
||||
if (hp.type & CODEC_UTF8) hp.codepage = CP_UTF8;
|
||||
this->hp = hp;
|
||||
address = hp.address;
|
||||
}
|
||||
|
@ -175,14 +175,12 @@ namespace
|
||||
if(embedcallback){
|
||||
auto & hp=thread->second.hp;
|
||||
if(hp.type&EMBED_ABLE){
|
||||
std::wstring text;
|
||||
if (hp.type & CODEC_UTF16)text=(std::wstring((wchar_t*)data->data, length / sizeof(wchar_t)));
|
||||
else if (auto converted = StringToWideString(std::string((char*)data->data, length), hp.codepage ? hp.codepage : Host::defaultCodepage))text=(converted.value());
|
||||
else text=L"";
|
||||
if(text.size()){
|
||||
embedcallback(text,tp);
|
||||
}
|
||||
|
||||
if (auto t=commonparsestring(data->data,length,&hp,Host::defaultCodepage)){
|
||||
auto text=t.value();
|
||||
if(text.size()){
|
||||
embedcallback(text,tp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -58,9 +58,7 @@ void TextThread::Push(BYTE* data, int length)
|
||||
}
|
||||
|
||||
if (hp.type & HEX_DUMP) for (int i = 0; i < length; i += sizeof(short)) buffer.append(FormatString(L"%04hX ", *(short*)(data + i)));
|
||||
else if (hp.type & CODEC_UTF16) buffer.append((wchar_t*)data, length / sizeof(wchar_t));
|
||||
else if(hp.type&CODEC_UTF32)buffer.append(std::move(utf32_to_utf16(data,length)));
|
||||
else if (auto converted = StringToWideString(std::string((char*)data, length), hp.codepage ? hp.codepage : Host::defaultCodepage)) buffer.append(converted.value());
|
||||
else if (auto converted = commonparsestring(data,length,&hp,Host::defaultCodepage)) buffer.append(converted.value());
|
||||
else Host::AddConsoleOutput(INVALID_CODEPAGE);
|
||||
if (hp.type & FULL_STRING) buffer.push_back(L'\n');
|
||||
lastPushTime = GetTickCount64();
|
||||
|
@ -26,7 +26,7 @@ enum HostNotificationType {
|
||||
HOST_SETTEXTTHREADTYPE
|
||||
};
|
||||
|
||||
enum HookParamType : unsigned
|
||||
enum HookParamType : uint64_t
|
||||
{
|
||||
//默认为CODEC_ANSI_LE&USING_CHAR
|
||||
//若使用了text_fun|hook_before,会改为默认USING_STRING,这时若其实是USING_CHAR,需标明USING_STRING
|
||||
@ -56,6 +56,7 @@ enum HookParamType : unsigned
|
||||
EMBED_BEFORE_SIMPLE=0x200000,
|
||||
EMBED_AFTER_NEW=0x400000,
|
||||
EMBED_AFTER_OVERWRITE=0x800000,
|
||||
EMBED_CODEC_UTF16=0x4000000
|
||||
};
|
||||
|
||||
|
||||
|
@ -170,3 +170,13 @@ size_t u32strlen(uint32_t* data){
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
|
||||
#include"const.h"
|
||||
#include"types.h"
|
||||
std::optional<std::wstring> commonparsestring(void* data,size_t length,void* php,DWORD df){
|
||||
auto hp=(HookParam*)php;
|
||||
if (hp->type & CODEC_UTF16) return std::wstring((wchar_t*)data, length / sizeof(wchar_t));
|
||||
else if(hp->type&CODEC_UTF32)return (std::move(utf32_to_utf16(data,length)));
|
||||
else if (auto converted = StringToWideString(std::string((char*)data, length), hp->codepage ? hp->codepage : ((hp->type&CODEC_UTF8)?CP_UTF8:df))) return (converted.value());
|
||||
else return {};
|
||||
}
|
@ -57,5 +57,7 @@ inline std::wstring FormatString(const wchar_t* format, const Args&... args)
|
||||
_swprintf(buffer.data(), format, FormatArg(args)...);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
std::optional<std::wstring> commonparsestring(void*,size_t,void*,DWORD);
|
||||
#pragma warning(pop)
|
||||
#endif
|
@ -80,7 +80,7 @@ struct HookParam
|
||||
wchar_t module[MAX_MODULE_SIZE];
|
||||
|
||||
char function[MAX_MODULE_SIZE];
|
||||
DWORD type; // flags
|
||||
uint64_t type; // flags
|
||||
UINT codepage; // text encoding
|
||||
short length_offset; // index of the string length
|
||||
ALIGNPTR(uint64_t __1,uintptr_t padding); // padding before string
|
||||
@ -184,6 +184,6 @@ struct HookInsertingNotif // From dll
|
||||
struct TextOutput_T
|
||||
{
|
||||
ThreadParam tp;
|
||||
DWORD type;
|
||||
uint64_t type;
|
||||
BYTE data[0];
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user