This commit is contained in:
恍兮惚兮 2024-08-26 15:07:27 +08:00
parent 483ea36170
commit 9be5ac3606
8 changed files with 261 additions and 64 deletions

View File

@ -46,10 +46,12 @@ import windows
import winsharedutils
from winsharedutils import collect_running_pids
from myutils.post import POSTSOLVE
from myutils.utils import nowisdark, getfilemd5
from myutils.utils import nowisdark
from myutils.traceplaytime import playtimemanager
from myutils.audioplayer import series_audioplayer
from gui.dynalang import LAction, LMenu
from gui.setting_textinput_ocr import showocrimage
class MAINUI:
@ -80,8 +82,26 @@ class MAINUI:
self.reader_uid = None
self.__hwnd = None
self.gameuid = 0
self.showocrimage = None
self.showocrimage_cached = None
self.autoswitchgameuid = True
def maybesetimage(self, pair):
if self.showocrimage:
try:
self.showocrimage.setimage.emit(pair)
except:
print_exc()
self.showocrimage_cached = pair
def createshowocrimage(self):
try:
self.showocrimage = showocrimage(self.settin_ui, self.showocrimage_cached)
if self.showocrimage:
self.showocrimage.show()
except:
print_exc()
@property
def reader(self):
return self._internal_reader

View File

@ -1,10 +1,10 @@
from qtsymbols import *
import functools, platform
import gobject, os, zipfile, shutil
import gobject, os, zipfile
from myutils.config import globalconfig, static_data
from gui.inputdialog import multicolorset, autoinitdialog
from myutils.wrapper import tryprint
from myutils.utils import dynamiclink, translate_exits
from myutils.utils import dynamiclink, translate_exits, copytree
from gui.usefulwidget import (
D_getsimplecombobox,
getsimplecombobox,
@ -175,23 +175,6 @@ def createinternalfontsettings(self, forml: LFormLayout, group, _type):
)
def copytree(src, dst, copy_function=shutil.copy2):
names = os.listdir(src)
os.makedirs(dst, exist_ok=True)
for name in names:
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
try:
if os.path.isdir(srcname):
copytree(srcname, dstname, copy_function)
else:
copy_function(srcname, dstname)
except:
pass
def doinstallqweb(self, dd, base):
if not dd["k"].endswith(base):
getQMessageBox(self, "错误", f"请选择_{base}")

View File

@ -7,6 +7,7 @@ from gui.usefulwidget import (
D_getsimplecombobox,
D_getspinbox,
D_getIconButton,
getIconButton,
yuitsu_switch,
D_getcolorbutton,
D_getsimpleswitch,
@ -14,14 +15,15 @@ from gui.usefulwidget import (
getboxlayout,
selectcolor,
TableViewW,
listediter,
saveposwindow,
pixmapviewer,
LStandardItemModel,
LFocusCombo,
threebuttons,
)
import gobject
import gobject, qtawesome
from gui.dynalang import LFormLayout, LDialog, LAction
from myutils.ocrutil import ocr_end, ocr_init
from myutils.ocrutil import ocr_end, ocr_init, ocr_run
from myutils.wrapper import threader, Singleton_close
@ -277,6 +279,74 @@ def _ocrparam(self):
return self._ocrparam
@Singleton_close
class showocrimage(saveposwindow):
setimage = pyqtSignal(QImage)
def closeEvent(self, e):
gobject.baseobject.showocrimage = None
super().closeEvent(e)
def openff(self):
f = QFileDialog.getOpenFileName(
filter="image ("
+ " ".join(
["*" + _.data().decode() for _ in QImageWriter.supportedImageFormats()]
)
+ ")"
)
res = f[0]
if not res:
return
img = QImage(res)
if img.isNull():
return
self.originimage = img
self.setimagefunction(img)
text, infotype = ocr_run(img)
if infotype:
gobject.baseobject.displayinfomessage(text, infotype)
else:
gobject.baseobject.textgetmethod(text, False)
def __init__(self, parent, cached):
self.img1 = None
self.originimage = None
super().__init__(parent, poslist=globalconfig["showocrgeo"])
self.setWindowIcon(qtawesome.icon("fa.picture-o"))
self.setWindowTitle("截图")
self.originlabel = pixmapviewer()
qw = QWidget()
self.layout1 = QVBoxLayout()
self.setCentralWidget(qw)
qw.setLayout(self.layout1)
icon = getIconButton(callback=self.openff, icon="fa.folder-open")
button = getIconButton(callback=self.retest, icon="fa.rotate-right")
hb = QHBoxLayout()
hb.addWidget(icon)
hb.addWidget(button)
self.layout1.addLayout(hb)
self.layout1.addWidget(self.originlabel)
self.setimage.connect(self.setimagefunction)
if cached:
self.setimagefunction(cached)
def retest(self):
if self.originimage is None:
return
text, infotype = ocr_run(self.originimage)
if infotype:
gobject.baseobject.displayinfomessage(text, infotype)
else:
gobject.baseobject.textgetmethod(text, False)
def setimagefunction(self, originimage):
self.originimage = originimage
self.img1 = QPixmap.fromImage(originimage)
self.originlabel.showpixmap(self.img1)
def getocrgrid(self):
grids = []
@ -329,7 +399,13 @@ def getocrgrid(self):
D_getsimplecombobox(
["横向", "竖向", "自适应"], globalconfig, "verticalocr"
),
("", 4),
"",
D_getIconButton(
gobject.baseobject.createshowocrimage,
icon="fa.picture-o",
),
"",
"",
]
],
),

View File

@ -1,12 +1,12 @@
import requests
from myutils.config import savehook_new_data
from myutils.utils import initanewitem, gamdidchangedtask
import functools
import functools, time
from qtsymbols import *
from metadata.abstract import common
from gui.usefulwidget import getlineedit
from gui.dialog_savedgame import getreflist, getalistname
from myutils.wrapper import Singleton_close
from myutils.wrapper import Singleton_close, threader
from gui.dynalang import LPushButton
@ -120,13 +120,41 @@ class bgmsettings(QDialog):
def __getalistname(self, callback, _):
getalistname(self, callback)
infosig = pyqtSignal(str)
@threader
def checkvalid(self, k):
t = time.time()
self.tm = t
self._ref.config["access-token"] = k
headers = {
"accept": "application/json",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
}
headers["Authorization"] = "Bearer " + k
response = requests.get(f"https://api.bgm.tv/v0/me", headers=headers)
description = response.json().get("description", None)
if t != self.tm:
return
if description:
self.setWindowTitle(self._ref.config_all["name"] + " " + description)
else:
self.setWindowTitle(self._ref.config_all["name"])
def __init__(self, parent, _ref: common, gameuid: str) -> None:
super().__init__(parent, Qt.WindowType.WindowCloseButtonHint)
self.tm = None
self._ref = _ref
self.resize(QSize(800, 10))
self.setWindowTitle(self._ref.config_all["name"])
fl = QFormLayout(self)
fl.addRow("access-token", getlineedit(_ref.config, "access-token"))
s = QLineEdit()
s.textChanged.connect(self.checkvalid)
s.setText(_ref.config["access-token"])
fl.addRow("access-token", s)
btn = LPushButton("上传游戏")
btn.clicked.connect(
functools.partial(self.singleupload_existsoverride, gameuid)

View File

@ -6,7 +6,7 @@ from myutils.commonbase import ArgsEmptyExc
from myutils.hwnd import screenshot
from myutils.utils import stringfyerror
from traceback import print_exc
import threading
import threading, gobject
def qimage2binary(qimage: QImage, fmt="BMP"):
@ -54,6 +54,7 @@ def imageCut(hwnd, x1, y1, x2, y2) -> QImage:
pix = screenshot(x1, y1, x2, y2)
image = pix.toImage()
gobject.baseobject.maybesetimage(image)
return image

View File

@ -835,3 +835,20 @@ class loopbackrecorder:
with open(file, "wb") as ff:
ff.write(mp3)
callback(file)
def copytree(src, dst, copy_function=shutil.copy2):
names = os.listdir(src)
os.makedirs(dst, exist_ok=True)
for name in names:
srcname = os.path.join(src, name)
dstname = os.path.join(dst, name)
try:
if os.path.isdir(srcname):
copytree(srcname, dstname, copy_function)
else:
copy_function(srcname, dstname)
except:
pass

View File

@ -11,11 +11,13 @@ from myutils.config import (
findgameuidofpath,
)
from textsource.textsourcebase import basetext
from myutils.utils import checkchaos, getfilemd5, getlangtgt, getlanguagespace
from myutils.utils import checkchaos, getfilemd5, getlangtgt, getlanguagespace, copytree
from myutils.hwnd import injectdll, test_injectable, ListProcess, getpidexe
from myutils.wrapper import threader
from traceback import print_exc
import subprocess
import subprocess, hashlib, requests, zipfile, shutil
from myutils.proxy import getproxy
from ctypes import (
CDLL,
@ -40,6 +42,7 @@ from gui.usefulwidget import getQMessageBox
MAX_MODULE_SIZE = 120
HOOK_NAME_SIZE = 60
HOOKCODE_LEN = 500
oncecheckversion = True
class ThreadParam(Structure):
@ -125,7 +128,95 @@ class texthook(basetext):
return __shitdict(savehook_new_data[self.gameuid]["hooksetting_private"])
def tryqueryfromhost(self):
for i, main_server in enumerate(static_data["main_server"]):
try:
res = requests.get(
"{main_server}/version_lunahook".format(main_server=main_server),
verify=False,
proxies=getproxy(("update", "lunatranslator")),
)
res = res.json()
return res
except:
pass
@threader
def checkversion(self):
if not globalconfig["autoupdate"]:
return
dlls = ["LunaHook32.dll", "LunaHook64.dll", "LunaHost32.dll", "LunaHost64.dll"]
sha256 = {}
for dll in dlls:
f = os.path.join("files/plugins/LunaHook", dll)
with open(f, "rb") as ff:
bs = ff.read()
sha = hashlib.sha256(bs).hexdigest()
sha256[dll] = sha
res = self.tryqueryfromhost()
if not res:
return
isnew = True
for _, sha in res["sha256"].items():
if sha256[_] != sha:
isnew = False
break
if isnew:
return
url = res["download"]
savep = gobject.getcachedir("update/LunaHook.zip")
if url.startswith("https://github.com"):
__x = "github"
else:
__x = "lunatranslator"
data = requests.get(
url, verify=False, proxies=getproxy(("update", __x))
).content
with open(savep, "wb") as ff:
ff.write(data)
tgt = gobject.getcachedir("update/LunaHook")
with zipfile.ZipFile(savep) as zipf:
zipf.extractall(tgt)
if os.path.exists(os.path.join(tgt, "Release_English", "LunaHook32.dll")):
shutil.move(os.path.join(tgt, "Release_English"), "files/plugins/LunaHook")
else:
shutil.move(tgt, "files/plugins/LunaHook")
def init(self):
self.pids = []
self.keepref = []
self.hookdatacollecter = OrderedDict()
self.reverse = {}
self.forward = []
self.selectinghook = None
self.selectedhook = []
self.selectedhookidx = []
self.multiselectedcollector = []
self.multiselectedcollectorlock = threading.Lock()
self.lastflushtime = 0
self.runonce_line = ""
gobject.baseobject.autoswitchgameuid = False
self.delaycollectallselectedoutput()
self.autohookmonitorthread()
self.initdllonce = True
self.initdlllock = threading.Lock()
global oncecheckversion
if oncecheckversion:
oncecheckversion = False
self.checkversion()
def delayinit(self):
with self.initdlllock:
if not self.initdllonce:
return
self.initdllonce = False
self.__delayinit()
def __delayinit(self):
LunaHost = CDLL(
gobject.GetDllpath(
("LunaHost32.dll", "LunaHost64.dll"),
@ -188,23 +279,19 @@ class texthook(basetext):
self.Luna_QueryThreadHistory = LunaHost.Luna_QueryThreadHistory
self.Luna_QueryThreadHistory.argtypes = (ThreadParam,)
self.Luna_QueryThreadHistory.restype = c_void_p
self.pids = []
self.keepref = []
self.hookdatacollecter = OrderedDict()
self.reverse = {}
self.forward = []
self.selectinghook = None
self.selectedhook = []
self.selectedhookidx = []
self.multiselectedcollector = []
self.multiselectedcollectorlock = threading.Lock()
self.lastflushtime = 0
self.runonce_line = ""
gobject.baseobject.autoswitchgameuid = False
self.delaycollectallselectedoutput()
self.prepares()
self.autohookmonitorthread()
procs = [
ProcessEvent(self.onprocconnect),
ProcessEvent(self.removeproc),
ThreadEvent(self.onnewhook),
ThreadEvent(self.onremovehook),
OutputCallback(self.handle_output),
ConsoleHandler(gobject.baseobject.hookselectdialog.sysmessagesignal.emit),
HookInsertHandler(self.newhookinsert),
EmbedCallback(self.getembedtext),
]
self.keepref += procs
ptrs = [cast(_, c_void_p).value for _ in procs]
self.Luna_Start(*ptrs)
def listprocessm(self):
cachefname = gobject.gettempdir("{}.txt".format(time.time()))
@ -280,6 +367,7 @@ class texthook(basetext):
time.sleep(0.1)
def start(self, hwnd, pids, gamepath, gameuid, autostart=False):
self.delayinit()
gobject.baseobject.hwnd = hwnd
gobject.baseobject.gameuid = gameuid
self.gameuid = gameuid
@ -329,23 +417,7 @@ class texthook(basetext):
if len(self.pids) == 0:
self.autohookmonitorthread()
def prepares(self):
procs = [
ProcessEvent(self.onprocconnect),
ProcessEvent(self.removeproc),
ThreadEvent(self.onnewhook),
ThreadEvent(self.onremovehook),
OutputCallback(self.handle_output),
ConsoleHandler(gobject.baseobject.hookselectdialog.sysmessagesignal.emit),
HookInsertHandler(self.newhookinsert),
EmbedCallback(self.getembedtext),
]
self.keepref += procs
ptrs = [cast(_, c_void_p).value for _ in procs]
self.Luna_Start(*ptrs)
def start_unsafe(self, pids):
caninject = test_injectable(pids)
injectpids = []
for pid in pids:

View File

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