This commit is contained in:
恍兮惚兮 2024-03-23 20:24:03 +08:00
parent 973417b48e
commit 59fcf7d062
21 changed files with 117 additions and 61 deletions

View File

@ -4,11 +4,13 @@ import io,sys,platform,os
from ctypes import windll,wintypes
isbit64= platform.architecture()[0]=='64bit'
DLL3264path=os.path.abspath('files/plugins/DLL'+('32','64')[isbit64])
def GetDllpath(_):
def GetDllpath(_,base=None):
if base is None:
base=DLL3264path
if isinstance(_,str):
return os.path.join(DLL3264path,_)
return os.path.join(base,_)
elif isinstance(_,(list,tuple)):
return os.path.join(DLL3264path,_[isbit64])
return os.path.join(base,_[isbit64])
class debugoutput(io.IOBase):
def __init__(self,idx,file=sys.stdout) -> None:
super().__init__()

View File

@ -17,8 +17,8 @@ def sqlite2json2(self,sqlitefile,targetjson=None):
for _aret in ret:
if len(_aret)==4:
_id,source,mt,realsource=_aret
js_format2[realsource]=mt
_id,source_parsed,mt,source=_aret
js_format2[source]=mt
elif len(_aret)==3:
_id,source,mt =_aret
js_format2[source]=mt
@ -70,7 +70,6 @@ def sqlite2json2(self,sqlitefile,targetjson=None):
transkirokuuse=collect[combo.currentIndex()]
for k in js_format2:
js_format2[k]=js_format2[k].get(transkirokuuse,'')
# with open(e.text()+'.complex.json','w',encoding='utf8') as ff:
# ff.write(json.dumps(js,ensure_ascii=False,sort_keys=False, indent=4))

View File

@ -3,7 +3,7 @@ import functools,os,shutil,windows,json
from PyQt5.QtGui import QFont,QStandardItem,QStandardItemModel
from PyQt5.QtCore import Qt,QSize
from traceback import print_exc
from PyQt5.QtWidgets import QFontComboBox,QDialog,QLabel,QComboBox,QPushButton,QFileDialog,QVBoxLayout,QTableView,QHeaderView,QHBoxLayout,QLineEdit
from PyQt5.QtWidgets import QFontComboBox,QDialog,QLabel,QComboBox,QPushButton,QFileDialog,QFormLayout,QDialogButtonBox,QHeaderView,QHBoxLayout,QLineEdit
from gui.pretransfile import sqlite2json2
from gui.settingpage_ocr import getocrgrid
from myutils.config import globalconfig ,_TR,_TRL,savehook_new_data,savehook_new_list
@ -130,14 +130,14 @@ def getfridahookgrid(self) :
return grids
def doexportchspatch(exe):
def doexportchspatch(exe,realgame):
b=windows.GetBinaryType(exe)
is64=(b==6)
arch=['32','64'][is64]
dllhook=os.path.abspath('./files/plugins/LunaHook/LunaHook{}.dll'.format(arch))
dllhost=os.path.abspath('./files/plugins/DLL{}/LunaHost{}.dll'.format(arch,arch))
dllhost=os.path.abspath('./files/plugins/LunaHook/LunaHost{}.dll'.format(arch,arch))
runner=os.path.abspath('./files/plugins/shareddllproxy{}.exe'.format(arch))
windows.CopyFile(dllhook,os.path.join(os.path.dirname(exe),os.path.basename(dllhook)),False)
@ -147,10 +147,10 @@ def doexportchspatch(exe):
embedconfig={
'translation_file':'translation.json',
'target_exe':os.path.basename(exe),
'target_exe2':os.path.basename(realgame),
'startup_argument':None,
'isbit64':is64,
'inject_timeout':1000,
'embedhook':savehook_new_data[exe]['embedablehook'],
'embedhook':savehook_new_data[realgame]['embedablehook'],
'embedsettings':{
'font':globalconfig['embedded']['changefont_font'] if globalconfig['embedded']['changefont'] else '',
'insertspace_policy':globalconfig['embedded']['insertspace_policy'],
@ -159,18 +159,49 @@ def doexportchspatch(exe):
}
with open(os.path.join(os.path.dirname(exe),'LunaPatch.json'),'w',encoding='utf8') as ff:
ff.write(json.dumps(embedconfig,ensure_ascii=False,indent=4))
def getunknowgameexe(self):
dialog = QDialog(self,Qt.WindowCloseButtonHint) # 自定义一个dialog
dialog.setWindowTitle(_TR("选择游戏"))
dialog.resize(QSize(800,10))
formLayout = QFormLayout(dialog)
dialog.setLayout(formLayout)
combo=QComboBox()
combo.addItems([savehook_new_data[_]['title'] for _ in savehook_new_list])
formLayout.addRow(_TR("选择游戏"),combo)
button = QDialogButtonBox(QDialogButtonBox.Ok|QDialogButtonBox.Cancel)
formLayout.addRow(button)
button.rejected.connect(dialog.close)
button.accepted.connect(dialog.accept)
button.button(QDialogButtonBox.Ok).setText(_TR('确定'))
button.button(QDialogButtonBox.Cancel).setText(_TR('取消'))
if(dialog.exec()):
return savehook_new_list[combo.currentIndex()]
def exportchspatch(self):
f=QFileDialog.getOpenFileName(filter='*.exe')
exe=f[0]
if exe=='':return
exe=exe.replace('/','\\')
if exe not in savehook_new_list:return
doexportchspatch(exe)
realgame=getunknowgameexe(self)
if realgame is None:return
exe=realgame
if exe.lower().endswith('.exe')==False:
f=QFileDialog.getOpenFileName(self,caption= _TR("选择EXE文件"),filter='*.exe')
exe=f[0]
if exe=='':return
exe=exe.replace('/','\\')
doexportchspatch(exe,realgame)
md5=getfilemd5(exe)
name= os.path.basename(exe).replace('.'+os.path.basename(exe).split('.')[-1],'')
sqlfname_all='./translation_record/'+name+'_'+md5+'.sqlite'
sqlite2json2(self,sqlfname_all,os.path.join(os.path.dirname(exe),'translation.json'))
if os.path.exists(sqlfname_all)==False:
f=QFileDialog.getOpenFileName(self,caption=_TR("选择预翻译文件"), directory='./translation_record/',filter='*.sqlite')
sqlfname_all=f[0]
if os.path.exists(sqlfname_all):
sqlite2json2(self,sqlfname_all,os.path.join(os.path.dirname(exe),'translation.json'))
else:
with open(os.path.join(os.path.dirname(exe),'translation.json'),'w') as ff:
ff.write("{}")
def gethookembedgrid(self) :
self.gamefont_comboBox = QFontComboBox( )
def callback(x):

View File

@ -106,7 +106,7 @@ class texthook(basetext ):
self.declare()
self.start()
def declare(self):
LunaHost=CDLL(gobject.GetDllpath(('LunaHost32.dll','LunaHost64.dll')))
LunaHost=CDLL(gobject.GetDllpath(('LunaHost32.dll','LunaHost64.dll'),os.path.abspath('files/plugins/LunaHook')))
self.Luna_Settings=LunaHost.Luna_Settings
self.Luna_Settings.argtypes=c_int,c_bool,c_int,c_int
self.Luna_Start=LunaHost.Luna_Start

View File

@ -308,6 +308,8 @@
"./files/plugins/shareddllproxy64.exe",
"./files/plugins/LunaHook/LunaHook32.dll",
"./files/plugins/LunaHook/LunaHook64.dll",
"./files/plugins/LunaHook/LunaHost64.dll",
"./files/plugins/LunaHook/LunaHost32.dll",
"./files/plugins/LoaderDll.dll",
"./files/plugins/LocaleEmulator.dll",
"./files/plugins/hookmagpie.dll"
@ -317,16 +319,14 @@
"./files/plugins/DLL64/winrtutils64.dll",
"./files/plugins/DLL64/LunaOCR64.dll",
"./files/plugins/DLL64/libmecab.dll",
"./files/plugins/DLL64/libcurl-x64.dll",
"./files/plugins/DLL64/LunaHost64.dll"
"./files/plugins/DLL64/libcurl-x64.dll"
],
"32":[
"./files/plugins/DLL32/winsharedutils32.dll",
"./files/plugins/DLL32/winrtutils32.dll",
"./files/plugins/DLL32/LunaOCR32.dll",
"./files/plugins/DLL32/libmecab.dll",
"./files/plugins/DLL32/libcurl.dll",
"./files/plugins/DLL32/LunaHost32.dll"
"./files/plugins/DLL32/libcurl.dll"
]
}

View File

@ -720,5 +720,7 @@
"离线": "غير متصل",
"导出翻译补丁": "تصدير ترجمة التصحيح",
"语音修正": "صوت تصحيح",
"藏语": "التيبتية"
"藏语": "التيبتية",
"选择EXE文件": "حدد ملف إكس",
"选择预翻译文件": "حدد ملف ما قبل الترجمة"
}

View File

@ -720,5 +720,7 @@
"离线": "離線",
"导出翻译补丁": "匯出翻譯補丁",
"语音修正": "語音修正",
"藏语": "藏語"
"藏语": "藏語",
"选择EXE文件": "選擇EXE檔案",
"选择预翻译文件": "選擇預翻譯檔案"
}

View File

@ -720,5 +720,7 @@
"离线": "off-line",
"导出翻译补丁": "Export translation patches",
"语音修正": "Voice correction",
"藏语": "Tibetan"
"藏语": "Tibetan",
"选择EXE文件": "Select EXE file",
"选择预翻译文件": "Select pre translated file"
}

View File

@ -720,5 +720,7 @@
"离线": "Fuera de línea",
"导出翻译补丁": "Exportar parches de traducción",
"语音修正": "Corrección de voz",
"藏语": "Tibetano"
"藏语": "Tibetano",
"选择EXE文件": "Seleccionar archivo EXE",
"选择预翻译文件": "Seleccionar archivo pretranslatado"
}

View File

@ -720,5 +720,7 @@
"离线": "Hors ligne",
"导出翻译补丁": "Exporter le patch de traduction",
"语音修正": "Correction vocale",
"藏语": "Tibétain"
"藏语": "Tibétain",
"选择EXE文件": "Sélectionner un fichier exe",
"选择预翻译文件": "Choisir un fichier pré - traduit"
}

View File

@ -720,5 +720,7 @@
"离线": "off-line",
"导出翻译补丁": "Esporta patch di traduzione",
"语音修正": "Correzione vocale",
"藏语": "Tibetano"
"藏语": "Tibetano",
"选择EXE文件": "Seleziona file EXE",
"选择预翻译文件": "Seleziona file pre-tradotto"
}

View File

@ -720,5 +720,7 @@
"离线": "オフライン",
"导出翻译补丁": "翻訳パッチのエクスポート",
"语音修正": "音声修正",
"藏语": "チベット語"
"藏语": "チベット語",
"选择EXE文件": "EXEファイルを選択",
"选择预翻译文件": "事前翻訳ファイルの選択"
}

View File

@ -720,5 +720,7 @@
"离线": null,
"导出翻译补丁": "번역 패치 내보내기",
"语音修正": "음성 수정",
"藏语": "티베트어"
"藏语": "티베트어",
"选择EXE文件": "EXE 파일 선택",
"选择预翻译文件": "사전 번역 파일 선택"
}

View File

@ -720,5 +720,7 @@
"离线": "off-line",
"导出翻译补丁": "Eksportuj łatki tłumaczeniowe",
"语音修正": "Korekta głosu",
"藏语": "Tybetański"
"藏语": "Tybetański",
"选择EXE文件": "Wybierz plik EXE",
"选择预翻译文件": "Wybierz wstępnie przetłumaczony plik"
}

View File

@ -720,5 +720,7 @@
"离线": "В автономном режиме",
"导出翻译补丁": "Экспорт исправлений перевода",
"语音修正": "Голосовая коррекция",
"藏语": "Тибетский язык"
"藏语": "Тибетский язык",
"选择EXE文件": "Выберите файл EXE",
"选择预翻译文件": "Выберите файл для предварительного перевода"
}

View File

@ -720,5 +720,7 @@
"离线": "ออฟไลน์",
"导出翻译补丁": "ส่งออกแพทช์การแปล",
"语音修正": "แก้ไขเสียง",
"藏语": "ทิเบต"
"藏语": "ทิเบต",
"选择EXE文件": "เลือกไฟล์ EXE",
"选择预翻译文件": "เลือกไฟล์ที่แปลไว้ล่วงหน้า"
}

View File

@ -720,5 +720,7 @@
"离线": "off line",
"导出翻译补丁": "Çeviri örneklerini dışarı aktar",
"语音修正": "Ses düzeltmesi",
"藏语": "TibetanKCharselect unicode block name"
"藏语": "TibetanKCharselect unicode block name",
"选择EXE文件": "Select EXE file",
"选择预翻译文件": "Önceden çevirilen dosya seçin"
}

View File

@ -720,5 +720,7 @@
"离线": "вимкнено",
"导出翻译补丁": "Експортувати латки перекладу",
"语音修正": "Виправлення голосу",
"藏语": "Тибетський"
"藏语": "Тибетський",
"选择EXE文件": "Виберіть файл EXE",
"选择预翻译文件": "Виберіть попередньо перекладаний файл"
}

View File

@ -720,5 +720,7 @@
"离线": "Ngoại tuyến",
"导出翻译补丁": "Xuất bản bản vá dịch",
"语音修正": "Sửa giọng nói",
"藏语": "Tây Tạng"
"藏语": "Tây Tạng",
"选择EXE文件": "Chọn tập tin EXE",
"选择预翻译文件": "Chọn tập tin pre-translate"
}

View File

@ -720,5 +720,7 @@
"离线": "",
"导出翻译补丁": "",
"语音修正": "",
"藏语": ""
"藏语": "",
"选择EXE文件": "",
"选择预翻译文件": ""
}

View File

@ -105,7 +105,6 @@ class lunapatch{
public:
HANDLE hMessage;
HANDLE hwait;
std::wstring target_exe;
nlohmann::json config;
std::map<std::string,std::string>translation;
std::unordered_set<DWORD>connectedpids;
@ -116,6 +115,7 @@ public:
bool (*Luna_checkisusingembed)(DWORD pid,uint64_t address,uint64_t ctx1,uint64_t ctx2);
void (*Luna_embedcallback)(DWORD pid,LPCWSTR text,LPCWSTR trans);
std::set<std::string>notranslation;
HANDLE hsema;
lunapatch(std::wstring dll,nlohmann::json&&_translation,nlohmann::json&&_config):translation(_translation),config(_config){
auto LunaHost=LoadLibraryW(dll.c_str());
@ -125,13 +125,12 @@ public:
Luna_useembed=(decltype(Luna_useembed))GetProcAddress(LunaHost,"Luna_useembed");
Luna_checkisusingembed=(decltype(Luna_checkisusingembed))GetProcAddress(LunaHost,"Luna_checkisusingembed");
Luna_embedcallback=(decltype(Luna_embedcallback))GetProcAddress(LunaHost,"Luna_embedcallback");
hsema=CreateSemaphore(NULL,0,100,NULL);
Luna_Start(&hMessage);
std::thread([&](){Parsehostmessage();}).detach();
}
void run(){
target_exe=StringToWideString(config["target_exe"]);
auto target_exe=StringToWideString(config["target_exe"]);
auto _startup_argument=config["startup_argument"];
@ -147,29 +146,29 @@ public:
for(auto &text:notranslation){
translation[text]="";
}
auto notrs=nlohmann::json(notranslation).dump(4);
auto notrs=nlohmann::json(translation).dump(4);
std::ofstream of;
of.open("no_translation.json");
of<<notrs;
of.close();
notrs=nlohmann::json(translation).dump(4);
of.open("no_translation_and_translation.json");
of.open(std::string(config["translation_file"]));
of<<notrs;
of.close();
}
}
void wait(){
WaitForSingleObject(hwait,INFINITE);
while(connectedpids.size())
WaitForSingleObject(hsema,INFINITE);
}
void inject(){
//chrome has multi process
Sleep(config["inject_timeout"]);
auto pids=EnumerateProcesses(target_exe);
for(auto pid:pids){
Luna_Inject(pid,L"");
for(auto exe :std::set<std::string>{config["target_exe"],config["target_exe2"]})
{
auto pids=EnumerateProcesses(StringToWideString(exe));
for(auto pid:pids){
wprintf(L"%d\n",pid);
Luna_Inject(pid,L"");
}
}
}
std::wstring findtranslation(const std::wstring& text){
auto utf8text=WideStringToString(text);
@ -200,6 +199,7 @@ public:
case 1:
{
connectedpids.erase(message.pid);
ReleaseSemaphore(hsema,1,NULL);
}
break;
case 7:
@ -272,18 +272,12 @@ bool checkisapatch(){
std::string translation_file=configjson["translation_file"];
jsonfile.open(translation_file);
std::map<std::string,std::string> translation=nlohmann::json::parse(jsonfile);
jsonfile.close();
bool isbit64=configjson["isbit64"];
auto bitappendix=isbit64?L"64":L"32";
auto LunaHost=(curr/(std::wstring(L"LunaHost")+bitappendix)).wstring();
auto LunaHook=(curr/(std::wstring(L"LunaHook")+bitappendix)).wstring();
auto LunaHost=(curr/(std::wstring(L"LunaHost")+std::to_wstring(8*sizeof(void*)))).wstring();
lunapatch _lunapatch(LunaHost,std::move(translation),std::move(configjson));
_lunapatch.run();
_lunapatch.inject();
_lunapatch.wait();