This commit is contained in:
恍兮惚兮 2024-06-26 02:05:58 +08:00
parent 20f739a7c7
commit 3f1ce52f05
35 changed files with 875 additions and 865 deletions

View File

@ -6,6 +6,8 @@ from myutils.config import (
globalconfig, globalconfig,
_TR, _TR,
savehook_new_list, savehook_new_list,
uid2gamepath,
gamepath2uid,
savehook_new_data, savehook_new_data,
setlanguage, setlanguage,
static_data, static_data,
@ -407,7 +409,9 @@ class MAINUI:
try: try:
time.sleep(globalconfig["textthreaddelay"] / 1000) time.sleep(globalconfig["textthreaddelay"] / 1000)
name = self.textsource.currentname 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 needpass = False
if name in names: if name in names:
needpass = True needpass = True
@ -438,7 +442,7 @@ class MAINUI:
text = self.ttsrepair(self.currentread, globalconfig["ttscommon"]) text = self.ttsrepair(self.currentread, globalconfig["ttscommon"])
try: try:
text = self.ttsrepair( text = self.ttsrepair(
text, savehook_new_data[self.textsource.pname] text, savehook_new_data[self.textsource.gameuid]
) )
except: except:
pass pass
@ -476,7 +480,8 @@ class MAINUI:
pids, pexe, hwnd = selectedp pids, pexe, hwnd = selectedp
checkifnewgame(savehook_new_list, pexe, windows.GetWindowText(hwnd)) checkifnewgame(savehook_new_list, pexe, windows.GetWindowText(hwnd))
if globalconfig["sourcestatus2"]["texthook"]["use"]: 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): def starttextsource(self, use=None, checked=True):
self.translation_ui.showhidestate = False self.translation_ui.showhidestate = False
@ -683,7 +688,11 @@ class MAINUI:
hwnd = windows.GetForegroundWindow() hwnd = windows.GetForegroundWindow()
pid = windows.GetWindowThreadProcessId(hwnd) pid = windows.GetWindowThreadProcessId(hwnd)
name_ = getpidexe(pid) 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) lps = ListProcess(False)
for pids, _exe in lps: for pids, _exe in lps:
if _exe == name_: if _exe == name_:
@ -692,23 +701,26 @@ class MAINUI:
self.textsource = None self.textsource = None
if globalconfig["sourcestatus2"]["texthook"]["use"]: if globalconfig["sourcestatus2"]["texthook"]["use"]:
if globalconfig["startgamenototop"] == False: if globalconfig["startgamenototop"] == False:
idx = savehook_new_list.index(name_) idx = savehook_new_list.index(
gamepath2uid[name_]
)
savehook_new_list.insert( savehook_new_list.insert(
0, savehook_new_list.pop(idx) 0, savehook_new_list.pop(idx)
) )
needinserthookcode = savehook_new_data[name_][ needinserthookcode = savehook_new_data[
"needinserthookcode" gamepath2uid[name_]
] ]["needinserthookcode"]
self.textsource = texthook( self.textsource = texthook(
pids, pids,
hwnd, hwnd,
name_, name_,
autostarthookcode=savehook_new_data[name_][ gamepath2uid[name_],
"hook" autostarthookcode=savehook_new_data[
], gamepath2uid[name_]
]["hook"],
needinserthookcode=needinserthookcode, needinserthookcode=needinserthookcode,
) )
self.textsource.start()
else: else:
pids = self.textsource.pids pids = self.textsource.pids
if sum([int(pid_running(pid)) for pid in pids]) == 0: if sum([int(pid_running(pid)) for pid in pids]) == 0:
@ -778,9 +790,10 @@ class MAINUI:
) )
def createsavegamedb(self): def createsavegamedb(self):
os.makedirs("userconfig", exist_ok=True)
self.sqlsavegameinfo = sqlite3.connect( 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: try:
self.sqlsavegameinfo.execute( self.sqlsavegameinfo.execute(
@ -843,21 +856,22 @@ class MAINUI:
savehook_new_data[k].pop("imagepath") savehook_new_data[k].pop("imagepath")
savehook_new_data[k].pop("imagepath_much2") savehook_new_data[k].pop("imagepath_much2")
def querytraceplaytime_v4(self, k): def querytraceplaytime_v4(self, gameuid):
gameinternalid = self.get_gameinternalid(k) gameinternalid = self.get_gameinternalid(uid2gamepath[gameuid])
return self.sqlsavegameinfo.execute( return self.sqlsavegameinfo.execute(
"SELECT timestart,timestop FROM traceplaytime_v4 WHERE gameinternalid = ?", "SELECT timestart,timestop FROM traceplaytime_v4 WHERE gameinternalid = ?",
(gameinternalid,), (gameinternalid,),
).fetchall() ).fetchall()
def get_gameinternalid(self, k): def get_gameinternalid(self, gamepath):
while True: while True:
ret = self.sqlsavegameinfo.execute( ret = self.sqlsavegameinfo.execute(
"SELECT gameinternalid FROM gameinternalid WHERE gamepath = ?", (k,) "SELECT gameinternalid FROM gameinternalid WHERE gamepath = ?",
(gamepath,),
).fetchone() ).fetchone()
if ret is None: if ret is None:
self.sqlsavegameinfo.execute( self.sqlsavegameinfo.execute(
"INSERT INTO gameinternalid VALUES(NULL,?)", (k,) "INSERT INTO gameinternalid VALUES(NULL,?)", (gamepath,)
) )
else: else:
return ret[0] return ret[0]
@ -869,9 +883,9 @@ class MAINUI:
(to, _id), (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: if new:
self.sqlsavegameinfo.execute( self.sqlsavegameinfo.execute(
"INSERT INTO traceplaytime_v4 VALUES(NULL,?,?,?)", "INSERT INTO traceplaytime_v4 VALUES(NULL,?,?,?)",
@ -891,16 +905,21 @@ class MAINUI:
time.sleep(1) time.sleep(1)
_t = time.time() _t = time.time()
def isok(name_): def isok(gameuid):
savehook_new_data[name_]["statistic_playtime"] += _t - __t savehook_new_data[gameuid]["statistic_playtime"] += _t - __t
if self.__currentexe == name_: if self.__currentexe == name_:
self.traceplaytime(name_, self.__statistictime - 1, _t, False) self.traceplaytime(
uid2gamepath[gameuid], self.__statistictime - 1, _t, False
)
else: else:
self.__statistictime = time.time() self.__statistictime = time.time()
self.__currentexe = name_ self.__currentexe = name_
self.traceplaytime( self.traceplaytime(
name_, self.__statistictime - 1, self.__statistictime, True uid2gamepath[gameuid],
self.__statistictime - 1,
self.__statistictime,
True,
) )
try: try:
@ -911,13 +930,17 @@ class MAINUI:
if len(self.textsource.pids) == 0: if len(self.textsource.pids) == 0:
raise Exception() raise Exception()
if _pid in self.textsource.pids or _pid == os.getpid(): if _pid in self.textsource.pids or _pid == os.getpid():
isok(self.textsource.pname) isok(self.textsource.gameuid)
else: else:
self.__currentexe = None self.__currentexe = None
except: except:
name_ = getpidexe(_pid) name_ = getpidexe(_pid)
if name_ and name_ in savehook_new_list: if (
isok(name_) name_
and name_ in gamepath2uid
and gamepath2uid[name_] in savehook_new_list
):
isok(gamepath2uid[name_])
else: else:
self.__currentexe = None self.__currentexe = None
except: except:

View File

@ -1,6 +1,6 @@
import requests import requests
from urllib.parse import quote from urllib.parse import quote
import re, os import re, os, gobject
from cishu.cishubase import cishubase from cishu.cishubase import cishubase
@ -12,15 +12,15 @@ class goo(cishubase):
xx = re.findall("<section>([\\s\\S]*?)</section>", x) xx = re.findall("<section>([\\s\\S]*?)</section>", x)
xx = "".join(xx).replace('href="/', 'href="https://dictionary.goo.ne.jp/') 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( stl = requests.get(
"https://dictionary.goo.ne.jp/mix/css/app.css", proxies=self.proxy "https://dictionary.goo.ne.jp/mix/css/app.css", proxies=self.proxy
).text ).text
os.makedirs("cache/temp", exist_ok=True) with open(temp, "w", encoding="utf8") as ff:
with open("cache/temp/goo.css", "w", encoding="utf8") as ff:
ff.write(stl) ff.write(stl)
else: else:
with open("cache/temp/goo.css", "r", encoding="utf8") as ff: with open(temp, "r", encoding="utf8") as ff:
stl = ff.read() stl = ff.read()
if len(xx): if len(xx):

View File

@ -1,4 +1,4 @@
import math, base64, uuid import math, base64, uuid, gobject
import threading, time import threading, time
@ -341,270 +341,12 @@ def rol(s, x):
return (x << s | x >> (32 - s)) & 0xFFFFFFFF return (x << s | x >> (32 - s)) & 0xFFFFFFFF
r = [ # fmt: off
0, 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]
1, 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]
2, 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]
3, 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]
4, # fmt: on
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,
]
def ripemd128(message): def ripemd128(message):
@ -1962,13 +1704,12 @@ class IndexBuilder(object):
_filename, _file_extension = os.path.splitext(fname) _filename, _file_extension = os.path.splitext(fname)
assert _file_extension == ".mdx" assert _file_extension == ".mdx"
assert os.path.isfile(fname) assert os.path.isfile(fname)
os.makedirs("cache/mdict/index", exist_ok=True)
_mdxmd5 = ( _mdxmd5 = (
os.path.basename(_filename) os.path.basename(_filename)
+ "_" + "_"
+ hashlib.md5(_filename.encode("utf8")).hexdigest() + 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" self._mdx_db = _targetfilenamebase + ".mdx.db"
# make index anyway # make index anyway
if force_rebuild: if force_rebuild:
@ -2363,7 +2104,9 @@ class mdict(cishubase):
self.init_once_mdx(f) self.init_once_mdx(f)
try: 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)) ff.write(json.dumps(self.extraconf, ensure_ascii=False, indent=4))
except: except:
pass pass

View File

@ -15,6 +15,30 @@ def GetDllpath(_, base=None):
return os.path.join(base, _[isbit64]) 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): def dopathexists(file):
if not file: if not file:
return False return False

View File

@ -1,5 +1,5 @@
from qtsymbols import * from qtsymbols import *
import os import os, gobject
from myutils.config import _TR, globalconfig from myutils.config import _TR, globalconfig
from myutils.wrapper import Singleton_close from myutils.wrapper import Singleton_close
from gui.usefulwidget import saveposwindow from gui.usefulwidget import saveposwindow
@ -30,8 +30,7 @@ class dialog_memory(saveposwindow):
self.gamemd5 = gamemd5 self.gamemd5 = gamemd5
formLayout = QVBoxLayout() # formLayout = QVBoxLayout() #
self.showtext = QTextEdit() self.showtext = QTextEdit()
os.makedirs("./userconfig/memory", exist_ok=True) self.rwpath = gobject.getuserconfigdir("memory/{}.html".format(gamemd5))
self.rwpath = "./userconfig/memory/{}.html".format(gamemd5)
try: try:
with open(self.rwpath, "r", encoding="utf8") as ff: with open(self.rwpath, "r", encoding="utf8") as ff:
text = ff.read() text = ff.read()

File diff suppressed because it is too large Load Diff

View File

@ -95,7 +95,7 @@ def sqlite2json2(self, sqlitefile, targetjson=None, existsmerge=False):
for k in existsjs: for k in existsjs:
if k not in js_format2 or js_format2[k] == "": if k not in js_format2 or js_format2[k] == "":
js_format2[k] = existsjs[k] js_format2[k] = existsjs[k]
os.makedirs(os.path.dirname(target), exist_ok=True)
with open(target, "w", encoding="utf8") as ff: with open(target, "w", encoding="utf8") as ff:
ff.write( ff.write(
json.dumps(js_format2, ensure_ascii=False, sort_keys=False, indent=4) 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): 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] == "": if f[0] == "":
return return

View File

@ -74,8 +74,7 @@ class QButtonGroup_switch_widegt(QWidget):
def listprocessm(): def listprocessm():
os.makedirs("cache/temp", exist_ok=True) cachefname = gobject.gettempdir("{}.txt".format(time.time()))
cachefname = os.path.abspath("cache/temp/{}.txt".format(time.time()))
arch = "64" if gobject.baseobject.textsource.is64bit else "32" arch = "64" if gobject.baseobject.textsource.is64bit else "32"
exe = os.path.abspath("./files/plugins/shareddllproxy{}.exe".format(arch)) exe = os.path.abspath("./files/plugins/shareddllproxy{}.exe".format(arch))
pid = " ".join([str(_) for _ in gobject.baseobject.textsource.pids]) pid = " ".join([str(_) for _ in gobject.baseobject.textsource.pids])
@ -211,7 +210,7 @@ class searchhookparam(QDialog):
layout1 = QHBoxLayout() layout1 = QHBoxLayout()
layout1.addWidget(QLabel(_TR("代码页"))) layout1.addWidget(QLabel(_TR("代码页")))
self.codepagesave = { 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"] "codepage_index", globalconfig["codepage_index"]
) )
} }
@ -513,7 +512,7 @@ class hookselect(closeashidewindow):
gobject.baseobject.textsource.hooktypecollecter, gobject.baseobject.textsource.hooktypecollecter,
key, key,
callback=functools.partial( callback=functools.partial(
savehook_new_data[gobject.baseobject.textsource.pname][ savehook_new_data[gobject.baseobject.textsource.gameuid][
"hooktypeasname" "hooktypeasname"
].__setitem__, ].__setitem__,
json.dumps(gobject.baseobject.textsource.serialkey(key)), json.dumps(gobject.baseobject.textsource.serialkey(key)),
@ -537,10 +536,10 @@ class hookselect(closeashidewindow):
if hn[:8] == "UserHook": if hn[:8] == "UserHook":
needinserthookcode = savehook_new_data[ needinserthookcode = savehook_new_data[
gobject.baseobject.textsource.pname gobject.baseobject.textsource.gameuid
]["needinserthookcode"] ]["needinserthookcode"]
needinserthookcode = list(set(needinserthookcode + [hc])) needinserthookcode = list(set(needinserthookcode + [hc]))
savehook_new_data[gobject.baseobject.textsource.pname].update( savehook_new_data[gobject.baseobject.textsource.gameuid].update(
{"needinserthookcode": needinserthookcode} {"needinserthookcode": needinserthookcode}
) )
else: else:
@ -552,19 +551,19 @@ class hookselect(closeashidewindow):
gobject.baseobject.textsource.useembed(tp.addr, tp.ctx, tp.ctx2, _) gobject.baseobject.textsource.useembed(tp.addr, tp.ctx, tp.ctx2, _)
_use = self._check_tp_using(key) _use = self._check_tp_using(key)
if _use: if _use:
savehook_new_data[gobject.baseobject.textsource.pname][ savehook_new_data[gobject.baseobject.textsource.gameuid][
"embedablehook" "embedablehook"
].append([hc, tp.addr, tp.ctx, tp.ctx2]) ].append([hc, tp.addr, tp.ctx, tp.ctx2])
else: else:
save = [] save = []
for _ in savehook_new_data[gobject.baseobject.textsource.pname][ for _ in savehook_new_data[gobject.baseobject.textsource.gameuid][
"embedablehook" "embedablehook"
]: ]:
hc, ad, c1, c2 = _ hc, ad, c1, c2 = _
if (hc, 0, c1, c2) == (hc, 0, tp.ctx, tp.ctx2): if (hc, 0, c1, c2) == (hc, 0, tp.ctx, tp.ctx2):
save.append(_) save.append(_)
for _ in save: for _ in save:
savehook_new_data[gobject.baseobject.textsource.pname][ savehook_new_data[gobject.baseobject.textsource.gameuid][
"embedablehook" "embedablehook"
].remove(_) ].remove(_)
@ -710,7 +709,7 @@ class hookselect(closeashidewindow):
def opengamesetting(self): def opengamesetting(self):
try: try:
dialog_setting_game(self, gobject.baseobject.textsource.pname, True) dialog_setting_game(self, gobject.baseobject.textsource.gameuid, True)
except: except:
print_exc() print_exc()
@ -865,16 +864,16 @@ class hookselect(closeashidewindow):
if hn[:8] == "UserHook": if hn[:8] == "UserHook":
needinserthookcode = savehook_new_data[ needinserthookcode = savehook_new_data[
gobject.baseobject.textsource.pname gobject.baseobject.textsource.gameuid
]["needinserthookcode"] ]["needinserthookcode"]
needinserthookcode = list(set(needinserthookcode + [hc])) needinserthookcode = list(set(needinserthookcode + [hc]))
savehook_new_data[gobject.baseobject.textsource.pname].update( savehook_new_data[gobject.baseobject.textsource.gameuid].update(
{"needinserthookcode": needinserthookcode} {"needinserthookcode": needinserthookcode}
) )
else: else:
pass pass
savehook_new_data[gobject.baseobject.textsource.pname].update( savehook_new_data[gobject.baseobject.textsource.gameuid].update(
{"hook": gobject.baseobject.textsource.serialselectedhook()} {"hook": gobject.baseobject.textsource.serialselectedhook()}
) )
except: except:

View File

@ -52,8 +52,10 @@ def doupdate():
elif platform.architecture()[0] == "32bit": elif platform.architecture()[0] == "32bit":
bit = "_x86" bit = "_x86"
_6432 = "32" _6432 = "32"
os.makedirs("./cache", exist_ok=True) shutil.copy(
shutil.copy(rf".\files\plugins\shareddllproxy{_6432}.exe", rf".\cache\Updater.exe") rf".\files\plugins\shareddllproxy{_6432}.exe",
gobject.getcachedir("Updater.exe"),
)
subprocess.Popen(rf".\cache\Updater.exe update .\cache\update\LunaTranslator{bit}") subprocess.Popen(rf".\cache\Updater.exe update .\cache\update\LunaTranslator{bit}")
@ -82,9 +84,7 @@ def updatemethod(_version, self):
_version, bit _version, bit
) )
savep = "./cache/update/LunaTranslator{}.zip".format(bit) savep = gobject.getcachedir("update/LunaTranslator{}.zip".format(bit))
os.makedirs("./cache/update", exist_ok=True)
r2 = requests.get( r2 = requests.get(
url, stream=True, verify=False, proxies=getproxy(("github", "download")) url, stream=True, verify=False, proxies=getproxy(("github", "download"))
@ -124,11 +124,9 @@ def updatemethod(_version, self):
def uncompress(self, savep): def uncompress(self, savep):
self.progresssignal.emit("正在解压……", 10000) self.progresssignal.emit("正在解压……", 10000)
os.makedirs("./cache/update", exist_ok=True) shutil.rmtree(gobject.getcachedir("update/LunaTranslator"))
if os.path.exists("./cache/update/LunaTranslator"):
shutil.rmtree("./cache/update/LunaTranslator")
with zipfile.ZipFile(savep) as zipf: with zipfile.ZipFile(savep) as zipf:
zipf.extractall("./cache/update") zipf.extractall(gobject.getcachedir("update"))
@threader @threader

View File

@ -72,8 +72,9 @@ class extrahtml(saveposwindow):
) )
def savehtml(self): def savehtml(self):
os.makedirs("userconfig", exist_ok=True) with open(
with open("userconfig/extrahtml.html", "w", encoding="utf8") as ff: gobject.getuserconfigdir("extrahtml.html"), "w", encoding="utf8"
) as ff:
ff.write(self.vistext.toPlainText()) ff.write(self.vistext.toPlainText())
def __init__(self, parent) -> None: def __init__(self, parent) -> None:
@ -188,8 +189,7 @@ def doinstallqweb(self, dd, base):
getQMessageBox(self, "错误", f"请选择_{base}") getQMessageBox(self, "错误", f"请选择_{base}")
return return
with zipfile.ZipFile(dd["k"]) as zipf: with zipfile.ZipFile(dd["k"]) as zipf:
target = "cache/temp/QWebEngine" target = gobject.gettempdir("QWebEngine/")
os.makedirs(target, exist_ok=True)
zipf.extractall(target) zipf.extractall(target)
bit = ["x86", "x64"][platform.architecture()[0] == "64bit"] bit = ["x86", "x64"][platform.architecture()[0] == "64bit"]
copytree(f"{target}/{bit}/PyQt5", "LunaTranslator/runtime/PyQt5") copytree(f"{target}/{bit}/PyQt5", "LunaTranslator/runtime/PyQt5")

View File

@ -7,6 +7,7 @@ from myutils.config import (
_TR, _TR,
_TRL, _TRL,
savehook_new_data, savehook_new_data,
uid2gamepath,
savehook_new_list, savehook_new_list,
static_data, static_data,
) )
@ -176,7 +177,7 @@ def gethookgrid(self):
return grids return grids
def doexportchspatch(exe, realgame): def doexportchspatch(exe, gameuid):
b = windows.GetBinaryType(exe) b = windows.GetBinaryType(exe)
is64 = b == 6 is64 = b == 6
@ -199,10 +200,10 @@ def doexportchspatch(exe, realgame):
embedconfig = { embedconfig = {
"translation_file": "translation.json", "translation_file": "translation.json",
"target_exe": os.path.basename(exe), "target_exe": os.path.basename(exe),
"target_exe2": os.path.basename(realgame), "target_exe2": os.path.basename(exe),
"startup_argument": None, "startup_argument": None,
"inject_timeout": 1000, "inject_timeout": 1000,
"embedhook": savehook_new_data[realgame]["embedablehook"], "embedhook": savehook_new_data[gameuid]["embedablehook"],
"embedsettings": { "embedsettings": {
"font": ( "font": (
globalconfig["embedded"]["changefont_font"] globalconfig["embedded"]["changefont_font"]
@ -219,7 +220,7 @@ def doexportchspatch(exe, realgame):
ff.write(json.dumps(embedconfig, ensure_ascii=False, indent=4)) ff.write(json.dumps(embedconfig, ensure_ascii=False, indent=4))
def getunknowgameexe(self): def selectgameuid(self):
dialog = QDialog(self, Qt.WindowType.WindowCloseButtonHint) # 自定义一个dialog dialog = QDialog(self, Qt.WindowType.WindowCloseButtonHint) # 自定义一个dialog
dialog.setWindowTitle(_TR("选择游戏")) dialog.setWindowTitle(_TR("选择游戏"))
@ -245,10 +246,10 @@ def getunknowgameexe(self):
def exportchspatch(self): def exportchspatch(self):
realgame = getunknowgameexe(self) gameuid = selectgameuid(self)
if realgame is None: if gameuid is None:
return return
exe = realgame exe = uid2gamepath[gameuid]
if exe.lower().endswith(".exe") == False: if exe.lower().endswith(".exe") == False:
f = QFileDialog.getOpenFileName( f = QFileDialog.getOpenFileName(
self, caption=_TR("选择EXE文件"), filter="*.exe" self, caption=_TR("选择EXE文件"), filter="*.exe"
@ -257,16 +258,15 @@ def exportchspatch(self):
if exe == "": if exe == "":
return return
exe = os.path.normpath(exe) exe = os.path.normpath(exe)
doexportchspatch(exe, realgame) doexportchspatch(exe, gameuid)
md5 = getfilemd5(exe) md5 = getfilemd5(exe)
name = os.path.basename(exe).replace("." + os.path.basename(exe).split(".")[-1], "") name = os.path.basename(exe).replace("." + os.path.basename(exe).split(".")[-1], "")
os.makedirs("./translation_record", exist_ok=True) sqlfname_all = gobject.gettranslationrecorddir(name + "_" + md5 + ".sqlite")
sqlfname_all = "./translation_record/" + name + "_" + md5 + ".sqlite"
if os.path.exists(sqlfname_all) == False: if os.path.exists(sqlfname_all) == False:
f = QFileDialog.getOpenFileName( f = QFileDialog.getOpenFileName(
self, self,
caption=_TR("选择预翻译文件"), caption=_TR("选择预翻译文件"),
directory="./translation_record/", directory="translation_record",
filter="*.sqlite", filter="*.sqlite",
) )
sqlfname_all = f[0] sqlfname_all = f[0]
@ -391,7 +391,7 @@ def getTabclip(self):
"排除复制自翻译器的文本", "排除复制自翻译器的文本",
D_getsimpleswitch(globalconfig, "excule_from_self"), D_getsimpleswitch(globalconfig, "excule_from_self"),
"", "",
"" "",
] ]
] ]
return grids return grids

View File

@ -6,7 +6,7 @@ import qtawesome, requests, gobject, windows
import myutils.ankiconnect as anki import myutils.ankiconnect as anki
from myutils.hwnd import grabwindow from myutils.hwnd import grabwindow
from myutils.utils import parsekeystringtomodvkcode, unsupportkey 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.subproc import subproc_w
from myutils.wrapper import threader from myutils.wrapper import threader
from myutils.ocrutil import imageCut, ocr_run from myutils.ocrutil import imageCut, ocr_run
@ -39,12 +39,10 @@ def getimageformat():
return getimageformatlist()[globalconfig["imageformat"]] return getimageformatlist()[globalconfig["imageformat"]]
class loopbackrecorder: class loopbackrecorder:
def __init__(self): def __init__(self):
os.makedirs("cache/temp", exist_ok=True) self.file = gobject.gettempdir(str(time.time()) + ".wav")
self.file = os.path.abspath(
os.path.join("cache/temp", str(time.time()) + ".wav")
)
try: try:
self.waitsignal = str(time.time()) self.waitsignal = str(time.time())
self.engine = subproc_w( self.engine = subproc_w(
@ -112,8 +110,7 @@ class AnkiWindow(QWidget):
refreshhtml = pyqtSignal() refreshhtml = pyqtSignal()
def callbacktts(self, edit, data): def callbacktts(self, edit, data):
fname = "cache/temp/" + str(uuid.uuid4()) + ".mp3" fname = gobject.gettempdir(str(uuid.uuid4()) + ".mp3")
os.makedirs("cache/temp", exist_ok=True)
with open(fname, "wb") as ff: with open(fname, "wb") as ff:
ff.write(data) ff.write(data)
edit.setText(os.path.abspath(fname)) edit.setText(os.path.abspath(fname))
@ -140,8 +137,7 @@ class AnkiWindow(QWidget):
img = imageCut( img = imageCut(
0, rect[0][0], rect[0][1], rect[1][0], rect[1][1], False, True 0, rect[0][0], rect[0][1], rect[1][0], rect[1][1], False, True
) )
fname = "cache/temp/" + str(uuid.uuid4()) + "." + getimageformat() fname = gobject.gettempdir(str(uuid.uuid4()) + "." + getimageformat())
os.makedirs("cache/temp", exist_ok=True)
img.save(fname) img.save(fname)
self.editpath.setText(os.path.abspath(fname)) self.editpath.setText(os.path.abspath(fname))
if globalconfig["ankiconnect"]["ocrcroped"]: if globalconfig["ankiconnect"]["ocrcroped"]:
@ -337,12 +333,17 @@ class AnkiWindow(QWidget):
model_htmlfront = self.fronttext.toPlainText() model_htmlfront = self.fronttext.toPlainText()
model_htmlback = self.backtext.toPlainText() model_htmlback = self.backtext.toPlainText()
model_css = self.csstext.toPlainText() model_css = self.csstext.toPlainText()
os.makedirs("userconfig/anki", exist_ok=True) with open(
with open("userconfig/anki/back.html", "w", encoding="utf8") as ff: gobject.getuserconfigdir("anki/back.html"), "w", encoding="utf8"
) as ff:
ff.write(model_htmlback) 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) 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) ff.write(model_css)
def creatsetdtab(self, baselay): def creatsetdtab(self, baselay):
@ -431,14 +432,34 @@ class AnkiWindow(QWidget):
@threader @threader
def simulate_key(self, i): 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 return
windows.SetForegroundWindow(gobject.baseobject.textsource.hwnd) windows.SetForegroundWindow(gobject.baseobject.textsource.hwnd)
time.sleep(0.1) time.sleep(0.1)
try: try:
modes, vkcode = parsekeystringtomodvkcode( modes, vkcode = parsekeystringtomodvkcode(keystring, modes=True)
globalconfig["ankiconnect"]["simulate_key"][i]["keystring"], modes=True
)
except unsupportkey as e: except unsupportkey as e:
print("不支持的键") print("不支持的键")
return return
@ -593,7 +614,9 @@ class AnkiWindow(QWidget):
or pix.height() > self.viewimagelabel.height() or pix.height() > self.viewimagelabel.height()
): ):
pix = pix.scaled( pix = pix.scaled(
self.viewimagelabel.size() * rate, Qt.AspectRatioMode.KeepAspectRatio self.viewimagelabel.size() * rate,
Qt.AspectRatioMode.KeepAspectRatio,
Qt.TransformationMode.SmoothTransformation,
) )
self.viewimagelabel.setPixmap(pix) self.viewimagelabel.setPixmap(pix)
@ -650,11 +673,30 @@ class AnkiWindow(QWidget):
return model_htmlfront, model_htmlback, model_css return model_htmlfront, model_htmlback, model_css
def addanki(self): 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"] autoUpdateModel = globalconfig["ankiconnect"]["autoUpdateModel"]
allowDuplicate = globalconfig["ankiconnect"]["allowDuplicate"] allowDuplicate = globalconfig["ankiconnect"]["allowDuplicate"]
anki.global_port = globalconfig["ankiconnect"]["port"] anki.global_port = globalconfig["ankiconnect"]["port"]
ModelName = globalconfig["ankiconnect"]["ModelName5"] ModelName = globalconfig["ankiconnect"]["ModelName5"]
DeckName = globalconfig["ankiconnect"]["DeckName"] DeckName = __internal__DeckName()
model_htmlfront, model_htmlback, model_css = self.tryloadankitemplates() model_htmlfront, model_htmlback, model_css = self.tryloadankitemplates()
tags = globalconfig["ankiconnect"]["tags"] tags = globalconfig["ankiconnect"]["tags"]
anki.Deck.create(DeckName) anki.Deck.create(DeckName)

View File

@ -474,7 +474,6 @@ class delayloadvbox(QWidget):
self.lock = threading.Lock() self.lock = threading.Lock()
self.nowvisregion = QRect() self.nowvisregion = QRect()
def resizeEvent(self, e: QResizeEvent): def resizeEvent(self, e: QResizeEvent):
if e.oldSize().width() != e.size().width(): if e.oldSize().width() != e.size().width():
@ -483,6 +482,7 @@ class delayloadvbox(QWidget):
if isinstance(w, QWidget): if isinstance(w, QWidget):
w.resize(self.width(), w.height()) w.resize(self.width(), w.height())
return super().resizeEvent(e) return super().resizeEvent(e)
def _dovisinternal(self, procevent, region: QRect): def _dovisinternal(self, procevent, region: QRect):
if region.isEmpty(): if region.isEmpty():
return return
@ -544,6 +544,12 @@ class delayloadvbox(QWidget):
# setFixedHeight会导致上面的闪烁 # setFixedHeight会导致上面的闪烁
self._dovisinternal(False, self.nowvisregion) 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): def insertw(self, i, wf, height):
refresh = True refresh = True
with self.lock: with self.lock:
@ -597,6 +603,9 @@ class shrinkableitem(QWidget):
def insertw(self, i, wf, height): def insertw(self, i, wf, height):
self.items.insertw(i, wf, height) self.items.insertw(i, wf, height)
def torank1(self, i):
self.items.torank1(i)
def popw(self, i): def popw(self, i):
return self.items.popw(i) return self.items.popw(i)

View File

@ -3,11 +3,11 @@ import time, functools, threading, os, sys, importlib, shutil
from traceback import print_exc from traceback import print_exc
import windows, qtawesome, gobject, winsharedutils import windows, qtawesome, gobject, winsharedutils
from myutils.wrapper import threader, trypass 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.subproc import endsubprocs
from myutils.ocrutil import ocr_run, imageCut from myutils.ocrutil import ocr_run, imageCut
from myutils.utils import loadpostsettingwindowmethod, str2rgba 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.setting_about import doupdate
from gui.dialog_memory import dialog_memory from gui.dialog_memory import dialog_memory
from gui.textbrowser import Textbrowser from gui.textbrowser import Textbrowser
@ -381,7 +381,7 @@ class QUnFrameWindow(resizableframeless):
"open_relative_link", "open_relative_link",
lambda: browserdialog( lambda: browserdialog(
gobject.baseobject.commonstylebase, 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 gobject.baseobject.textsource.hwnd = hwnd if pid != _pid else None
if not globalconfig["sourcestatus2"]["texthook"]["use"]: if not globalconfig["sourcestatus2"]["texthook"]["use"]:
gobject.baseobject.textsource.pids = [pid] if pid != _pid else None 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.isbindedwindow = pid != _pid
self.refreshtoolicon() self.refreshtoolicon()
@ -1007,7 +1010,7 @@ class QUnFrameWindow(resizableframeless):
def tryremoveuseless(self): def tryremoveuseless(self):
try: try:
shutil.rmtree("./cache/temp") shutil.rmtree(gobject.gettempdir(''))
except: except:
pass pass
try: try:

View File

@ -920,8 +920,7 @@ class abstractwebview(QWidget):
if len(html) < self.html_limit: if len(html) < self.html_limit:
self._setHtml(html) self._setHtml(html)
else: else:
os.makedirs("cache/temp", exist_ok=True) lastcachehtml = gobject.gettempdir(str(time.time()) + ".html")
lastcachehtml = os.path.abspath("cache/temp/" + str(time.time()) + ".html")
with open(lastcachehtml, "w", encoding="utf8") as ff: with open(lastcachehtml, "w", encoding="utf8") as ff:
ff.write(html) ff.write(html)
self.navigate(lastcachehtml) self.navigate(lastcachehtml)
@ -1665,9 +1664,9 @@ class listediter(QDialog):
if self.closecallback: if self.closecallback:
self.closecallback() self.closecallback()
def __cb(self, path): def __cb(self, paths):
for path in paths:
self.hcmodel.insertRow(0, [QStandardItem(path)]) self.hcmodel.insertRow(0, [QStandardItem(path)])
def click1(self): def click1(self):
@ -1676,7 +1675,7 @@ class listediter(QDialog):
else: else:
openfiledirectory( openfiledirectory(
"", "",
multi=False, multi=True,
edit=None, edit=None,
isdir=self.ispathsedit.get("isdir", False), isdir=self.ispathsedit.get("isdir", False),
filter1=self.ispathsedit.get("filter1", "*.*"), filter1=self.ispathsedit.get("filter1", "*.*"),

View File

@ -45,19 +45,24 @@ class common:
Thread(target=self.__autodownloadimage).start() Thread(target=self.__autodownloadimage).start()
def __autodownloadimage(self): def __autodownloadimage(self):
def tryremove(pair):
try:
globalconfig["metadata"][self.typename]["downloadtasks"].remove(
list(pair)
)
except:
pass
while True: while True:
url, save = self.__tasks.get() pair = self.__tasks.get()
url, save = pair
if os.path.exists(save): if os.path.exists(save):
tryremove(pair)
continue continue
if self.__realdodownload(url, save): if self.__realdodownload(url, save):
try: tryremove(pair)
globalconfig["metadata"][self.typename]["downloadtasks"].remove(
(url, save)
)
except:
pass
else: else:
self.__tasks.put((url, save)) self.__tasks.put(pair)
time.sleep(1) time.sleep(1)
def __realdodownload(self, url, save): def __realdodownload(self, url, save):
@ -73,36 +78,27 @@ class common:
} }
try: try:
_content = self.proxysession.get(url, headers=headers).content _content = self.proxysession.get(url, headers=headers).content
os.makedirs(os.path.dirname(save), exist_ok=True)
with open(save, "wb") as ff: with open(save, "wb") as ff:
ff.write(_content) ff.write(_content)
return True return True
except: except:
return False return False
def dispatchdownloadtask(self, url, ishtml=False, delay=True): def dispatchdownloadtask(self, url):
__routine = f"cache/metadata/{self.typename}" __routine = f"cache/metadata/{self.typename}"
if self.typename == "vndb": if self.typename == "vndb":
__routine = "cache/vndb" __routine = "cache/vndb"
os.makedirs(__routine, exist_ok=True)
if ishtml: if "." in url[5:]:
__ = ".html" __ = url[url.rfind(".") :]
else: else:
if "." in url[5:]: __ = ".jpg"
__ = url[url.rfind(".") :]
else:
__ = ".jpg"
savepath = f"{__routine}/{self.b64string(url)}{__}" savepath = f"{__routine}/{self.b64string(url)}{__}"
if delay:
globalconfig["metadata"][self.typename]["downloadtasks"].append( globalconfig["metadata"][self.typename]["downloadtasks"].append((url, savepath))
(url, savepath) self.__tasks.put((url, savepath))
) return savepath
self.__tasks.put((url, savepath))
return savepath
else:
if self.__realdodownload(url, savepath):
return savepath
else:
return None
def b64string(self, a): def b64string(self, a):
return hashlib.md5(a.encode("utf8")).hexdigest() return hashlib.md5(a.encode("utf8")).hexdigest()

View File

@ -1,7 +1,7 @@
import requests, re, os import requests, re, os
from myutils.config import tryreadconfig, safesave from myutils.config import tryreadconfig, safesave
import gzip, json import gzip, json
import shutil import shutil, gobject
from metadata.abstract import common from metadata.abstract import common
@ -156,14 +156,12 @@ def safedownload(proxy):
"https://dl.vndb.org/dump/vndb-tags-latest.json.gz", "https://dl.vndb.org/dump/vndb-tags-latest.json.gz",
proxies=proxy, proxies=proxy,
) )
os.makedirs("cache/temp", exist_ok=True) jsongz = gobject.gettempdir("vndb-tags-latest.json.gz")
with open("cache/temp/vndb-tags-latest.json.gz", "wb") as ff: jsonfile = gobject.gettempdir("vndb-tags-latest.json")
with open(jsongz, "wb") as ff:
ff.write(resp.content) ff.write(resp.content)
decompress_gzip_file( decompress_gzip_file(jsongz, jsonfile)
"cache/temp/vndb-tags-latest.json.gz", with open(jsonfile, "r", encoding="utf8") as ff:
"cache/temp/vndb-tags-latest.json",
)
with open("cache/temp/vndb-tags-latest.json", "r", encoding="utf8") as ff:
js = json.load(ff) js = json.load(ff)
newjs = {} newjs = {}
for item in js: for item in js:
@ -215,18 +213,6 @@ def getvntagsbyid(proxy, vid):
return tags 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('<div id="vntags">([\\s\\S]*?)</div>', html)
if find:
html = find.groups()[0]
return [_[1] for _ in re.findall("<a(.*?)>(.*?)</a>", html)]
return []
class searcher(common): class searcher(common):
def refmainpage(self, _id): def refmainpage(self, _id):
@ -238,8 +224,27 @@ class searcher(common):
return int(vid[1:]) return int(vid[1:])
return None 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('<div id="vntags">([\\s\\S]*?)</div>', html)
if find:
html = find.groups()[0]
return [_[1] for _ in re.findall("<a(.*?)>(.*?)</a>", html)]
else:
return []
def searchfordata(self, _vid): def searchfordata(self, _vid):
os.makedirs("./cache/vndb", exist_ok=True)
vid = "v{}".format(_vid) vid = "v{}".format(_vid)
img = getimgbyid(self.proxy, vid) img = getimgbyid(self.proxy, vid)
title = gettitlebyid(self.proxy, vid) title = gettitlebyid(self.proxy, vid)
@ -247,11 +252,7 @@ class searcher(common):
vndbtags = [] # getvntagsbyid(self.proxy, vid) #这个东西谜之慢 vndbtags = [] # getvntagsbyid(self.proxy, vid) #这个东西谜之慢
if len(vndbtags) == 0: if len(vndbtags) == 0:
# 没代理时下不动那个tag的json # 没代理时下不动那个tag的json
vndbtags = gettagfromhtml( vndbtags = self.gettagfromhtml(_vid)
self.dispatchdownloadtask(
self.refmainpage(_vid), ishtml=True, delay=False
)
)
developers = getdevelopersbyid(self.proxy, vid) developers = getdevelopersbyid(self.proxy, vid)
try: try:
imagepath_much2 = [ imagepath_much2 = [

View File

@ -4,22 +4,23 @@ from traceback import print_exc
def tryreadconfig(path, default=None): 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: try:
path = os.path.join("./userconfig/", path) with open(path, "r", encoding="utf-8") as ff:
if os.path.exists(path) == False: x = json.load(ff)
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 {}
return x return x
except: except:
return {} return dfret
def tryreadconfig2(path): 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: with open(path, "r", encoding="utf-8") as ff:
x = json.load(ff) x = json.load(ff)
return x return x
@ -41,25 +42,67 @@ magpie_config = tryreadconfig("magpie_config.json")
postprocessconfig = tryreadconfig("postprocessconfig.json") postprocessconfig = tryreadconfig("postprocessconfig.json")
noundictconfig = tryreadconfig("noundictconfig.json") noundictconfig = tryreadconfig("noundictconfig.json")
transerrorfixdictconfig = tryreadconfig("transerrorfixdictconfig.json") transerrorfixdictconfig = tryreadconfig("transerrorfixdictconfig.json")
_savehook = tryreadconfig("savehook_new_1.39.4.json", default=[[], {}]) _savehook = tryreadconfig("savegamedata_5.3.1.json")
try: 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_list = _savehook[0]
savehook_new_data = _savehook[1] savehook_new_data = _savehook[1]
except:
savehook_new_list = []
savehook_new_data = {}
try:
savegametaged = _savehook[2] savegametaged = _savehook[2]
except: gamepath2uid = _savehook[3]
savegametaged = [None] 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") translatorsetting = tryreadconfig("translatorsetting.json")
ocrsetting = tryreadconfig("ocrsetting.json") ocrsetting = tryreadconfig("ocrsetting.json")
def getdefaultsavehook(gamepath, title=None): def getdefaultsavehook(gamepath, title=None):
default = { default = {
# "gamepath": gamepath,
"hooksetting_follow_default": True, "hooksetting_follow_default": True,
"hooksetting_private": {}, # 显示时再加载缺省用global中的键 "hooksetting_private": {}, # 显示时再加载缺省用global中的键
"textproc_follow_default": True, "textproc_follow_default": True,
@ -71,6 +114,8 @@ def getdefaultsavehook(gamepath, title=None):
"lang_follow_default": True, "lang_follow_default": True,
# "private_srclang": 0,# 显示时再加载缺省用global中的键 # "private_srclang": 0,# 显示时再加载缺省用global中的键
# "private_tgtlang": 0, # "private_tgtlang": 0,
"follow_default_ankisettings": True,
# "anki_DeckName":str
"localeswitcher": 0, "localeswitcher": 0,
"onloadautochangemode2": 0, "onloadautochangemode2": 0,
"needinserthookcode": [], "needinserthookcode": [],
@ -132,19 +177,31 @@ def getdefaultsavehook(gamepath, title=None):
_dfsavehook = getdefaultsavehook("") _dfsavehook = getdefaultsavehook("")
for game in savehook_new_data: for uid in savehook_new_data:
if ( if (
("allow_tts_auto_names_v4" not in savehook_new_data[game]) ("allow_tts_auto_names_v4" not in savehook_new_data[uid])
and ("allow_tts_auto_names" in savehook_new_data[game]) and ("allow_tts_auto_names" in savehook_new_data[uid])
and len(savehook_new_data[game]["allow_tts_auto_names"]) 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" "allow_tts_auto_names"
].split("|") ].split("|")
for k in _dfsavehook: for k in _dfsavehook:
if k not in savehook_new_data[game]: if k not in savehook_new_data[uid]:
savehook_new_data[game][k] = _dfsavehook[k] 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): def syncconfig(config1, default, drop=False, deep=0, skipdict=False):
@ -367,8 +424,8 @@ def saveallconfig():
safesave("./userconfig/ocrerrorfix.json", ocrerrorfix) safesave("./userconfig/ocrerrorfix.json", ocrerrorfix)
safesave("./userconfig/ocrsetting.json", ocrsetting) safesave("./userconfig/ocrsetting.json", ocrsetting)
safesave( safesave(
"./userconfig/savehook_new_1.39.4.json", "./userconfig/savegamedata_5.3.1.json",
[savehook_new_list, savehook_new_data, savegametaged], [savehook_new_list, savehook_new_data, savegametaged, gamepath2uid],
) )
safesave( safesave(
"./files/lang/{}.json".format(getlanguse()), "./files/lang/{}.json".format(getlanguse()),

View File

@ -10,21 +10,19 @@ from myutils.wrapper import threader
@threader @threader
def grabwindow(app="PNG", callback=None): def grabwindow(app="PNG", callback=None):
if callback: if callback:
fnamebase = "cache/temp" fname = gobject.gettempdir(time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()))
else: else:
fnamebase = "cache/screenshot/{}".format(0) dirname = "0"
try: try:
if gobject.baseobject.textsource.md5 != "0": if gobject.baseobject.textsource.md5 != "0":
fnamebase = "cache/screenshot/{}".format( dirname = gobject.baseobject.textsource.basename
gobject.baseobject.textsource.basename
)
except: except:
pass pass
if os.path.exists(fnamebase) == False: fname = gobject.getcachedir(
os.mkdir(fnamebase) f"screenshot/{dirname}/"
fname = "{}/{}".format( + time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()),
fnamebase, time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime()) )
)
hwnd = windows.FindWindow( hwnd = windows.FindWindow(
"Window_Magpie_967EB565-6F73-4E94-AE53-00CC42592A22", None "Window_Magpie_967EB565-6F73-4E94-AE53-00CC42592A22", None
@ -154,8 +152,9 @@ def getExeIcon(name, icon=True, cache=False):
name = exepath name = exepath
data = winsharedutils.extracticon2data(name) data = winsharedutils.extracticon2data(name)
if cache: if cache:
os.makedirs("./cache/icon", exist_ok=True) fn = gobject.getcachedir(
fn = "./cache/icon/{}.bmp".format(hashlib.md5(name.encode("utf8")).hexdigest()) "icon/{}.bmp".format(hashlib.md5(name.encode("utf8")).hexdigest())
)
if data: if data:
pixmap = QPixmap() pixmap = QPixmap()
pixmap.loadFromData(data) pixmap.loadFromData(data)

View File

@ -373,22 +373,24 @@ def POSTSOLVE(line):
usemypostpath = "./userconfig/mypost.py" usemypostpath = "./userconfig/mypost.py"
usemodule = "mypost" usemodule = "mypost"
try: try:
if gobject.baseobject.textsource and ("pname" in dir(gobject.baseobject.textsource)): if gobject.baseobject.textsource:
exepath = gobject.baseobject.textsource.pname gameuid = gobject.baseobject.textsource.gameuid
if not savehook_new_data[exepath]["textproc_follow_default"]: if gameuid and not savehook_new_data[gameuid]["textproc_follow_default"]:
useranklist = savehook_new_data[exepath]["save_text_process_info"][ useranklist = savehook_new_data[gameuid]["save_text_process_info"][
"rank" "rank"
] ]
usedpostprocessconfig = savehook_new_data[exepath][ usedpostprocessconfig = savehook_new_data[gameuid][
"save_text_process_info" "save_text_process_info"
]["postprocessconfig"] ]["postprocessconfig"]
if savehook_new_data[exepath]["save_text_process_info"]["mypost"]: if savehook_new_data[gameuid]["save_text_process_info"].get(
"mypost", None
):
usemodule = ( usemodule = (
"posts." "posts."
+ savehook_new_data[exepath]["save_text_process_info"]["mypost"] + savehook_new_data[gameuid]["save_text_process_info"]["mypost"]
) )
usemypostpath = "./userconfig/posts/{}.py".format( usemypostpath = "./userconfig/posts/{}.py".format(
savehook_new_data[exepath]["save_text_process_info"]["mypost"] savehook_new_data[gameuid]["save_text_process_info"]["mypost"]
) )
except: except:
print_exc() print_exc()

View File

@ -3,7 +3,7 @@ import os, time
from traceback import print_exc from traceback import print_exc
import codecs, hashlib import codecs, hashlib
import os, time import os, time
import socket, gobject import socket, gobject, uuid
import ctypes, importlib import ctypes, importlib
import time import time
import ctypes.wintypes import ctypes.wintypes
@ -15,7 +15,8 @@ from myutils.config import (
static_data, static_data,
getlanguse, getlanguse,
savehook_new_data, savehook_new_data,
_TR, uid2gamepath,
gamepath2uid,
getdefaultsavehook, getdefaultsavehook,
) )
from ctypes import c_float, pointer, c_void_p from ctypes import c_float, pointer, c_void_p
@ -30,14 +31,15 @@ def __internal__getlang(k1, k2):
if not gobject.baseobject.textsource: if not gobject.baseobject.textsource:
break break
if "pname" not in dir(gobject.baseobject.textsource):
gameuid = gobject.baseobject.textsource.gameuid
if not gameuid:
break break
exepath = gobject.baseobject.textsource.pname if savehook_new_data[gameuid]["lang_follow_default"]:
if savehook_new_data[exepath]["lang_follow_default"]:
break break
return static_data["language_list_translator_inner"][ return static_data["language_list_translator_inner"][
savehook_new_data[exepath][k1] savehook_new_data[gameuid][k1]
] ]
except: except:
pass pass
@ -116,16 +118,18 @@ class PriorityQueue:
searchvndbqueue = PriorityQueue() searchvndbqueue = PriorityQueue()
def guessmaybetitle(gamepath): def guessmaybetitle(gamepath, title):
__t = [] __t = []
print(gamepath) print(gamepath)
for _ in [ for _ in [
savehook_new_data[gamepath]["title"], title,
os.path.basename(os.path.dirname(gamepath)), os.path.basename(os.path.dirname(gamepath)),
os.path.basename(gamepath)[:-4], os.path.basename(gamepath)[:-4],
]: ]:
if not title:
continue
_ = _.replace("(同人ゲーム)", "").replace("(18禁ゲーム)", "") _ = _.replace("(同人ゲーム)", "").replace("(18禁ゲーム)", "")
_ = re.sub(r"\[RJ(.*?)\]", "", _) _ = re.sub(r"\[RJ(.*?)\]", "", _)
_ = re.sub(r"\[\d{4}-?\d{2}\-?\d{2}\]", "", _) _ = re.sub(r"\[\d{4}-?\d{2}\-?\d{2}\]", "", _)
@ -150,7 +154,7 @@ def guessmaybetitle(gamepath):
targetmod = {} targetmod = {}
def trysearchforid(gamepath, searchargs: list): def trysearchforid(gameuid, searchargs: list):
infoid = None infoid = None
primitivtemetaorigin = globalconfig["primitivtemetaorigin"] primitivtemetaorigin = globalconfig["primitivtemetaorigin"]
__ = list(targetmod.keys()) __ = list(targetmod.keys())
@ -168,17 +172,17 @@ def trysearchforid(gamepath, searchargs: list):
if not vid: if not vid:
continue continue
idname = globalconfig["metadata"][key]["target"] idname = globalconfig["metadata"][key]["target"]
savehook_new_data[gamepath][idname] = vid savehook_new_data[gameuid][idname] = vid
if infoid is None or key == primitivtemetaorigin: if infoid is None or key == primitivtemetaorigin:
infoid = key, vid infoid = key, vid
if key == primitivtemetaorigin: if key == primitivtemetaorigin:
break break
if infoid: if infoid:
searchvndbqueue.put((1, gamepath, infoid)) searchvndbqueue.put((1, gameuid, infoid))
return infoid return infoid
def trysearchfordata(gamepath, key, vid): def trysearchfordata(gameuid, key, vid):
try: try:
data = targetmod[key].searchfordata(vid) data = targetmod[key].searchfordata(vid)
except: except:
@ -193,34 +197,34 @@ def trysearchfordata(gamepath, key, vid):
for _ in imagepath_all: for _ in imagepath_all:
if _ is None: if _ is None:
continue continue
if _ not in savehook_new_data[gamepath]["imagepath_all"]: if _ not in savehook_new_data[gameuid]["imagepath_all"]:
savehook_new_data[gamepath]["imagepath_all"].append(_) savehook_new_data[gameuid]["imagepath_all"].append(_)
if title: if title:
if not savehook_new_data[gamepath]["istitlesetted"]: if not savehook_new_data[gameuid]["istitlesetted"]:
savehook_new_data[gamepath]["title"] = title savehook_new_data[gameuid]["title"] = title
_vis = globalconfig["metadata"][key]["name"] _vis = globalconfig["metadata"][key]["name"]
_url = targetmod[key].refmainpage(vid) _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: if _url not in _urls:
savehook_new_data[gamepath]["relationlinks"].append( savehook_new_data[gameuid]["relationlinks"].append(
(_vis, targetmod[key].refmainpage(vid)) (_vis, targetmod[key].refmainpage(vid))
) )
if namemap: if namemap:
savehook_new_data[gamepath]["namemap"] = namemap savehook_new_data[gameuid]["namemap"] = namemap
if len(webtags): if len(webtags):
savehook_new_data[gamepath]["webtags"] = webtags savehook_new_data[gameuid]["webtags"] = webtags
if len(developers): if len(developers):
savehook_new_data[gamepath]["developers"] = developers savehook_new_data[gameuid]["developers"] = developers
return True return True
def everymethodsthread(): def everymethodsthread():
while True: while True:
_ = searchvndbqueue.get() _ = searchvndbqueue.get()
_type, gamepath, arg = _ _type, gameuid, arg = _
try: try:
if _type == 0: if _type == 0:
infoid = trysearchforid(gamepath, arg) infoid = trysearchforid(gameuid, arg)
key, vid = infoid key, vid = infoid
gobject.baseobject.translation_ui.displayglobaltooltip.emit( gobject.baseobject.translation_ui.displayglobaltooltip.emit(
f"{key}: found {vid}" f"{key}: found {vid}"
@ -228,7 +232,7 @@ def everymethodsthread():
elif _type == 1: elif _type == 1:
key, vid = arg key, vid = arg
if trysearchfordata(gamepath, key, vid): if trysearchfordata(gameuid, key, vid):
gobject.baseobject.translation_ui.displayglobaltooltip.emit( gobject.baseobject.translation_ui.displayglobaltooltip.emit(
f"{key}: {vid} data loaded" f"{key}: {vid} data loaded"
) )
@ -241,8 +245,8 @@ def everymethodsthread():
print_exc() print_exc()
def gamdidchangedtask(key, idname, gamepath): def gamdidchangedtask(key, idname, gameuid):
vid = savehook_new_data[gamepath][idname] vid = savehook_new_data[gameuid][idname]
if vid == "": if vid == "":
return return
else: else:
@ -253,26 +257,34 @@ def gamdidchangedtask(key, idname, gamepath):
except: except:
print(vid) print(vid)
return return
savehook_new_data[gamepath][idname] = vid savehook_new_data[gameuid][idname] = vid
searchvndbqueue.put((1, gamepath, (key, vid)), 1) searchvndbqueue.put((1, gameuid, (key, vid)), 1)
except: except:
print_exc() print_exc()
def titlechangedtask(gamepath, title): def titlechangedtask(gameuid, title):
savehook_new_data[gamepath]["title"] = title savehook_new_data[gameuid]["title"] = title
savehook_new_data[gamepath]["istitlesetted"] = True savehook_new_data[gameuid]["istitlesetted"] = True
searchvndbqueue.put((0, gamepath, [title]), 1) searchvndbqueue.put((0, gameuid, [title]), 1)
def checkifnewgame(targetlist, gamepath, title=None): 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: if isnew:
targetlist.insert(0, gamepath) targetlist.insert(0, uid)
if gamepath not in savehook_new_data: return uid
savehook_new_data[gamepath] = getdefaultsavehook(gamepath, title) else:
searchvndbqueue.put((0, gamepath, [title] + guessmaybetitle(gamepath))) return None
return isnew
kanjichs2ja = str.maketrans(static_data["kanjichs2ja"]) kanjichs2ja = str.maketrans(static_data["kanjichs2ja"])

View File

@ -1,15 +1,12 @@
import requests import requests
from ocrengines.baseocrclass import baseocr from ocrengines.baseocrclass import baseocr
import os, uuid import os, uuid, gobject
from myutils.ocrutil import binary2qimage
class OCR(baseocr): class OCR(baseocr):
def ocr(self, imagebinary): def ocr(self, imagebinary):
os.makedirs("cache/temp", exist_ok=True) fname = gobject.gettempdir(str(uuid.uuid4()) + ".png")
fname = "cache/temp/" + str(uuid.uuid4()) + ".png"
with open(fname, "wb") as ff: with open(fname, "wb") as ff:
ff.write(imagebinary) ff.write(imagebinary)
self.checkempty(["Port"]) self.checkempty(["Port"])

View File

@ -1,4 +1,4 @@
import os, uuid import os, uuid, gobject
from myutils.config import _TR, ocrsetting from myutils.config import _TR, ocrsetting
from ocrengines.baseocrclass import baseocr from ocrengines.baseocrclass import baseocr
from myutils.subproc import subproc_w from myutils.subproc import subproc_w
@ -24,8 +24,7 @@ class OCR(baseocr):
if os.path.exists(path) == False: if os.path.exists(path) == False:
raise Exception(_TR("路径不存在")) raise Exception(_TR("路径不存在"))
os.makedirs("cache/temp", exist_ok=True) fname = gobject.gettempdir(str(uuid.uuid4()) + ".png")
fname = "cache/temp/" + str(uuid.uuid4()) + ".png"
with open(fname, "wb") as ff: with open(fname, "wb") as ff:
ff.write(imagebinary) ff.write(imagebinary)
imgfile = os.path.abspath(fname) imgfile = os.path.abspath(fname)

View File

@ -1,8 +1,8 @@
try: try:
from PyQt5 import QtSvg 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.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 isqt5 = True
class LineHeightTypes: class LineHeightTypes:
LineDistanceHeight=QTextBlockFormat.LineHeightTypes.LineDistanceHeight LineDistanceHeight=QTextBlockFormat.LineHeightTypes.LineDistanceHeight
@ -11,9 +11,9 @@ except:
#from traceback import print_exc #from traceback import print_exc
#print_exc() #print_exc()
from PyQt6 import QtSvg 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.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 isqt5 = False
class LineHeightTypes: class LineHeightTypes:

View File

@ -1,6 +1,6 @@
from scalemethod.base import scalebase from scalemethod.base import scalebase
import os, json import os, json
import windows import windows, gobject
from myutils.config import globalconfig, magpie_config from myutils.config import globalconfig, magpie_config
from myutils.subproc import subproc_w from myutils.subproc import subproc_w
from myutils.wrapper import threader from myutils.wrapper import threader
@ -25,8 +25,7 @@ class Method(scalebase):
def init(self): def init(self):
self.statuslistener() self.statuslistener()
os.makedirs("cache/temp", exist_ok=True) self.jspath = gobject.gettempdir("magpie.config.json")
self.jspath = os.path.abspath("cache/temp/magpie.config.json")
self.engine = subproc_w( self.engine = subproc_w(
'./files/plugins/Magpie/Magpie.Core.exe "{}"'.format(self.jspath), './files/plugins/Magpie/Magpie.Core.exe "{}"'.format(self.jspath),
cwd="./files/plugins/Magpie/", cwd="./files/plugins/Magpie/",

View File

@ -10,6 +10,8 @@ from textsource.textsourcebase import basetext
from myutils.utils import checkchaos from myutils.utils import checkchaos
from myutils.hwnd import injectdll from myutils.hwnd import injectdll
from myutils.wrapper import threader from myutils.wrapper import threader
from myutils.utils import getfilemd5
from ctypes import ( from ctypes import (
CDLL, CDLL,
CFUNCTYPE, CFUNCTYPE,
@ -85,7 +87,7 @@ EmbedCallback = CFUNCTYPE(None, c_wchar_p, ThreadParam)
class texthook(basetext): class texthook(basetext):
@property @property
def config(self): def config(self):
if savehook_new_data[self.pname]["hooksetting_follow_default"]: if savehook_new_data[self.gameuid]["hooksetting_follow_default"]:
return globalconfig return globalconfig
else: else:
@ -96,22 +98,24 @@ class texthook(basetext):
else: else:
return globalconfig[key] return globalconfig[key]
return __shitdict(savehook_new_data[self.pname]["hooksetting_private"]) return __shitdict(savehook_new_data[self.gameuid]["hooksetting_private"])
def __init__( def __init__(
self, pids, hwnd, pname, autostarthookcode=None, needinserthookcode=None self,
pids,
hwnd,
gamepath,
gameuid,
autostarthookcode=None,
needinserthookcode=None,
): ):
if autostarthookcode is None: if autostarthookcode is None:
autostarthookcode = [] autostarthookcode = []
if needinserthookcode is None: if needinserthookcode is None:
needinserthookcode = [] needinserthookcode = []
self.pname = pname
self.pids = pids
self.hwnd = hwnd
self.keepref = [] self.keepref = []
self.newline = Queue() self.newline = Queue()
self.newline_delaywait = Queue() self.newline_delaywait = Queue()
self.is64bit = Is64bit(pids[0])
self.hookdatacollecter = OrderedDict() self.hookdatacollecter = OrderedDict()
self.hooktypecollecter = OrderedDict() self.hooktypecollecter = OrderedDict()
self.currentname = None self.currentname = None
@ -119,30 +123,41 @@ class texthook(basetext):
self.forward = [] self.forward = []
self.selectinghook = None self.selectinghook = None
self.selectedhook = [] self.selectedhook = []
self.showonce = False
self.selectedhookidx = [] self.selectedhookidx = []
self.allow_set_text_name = self.config["allow_set_text_name"]
self.connectedpids = [] self.connectedpids = []
self.runonce_line = "" self.runonce_line = ""
self.autostarthookcode = [self.deserial(__) for __ in autostarthookcode] self.autostarthookcode = [self.deserial(__) for __ in autostarthookcode]
self.isremoveuseless = self.config["removeuseless"] and len(
self.autostarthookcode
)
self.needinserthookcode = needinserthookcode self.needinserthookcode = needinserthookcode
self.removedaddress = [] 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) 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 ( if (
len(autostarthookcode) == 0 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) gobject.baseobject.hookselectdialog.realshowhide.emit(True)
self.delaycollectallselectedoutput() self.delaycollectallselectedoutput()
super(texthook, self).__init__(*self.checkmd5prefix(pname))
self.declare() 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): def declare(self):
LunaHost = CDLL( LunaHost = CDLL(
@ -254,14 +269,24 @@ class texthook(basetext):
def onprocconnect(self, pid): def onprocconnect(self, pid):
self.connectedpids.append(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: for hookcode in self.needinserthookcode:
self.Luna_InsertHookCode(pid, hookcode) self.Luna_InsertHookCode(pid, hookcode)
self.showgamename() self.showgamename()
self.flashembedsettings(pid) self.flashembedsettings(pid)
def showgamename(self):
if self.showonce:
return
self.showonce = False
gobject.baseobject.textgetmethod(
"<msg_info_refresh>" + savehook_new_data[self.gameuid]["title"]
)
def newhookinsert(self, addr, hcode): 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: if hcode == _hc:
self.useembed(addr, _ctx1, _ctx2, True) self.useembed(addr, _ctx1, _ctx2, True)
@ -339,8 +364,8 @@ class texthook(basetext):
self.hookdatacollecter[key] = [] self.hookdatacollecter[key] = []
self.hooktypecollecter[key] = 0 self.hooktypecollecter[key] = 0
if self.allow_set_text_name: if self.allow_set_text_name:
for jskey in savehook_new_data[self.pname]["hooktypeasname"]: for jskey in savehook_new_data[self.gameuid]["hooktypeasname"]:
if savehook_new_data[self.pname]["hooktypeasname"][jskey] == 0: if savehook_new_data[self.gameuid]["hooktypeasname"][jskey] == 0:
continue continue
if self.match_compatibility(self.deserial(json.loads(jskey)), key): if self.match_compatibility(self.deserial(json.loads(jskey)), key):
self.hooktypecollecter[key] = 1 self.hooktypecollecter[key] = 1
@ -396,7 +421,7 @@ class texthook(basetext):
usestruct.searchTime = 30000 usestruct.searchTime = 30000
usestruct.maxRecords = 100000 usestruct.maxRecords = 100000
usestruct.codepage = self.codepage() usestruct.codepage = self.codepage()
usestruct.boundaryModule = os.path.basename(self.pname) usestruct.boundaryModule = os.path.basename(self.gamepath)
usestruct.jittype = 0 usestruct.jittype = 0
return usestruct return usestruct
@ -463,8 +488,6 @@ class texthook(basetext):
self.runonce_line = _collector self.runonce_line = _collector
collector.clear() collector.clear()
def handle_output(self, hc, hn, tp, output): def handle_output(self, hc, hn, tp, output):
if self.config["filter_chaos_code"] and checkchaos(output): if self.config["filter_chaos_code"] and checkchaos(output):

View File

@ -2,28 +2,30 @@ import threading, gobject, queue
import time, sqlite3, json, os import time, sqlite3, json, os
from traceback import print_exc from traceback import print_exc
from myutils.config import globalconfig, savehook_new_data from myutils.config import globalconfig, savehook_new_data
from myutils.utils import getfilemd5, autosql from myutils.utils import autosql
class basetext: class basetext:
def __init__(self, md5, basename): 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.md5 = md5
self.basename = basename self.basename = basename
os.makedirs("./translation_record", exist_ok=True) self.hwnd = None
sqlfname_all_old = ( self.pids = []
"./translation_record/" + md5 + "_" + basename + ".pretrans_common.sqlite" 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): if os.path.exists(sqlfname_all_old):
sqlfname_all = sqlfname_all_old sqlfname_all = sqlfname_all_old
self.uuname = basename + "_" + md5
try: try:
# self.sqlwrite=sqlite3.connect(self.sqlfname,check_same_thread = False, isolation_level=None) # 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,) "SELECT * FROM artificialtrans WHERE source = ?", (src,)
).fetchone() ).fetchone()
try: try:
savehook_new_data[self.pname]["statistic_wordcount"] += lensrc savehook_new_data[self.gameuid]["statistic_wordcount"] += lensrc
except: except:
pass pass
if ret is None: if ret is None:
@ -89,7 +91,7 @@ class basetext:
(src, json.dumps({})), (src, json.dumps({})),
) )
try: try:
savehook_new_data[self.pname][ savehook_new_data[self.gameuid][
"statistic_wordcount_nodump" "statistic_wordcount_nodump"
] += lensrc ] += lensrc
except: except:
@ -111,20 +113,6 @@ class basetext:
except: except:
print_exc() 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(
"<msg_info_refresh>" + savehook_new_data[self.pname]["title"]
)
self.showonce = 1
def gettextthread_(self): def gettextthread_(self):
while True: while True:
if self.ending: if self.ending:

View File

@ -10,7 +10,7 @@ class TS(basetrans):
return x # {"zh":"ZH","ja":"JA","en":"EN","es":"ES","fr":"FR","ru":"RU"} return x # {"zh":"ZH","ja":"JA","en":"EN","es":"ES","fr":"FR","ru":"RU"}
def translate(self, query): def translate(self, query):
self.checkempty(["api"])
payload = { payload = {
"text": query, "text": query,
"source_lang": self.srclang, "source_lang": self.srclang,

View File

@ -109,10 +109,12 @@ class basetrans(commonbase):
if self.transtype != "pre": if self.transtype != "pre":
try: try:
os.makedirs("./translation_record/cache", exist_ok=True)
self.sqlwrite2 = autosql( self.sqlwrite2 = autosql(
sqlite3.connect( sqlite3.connect(
"./translation_record/cache/{}.sqlite".format(self.typename), gobject.gettranslationrecorddir(
"cache/{}.sqlite".format(self.typename)
),
check_same_thread=False, check_same_thread=False,
isolation_level=None, isolation_level=None,
) )

View File

@ -11,8 +11,8 @@ import winsharedutils
class TS(basetrans): class TS(basetrans):
def unsafegetcurrentgameconfig(self): def unsafegetcurrentgameconfig(self):
try: try:
_path = gobject.baseobject.textsource.pname gameuid = gobject.baseobject.textsource.gameuid
_path = savehook_new_data[_path]["gamesqlitefile"] _path = savehook_new_data[gameuid]["gamesqlitefile"]
return _path return _path
except: except:
return None return None

View File

@ -24,8 +24,8 @@ class TS(basetrans):
def unsafegetcurrentgameconfig(self): def unsafegetcurrentgameconfig(self):
try: try:
_path = gobject.baseobject.textsource.pname gameuid = gobject.baseobject.textsource.gameuid
_path = savehook_new_data[_path]["gamejsonfile"] _path = savehook_new_data[gameuid]["gamejsonfile"]
if isinstance(_path, str): if isinstance(_path, str):
_path = [_path] _path = [_path]
return tuple(_path) return tuple(_path)

View File

@ -6,8 +6,8 @@ class Process:
def process_before(self, s): def process_before(self, s):
exepath = gobject.baseobject.textsource.pname gameuid = gobject.baseobject.textsource.gameuid
namemap = savehook_new_data[exepath]["namemap"] namemap = savehook_new_data[gameuid]["namemap"]
bettermap = {} bettermap = {}
for k, v in namemap.items(): for k, v in namemap.items():
for sp in ["", " "]: for sp in ["", " "]:

View File

@ -2,7 +2,7 @@ import time
import os import os
import windows import windows
from tts.basettsclass import TTSbase from tts.basettsclass import TTSbase
import ctypes, subprocess import ctypes, subprocess, gobject
from myutils.subproc import subproc_w, autoproc from myutils.subproc import subproc_w, autoproc
from ctypes import cast, POINTER, c_char, c_int32 from ctypes import cast, POINTER, c_char, c_int32
@ -69,8 +69,7 @@ class TTS(TTSbase):
return self.mapx[(hk, idx)] return self.mapx[(hk, idx)]
def getvoicelist(self): def getvoicelist(self):
os.makedirs("cache/temp", exist_ok=True) cachefname = gobject.gettempdir(f"{time.time()}.txt")
cachefname = os.path.abspath("cache/temp/{}.txt".format(time.time()))
exe = os.path.abspath("./files/plugins/shareddllproxy32.exe") exe = os.path.abspath("./files/plugins/shareddllproxy32.exe")
subprocess.run('"{}" neospeechlist "{}"'.format(exe, cachefname)) subprocess.run('"{}" neospeechlist "{}"'.format(exe, cachefname))

View File

@ -6,7 +6,7 @@
}, },
"DeepLX": { "DeepLX": {
"args": { "args": {
"api": "https://api.deeplx.org/translate" "api": ""
} }
}, },
"baiduapi": { "baiduapi": {

View File

@ -29,7 +29,7 @@ include(generate_product_version)
set(VERSION_MAJOR 5) set(VERSION_MAJOR 5)
set(VERSION_MINOR 3) set(VERSION_MINOR 3)
set(VERSION_PATCH 0) set(VERSION_PATCH 1)
add_library(pch pch.cpp) add_library(pch pch.cpp)
target_precompile_headers(pch PUBLIC pch.h) target_precompile_headers(pch PUBLIC pch.h)