mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-27 15:44:12 +08:00
fix
This commit is contained in:
parent
0c40cdc6dd
commit
38be8e7ff6
@ -7,7 +7,7 @@ from myutils.config import (
|
||||
_TR,
|
||||
savehook_new_list,
|
||||
uid2gamepath,
|
||||
gamepath2uid,
|
||||
findgameuidofpath,
|
||||
savehook_new_data,
|
||||
setlanguage,
|
||||
static_data,
|
||||
@ -20,7 +20,6 @@ from myutils.utils import (
|
||||
kanjitrans,
|
||||
checkifnewgame,
|
||||
checkpostusing,
|
||||
getpostfile,
|
||||
stringfyerror,
|
||||
)
|
||||
from myutils.wrapper import threader
|
||||
@ -43,7 +42,7 @@ from gui.attachprocessdialog import AttachProcessDialog
|
||||
import windows
|
||||
import gobject
|
||||
import winsharedutils
|
||||
from winsharedutils import pid_running
|
||||
from winsharedutils import collect_running_pids
|
||||
from myutils.post import POSTSOLVE
|
||||
from myutils.utils import nowisdark
|
||||
|
||||
@ -105,9 +104,11 @@ class MAINUI:
|
||||
for item in static_data["transoptimi"]:
|
||||
name = item["name"]
|
||||
try:
|
||||
mm = getpostfile(name)
|
||||
if not mm:
|
||||
checkpath = "./LunaTranslator/transoptimi/" + name + ".py"
|
||||
if os.path.exists(checkpath) == False:
|
||||
continue
|
||||
mm = "transoptimi." + name
|
||||
|
||||
Process = importlib.import_module(mm).Process
|
||||
|
||||
def __(kls, _name):
|
||||
@ -475,12 +476,17 @@ class MAINUI:
|
||||
use, self.settin_ui.voicelistsignal, self.settin_ui.mp3playsignal
|
||||
)
|
||||
|
||||
def selectprocess(self, selectedp):
|
||||
def selectprocess(self, selectedp, title):
|
||||
self.textsource = None
|
||||
pids, pexe, hwnd = selectedp
|
||||
checkifnewgame(savehook_new_list, pexe, windows.GetWindowText(hwnd))
|
||||
if len(collect_running_pids(pids)) == 0:
|
||||
return
|
||||
if not title:
|
||||
title = windows.GetWindowText(hwnd)
|
||||
checkifnewgame(savehook_new_list, pexe, title)
|
||||
if globalconfig["sourcestatus2"]["texthook"]["use"]:
|
||||
self.textsource = texthook(pids, hwnd, pexe, gamepath2uid[pexe])
|
||||
gameuid = findgameuidofpath(pexe, savehook_new_list)
|
||||
self.textsource = texthook(pids, hwnd, pexe, gameuid)
|
||||
self.textsource.start()
|
||||
|
||||
def starttextsource(self, use=None, checked=True):
|
||||
@ -563,16 +569,9 @@ class MAINUI:
|
||||
|
||||
def fanyiinitmethod(self, classname):
|
||||
try:
|
||||
if classname == "selfbuild":
|
||||
if not os.path.exists("./userconfig/selfbuild.py"):
|
||||
return None
|
||||
aclass = importlib.import_module("selfbuild").TS
|
||||
else:
|
||||
if not os.path.exists(
|
||||
"./LunaTranslator/translator/" + classname + ".py"
|
||||
):
|
||||
return None
|
||||
aclass = importlib.import_module("translator." + classname).TS
|
||||
if not os.path.exists("./LunaTranslator/translator/" + classname + ".py"):
|
||||
return None
|
||||
aclass = importlib.import_module("translator." + classname).TS
|
||||
except Exception as e:
|
||||
print_exc()
|
||||
self.textgetmethod(
|
||||
@ -676,109 +675,101 @@ class MAINUI:
|
||||
except:
|
||||
print_exc()
|
||||
|
||||
def onwindowloadautohook(self):
|
||||
textsourceusing = globalconfig["sourcestatus2"]["texthook"]["use"]
|
||||
if not (globalconfig["autostarthook"] and textsourceusing):
|
||||
return
|
||||
elif self.AttachProcessDialog and self.AttachProcessDialog.isVisible():
|
||||
return
|
||||
else:
|
||||
try:
|
||||
if self.textsource is None:
|
||||
hwnd = windows.GetForegroundWindow()
|
||||
pid = windows.GetWindowThreadProcessId(hwnd)
|
||||
name_ = getpidexe(pid)
|
||||
if (
|
||||
name_
|
||||
and name_ in gamepath2uid
|
||||
and gamepath2uid[name_] in savehook_new_list
|
||||
):
|
||||
lps = ListProcess(False)
|
||||
for pids, _exe in lps:
|
||||
if _exe == name_:
|
||||
|
||||
# if any(map(testprivilege,pids)):
|
||||
self.textsource = None
|
||||
if globalconfig["sourcestatus2"]["texthook"]["use"]:
|
||||
if globalconfig["startgamenototop"] == False:
|
||||
idx = savehook_new_list.index(
|
||||
gamepath2uid[name_]
|
||||
)
|
||||
savehook_new_list.insert(
|
||||
0, savehook_new_list.pop(idx)
|
||||
)
|
||||
needinserthookcode = savehook_new_data[
|
||||
gamepath2uid[name_]
|
||||
]["needinserthookcode"]
|
||||
self.textsource = texthook(
|
||||
pids,
|
||||
hwnd,
|
||||
name_,
|
||||
gamepath2uid[name_],
|
||||
autostarthookcode=savehook_new_data[
|
||||
gamepath2uid[name_]
|
||||
]["hook"],
|
||||
needinserthookcode=needinserthookcode,
|
||||
)
|
||||
self.textsource.start()
|
||||
else:
|
||||
pids = self.textsource.pids
|
||||
if sum([int(pid_running(pid)) for pid in pids]) == 0:
|
||||
self.textsource = None
|
||||
self.translation_ui.thistimenotsetop = False
|
||||
if globalconfig["keepontop"]:
|
||||
self.translation_ui.settop()
|
||||
|
||||
except:
|
||||
|
||||
print_exc()
|
||||
|
||||
def autohookmonitorthread(self):
|
||||
def onwindowloadautohook():
|
||||
textsourceusing = globalconfig["sourcestatus2"]["texthook"]["use"]
|
||||
if not (globalconfig["autostarthook"] and textsourceusing):
|
||||
return
|
||||
elif self.AttachProcessDialog and self.AttachProcessDialog.isVisible():
|
||||
return
|
||||
if self.textsource is None:
|
||||
hwnd = windows.GetForegroundWindow()
|
||||
pid = windows.GetWindowThreadProcessId(hwnd)
|
||||
name_ = getpidexe(pid)
|
||||
if not name_:
|
||||
return
|
||||
uid = findgameuidofpath(name_, savehook_new_list)
|
||||
if not uid:
|
||||
return
|
||||
lps = ListProcess(False)
|
||||
for pids, _exe in lps:
|
||||
if _exe != name_:
|
||||
continue
|
||||
|
||||
if self.textsource is not None:
|
||||
return
|
||||
if not globalconfig["sourcestatus2"]["texthook"]["use"]:
|
||||
return
|
||||
if globalconfig["startgamenototop"] == False:
|
||||
idx = savehook_new_list.index(uid)
|
||||
savehook_new_list.insert(0, savehook_new_list.pop(idx))
|
||||
needinserthookcode = savehook_new_data[uid]["needinserthookcode"]
|
||||
self.textsource = texthook(
|
||||
pids,
|
||||
hwnd,
|
||||
name_,
|
||||
uid,
|
||||
autostarthookcode=savehook_new_data[uid]["hook"],
|
||||
needinserthookcode=needinserthookcode,
|
||||
)
|
||||
self.textsource.start()
|
||||
|
||||
else:
|
||||
pids = self.textsource.pids
|
||||
if len(collect_running_pids(pids)) != 0:
|
||||
return
|
||||
self.textsource = None
|
||||
self.translation_ui.thistimenotsetop = False
|
||||
if globalconfig["keepontop"]:
|
||||
self.translation_ui.settop()
|
||||
|
||||
while self.isrunning:
|
||||
self.onwindowloadautohook()
|
||||
time.sleep(
|
||||
0.5
|
||||
) # 太短了的话,中间存在一瞬间,后台进程比前台窗口内存占用要大。。。
|
||||
try:
|
||||
onwindowloadautohook()
|
||||
except:
|
||||
print_exc()
|
||||
time.sleep(0.5)
|
||||
# 太短了的话,中间存在一瞬间,后台进程比前台窗口内存占用要大。。。
|
||||
|
||||
def autocheckhwndexists(self):
|
||||
def setandrefresh(bool):
|
||||
if self.translation_ui.isbindedwindow != bool:
|
||||
self.translation_ui.isbindedwindow = bool
|
||||
def setandrefresh(b):
|
||||
if self.translation_ui.isbindedwindow != b:
|
||||
self.translation_ui.isbindedwindow = b
|
||||
self.translation_ui.refreshtooliconsignal.emit()
|
||||
|
||||
while self.isrunning:
|
||||
if self.textsource:
|
||||
|
||||
hwnd = self.textsource.hwnd
|
||||
|
||||
if hwnd == 0:
|
||||
if globalconfig["sourcestatus2"]["texthook"]["use"]:
|
||||
fhwnd = windows.GetForegroundWindow()
|
||||
pids = self.textsource.pids
|
||||
if (
|
||||
hwnd == 0
|
||||
and windows.GetWindowThreadProcessId(fhwnd) in pids
|
||||
):
|
||||
if "once" not in dir(self.textsource):
|
||||
self.textsource.once = True
|
||||
self.textsource.hwnd = fhwnd
|
||||
setandrefresh(True)
|
||||
else:
|
||||
setandrefresh(False)
|
||||
else:
|
||||
if windows.GetWindowThreadProcessId(hwnd) == 0:
|
||||
self.textsource.hwnd = 0
|
||||
setandrefresh(False)
|
||||
elif "once" not in dir(self.textsource):
|
||||
self.textsource.once = True
|
||||
setandrefresh(True)
|
||||
if len(self.textsource.pids):
|
||||
_mute = winsharedutils.GetProcessMute(self.textsource.pids[0])
|
||||
if self.translation_ui.processismuteed != _mute:
|
||||
self.translation_ui.processismuteed = _mute
|
||||
self.translation_ui.refreshtooliconsignal.emit()
|
||||
else:
|
||||
def __do():
|
||||
if not self.textsource:
|
||||
setandrefresh(False)
|
||||
return
|
||||
hwnd = self.textsource.hwnd
|
||||
|
||||
if hwnd == 0:
|
||||
if not globalconfig["sourcestatus2"]["texthook"]["use"]:
|
||||
setandrefresh(False)
|
||||
else:
|
||||
fhwnd = windows.GetForegroundWindow()
|
||||
pids = self.textsource.pids
|
||||
notdone = "once" not in dir(self.textsource)
|
||||
isgoodproc = windows.GetWindowThreadProcessId(fhwnd) in pids
|
||||
if isgoodproc and notdone:
|
||||
self.textsource.once = True
|
||||
self.textsource.hwnd = fhwnd
|
||||
setandrefresh(True)
|
||||
else:
|
||||
if windows.GetWindowThreadProcessId(hwnd) == 0:
|
||||
self.textsource.hwnd = 0
|
||||
setandrefresh(False)
|
||||
elif "once" not in dir(self.textsource):
|
||||
self.textsource.once = True
|
||||
setandrefresh(True)
|
||||
if len(self.textsource.pids):
|
||||
_mute = winsharedutils.GetProcessMute(self.textsource.pids[0])
|
||||
if self.translation_ui.processismuteed != _mute:
|
||||
self.translation_ui.processismuteed = _mute
|
||||
self.translation_ui.refreshtooliconsignal.emit()
|
||||
|
||||
while self.isrunning:
|
||||
__do()
|
||||
|
||||
time.sleep(0.5)
|
||||
|
||||
@ -925,29 +916,28 @@ class MAINUI:
|
||||
True,
|
||||
)
|
||||
|
||||
_hwnd = windows.GetForegroundWindow()
|
||||
_pid = windows.GetWindowThreadProcessId(_hwnd)
|
||||
try:
|
||||
_hwnd = windows.GetForegroundWindow()
|
||||
_pid = windows.GetWindowThreadProcessId(_hwnd)
|
||||
|
||||
if len(self.textsource.pids) == 0:
|
||||
raise Exception()
|
||||
if _pid in self.textsource.pids or _pid == os.getpid():
|
||||
isok(self.textsource.gameuid)
|
||||
else:
|
||||
self.__currentexe = None
|
||||
except:
|
||||
name_ = getpidexe(_pid)
|
||||
if not name_:
|
||||
return
|
||||
uids = findgameuidofpath(name_, findall=True)
|
||||
try:
|
||||
if len(self.textsource.pids) == 0:
|
||||
raise Exception()
|
||||
if _pid in self.textsource.pids or _pid == os.getpid():
|
||||
isok(self.textsource.gameuid)
|
||||
if len(uids):
|
||||
for uid in uids:
|
||||
isok(uid)
|
||||
else:
|
||||
self.__currentexe = None
|
||||
except:
|
||||
name_ = getpidexe(_pid)
|
||||
if (
|
||||
name_
|
||||
and name_ in gamepath2uid
|
||||
and gamepath2uid[name_] in savehook_new_list
|
||||
):
|
||||
isok(gamepath2uid[name_])
|
||||
else:
|
||||
self.__currentexe = None
|
||||
except:
|
||||
print_exc()
|
||||
print_exc()
|
||||
|
||||
@threader
|
||||
def clickwordcallback(self, word, append):
|
||||
|
@ -34,8 +34,13 @@ def gettranslationrecorddir(name):
|
||||
return getcachedir(name, "translation_record")
|
||||
|
||||
|
||||
def gettempdir_1():
|
||||
tgt = getcachedir("temp")
|
||||
return tgt
|
||||
|
||||
|
||||
def gettempdir(filename):
|
||||
tgt = getcachedir(os.path.join(f"temp{os.getpid()}", filename))
|
||||
tgt = getcachedir(os.path.join(f"temp/{os.getpid()}", filename))
|
||||
return tgt
|
||||
|
||||
|
||||
|
@ -32,8 +32,10 @@ class AttachProcessDialog(saveposwindow):
|
||||
_pids = [pid]
|
||||
self.processEdit.setText(name)
|
||||
self.processIdEdit.setText(",".join([str(pid) for pid in _pids]))
|
||||
[_.show() for _ in self.windowtextlayoutwidgets]
|
||||
self.windowtext.setText(windows.GetWindowText(hwnd))
|
||||
self.processEdit.setCursorPosition(0)
|
||||
self.processIdEdit.setCursorPosition(0)
|
||||
self.windowtext.setCursorPosition(0)
|
||||
self.selectedp = (_pids, name, hwnd)
|
||||
|
||||
def closeEvent(self, e):
|
||||
@ -80,10 +82,8 @@ class AttachProcessDialog(saveposwindow):
|
||||
self.layout3.addWidget(self.processEdit)
|
||||
|
||||
self.windowtext = QLineEdit()
|
||||
self.windowtextlayoutwidgets = [QLabel(_TR("窗口名")), self.windowtext]
|
||||
[_.hide() for _ in self.windowtextlayoutwidgets]
|
||||
self.layout2.addWidget(self.windowtextlayoutwidgets[0])
|
||||
self.layout2.addWidget(self.windowtextlayoutwidgets[1])
|
||||
self.layout2.addWidget(QLabel(_TR("标题")))
|
||||
self.layout2.addWidget(self.windowtext)
|
||||
self.processList = QListView()
|
||||
self.buttonBox = QDialogButtonBox()
|
||||
self.buttonBox.setStandardButtons(
|
||||
@ -109,15 +109,25 @@ class AttachProcessDialog(saveposwindow):
|
||||
self.processList.clicked.connect(self.selectedfunc)
|
||||
self.processIdEdit.textEdited.connect(self.editpid)
|
||||
|
||||
self.processEdit.setReadOnly(True)
|
||||
self.windowtext.setReadOnly(True)
|
||||
# self.processEdit.setReadOnly(True)
|
||||
self.processEdit.textEdited.connect(self.filterproc)
|
||||
|
||||
def filterproc(self):
|
||||
self.processIdEdit.clear()
|
||||
self.windowtext.clear()
|
||||
text = self.processEdit.text()
|
||||
if len(text) == 0:
|
||||
self.refreshfunction()
|
||||
return
|
||||
for row in range(self.model.rowCount()):
|
||||
hide = not (text in self.model.item(row, 0).text())
|
||||
self.processList.setRowHidden(row, hide)
|
||||
|
||||
def refreshfunction(self):
|
||||
|
||||
self.windowtext.clear()
|
||||
self.processEdit.clear()
|
||||
self.processIdEdit.clear()
|
||||
[_.hide() for _ in self.windowtextlayoutwidgets]
|
||||
self.selectedp = None
|
||||
|
||||
###########################
|
||||
@ -151,15 +161,21 @@ class AttachProcessDialog(saveposwindow):
|
||||
def editpid(self, process):
|
||||
pids = self.safesplit(process)
|
||||
self.selectedp = (pids, getpidexe(pids[0]), self.guesshwnd(pids))
|
||||
self.windowtext.setText(windows.GetWindowText(self.selectedp[-1]))
|
||||
self.processEdit.setText(self.selectedp[1])
|
||||
[_.hide() for _ in self.windowtextlayoutwidgets]
|
||||
self.windowtext.setCursorPosition(0)
|
||||
self.processEdit.setCursorPosition(0)
|
||||
|
||||
|
||||
def selectedfunc(self, index):
|
||||
pids, pexe = self.processlist[index.row()]
|
||||
self.processEdit.setText(pexe)
|
||||
self.processIdEdit.setText(",".join([str(pid) for pid in pids]))
|
||||
[_.hide() for _ in self.windowtextlayoutwidgets]
|
||||
self.selectedp = pids, pexe, self.guesshwnd(pids)
|
||||
self.windowtext.setText(windows.GetWindowText(self.selectedp[-1]))
|
||||
self.processEdit.setCursorPosition(0)
|
||||
self.processIdEdit.setCursorPosition(0)
|
||||
self.windowtext.setCursorPosition(0)
|
||||
|
||||
def guesshwnd(self, pids):
|
||||
for pid in pids:
|
||||
@ -175,10 +191,5 @@ class AttachProcessDialog(saveposwindow):
|
||||
if self.selectedp[1] is None:
|
||||
getQMessageBox(self, "错误", "权限不足,请以管理员权限运行!")
|
||||
return
|
||||
# for pid in self.selectedp[0]:
|
||||
|
||||
# if(not testprivilege(pid)):
|
||||
# getQMessageBox(self,"错误","权限不足,请使用管理员权限运行本程序!")
|
||||
# return
|
||||
self.close()
|
||||
self.callback(self.selectedp)
|
||||
self.callback(self.selectedp, self.windowtext.text())
|
||||
|
@ -6,7 +6,6 @@ import windows, gobject, winsharedutils
|
||||
from myutils.config import (
|
||||
savehook_new_list,
|
||||
savehook_new_data,
|
||||
gamepath2uid,
|
||||
savegametaged,
|
||||
uid2gamepath,
|
||||
_TR,
|
||||
@ -614,15 +613,14 @@ def maybehavebutton(self, gameuid, post):
|
||||
|
||||
class dialog_setting_game_internal(QWidget):
|
||||
def selectexe(self):
|
||||
f = QFileDialog.getOpenFileName(directory=uid2gamepath[self.gameuid])
|
||||
originpath = uid2gamepath[self.gameuid]
|
||||
f = QFileDialog.getOpenFileName(directory=originpath)
|
||||
res = f[0]
|
||||
if res == "":
|
||||
return
|
||||
# 修改路径允许路径重复
|
||||
# 添加路径实际上也允许重复,只不过会去重。
|
||||
res = os.path.normpath(res)
|
||||
if res in gamepath2uid:
|
||||
return
|
||||
originpath = uid2gamepath[self.gameuid]
|
||||
gamepath2uid[res] = gamepath2uid.pop(originpath)
|
||||
uid2gamepath[self.gameuid] = res
|
||||
gobject.baseobject.resetgameinternal(originpath, res)
|
||||
_icon = getExeIcon(res, cache=True)
|
||||
@ -715,13 +713,16 @@ class dialog_setting_game_internal(QWidget):
|
||||
internallist=list(globalconfig["metadata"].keys()),
|
||||
),
|
||||
)
|
||||
formLayout.addRow(None, QLabel())
|
||||
for key in globalconfig["metadata"]:
|
||||
try:
|
||||
idname = globalconfig["metadata"][key]["target"]
|
||||
vndbid = QLineEdit(str(savehook_new_data[gameuid][idname]))
|
||||
if globalconfig["metadata"][key].get("idtype", 1) == 0:
|
||||
vndbid.setValidator(QIntValidator())
|
||||
vndbid.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
|
||||
vndbid.setSizePolicy(
|
||||
QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed
|
||||
)
|
||||
|
||||
vndbid.textEdited.connect(
|
||||
functools.partial(idtypecheck, key, idname, gameuid)
|
||||
@ -730,6 +731,7 @@ class dialog_setting_game_internal(QWidget):
|
||||
functools.partial(gamdidchangedtask, key, idname, gameuid)
|
||||
)
|
||||
_vbox_internal = [
|
||||
getsimpleswitch(globalconfig["metadata"][key], "auto"),
|
||||
vndbid,
|
||||
getIconButton(
|
||||
functools.partial(self.openrefmainpage, key, idname, gameuid),
|
||||
@ -746,7 +748,7 @@ class dialog_setting_game_internal(QWidget):
|
||||
try:
|
||||
__settting = targetmod[key].querysettingwindow
|
||||
_vbox_internal.insert(
|
||||
1,
|
||||
2,
|
||||
getIconButton(
|
||||
functools.partial(__settting, self, gameuid), icon="fa.gear"
|
||||
),
|
||||
@ -1974,7 +1976,7 @@ class dialog_savedgame_new(QWidget):
|
||||
menu = QMenu(self)
|
||||
|
||||
editname = QAction(_TR("修改列表名称"))
|
||||
addlist = QAction(_TR("添加列表"))
|
||||
addlist = QAction(_TR("创建列表"))
|
||||
dellist = QAction(_TR("删除列表"))
|
||||
|
||||
startgame = QAction(_TR("开始游戏"))
|
||||
@ -2028,7 +2030,7 @@ class dialog_savedgame_new(QWidget):
|
||||
elif action == editname or action == addlist:
|
||||
_dia = Prompt_dialog(
|
||||
self,
|
||||
_TR("修改列表名称" if action == editname else "添加列表"),
|
||||
_TR("修改列表名称" if action == editname else "创建列表"),
|
||||
"",
|
||||
[
|
||||
[
|
||||
@ -2160,7 +2162,7 @@ class dialog_savedgame_new(QWidget):
|
||||
self.simplebutton("删除游戏", True, self.clicked2, False)
|
||||
self.simplebutton("打开目录", True, self.clicked4, True)
|
||||
|
||||
self.simplebutton("添加到列表", False, self.addtolist, 1)
|
||||
self.simplebutton("添加到列表", True, self.addtolist, False)
|
||||
if globalconfig["startgamenototop"]:
|
||||
self.simplebutton("左移", True, functools.partial(self.moverank, -1), False)
|
||||
self.simplebutton("右移", True, functools.partial(self.moverank, 1), False)
|
||||
@ -2770,9 +2772,9 @@ class dialog_savedgame_v3(QWidget):
|
||||
self.stack.directshow()
|
||||
|
||||
def stack_showmenu(self, ispixmenu, p):
|
||||
if not self.currentfocusuid:
|
||||
return
|
||||
menu = QMenu(self)
|
||||
|
||||
addlist = QAction(_TR("创建列表"))
|
||||
startgame = QAction(_TR("开始游戏"))
|
||||
delgame = QAction(_TR("删除游戏"))
|
||||
opendir = QAction(_TR("打开目录"))
|
||||
@ -2780,24 +2782,57 @@ class dialog_savedgame_v3(QWidget):
|
||||
setimage = QAction(_TR("设为封面"))
|
||||
deleteimage = QAction(_TR("删除图片"))
|
||||
hualang = QAction(_TR("画廊"))
|
||||
exists = os.path.exists(uid2gamepath[self.currentfocusuid])
|
||||
if exists:
|
||||
menu.addAction(startgame)
|
||||
menu.addAction(delgame)
|
||||
if exists:
|
||||
menu.addAction(opendir)
|
||||
if not self.currentfocusuid:
|
||||
|
||||
menu.addSeparator()
|
||||
menu.addAction(addtolist)
|
||||
menu.addAction(addlist)
|
||||
else:
|
||||
exists = os.path.exists(uid2gamepath[self.currentfocusuid])
|
||||
if exists:
|
||||
menu.addAction(startgame)
|
||||
menu.addAction(delgame)
|
||||
if exists:
|
||||
menu.addAction(opendir)
|
||||
|
||||
if ispixmenu:
|
||||
menu.addSeparator()
|
||||
menu.addAction(setimage)
|
||||
menu.addAction(deleteimage)
|
||||
menu.addAction(hualang)
|
||||
menu.addAction(addtolist)
|
||||
|
||||
if ispixmenu:
|
||||
menu.addSeparator()
|
||||
menu.addAction(setimage)
|
||||
menu.addAction(deleteimage)
|
||||
menu.addAction(hualang)
|
||||
action = menu.exec(QCursor.pos())
|
||||
if action == startgame:
|
||||
startgamecheck(self, self.currentfocusuid)
|
||||
elif addlist == action:
|
||||
_dia = Prompt_dialog(
|
||||
self,
|
||||
_TR("创建列表"),
|
||||
"",
|
||||
[
|
||||
[
|
||||
_TR("名称"),
|
||||
(""),
|
||||
],
|
||||
],
|
||||
)
|
||||
|
||||
if _dia.exec():
|
||||
|
||||
title = _dia.text[0].text()
|
||||
if title != "":
|
||||
i = calculatetagidx(None)
|
||||
if action == addlist:
|
||||
tag = {
|
||||
"title": title,
|
||||
"games": [],
|
||||
"uid": str(uuid.uuid4()),
|
||||
"opened": True,
|
||||
}
|
||||
savegametaged.insert(i, tag)
|
||||
group0 = self.createtaglist(self.stack, title, tag["uid"], True)
|
||||
self.stack.insertw(i, group0)
|
||||
|
||||
elif action == delgame:
|
||||
self.shanchuyouxi()
|
||||
elif action == hualang:
|
||||
@ -2885,7 +2920,7 @@ class dialog_savedgame_v3(QWidget):
|
||||
)
|
||||
self.simplebutton("删除游戏", True, self.shanchuyouxi, False)
|
||||
self.simplebutton("打开目录", True, self.clicked4, True)
|
||||
self.simplebutton("添加到列表", False, self.addtolist, 1)
|
||||
self.simplebutton("添加到列表", True, self.addtolist, False)
|
||||
if globalconfig["startgamenototop"]:
|
||||
self.simplebutton("上移", True, functools.partial(self.moverank, -1), False)
|
||||
self.simplebutton("下移", True, functools.partial(self.moverank, 1), False)
|
||||
@ -2945,7 +2980,7 @@ class dialog_savedgame_v3(QWidget):
|
||||
self.reftagid = tagid
|
||||
menu = QMenu(self)
|
||||
editname = QAction(_TR("修改列表名称"))
|
||||
addlist = QAction(_TR("添加列表"))
|
||||
addlist = QAction(_TR("创建列表"))
|
||||
dellist = QAction(_TR("删除列表"))
|
||||
Upaction = QAction(_TR("上移"))
|
||||
Downaction = QAction(_TR("下移"))
|
||||
@ -2975,7 +3010,7 @@ class dialog_savedgame_v3(QWidget):
|
||||
elif action == editname or action == addlist:
|
||||
_dia = Prompt_dialog(
|
||||
self,
|
||||
_TR("修改列表名称" if action == editname else "添加列表"),
|
||||
_TR("修改列表名称" if action == editname else "创建列表"),
|
||||
"",
|
||||
[
|
||||
[
|
||||
|
@ -22,7 +22,7 @@ def getall(l, item="fanyi", name=None):
|
||||
continue
|
||||
if name:
|
||||
_f = name % fanyi
|
||||
if fanyi != "selfbuild" and os.path.exists(_f) == False:
|
||||
if not os.path.exists(_f):
|
||||
continue
|
||||
i += 1
|
||||
|
||||
|
@ -34,14 +34,18 @@ from gui.usefulwidget import (
|
||||
|
||||
def __create(self):
|
||||
self.selectbutton = getIconButton(
|
||||
gobject.baseobject.createattachprocess, icon="fa.gear"
|
||||
gobject.baseobject.createattachprocess,
|
||||
icon="fa.gear",
|
||||
enable=globalconfig["sourcestatus2"]["texthook"]["use"],
|
||||
)
|
||||
return self.selectbutton
|
||||
|
||||
|
||||
def __create2(self):
|
||||
self.selecthookbutton = getIconButton(
|
||||
lambda: gobject.baseobject.hookselectdialog.showsignal.emit(), icon="fa.gear"
|
||||
lambda: gobject.baseobject.hookselectdialog.showsignal.emit(),
|
||||
icon="fa.gear",
|
||||
enable=globalconfig["sourcestatus2"]["texthook"]["use"],
|
||||
)
|
||||
return self.selecthookbutton
|
||||
|
||||
|
@ -38,7 +38,7 @@ def initsome11(self, l, label=None):
|
||||
continue
|
||||
|
||||
_f = "./Lunatranslator/translator/{}.py".format(fanyi)
|
||||
if fanyi != "selfbuild" and os.path.exists(_f) == False:
|
||||
if not os.path.exists(_f):
|
||||
continue
|
||||
i += 1
|
||||
|
||||
@ -128,12 +128,9 @@ def checkconnected(self):
|
||||
for dev in develop:
|
||||
if not globalconfig["fanyi"][dev]["use"]:
|
||||
continue
|
||||
if dev == "selfbuild":
|
||||
if not os.path.exists("./userconfig/selfbuild.py"):
|
||||
continue
|
||||
else:
|
||||
if not os.path.exists("./LunaTranslator/translator/" + dev + ".py"):
|
||||
continue
|
||||
|
||||
if not os.path.exists("./LunaTranslator/translator/" + dev + ".py"):
|
||||
continue
|
||||
needstart = True
|
||||
break
|
||||
try:
|
||||
@ -218,7 +215,7 @@ def setTabTwo_lazy(self, basel):
|
||||
"",
|
||||
"模糊匹配_相似度_%",
|
||||
D_getspinbox(0, 100, globalconfig, "premtsimi2"),
|
||||
""
|
||||
"",
|
||||
],
|
||||
[
|
||||
(functools.partial(createbtnexport, self), 0),
|
||||
@ -229,7 +226,7 @@ def setTabTwo_lazy(self, basel):
|
||||
"group",
|
||||
)
|
||||
],
|
||||
[]
|
||||
[],
|
||||
]
|
||||
_items = [
|
||||
{
|
||||
|
@ -489,6 +489,11 @@ class AnkiWindow(QWidget):
|
||||
cropbutton = QPushButton(qtawesome.icon("fa.crop"), "")
|
||||
cropbutton.clicked.connect(self.crop)
|
||||
|
||||
grabwindowbtn = QPushButton(qtawesome.icon("fa.camera"), "")
|
||||
grabwindowbtn.clicked.connect(
|
||||
lambda: grabwindow(getimageformat(), self.editpath.setText)
|
||||
)
|
||||
|
||||
self.audiopath = QLineEdit()
|
||||
self.audiopath.setReadOnly(True)
|
||||
self.audiopath_sentence = QLineEdit()
|
||||
@ -566,6 +571,7 @@ class AnkiWindow(QWidget):
|
||||
QLabel(_TR("截图")),
|
||||
self.editpath,
|
||||
cropbutton,
|
||||
grabwindowbtn,
|
||||
getIconButton(
|
||||
functools.partial(
|
||||
self.selecfile, self.editpath
|
||||
|
@ -3,7 +3,14 @@ import time, functools, threading, os, sys, importlib, shutil
|
||||
from traceback import print_exc
|
||||
import windows, qtawesome, gobject, winsharedutils
|
||||
from myutils.wrapper import threader, trypass
|
||||
from myutils.config import globalconfig, saveallconfig, _TR, static_data, gamepath2uid
|
||||
from myutils.config import (
|
||||
globalconfig,
|
||||
saveallconfig,
|
||||
_TR,
|
||||
static_data,
|
||||
findgameuidofpath,
|
||||
savehook_new_list,
|
||||
)
|
||||
from myutils.subproc import endsubprocs
|
||||
from myutils.ocrutil import ocr_run, imageCut
|
||||
from myutils.utils import loadpostsettingwindowmethod, str2rgba
|
||||
@ -12,13 +19,14 @@ from gui.setting_about import doupdate
|
||||
from gui.dialog_memory import dialog_memory
|
||||
from gui.textbrowser import Textbrowser
|
||||
from gui.rangeselect import rangeselct_function
|
||||
from gui.usefulwidget import resizableframeless, isinrect
|
||||
from gui.usefulwidget import resizableframeless, isinrect, getQMessageBox
|
||||
from gui.edittext import edittrans
|
||||
from gui.dialog_savedgame import browserdialog, dialog_savedgame_integrated
|
||||
|
||||
|
||||
class QUnFrameWindow(resizableframeless):
|
||||
displayglobaltooltip = pyqtSignal(str)
|
||||
displaymessagebox = pyqtSignal(str, str)
|
||||
displayres = pyqtSignal(dict)
|
||||
displayraw1 = pyqtSignal(dict)
|
||||
displaystatus = pyqtSignal(str, str, bool, bool)
|
||||
@ -522,9 +530,13 @@ class QUnFrameWindow(resizableframeless):
|
||||
def displayglobaltooltip_f(self, string):
|
||||
QToolTip.showText(QCursor.pos(), string, self)
|
||||
|
||||
def displaymessagebox_f(self, string1, string2):
|
||||
getQMessageBox(self, string1, string2)
|
||||
|
||||
def initsignals(self):
|
||||
self.hidesignal.connect(self.hide_)
|
||||
self.displayglobaltooltip.connect(self.displayglobaltooltip_f)
|
||||
self.displaymessagebox.connect(self.displaymessagebox_f)
|
||||
self.ocr_once_signal.connect(self.ocr_once_function)
|
||||
self.displaystatus.connect(self.showstatus)
|
||||
self.showhideuisignal.connect(self.showhideui)
|
||||
@ -797,7 +809,7 @@ class QUnFrameWindow(resizableframeless):
|
||||
gobject.baseobject.textsource.hwnd = hwnd if pid != _pid else None
|
||||
if not globalconfig["sourcestatus2"]["texthook"]["use"]:
|
||||
gobject.baseobject.textsource.pids = [pid] if pid != _pid else None
|
||||
gameuid = gamepath2uid.get(getpidexe(pid), None)
|
||||
gameuid = findgameuidofpath(getpidexe(pid), savehook_new_list)
|
||||
if gameuid:
|
||||
gobject.baseobject.textsource.gameuid = gameuid
|
||||
self.isbindedwindow = pid != _pid
|
||||
@ -1008,13 +1020,31 @@ class QUnFrameWindow(resizableframeless):
|
||||
self.buttons[name] = button
|
||||
|
||||
def tryremoveuseless(self):
|
||||
try:
|
||||
allisremoved = True
|
||||
tmpbase = gobject.gettempdir_1()
|
||||
for f in os.listdir(tmpbase):
|
||||
try:
|
||||
pid = int(f)
|
||||
except:
|
||||
continue
|
||||
if (pid != os.getpid()) and (winsharedutils.pid_running(pid)):
|
||||
allisremoved = False
|
||||
continue
|
||||
|
||||
try:
|
||||
shutil.rmtree(gobject.gettempdir(''))
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
os.remove("./cache/Updater.exe")
|
||||
try:
|
||||
shutil.rmtree(os.path.join(tmpbase, f))
|
||||
except:
|
||||
pass
|
||||
if allisremoved:
|
||||
try:
|
||||
shutil.rmtree(tmpbase)
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
os.remove("./cache/Updater.exe")
|
||||
except:
|
||||
pass
|
||||
except:
|
||||
pass
|
||||
|
||||
|
@ -71,7 +71,7 @@ class bgmsettings(QDialog):
|
||||
if vid in collect:
|
||||
gameuid = collect[vid]
|
||||
else:
|
||||
gameuid = initanewitem(f"bgm_{vid}_{time.time()}", title)
|
||||
gameuid = initanewitem(title)
|
||||
savehook_new_data[gameuid][self._ref.idname] = vid
|
||||
gamdidchangedtask(self._ref.typename, self._ref.idname, gameuid)
|
||||
reflist.insert(0, gameuid)
|
||||
@ -203,9 +203,8 @@ class searcher(common):
|
||||
vndbtags = [_["name"] for _ in response["tags"]]
|
||||
developers = []
|
||||
for _ in response["infobox"]:
|
||||
if _["key"] == "游戏开发商":
|
||||
developers = [_["value"]]
|
||||
break
|
||||
if _["key"] in ["游戏开发商", "开发", "发行"]:
|
||||
developers += [_["value"]]
|
||||
return {
|
||||
# "namemap": namemap,
|
||||
"title": response["name"],
|
||||
|
@ -72,7 +72,7 @@ class steamsettings(QDialog):
|
||||
if vid in collect:
|
||||
gameuid = collect[vid]
|
||||
else:
|
||||
gameuid = initanewitem(f"steam_{vid}_{time.time()}", title)
|
||||
gameuid = initanewitem(title)
|
||||
savehook_new_data[gameuid][self._ref.idname] = vid
|
||||
gamdidchangedtask(self._ref.typename, self._ref.idname, gameuid)
|
||||
reflist.insert(0, gameuid)
|
||||
|
@ -232,7 +232,7 @@ class vndbsettings(QDialog):
|
||||
if vid in collect:
|
||||
gameuid = collect[vid]
|
||||
else:
|
||||
gameuid = initanewitem(f"vndb_{vid}_{time.time()}", title)
|
||||
gameuid = initanewitem(title)
|
||||
savehook_new_data[gameuid][self._ref.idname] = vid
|
||||
gamdidchangedtask(self._ref.typename, self._ref.idname, gameuid)
|
||||
reflist.insert(0, gameuid)
|
||||
|
@ -52,11 +52,11 @@ if _savehook:
|
||||
savehook_new_list = _savehook[0]
|
||||
savehook_new_data = _savehook[1]
|
||||
savegametaged = _savehook[2]
|
||||
gamepath2uid = _savehook[3]
|
||||
# gamepath2uid = _savehook[3] 不再使用,允许重复的path
|
||||
else:
|
||||
|
||||
_savehook = tryreadconfig("savehook_new_1.39.4.json", default=[[], {}])
|
||||
|
||||
|
||||
# savehook_new_list: [gamepath,...]
|
||||
# savehook_new_data:{gamepath:dict,...}
|
||||
# savegametaged: 可能没有该项 [ None, {'games':[gamepath,...],'title':str,'opened':bool,'uid':str},...]
|
||||
@ -73,23 +73,23 @@ else:
|
||||
savegametaged = [None]
|
||||
|
||||
# 将savehook_new_data转换为新的格式
|
||||
gamepath2uid = {}
|
||||
__gamepath2uid = {}
|
||||
__savehook_new_data = {}
|
||||
for k in savehook_new_data:
|
||||
uid = f"{time.time()}_{uuid.uuid4()}"
|
||||
|
||||
__savehook_new_data[uid] = savehook_new_data[k]
|
||||
__savehook_new_data[uid].update(gamepath=k)
|
||||
gamepath2uid[k] = uid
|
||||
__gamepath2uid[k] = uid
|
||||
savehook_new_data = __savehook_new_data
|
||||
|
||||
# 将global游戏表和自定义子列表都转换成新格式
|
||||
def parselist(ls):
|
||||
for i in range(len(ls)):
|
||||
ori = ls[i]
|
||||
if ori not in gamepath2uid:
|
||||
if ori not in __gamepath2uid:
|
||||
continue
|
||||
ls[i] = gamepath2uid[ori]
|
||||
ls[i] = __gamepath2uid[ori]
|
||||
|
||||
parselist(savehook_new_list)
|
||||
for sub in savegametaged:
|
||||
@ -100,9 +100,9 @@ translatorsetting = tryreadconfig("translatorsetting.json")
|
||||
ocrsetting = tryreadconfig("ocrsetting.json")
|
||||
|
||||
|
||||
def getdefaultsavehook(gamepath, title=None):
|
||||
def getdefaultsavehook(title=None):
|
||||
default = {
|
||||
# "gamepath": gamepath,
|
||||
"gamepath": "", # 不要直接访问,要通过uid2gamepath来间接访问
|
||||
"hooksetting_follow_default": True,
|
||||
"hooksetting_private": {}, # 显示时再加载,缺省用global中的键
|
||||
"textproc_follow_default": True,
|
||||
@ -167,12 +167,6 @@ def getdefaultsavehook(gamepath, title=None):
|
||||
}
|
||||
if title and len(title):
|
||||
default["title"] = title # metadata
|
||||
else:
|
||||
default["title"] = (
|
||||
os.path.basename(os.path.dirname(gamepath))
|
||||
+ "/"
|
||||
+ os.path.basename(gamepath)
|
||||
)
|
||||
|
||||
return default
|
||||
|
||||
@ -205,6 +199,34 @@ class __uid2gamepath:
|
||||
uid2gamepath = __uid2gamepath()
|
||||
|
||||
|
||||
def findgameuidofpath(gamepath, targetlist=None, findall=False):
|
||||
# 一般只在save_game_list里查找,用于从getpidexe获取uid
|
||||
# 因为有可能有过去的不再使用的uid,发生碰撞。
|
||||
# 只在添加游戏时,全面查找。
|
||||
if not gamepath:
|
||||
if findall:
|
||||
return []
|
||||
else:
|
||||
return None
|
||||
# 遍历的速度非常快,1w条的速度也就0.001x秒
|
||||
# 但1w条数据时,load/dump的速度就有点慢了,能2秒多
|
||||
|
||||
checkin = targetlist
|
||||
if checkin is None:
|
||||
checkin = savehook_new_data.keys()
|
||||
collect = []
|
||||
for uid in checkin:
|
||||
if savehook_new_data[uid]["gamepath"] == gamepath:
|
||||
if findall:
|
||||
collect.append(uid)
|
||||
else:
|
||||
return uid
|
||||
if findall:
|
||||
return collect
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def syncconfig(config1, default, drop=False, deep=0, skipdict=False):
|
||||
|
||||
for key in default:
|
||||
@ -404,11 +426,15 @@ def _TRL(kk):
|
||||
return x
|
||||
|
||||
|
||||
def safesave(fname, js):
|
||||
def safesave(fname, js, beatiful=True):
|
||||
# 有时保存时意外退出,会导致config文件被清空
|
||||
os.makedirs("./userconfig", exist_ok=True)
|
||||
with open(fname + ".tmp", "w", encoding="utf-8") as ff:
|
||||
ff.write(json.dumps(js, ensure_ascii=False, sort_keys=False, indent=4))
|
||||
if beatiful:
|
||||
ff.write(json.dumps(js, ensure_ascii=False, sort_keys=False, indent=4))
|
||||
else:
|
||||
# savegamedata 1w条时,indent=4要2秒,不indent 0.37秒,不ensure_ascii 0.27秒,用不着数据库了
|
||||
ff.write(json.dumps(js, sort_keys=False))
|
||||
if os.path.exists(fname):
|
||||
os.remove(fname)
|
||||
os.rename(fname + ".tmp", fname)
|
||||
@ -426,7 +452,8 @@ def saveallconfig():
|
||||
safesave("./userconfig/ocrsetting.json", ocrsetting)
|
||||
safesave(
|
||||
"./userconfig/savegamedata_5.3.1.json",
|
||||
[savehook_new_list, savehook_new_data, savegametaged, gamepath2uid],
|
||||
[savehook_new_list, savehook_new_data, savegametaged, None],
|
||||
beatiful=False,
|
||||
)
|
||||
safesave(
|
||||
"./files/lang/{}.json".format(getlanguse()),
|
||||
|
@ -84,25 +84,33 @@ def getprocesslist():
|
||||
|
||||
def getpidexe(pid):
|
||||
hwnd1 = windows.AutoHandle(
|
||||
windows.OpenProcess(windows.PROCESS_ALL_ACCESS, False, (pid))
|
||||
windows.OpenProcess(windows.PROCESS_ALL_ACCESS, False, pid)
|
||||
)
|
||||
if hwnd1 == 0:
|
||||
if not hwnd1:
|
||||
|
||||
hwnd1 = windows.OpenProcess(
|
||||
windows.PROCESS_QUERY_LIMITED_INFORMATION, False, (pid)
|
||||
windows.PROCESS_QUERY_LIMITED_INFORMATION, False, pid
|
||||
)
|
||||
if hwnd1 == 0:
|
||||
if not hwnd1:
|
||||
name_ = None
|
||||
else:
|
||||
name_ = windows.GetProcessFileName(hwnd1)
|
||||
return name_
|
||||
|
||||
|
||||
def testprivilege(pid):
|
||||
hwnd1 = windows.AutoHandle(
|
||||
windows.OpenProcess(windows.PROCESS_INJECT_ACCESS, False, (pid))
|
||||
def test_injectable_1(pid):
|
||||
return bool(
|
||||
windows.AutoHandle(
|
||||
windows.OpenProcess(windows.PROCESS_INJECT_ACCESS, False, pid)
|
||||
)
|
||||
)
|
||||
return hwnd1 != 0
|
||||
|
||||
|
||||
def test_injectable(pids):
|
||||
for pid in pids:
|
||||
if not test_injectable_1(pid):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def ListProcess(filt=True):
|
||||
@ -128,18 +136,13 @@ def ListProcess(filt=True):
|
||||
pass
|
||||
kv = {}
|
||||
for pid, exe in ret:
|
||||
if exe in kv:
|
||||
kv[exe]["pid"].append(pid)
|
||||
else:
|
||||
kv[exe] = {"pid": [pid]}
|
||||
# for exe in kv:
|
||||
# if len(kv[exe]['pid'])>1:
|
||||
# mems=[getprocessmem(_) for _ in kv[exe]['pid']]
|
||||
# _i=argsort(mems)
|
||||
# kv[exe]['pid']=[kv[exe]['pid'][_i[-1]]]
|
||||
if exe not in kv:
|
||||
kv[exe] = []
|
||||
|
||||
kv[exe].append(pid)
|
||||
xxx = []
|
||||
for exe in kv:
|
||||
xxx.append([kv[exe]["pid"], exe])
|
||||
xxx.append([kv[exe], exe])
|
||||
return xxx
|
||||
|
||||
|
||||
@ -184,28 +187,26 @@ def getExeIcon(name, icon=True, cache=False):
|
||||
|
||||
def injectdll(injectpids, injecter, dll):
|
||||
pid = " ".join([str(_) for _ in injectpids])
|
||||
if any(map(testprivilege, injectpids)) == False:
|
||||
windows.ShellExecute(
|
||||
0,
|
||||
"runas",
|
||||
injecter,
|
||||
'dllinject {} "{}"'.format(pid, dll),
|
||||
None,
|
||||
windows.SW_HIDE,
|
||||
)
|
||||
else:
|
||||
for _ in (0,):
|
||||
if not test_injectable(injectpids):
|
||||
break
|
||||
|
||||
ret = subprocess.run(
|
||||
'"{}" dllinject {} "{}"'.format(injecter, pid, dll)
|
||||
).returncode
|
||||
if ret == 0:
|
||||
windows.ShellExecute(
|
||||
0,
|
||||
"runas",
|
||||
injecter,
|
||||
'dllinject {} "{}"'.format(pid, dll),
|
||||
None,
|
||||
windows.SW_HIDE,
|
||||
)
|
||||
if ret:
|
||||
return
|
||||
pids = winsharedutils.collect_running_pids(injectpids)
|
||||
pid = " ".join([str(_) for _ in pids])
|
||||
|
||||
windows.ShellExecute(
|
||||
0,
|
||||
"runas",
|
||||
injecter,
|
||||
'dllinject {} "{}"'.format(pid, dll),
|
||||
None,
|
||||
windows.SW_HIDE,
|
||||
)
|
||||
|
||||
|
||||
def mouseselectwindow(callback):
|
||||
|
@ -1,8 +1,8 @@
|
||||
import re, codecs, inspect
|
||||
from traceback import print_exc
|
||||
from collections import Counter
|
||||
import importlib, gobject
|
||||
from myutils.utils import getfilemd5, LRUCache, getlangsrc
|
||||
import gobject
|
||||
from myutils.utils import checkchaos, checkmd5reloadmodule, LRUCache, getlangsrc
|
||||
from myutils.config import (
|
||||
postprocessconfig,
|
||||
globalconfig,
|
||||
@ -322,9 +322,6 @@ def lines_threshold(line, args):
|
||||
return line
|
||||
|
||||
|
||||
from myutils.utils import checkchaos
|
||||
|
||||
|
||||
def _remove_chaos(line):
|
||||
newline = ""
|
||||
for c in line:
|
||||
@ -334,12 +331,16 @@ def _remove_chaos(line):
|
||||
return newline
|
||||
|
||||
|
||||
_selfdefpost = None
|
||||
_selfdefpostmd5 = None
|
||||
def _mypostloader(line, file, module):
|
||||
|
||||
isnew, _ = checkmd5reloadmodule(file, module)
|
||||
# 这个是单独函数的模块,不需要用isnew来判断是否需要重新初始化
|
||||
if not _:
|
||||
return line
|
||||
return _.POSTSOLVE(line)
|
||||
|
||||
|
||||
def POSTSOLVE(line):
|
||||
global _selfdefpostmd5, _selfdefpost
|
||||
if line == "":
|
||||
return ""
|
||||
functions = {
|
||||
@ -367,6 +368,7 @@ def POSTSOLVE(line):
|
||||
"dedump": dedump,
|
||||
"length_threshold": length_threshold,
|
||||
"lines_threshold": lines_threshold,
|
||||
"_11": _mypostloader,
|
||||
}
|
||||
useranklist = globalconfig["postprocess_rank"]
|
||||
usedpostprocessconfig = postprocessconfig
|
||||
@ -394,22 +396,6 @@ def POSTSOLVE(line):
|
||||
)
|
||||
except:
|
||||
print_exc()
|
||||
try:
|
||||
md5 = getfilemd5(usemypostpath)
|
||||
if md5 != _selfdefpostmd5:
|
||||
_ = importlib.import_module(usemodule)
|
||||
_ = importlib.reload(_)
|
||||
_selfdefpostmd5 = md5
|
||||
_selfdefpost = _
|
||||
else:
|
||||
_ = _selfdefpost
|
||||
functions.update({"_11": _.POSTSOLVE})
|
||||
except ModuleNotFoundError:
|
||||
pass
|
||||
except:
|
||||
print_exc()
|
||||
pass
|
||||
|
||||
for postitem in useranklist:
|
||||
if postitem not in functions:
|
||||
continue
|
||||
@ -418,20 +404,20 @@ def POSTSOLVE(line):
|
||||
if usedpostprocessconfig[postitem]["use"]:
|
||||
try:
|
||||
_f = functions[postitem]
|
||||
|
||||
sig = inspect.signature(_f)
|
||||
np = len(sig.parameters)
|
||||
if np == 1:
|
||||
line = functions[postitem](line)
|
||||
elif np == 2:
|
||||
line = functions[postitem](
|
||||
line, usedpostprocessconfig[postitem].get("args", {})
|
||||
)
|
||||
else:
|
||||
raise Exception("unsupported parameters num")
|
||||
|
||||
except Exception as e:
|
||||
print_exc()
|
||||
if postitem == "_11":
|
||||
raise e
|
||||
line = functions[postitem](line, usemypostpath, usemodule)
|
||||
else:
|
||||
sig = inspect.signature(_f)
|
||||
np = len(sig.parameters)
|
||||
if np == 1:
|
||||
line = functions[postitem](line)
|
||||
elif np == 2:
|
||||
line = functions[postitem](
|
||||
line, usedpostprocessconfig[postitem].get("args", {})
|
||||
)
|
||||
else:
|
||||
raise Exception("unsupported parameters num")
|
||||
|
||||
except:
|
||||
print_exc()
|
||||
return line
|
||||
|
@ -13,9 +13,9 @@ from myutils.config import (
|
||||
globalconfig,
|
||||
static_data,
|
||||
getlanguse,
|
||||
savehook_new_data,
|
||||
uid2gamepath,
|
||||
gamepath2uid,
|
||||
savehook_new_data,
|
||||
findgameuidofpath,
|
||||
getdefaultsavehook,
|
||||
)
|
||||
from ctypes import c_float, pointer, c_void_p
|
||||
@ -127,9 +127,6 @@ class PriorityQueue:
|
||||
return bool(len(self._heap) == 0)
|
||||
|
||||
|
||||
searchvndbqueue = PriorityQueue()
|
||||
|
||||
|
||||
def guessmaybetitle(gamepath, title):
|
||||
|
||||
__t = []
|
||||
@ -167,14 +164,20 @@ def guessmaybetitle(gamepath, title):
|
||||
targetmod = {}
|
||||
|
||||
|
||||
def trysearchforid(gameuid, searchargs: list):
|
||||
def dispatchsearchfordata(gameuid, target, vid):
|
||||
targetmod[target].dispatchsearchfordata(gameuid, vid)
|
||||
|
||||
|
||||
def trysearchforid_1(gameuid, searchargs: list):
|
||||
infoid = None
|
||||
primitivtemetaorigin = globalconfig["primitivtemetaorigin"]
|
||||
__ = list(targetmod.keys())
|
||||
if primitivtemetaorigin not in __:
|
||||
primitivtemetaorigin = __[0]
|
||||
__.remove(primitivtemetaorigin)
|
||||
__.insert(0, primitivtemetaorigin)
|
||||
__ = [primitivtemetaorigin]
|
||||
for k in targetmod:
|
||||
if k == primitivtemetaorigin:
|
||||
continue
|
||||
if not globalconfig["metadata"][k]["auto"]:
|
||||
continue
|
||||
__.append(k)
|
||||
|
||||
for key in __:
|
||||
vid = None
|
||||
@ -195,28 +198,15 @@ def trysearchforid(gameuid, searchargs: list):
|
||||
if key == primitivtemetaorigin:
|
||||
break
|
||||
if infoid:
|
||||
searchvndbqueue.put((1, gameuid, infoid))
|
||||
return infoid
|
||||
key, vid = infoid
|
||||
dispatchsearchfordata(gameuid, key, vid)
|
||||
gobject.baseobject.translation_ui.displayglobaltooltip.emit(
|
||||
f"{key}: found {vid}"
|
||||
)
|
||||
|
||||
|
||||
def everymethodsthread():
|
||||
while True:
|
||||
_ = searchvndbqueue.get()
|
||||
_type, gameuid, arg = _
|
||||
try:
|
||||
if _type == 0:
|
||||
infoid = trysearchforid(gameuid, arg)
|
||||
key, vid = infoid
|
||||
gobject.baseobject.translation_ui.displayglobaltooltip.emit(
|
||||
f"{key}: found {vid}"
|
||||
)
|
||||
|
||||
elif _type == 1:
|
||||
key, vid = arg
|
||||
targetmod[key].dispatchsearchfordata(gameuid, vid)
|
||||
|
||||
except:
|
||||
print_exc()
|
||||
def trysearchforid(gameuid, searchargs: list):
|
||||
threading.Thread(target=trysearchforid_1, args=(gameuid, searchargs)).start()
|
||||
|
||||
|
||||
def idtypecheck(key, idname, gameuid, vid):
|
||||
@ -237,30 +227,43 @@ def idtypecheck(key, idname, gameuid, vid):
|
||||
|
||||
def gamdidchangedtask(key, idname, gameuid):
|
||||
vid = savehook_new_data[gameuid][idname]
|
||||
searchvndbqueue.put((1, gameuid, (key, vid)), 1)
|
||||
dispatchsearchfordata(gameuid, key, vid)
|
||||
|
||||
|
||||
def titlechangedtask(gameuid, title):
|
||||
savehook_new_data[gameuid]["title"] = title
|
||||
savehook_new_data[gameuid]["istitlesetted"] = True
|
||||
searchvndbqueue.put((0, gameuid, [title]), 1)
|
||||
trysearchforid(gameuid, [title])
|
||||
|
||||
|
||||
def initanewitem(gamepath, title):
|
||||
def initanewitem(title):
|
||||
uid = f"{time.time()}_{uuid.uuid4()}"
|
||||
gamepath2uid[gamepath] = uid
|
||||
savehook_new_data[uid] = getdefaultsavehook(gamepath, title)
|
||||
uid2gamepath[uid] = gamepath
|
||||
savehook_new_data[uid] = getdefaultsavehook(title)
|
||||
return uid
|
||||
|
||||
|
||||
def checkifnewgame(targetlist, gamepath, title=None):
|
||||
if gamepath not in gamepath2uid:
|
||||
uid = initanewitem(gamepath, title)
|
||||
searchvndbqueue.put((0, uid, [title] + guessmaybetitle(gamepath, title)))
|
||||
# 用于添加游戏时,全局查找是否有过历史记录
|
||||
uids = findgameuidofpath(gamepath, findall=True)
|
||||
print(uids)
|
||||
if len(uids) == 0:
|
||||
uid = initanewitem(title)
|
||||
if title is None:
|
||||
savehook_new_data[uid]["title"] = (
|
||||
os.path.basename(os.path.dirname(gamepath))
|
||||
+ "/"
|
||||
+ os.path.basename(gamepath)
|
||||
)
|
||||
uid2gamepath[uid] = gamepath
|
||||
trysearchforid(uid, [title] + guessmaybetitle(gamepath, title))
|
||||
isnew = True
|
||||
else:
|
||||
uid = gamepath2uid[gamepath]
|
||||
isnew = uid not in targetlist
|
||||
isnew = True
|
||||
for uid in uids:
|
||||
if uid in targetlist:
|
||||
isnew = False
|
||||
break
|
||||
|
||||
if isnew:
|
||||
targetlist.insert(0, uid)
|
||||
return uid
|
||||
@ -414,7 +417,10 @@ class Process:
|
||||
pass
|
||||
"""
|
||||
)
|
||||
os.startfile(p)
|
||||
# os.startfile(p)
|
||||
threading.Thread(
|
||||
target=os.system, args=(f'notepad "{os.path.normpath(p)}"',)
|
||||
).start()
|
||||
return p
|
||||
|
||||
|
||||
@ -619,24 +625,11 @@ def checkpostusing(name):
|
||||
return use and checkpostlangmatch(name)
|
||||
|
||||
|
||||
def getpostfile(name):
|
||||
if name == "myprocess":
|
||||
mm = "myprocess"
|
||||
checkpath = "./userconfig/myprocess.py"
|
||||
else:
|
||||
mm = "transoptimi." + name
|
||||
checkpath = "./LunaTranslator/transoptimi/" + name + ".py"
|
||||
def loadpostsettingwindowmethod(name):
|
||||
checkpath = "./LunaTranslator/transoptimi/" + name + ".py"
|
||||
if os.path.exists(checkpath) == False:
|
||||
return None
|
||||
return mm
|
||||
|
||||
|
||||
def loadpostsettingwindowmethod(name):
|
||||
if name == "myprocess":
|
||||
return lambda _: selectdebugfile("./userconfig/myprocess.py")
|
||||
mm = getpostfile(name)
|
||||
if not mm:
|
||||
return None
|
||||
mm = "transoptimi." + name
|
||||
|
||||
try:
|
||||
Process = importlib.import_module(mm).Process
|
||||
@ -739,5 +732,29 @@ for k in globalconfig["metadata"]:
|
||||
except:
|
||||
print_exc()
|
||||
|
||||
globalcachedmodule = {}
|
||||
|
||||
threading.Thread(target=everymethodsthread).start()
|
||||
|
||||
def checkmd5reloadmodule(filename, module):
|
||||
if not os.path.exists(filename):
|
||||
# reload重新加载不存在的文件时不会报错。
|
||||
return True, None
|
||||
key = (filename, module)
|
||||
md5 = getfilemd5(filename)
|
||||
cachedmd5 = globalcachedmodule.get(key, {}).get("md5", None)
|
||||
if md5 != cachedmd5:
|
||||
try:
|
||||
_ = importlib.import_module(module)
|
||||
_ = importlib.reload(_)
|
||||
except ModuleNotFoundError:
|
||||
return True, None
|
||||
# 不要捕获其他错误,缺少模块时直接跳过,只报实现错误
|
||||
# except:
|
||||
# print_exc()
|
||||
# return True, None
|
||||
globalcachedmodule[key] = {"md5": md5, "module": _}
|
||||
|
||||
return True, _
|
||||
else:
|
||||
|
||||
return False, globalcachedmodule.get(key, {}).get("module", None)
|
||||
|
@ -8,9 +8,10 @@ from winsharedutils import Is64bit
|
||||
from myutils.config import globalconfig, savehook_new_data, static_data
|
||||
from textsource.textsourcebase import basetext
|
||||
from myutils.utils import checkchaos
|
||||
from myutils.hwnd import injectdll
|
||||
from myutils.hwnd import injectdll, test_injectable
|
||||
from myutils.wrapper import threader
|
||||
from myutils.utils import getfilemd5
|
||||
from traceback import print_exc
|
||||
|
||||
from ctypes import (
|
||||
CDLL,
|
||||
@ -151,6 +152,7 @@ class texthook(basetext):
|
||||
gobject.baseobject.hookselectdialog.realshowhide.emit(True)
|
||||
self.delaycollectallselectedoutput()
|
||||
self.declare()
|
||||
self.prepares()
|
||||
|
||||
def checkmd5prefix(self, gamepath):
|
||||
md5 = getfilemd5(gamepath)
|
||||
@ -229,7 +231,7 @@ class texthook(basetext):
|
||||
self.Luna_FreePtr(ws)
|
||||
return string
|
||||
|
||||
def Luna_Startup(self):
|
||||
def prepares(self):
|
||||
procs = [
|
||||
ProcessEvent(self.onprocconnect),
|
||||
ProcessEvent(self.connectedpids.remove),
|
||||
@ -243,15 +245,14 @@ class texthook(basetext):
|
||||
self.keepref += procs
|
||||
ptrs = [cast(_, c_void_p).value for _ in procs]
|
||||
self.Luna_Start(*ptrs)
|
||||
|
||||
def start(self):
|
||||
|
||||
self.Luna_Startup()
|
||||
self.setsettings()
|
||||
|
||||
def start_unsafe(self):
|
||||
|
||||
caninject = test_injectable(self.pids)
|
||||
injectpids = []
|
||||
for pid in self.pids:
|
||||
if self.config["use_yapi"]:
|
||||
if caninject and self.config["use_yapi"]:
|
||||
self.Luna_Inject(pid, os.path.abspath("./files/plugins/LunaHook"))
|
||||
else:
|
||||
if self.Luna_CreatePipeAndCheck(pid):
|
||||
@ -264,9 +265,17 @@ class texthook(basetext):
|
||||
dll = os.path.abspath(
|
||||
"./files/plugins/LunaHook/LunaHook{}.dll".format(arch)
|
||||
)
|
||||
# subprocess.Popen('"{}" dllinject {} "{}"'.format(injecter,pid,dll))
|
||||
injectdll(injectpids, injecter, dll)
|
||||
|
||||
def start(self):
|
||||
try:
|
||||
self.start_unsafe()
|
||||
except:
|
||||
print_exc()
|
||||
gobject.baseobject.translation_ui.displaymessagebox.emit(
|
||||
"错误", "权限不足,请以管理员权限运行!"
|
||||
)
|
||||
|
||||
def onprocconnect(self, pid):
|
||||
self.connectedpids.append(pid)
|
||||
time.sleep(savehook_new_data[self.gameuid]["inserthooktimeout"] / 1000)
|
||||
|
27
LunaTranslator/LunaTranslator/translator/selfbuild.py
Normal file
27
LunaTranslator/LunaTranslator/translator/selfbuild.py
Normal file
@ -0,0 +1,27 @@
|
||||
from translator.basetranslator import basetrans
|
||||
from myutils.utils import checkmd5reloadmodule
|
||||
|
||||
|
||||
class TS(basetrans):
|
||||
def mayreinit(self):
|
||||
isnew, module = checkmd5reloadmodule("./userconfig/selfbuild.py", "selfbuild")
|
||||
if not isnew:
|
||||
return
|
||||
if module:
|
||||
self.internal = module.TS("selfbuild")
|
||||
|
||||
def inittranslator(self):
|
||||
self.internal = None
|
||||
self.mayreinit()
|
||||
|
||||
def langmap(self):
|
||||
self.mayreinit()
|
||||
if not self.internal:
|
||||
return {}
|
||||
return self.internal.langmap()
|
||||
|
||||
def translate(self, content):
|
||||
self.mayreinit()
|
||||
if not self.internal:
|
||||
return ""
|
||||
return self.internal.translate(content)
|
31
LunaTranslator/LunaTranslator/transoptimi/myprocess.py
Normal file
31
LunaTranslator/LunaTranslator/transoptimi/myprocess.py
Normal file
@ -0,0 +1,31 @@
|
||||
from myutils.utils import selectdebugfile, checkmd5reloadmodule
|
||||
|
||||
|
||||
class Process:
|
||||
@staticmethod
|
||||
def get_setting_window(parent_window):
|
||||
return selectdebugfile("./userconfig/myprocess.py")
|
||||
|
||||
def process_after(self, res, contenxt):
|
||||
self.mayreinit()
|
||||
if not self.internal:
|
||||
return res
|
||||
return self.internal.process_after(res, contenxt)
|
||||
|
||||
def process_before(self, s):
|
||||
|
||||
self.mayreinit()
|
||||
if not self.internal:
|
||||
return s, None
|
||||
return self.internal.process_before(s)
|
||||
|
||||
def __init__(self) -> None:
|
||||
self.internal = None
|
||||
self.mayreinit()
|
||||
|
||||
def mayreinit(self):
|
||||
isnew, module = checkmd5reloadmodule("./userconfig/myprocess.py", "myprocess")
|
||||
if not isnew:
|
||||
return
|
||||
if module:
|
||||
self.internal = module.Process()
|
@ -900,6 +900,9 @@ def ScreenToClient(hwnd, x, y):
|
||||
return (P.x, P.y)
|
||||
|
||||
|
||||
INVALID_HANDLE_VALUE = -1
|
||||
|
||||
|
||||
class AutoHandle(HANDLE):
|
||||
def __new__(cls, value) -> None:
|
||||
instance = super().__new__(cls, value)
|
||||
@ -909,6 +912,9 @@ class AutoHandle(HANDLE):
|
||||
if self:
|
||||
CloseHandle(self)
|
||||
|
||||
def __bool__(self):
|
||||
return (self.value != INVALID_HANDLE_VALUE) and (self.value != None)
|
||||
|
||||
|
||||
_MapVirtualKey = _user32.MapVirtualKeyW
|
||||
_MapVirtualKey.argtypes = UINT, UINT
|
||||
|
@ -339,6 +339,16 @@ pid_running = utilsdll.pid_running
|
||||
pid_running.argtypes = (DWORD,)
|
||||
pid_running.restype = c_bool
|
||||
|
||||
|
||||
def collect_running_pids(pids):
|
||||
_ = []
|
||||
for __ in pids:
|
||||
if not pid_running(__):
|
||||
continue
|
||||
_.append(__)
|
||||
return _
|
||||
|
||||
|
||||
getpidhwndfirst = utilsdll.getpidhwndfirst
|
||||
getpidhwndfirst.argtypes = (DWORD,)
|
||||
getpidhwndfirst.restype = HWND
|
||||
|
@ -232,6 +232,7 @@
|
||||
},
|
||||
"metadata": {
|
||||
"vndb": {
|
||||
"auto": true,
|
||||
"name": "vndb",
|
||||
"downloadtasks": [],
|
||||
"searchfordatatasks": [],
|
||||
@ -243,6 +244,7 @@
|
||||
}
|
||||
},
|
||||
"dlsite": {
|
||||
"auto": false,
|
||||
"name": "dlsite",
|
||||
"downloadtasks": [],
|
||||
"searchfordatatasks": [],
|
||||
@ -250,6 +252,7 @@
|
||||
"target": "dlsiteid"
|
||||
},
|
||||
"bangumi": {
|
||||
"auto": true,
|
||||
"name": "bangumi",
|
||||
"downloadtasks": [],
|
||||
"searchfordatatasks": [],
|
||||
@ -261,6 +264,7 @@
|
||||
}
|
||||
},
|
||||
"fanza": {
|
||||
"auto": false,
|
||||
"name": "FanzaGames",
|
||||
"downloadtasks": [],
|
||||
"searchfordatatasks": [],
|
||||
@ -268,6 +272,7 @@
|
||||
"target": "fanzaid"
|
||||
},
|
||||
"steam": {
|
||||
"auto": false,
|
||||
"name": "steam",
|
||||
"downloadtasks": [],
|
||||
"searchfordatatasks": [],
|
||||
|
@ -485,7 +485,6 @@
|
||||
"进程号": "رقم العملية",
|
||||
"最长翻译字数": "أقصى عدد من الكلمات المترجمة",
|
||||
"过滤控制字符": "تصفية السيطرة الشخصية",
|
||||
"窗口名": "اسم النافذة",
|
||||
"法语": "الفرنسية .",
|
||||
"分词": "اسم الفاعل",
|
||||
"用户词典1": "قاموس المستخدم",
|
||||
@ -716,7 +715,6 @@
|
||||
"过滤历史重复": "تصفية التاريخ تكرار",
|
||||
"缓存条数": "عدد شرائط التخزين المؤقت",
|
||||
"腾讯OCR": "تينسنت التعرف الضوئي على الحروف",
|
||||
"添加列表": "إضافة قائمة",
|
||||
"删除列表": "حذف قائمة",
|
||||
"上移": "رفع",
|
||||
"下移": "نزولا",
|
||||
@ -813,5 +811,6 @@
|
||||
"上传游戏": "تحميل العاب",
|
||||
"以当前md5复制选中行": "حدد صف مع نسخة MD5 الحالي",
|
||||
"修改列表名称": "تعديل اسم القائمة",
|
||||
"滚动到最后": "انتقل إلى آخر"
|
||||
"滚动到最后": "انتقل إلى آخر",
|
||||
"创建列表": "إنشاء قائمة"
|
||||
}
|
@ -388,7 +388,6 @@
|
||||
"错误": "錯誤",
|
||||
"所选文件格式错误!": "所選檔案格式錯誤!",
|
||||
"进程号": "行程號",
|
||||
"窗口名": "視窗名",
|
||||
"无法识别的路径!": "無法識別的路徑!",
|
||||
"进程": "行程",
|
||||
"到进程": "到行程",
|
||||
@ -716,7 +715,6 @@
|
||||
"过滤历史重复": "過濾歷史重複",
|
||||
"缓存条数": "緩存條數",
|
||||
"腾讯OCR": "騰訊OCR",
|
||||
"添加列表": "添加清單",
|
||||
"删除列表": "删除清單",
|
||||
"上移": "上移",
|
||||
"下移": "下移",
|
||||
@ -813,5 +811,6 @@
|
||||
"上传游戏": "上傳遊戲",
|
||||
"以当前md5复制选中行": "以當前md5複製選中行",
|
||||
"修改列表名称": "修改清單名稱",
|
||||
"滚动到最后": "滾動到最後"
|
||||
"滚动到最后": "滾動到最後",
|
||||
"创建列表": "創建清單"
|
||||
}
|
@ -388,7 +388,6 @@
|
||||
"错误": "Error",
|
||||
"所选文件格式错误!": "Invalid File Format Selected!",
|
||||
"进程号": "Process ID",
|
||||
"窗口名": "Window name",
|
||||
"无法识别的路径!": "Unrecognizable Path!",
|
||||
"进程": "Process",
|
||||
"到进程": "Select Process",
|
||||
@ -558,7 +557,6 @@
|
||||
"点击单词复制": "Copy On Click",
|
||||
"窗口背景透明": "Window Background Transparency",
|
||||
"背景窗口透明": "Background Window Transparency",
|
||||
"指定模式": "Specify Mode",
|
||||
"搜索范围": "Search Range",
|
||||
"搜索方式": "Search Method",
|
||||
"使用翻译缓存": "Use Translation Cache",
|
||||
@ -716,7 +714,6 @@
|
||||
"过滤历史重复": "Filter Historical Duplicates",
|
||||
"缓存条数": "Number of Cached Items",
|
||||
"腾讯OCR": "Tencent OCR",
|
||||
"添加列表": "Add List",
|
||||
"删除列表": "Delete List",
|
||||
"上移": "Move Up",
|
||||
"下移": "Move Down",
|
||||
@ -813,5 +810,7 @@
|
||||
"上传游戏": "Upload Game",
|
||||
"以当前md5复制选中行": "Copy Selected Row with Current MD5",
|
||||
"修改列表名称": "Modify List Name",
|
||||
"滚动到最后": "Scroll to End"
|
||||
}
|
||||
"滚动到最后": "Scroll to End",
|
||||
"指定模块": "Specify modules",
|
||||
"创建列表": "Create List"
|
||||
}
|
@ -388,7 +388,6 @@
|
||||
"错误": "Error",
|
||||
"所选文件格式错误!": "¡¡ el archivo seleccionado tiene un formato incorrecto!",
|
||||
"进程号": "Número de proceso",
|
||||
"窗口名": "Nombre de la ventana",
|
||||
"无法识别的路径!": "¡Caminos no reconocibles!",
|
||||
"进程": "Proceso",
|
||||
"到进程": "Al proceso",
|
||||
@ -716,7 +715,6 @@
|
||||
"过滤历史重复": "Filtrar repetición histórica",
|
||||
"缓存条数": "Número de barras de caché",
|
||||
"腾讯OCR": "Tencent OCR",
|
||||
"添加列表": "Añadir lista",
|
||||
"删除列表": "Eliminar lista",
|
||||
"上移": "Subir",
|
||||
"下移": "Bajar",
|
||||
@ -813,5 +811,6 @@
|
||||
"上传游戏": "Sube el juego",
|
||||
"以当前md5复制选中行": "Copiar la línea seleccionada con el MD5 actual",
|
||||
"修改列表名称": "Modificar el nombre de la lista",
|
||||
"滚动到最后": "Rodar hasta el final"
|
||||
"滚动到最后": "Rodar hasta el final",
|
||||
"创建列表": "Crear lista"
|
||||
}
|
@ -388,7 +388,6 @@
|
||||
"错误": "Erreur",
|
||||
"所选文件格式错误!": "Mauvais format de fichier sélectionné!",
|
||||
"进程号": "Numéro de processus",
|
||||
"窗口名": "Nom de la fenêtre",
|
||||
"无法识别的路径!": "Un chemin méconnaissable!",
|
||||
"进程": "Processus",
|
||||
"到进程": "Au processus",
|
||||
@ -716,7 +715,6 @@
|
||||
"过滤历史重复": "Filtrer historique répétition",
|
||||
"缓存条数": "Nombre de barres de cache",
|
||||
"腾讯OCR": "OCR Tencent",
|
||||
"添加列表": "Ajouter une liste",
|
||||
"删除列表": "Supprimer une liste",
|
||||
"上移": "Déplacement vers le Haut",
|
||||
"下移": "Descendre",
|
||||
@ -813,5 +811,6 @@
|
||||
"上传游戏": "Télécharger un jeu",
|
||||
"以当前md5复制选中行": "Copier la ligne sélectionnée avec le MD5 actuel",
|
||||
"修改列表名称": "Modifier le nom de la Liste",
|
||||
"滚动到最后": "Rouler jusqu'à la fin"
|
||||
"滚动到最后": "Rouler jusqu'à la fin",
|
||||
"创建列表": "Créer une liste"
|
||||
}
|
@ -376,7 +376,6 @@
|
||||
"错误": "errore",
|
||||
"所选文件格式错误!": "Il formato del file selezionato non è corretto!",
|
||||
"进程号": "Numero del processo",
|
||||
"窗口名": "Nome finestra",
|
||||
"无法识别的路径!": "Percorso sconosciuto!",
|
||||
"进程": "processo",
|
||||
"到进程": "Da elaborare",
|
||||
@ -716,7 +715,6 @@
|
||||
"过滤历史重复": "Filtra duplicati storici",
|
||||
"缓存条数": "Numero di voci della cache",
|
||||
"腾讯OCR": "Tencent OCR",
|
||||
"添加列表": "Aggiungi elenco",
|
||||
"删除列表": "Elimina elenco",
|
||||
"上移": "Sposta su",
|
||||
"下移": "Sposta giù",
|
||||
@ -813,5 +811,6 @@
|
||||
"上传游戏": "Carica gioco",
|
||||
"以当前md5复制选中行": "Copia la riga selezionata con l'MD5 corrente",
|
||||
"修改列表名称": "Modifica nome elenco",
|
||||
"滚动到最后": "Scorri fino alla fine"
|
||||
"滚动到最后": "Scorri fino alla fine",
|
||||
"创建列表": "Crea elenco"
|
||||
}
|
@ -388,7 +388,6 @@
|
||||
"错误": "エラー",
|
||||
"所选文件格式错误!": "選択したファイルフォーマットが間違っています!",
|
||||
"进程号": "プロセス番号",
|
||||
"窗口名": "ウィンドウ名",
|
||||
"无法识别的路径!": "認識できないパス!",
|
||||
"进程": "プロセス",
|
||||
"到进程": "プロセスへ",
|
||||
@ -716,7 +715,6 @@
|
||||
"过滤历史重复": "フィルタ履歴の繰り返し",
|
||||
"缓存条数": "キャッシュ・エントリ数",
|
||||
"腾讯OCR": "テンセントOCR",
|
||||
"添加列表": "リストの追加",
|
||||
"删除列表": "リストの削除",
|
||||
"上移": "上へ移動",
|
||||
"下移": "下へ移動",
|
||||
@ -813,5 +811,6 @@
|
||||
"上传游戏": "ゲームをアップロード",
|
||||
"以当前md5复制选中行": "選択した行を現在のmd 5でコピー",
|
||||
"修改列表名称": "リスト名の変更",
|
||||
"滚动到最后": "最後までスクロール"
|
||||
"滚动到最后": "最後までスクロール",
|
||||
"创建列表": "リストの作成"
|
||||
}
|
@ -388,7 +388,6 @@
|
||||
"错误": "오류",
|
||||
"所选文件格式错误!": "선택한 파일의 형식이 잘못되었습니다!",
|
||||
"进程号": "프로세스 번호",
|
||||
"窗口名": "창 이름",
|
||||
"无法识别的路径!": "인식할 수 없는 경로!",
|
||||
"进程": "프로세스",
|
||||
"到进程": "프로세스로",
|
||||
@ -716,7 +715,6 @@
|
||||
"过滤历史重复": "반복된 기록 필터링",
|
||||
"缓存条数": "캐시 바 수",
|
||||
"腾讯OCR": "텐센트 OCR",
|
||||
"添加列表": "목록 추가",
|
||||
"删除列表": "목록 삭제",
|
||||
"上移": "위로 이동",
|
||||
"下移": "아래로 이동",
|
||||
@ -813,5 +811,6 @@
|
||||
"上传游戏": "게임 업로드",
|
||||
"以当前md5复制选中行": "선택된 행을 현재 md5로 복사",
|
||||
"修改列表名称": "목록 이름 수정",
|
||||
"滚动到最后": "끝까지 스크롤"
|
||||
"滚动到最后": "끝까지 스크롤",
|
||||
"创建列表": "목록 만들기"
|
||||
}
|
@ -388,7 +388,6 @@
|
||||
"错误": "błąd",
|
||||
"所选文件格式错误!": "Wybrany format pliku jest niepoprawny!",
|
||||
"进程号": "Numer procesu",
|
||||
"窗口名": "Nazwa okna",
|
||||
"无法识别的路径!": "Nierozpoznana ścieżka!",
|
||||
"进程": "proces",
|
||||
"到进程": "Do przetwarzania",
|
||||
@ -716,7 +715,6 @@
|
||||
"过滤历史重复": "Filtruj duplikaty historyczne",
|
||||
"缓存条数": "Liczba wpisów pamięci podręcznej",
|
||||
"腾讯OCR": "Dziesięć OCR",
|
||||
"添加列表": "Dodaj listę",
|
||||
"删除列表": "Usuń listę",
|
||||
"上移": "Przesuń się w górę",
|
||||
"下移": "Przesuń w dół",
|
||||
@ -813,5 +811,6 @@
|
||||
"上传游戏": "Przesyłaj grę",
|
||||
"以当前md5复制选中行": "Kopiuj zaznaczony wiersz z bieżącym MD5",
|
||||
"修改列表名称": "Zmień nazwę listy",
|
||||
"滚动到最后": "Przewiń do końca"
|
||||
"滚动到最后": "Przewiń do końca",
|
||||
"创建列表": "Utwórz listę"
|
||||
}
|
@ -388,7 +388,6 @@
|
||||
"错误": "Ошибка",
|
||||
"所选文件格式错误!": "Ошибка формата выбранного файла!",
|
||||
"进程号": "Номер процесса",
|
||||
"窗口名": "Имя окна",
|
||||
"无法识别的路径!": "Невозможно определить путь!",
|
||||
"进程": "Процесс",
|
||||
"到进程": "К процессу",
|
||||
@ -716,7 +715,6 @@
|
||||
"过滤历史重复": "Фильтровать повторение истории",
|
||||
"缓存条数": "Количество кэшированных записей",
|
||||
"腾讯OCR": "Скачать OCR",
|
||||
"添加列表": "Добавить список",
|
||||
"删除列表": "Удалить список",
|
||||
"上移": "Переместить вверх",
|
||||
"下移": "Переместить вниз",
|
||||
@ -813,5 +811,6 @@
|
||||
"上传游戏": "Загрузить игру",
|
||||
"以当前md5复制选中行": "Копировать выделенную строку в текущем MD5",
|
||||
"修改列表名称": "Изменить имя списка",
|
||||
"滚动到最后": "Прокрутить до конца"
|
||||
"滚动到最后": "Прокрутить до конца",
|
||||
"创建列表": "Создать список"
|
||||
}
|
@ -59,7 +59,6 @@
|
||||
"插值算法": "อัลกอริทึมการแทรก",
|
||||
"显示帧率": "แสดงอัตราเฟรม",
|
||||
"最新版本": "รุ่นล่าสุด",
|
||||
"窗口名": "ชื่อหน้าต่าง",
|
||||
"搜索": "ค้นหา",
|
||||
"游戏信息": "ข้อมูลเกม",
|
||||
"特殊码": "รหัสพิเศษ",
|
||||
@ -716,7 +715,6 @@
|
||||
"过滤历史重复": "ประวัติการกรอง ทำซ้ำ",
|
||||
"缓存条数": "จำนวนแถบแคช",
|
||||
"腾讯OCR": "Tencent โอซีอาร์",
|
||||
"添加列表": "เพิ่มรายการ",
|
||||
"删除列表": "ลบรายการ",
|
||||
"上移": "เลื่อนขึ้น",
|
||||
"下移": "เลื่อนลง",
|
||||
@ -813,5 +811,6 @@
|
||||
"上传游戏": "อัปโหลดเกม",
|
||||
"以当前md5复制选中行": "คัดลอกแถวที่เลือกด้วย md5 ปัจจุบัน",
|
||||
"修改列表名称": "แก้ไขชื่อรายการ",
|
||||
"滚动到最后": "เลื่อนไปจนสุด"
|
||||
"滚动到最后": "เลื่อนไปจนสุด",
|
||||
"创建列表": "สร้างรายการ"
|
||||
}
|
@ -388,7 +388,6 @@
|
||||
"错误": "hata",
|
||||
"所选文件格式错误!": "Seçili dosya format ı yanlış!",
|
||||
"进程号": "İşlem numarası",
|
||||
"窗口名": "Pencere İsmi",
|
||||
"无法识别的路径!": "Bilinmeyen yol!",
|
||||
"进程": "işlem",
|
||||
"到进程": "İşleme",
|
||||
@ -716,7 +715,6 @@
|
||||
"过滤历史重复": "Tarihi çizgileri sil",
|
||||
"缓存条数": "Cache girişlerinin sayısı",
|
||||
"腾讯OCR": "Tencent OCR",
|
||||
"添加列表": "Liste Ekle",
|
||||
"删除列表": "Listeyi sil",
|
||||
"上移": "Yukarı Taşı",
|
||||
"下移": "Aşağı taşın",
|
||||
@ -813,5 +811,6 @@
|
||||
"上传游戏": "Oyunu yükle",
|
||||
"以当前md5复制选中行": "Seçili satırı mevcut MD5 ile kopyalayın",
|
||||
"修改列表名称": "Liste ismini değiştir",
|
||||
"滚动到最后": "Sonuna doğru yürüt"
|
||||
"滚动到最后": "Sonuna doğru yürüt",
|
||||
"创建列表": "Liste oluştur"
|
||||
}
|
@ -376,7 +376,6 @@
|
||||
"错误": "помилка",
|
||||
"所选文件格式错误!": "Вибраний формат файла неправильний!",
|
||||
"进程号": "Номер процесу",
|
||||
"窗口名": "Назва вікна",
|
||||
"无法识别的路径!": "Нерозпізнаний шлях!",
|
||||
"进程": "процес",
|
||||
"到进程": "Процес",
|
||||
@ -716,7 +715,6 @@
|
||||
"过滤历史重复": "Фільтрувати історичні дублікати",
|
||||
"缓存条数": "Кількість записів кешу",
|
||||
"腾讯OCR": "Похильний OCR",
|
||||
"添加列表": "Додати список",
|
||||
"删除列表": "Вилучити список",
|
||||
"上移": "Пересунути вгору",
|
||||
"下移": "Пересунути вниз",
|
||||
@ -813,5 +811,6 @@
|
||||
"上传游戏": "Вивантажити гру",
|
||||
"以当前md5复制选中行": "Копіювати вибраний рядок поточним MD5",
|
||||
"修改列表名称": "Змінити назву списку",
|
||||
"滚动到最后": "Пересунутися до кінця"
|
||||
"滚动到最后": "Пересунутися до кінця",
|
||||
"创建列表": "Створити список"
|
||||
}
|
@ -388,7 +388,6 @@
|
||||
"错误": "Lỗi",
|
||||
"所选文件格式错误!": "Lỗi định dạng tập tin đã chọn!",
|
||||
"进程号": "Số tiến trình",
|
||||
"窗口名": "Tên cửa sổ",
|
||||
"无法识别的路径!": "Đường không nhận ra!",
|
||||
"进程": "Quy trình",
|
||||
"到进程": "Tiến trình",
|
||||
@ -716,7 +715,6 @@
|
||||
"过滤历史重复": "Lọc lịch sử lặp lại",
|
||||
"缓存条数": "Số thanh bộ nhớ cache",
|
||||
"腾讯OCR": "Thông tin OCR",
|
||||
"添加列表": "Thêm danh sách",
|
||||
"删除列表": "Xoá danh sách",
|
||||
"上移": "Di chuyển lên",
|
||||
"下移": "Di chuyển xuống",
|
||||
@ -813,5 +811,6 @@
|
||||
"上传游戏": "Tải lên trò chơi",
|
||||
"以当前md5复制选中行": "Dòng đã chọn sao chép md5 hiện tại",
|
||||
"修改列表名称": "Thay đổi tên danh sách",
|
||||
"滚动到最后": "Cuộn đến cuối"
|
||||
"滚动到最后": "Cuộn đến cuối",
|
||||
"创建列表": "Tạo danh sách"
|
||||
}
|
@ -60,7 +60,6 @@
|
||||
"插值算法": "",
|
||||
"显示帧率": "",
|
||||
"最新版本": "",
|
||||
"窗口名": "",
|
||||
"搜索": "",
|
||||
"游戏信息": "",
|
||||
"特殊码": "",
|
||||
@ -724,7 +723,7 @@
|
||||
"过滤历史重复": "",
|
||||
"缓存条数": "",
|
||||
"腾讯OCR": "",
|
||||
"添加列表": "",
|
||||
"创建列表": "",
|
||||
"删除列表": "",
|
||||
"上移": "",
|
||||
"下移": "",
|
||||
|
@ -28,7 +28,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/version)
|
||||
include(generate_product_version)
|
||||
|
||||
set(VERSION_MAJOR 5)
|
||||
set(VERSION_MINOR 5)
|
||||
set(VERSION_MINOR 6)
|
||||
set(VERSION_PATCH 0)
|
||||
|
||||
add_library(pch pch.cpp)
|
||||
|
@ -55,7 +55,9 @@ DECLARE void recoverwindow(HWND hwnd, windowstatus status)
|
||||
DECLARE bool pid_running(DWORD pid)
|
||||
{
|
||||
DWORD code;
|
||||
GetExitCodeProcess(AutoHandle(OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid)), &code);
|
||||
GetExitCodeProcess(AutoHandle(OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid)), &code);
|
||||
// 句柄必須具有 PROCESS_QUERY_INFORMATION 或 PROCESS_QUERY_LIMITED_INFORMATION 訪問許可權。 如需詳細資訊,請參閱 處理安全性和訪問許可權。
|
||||
// Windows Server 2003 和 Windows XP: 句柄必須具有 PROCESS_QUERY_INFORMATION 訪問許可權。
|
||||
return code == STILL_ACTIVE;
|
||||
// auto process = AutoHandle(OpenProcess(SYNCHRONIZE, FALSE, pid));
|
||||
// DWORD ret = WaitForSingleObject(process, 0);
|
||||
@ -95,7 +97,9 @@ DECLARE bool Is64bit(DWORD pid)
|
||||
GetNativeSystemInfo(&sysinfo);
|
||||
if (sysinfo.wProcessorArchitecture == 9 || sysinfo.wProcessorArchitecture == 6)
|
||||
{
|
||||
auto hprocess = AutoHandle(OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid));
|
||||
auto hprocess = AutoHandle(OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid));
|
||||
// 進程的控制碼。 控制碼必須具有PROCESS_QUERY_INFORMATION或PROCESS_QUERY_LIMITED_INFORMATION存取權限。 如需詳細資訊,請參閱 處理安全性和存取權限。
|
||||
// Windows Server 2003 和 Windows XP: 控制碼必須具有PROCESS_QUERY_INFORMATION存取權限。
|
||||
BOOL b;
|
||||
IsWow64Process(hprocess, &b);
|
||||
return !b;
|
||||
|
Loading…
x
Reference in New Issue
Block a user