diff --git a/LunaTranslator/LunaTranslator/LunaTranslator.py b/LunaTranslator/LunaTranslator/LunaTranslator.py
index bc7c7bc9..8afb4e6e 100644
--- a/LunaTranslator/LunaTranslator/LunaTranslator.py
+++ b/LunaTranslator/LunaTranslator/LunaTranslator.py
@@ -6,6 +6,8 @@ from myutils.config import (
globalconfig,
_TR,
savehook_new_list,
+ uid2gamepath,
+ gamepath2uid,
savehook_new_data,
setlanguage,
static_data,
@@ -407,7 +409,9 @@ class MAINUI:
try:
time.sleep(globalconfig["textthreaddelay"] / 1000)
name = self.textsource.currentname
- names = savehook_new_data[self.textsource.pname]["allow_tts_auto_names_v4"]
+ names = savehook_new_data[self.textsource.gameuid][
+ "allow_tts_auto_names_v4"
+ ]
needpass = False
if name in names:
needpass = True
@@ -438,7 +442,7 @@ class MAINUI:
text = self.ttsrepair(self.currentread, globalconfig["ttscommon"])
try:
text = self.ttsrepair(
- text, savehook_new_data[self.textsource.pname]
+ text, savehook_new_data[self.textsource.gameuid]
)
except:
pass
@@ -476,7 +480,8 @@ class MAINUI:
pids, pexe, hwnd = selectedp
checkifnewgame(savehook_new_list, pexe, windows.GetWindowText(hwnd))
if globalconfig["sourcestatus2"]["texthook"]["use"]:
- self.textsource = texthook(pids, hwnd, pexe)
+ self.textsource = texthook(pids, hwnd, pexe, gamepath2uid[pexe])
+ self.textsource.start()
def starttextsource(self, use=None, checked=True):
self.translation_ui.showhidestate = False
@@ -683,7 +688,11 @@ class MAINUI:
hwnd = windows.GetForegroundWindow()
pid = windows.GetWindowThreadProcessId(hwnd)
name_ = getpidexe(pid)
- if name_ and name_ in savehook_new_list:
+ if (
+ name_
+ and name_ in gamepath2uid
+ and gamepath2uid[name_] in savehook_new_list
+ ):
lps = ListProcess(False)
for pids, _exe in lps:
if _exe == name_:
@@ -692,23 +701,26 @@ class MAINUI:
self.textsource = None
if globalconfig["sourcestatus2"]["texthook"]["use"]:
if globalconfig["startgamenototop"] == False:
- idx = savehook_new_list.index(name_)
+ idx = savehook_new_list.index(
+ gamepath2uid[name_]
+ )
savehook_new_list.insert(
0, savehook_new_list.pop(idx)
)
- needinserthookcode = savehook_new_data[name_][
- "needinserthookcode"
- ]
+ needinserthookcode = savehook_new_data[
+ gamepath2uid[name_]
+ ]["needinserthookcode"]
self.textsource = texthook(
pids,
hwnd,
name_,
- autostarthookcode=savehook_new_data[name_][
- "hook"
- ],
+ 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:
@@ -778,9 +790,10 @@ class MAINUI:
)
def createsavegamedb(self):
- os.makedirs("userconfig", exist_ok=True)
self.sqlsavegameinfo = sqlite3.connect(
- "userconfig/savegame.db", check_same_thread=False, isolation_level=None
+ gobject.getuserconfigdir("savegame.db"),
+ check_same_thread=False,
+ isolation_level=None,
)
try:
self.sqlsavegameinfo.execute(
@@ -843,21 +856,22 @@ class MAINUI:
savehook_new_data[k].pop("imagepath")
savehook_new_data[k].pop("imagepath_much2")
- def querytraceplaytime_v4(self, k):
- gameinternalid = self.get_gameinternalid(k)
+ def querytraceplaytime_v4(self, gameuid):
+ gameinternalid = self.get_gameinternalid(uid2gamepath[gameuid])
return self.sqlsavegameinfo.execute(
"SELECT timestart,timestop FROM traceplaytime_v4 WHERE gameinternalid = ?",
(gameinternalid,),
).fetchall()
- def get_gameinternalid(self, k):
+ def get_gameinternalid(self, gamepath):
while True:
ret = self.sqlsavegameinfo.execute(
- "SELECT gameinternalid FROM gameinternalid WHERE gamepath = ?", (k,)
+ "SELECT gameinternalid FROM gameinternalid WHERE gamepath = ?",
+ (gamepath,),
).fetchone()
if ret is None:
self.sqlsavegameinfo.execute(
- "INSERT INTO gameinternalid VALUES(NULL,?)", (k,)
+ "INSERT INTO gameinternalid VALUES(NULL,?)", (gamepath,)
)
else:
return ret[0]
@@ -869,9 +883,9 @@ class MAINUI:
(to, _id),
)
- def traceplaytime(self, k, start, end, new):
+ def traceplaytime(self, gamepath, start, end, new):
- gameinternalid = self.get_gameinternalid(k)
+ gameinternalid = self.get_gameinternalid(gamepath)
if new:
self.sqlsavegameinfo.execute(
"INSERT INTO traceplaytime_v4 VALUES(NULL,?,?,?)",
@@ -891,16 +905,21 @@ class MAINUI:
time.sleep(1)
_t = time.time()
- def isok(name_):
- savehook_new_data[name_]["statistic_playtime"] += _t - __t
+ def isok(gameuid):
+ savehook_new_data[gameuid]["statistic_playtime"] += _t - __t
if self.__currentexe == name_:
- self.traceplaytime(name_, self.__statistictime - 1, _t, False)
+ self.traceplaytime(
+ uid2gamepath[gameuid], self.__statistictime - 1, _t, False
+ )
else:
self.__statistictime = time.time()
self.__currentexe = name_
self.traceplaytime(
- name_, self.__statistictime - 1, self.__statistictime, True
+ uid2gamepath[gameuid],
+ self.__statistictime - 1,
+ self.__statistictime,
+ True,
)
try:
@@ -911,13 +930,17 @@ class MAINUI:
if len(self.textsource.pids) == 0:
raise Exception()
if _pid in self.textsource.pids or _pid == os.getpid():
- isok(self.textsource.pname)
+ isok(self.textsource.gameuid)
else:
self.__currentexe = None
except:
name_ = getpidexe(_pid)
- if name_ and name_ in savehook_new_list:
- isok(name_)
+ if (
+ name_
+ and name_ in gamepath2uid
+ and gamepath2uid[name_] in savehook_new_list
+ ):
+ isok(gamepath2uid[name_])
else:
self.__currentexe = None
except:
diff --git a/LunaTranslator/LunaTranslator/cishu/goo.py b/LunaTranslator/LunaTranslator/cishu/goo.py
index 65c38a5d..ed217088 100644
--- a/LunaTranslator/LunaTranslator/cishu/goo.py
+++ b/LunaTranslator/LunaTranslator/cishu/goo.py
@@ -1,6 +1,6 @@
import requests
from urllib.parse import quote
-import re, os
+import re, os, gobject
from cishu.cishubase import cishubase
@@ -12,15 +12,15 @@ class goo(cishubase):
xx = re.findall("", x)
xx = "".join(xx).replace('href="/', 'href="https://dictionary.goo.ne.jp/')
- if os.path.exists("cache/temp/goo.css") == False:
+ temp = gobject.gettempdir("goo.css")
+ if os.path.exists(temp) == False:
stl = requests.get(
"https://dictionary.goo.ne.jp/mix/css/app.css", proxies=self.proxy
).text
- os.makedirs("cache/temp", exist_ok=True)
- with open("cache/temp/goo.css", "w", encoding="utf8") as ff:
+ with open(temp, "w", encoding="utf8") as ff:
ff.write(stl)
else:
- with open("cache/temp/goo.css", "r", encoding="utf8") as ff:
+ with open(temp, "r", encoding="utf8") as ff:
stl = ff.read()
if len(xx):
diff --git a/LunaTranslator/LunaTranslator/cishu/mdict.py b/LunaTranslator/LunaTranslator/cishu/mdict.py
index 1c626eb4..295bbcd4 100644
--- a/LunaTranslator/LunaTranslator/cishu/mdict.py
+++ b/LunaTranslator/LunaTranslator/cishu/mdict.py
@@ -1,4 +1,4 @@
-import math, base64, uuid
+import math, base64, uuid, gobject
import threading, time
@@ -341,270 +341,12 @@ def rol(s, x):
return (x << s | x >> (32 - s)) & 0xFFFFFFFF
-r = [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 9,
- 10,
- 11,
- 12,
- 13,
- 14,
- 15,
- 7,
- 4,
- 13,
- 1,
- 10,
- 6,
- 15,
- 3,
- 12,
- 0,
- 9,
- 5,
- 2,
- 14,
- 11,
- 8,
- 3,
- 10,
- 14,
- 4,
- 9,
- 15,
- 8,
- 1,
- 2,
- 7,
- 0,
- 6,
- 13,
- 11,
- 5,
- 12,
- 1,
- 9,
- 11,
- 10,
- 0,
- 8,
- 12,
- 4,
- 13,
- 3,
- 7,
- 15,
- 14,
- 5,
- 6,
- 2,
-]
-rp = [
- 5,
- 14,
- 7,
- 0,
- 9,
- 2,
- 11,
- 4,
- 13,
- 6,
- 15,
- 8,
- 1,
- 10,
- 3,
- 12,
- 6,
- 11,
- 3,
- 7,
- 0,
- 13,
- 5,
- 10,
- 14,
- 15,
- 8,
- 12,
- 4,
- 9,
- 1,
- 2,
- 15,
- 5,
- 1,
- 3,
- 7,
- 14,
- 6,
- 9,
- 11,
- 8,
- 12,
- 2,
- 10,
- 0,
- 4,
- 13,
- 8,
- 6,
- 4,
- 1,
- 3,
- 11,
- 15,
- 0,
- 5,
- 12,
- 2,
- 13,
- 9,
- 7,
- 10,
- 14,
-]
-s = [
- 11,
- 14,
- 15,
- 12,
- 5,
- 8,
- 7,
- 9,
- 11,
- 13,
- 14,
- 15,
- 6,
- 7,
- 9,
- 8,
- 7,
- 6,
- 8,
- 13,
- 11,
- 9,
- 7,
- 15,
- 7,
- 12,
- 15,
- 9,
- 11,
- 7,
- 13,
- 12,
- 11,
- 13,
- 6,
- 7,
- 14,
- 9,
- 13,
- 15,
- 14,
- 8,
- 13,
- 6,
- 5,
- 12,
- 7,
- 5,
- 11,
- 12,
- 14,
- 15,
- 14,
- 15,
- 9,
- 8,
- 9,
- 14,
- 5,
- 6,
- 8,
- 6,
- 5,
- 12,
-]
-sp = [
- 8,
- 9,
- 9,
- 11,
- 13,
- 15,
- 15,
- 5,
- 7,
- 7,
- 8,
- 11,
- 14,
- 14,
- 12,
- 6,
- 9,
- 13,
- 15,
- 7,
- 12,
- 8,
- 9,
- 11,
- 7,
- 7,
- 12,
- 7,
- 6,
- 15,
- 13,
- 11,
- 9,
- 7,
- 15,
- 11,
- 8,
- 6,
- 6,
- 14,
- 12,
- 13,
- 5,
- 14,
- 13,
- 13,
- 7,
- 5,
- 15,
- 5,
- 8,
- 11,
- 14,
- 14,
- 6,
- 14,
- 6,
- 9,
- 12,
- 9,
- 12,
- 5,
- 15,
- 8,
-]
+# fmt: off
+r = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 7, 4, 13, 1, 10, 6, 15, 3, 12, 0, 9, 5, 2, 14, 11, 8, 3, 10, 14, 4, 9, 15, 8, 1, 2, 7, 0, 6, 13, 11, 5, 12, 1, 9, 11, 10, 0, 8, 12, 4, 13, 3, 7, 15, 14, 5, 6, 2]
+rp = [ 5, 14, 7, 0, 9, 2, 11, 4, 13, 6, 15, 8, 1, 10, 3, 12, 6, 11, 3, 7, 0, 13, 5, 10, 14, 15, 8, 12, 4, 9, 1, 2, 15, 5, 1, 3, 7, 14, 6, 9, 11, 8, 12, 2, 10, 0, 4, 13, 8, 6, 4, 1, 3, 11, 15, 0, 5, 12, 2, 13, 9, 7, 10, 14]
+s = [ 11, 14, 15, 12, 5, 8, 7, 9, 11, 13, 14, 15, 6, 7, 9, 8, 7, 6, 8, 13, 11, 9, 7, 15, 7, 12, 15, 9, 11, 7, 13, 12, 11, 13, 6, 7, 14, 9, 13, 15, 14, 8, 13, 6, 5, 12, 7, 5, 11, 12, 14, 15, 14, 15, 9, 8, 9, 14, 5, 6, 8, 6, 5, 12]
+sp = [ 8, 9, 9, 11, 13, 15, 15, 5, 7, 7, 8, 11, 14, 14, 12, 6, 9, 13, 15, 7, 12, 8, 9, 11, 7, 7, 12, 7, 6, 15, 13, 11, 9, 7, 15, 11, 8, 6, 6, 14, 12, 13, 5, 14, 13, 13, 7, 5, 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8]
+# fmt: on
def ripemd128(message):
@@ -1962,13 +1704,12 @@ class IndexBuilder(object):
_filename, _file_extension = os.path.splitext(fname)
assert _file_extension == ".mdx"
assert os.path.isfile(fname)
- os.makedirs("cache/mdict/index", exist_ok=True)
_mdxmd5 = (
os.path.basename(_filename)
+ "_"
+ hashlib.md5(_filename.encode("utf8")).hexdigest()
)
- _targetfilenamebase = os.path.join("cache/mdict/index", _mdxmd5)
+ _targetfilenamebase = gobject.getcachedir("mdict/index/" + _mdxmd5)
self._mdx_db = _targetfilenamebase + ".mdx.db"
# make index anyway
if force_rebuild:
@@ -2363,7 +2104,9 @@ class mdict(cishubase):
self.init_once_mdx(f)
try:
- with open("userconfig/mdict_config.json", "w", encoding="utf8") as ff:
+ with open(
+ gobject.getuserconfigdir("mdict_config.json"), "w", encoding="utf8"
+ ) as ff:
ff.write(json.dumps(self.extraconf, ensure_ascii=False, indent=4))
except:
pass
diff --git a/LunaTranslator/LunaTranslator/gobject.py b/LunaTranslator/LunaTranslator/gobject.py
index 44c6e02b..c266f69b 100644
--- a/LunaTranslator/LunaTranslator/gobject.py
+++ b/LunaTranslator/LunaTranslator/gobject.py
@@ -15,6 +15,30 @@ def GetDllpath(_, base=None):
return os.path.join(base, _[isbit64])
+def getcachedir(name, basedir="cache"):
+
+ fd = os.path.dirname(name)
+ fn = os.path.basename(name)
+ fn1 = os.path.abspath(basedir)
+ fn1 = os.path.join(fn1, fd)
+ os.makedirs(fn1, exist_ok=True)
+ fn1 = os.path.join(fn1, fn)
+ return fn1
+
+
+def getuserconfigdir(name):
+ return getcachedir(name, "userconfig")
+
+
+def gettranslationrecorddir(name):
+ return getcachedir(name, "translation_record")
+
+
+def gettempdir(filename):
+ tgt = getcachedir(os.path.join(f"temp{os.getpid()}", filename))
+ return tgt
+
+
def dopathexists(file):
if not file:
return False
diff --git a/LunaTranslator/LunaTranslator/gui/dialog_memory.py b/LunaTranslator/LunaTranslator/gui/dialog_memory.py
index 062ee16e..70412f5f 100644
--- a/LunaTranslator/LunaTranslator/gui/dialog_memory.py
+++ b/LunaTranslator/LunaTranslator/gui/dialog_memory.py
@@ -1,5 +1,5 @@
from qtsymbols import *
-import os
+import os, gobject
from myutils.config import _TR, globalconfig
from myutils.wrapper import Singleton_close
from gui.usefulwidget import saveposwindow
@@ -30,8 +30,7 @@ class dialog_memory(saveposwindow):
self.gamemd5 = gamemd5
formLayout = QVBoxLayout() #
self.showtext = QTextEdit()
- os.makedirs("./userconfig/memory", exist_ok=True)
- self.rwpath = "./userconfig/memory/{}.html".format(gamemd5)
+ self.rwpath = gobject.getuserconfigdir("memory/{}.html".format(gamemd5))
try:
with open(self.rwpath, "r", encoding="utf8") as ff:
text = ff.read()
diff --git a/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py b/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py
index cf22cb05..426bd489 100644
--- a/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py
+++ b/LunaTranslator/LunaTranslator/gui/dialog_savedgame.py
@@ -6,7 +6,9 @@ import windows, gobject, winsharedutils
from myutils.config import (
savehook_new_list,
savehook_new_data,
+ gamepath2uid,
savegametaged,
+ uid2gamepath,
_TR,
_TRL,
postprocessconfig,
@@ -57,6 +59,7 @@ from gui.usefulwidget import (
tabadd_lazy,
getsimpleswitch,
threebuttons,
+ getsimplekeyseq,
getspinbox,
selectcolor,
listediter,
@@ -87,7 +90,7 @@ class ItemWidget(QWidget):
if self != ItemWidget.globallashfocus:
ItemWidget.clearfocus()
ItemWidget.globallashfocus = self
- self.focuschanged.emit(True, self.exe)
+ self.focuschanged.emit(True, self.gameuid)
except:
print_exc()
@@ -96,16 +99,16 @@ class ItemWidget(QWidget):
def focusOut(self):
self.bottommask.setStyleSheet("background-color: rgba(255,255,255, 0);")
- self.focuschanged.emit(False, self.exe)
+ self.focuschanged.emit(False, self.gameuid)
def mouseDoubleClickEvent(self, e):
- self.doubleclicked.emit(self.exe)
+ self.doubleclicked.emit(self.gameuid)
def resizeEvent(self, a0: QResizeEvent) -> None:
self.bottommask.resize(a0.size())
self.maskshowfileexists.resize(a0.size())
- def __init__(self, exe, pixmap, file) -> None:
+ def __init__(self, gameuid, pixmap, file) -> None:
super().__init__()
self.itemw = globalconfig["dialog_savegame_layout"]["itemw"]
self.itemh = globalconfig["dialog_savegame_layout"]["itemh"]
@@ -147,9 +150,11 @@ class ItemWidget(QWidget):
self._lb.setAlignment(Qt.AlignmentFlag.AlignHCenter)
layout.addWidget(self._lb)
self.setLayout(layout)
- self.exe = exe
+ self.gameuid = gameuid
c = globalconfig["dialog_savegame_layout"][
- ("onfilenoexistscolor1", "backcolor1")[os.path.exists(exe)]
+ ("onfilenoexistscolor1", "backcolor1")[
+ os.path.exists(uid2gamepath[gameuid])
+ ]
]
c = str2rgba(c, globalconfig["dialog_savegame_layout"]["transparent"])
self.maskshowfileexists.setStyleSheet(f"background-color:{c};")
@@ -387,39 +392,34 @@ class TagWidget(QWidget):
class browserdialog(saveposwindow):
seturlsignal = pyqtSignal(str)
- def parsehtml(self, newpath):
- if newpath[:4].lower() != "http":
- newpath = os.path.abspath(newpath)
- return newpath
+ def startupsettitle(self, gameuid):
- def startupsettitle(self, exepath):
-
- if exepath:
- title = savehook_new_data[exepath]["title"]
+ if gameuid:
+ title = savehook_new_data[gameuid]["title"]
else:
title = "LunaTranslator"
self.setWindowTitle(title)
- def loadalllinks(self, exepath):
+ def loadalllinks(self, gameuid):
items = []
- if exepath:
- self.setWindowTitle(savehook_new_data[exepath]["title"])
+ if gameuid:
+ self.setWindowTitle(savehook_new_data[gameuid]["title"])
for link in globalconfig["relationlinks"]:
items.append((link[0], tagitem.TYPE_GLOABL_LIKE, link[1]))
- if exepath:
- for link in savehook_new_data[self.exepath]["relationlinks"]:
+ if gameuid:
+ for link in savehook_new_data[self.gameuid]["relationlinks"]:
items.append((link[0], tagitem.TYPE_GAME_LIKE, link[1]))
self.tagswidget.clearTag(False)
self.tagswidget.addTags(items)
- def startupnavi(self, exepath):
+ def startupnavi(self, gameuid):
for idx in range(2, 100):
if idx == 2:
- if exepath:
- if len(savehook_new_data[exepath]["relationlinks"]):
- navitarget = savehook_new_data[exepath]["relationlinks"][-1][1]
+ if gameuid:
+ if len(savehook_new_data[gameuid]["relationlinks"]):
+ navitarget = savehook_new_data[gameuid]["relationlinks"][-1][1]
break
elif idx == 3:
if len(globalconfig["relationlinks"]):
@@ -452,8 +452,8 @@ class browserdialog(saveposwindow):
text = []
for _t in _dia.text:
text.append(_t.text())
- if self.exepath:
- savehook_new_data[self.exepath]["relationlinks"].append(text)
+ if self.gameuid:
+ savehook_new_data[self.gameuid]["relationlinks"].append(text)
self.tagswidget.addTag(text[0], tagitem.TYPE_GAME_LIKE, text[1])
else:
globalconfig["relationlinks"].append(text)
@@ -468,20 +468,20 @@ class browserdialog(saveposwindow):
elif _type == tagitem.TYPE_GAME_LIKE:
__2.append([_name, _url])
globalconfig["relationlinks"] = __
- if self.exepath:
- savehook_new_data[self.exepath]["relationlinks"] = __2
+ if self.gameuid:
+ savehook_new_data[self.gameuid]["relationlinks"] = __2
- def reinit(self, exepath=None):
+ def reinit(self, gameuid=None):
- self.exepath = exepath
- self.loadalllinks(exepath)
- self.startupnavi(exepath)
- self.startupsettitle(exepath)
+ self.gameuid = gameuid
+ self.loadalllinks(gameuid)
+ self.startupnavi(gameuid)
+ self.startupsettitle(gameuid)
- def __init__(self, parent, exepath=None) -> None:
+ def __init__(self, parent, gameuid=None) -> None:
super().__init__(parent, poslist=globalconfig["browserwidget"])
- if exepath:
- self.setWindowIcon(getExeIcon(exepath, cache=True))
+ if gameuid:
+ self.setWindowIcon(getExeIcon(uid2gamepath[gameuid], cache=True))
self.browser = auto_select_webview(self)
self.tagswidget = TagWidget(self)
@@ -513,13 +513,13 @@ class browserdialog(saveposwindow):
__w.setLayout(layout)
self.setCentralWidget(__w)
- self.reinit(exepath)
+ self.reinit(gameuid)
self.show()
def urlclicked(self, _):
tag, _, url = _
- if url.startswith("./cache/vndb"):
- url = self.parsehtml(url)
+ if url[:4].lower() != "http":
+ url = os.path.abspath(url)
self.browser.navigate(url)
def showmenu(self, p):
@@ -533,7 +533,7 @@ class browserdialog(saveposwindow):
if action == shanchu:
self.nettab.setCurrentIndex(0)
self.nettab.removeTab(tab_index)
- savehook_new_data[self.exepath]["relationlinks"].pop(
+ savehook_new_data[self.gameuid]["relationlinks"].pop(
tab_index - self.hasvndb
)
@@ -550,15 +550,15 @@ def calculate_centered_rect(original_rect: QRect, size: QSize) -> QRect:
return new_rect
-def maybehavebutton(self, game, post):
+def maybehavebutton(self, gameuid, post):
if post == "_11":
- savehook_new_data[game]["save_text_process_info"]["mypost"] = str(
+ savehook_new_data[gameuid]["save_text_process_info"]["mypost"] = str(
uuid.uuid4()
).replace("-", "_")
return getIconButton(
callback=functools.partial(
selectdebugfile,
- savehook_new_data[game]["save_text_process_info"]["mypost"],
+ savehook_new_data[gameuid]["save_text_process_info"]["mypost"],
ismypost=True,
),
icon="fa.gear",
@@ -575,14 +575,14 @@ def maybehavebutton(self, game, post):
callback = functools.partial(
postconfigdialog,
self,
- savehook_new_data[game]["save_text_process_info"][
+ savehook_new_data[gameuid]["save_text_process_info"][
"postprocessconfig"
][post]["args"],
postprocessconfig[post]["name"],
)
else:
items = autoinitdialog_items(
- savehook_new_data[game]["save_text_process_info"][
+ savehook_new_data[gameuid]["save_text_process_info"][
"postprocessconfig"
][post]
)
@@ -600,32 +600,29 @@ def maybehavebutton(self, game, post):
class dialog_setting_game_internal(QWidget):
def selectexe(self):
- # 修改exe之后不要去动列表,否则会有一致性问题,很难搞,就这样吧。
- f = QFileDialog.getOpenFileName(directory=self.exepath)
+ f = QFileDialog.getOpenFileName(directory=uid2gamepath[self.gameuid])
res = f[0]
if res == "":
return
-
res = os.path.normpath(res)
- if res in savehook_new_list:
+ if res in gamepath2uid:
return
- _origin = savehook_new_list[savehook_new_list.index(self.exepath)]
- savehook_new_list[savehook_new_list.index(self.exepath)] = res
- savehook_new_data[res] = savehook_new_data[self.exepath]
- gobject.baseobject.resetgameinternal(_origin, res)
+ originpath = uid2gamepath[self.gameuid]
+ gamepath2uid[res] = gamepath2uid.pop(originpath)
+ uid2gamepath[self.gameuid] = res
+ gobject.baseobject.resetgameinternal(originpath, res)
_icon = getExeIcon(res, cache=True)
self.setWindowIcon(_icon)
self.editpath.setText(res)
- self.exepath = res
- def __init__(self, parent, exepath) -> None:
+ def __init__(self, parent, gameuid) -> None:
super().__init__(parent)
vbox = QVBoxLayout(self)
formLayout = QFormLayout()
self.setLayout(vbox)
- self.exepath = exepath
- self.editpath = QLineEdit(exepath)
+ self.gameuid = gameuid
+ self.editpath = QLineEdit(uid2gamepath[gameuid])
self.editpath.setReadOnly(True)
formLayout.addRow(
_TR("路径"),
@@ -634,21 +631,23 @@ class dialog_setting_game_internal(QWidget):
self.editpath,
getIconButton(functools.partial(self.selectexe), icon="fa.gear"),
getIconButton(
- lambda: browserdialog(gobject.baseobject.commonstylebase, exepath),
+ lambda: browserdialog(
+ gobject.baseobject.commonstylebase, gameuid
+ ),
icon="fa.book",
),
]
),
)
- titleedit = QLineEdit(savehook_new_data[exepath]["title"])
+ titleedit = QLineEdit(savehook_new_data[gameuid]["title"])
def _titlechange():
x = titleedit.text()
- titlechangedtask(exepath, x)
+ titlechangedtask(gameuid, x)
self.setWindowTitle(x)
titleedit.textEdited.connect(
- functools.partial(savehook_new_data[exepath].__setitem__, "title")
+ functools.partial(savehook_new_data[gameuid].__setitem__, "title")
)
titleedit.returnPressed.connect(_titlechange)
@@ -661,31 +660,21 @@ class dialog_setting_game_internal(QWidget):
]
),
)
+ functs = [
+ ("启动", self.starttab),
+ ("HOOK", self.gethooktab),
+ ("语言", self.getlangtab),
+ ("文本处理", self.gettextproc),
+ ("标签", self.getlabelsetting),
+ ("元数据", self.metadataorigin),
+ ("统计", self.getstatistic),
+ ("语音", self.getttssetting),
+ ("预翻译", self.getpretranstab),
+ ("Anki", self.maketabforanki),
+ ]
methodtab, do = makesubtab_lazy(
- _TRL(
- [
- "启动",
- "HOOK",
- "语言",
- "文本处理",
- "标签",
- "元数据",
- "统计",
- "语音",
- "预翻译",
- ]
- ),
- [
- functools.partial(self.doaddtab, self.starttab, exepath),
- functools.partial(self.doaddtab, self.gethooktab, exepath),
- functools.partial(self.doaddtab, self.getlangtab, exepath),
- functools.partial(self.doaddtab, self.gettextproc, exepath),
- functools.partial(self.doaddtab, self.getlabelsetting, exepath),
- functools.partial(self.doaddtab, self.metadataorigin, exepath),
- functools.partial(self.doaddtab, self.getstatistic, exepath),
- functools.partial(self.doaddtab, self.getttssetting, exepath),
- functools.partial(self.doaddtab, self.getpretranstab, exepath),
- ],
+ _TRL([_[0] for _ in functs]),
+ [functools.partial(self.doaddtab, _[1], gameuid) for _ in functs],
delay=True,
)
self.methodtab = methodtab
@@ -693,13 +682,13 @@ class dialog_setting_game_internal(QWidget):
vbox.addWidget(methodtab)
do()
- def openrefmainpage(self, key, idname, exepath):
+ def openrefmainpage(self, key, idname, gameuid):
try:
- os.startfile(targetmod[key].refmainpage(savehook_new_data[exepath][idname]))
+ os.startfile(targetmod[key].refmainpage(savehook_new_data[gameuid][idname]))
except:
print_exc()
- def metadataorigin(self, exepath):
+ def metadataorigin(self, gameuid):
formLayout = QFormLayout()
_w = QWidget()
_w.setLayout(formLayout)
@@ -714,24 +703,24 @@ class dialog_setting_game_internal(QWidget):
)
for key in globalconfig["metadata"]:
idname = globalconfig["metadata"][key]["target"]
- vndbid = QLineEdit(str(savehook_new_data[exepath][idname]))
+ vndbid = QLineEdit(str(savehook_new_data[gameuid][idname]))
if globalconfig["metadata"][key]["idtype"] == 0:
vndbid.setValidator(QIntValidator())
vndbid.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Fixed)
vndbid.textEdited.connect(
- functools.partial(savehook_new_data[exepath].__setitem__, idname)
+ functools.partial(savehook_new_data[gameuid].__setitem__, idname)
)
vndbid.returnPressed.connect(
- functools.partial(gamdidchangedtask, key, idname, exepath)
+ functools.partial(gamdidchangedtask, key, idname, gameuid)
)
_vbox_internal = [
vndbid,
getIconButton(
- functools.partial(self.openrefmainpage, key, idname, exepath),
+ functools.partial(self.openrefmainpage, key, idname, gameuid),
icon="fa.chrome",
),
getIconButton(
- functools.partial(gamdidchangedtask, key, idname, exepath),
+ functools.partial(gamdidchangedtask, key, idname, gameuid),
icon="fa.search",
),
]
@@ -754,26 +743,26 @@ class dialog_setting_game_internal(QWidget):
w = wfunct(exe)
layout.addWidget(w)
- def starttab(self, exepath):
+ def starttab(self, gameuid):
_w = QWidget()
formLayout = QFormLayout()
_w.setLayout(formLayout)
- b = windows.GetBinaryType(exepath)
+ b = windows.GetBinaryType(uid2gamepath[gameuid])
if b == 6:
_methods = ["", "Locale_Remulator", "Ntleas"]
else:
_methods = ["Locale-Emulator", "Locale_Remulator", "Ntleas"]
- if b == 6 and savehook_new_data[exepath]["localeswitcher"] == 0:
- savehook_new_data[exepath]["localeswitcher"] = 1
+ if b == 6 and savehook_new_data[gameuid]["localeswitcher"] == 0:
+ savehook_new_data[gameuid]["localeswitcher"] = 1
formLayout.addRow(
_TR("转区启动"),
getboxlayout(
[
- getsimpleswitch(savehook_new_data[exepath], "leuse"),
+ getsimpleswitch(savehook_new_data[gameuid], "leuse"),
getsimplecombobox(
- _TRL(_methods), savehook_new_data[exepath], "localeswitcher"
+ _TRL(_methods), savehook_new_data[gameuid], "localeswitcher"
),
]
),
@@ -783,8 +772,8 @@ class dialog_setting_game_internal(QWidget):
_TR("命令行启动"),
getboxlayout(
[
- getsimpleswitch(savehook_new_data[exepath], "startcmduse"),
- getlineedit(savehook_new_data[exepath], "startcmd"),
+ getsimpleswitch(savehook_new_data[gameuid], "startcmduse"),
+ getlineedit(savehook_new_data[gameuid], "startcmd"),
]
),
)
@@ -793,13 +782,13 @@ class dialog_setting_game_internal(QWidget):
_TR("自动切换到模式"),
getsimplecombobox(
_TRL(["不切换", "HOOK", "剪贴板", "OCR"]),
- savehook_new_data[exepath],
+ savehook_new_data[gameuid],
"onloadautochangemode2",
),
)
return _w
- def getstatistic(self, exepath):
+ def getstatistic(self, gameuid):
_w = QWidget()
formLayout = QVBoxLayout()
@@ -867,12 +856,12 @@ class dialog_setting_game_internal(QWidget):
return lists
def refresh(self):
- __ = gobject.baseobject.querytraceplaytime_v4(self.exepath)
+ __ = gobject.baseobject.querytraceplaytime_v4(self.gameuid)
_cnt = sum([_[1] - _[0] for _ in __])
- savehook_new_data[self.exepath]["statistic_playtime"] = _cnt
+ savehook_new_data[self.gameuid]["statistic_playtime"] = _cnt
self._timelabel.setText(self.formattime(_cnt))
self._wordlabel.setText(
- str(savehook_new_data[self.exepath]["statistic_wordcount"])
+ str(savehook_new_data[self.gameuid]["statistic_wordcount"])
)
self.chart.setdata(self.split_range_into_days(__))
@@ -897,7 +886,7 @@ class dialog_setting_game_internal(QWidget):
string = "0"
return string
- def getlabelsetting(self, exepath):
+ def getlabelsetting(self, gameuid):
_w = QWidget()
formLayout = QVBoxLayout()
_w.setLayout(formLayout)
@@ -910,9 +899,9 @@ class dialog_setting_game_internal(QWidget):
def __(_qw, _):
t, _type, _ = _
_qw.remove()
- i = savehook_new_data[exepath]["usertags"].index(t)
+ i = savehook_new_data[gameuid]["usertags"].index(t)
self.labelflow.removeidx(i)
- savehook_new_data[exepath]["usertags"].remove(t)
+ savehook_new_data[gameuid]["usertags"].remove(t)
if removeable:
qw.removesignal.connect(functools.partial(__, qw))
@@ -929,11 +918,11 @@ class dialog_setting_game_internal(QWidget):
else:
self.labelflow.addwidget(qw)
- for tag in savehook_new_data[exepath]["usertags"]:
+ for tag in savehook_new_data[gameuid]["usertags"]:
newitem(tag, True, _type=tagitem.TYPE_USERTAG)
- for tag in savehook_new_data[exepath]["developers"]:
+ for tag in savehook_new_data[gameuid]["developers"]:
newitem(tag, False, _type=tagitem.TYPE_DEVELOPER)
- for tag in savehook_new_data[exepath]["webtags"]:
+ for tag in savehook_new_data[gameuid]["webtags"]:
newitem(tag, False, _type=tagitem.TYPE_TAG)
formLayout.addWidget(self.labelflow)
_dict = {"new": 0}
@@ -949,8 +938,8 @@ class dialog_setting_game_internal(QWidget):
tag = combo.currentText()
# tag = globalconfig["labelset"][_dict["new"]]
- if tag and tag not in savehook_new_data[exepath]["usertags"]:
- savehook_new_data[exepath]["usertags"].insert(0, tag)
+ if tag and tag not in savehook_new_data[gameuid]["usertags"]:
+ savehook_new_data[gameuid]["usertags"].insert(0, tag)
newitem(tag, True, True, _type=tagitem.TYPE_USERTAG)
combo.clearEditText()
@@ -966,62 +955,135 @@ class dialog_setting_game_internal(QWidget):
)
return _w
- def getttssetting(self, exepath):
+ def getttssetting(self, gameuid):
_w = QWidget()
- formLayout = QVBoxLayout()
- formLayout.setAlignment(Qt.AlignmentFlag.AlignTop)
+ formLayout = QFormLayout()
_w.setLayout(formLayout)
- formLayout.addLayout(
- getboxlayout(
- [
- QLabel(_TR("禁止自动朗读的人名")),
- listediterline(
- _TR("禁止自动朗读的人名"),
- _TR("人名"),
- savehook_new_data[exepath]["allow_tts_auto_names_v4"],
- ),
- ]
- )
+ formLayout.addRow(
+ _TR("禁止自动朗读的人名"),
+ listediterline(
+ _TR("禁止自动朗读的人名"),
+ _TR("人名"),
+ savehook_new_data[gameuid]["allow_tts_auto_names_v4"],
+ ),
)
- formLayout.addLayout(
+ formLayout.addRow(
+ _TR("语音修正"),
getboxlayout(
[
- QLabel(_TR("语音修正")),
- getsimpleswitch(savehook_new_data[exepath], "tts_repair"),
+ getsimpleswitch(savehook_new_data[gameuid], "tts_repair"),
getIconButton(
- callback=lambda : noundictconfigdialog1(
+ callback=lambda: noundictconfigdialog1(
self,
- savehook_new_data[exepath]["tts_repair_regex"],
+ savehook_new_data[gameuid]["tts_repair_regex"],
"语音修正",
["正则", "原文", "替换"],
),
icon="fa.gear",
),
- ]
- )
+ QLabel(),
+ ],
+ makewidget=True,
+ ),
)
return _w
- def getpretranstab(self, exepath):
+ def maketabforanki(self, gameuid):
+ _w = QWidget()
+ formLayout = QFormLayout()
+ _w.setLayout(formLayout)
+ __extraw = QWidget()
+
+ formLayout.addRow(
+ _TR("跟随默认"),
+ getsimpleswitch(
+ savehook_new_data[gameuid],
+ "follow_default_ankisettings",
+ callback=lambda _: __extraw.setEnabled(not _),
+ ),
+ )
+ __extraw.setEnabled(
+ not savehook_new_data[gameuid]["follow_default_ankisettings"]
+ )
+ savehook_new_data[gameuid]["anki_DeckName"] = globalconfig["ankiconnect"][
+ "DeckName"
+ ]
+ savehook_new_data[gameuid]["anki_simulate_key_1_use"] = globalconfig[
+ "ankiconnect"
+ ]["simulate_key"]["1"]["use"]
+ savehook_new_data[gameuid]["anki_simulate_key_1_keystring"] = globalconfig[
+ "ankiconnect"
+ ]["simulate_key"]["1"]["keystring"]
+ savehook_new_data[gameuid]["anki_simulate_key_2_use"] = globalconfig[
+ "ankiconnect"
+ ]["simulate_key"]["2"]["use"]
+ savehook_new_data[gameuid]["anki_simulate_key_2_keystring"] = globalconfig[
+ "ankiconnect"
+ ]["simulate_key"]["2"]["keystring"]
+
+ formLayout.addRow(__extraw)
+ formLayout2 = QFormLayout()
+ formLayout2.setContentsMargins(0, 0, 0, 0)
+ __extraw.setLayout(formLayout2)
+ formLayout2.addRow(
+ _TR("DeckName"),
+ getlineedit(
+ savehook_new_data[gameuid],
+ "anki_DeckName",
+ ),
+ )
+ formLayout2.addRow(
+ _TR("录音时模拟按键"),
+ getboxlayout(
+ [
+ getsimpleswitch(
+ savehook_new_data[gameuid], "anki_simulate_key_1_use"
+ ),
+ getsimplekeyseq(
+ savehook_new_data[gameuid], "anki_simulate_key_1_keystring"
+ ),
+ ],
+ margin0=True,
+ makewidget=True,
+ ),
+ )
+ formLayout2.addRow(
+ _TR("录音时模拟按键_例句"),
+ getboxlayout(
+ [
+ getsimpleswitch(
+ savehook_new_data[gameuid], "anki_simulate_key_2_use"
+ ),
+ getsimplekeyseq(
+ savehook_new_data[gameuid], "anki_simulate_key_2_keystring"
+ ),
+ ],
+ margin0=True,
+ makewidget=True,
+ ),
+ )
+ return _w
+
+ def getpretranstab(self, gameuid):
_w = QWidget()
formLayout = QFormLayout()
_w.setLayout(formLayout)
- def selectimg(exepath, key, res):
- savehook_new_data[exepath][key] = res
+ def selectimg(gameuid, key, res):
+ savehook_new_data[gameuid][key] = res
for showname, key, filt in [
("json翻译文件", "gamejsonfile", "*.json"),
]:
- if isinstance(savehook_new_data[exepath][key], str):
- savehook_new_data[exepath][key] = [savehook_new_data[exepath][key]]
+ if isinstance(savehook_new_data[gameuid][key], str):
+ savehook_new_data[gameuid][key] = [savehook_new_data[gameuid][key]]
formLayout.addRow(
_TR(showname),
listediterline(
showname,
showname,
- savehook_new_data[exepath][key],
+ savehook_new_data[gameuid][key],
ispathsedit=dict(filter1=filt),
),
)
@@ -1032,17 +1094,17 @@ class dialog_setting_game_internal(QWidget):
formLayout.addRow(
_TR(showname),
getsimplepatheditor(
- savehook_new_data[exepath][key],
+ savehook_new_data[gameuid][key],
False,
False,
filt,
- functools.partial(selectimg, exepath, key),
+ functools.partial(selectimg, gameuid, key),
True,
),
)
return _w
- def gettextproc(self, exepath):
+ def gettextproc(self, gameuid):
_w = QWidget()
formLayout = QFormLayout()
_w.setLayout(formLayout)
@@ -1054,19 +1116,19 @@ class dialog_setting_game_internal(QWidget):
formLayout.addRow(
_TR("跟随默认"),
getsimpleswitch(
- savehook_new_data[exepath],
+ savehook_new_data[gameuid],
"textproc_follow_default",
callback=__function,
),
)
- __extra.setEnabled(not savehook_new_data[exepath]["textproc_follow_default"])
+ __extra.setEnabled(not savehook_new_data[gameuid]["textproc_follow_default"])
vbox = QVBoxLayout()
vbox.setContentsMargins(0, 0, 0, 0)
__extra.setLayout(vbox)
formLayout.addRow(__extra)
model = QStandardItemModel()
- model.setHorizontalHeaderLabels(_TRL(["使用", "预处理方法", "设置"]))
+ model.setHorizontalHeaderLabels(_TRL(["预处理方法", "使用", "设置"]))
table = QTableView()
@@ -1081,9 +1143,9 @@ class dialog_setting_game_internal(QWidget):
table.customContextMenuRequested.connect(self.__privatetextproc_showmenu)
self.__textprocinternaltable = table
self.__textprocinternalmodel = model
- self.__privatetextproc_exe = exepath
+ self.__privatetextproc_gameuid = gameuid
for row, k in enumerate(
- savehook_new_data[exepath]["save_text_process_info"]["rank"]
+ savehook_new_data[gameuid]["save_text_process_info"]["rank"]
): # 2
self.__checkaddnewmethod(row, k)
vbox.addWidget(table)
@@ -1116,7 +1178,7 @@ class dialog_setting_game_internal(QWidget):
def __privatetextproc_moverank(self, dy):
__row = self.__textprocinternaltable.currentIndex().row()
- __list = savehook_new_data[self.__privatetextproc_exe][
+ __list = savehook_new_data[self.__privatetextproc_gameuid][
"save_text_process_info"
]["rank"]
game = __list[__row]
@@ -1133,21 +1195,21 @@ class dialog_setting_game_internal(QWidget):
self.__textprocinternalmodel.insertRow(
row,
[
- QStandardItem(),
QStandardItem(postprocessconfig[_internal]["name"]),
QStandardItem(),
+ QStandardItem(),
],
)
- __dict = savehook_new_data[self.__privatetextproc_exe][
+ __dict = savehook_new_data[self.__privatetextproc_gameuid][
"save_text_process_info"
]["postprocessconfig"]
if _internal not in __dict:
__dict[_internal] = postprocessconfig[_internal]
__dict[_internal]["use"] = True
- btn = maybehavebutton(self, self.__privatetextproc_exe, _internal)
+ btn = maybehavebutton(self, self.__privatetextproc_gameuid, _internal)
self.__textprocinternaltable.setIndexWidget(
- self.__textprocinternalmodel.index(row, 0),
+ self.__textprocinternalmodel.index(row, 1),
getsimpleswitch(__dict[_internal], "use"),
)
if btn:
@@ -1161,7 +1223,9 @@ class dialog_setting_game_internal(QWidget):
if row < 0:
return
self.__textprocinternalmodel.removeRow(row)
- _dict = savehook_new_data[self.__privatetextproc_exe]["save_text_process_info"]
+ _dict = savehook_new_data[self.__privatetextproc_gameuid][
+ "save_text_process_info"
+ ]
post = _dict["rank"][row]
_dict["rank"].pop(row)
if post in _dict["postprocessconfig"]:
@@ -1174,7 +1238,7 @@ class dialog_setting_game_internal(QWidget):
def __callback(d):
__ = list(postprocessconfig.keys())[d["k"]]
- __list = savehook_new_data[self.__privatetextproc_exe][
+ __list = savehook_new_data[self.__privatetextproc_gameuid][
"save_text_process_info"
]["rank"]
if __ in __list:
@@ -1202,7 +1266,7 @@ class dialog_setting_game_internal(QWidget):
],
)
- def getlangtab(self, exepath):
+ def getlangtab(self, gameuid):
_w = QWidget()
formLayout = QFormLayout()
_w.setLayout(formLayout)
@@ -1211,16 +1275,16 @@ class dialog_setting_game_internal(QWidget):
formLayout.addRow(
_TR("跟随默认"),
getsimpleswitch(
- savehook_new_data[exepath],
+ savehook_new_data[gameuid],
"lang_follow_default",
callback=lambda _: __extraw.setEnabled(not _),
),
)
- __extraw.setEnabled(not savehook_new_data[exepath]["lang_follow_default"])
- savehook_new_data[exepath]["private_tgtlang"] = savehook_new_data[exepath].get(
+ __extraw.setEnabled(not savehook_new_data[gameuid]["lang_follow_default"])
+ savehook_new_data[gameuid]["private_tgtlang"] = savehook_new_data[gameuid].get(
"private_tgtlang", globalconfig["tgtlang3"]
)
- savehook_new_data[exepath]["private_srclang"] = savehook_new_data[exepath].get(
+ savehook_new_data[gameuid]["private_srclang"] = savehook_new_data[gameuid].get(
"private_srclang", globalconfig["srclang3"]
)
@@ -1232,7 +1296,7 @@ class dialog_setting_game_internal(QWidget):
_TR("源语言"),
getsimplecombobox(
_TRL(static_data["language_list_translator"]),
- savehook_new_data[exepath],
+ savehook_new_data[gameuid],
"private_srclang",
),
)
@@ -1240,13 +1304,13 @@ class dialog_setting_game_internal(QWidget):
_TR("目标语言"),
getsimplecombobox(
_TRL(static_data["language_list_translator"]),
- savehook_new_data[exepath],
+ savehook_new_data[gameuid],
"private_tgtlang",
),
)
return _w
- def gethooktab(self, exepath):
+ def gethooktab(self, gameuid):
_w = QWidget()
formLayout = QFormLayout()
_w.setLayout(formLayout)
@@ -1255,13 +1319,13 @@ class dialog_setting_game_internal(QWidget):
listediterline(
_TR("特殊码"),
_TR("特殊码"),
- savehook_new_data[exepath]["needinserthookcode"],
+ savehook_new_data[gameuid]["needinserthookcode"],
),
)
formLayout.addRow(
_TR("插入特殊码延迟(ms)"),
- getspinbox(0, 1000000, savehook_new_data[exepath], "inserthooktimeout"),
+ getspinbox(0, 1000000, savehook_new_data[gameuid], "inserthooktimeout"),
)
__extraw = QWidget()
@@ -1275,13 +1339,13 @@ class dialog_setting_game_internal(QWidget):
formLayout.addRow(
_TR("跟随默认"),
getsimpleswitch(
- savehook_new_data[exepath],
+ savehook_new_data[gameuid],
"hooksetting_follow_default",
callback=__function,
),
)
__extraw.setEnabled(
- not savehook_new_data[exepath]["hooksetting_follow_default"]
+ not savehook_new_data[gameuid]["hooksetting_follow_default"]
)
for k in [
@@ -1295,8 +1359,8 @@ class dialog_setting_game_internal(QWidget):
"allow_set_text_name",
"use_yapi",
]:
- if k not in savehook_new_data[exepath]["hooksetting_private"]:
- savehook_new_data[exepath]["hooksetting_private"][k] = globalconfig[k]
+ if k not in savehook_new_data[gameuid]["hooksetting_private"]:
+ savehook_new_data[gameuid]["hooksetting_private"][k] = globalconfig[k]
formLayout.addRow(__extraw)
formLayout2 = QFormLayout()
formLayout2.setContentsMargins(0, 0, 0, 0)
@@ -1305,7 +1369,7 @@ class dialog_setting_game_internal(QWidget):
_TR("代码页"),
getsimplecombobox(
_TRL(static_data["codepage_display"]),
- savehook_new_data[exepath]["hooksetting_private"],
+ savehook_new_data[gameuid]["hooksetting_private"],
"codepage_index",
lambda x: gobject.baseobject.textsource.setsettings(),
),
@@ -1313,7 +1377,7 @@ class dialog_setting_game_internal(QWidget):
formLayout2.addRow(
_TR("过滤反复刷新的句子"),
getsimpleswitch(
- savehook_new_data[exepath]["hooksetting_private"],
+ savehook_new_data[gameuid]["hooksetting_private"],
"direct_filterrepeat",
callback=lambda x: gobject.baseobject.textsource.setsettings(),
),
@@ -1322,7 +1386,7 @@ class dialog_setting_game_internal(QWidget):
formLayout2.addRow(
_TR("移除非选定hook"),
getsimpleswitch(
- savehook_new_data[exepath]["hooksetting_private"], "removeuseless"
+ savehook_new_data[gameuid]["hooksetting_private"], "removeuseless"
),
)
formLayout2.addRow(
@@ -1330,7 +1394,7 @@ class dialog_setting_game_internal(QWidget):
getspinbox(
0,
10000,
- savehook_new_data[exepath]["hooksetting_private"],
+ savehook_new_data[gameuid]["hooksetting_private"],
"textthreaddelay",
callback=lambda x: gobject.baseobject.textsource.setsettings(),
),
@@ -1340,7 +1404,7 @@ class dialog_setting_game_internal(QWidget):
getspinbox(
0,
1000000,
- savehook_new_data[exepath]["hooksetting_private"],
+ savehook_new_data[gameuid]["hooksetting_private"],
"maxBufferSize",
callback=lambda x: gobject.baseobject.textsource.setsettings(),
),
@@ -1350,7 +1414,7 @@ class dialog_setting_game_internal(QWidget):
getspinbox(
0,
1000000000,
- savehook_new_data[exepath]["hooksetting_private"],
+ savehook_new_data[gameuid]["hooksetting_private"],
"maxHistorySize",
callback=lambda x: gobject.baseobject.textsource.setsettings(),
),
@@ -1358,21 +1422,21 @@ class dialog_setting_game_internal(QWidget):
formLayout2.addRow(
_TR("过滤包含乱码的文本行"),
getsimpleswitch(
- savehook_new_data[exepath]["hooksetting_private"],
+ savehook_new_data[gameuid]["hooksetting_private"],
"filter_chaos_code",
),
)
formLayout2.addRow(
_TR("区分人名和文本"),
getsimpleswitch(
- savehook_new_data[exepath]["hooksetting_private"],
+ savehook_new_data[gameuid]["hooksetting_private"],
"allow_set_text_name",
),
)
formLayout2.addRow(
_TR("使用YAPI注入"),
getsimpleswitch(
- savehook_new_data[exepath]["hooksetting_private"],
+ savehook_new_data[gameuid]["hooksetting_private"],
"use_yapi",
),
)
@@ -1383,15 +1447,15 @@ class dialog_setting_game_internal(QWidget):
@Singleton_close
class dialog_setting_game(QDialog):
- def __init__(self, parent, exepath, setindexhook=False) -> None:
+ def __init__(self, parent, gameuid, setindexhook=False) -> None:
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
global _global_dialog_setting_game
_global_dialog_setting_game = self
- self.setWindowTitle(savehook_new_data[exepath]["title"])
+ self.setWindowTitle(savehook_new_data[gameuid]["title"])
- self.setWindowIcon(getExeIcon(exepath, cache=True))
- _ = dialog_setting_game_internal(self, exepath)
+ self.setWindowIcon(getExeIcon(uid2gamepath[gameuid], cache=True))
+ _ = dialog_setting_game_internal(self, gameuid)
if setindexhook:
_.methodtab.setCurrentIndex(1)
_.setMinimumSize(QSize(600, 500))
@@ -1504,10 +1568,11 @@ class dialog_syssetting(QDialog):
@threader
-def startgame(game):
+def startgame(gameuid):
try:
+ game = uid2gamepath[gameuid]
if os.path.exists(game):
- mode = savehook_new_data[game]["onloadautochangemode2"]
+ mode = savehook_new_data[gameuid]["onloadautochangemode2"]
if mode > 0:
_ = {1: "texthook", 2: "copy", 3: "ocr"}
if globalconfig["sourcestatus2"][_[mode]]["use"] == False:
@@ -1525,8 +1590,8 @@ def startgame(game):
dirpath = os.path.dirname(game)
- if savehook_new_data[game]["startcmduse"]:
- usearg = savehook_new_data[game]["startcmd"].format(exepath=game)
+ if savehook_new_data[gameuid]["startcmduse"]:
+ usearg = savehook_new_data[gameuid]["startcmd"].format(exepath=game)
windows.CreateProcess(
None,
usearg,
@@ -1539,7 +1604,7 @@ def startgame(game):
windows.STARTUPINFO(),
)
return
- if savehook_new_data[game]["leuse"] == False or (
+ if savehook_new_data[gameuid]["leuse"] == False or (
game.lower()[-4:] not in [".lnk", ".exe"]
):
# 对于其他文件,需要AssocQueryStringW获取命令行才能正确le,太麻烦,放弃。
@@ -1562,7 +1627,7 @@ def startgame(game):
if dirp != "":
dirpath = dirp
- localeswitcher = savehook_new_data[game]["localeswitcher"]
+ localeswitcher = savehook_new_data[gameuid]["localeswitcher"]
b = windows.GetBinaryType(execheck3264)
if b == 6 and localeswitcher == 0:
localeswitcher = 1
@@ -1587,7 +1652,8 @@ def startgame(game):
print_exc()
-def opendir(f):
+def opendirforgameuid(gameuid):
+ f = uid2gamepath[gameuid]
f = os.path.dirname(f)
if os.path.exists(f) and os.path.isdir(f):
os.startfile(f)
@@ -1605,20 +1671,20 @@ def _getpixfunction(kk):
_pix = QPixmap(_)
if _pix and not _pix.isNull():
return _pix
- _pix = getExeIcon(kk, False, cache=True)
+ _pix = getExeIcon(uid2gamepath[kk], False, cache=True)
return _pix
-def startgamecheck(self, game):
- if not game:
+def startgamecheck(self, gameuid):
+ if not gameuid:
return
- if not os.path.exists(game):
+ if not os.path.exists(uid2gamepath[gameuid]):
return
if globalconfig["startgamenototop"] == False:
- idx = savehook_new_list.index(game)
+ idx = savehook_new_list.index(gameuid)
savehook_new_list.insert(0, savehook_new_list.pop(idx))
self.parent().parent().close()
- startgame(game)
+ startgame(gameuid)
def addgamesingle(callback, targetlist):
@@ -1628,8 +1694,9 @@ def addgamesingle(callback, targetlist):
if res == "":
return
res = os.path.normpath(res)
- if checkifnewgame(targetlist, res):
- callback(res)
+ uid = checkifnewgame(targetlist, res)
+ if uid:
+ callback(uid)
def addgamebatch(callback, targetlist):
@@ -1643,8 +1710,9 @@ def addgamebatch(callback, targetlist):
path = os.path.normpath(os.path.abspath(os.path.join(_dir, _f)))
if path.lower().endswith(".exe") == False:
continue
- if checkifnewgame(targetlist, path):
- callback(path)
+ uid = checkifnewgame(targetlist, path)
+ if uid:
+ callback(uid)
@Singleton_close
@@ -1704,9 +1772,9 @@ class dialog_savedgame_integrated(saveposwindow):
self.internallayout.addWidget(QWidget())
self.setCentralWidget(w)
- self.layout1btn = MySwitch(self, icon="fa.th", )
- self.layout2btn = MySwitch(self, icon="fa.th-list", )
- self.layout3btn = MySwitch(self, icon="fa.list" , )
+ self.layout1btn = MySwitch(self, icon="fa.th")
+ self.layout2btn = MySwitch(self, icon="fa.th-list")
+ self.layout3btn = MySwitch(self, icon="fa.list")
self.layout1btn.clicked.connect(functools.partial(self.selectlayout, 0))
self.layout2btn.clicked.connect(functools.partial(self.selectlayout, 1))
self.layout3btn.clicked.connect(functools.partial(self.selectlayout, 2))
@@ -1755,7 +1823,7 @@ def getreflist(reftagid):
class dialog_savedgame_new(QWidget):
def clicked2(self):
try:
- game = self.currentfocuspath
+ game = self.currentfocusuid
idx2 = self.reflist.index(game)
self.reflist.pop(idx2)
@@ -1772,13 +1840,13 @@ class dialog_savedgame_new(QWidget):
print_exc()
def clicked4(self):
- opendir(self.currentfocuspath)
+ opendirforgameuid(self.currentfocusuid)
def clicked3_batch(self):
- addgamebatch(lambda res: self.newline(res, True), self.reflist)
+ addgamebatch(lambda uid: self.newline(uid, True), self.reflist)
def clicked3(self):
- addgamesingle(lambda res: self.newline(res, True), self.reflist)
+ addgamesingle(lambda uid: self.newline(uid, True), self.reflist)
def tagschanged(self, tags):
self.currtags = tags
@@ -1798,7 +1866,7 @@ class dialog_savedgame_new(QWidget):
notshow = False
for tag, _type, _ in tags:
if _type == tagitem.TYPE_EXISTS:
- if os.path.exists(k) == False:
+ if os.path.exists(uid2gamepath[k]) == False:
notshow = True
break
elif _type == tagitem.TYPE_DEVELOPER:
@@ -1838,8 +1906,8 @@ class dialog_savedgame_new(QWidget):
batchadd = QAction(_TR("批量添加"))
othersetting = QAction(_TR("其他设置"))
- if self.currentfocuspath:
- exists = os.path.exists(self.currentfocuspath)
+ if self.currentfocusuid:
+ exists = os.path.exists(uid2gamepath[self.currentfocusuid])
if exists:
menu.addAction(startgame)
menu.addAction(delgame)
@@ -1852,7 +1920,7 @@ class dialog_savedgame_new(QWidget):
menu.addAction(othersetting)
action = menu.exec(self.mapToGlobal(p))
if action == startgame:
- startgamecheck(self, self.currentfocuspath)
+ startgamecheck(self, self.currentfocusuid)
elif action == gamesetting:
self.showsettingdialog()
elif action == delgame:
@@ -1897,7 +1965,7 @@ class dialog_savedgame_new(QWidget):
layout.addWidget(
getIconButton(
- lambda : listediter(
+ lambda: listediter(
parent,
_TR("标签集"),
_TR("标签"),
@@ -1939,7 +2007,7 @@ class dialog_savedgame_new(QWidget):
self.buttonlayout = buttonlayout
self.savebutton = []
self.simplebutton(
- "开始游戏", True, lambda: startgamecheck(self, self.currentfocuspath), True
+ "开始游戏", True, lambda: startgamecheck(self, self.currentfocusuid), True
)
self.simplebutton("游戏设置", True, self.showsettingdialog, False)
self.simplebutton("删除游戏", True, self.clicked2, False)
@@ -1975,7 +2043,7 @@ class dialog_savedgame_new(QWidget):
self.installEventFilter(self.__filter)
def moverank(self, dx):
- game = self.currentfocuspath
+ game = self.currentfocusuid
idx1 = self.idxsave.index(game)
idx2 = (idx1 + dx) % len(self.idxsave)
@@ -1989,7 +2057,7 @@ class dialog_savedgame_new(QWidget):
def showsettingdialog(self):
try:
- dialog_setting_game(self.parent(), self.currentfocuspath)
+ dialog_setting_game(self.parent(), self.currentfocusuid)
except:
print_exc()
@@ -2006,15 +2074,15 @@ class dialog_savedgame_new(QWidget):
def itemfocuschanged(self, b, k):
if b:
- self.currentfocuspath = k
+ self.currentfocusuid = k
else:
- self.currentfocuspath = None
+ self.currentfocusuid = None
for _btn, exists in self.savebutton:
_able1 = b and (
(not exists)
- or (self.currentfocuspath)
- and (os.path.exists(self.currentfocuspath))
+ or (self.currentfocusuid)
+ and (os.path.exists(uid2gamepath[self.currentfocusuid]))
)
_btn.setEnabled(_able1)
@@ -2139,8 +2207,8 @@ class dialog_savedgame_lagacy(QWidget):
pass
def clicked3(self):
- def call(res):
- self.newline(0, res)
+ def call(uid):
+ self.newline(0, uid)
self.table.setCurrentIndex(self.model.index(0, 0))
addgamesingle(call)
@@ -2152,13 +2220,15 @@ class dialog_savedgame_lagacy(QWidget):
def delayloadicon(self, k):
return getcolorbutton(
- "", "", functools.partial(opendir, k), qicon=getExeIcon(k, cache=True)
+ "",
+ "",
+ functools.partial(opendirforgameuid, k),
+ qicon=getExeIcon(uid2gamepath[k], cache=True),
)
def newline(self, row, k):
keyitem = QStandardItem()
keyitem.savetext = k
- k = k.replace("/", "\\")
self.model.insertRow(
row,
[
@@ -2248,7 +2318,7 @@ class clickitem(QWidget):
clickitem.globallashfocus = None
def mouseDoubleClickEvent(self, e):
- self.doubleclicked.emit(self.exe)
+ self.doubleclicked.emit(self.uid)
def click(self):
try:
@@ -2259,7 +2329,7 @@ class clickitem(QWidget):
if self != clickitem.globallashfocus:
clickitem.clearfocus()
clickitem.globallashfocus = self
- self.focuschanged.emit(True, self.exe)
+ self.focuschanged.emit(True, self.uid)
except:
print_exc()
@@ -2268,17 +2338,17 @@ class clickitem(QWidget):
def focusOut(self):
self.bottommask.setStyleSheet("background-color: rgba(255,255,255, 0);")
- self.focuschanged.emit(False, self.exe)
+ self.focuschanged.emit(False, self.uid)
def resizeEvent(self, a0: QResizeEvent) -> None:
self.bottommask.resize(a0.size())
self.maskshowfileexists.resize(a0.size())
self.bottomline.resize(a0.size())
- def __init__(self, exe):
+ def __init__(self, uid):
super().__init__()
- self.exe = exe
+ self.uid = uid
self.lay = QHBoxLayout()
self.lay.setSpacing(0)
self.lay.setContentsMargins(0, 0, 0, 0)
@@ -2286,7 +2356,7 @@ class clickitem(QWidget):
self.maskshowfileexists = QLabel(self)
c = globalconfig["dialog_savegame_layout"][
- ("onfilenoexistscolor1", "backcolor1")[os.path.exists(exe)]
+ ("onfilenoexistscolor1", "backcolor1")[os.path.exists(uid2gamepath[uid])]
]
c = str2rgba(c, globalconfig["dialog_savegame_layout"]["transparent"])
self.maskshowfileexists.setStyleSheet(f"background-color:{c};")
@@ -2302,11 +2372,11 @@ class clickitem(QWidget):
_.setFixedSize(QSize(size, size))
_.setScaledContents(True)
_.setStyleSheet("background-color: rgba(255,255,255, 0);")
- icon = getExeIcon(exe, icon=False, cache=True)
+ icon = getExeIcon(uid2gamepath[uid], icon=False, cache=True)
icon.setDevicePixelRatio(self.devicePixelRatioF())
_.setPixmap(icon)
self.lay.addWidget(_)
- _ = QLabel(savehook_new_data[exe]["title"])
+ _ = QLabel(savehook_new_data[uid]["title"])
_.setWordWrap(True)
_.setFixedHeight(size + 1)
self.lay.addWidget(_)
@@ -2314,10 +2384,30 @@ class clickitem(QWidget):
_.setStyleSheet("""background-color: rgba(255,255,255, 0);""")
+class fadeoutlabel(QLabel):
+ def __init__(self, p=None):
+ super().__init__(p)
+
+ effect = QGraphicsOpacityEffect(self)
+ self.setGraphicsEffect(effect)
+
+ self.animation = QPropertyAnimation(effect, b"opacity")
+ self.animation.setDuration(4000)
+ self.animation.setStartValue(1.0)
+ self.animation.setEndValue(0.0)
+ self.animation.setDirection(QPropertyAnimation.Direction.Forward)
+
+ def setText(self, t):
+ super().setText(t)
+ self.animation.stop()
+ self.animation.start()
+
+
class pixwrapper(QWidget):
def __init__(self) -> None:
super().__init__()
self.pixview = QLabel(self)
+ self.pathview = fadeoutlabel(self)
self.pixmaps = []
self.rflist = []
self.iternalpixmaps = []
@@ -2342,13 +2432,14 @@ class pixwrapper(QWidget):
def resizeEvent(self, e: QResizeEvent):
self.pixview.resize(e.size().width(), e.size().height())
+ self.pathview.resize(e.size().width(), self.pathview.height())
self.visidx()
def visidx(self):
if len(self.pixmaps) == 0:
if not self.k:
return
- pixmap = getExeIcon(self.k, False, cache=True)
+ pixmap = getExeIcon(uid2gamepath[self.k], False, cache=True)
pixmap.setDevicePixelRatio(self.devicePixelRatioF())
self.pixview.setPixmap(self.scalepix(pixmap))
else:
@@ -2358,6 +2449,7 @@ class pixwrapper(QWidget):
if pixmap is None or pixmap.isNull():
self.pixmaps.pop(self.pixmapi)
return self.visidx()
+ self.pathview.setText(pixmap_)
savehook_new_data[self.k]["currentvisimage"] = pixmap_
pixmap.setDevicePixelRatio(self.devicePixelRatioF())
self.pixview.setPixmap(self.scalepix(pixmap))
@@ -2397,7 +2489,7 @@ class dialog_savedgame_v3(QWidget):
def viewitem(self, k):
try:
self.pixview.setpix(k)
- self.currentfocuspath = k
+ self.currentfocusuid = k
if self.righttop.count() > 1:
self.righttop.removeTab(1)
tabadd_lazy(
@@ -2413,18 +2505,18 @@ class dialog_savedgame_v3(QWidget):
self.reftagid = reftagid
if b:
- self.currentfocuspath = k
+ self.currentfocusuid = k
else:
- self.currentfocuspath = None
+ self.currentfocusuid = None
for _btn, exists in self.savebutton:
_able1 = b and (
(not exists)
- or (self.currentfocuspath)
- and (os.path.exists(self.currentfocuspath))
+ or (self.currentfocusuid)
+ and (os.path.exists(uid2gamepath[self.currentfocusuid]))
)
_btn.setEnabled(_able1)
- if self.currentfocuspath:
+ if self.currentfocusuid:
self.viewitem(k)
def delayitemcreater(self, k, select, reftagid):
@@ -2451,7 +2543,7 @@ class dialog_savedgame_v3(QWidget):
self.stack.directshow()
def stack_showmenu(self, ispixmenu, p):
- if not self.currentfocuspath:
+ if not self.currentfocusuid:
return
menu = QMenu(self)
startgame = QAction(_TR("开始游戏"))
@@ -2461,7 +2553,7 @@ class dialog_savedgame_v3(QWidget):
setimage = QAction(_TR("设为封面"))
deleteimage = QAction(_TR("删除图片"))
hualang = QAction(_TR("画廊"))
- exists = os.path.exists(self.currentfocuspath)
+ exists = os.path.exists(uid2gamepath[self.currentfocusuid])
if exists:
menu.addAction(startgame)
menu.addAction(delgame)
@@ -2475,16 +2567,16 @@ class dialog_savedgame_v3(QWidget):
menu.addAction(hualang)
action = menu.exec(QCursor.pos())
if action == startgame:
- startgamecheck(self, self.currentfocuspath)
+ startgamecheck(self, self.currentfocusuid)
elif action == delgame:
- self.clicked2()
+ self.shanchuyouxi()
elif action == hualang:
listediter(
self,
_TR("画廊"),
_TR("画廊"),
- savehook_new_data[self.currentfocuspath]["imagepath_all"],
- closecallback=lambda: self.pixview.setpix(self.currentfocuspath),
+ savehook_new_data[self.currentfocusuid]["imagepath_all"],
+ closecallback=lambda: self.pixview.setpix(self.currentfocusuid),
ispathsedit=dict(),
)
@@ -2495,11 +2587,11 @@ class dialog_savedgame_v3(QWidget):
elif action == addtolist:
self.addtolist()
elif action == setimage:
- curr = savehook_new_data[self.currentfocuspath]["currentvisimage"]
+ curr = savehook_new_data[self.currentfocusuid]["currentvisimage"]
if curr and os.path.exists(curr):
- savehook_new_data[self.currentfocuspath]["currentmainimage"] = curr
+ savehook_new_data[self.currentfocusuid]["currentmainimage"] = curr
- def addtolistcallback(self, __d, __uid, path):
+ def addtolistcallback(self, __d, __uid, gameuid):
if len(__uid) == 0:
return
@@ -2508,9 +2600,13 @@ class dialog_savedgame_v3(QWidget):
__save = self.reftagid
self.reftagid = uid
- if path not in getreflist(self.reftagid):
- getreflist(self.reftagid).insert(0, path)
- self.newline(path)
+ if gameuid not in getreflist(self.reftagid):
+ getreflist(self.reftagid).insert(0, gameuid)
+ self.newline(gameuid)
+ else:
+ idx = getreflist(self.reftagid).index(gameuid)
+ getreflist(self.reftagid).insert(0, getreflist(self.reftagid).pop(idx))
+ self.stack.w(calculatetagidx(self.reftagid)).torank1(idx)
self.reftagid = __save
def addtolist(self):
@@ -2543,7 +2639,7 @@ class dialog_savedgame_v3(QWidget):
{
"type": "okcancel",
"callback": functools.partial(
- self.addtolistcallback, __d, __uid, self.currentfocuspath
+ self.addtolistcallback, __d, __uid, self.currentfocusuid
),
},
],
@@ -2554,7 +2650,7 @@ class dialog_savedgame_v3(QWidget):
def __init__(self, parent) -> None:
super().__init__(parent)
- self.currentfocuspath = None
+ self.currentfocusuid = None
self.reftagid = None
self.reallist = {}
self.stack = stackedlist()
@@ -2588,9 +2684,9 @@ class dialog_savedgame_v3(QWidget):
rightlay.addLayout(self.buttonlayout)
self.simplebutton(
- "开始游戏", True, lambda: startgamecheck(self, self.currentfocuspath), True
+ "开始游戏", True, lambda: startgamecheck(self, self.currentfocusuid), True
)
- self.simplebutton("删除游戏", True, self.clicked2, False)
+ self.simplebutton("删除游戏", True, self.shanchuyouxi, False)
self.simplebutton("打开目录", True, self.clicked4, True)
self.simplebutton("添加到列表", False, self.addtolist, 1)
if globalconfig["startgamenototop"]:
@@ -2622,7 +2718,9 @@ class dialog_savedgame_v3(QWidget):
self.stack.insertw(i, group0)
rowreal = 0
for row, k in enumerate(lst):
- if globalconfig["hide_not_exists"] and not os.path.exists(k):
+ if globalconfig["hide_not_exists"] and not os.path.exists(
+ uid2gamepath[k]
+ ):
continue
self.reallist[tagid].append(k)
group0.insertw(
@@ -2643,7 +2741,7 @@ class dialog_savedgame_v3(QWidget):
self.stack.switchidx(idx1, idx2)
def tagbuttonmenu(self, tagid):
- self.currentfocuspath = None
+ self.currentfocusuid = None
self.reftagid = tagid
menu = QMenu(self)
editname = QAction(_TR("修改名称"))
@@ -2724,29 +2822,29 @@ class dialog_savedgame_v3(QWidget):
return shrinkableitem(_btn, opened)
def moverank(self, dx):
- game = self.currentfocuspath
- idx1 = self.reallist[self.reftagid].index(game)
+ uid = self.currentfocusuid
+ idx1 = self.reallist[self.reftagid].index(uid)
idx2 = (idx1 + dx) % len(self.reallist[self.reftagid])
- game2 = self.reallist[self.reftagid][idx2]
+ uid2 = self.reallist[self.reftagid][idx2]
self.reallist[self.reftagid].insert(
idx2, self.reallist[self.reftagid].pop(idx1)
)
self.stack.w(calculatetagidx(self.reftagid)).switchidx(idx1, idx2)
- idx1 = getreflist(self.reftagid).index(game)
- idx2 = getreflist(self.reftagid).index(game2)
+ idx1 = getreflist(self.reftagid).index(uid)
+ idx2 = getreflist(self.reftagid).index(uid2)
getreflist(self.reftagid).insert(idx2, getreflist(self.reftagid).pop(idx1))
- def clicked2(self):
- if not self.currentfocuspath:
+ def shanchuyouxi(self):
+ if not self.currentfocusuid:
return
try:
- game = self.currentfocuspath
- idx2 = getreflist(self.reftagid).index(game)
+ uid = self.currentfocusuid
+ idx2 = getreflist(self.reftagid).index(uid)
getreflist(self.reftagid).pop(idx2)
- idx2 = self.reallist[self.reftagid].index(game)
+ idx2 = self.reallist[self.reftagid].index(uid)
self.reallist[self.reftagid].pop(idx2)
clickitem.clearfocus()
group0 = self.stack.w(calculatetagidx(self.reftagid))
@@ -2759,16 +2857,16 @@ class dialog_savedgame_v3(QWidget):
print_exc()
def clicked4(self):
- opendir(self.currentfocuspath)
+ opendirforgameuid(self.currentfocusuid)
def clicked3_batch(self):
- addgamebatch(lambda res: self.newline(res), getreflist(self.reftagid))
+ addgamebatch(lambda uid: self.newline(uid), getreflist(self.reftagid))
def clicked3(self):
- addgamesingle(lambda res: self.newline(res), getreflist(self.reftagid))
+ addgamesingle(lambda uid: self.newline(uid), getreflist(self.reftagid))
def clicked(self):
- startgamecheck(self, self.currentfocuspath)
+ startgamecheck(self, self.currentfocusuid)
def simplebutton(self, text, save, callback, exists):
button5 = QPushButton()
diff --git a/LunaTranslator/LunaTranslator/gui/pretransfile.py b/LunaTranslator/LunaTranslator/gui/pretransfile.py
index 33393d0d..a8d4e692 100644
--- a/LunaTranslator/LunaTranslator/gui/pretransfile.py
+++ b/LunaTranslator/LunaTranslator/gui/pretransfile.py
@@ -95,7 +95,7 @@ def sqlite2json2(self, sqlitefile, targetjson=None, existsmerge=False):
for k in existsjs:
if k not in js_format2 or js_format2[k] == "":
js_format2[k] = existsjs[k]
-
+ os.makedirs(os.path.dirname(target), exist_ok=True)
with open(target, "w", encoding="utf8") as ff:
ff.write(
json.dumps(js_format2, ensure_ascii=False, sort_keys=False, indent=4)
@@ -109,8 +109,7 @@ def sqlite2json2(self, sqlitefile, targetjson=None, existsmerge=False):
def sqlite2json(self):
- os.makedirs("./translation_record", exist_ok=True)
- f = QFileDialog.getOpenFileName(directory="./translation_record", filter="*.sqlite")
+ f = QFileDialog.getOpenFileName(directory="translation_record", filter="*.sqlite")
if f[0] == "":
return
diff --git a/LunaTranslator/LunaTranslator/gui/selecthook.py b/LunaTranslator/LunaTranslator/gui/selecthook.py
index aefd1821..5afc18d4 100644
--- a/LunaTranslator/LunaTranslator/gui/selecthook.py
+++ b/LunaTranslator/LunaTranslator/gui/selecthook.py
@@ -74,8 +74,7 @@ class QButtonGroup_switch_widegt(QWidget):
def listprocessm():
- os.makedirs("cache/temp", exist_ok=True)
- cachefname = os.path.abspath("cache/temp/{}.txt".format(time.time()))
+ cachefname = gobject.gettempdir("{}.txt".format(time.time()))
arch = "64" if gobject.baseobject.textsource.is64bit else "32"
exe = os.path.abspath("./files/plugins/shareddllproxy{}.exe".format(arch))
pid = " ".join([str(_) for _ in gobject.baseobject.textsource.pids])
@@ -211,7 +210,7 @@ class searchhookparam(QDialog):
layout1 = QHBoxLayout()
layout1.addWidget(QLabel(_TR("代码页")))
self.codepagesave = {
- "spcp": savehook_new_data[gobject.baseobject.textsource.pname].get(
+ "spcp": savehook_new_data[gobject.baseobject.textsource.gameuid].get(
"codepage_index", globalconfig["codepage_index"]
)
}
@@ -513,7 +512,7 @@ class hookselect(closeashidewindow):
gobject.baseobject.textsource.hooktypecollecter,
key,
callback=functools.partial(
- savehook_new_data[gobject.baseobject.textsource.pname][
+ savehook_new_data[gobject.baseobject.textsource.gameuid][
"hooktypeasname"
].__setitem__,
json.dumps(gobject.baseobject.textsource.serialkey(key)),
@@ -537,10 +536,10 @@ class hookselect(closeashidewindow):
if hn[:8] == "UserHook":
needinserthookcode = savehook_new_data[
- gobject.baseobject.textsource.pname
+ gobject.baseobject.textsource.gameuid
]["needinserthookcode"]
needinserthookcode = list(set(needinserthookcode + [hc]))
- savehook_new_data[gobject.baseobject.textsource.pname].update(
+ savehook_new_data[gobject.baseobject.textsource.gameuid].update(
{"needinserthookcode": needinserthookcode}
)
else:
@@ -552,19 +551,19 @@ class hookselect(closeashidewindow):
gobject.baseobject.textsource.useembed(tp.addr, tp.ctx, tp.ctx2, _)
_use = self._check_tp_using(key)
if _use:
- savehook_new_data[gobject.baseobject.textsource.pname][
+ savehook_new_data[gobject.baseobject.textsource.gameuid][
"embedablehook"
].append([hc, tp.addr, tp.ctx, tp.ctx2])
else:
save = []
- for _ in savehook_new_data[gobject.baseobject.textsource.pname][
+ for _ in savehook_new_data[gobject.baseobject.textsource.gameuid][
"embedablehook"
]:
hc, ad, c1, c2 = _
if (hc, 0, c1, c2) == (hc, 0, tp.ctx, tp.ctx2):
save.append(_)
for _ in save:
- savehook_new_data[gobject.baseobject.textsource.pname][
+ savehook_new_data[gobject.baseobject.textsource.gameuid][
"embedablehook"
].remove(_)
@@ -710,7 +709,7 @@ class hookselect(closeashidewindow):
def opengamesetting(self):
try:
- dialog_setting_game(self, gobject.baseobject.textsource.pname, True)
+ dialog_setting_game(self, gobject.baseobject.textsource.gameuid, True)
except:
print_exc()
@@ -865,16 +864,16 @@ class hookselect(closeashidewindow):
if hn[:8] == "UserHook":
needinserthookcode = savehook_new_data[
- gobject.baseobject.textsource.pname
+ gobject.baseobject.textsource.gameuid
]["needinserthookcode"]
needinserthookcode = list(set(needinserthookcode + [hc]))
- savehook_new_data[gobject.baseobject.textsource.pname].update(
+ savehook_new_data[gobject.baseobject.textsource.gameuid].update(
{"needinserthookcode": needinserthookcode}
)
else:
pass
- savehook_new_data[gobject.baseobject.textsource.pname].update(
+ savehook_new_data[gobject.baseobject.textsource.gameuid].update(
{"hook": gobject.baseobject.textsource.serialselectedhook()}
)
except:
diff --git a/LunaTranslator/LunaTranslator/gui/setting_about.py b/LunaTranslator/LunaTranslator/gui/setting_about.py
index aa7de973..89752b7a 100644
--- a/LunaTranslator/LunaTranslator/gui/setting_about.py
+++ b/LunaTranslator/LunaTranslator/gui/setting_about.py
@@ -52,8 +52,10 @@ def doupdate():
elif platform.architecture()[0] == "32bit":
bit = "_x86"
_6432 = "32"
- os.makedirs("./cache", exist_ok=True)
- shutil.copy(rf".\files\plugins\shareddllproxy{_6432}.exe", rf".\cache\Updater.exe")
+ shutil.copy(
+ rf".\files\plugins\shareddllproxy{_6432}.exe",
+ gobject.getcachedir("Updater.exe"),
+ )
subprocess.Popen(rf".\cache\Updater.exe update .\cache\update\LunaTranslator{bit}")
@@ -82,9 +84,7 @@ def updatemethod(_version, self):
_version, bit
)
- savep = "./cache/update/LunaTranslator{}.zip".format(bit)
-
- os.makedirs("./cache/update", exist_ok=True)
+ savep = gobject.getcachedir("update/LunaTranslator{}.zip".format(bit))
r2 = requests.get(
url, stream=True, verify=False, proxies=getproxy(("github", "download"))
@@ -124,11 +124,9 @@ def updatemethod(_version, self):
def uncompress(self, savep):
self.progresssignal.emit("正在解压……", 10000)
- os.makedirs("./cache/update", exist_ok=True)
- if os.path.exists("./cache/update/LunaTranslator"):
- shutil.rmtree("./cache/update/LunaTranslator")
+ shutil.rmtree(gobject.getcachedir("update/LunaTranslator"))
with zipfile.ZipFile(savep) as zipf:
- zipf.extractall("./cache/update")
+ zipf.extractall(gobject.getcachedir("update"))
@threader
diff --git a/LunaTranslator/LunaTranslator/gui/setting_display_text.py b/LunaTranslator/LunaTranslator/gui/setting_display_text.py
index c536abfc..ebaadfde 100644
--- a/LunaTranslator/LunaTranslator/gui/setting_display_text.py
+++ b/LunaTranslator/LunaTranslator/gui/setting_display_text.py
@@ -72,8 +72,9 @@ class extrahtml(saveposwindow):
)
def savehtml(self):
- os.makedirs("userconfig", exist_ok=True)
- with open("userconfig/extrahtml.html", "w", encoding="utf8") as ff:
+ with open(
+ gobject.getuserconfigdir("extrahtml.html"), "w", encoding="utf8"
+ ) as ff:
ff.write(self.vistext.toPlainText())
def __init__(self, parent) -> None:
@@ -188,8 +189,7 @@ def doinstallqweb(self, dd, base):
getQMessageBox(self, "错误", f"请选择_{base}")
return
with zipfile.ZipFile(dd["k"]) as zipf:
- target = "cache/temp/QWebEngine"
- os.makedirs(target, exist_ok=True)
+ target = gobject.gettempdir("QWebEngine/")
zipf.extractall(target)
bit = ["x86", "x64"][platform.architecture()[0] == "64bit"]
copytree(f"{target}/{bit}/PyQt5", "LunaTranslator/runtime/PyQt5")
diff --git a/LunaTranslator/LunaTranslator/gui/setting_textinput.py b/LunaTranslator/LunaTranslator/gui/setting_textinput.py
index 51713b4d..6b03f9eb 100644
--- a/LunaTranslator/LunaTranslator/gui/setting_textinput.py
+++ b/LunaTranslator/LunaTranslator/gui/setting_textinput.py
@@ -7,6 +7,7 @@ from myutils.config import (
_TR,
_TRL,
savehook_new_data,
+ uid2gamepath,
savehook_new_list,
static_data,
)
@@ -176,7 +177,7 @@ def gethookgrid(self):
return grids
-def doexportchspatch(exe, realgame):
+def doexportchspatch(exe, gameuid):
b = windows.GetBinaryType(exe)
is64 = b == 6
@@ -199,10 +200,10 @@ def doexportchspatch(exe, realgame):
embedconfig = {
"translation_file": "translation.json",
"target_exe": os.path.basename(exe),
- "target_exe2": os.path.basename(realgame),
+ "target_exe2": os.path.basename(exe),
"startup_argument": None,
"inject_timeout": 1000,
- "embedhook": savehook_new_data[realgame]["embedablehook"],
+ "embedhook": savehook_new_data[gameuid]["embedablehook"],
"embedsettings": {
"font": (
globalconfig["embedded"]["changefont_font"]
@@ -219,7 +220,7 @@ def doexportchspatch(exe, realgame):
ff.write(json.dumps(embedconfig, ensure_ascii=False, indent=4))
-def getunknowgameexe(self):
+def selectgameuid(self):
dialog = QDialog(self, Qt.WindowType.WindowCloseButtonHint) # 自定义一个dialog
dialog.setWindowTitle(_TR("选择游戏"))
@@ -245,10 +246,10 @@ def getunknowgameexe(self):
def exportchspatch(self):
- realgame = getunknowgameexe(self)
- if realgame is None:
+ gameuid = selectgameuid(self)
+ if gameuid is None:
return
- exe = realgame
+ exe = uid2gamepath[gameuid]
if exe.lower().endswith(".exe") == False:
f = QFileDialog.getOpenFileName(
self, caption=_TR("选择EXE文件"), filter="*.exe"
@@ -257,16 +258,15 @@ def exportchspatch(self):
if exe == "":
return
exe = os.path.normpath(exe)
- doexportchspatch(exe, realgame)
+ doexportchspatch(exe, gameuid)
md5 = getfilemd5(exe)
name = os.path.basename(exe).replace("." + os.path.basename(exe).split(".")[-1], "")
- os.makedirs("./translation_record", exist_ok=True)
- sqlfname_all = "./translation_record/" + name + "_" + md5 + ".sqlite"
+ sqlfname_all = gobject.gettranslationrecorddir(name + "_" + md5 + ".sqlite")
if os.path.exists(sqlfname_all) == False:
f = QFileDialog.getOpenFileName(
self,
caption=_TR("选择预翻译文件"),
- directory="./translation_record/",
+ directory="translation_record",
filter="*.sqlite",
)
sqlfname_all = f[0]
@@ -388,10 +388,10 @@ def getTabclip(self):
grids = [
[
- "排除复制自翻译器的文本",
+ "排除复制自翻译器的文本",
D_getsimpleswitch(globalconfig, "excule_from_self"),
"",
- ""
+ "",
]
]
return grids
diff --git a/LunaTranslator/LunaTranslator/gui/showword.py b/LunaTranslator/LunaTranslator/gui/showword.py
index 46d1a7be..d3e63cc5 100644
--- a/LunaTranslator/LunaTranslator/gui/showword.py
+++ b/LunaTranslator/LunaTranslator/gui/showword.py
@@ -6,7 +6,7 @@ import qtawesome, requests, gobject, windows
import myutils.ankiconnect as anki
from myutils.hwnd import grabwindow
from myutils.utils import parsekeystringtomodvkcode, unsupportkey
-from myutils.config import globalconfig, _TR, static_data
+from myutils.config import globalconfig, _TR, static_data, savehook_new_data
from myutils.subproc import subproc_w
from myutils.wrapper import threader
from myutils.ocrutil import imageCut, ocr_run
@@ -39,12 +39,10 @@ def getimageformat():
return getimageformatlist()[globalconfig["imageformat"]]
+
class loopbackrecorder:
def __init__(self):
- os.makedirs("cache/temp", exist_ok=True)
- self.file = os.path.abspath(
- os.path.join("cache/temp", str(time.time()) + ".wav")
- )
+ self.file = gobject.gettempdir(str(time.time()) + ".wav")
try:
self.waitsignal = str(time.time())
self.engine = subproc_w(
@@ -112,8 +110,7 @@ class AnkiWindow(QWidget):
refreshhtml = pyqtSignal()
def callbacktts(self, edit, data):
- fname = "cache/temp/" + str(uuid.uuid4()) + ".mp3"
- os.makedirs("cache/temp", exist_ok=True)
+ fname = gobject.gettempdir(str(uuid.uuid4()) + ".mp3")
with open(fname, "wb") as ff:
ff.write(data)
edit.setText(os.path.abspath(fname))
@@ -140,8 +137,7 @@ class AnkiWindow(QWidget):
img = imageCut(
0, rect[0][0], rect[0][1], rect[1][0], rect[1][1], False, True
)
- fname = "cache/temp/" + str(uuid.uuid4()) + "." + getimageformat()
- os.makedirs("cache/temp", exist_ok=True)
+ fname = gobject.gettempdir(str(uuid.uuid4()) + "." + getimageformat())
img.save(fname)
self.editpath.setText(os.path.abspath(fname))
if globalconfig["ankiconnect"]["ocrcroped"]:
@@ -337,12 +333,17 @@ class AnkiWindow(QWidget):
model_htmlfront = self.fronttext.toPlainText()
model_htmlback = self.backtext.toPlainText()
model_css = self.csstext.toPlainText()
- os.makedirs("userconfig/anki", exist_ok=True)
- with open("userconfig/anki/back.html", "w", encoding="utf8") as ff:
+ with open(
+ gobject.getuserconfigdir("anki/back.html"), "w", encoding="utf8"
+ ) as ff:
ff.write(model_htmlback)
- with open("userconfig/anki/front.html", "w", encoding="utf8") as ff:
+ with open(
+ gobject.getuserconfigdir("anki/front.html"), "w", encoding="utf8"
+ ) as ff:
ff.write(model_htmlfront)
- with open("userconfig/anki/style.css", "w", encoding="utf8") as ff:
+ with open(
+ gobject.getuserconfigdir("anki/style.css"), "w", encoding="utf8"
+ ) as ff:
ff.write(model_css)
def creatsetdtab(self, baselay):
@@ -431,14 +432,34 @@ class AnkiWindow(QWidget):
@threader
def simulate_key(self, i):
- if not globalconfig["ankiconnect"]["simulate_key"][i]["use"]:
+ def __internal__keystring(i):
+ try:
+ for _ in (0,):
+
+ if not gobject.baseobject.textsource:
+ break
+
+ gameuid = gobject.baseobject.textsource.gameuid
+ if not gameuid:
+ break
+ if savehook_new_data[gameuid]["follow_default_ankisettings"]:
+ break
+ if not savehook_new_data[gameuid][f"anki_simulate_key_{i}_use"]:
+ return None
+ return savehook_new_data[gameuid][
+ f"anki_simulate_key_{i}_keystring"
+ ]
+ except:
+ pass
+ return globalconfig["ankiconnect"]["simulate_key"][i]["keystring"]
+
+ keystring = __internal__keystring(i)
+ if not keystring:
return
windows.SetForegroundWindow(gobject.baseobject.textsource.hwnd)
time.sleep(0.1)
try:
- modes, vkcode = parsekeystringtomodvkcode(
- globalconfig["ankiconnect"]["simulate_key"][i]["keystring"], modes=True
- )
+ modes, vkcode = parsekeystringtomodvkcode(keystring, modes=True)
except unsupportkey as e:
print("不支持的键")
return
@@ -593,7 +614,9 @@ class AnkiWindow(QWidget):
or pix.height() > self.viewimagelabel.height()
):
pix = pix.scaled(
- self.viewimagelabel.size() * rate, Qt.AspectRatioMode.KeepAspectRatio
+ self.viewimagelabel.size() * rate,
+ Qt.AspectRatioMode.KeepAspectRatio,
+ Qt.TransformationMode.SmoothTransformation,
)
self.viewimagelabel.setPixmap(pix)
@@ -650,11 +673,30 @@ class AnkiWindow(QWidget):
return model_htmlfront, model_htmlback, model_css
def addanki(self):
+
+ def __internal__DeckName():
+ try:
+ for _ in (0,):
+
+ if not gobject.baseobject.textsource:
+ break
+
+ gameuid = gobject.baseobject.textsource.gameuid
+ if not gameuid:
+ break
+ if savehook_new_data[gameuid]["follow_default_ankisettings"]:
+ break
+
+ return savehook_new_data[gameuid]["anki_DeckName"]
+ except:
+ pass
+ return globalconfig["ankiconnect"]["DeckName"]
+
autoUpdateModel = globalconfig["ankiconnect"]["autoUpdateModel"]
allowDuplicate = globalconfig["ankiconnect"]["allowDuplicate"]
anki.global_port = globalconfig["ankiconnect"]["port"]
ModelName = globalconfig["ankiconnect"]["ModelName5"]
- DeckName = globalconfig["ankiconnect"]["DeckName"]
+ DeckName = __internal__DeckName()
model_htmlfront, model_htmlback, model_css = self.tryloadankitemplates()
tags = globalconfig["ankiconnect"]["tags"]
anki.Deck.create(DeckName)
diff --git a/LunaTranslator/LunaTranslator/gui/specialwidget.py b/LunaTranslator/LunaTranslator/gui/specialwidget.py
index 10369e03..05f9a73d 100644
--- a/LunaTranslator/LunaTranslator/gui/specialwidget.py
+++ b/LunaTranslator/LunaTranslator/gui/specialwidget.py
@@ -474,7 +474,6 @@ class delayloadvbox(QWidget):
self.lock = threading.Lock()
self.nowvisregion = QRect()
-
def resizeEvent(self, e: QResizeEvent):
if e.oldSize().width() != e.size().width():
@@ -483,6 +482,7 @@ class delayloadvbox(QWidget):
if isinstance(w, QWidget):
w.resize(self.width(), w.height())
return super().resizeEvent(e)
+
def _dovisinternal(self, procevent, region: QRect):
if region.isEmpty():
return
@@ -544,6 +544,12 @@ class delayloadvbox(QWidget):
# setFixedHeight会导致上面的闪烁
self._dovisinternal(False, self.nowvisregion)
+ def torank1(self, i):
+ with self.lock:
+ self.internal_widgets.insert(0, self.internal_widgets.pop(i))
+ self.internal_itemH.insert(0, self.internal_itemH.pop(i))
+ self._dovisinternal(False, self.nowvisregion)
+
def insertw(self, i, wf, height):
refresh = True
with self.lock:
@@ -597,6 +603,9 @@ class shrinkableitem(QWidget):
def insertw(self, i, wf, height):
self.items.insertw(i, wf, height)
+ def torank1(self, i):
+ self.items.torank1(i)
+
def popw(self, i):
return self.items.popw(i)
diff --git a/LunaTranslator/LunaTranslator/gui/translatorUI.py b/LunaTranslator/LunaTranslator/gui/translatorUI.py
index 9d01be5d..f570a72e 100644
--- a/LunaTranslator/LunaTranslator/gui/translatorUI.py
+++ b/LunaTranslator/LunaTranslator/gui/translatorUI.py
@@ -3,11 +3,11 @@ 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
+from myutils.config import globalconfig, saveallconfig, _TR, static_data, gamepath2uid
from myutils.subproc import endsubprocs
from myutils.ocrutil import ocr_run, imageCut
from myutils.utils import loadpostsettingwindowmethod, str2rgba
-from myutils.hwnd import mouseselectwindow, grabwindow, getExeIcon
+from myutils.hwnd import mouseselectwindow, grabwindow, getExeIcon, getpidexe
from gui.setting_about import doupdate
from gui.dialog_memory import dialog_memory
from gui.textbrowser import Textbrowser
@@ -381,7 +381,7 @@ class QUnFrameWindow(resizableframeless):
"open_relative_link",
lambda: browserdialog(
gobject.baseobject.commonstylebase,
- trypass(lambda: gobject.baseobject.textsource.pname)(),
+ trypass(lambda: gobject.baseobject.textsource.gameuid)(),
),
),
(
@@ -797,6 +797,9 @@ 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)
+ if gameuid:
+ gobject.baseobject.textsource.gameuid = gameuid
self.isbindedwindow = pid != _pid
self.refreshtoolicon()
@@ -1007,7 +1010,7 @@ class QUnFrameWindow(resizableframeless):
def tryremoveuseless(self):
try:
- shutil.rmtree("./cache/temp")
+ shutil.rmtree(gobject.gettempdir(''))
except:
pass
try:
diff --git a/LunaTranslator/LunaTranslator/gui/usefulwidget.py b/LunaTranslator/LunaTranslator/gui/usefulwidget.py
index 3faf5b35..e085ee56 100644
--- a/LunaTranslator/LunaTranslator/gui/usefulwidget.py
+++ b/LunaTranslator/LunaTranslator/gui/usefulwidget.py
@@ -920,8 +920,7 @@ class abstractwebview(QWidget):
if len(html) < self.html_limit:
self._setHtml(html)
else:
- os.makedirs("cache/temp", exist_ok=True)
- lastcachehtml = os.path.abspath("cache/temp/" + str(time.time()) + ".html")
+ lastcachehtml = gobject.gettempdir(str(time.time()) + ".html")
with open(lastcachehtml, "w", encoding="utf8") as ff:
ff.write(html)
self.navigate(lastcachehtml)
@@ -1665,9 +1664,9 @@ class listediter(QDialog):
if self.closecallback:
self.closecallback()
- def __cb(self, path):
-
- self.hcmodel.insertRow(0, [QStandardItem(path)])
+ def __cb(self, paths):
+ for path in paths:
+ self.hcmodel.insertRow(0, [QStandardItem(path)])
def click1(self):
@@ -1676,7 +1675,7 @@ class listediter(QDialog):
else:
openfiledirectory(
"",
- multi=False,
+ multi=True,
edit=None,
isdir=self.ispathsedit.get("isdir", False),
filter1=self.ispathsedit.get("filter1", "*.*"),
diff --git a/LunaTranslator/LunaTranslator/metadata/abstract.py b/LunaTranslator/LunaTranslator/metadata/abstract.py
index 85d293fb..375e7e70 100644
--- a/LunaTranslator/LunaTranslator/metadata/abstract.py
+++ b/LunaTranslator/LunaTranslator/metadata/abstract.py
@@ -45,19 +45,24 @@ class common:
Thread(target=self.__autodownloadimage).start()
def __autodownloadimage(self):
+ def tryremove(pair):
+ try:
+ globalconfig["metadata"][self.typename]["downloadtasks"].remove(
+ list(pair)
+ )
+ except:
+ pass
+
while True:
- url, save = self.__tasks.get()
+ pair = self.__tasks.get()
+ url, save = pair
if os.path.exists(save):
+ tryremove(pair)
continue
if self.__realdodownload(url, save):
- try:
- globalconfig["metadata"][self.typename]["downloadtasks"].remove(
- (url, save)
- )
- except:
- pass
+ tryremove(pair)
else:
- self.__tasks.put((url, save))
+ self.__tasks.put(pair)
time.sleep(1)
def __realdodownload(self, url, save):
@@ -73,36 +78,27 @@ class common:
}
try:
_content = self.proxysession.get(url, headers=headers).content
+ os.makedirs(os.path.dirname(save), exist_ok=True)
with open(save, "wb") as ff:
ff.write(_content)
return True
except:
return False
- def dispatchdownloadtask(self, url, ishtml=False, delay=True):
+ def dispatchdownloadtask(self, url):
__routine = f"cache/metadata/{self.typename}"
if self.typename == "vndb":
__routine = "cache/vndb"
- os.makedirs(__routine, exist_ok=True)
- if ishtml:
- __ = ".html"
+
+ if "." in url[5:]:
+ __ = url[url.rfind(".") :]
else:
- if "." in url[5:]:
- __ = url[url.rfind(".") :]
- else:
- __ = ".jpg"
+ __ = ".jpg"
savepath = f"{__routine}/{self.b64string(url)}{__}"
- if delay:
- globalconfig["metadata"][self.typename]["downloadtasks"].append(
- (url, savepath)
- )
- self.__tasks.put((url, savepath))
- return savepath
- else:
- if self.__realdodownload(url, savepath):
- return savepath
- else:
- return None
+
+ globalconfig["metadata"][self.typename]["downloadtasks"].append((url, savepath))
+ self.__tasks.put((url, savepath))
+ return savepath
def b64string(self, a):
return hashlib.md5(a.encode("utf8")).hexdigest()
diff --git a/LunaTranslator/LunaTranslator/metadata/vndb.py b/LunaTranslator/LunaTranslator/metadata/vndb.py
index 72f8781a..2afdf606 100644
--- a/LunaTranslator/LunaTranslator/metadata/vndb.py
+++ b/LunaTranslator/LunaTranslator/metadata/vndb.py
@@ -1,7 +1,7 @@
import requests, re, os
from myutils.config import tryreadconfig, safesave
import gzip, json
-import shutil
+import shutil, gobject
from metadata.abstract import common
@@ -156,14 +156,12 @@ def safedownload(proxy):
"https://dl.vndb.org/dump/vndb-tags-latest.json.gz",
proxies=proxy,
)
- os.makedirs("cache/temp", exist_ok=True)
- with open("cache/temp/vndb-tags-latest.json.gz", "wb") as ff:
+ jsongz = gobject.gettempdir("vndb-tags-latest.json.gz")
+ jsonfile = gobject.gettempdir("vndb-tags-latest.json")
+ with open(jsongz, "wb") as ff:
ff.write(resp.content)
- decompress_gzip_file(
- "cache/temp/vndb-tags-latest.json.gz",
- "cache/temp/vndb-tags-latest.json",
- )
- with open("cache/temp/vndb-tags-latest.json", "r", encoding="utf8") as ff:
+ decompress_gzip_file(jsongz, jsonfile)
+ with open(jsonfile, "r", encoding="utf8") as ff:
js = json.load(ff)
newjs = {}
for item in js:
@@ -215,18 +213,6 @@ def getvntagsbyid(proxy, vid):
return tags
-
-def gettagfromhtml(path):
- if path and os.path.exists(path):
- with open(path, "r", encoding="utf8") as ff:
- html = ff.read()
- find = re.search('
([\\s\\S]*?)
', html)
- if find:
- html = find.groups()[0]
- return [_[1] for _ in re.findall("(.*?)", html)]
- return []
-
-
class searcher(common):
def refmainpage(self, _id):
@@ -238,8 +224,27 @@ class searcher(common):
return int(vid[1:])
return None
+ def gettagfromhtml(self, _vid):
+
+ headers = {
+ "sec-ch-ua": '"Microsoft Edge";v="113", "Chromium";v="113", "Not-A.Brand";v="24"',
+ "Referer": "https://vndb.org/",
+ "sec-ch-ua-mobile": "?0",
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36 Edg/113.0.1774.42",
+ "sec-ch-ua-platform": '"Windows"',
+ }
+ try:
+ html = self.proxysession.get(self.refmainpage(_vid), headers=headers).text
+ except:
+ return []
+ find = re.search('([\\s\\S]*?)
', html)
+ if find:
+ html = find.groups()[0]
+ return [_[1] for _ in re.findall("(.*?)", html)]
+ else:
+ return []
+
def searchfordata(self, _vid):
- os.makedirs("./cache/vndb", exist_ok=True)
vid = "v{}".format(_vid)
img = getimgbyid(self.proxy, vid)
title = gettitlebyid(self.proxy, vid)
@@ -247,11 +252,7 @@ class searcher(common):
vndbtags = [] # getvntagsbyid(self.proxy, vid) #这个东西谜之慢
if len(vndbtags) == 0:
# 没代理时下不动那个tag的json
- vndbtags = gettagfromhtml(
- self.dispatchdownloadtask(
- self.refmainpage(_vid), ishtml=True, delay=False
- )
- )
+ vndbtags = self.gettagfromhtml(_vid)
developers = getdevelopersbyid(self.proxy, vid)
try:
imagepath_much2 = [
diff --git a/LunaTranslator/LunaTranslator/myutils/config.py b/LunaTranslator/LunaTranslator/myutils/config.py
index 99b15bb3..8d5add2e 100644
--- a/LunaTranslator/LunaTranslator/myutils/config.py
+++ b/LunaTranslator/LunaTranslator/myutils/config.py
@@ -4,22 +4,23 @@ from traceback import print_exc
def tryreadconfig(path, default=None):
+ path = os.path.join("userconfig", path)
+ if not os.path.exists(path):
+ path += ".tmp"
+ dfret = default if default else {}
+ if not os.path.exists(path):
+ return dfret
try:
- path = os.path.join("./userconfig/", path)
- if os.path.exists(path) == False:
- path += ".tmp"
- if os.path.exists(path):
- with open(path, "r", encoding="utf-8") as ff:
- x = json.load(ff)
- else:
- x = default if default else {}
+ with open(path, "r", encoding="utf-8") as ff:
+ x = json.load(ff)
+
return x
except:
- return {}
+ return dfret
def tryreadconfig2(path):
- path = os.path.join("./files/defaultconfig/", path)
+ path = os.path.join("files/defaultconfig", path)
with open(path, "r", encoding="utf-8") as ff:
x = json.load(ff)
return x
@@ -41,25 +42,67 @@ magpie_config = tryreadconfig("magpie_config.json")
postprocessconfig = tryreadconfig("postprocessconfig.json")
noundictconfig = tryreadconfig("noundictconfig.json")
transerrorfixdictconfig = tryreadconfig("transerrorfixdictconfig.json")
-_savehook = tryreadconfig("savehook_new_1.39.4.json", default=[[], {}])
-try:
+_savehook = tryreadconfig("savegamedata_5.3.1.json")
+if _savehook:
+ # 新版
+ # savehook_new_list: [uid,...]
+ # savehook_new_data:{uid:dict,...}
+ # savegametaged:[ None, {'games':[uid,...],'title':str,'opened':bool,'uid':str},...]
+ # gamepath2uid:{gamepath:uid}
savehook_new_list = _savehook[0]
savehook_new_data = _savehook[1]
-except:
- savehook_new_list = []
- savehook_new_data = {}
-
-try:
savegametaged = _savehook[2]
-except:
- savegametaged = [None]
+ gamepath2uid = _savehook[3]
+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},...]
+ try:
+ savehook_new_list = _savehook[0]
+ savehook_new_data = _savehook[1]
+ except:
+ savehook_new_list = []
+ savehook_new_data = {}
+
+ try:
+ savegametaged = _savehook[2]
+ except:
+ savegametaged = [None]
+
+ # 将savehook_new_data转换为新的格式
+ 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
+ savehook_new_data = __savehook_new_data
+
+ # 将global游戏表和自定义子列表都转换成新格式
+ def parselist(ls):
+ for i in range(len(ls)):
+ ori = ls[i]
+ if ori not in gamepath2uid:
+ continue
+ ls[i] = gamepath2uid[ori]
+
+ parselist(savehook_new_list)
+ for sub in savegametaged:
+ if sub is None:
+ continue
+ parselist(sub["games"])
translatorsetting = tryreadconfig("translatorsetting.json")
ocrsetting = tryreadconfig("ocrsetting.json")
def getdefaultsavehook(gamepath, title=None):
default = {
+ # "gamepath": gamepath,
"hooksetting_follow_default": True,
"hooksetting_private": {}, # 显示时再加载,缺省用global中的键
"textproc_follow_default": True,
@@ -71,6 +114,8 @@ def getdefaultsavehook(gamepath, title=None):
"lang_follow_default": True,
# "private_srclang": 0,# 显示时再加载,缺省用global中的键
# "private_tgtlang": 0,
+ "follow_default_ankisettings": True,
+ # "anki_DeckName":str
"localeswitcher": 0,
"onloadautochangemode2": 0,
"needinserthookcode": [],
@@ -132,19 +177,31 @@ def getdefaultsavehook(gamepath, title=None):
_dfsavehook = getdefaultsavehook("")
-for game in savehook_new_data:
+for uid in savehook_new_data:
if (
- ("allow_tts_auto_names_v4" not in savehook_new_data[game])
- and ("allow_tts_auto_names" in savehook_new_data[game])
- and len(savehook_new_data[game]["allow_tts_auto_names"])
+ ("allow_tts_auto_names_v4" not in savehook_new_data[uid])
+ and ("allow_tts_auto_names" in savehook_new_data[uid])
+ and len(savehook_new_data[uid]["allow_tts_auto_names"])
):
- savehook_new_data[game]["allow_tts_auto_names_v4"] = savehook_new_data[game][
+ savehook_new_data[uid]["allow_tts_auto_names_v4"] = savehook_new_data[uid][
"allow_tts_auto_names"
].split("|")
for k in _dfsavehook:
- if k not in savehook_new_data[game]:
- savehook_new_data[game][k] = _dfsavehook[k]
+ if k not in savehook_new_data[uid]:
+ savehook_new_data[uid][k] = _dfsavehook[k]
+
+
+class __uid2gamepath:
+ def __setitem__(self, uid, value):
+
+ savehook_new_data[uid]["gamepath"] = value
+
+ def __getitem__(self, uid):
+ return savehook_new_data.get(uid, {}).get("gamepath", None)
+
+
+uid2gamepath = __uid2gamepath()
def syncconfig(config1, default, drop=False, deep=0, skipdict=False):
@@ -367,8 +424,8 @@ def saveallconfig():
safesave("./userconfig/ocrerrorfix.json", ocrerrorfix)
safesave("./userconfig/ocrsetting.json", ocrsetting)
safesave(
- "./userconfig/savehook_new_1.39.4.json",
- [savehook_new_list, savehook_new_data, savegametaged],
+ "./userconfig/savegamedata_5.3.1.json",
+ [savehook_new_list, savehook_new_data, savegametaged, gamepath2uid],
)
safesave(
"./files/lang/{}.json".format(getlanguse()),
diff --git a/LunaTranslator/LunaTranslator/myutils/hwnd.py b/LunaTranslator/LunaTranslator/myutils/hwnd.py
index b73fe923..d3d39d1f 100644
--- a/LunaTranslator/LunaTranslator/myutils/hwnd.py
+++ b/LunaTranslator/LunaTranslator/myutils/hwnd.py
@@ -10,21 +10,19 @@ from myutils.wrapper import threader
@threader
def grabwindow(app="PNG", callback=None):
if callback:
- fnamebase = "cache/temp"
+ fname = gobject.gettempdir(time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()))
else:
- fnamebase = "cache/screenshot/{}".format(0)
+ dirname = "0"
+
try:
if gobject.baseobject.textsource.md5 != "0":
- fnamebase = "cache/screenshot/{}".format(
- gobject.baseobject.textsource.basename
- )
+ dirname = gobject.baseobject.textsource.basename
except:
pass
- if os.path.exists(fnamebase) == False:
- os.mkdir(fnamebase)
- fname = "{}/{}".format(
- fnamebase, time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
- )
+ fname = gobject.getcachedir(
+ f"screenshot/{dirname}/"
+ + time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()),
+ )
hwnd = windows.FindWindow(
"Window_Magpie_967EB565-6F73-4E94-AE53-00CC42592A22", None
@@ -154,8 +152,9 @@ def getExeIcon(name, icon=True, cache=False):
name = exepath
data = winsharedutils.extracticon2data(name)
if cache:
- os.makedirs("./cache/icon", exist_ok=True)
- fn = "./cache/icon/{}.bmp".format(hashlib.md5(name.encode("utf8")).hexdigest())
+ fn = gobject.getcachedir(
+ "icon/{}.bmp".format(hashlib.md5(name.encode("utf8")).hexdigest())
+ )
if data:
pixmap = QPixmap()
pixmap.loadFromData(data)
diff --git a/LunaTranslator/LunaTranslator/myutils/post.py b/LunaTranslator/LunaTranslator/myutils/post.py
index 98ad0269..7b0c25b4 100644
--- a/LunaTranslator/LunaTranslator/myutils/post.py
+++ b/LunaTranslator/LunaTranslator/myutils/post.py
@@ -373,22 +373,24 @@ def POSTSOLVE(line):
usemypostpath = "./userconfig/mypost.py"
usemodule = "mypost"
try:
- if gobject.baseobject.textsource and ("pname" in dir(gobject.baseobject.textsource)):
- exepath = gobject.baseobject.textsource.pname
- if not savehook_new_data[exepath]["textproc_follow_default"]:
- useranklist = savehook_new_data[exepath]["save_text_process_info"][
+ if gobject.baseobject.textsource:
+ gameuid = gobject.baseobject.textsource.gameuid
+ if gameuid and not savehook_new_data[gameuid]["textproc_follow_default"]:
+ useranklist = savehook_new_data[gameuid]["save_text_process_info"][
"rank"
]
- usedpostprocessconfig = savehook_new_data[exepath][
+ usedpostprocessconfig = savehook_new_data[gameuid][
"save_text_process_info"
]["postprocessconfig"]
- if savehook_new_data[exepath]["save_text_process_info"]["mypost"]:
+ if savehook_new_data[gameuid]["save_text_process_info"].get(
+ "mypost", None
+ ):
usemodule = (
"posts."
- + savehook_new_data[exepath]["save_text_process_info"]["mypost"]
+ + savehook_new_data[gameuid]["save_text_process_info"]["mypost"]
)
usemypostpath = "./userconfig/posts/{}.py".format(
- savehook_new_data[exepath]["save_text_process_info"]["mypost"]
+ savehook_new_data[gameuid]["save_text_process_info"]["mypost"]
)
except:
print_exc()
diff --git a/LunaTranslator/LunaTranslator/myutils/utils.py b/LunaTranslator/LunaTranslator/myutils/utils.py
index 6642bf54..1f2b629e 100644
--- a/LunaTranslator/LunaTranslator/myutils/utils.py
+++ b/LunaTranslator/LunaTranslator/myutils/utils.py
@@ -3,7 +3,7 @@ import os, time
from traceback import print_exc
import codecs, hashlib
import os, time
-import socket, gobject
+import socket, gobject, uuid
import ctypes, importlib
import time
import ctypes.wintypes
@@ -15,7 +15,8 @@ from myutils.config import (
static_data,
getlanguse,
savehook_new_data,
- _TR,
+ uid2gamepath,
+ gamepath2uid,
getdefaultsavehook,
)
from ctypes import c_float, pointer, c_void_p
@@ -30,14 +31,15 @@ def __internal__getlang(k1, k2):
if not gobject.baseobject.textsource:
break
- if "pname" not in dir(gobject.baseobject.textsource):
+
+ gameuid = gobject.baseobject.textsource.gameuid
+ if not gameuid:
break
- exepath = gobject.baseobject.textsource.pname
- if savehook_new_data[exepath]["lang_follow_default"]:
+ if savehook_new_data[gameuid]["lang_follow_default"]:
break
return static_data["language_list_translator_inner"][
- savehook_new_data[exepath][k1]
+ savehook_new_data[gameuid][k1]
]
except:
pass
@@ -116,16 +118,18 @@ class PriorityQueue:
searchvndbqueue = PriorityQueue()
-def guessmaybetitle(gamepath):
+def guessmaybetitle(gamepath, title):
__t = []
print(gamepath)
for _ in [
- savehook_new_data[gamepath]["title"],
+ title,
os.path.basename(os.path.dirname(gamepath)),
os.path.basename(gamepath)[:-4],
]:
+ if not title:
+ continue
_ = _.replace("(同人ゲーム)", "").replace("(18禁ゲーム)", "")
_ = re.sub(r"\[RJ(.*?)\]", "", _)
_ = re.sub(r"\[\d{4}-?\d{2}\-?\d{2}\]", "", _)
@@ -150,7 +154,7 @@ def guessmaybetitle(gamepath):
targetmod = {}
-def trysearchforid(gamepath, searchargs: list):
+def trysearchforid(gameuid, searchargs: list):
infoid = None
primitivtemetaorigin = globalconfig["primitivtemetaorigin"]
__ = list(targetmod.keys())
@@ -168,17 +172,17 @@ def trysearchforid(gamepath, searchargs: list):
if not vid:
continue
idname = globalconfig["metadata"][key]["target"]
- savehook_new_data[gamepath][idname] = vid
+ savehook_new_data[gameuid][idname] = vid
if infoid is None or key == primitivtemetaorigin:
infoid = key, vid
if key == primitivtemetaorigin:
break
if infoid:
- searchvndbqueue.put((1, gamepath, infoid))
+ searchvndbqueue.put((1, gameuid, infoid))
return infoid
-def trysearchfordata(gamepath, key, vid):
+def trysearchfordata(gameuid, key, vid):
try:
data = targetmod[key].searchfordata(vid)
except:
@@ -193,34 +197,34 @@ def trysearchfordata(gamepath, key, vid):
for _ in imagepath_all:
if _ is None:
continue
- if _ not in savehook_new_data[gamepath]["imagepath_all"]:
- savehook_new_data[gamepath]["imagepath_all"].append(_)
+ if _ not in savehook_new_data[gameuid]["imagepath_all"]:
+ savehook_new_data[gameuid]["imagepath_all"].append(_)
if title:
- if not savehook_new_data[gamepath]["istitlesetted"]:
- savehook_new_data[gamepath]["title"] = title
+ if not savehook_new_data[gameuid]["istitlesetted"]:
+ savehook_new_data[gameuid]["title"] = title
_vis = globalconfig["metadata"][key]["name"]
_url = targetmod[key].refmainpage(vid)
- _urls = [_[1] for _ in savehook_new_data[gamepath]["relationlinks"]]
+ _urls = [_[1] for _ in savehook_new_data[gameuid]["relationlinks"]]
if _url not in _urls:
- savehook_new_data[gamepath]["relationlinks"].append(
+ savehook_new_data[gameuid]["relationlinks"].append(
(_vis, targetmod[key].refmainpage(vid))
)
if namemap:
- savehook_new_data[gamepath]["namemap"] = namemap
+ savehook_new_data[gameuid]["namemap"] = namemap
if len(webtags):
- savehook_new_data[gamepath]["webtags"] = webtags
+ savehook_new_data[gameuid]["webtags"] = webtags
if len(developers):
- savehook_new_data[gamepath]["developers"] = developers
+ savehook_new_data[gameuid]["developers"] = developers
return True
def everymethodsthread():
while True:
_ = searchvndbqueue.get()
- _type, gamepath, arg = _
+ _type, gameuid, arg = _
try:
if _type == 0:
- infoid = trysearchforid(gamepath, arg)
+ infoid = trysearchforid(gameuid, arg)
key, vid = infoid
gobject.baseobject.translation_ui.displayglobaltooltip.emit(
f"{key}: found {vid}"
@@ -228,7 +232,7 @@ def everymethodsthread():
elif _type == 1:
key, vid = arg
- if trysearchfordata(gamepath, key, vid):
+ if trysearchfordata(gameuid, key, vid):
gobject.baseobject.translation_ui.displayglobaltooltip.emit(
f"{key}: {vid} data loaded"
)
@@ -241,8 +245,8 @@ def everymethodsthread():
print_exc()
-def gamdidchangedtask(key, idname, gamepath):
- vid = savehook_new_data[gamepath][idname]
+def gamdidchangedtask(key, idname, gameuid):
+ vid = savehook_new_data[gameuid][idname]
if vid == "":
return
else:
@@ -253,26 +257,34 @@ def gamdidchangedtask(key, idname, gamepath):
except:
print(vid)
return
- savehook_new_data[gamepath][idname] = vid
- searchvndbqueue.put((1, gamepath, (key, vid)), 1)
+ savehook_new_data[gameuid][idname] = vid
+ searchvndbqueue.put((1, gameuid, (key, vid)), 1)
except:
print_exc()
-def titlechangedtask(gamepath, title):
- savehook_new_data[gamepath]["title"] = title
- savehook_new_data[gamepath]["istitlesetted"] = True
- searchvndbqueue.put((0, gamepath, [title]), 1)
+def titlechangedtask(gameuid, title):
+ savehook_new_data[gameuid]["title"] = title
+ savehook_new_data[gameuid]["istitlesetted"] = True
+ searchvndbqueue.put((0, gameuid, [title]), 1)
def checkifnewgame(targetlist, gamepath, title=None):
- isnew = gamepath not in targetlist
+ if gamepath not in gamepath2uid:
+ uid = f"{time.time()}_{uuid.uuid4()}"
+ gamepath2uid[gamepath] = uid
+ savehook_new_data[uid] = getdefaultsavehook(gamepath, title)
+
+ uid2gamepath[uid] = gamepath
+ searchvndbqueue.put((0, uid, [title] + guessmaybetitle(gamepath, title)))
+ else:
+ uid = gamepath2uid[gamepath]
+ isnew = uid not in targetlist
if isnew:
- targetlist.insert(0, gamepath)
- if gamepath not in savehook_new_data:
- savehook_new_data[gamepath] = getdefaultsavehook(gamepath, title)
- searchvndbqueue.put((0, gamepath, [title] + guessmaybetitle(gamepath)))
- return isnew
+ targetlist.insert(0, uid)
+ return uid
+ else:
+ return None
kanjichs2ja = str.maketrans(static_data["kanjichs2ja"])
diff --git a/LunaTranslator/LunaTranslator/ocrengines/mangaocr.py b/LunaTranslator/LunaTranslator/ocrengines/mangaocr.py
index bd6ec799..2586c7cb 100644
--- a/LunaTranslator/LunaTranslator/ocrengines/mangaocr.py
+++ b/LunaTranslator/LunaTranslator/ocrengines/mangaocr.py
@@ -1,15 +1,12 @@
import requests
from ocrengines.baseocrclass import baseocr
-import os, uuid
-from myutils.ocrutil import binary2qimage
-
+import os, uuid, gobject
class OCR(baseocr):
def ocr(self, imagebinary):
- os.makedirs("cache/temp", exist_ok=True)
- fname = "cache/temp/" + str(uuid.uuid4()) + ".png"
+ fname = gobject.gettempdir(str(uuid.uuid4()) + ".png")
with open(fname, "wb") as ff:
ff.write(imagebinary)
self.checkempty(["Port"])
diff --git a/LunaTranslator/LunaTranslator/ocrengines/tesseract5.py b/LunaTranslator/LunaTranslator/ocrengines/tesseract5.py
index 9821ffaf..a44bd4b0 100644
--- a/LunaTranslator/LunaTranslator/ocrengines/tesseract5.py
+++ b/LunaTranslator/LunaTranslator/ocrengines/tesseract5.py
@@ -1,4 +1,4 @@
-import os, uuid
+import os, uuid, gobject
from myutils.config import _TR, ocrsetting
from ocrengines.baseocrclass import baseocr
from myutils.subproc import subproc_w
@@ -24,8 +24,7 @@ class OCR(baseocr):
if os.path.exists(path) == False:
raise Exception(_TR("路径不存在"))
- os.makedirs("cache/temp", exist_ok=True)
- fname = "cache/temp/" + str(uuid.uuid4()) + ".png"
+ fname = gobject.gettempdir(str(uuid.uuid4()) + ".png")
with open(fname, "wb") as ff:
ff.write(imagebinary)
imgfile = os.path.abspath(fname)
diff --git a/LunaTranslator/LunaTranslator/qtsymbols.py b/LunaTranslator/LunaTranslator/qtsymbols.py
index 32f241c2..1de72275 100644
--- a/LunaTranslator/LunaTranslator/qtsymbols.py
+++ b/LunaTranslator/LunaTranslator/qtsymbols.py
@@ -1,8 +1,8 @@
try:
from PyQt5 import QtSvg
- from PyQt5.QtWidgets import QFrame,QListView,QCheckBox,QAbstractItemView,QTextEdit,QTableView,QHeaderView,QColorDialog,QSpinBox,QDoubleSpinBox,QComboBox,QDialogButtonBox,QMainWindow,QMessageBox,QDialog,QGridLayout,QTextBrowser,QGraphicsDropShadowEffect,QWidget,QSizePolicy,QScrollArea,QApplication,QPushButton,QSystemTrayIcon,QPlainTextEdit,QAction,QMenu,QFileDialog,QKeySequenceEdit,QLabel,QSpacerItem,QWidgetItem,QLayout,QTextBrowser,QLineEdit,QFormLayout,QSizePolicy,QTabWidget,QTabBar,QSplitter,QListWidget,QListWidgetItem,QHBoxLayout,QVBoxLayout,QSizeGrip,QFontComboBox,QProgressBar,QRadioButton,QButtonGroup,QSlider,QToolTip,QGroupBox
+ from PyQt5.QtWidgets import QFrame,QListView,QCheckBox,QAbstractItemView,QTextEdit,QTableView,QHeaderView,QColorDialog,QSpinBox,QDoubleSpinBox,QComboBox,QDialogButtonBox,QMainWindow,QMessageBox,QDialog,QGridLayout,QTextBrowser,QGraphicsDropShadowEffect,QWidget,QSizePolicy,QScrollArea,QApplication,QPushButton,QSystemTrayIcon,QPlainTextEdit,QAction,QMenu,QFileDialog,QKeySequenceEdit,QLabel,QSpacerItem,QWidgetItem,QLayout,QTextBrowser,QLineEdit,QFormLayout,QSizePolicy,QTabWidget,QTabBar,QSplitter,QListWidget,QListWidgetItem,QHBoxLayout,QVBoxLayout,QSizeGrip,QFontComboBox,QProgressBar,QRadioButton,QButtonGroup,QSlider,QToolTip,QGroupBox,QGraphicsOpacityEffect
from PyQt5.QtGui import QIconEngine,QIntValidator,QStandardItem,QStandardItemModel,QImageWriter,QIcon,QTextCharFormat,QTextBlockFormat,QResizeEvent,QTextCursor,QFontMetricsF,QMouseEvent,QImage,QPainter,QRegion,QCloseEvent,QFontDatabase,QKeySequence,QPixmap,QCursor,QColor,QFont,QPen,QPainterPath,QBrush,QFontMetrics,QShowEvent,QWheelEvent,QPaintEvent
- from PyQt5.QtCore import QObject,pyqtSignal,Qt,QSize,QByteArray,QBuffer,QPointF,QPoint,QRect,QEvent,QModelIndex,QTimer,QRectF,QVariantAnimation,QUrl
+ from PyQt5.QtCore import QObject,pyqtSignal,Qt,QSize,QByteArray,QBuffer,QPointF,QPoint,QRect,QEvent,QModelIndex,QTimer,QRectF,QVariantAnimation,QUrl,QPropertyAnimation
isqt5 = True
class LineHeightTypes:
LineDistanceHeight=QTextBlockFormat.LineHeightTypes.LineDistanceHeight
@@ -11,9 +11,9 @@ except:
#from traceback import print_exc
#print_exc()
from PyQt6 import QtSvg
- from PyQt6.QtWidgets import QFrame,QListView,QCheckBox,QAbstractItemView,QTextEdit,QTableView,QHeaderView,QColorDialog,QSpinBox,QDoubleSpinBox,QComboBox,QDialogButtonBox,QMainWindow,QMessageBox,QDialog,QGridLayout,QTextBrowser,QGraphicsDropShadowEffect,QWidget,QSizePolicy,QScrollArea,QApplication,QPushButton,QSystemTrayIcon,QPlainTextEdit,QMenu,QFileDialog,QKeySequenceEdit,QLabel,QSpacerItem,QWidgetItem,QLayout,QTextBrowser,QLineEdit,QFormLayout,QSizePolicy,QTabWidget,QTabBar,QSplitter,QListWidget,QListWidgetItem,QHBoxLayout,QVBoxLayout,QSizeGrip,QFontComboBox,QProgressBar,QRadioButton,QButtonGroup,QSlider,QToolTip,QGroupBox
+ from PyQt6.QtWidgets import QFrame,QListView,QCheckBox,QAbstractItemView,QTextEdit,QTableView,QHeaderView,QColorDialog,QSpinBox,QDoubleSpinBox,QComboBox,QDialogButtonBox,QMainWindow,QMessageBox,QDialog,QGridLayout,QTextBrowser,QGraphicsDropShadowEffect,QWidget,QSizePolicy,QScrollArea,QApplication,QPushButton,QSystemTrayIcon,QPlainTextEdit,QMenu,QFileDialog,QKeySequenceEdit,QLabel,QSpacerItem,QWidgetItem,QLayout,QTextBrowser,QLineEdit,QFormLayout,QSizePolicy,QTabWidget,QTabBar,QSplitter,QListWidget,QListWidgetItem,QHBoxLayout,QVBoxLayout,QSizeGrip,QFontComboBox,QProgressBar,QRadioButton,QButtonGroup,QSlider,QToolTip,QGroupBox,QGraphicsOpacityEffect
from PyQt6.QtGui import QIconEngine,QIntValidator,QAction,QStandardItem,QStandardItemModel,QImageWriter,QIcon,QTextCharFormat,QTextBlockFormat,QResizeEvent,QTextCursor,QFontMetricsF,QMouseEvent,QImage,QPainter,QRegion,QCloseEvent,QFontDatabase,QKeySequence,QPixmap,QCursor,QColor,QFont,QPen,QPainterPath,QBrush,QFontMetrics,QShowEvent,QWheelEvent,QPaintEvent
- from PyQt6.QtCore import QObject,pyqtSignal,Qt,QSize,QByteArray,QBuffer,QPointF,QPoint,QRect,QEvent,QModelIndex,QTimer,QRectF,QVariantAnimation,QUrl
+ from PyQt6.QtCore import QObject,pyqtSignal,Qt,QSize,QByteArray,QBuffer,QPointF,QPoint,QRect,QEvent,QModelIndex,QTimer,QRectF,QVariantAnimation,QUrl,QPropertyAnimation
isqt5 = False
class LineHeightTypes:
diff --git a/LunaTranslator/LunaTranslator/scalemethod/magpie_builtin.py b/LunaTranslator/LunaTranslator/scalemethod/magpie_builtin.py
index 5da0684e..1c788802 100644
--- a/LunaTranslator/LunaTranslator/scalemethod/magpie_builtin.py
+++ b/LunaTranslator/LunaTranslator/scalemethod/magpie_builtin.py
@@ -1,6 +1,6 @@
from scalemethod.base import scalebase
import os, json
-import windows
+import windows, gobject
from myutils.config import globalconfig, magpie_config
from myutils.subproc import subproc_w
from myutils.wrapper import threader
@@ -25,8 +25,7 @@ class Method(scalebase):
def init(self):
self.statuslistener()
- os.makedirs("cache/temp", exist_ok=True)
- self.jspath = os.path.abspath("cache/temp/magpie.config.json")
+ self.jspath = gobject.gettempdir("magpie.config.json")
self.engine = subproc_w(
'./files/plugins/Magpie/Magpie.Core.exe "{}"'.format(self.jspath),
cwd="./files/plugins/Magpie/",
diff --git a/LunaTranslator/LunaTranslator/textsource/texthook.py b/LunaTranslator/LunaTranslator/textsource/texthook.py
index e8f2e582..cb05095f 100644
--- a/LunaTranslator/LunaTranslator/textsource/texthook.py
+++ b/LunaTranslator/LunaTranslator/textsource/texthook.py
@@ -10,6 +10,8 @@ from textsource.textsourcebase import basetext
from myutils.utils import checkchaos
from myutils.hwnd import injectdll
from myutils.wrapper import threader
+from myutils.utils import getfilemd5
+
from ctypes import (
CDLL,
CFUNCTYPE,
@@ -85,7 +87,7 @@ EmbedCallback = CFUNCTYPE(None, c_wchar_p, ThreadParam)
class texthook(basetext):
@property
def config(self):
- if savehook_new_data[self.pname]["hooksetting_follow_default"]:
+ if savehook_new_data[self.gameuid]["hooksetting_follow_default"]:
return globalconfig
else:
@@ -96,22 +98,24 @@ class texthook(basetext):
else:
return globalconfig[key]
- return __shitdict(savehook_new_data[self.pname]["hooksetting_private"])
+ return __shitdict(savehook_new_data[self.gameuid]["hooksetting_private"])
def __init__(
- self, pids, hwnd, pname, autostarthookcode=None, needinserthookcode=None
+ self,
+ pids,
+ hwnd,
+ gamepath,
+ gameuid,
+ autostarthookcode=None,
+ needinserthookcode=None,
):
if autostarthookcode is None:
autostarthookcode = []
if needinserthookcode is None:
needinserthookcode = []
- self.pname = pname
- self.pids = pids
- self.hwnd = hwnd
self.keepref = []
self.newline = Queue()
self.newline_delaywait = Queue()
- self.is64bit = Is64bit(pids[0])
self.hookdatacollecter = OrderedDict()
self.hooktypecollecter = OrderedDict()
self.currentname = None
@@ -119,30 +123,41 @@ class texthook(basetext):
self.forward = []
self.selectinghook = None
self.selectedhook = []
+ self.showonce = False
self.selectedhookidx = []
- self.allow_set_text_name = self.config["allow_set_text_name"]
self.connectedpids = []
self.runonce_line = ""
self.autostarthookcode = [self.deserial(__) for __ in autostarthookcode]
- self.isremoveuseless = self.config["removeuseless"] and len(
- self.autostarthookcode
- )
+
self.needinserthookcode = needinserthookcode
self.removedaddress = []
+ super(texthook, self).__init__(*self.checkmd5prefix(gamepath))
+ self.gamepath = gamepath
+ self.gameuid = gameuid
+ self.pids = pids
+ self.is64bit = Is64bit(pids[0])
+ self.hwnd = hwnd
gobject.baseobject.hookselectdialog.changeprocessclearsignal.emit(self.config)
+ self.allow_set_text_name = self.config["allow_set_text_name"]
+ self.isremoveuseless = self.config["removeuseless"] and len(
+ self.autostarthookcode
+ )
if (
len(autostarthookcode) == 0
- and len(savehook_new_data[self.pname]["embedablehook"]) == 0
+ and len(savehook_new_data[self.gameuid]["embedablehook"]) == 0
):
gobject.baseobject.hookselectdialog.realshowhide.emit(True)
-
self.delaycollectallselectedoutput()
-
- super(texthook, self).__init__(*self.checkmd5prefix(pname))
self.declare()
- self.start()
+
+ def checkmd5prefix(self, gamepath):
+ md5 = getfilemd5(gamepath)
+ name = os.path.basename(gamepath).replace(
+ "." + os.path.basename(gamepath).split(".")[-1], ""
+ )
+ return md5, name
def declare(self):
LunaHost = CDLL(
@@ -254,14 +269,24 @@ class texthook(basetext):
def onprocconnect(self, pid):
self.connectedpids.append(pid)
- time.sleep(savehook_new_data[self.pname]["inserthooktimeout"] / 1000)
+ time.sleep(savehook_new_data[self.gameuid]["inserthooktimeout"] / 1000)
for hookcode in self.needinserthookcode:
self.Luna_InsertHookCode(pid, hookcode)
self.showgamename()
self.flashembedsettings(pid)
+ def showgamename(self):
+ if self.showonce:
+ return
+ self.showonce = False
+ gobject.baseobject.textgetmethod(
+ "" + savehook_new_data[self.gameuid]["title"]
+ )
+
def newhookinsert(self, addr, hcode):
- for _hc, _addr, _ctx1, _ctx2 in savehook_new_data[self.pname]["embedablehook"]:
+ for _hc, _addr, _ctx1, _ctx2 in savehook_new_data[self.gameuid][
+ "embedablehook"
+ ]:
if hcode == _hc:
self.useembed(addr, _ctx1, _ctx2, True)
@@ -339,8 +364,8 @@ class texthook(basetext):
self.hookdatacollecter[key] = []
self.hooktypecollecter[key] = 0
if self.allow_set_text_name:
- for jskey in savehook_new_data[self.pname]["hooktypeasname"]:
- if savehook_new_data[self.pname]["hooktypeasname"][jskey] == 0:
+ for jskey in savehook_new_data[self.gameuid]["hooktypeasname"]:
+ if savehook_new_data[self.gameuid]["hooktypeasname"][jskey] == 0:
continue
if self.match_compatibility(self.deserial(json.loads(jskey)), key):
self.hooktypecollecter[key] = 1
@@ -396,7 +421,7 @@ class texthook(basetext):
usestruct.searchTime = 30000
usestruct.maxRecords = 100000
usestruct.codepage = self.codepage()
- usestruct.boundaryModule = os.path.basename(self.pname)
+ usestruct.boundaryModule = os.path.basename(self.gamepath)
usestruct.jittype = 0
return usestruct
@@ -462,8 +487,6 @@ class texthook(basetext):
self.newline.put(_collector)
self.runonce_line = _collector
collector.clear()
-
-
def handle_output(self, hc, hn, tp, output):
diff --git a/LunaTranslator/LunaTranslator/textsource/textsourcebase.py b/LunaTranslator/LunaTranslator/textsource/textsourcebase.py
index 2ad94a1e..03845fa2 100644
--- a/LunaTranslator/LunaTranslator/textsource/textsourcebase.py
+++ b/LunaTranslator/LunaTranslator/textsource/textsourcebase.py
@@ -2,28 +2,30 @@ import threading, gobject, queue
import time, sqlite3, json, os
from traceback import print_exc
from myutils.config import globalconfig, savehook_new_data
-from myutils.utils import getfilemd5, autosql
+from myutils.utils import autosql
class basetext:
+
def __init__(self, md5, basename):
- self.textgetmethod = gobject.baseobject.textgetmethod
- self.ending = False
- self.sqlqueue = queue.Queue()
- if "hwnd" not in dir(self):
- self.hwnd = 0
- if "pids" not in dir(self):
- self.pids = []
self.md5 = md5
self.basename = basename
- os.makedirs("./translation_record", exist_ok=True)
- sqlfname_all_old = (
- "./translation_record/" + md5 + "_" + basename + ".pretrans_common.sqlite"
+ self.hwnd = None
+ self.pids = []
+ self.gameuid = None
+ #
+
+ self.textgetmethod = gobject.baseobject.textgetmethod
+
+ self.ending = False
+ self.sqlqueue = queue.Queue()
+
+ sqlfname_all_old = gobject.gettranslationrecorddir(
+ md5 + "_" + basename + ".pretrans_common.sqlite"
)
- sqlfname_all = "./translation_record/" + basename + "_" + md5 + ".sqlite"
+ sqlfname_all = gobject.gettranslationrecorddir(basename + "_" + md5 + ".sqlite")
if os.path.exists(sqlfname_all_old):
sqlfname_all = sqlfname_all_old
- self.uuname = basename + "_" + md5
try:
# self.sqlwrite=sqlite3.connect(self.sqlfname,check_same_thread = False, isolation_level=None)
@@ -74,7 +76,7 @@ class basetext:
"SELECT * FROM artificialtrans WHERE source = ?", (src,)
).fetchone()
try:
- savehook_new_data[self.pname]["statistic_wordcount"] += lensrc
+ savehook_new_data[self.gameuid]["statistic_wordcount"] += lensrc
except:
pass
if ret is None:
@@ -89,7 +91,7 @@ class basetext:
(src, json.dumps({})),
)
try:
- savehook_new_data[self.pname][
+ savehook_new_data[self.gameuid][
"statistic_wordcount_nodump"
] += lensrc
except:
@@ -111,20 +113,6 @@ class basetext:
except:
print_exc()
- def checkmd5prefix(self, pname):
- md5 = getfilemd5(pname)
- name = os.path.basename(pname).replace(
- "." + os.path.basename(pname).split(".")[-1], ""
- )
- return md5, name
-
- def showgamename(self):
- if "showonce" not in dir(self):
- gobject.baseobject.textgetmethod(
- "" + savehook_new_data[self.pname]["title"]
- )
- self.showonce = 1
-
def gettextthread_(self):
while True:
if self.ending:
diff --git a/LunaTranslator/LunaTranslator/translator/DeepLX.py b/LunaTranslator/LunaTranslator/translator/DeepLX.py
index fb6ff85b..e41880e0 100644
--- a/LunaTranslator/LunaTranslator/translator/DeepLX.py
+++ b/LunaTranslator/LunaTranslator/translator/DeepLX.py
@@ -10,7 +10,7 @@ class TS(basetrans):
return x # {"zh":"ZH","ja":"JA","en":"EN","es":"ES","fr":"FR","ru":"RU"}
def translate(self, query):
-
+ self.checkempty(["api"])
payload = {
"text": query,
"source_lang": self.srclang,
diff --git a/LunaTranslator/LunaTranslator/translator/basetranslator.py b/LunaTranslator/LunaTranslator/translator/basetranslator.py
index 1bfa1aef..70acc06f 100644
--- a/LunaTranslator/LunaTranslator/translator/basetranslator.py
+++ b/LunaTranslator/LunaTranslator/translator/basetranslator.py
@@ -109,10 +109,12 @@ class basetrans(commonbase):
if self.transtype != "pre":
try:
- os.makedirs("./translation_record/cache", exist_ok=True)
+
self.sqlwrite2 = autosql(
sqlite3.connect(
- "./translation_record/cache/{}.sqlite".format(self.typename),
+ gobject.gettranslationrecorddir(
+ "cache/{}.sqlite".format(self.typename)
+ ),
check_same_thread=False,
isolation_level=None,
)
diff --git a/LunaTranslator/LunaTranslator/translator/premt.py b/LunaTranslator/LunaTranslator/translator/premt.py
index 28e9c3e5..418a5d04 100644
--- a/LunaTranslator/LunaTranslator/translator/premt.py
+++ b/LunaTranslator/LunaTranslator/translator/premt.py
@@ -11,8 +11,8 @@ import winsharedutils
class TS(basetrans):
def unsafegetcurrentgameconfig(self):
try:
- _path = gobject.baseobject.textsource.pname
- _path = savehook_new_data[_path]["gamesqlitefile"]
+ gameuid = gobject.baseobject.textsource.gameuid
+ _path = savehook_new_data[gameuid]["gamesqlitefile"]
return _path
except:
return None
diff --git a/LunaTranslator/LunaTranslator/translator/rengong.py b/LunaTranslator/LunaTranslator/translator/rengong.py
index d9dfc7e5..990ce45f 100644
--- a/LunaTranslator/LunaTranslator/translator/rengong.py
+++ b/LunaTranslator/LunaTranslator/translator/rengong.py
@@ -24,8 +24,8 @@ class TS(basetrans):
def unsafegetcurrentgameconfig(self):
try:
- _path = gobject.baseobject.textsource.pname
- _path = savehook_new_data[_path]["gamejsonfile"]
+ gameuid = gobject.baseobject.textsource.gameuid
+ _path = savehook_new_data[gameuid]["gamejsonfile"]
if isinstance(_path, str):
_path = [_path]
return tuple(_path)
diff --git a/LunaTranslator/LunaTranslator/transoptimi/vndbnamemap.py b/LunaTranslator/LunaTranslator/transoptimi/vndbnamemap.py
index 0c9371e3..71098467 100644
--- a/LunaTranslator/LunaTranslator/transoptimi/vndbnamemap.py
+++ b/LunaTranslator/LunaTranslator/transoptimi/vndbnamemap.py
@@ -6,8 +6,8 @@ class Process:
def process_before(self, s):
- exepath = gobject.baseobject.textsource.pname
- namemap = savehook_new_data[exepath]["namemap"]
+ gameuid = gobject.baseobject.textsource.gameuid
+ namemap = savehook_new_data[gameuid]["namemap"]
bettermap = {}
for k, v in namemap.items():
for sp in ["・", " "]:
diff --git a/LunaTranslator/LunaTranslator/tts/NeoSpeech.py b/LunaTranslator/LunaTranslator/tts/NeoSpeech.py
index b9ce997c..8a123d26 100644
--- a/LunaTranslator/LunaTranslator/tts/NeoSpeech.py
+++ b/LunaTranslator/LunaTranslator/tts/NeoSpeech.py
@@ -2,7 +2,7 @@ import time
import os
import windows
from tts.basettsclass import TTSbase
-import ctypes, subprocess
+import ctypes, subprocess, gobject
from myutils.subproc import subproc_w, autoproc
from ctypes import cast, POINTER, c_char, c_int32
@@ -69,8 +69,7 @@ class TTS(TTSbase):
return self.mapx[(hk, idx)]
def getvoicelist(self):
- os.makedirs("cache/temp", exist_ok=True)
- cachefname = os.path.abspath("cache/temp/{}.txt".format(time.time()))
+ cachefname = gobject.gettempdir(f"{time.time()}.txt")
exe = os.path.abspath("./files/plugins/shareddllproxy32.exe")
subprocess.run('"{}" neospeechlist "{}"'.format(exe, cachefname))
diff --git a/LunaTranslator/files/defaultconfig/translatorsetting.json b/LunaTranslator/files/defaultconfig/translatorsetting.json
index 4dc4bc8b..92fd383a 100644
--- a/LunaTranslator/files/defaultconfig/translatorsetting.json
+++ b/LunaTranslator/files/defaultconfig/translatorsetting.json
@@ -6,7 +6,7 @@
},
"DeepLX": {
"args": {
- "api": "https://api.deeplx.org/translate"
+ "api": ""
}
},
"baiduapi": {
diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
index c889945c..47e6f503 100644
--- a/plugins/CMakeLists.txt
+++ b/plugins/CMakeLists.txt
@@ -29,7 +29,7 @@ include(generate_product_version)
set(VERSION_MAJOR 5)
set(VERSION_MINOR 3)
-set(VERSION_PATCH 0)
+set(VERSION_PATCH 1)
add_library(pch pch.cpp)
target_precompile_headers(pch PUBLIC pch.h)