renpy2&3内嵌翻译

This commit is contained in:
恍兮惚兮 2024-02-08 21:48:24 +08:00
parent 12963a053b
commit 3682ccebe9
12 changed files with 83 additions and 36 deletions

View File

@ -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;

View File

@ -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");

View File

@ -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");
}();

View File

@ -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);
}
};

View File

@ -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))
{

View File

@ -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;
}

View File

@ -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);
}
}
}
}

View File

@ -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();

View File

@ -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
};

View File

@ -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 {};
}

View File

@ -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

View File

@ -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];
};