From 84e9220e89196983263b7d54d693183b4c7e530e Mon Sep 17 00:00:00 2001 From: HIllya51 <1173718158@qq.com> Date: Tue, 25 Feb 2025 08:15:30 +0800 Subject: [PATCH] . --- src/LunaTranslator/LunaTranslator_main.py | 14 +- .../gui/dialog_savedgame_common.py | 2 +- src/LunaTranslator/gui/dialog_savedgame_v3.py | 2 + src/LunaTranslator/gui/selecthook.py | 8 - src/LunaTranslator/gui/setting.py | 15 +- src/LunaTranslator/gui/setting_about.py | 20 +- src/LunaTranslator/gui/usefulwidget.py | 4 +- src/LunaTranslator/ocrengines/local.py | 200 ++++++++++++------ src/LunaTranslator/requests.py | 22 +- src/LunaTranslator/translator/kingsoft.py | 2 +- src/cpp/LunaHook/LunaHook/CMakeLists.txt | 3 +- .../LunaHook/LunaHook/engine32/SmartAdv.cpp | 28 +++ src/cpp/LunaHook/LunaHook/engine32/SmartAdv.h | 49 +++++ .../LunaHook/LunaHook/enginecollection32.cpp | 4 +- src/cpp/LunaHook/LunaHook/util/util.cc | 9 +- src/cpp/LunaHook/LunaHook/util/util.h | 2 +- src/cpp/common.hpp | 5 +- .../shareddllproxy/voiceroid2/api_settings.cc | 2 +- src/cpp/version.cmake | 4 +- .../LoopbackCapture.cpp | 2 +- .../LoopbackCapture.h | 79 +------ .../applicationloopbackaudio/runer.cpp | 1 + src/cpp/winsharedutils/mshtml/MWebBrowser.cpp | 4 +- src/files/lang/ar.json | 4 +- src/files/lang/cht.json | 4 +- src/files/lang/cs.json | 4 +- src/files/lang/de.json | 4 +- src/files/lang/en.json | 4 +- src/files/lang/es.json | 4 +- src/files/lang/fr.json | 4 +- src/files/lang/it.json | 4 +- src/files/lang/ja.json | 4 +- src/files/lang/ko.json | 4 +- src/files/lang/nl.json | 4 +- src/files/lang/pl.json | 4 +- src/files/lang/pt.json | 4 +- src/files/lang/ru.json | 4 +- src/files/lang/sv.json | 4 +- src/files/lang/th.json | 4 +- src/files/lang/tr.json | 4 +- src/files/lang/uk.json | 4 +- src/files/lang/vi.json | 4 +- src/files/lang/zh.json | 4 +- 43 files changed, 353 insertions(+), 208 deletions(-) create mode 100644 src/cpp/LunaHook/LunaHook/engine32/SmartAdv.cpp create mode 100644 src/cpp/LunaHook/LunaHook/engine32/SmartAdv.h diff --git a/src/LunaTranslator/LunaTranslator_main.py b/src/LunaTranslator/LunaTranslator_main.py index ff98ac37804..f80fa3b1142 100644 --- a/src/LunaTranslator/LunaTranslator_main.py +++ b/src/LunaTranslator/LunaTranslator_main.py @@ -15,6 +15,16 @@ def dopathexists(file: str): originstartfile = os.startfile +originisdir = os.path.isdir +originisfile = os.path.isfile + + +def doisdir(file: str): + return dopathexists(file) and originisdir(file) + + +def doisfile(file: str): + return dopathexists(file) and originisfile(file) def safestartfile(f): @@ -33,8 +43,10 @@ def safestartfile(f): def overridepathexists(): # win7上,如果假如没有D盘,然后os.path.exists("D:/..."),就会弹窗说不存在D盘 + # 对于不存在的UNC路径,会先进行网络探测,达到timeout才会返回,导致非常卡顿 os.path.exists = dopathexists - + os.path.isdir = doisdir + os.path.isfile = doisfile os.startfile = safestartfile diff --git a/src/LunaTranslator/gui/dialog_savedgame_common.py b/src/LunaTranslator/gui/dialog_savedgame_common.py index 4bcd990cdb3..6c581533ddc 100644 --- a/src/LunaTranslator/gui/dialog_savedgame_common.py +++ b/src/LunaTranslator/gui/dialog_savedgame_common.py @@ -104,7 +104,7 @@ def __init__(self, tag, removeable=True, _type=TYPE_SEARCH, refdata=None) -> Non def opendirforgameuid(gameuid): f = get_launchpath(gameuid) f = os.path.dirname(f) - if os.path.exists(f) and os.path.isdir(f): + if os.path.isdir(f): os.startfile(f) diff --git a/src/LunaTranslator/gui/dialog_savedgame_v3.py b/src/LunaTranslator/gui/dialog_savedgame_v3.py index 1ee7f92a997..4675ed72df7 100644 --- a/src/LunaTranslator/gui/dialog_savedgame_v3.py +++ b/src/LunaTranslator/gui/dialog_savedgame_v3.py @@ -483,6 +483,8 @@ def changepixmappath(self, path): self.centerwidget.setVisible(False) self.pathview.setText(path) try: + if not os.path.isfile(extradatas["localedpath"].get(path, path)): + raise Exception() timestamp = get_time_stamp( ct=os.path.getctime(extradatas["localedpath"].get(path, path)), ms=False ) diff --git a/src/LunaTranslator/gui/selecthook.py b/src/LunaTranslator/gui/selecthook.py index c8d85511e61..c798ce0d3ba 100644 --- a/src/LunaTranslator/gui/selecthook.py +++ b/src/LunaTranslator/gui/selecthook.py @@ -420,14 +420,7 @@ class hookselect(closeashidewindow): removehooksignal = pyqtSignal(tuple) getfoundhooksignal = pyqtSignal(dict) update_item_new_line = pyqtSignal(tuple, str) - SaveTextThreadRole = Qt.ItemDataRole.UserRole + 1 - procchanged = pyqtSignal() - - def _procchanged(self): - if self.searchhookparam: - self.searchhookparam.deleteLater() - self.searchhookparam = None def __init__(self, parent): super(hookselect, self).__init__(parent, globalconfig["selecthookgeo"]) @@ -435,7 +428,6 @@ def __init__(self, parent): self.hidesearchhookbuttons() self.firsttimex = True self.searchhookparam = None - self.procchanged.connect(self._procchanged) self.removehooksignal.connect(self.removehook) self.addnewhooksignal.connect(self.addnewhook) self.getnewsentencesignal.connect(self.getnewsentence) diff --git a/src/LunaTranslator/gui/setting.py b/src/LunaTranslator/gui/setting.py index 0589112ae54..91582274a80 100644 --- a/src/LunaTranslator/gui/setting.py +++ b/src/LunaTranslator/gui/setting.py @@ -28,7 +28,9 @@ def adjust_list_widget_width(self): max_width = 0 for i in range(list_widget.count()): item = list_widget.item(i) - width = font_metrics.size(0, item.text() + item.text()[0] + item.text()[-1]).width() + width = font_metrics.size( + 0, item.text() + item.text()[0] + item.text()[-1] + ).width() max_width = max(max_width, width) item.setSizeHint(QSize(0, int(font_metrics.ascent() * 2))) list_widget.setFixedWidth(max_width) @@ -77,13 +79,24 @@ class Setting(closeashidewindow): voicelistsignal = pyqtSignal(object) versiontextsignal = pyqtSignal(str) progresssignal2 = pyqtSignal(str, int) + progresssignal4 = pyqtSignal(str, int) progresssignal3 = pyqtSignal(int) showandsolvesig = pyqtSignal(str, str) + def _progresssignal4(self, text, val): + try: + self.downloadprogress.setValue(val) + self.downloadprogress.setFormat(text) + if val or text: + self.downloadprogress.setVisible(True) + except: + self.downloadprogress_cache = text, val + def __init__(self, parent): super(Setting, self).__init__(parent, globalconfig["setting_geo_2"]) self.setWindowIcon(qtawesome.icon("fa.gear")) + self.progresssignal4.connect(self._progresssignal4) self.showandsolvesig.connect(functools.partial(delaysetcomparetext, self)) self.voicelistsignal.connect(functools.partial(showvoicelist, self)) self.versiontextsignal.connect( diff --git a/src/LunaTranslator/gui/setting_about.py b/src/LunaTranslator/gui/setting_about.py index c84f7727746..e01a4716aa4 100644 --- a/src/LunaTranslator/gui/setting_about.py +++ b/src/LunaTranslator/gui/setting_about.py @@ -113,6 +113,8 @@ def updatemethod(urls, self): ) savep = gobject.getcachedir("update/" + url.split("/")[-1]) + if not savep.endswith(".zip"): + savep += ".zip" if url.startswith("https://github.com"): __x = "github" else: @@ -132,7 +134,7 @@ def updatemethod(urls, self): proxies=getproxy(("update", __x)), ) file_size = 0 - for i in r.iter_content(chunk_size=1024): + for i in r.iter_content(chunk_size=1024 * 32): if check_interrupt(): return if not i: @@ -144,7 +146,7 @@ def updatemethod(urls, self): prg = int(10000 * file_size / size) prg100 = prg / 100 sz = int(1000 * (int(size / 1024) / 1024)) / 1000 - self.downloadprogress_cache = ( + self.progresssignal4.emit( _TR("总大小_{} MB _进度_{:0.2f}%").format(sz, prg100), prg, ) @@ -156,7 +158,7 @@ def updatemethod(urls, self): def uncompress(self, savep): - self.downloadprogress_cache = (_TR("正在解压"), 10000) + self.progresssignal4.emit(_TR("正在解压"), 10000) shutil.rmtree(gobject.getcachedir("update/LunaTranslator/")) with zipfile.ZipFile(savep) as zipf: zipf.extractall(gobject.getcachedir("update")) @@ -168,7 +170,7 @@ def versioncheckthread(self): while True: x = versionchecktask.get() gobject.baseobject.update_avalable = False - self.downloadprogress_cache = ("", 0) + self.progresssignal4.emit("", 0) if not x: continue self.versiontextsignal.emit("获取中") # ,'',url,url)) @@ -189,10 +191,10 @@ def versioncheckthread(self): ) if not (need and globalconfig["autoupdate"]): continue - self.downloadprogress_cache = ("……", 0) + self.progresssignal4.emit("……", 0) savep = updatemethod(_version[1:], self) if not savep: - self.downloadprogress_cache = (_TR("自动更新失败,请手动更新"), 0) + self.progresssignal4.emit(_TR("自动更新失败,请手动更新"), 0) continue uncompress(self, savep) @@ -205,7 +207,7 @@ def versioncheckthread(self): def createdownloadprogress(self): - self.downloadprogress = QProgressBar() + self.downloadprogress = QProgressBar(self) self.downloadprogress.setRange(0, 10000) self.downloadprogress.setVisible(False) @@ -223,9 +225,7 @@ def __cb(self): if val or text: self.downloadprogress.setVisible(True) - self.downloadprogresstimer = QTimer(self.downloadprogress) - self.downloadprogresstimer.timeout.connect(functools.partial(__cb, self)) - self.downloadprogresstimer.start(100) + __cb(self) return self.downloadprogress diff --git a/src/LunaTranslator/gui/usefulwidget.py b/src/LunaTranslator/gui/usefulwidget.py index c75d08a05f1..9ac92bea5c9 100644 --- a/src/LunaTranslator/gui/usefulwidget.py +++ b/src/LunaTranslator/gui/usefulwidget.py @@ -1323,11 +1323,11 @@ def Addext(self, *_): edges = os.path.join( os.environ["LOCALAPPDATA"], r"Microsoft\Edge\User Data\Default\Extensions" ) - if os.path.exists(edges): + if os.path.isdir(edges): edgeslen = len(os.listdir(edges)) else: edgeslen = 0 - if os.path.exists(chromes): + if os.path.isdir(chromes): chromelen = len(os.listdir(chromes)) else: chromelen = 0 diff --git a/src/LunaTranslator/ocrengines/local.py b/src/LunaTranslator/ocrengines/local.py index 459c35e3dcd..5f5990aaddc 100644 --- a/src/LunaTranslator/ocrengines/local.py +++ b/src/LunaTranslator/ocrengines/local.py @@ -1,5 +1,5 @@ import os, zipfile -from myutils.utils import dynamiclink +from myutils.utils import dynamiclink, stringfyerror from myutils.config import _TR, getlang_inner2show, globalconfig from ocrengines.baseocrclass import baseocr from ctypes import ( @@ -15,11 +15,14 @@ ) import os from language import Languages -import gobject, functools +import gobject, requests, uuid from traceback import print_exc from qtsymbols import * +from myutils.wrapper import threader +from myutils.proxy import getproxy from gui.usefulwidget import SuperCombo, getboxlayout -from gui.dynalang import LPushButton, LFormLayout, LLabel +from gui.dynalang import LPushButton, LLabel +from gui.usefulwidget import VisLFormLayout class ocrpoints(Structure): @@ -92,9 +95,9 @@ def __del__(self): def findmodel(langcode): check = lambda path: ( - os.path.exists(path + "/det.onnx") - and os.path.exists(path + "/rec.onnx") - and os.path.exists(path + "/dict.txt") + os.path.isfile(path + "/det.onnx") + and os.path.isfile(path + "/rec.onnx") + and os.path.isfile(path + "/dict.txt") ) for path in [ "./files/ocrmodel/{}".format(langcode), @@ -107,54 +110,21 @@ def findmodel(langcode): def getallsupports(): validlangs = [] for d in ["./files/ocrmodel", "cache/ocrmodel"]: - if os.path.exists(d): + if os.path.isdir(d): for lang in os.listdir(d): if findmodel(lang): validlangs.append(lang) return validlangs -def dodownload(combo: QComboBox, allsupports: list): - if not allsupports: - return - lang = allsupports[combo.currentIndex()] - os.startfile( - dynamiclink("{main_server}") + "/Resource/ocr_models/{}.zip".format(lang) - ) +class question(QWidget): + installsucc = pyqtSignal(bool, str) + + def loadcombo(self): -def doinstall(self, allsupports: list, parent, callback): - if not allsupports: - return - f = QFileDialog.getOpenFileName( - parent, - filter="model ({})".format(" ".join(["{}.zip".format(_) for _ in allsupports])), - ) - fn = f[0] - if not fn: - return - try: - with zipfile.ZipFile(fn) as zipf: - zipf.extractall("cache/ocrmodel") - QMessageBox.information(self, _TR("成功"), _TR("添加成功")) - callback() - except: - print_exc() - - -def question(): - dialog = QWidget() - formLayout = LFormLayout(dialog) - formLayout.setContentsMargins(0, 0, 0, 0) - supportlang = LLabel() - supportlang.setWordWrap(True) - formLayout.addRow("当前支持的语言", supportlang) - combo = SuperCombo() - allsupports = [] - - def callback(): langs = getallsupports() - supportlang.setText("_,_".join([getlang_inner2show(f) for f in langs])) + self.supportlang.setText("_,_".join([getlang_inner2show(f) for f in langs])) _allsupports = [ Languages.Japanese, Languages.English, @@ -165,26 +135,130 @@ def callback(): Languages.Arabic, Languages.Ukrainian, ] - allsupports.clear() + self.allsupports.clear() for l in _allsupports: if l not in langs: - allsupports.append(l) - vis = [getlang_inner2show(f) for f in allsupports] - combo.clear() - combo.addItems(vis) - - callback() - btndownload = LPushButton("下载") - btndownload.clicked.connect(functools.partial(dodownload, combo, allsupports)) - btninstall = LPushButton("添加") - btninstall.clicked.connect( - functools.partial(doinstall, combo, allsupports, dialog, callback) - ) - formLayout.addRow( - "添加语言包", - getboxlayout([combo, btndownload, btninstall], makewidget=True, margin0=True), - ) - return dialog + self.allsupports.append(l) + vis = [getlang_inner2show(f) for f in self.allsupports] + self.combo.clear() + self.combo.addItems(vis) + if not self.allsupports: + self.btninstall.setEnabled(False) + + @property + def cururl(self): + if not self.allsupports: + return + lang = self.allsupports[self.combo.currentIndex()] + return dynamiclink("{main_server}") + "/Resource/ocr_models/{}.zip".format(lang) + + def downloadauto(self): + if not self.cururl: + return + self.downloadxSafe(self.cururl) + self.formLayout.setRowVisible(self.row, True) + self.lineX.setEnabled(False) + + progresssetval = pyqtSignal(str, int) + + @threader + def downloadxSafe(self, url): + try: + self.downloadx(url) + self.installsucc.emit(True, "") + except Exception as e: + self.installsucc.emit(False, stringfyerror(e)) + + def downloadx(self, url): + + self.progresssetval.emit("……", 0) + req = requests.head(url, verify=False, proxies=getproxy()) + size = int(req.headers["Content-Length"]) + file_size = 0 + req = requests.get(url, verify=False, proxies=getproxy(), stream=True) + target = gobject.getcachedir("ocrmodel/" + self.cururl.split("/")[-1]) + with open(target, "wb") as ff: + for _ in req.iter_content(chunk_size=1024 * 32): + ff.write(_) + file_size += len(_) + prg = int(10000 * file_size / size) + prg100 = prg / 100 + sz = int(1000 * (int(size / 1024) / 1024)) / 1000 + self.progresssetval.emit( + _TR("总大小_{} MB _进度_{:0.2f}%").format(sz, prg100), + prg, + ) + self.progresssetval.emit(_TR("正在解压"), 10000) + with zipfile.ZipFile(target) as zipf: + zipf.extractall("cache/ocrmodel") + + def _installsucc(self, succ, failreason): + if succ: + self.progresssetval.emit(_TR("添加成功"), 10000) + QMessageBox.information(self, _TR("成功"), _TR("添加成功")) + else: + self.progresssetval.emit(_TR("添加失败"), 0) + res = QMessageBox.question( + self, + _TR("错误"), + failreason + "\n\n" + _TR("自动添加失败,是否手动添加?"), + ) + if res == QMessageBox.StandardButton.Yes: + self.formLayout.setRowVisible(self.row, False) + os.startfile(self.cururl) + f = QFileDialog.getOpenFileName( + self, + filter=self.cururl.split("/")[-1], + ) + fn = f[0] + if fn: + try: + with zipfile.ZipFile(fn) as zipf: + zipf.extractall("cache/ocrmodel") + QMessageBox.information(self, _TR("成功"), _TR("添加成功")) + except: + QMessageBox.information(self, _TR("错误"), _TR("添加失败")) + print_exc() + self.loadcombo() + self.formLayout.setRowVisible(self.row, False) + self.lineX.setEnabled(True) + + def progresssetval_(self, text, val): + self.downloadprogress.setValue(val) + self.downloadprogress.setFormat(text) + + def __init__(self, *argc, **kw): + super().__init__(*argc, **kw) + self.installsucc.connect(self._installsucc) + self.progresssetval.connect(self.progresssetval_) + formLayout = VisLFormLayout(self) + formLayout.setContentsMargins(0, 0, 0, 0) + self.supportlang = LLabel() + self.supportlang.setWordWrap(True) + formLayout.addRow("当前支持的语言", self.supportlang) + self.combo = SuperCombo() + self.allsupports = [] + + btninstall = LPushButton("添加") + btninstall.clicked.connect(self.downloadauto) + self.btninstall = btninstall + self.loadcombo() + self.lineX = getboxlayout( + [self.combo, btninstall], makewidget=True, margin0=True + ) + formLayout.addRow("添加语言包", self.lineX) + + downloadprogress = QProgressBar() + + downloadprogress.setRange(0, 10000) + downloadprogress.setAlignment( + Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter + ) + formLayout.addRow(downloadprogress) + self.downloadprogress = downloadprogress + self.row = formLayout.rowCount() - 1 + formLayout.setRowVisible(self.row, False) + self.formLayout = formLayout class OCR(baseocr): diff --git a/src/LunaTranslator/requests.py b/src/LunaTranslator/requests.py index 42fad4242e9..0c7c9cac9e0 100644 --- a/src/LunaTranslator/requests.py +++ b/src/LunaTranslator/requests.py @@ -67,6 +67,10 @@ def __repr__(self): return str(dict(self.items())) +CONTENT_CHUNK_SIZE = 10 * 1024 +ITER_CHUNK_SIZE = 512 + + class Response: def __init__(self, stream): self.headers = CaseInsensitiveDict() @@ -76,18 +80,16 @@ def __init__(self, stream): self.status_code = 0 self.reason = "" self.__content = b"" - self.__content_s = [] - self.content_prepared = threading.Event() self.iter_once = True + self.stream_X = False @property def content(self): if self.stream: - if self.iter_once: - for _ in self.iter_content(): - pass - self.content_prepared.wait() - return b"".join(self.__content_s) + if not self.stream_X: + self.__content = b"".join(self.iter_content(CONTENT_CHUNK_SIZE)) + self.stream_X = True + return self.__content else: return self.__content @@ -135,9 +137,7 @@ def iter_content(self, chunk_size=1, decode_unicode=False): def __generate(): for chunk in self.iter_content_impl(chunk_size): - self.__content_s.append(chunk) yield chunk - self.content_prepared.set() stream_chunks = __generate() @@ -151,7 +151,9 @@ def __generate(): def iter_content_impl(self, chunk_size=1): pass - def iter_lines(self, chunk_size=512, decode_unicode=False, delimiter=None): + def iter_lines( + self, chunk_size=ITER_CHUNK_SIZE, decode_unicode=False, delimiter=None + ): pending = None size = 0 for chunk in self.iter_content( diff --git a/src/LunaTranslator/translator/kingsoft.py b/src/LunaTranslator/translator/kingsoft.py index cd7da683a6e..66804d34760 100644 --- a/src/LunaTranslator/translator/kingsoft.py +++ b/src/LunaTranslator/translator/kingsoft.py @@ -20,7 +20,7 @@ def checkpath(self): base = os.path.abspath( os.path.join(self.config["path"], "GTS/" + self.srclang + self.tgtlang) ) - if os.path.exists(base) == False: + if not os.path.isdir(base): return False dll = None for f in os.listdir(base): diff --git a/src/cpp/LunaHook/LunaHook/CMakeLists.txt b/src/cpp/LunaHook/LunaHook/CMakeLists.txt index 04044d408e3..e5c3e893e10 100644 --- a/src/cpp/LunaHook/LunaHook/CMakeLists.txt +++ b/src/cpp/LunaHook/LunaHook/CMakeLists.txt @@ -23,7 +23,8 @@ else() Syuntada Pensil Anim hibiki Nitroplus Reallive Siglus Taskforce2 RUGP IronGameSystem Anex86 ShinyDaysGame MarineHeart ShinaRio CaramelBox UnisonShift Escude Ryokucha Alice Footy2 utawarerumono System4x Abalone Abel 5pb HorkEye XUSE Leaf Nekopack AXL AGS AdobeFlash10 - FocasLens Tamamo Ages3ResT H_do_C RScript TYPEMOON TAKUYO MixwillSoft MerRouge GROOVER) + FocasLens Tamamo Ages3ResT H_do_C RScript TYPEMOON TAKUYO MixwillSoft MerRouge GROOVER + SmartAdv) set(enginepath "engine32") set(collector "enginecollection32.cpp") endif() diff --git a/src/cpp/LunaHook/LunaHook/engine32/SmartAdv.cpp b/src/cpp/LunaHook/LunaHook/engine32/SmartAdv.cpp new file mode 100644 index 00000000000..c715a80efd3 --- /dev/null +++ b/src/cpp/LunaHook/LunaHook/engine32/SmartAdv.cpp @@ -0,0 +1,28 @@ +#include "SmartAdv.h" +// https://vndb.org/r6347 +// VALENTINE PINK~パーフェクトエディション~ + +bool SmartAdv::attach_function() +{ /* +int __stdcall sub_100122D0(_DWORD *a1, int a2, int a3, int *a4, int a5) + +ms_exc.registration.Next = (struct _EH3_EXCEPTION_REGISTRATION *)a2; +*/ + auto [s, e] = Util::QueryModuleLimits(GetModuleHandle(L"video.dll")); + auto addr = findiatcallormov((DWORD)CreateFontIndirectA, (DWORD)GetModuleHandle(L"video.dll"), s, e); + if (!addr) + return false; + addr = MemDbg::findEnclosingAlignedFunction(addr); + if (!addr) + return false; + HookParam hp; + hp.address = addr; + hp.type = USING_STRING | EMBED_ABLE | EMBED_DYNA_SJIS | EMBED_AFTER_NEW; + hp.embed_hook_font = F_ExtTextOutA; + hp.offset = stackoffset(2); + hp.filter_fun = [](TextBuffer *buffer, HookParam *hp) + { + CharFilter(buffer, '\n'); + }; + return NewHook(hp, "SmartAdv"); +} \ No newline at end of file diff --git a/src/cpp/LunaHook/LunaHook/engine32/SmartAdv.h b/src/cpp/LunaHook/LunaHook/engine32/SmartAdv.h new file mode 100644 index 00000000000..554430ae51a --- /dev/null +++ b/src/cpp/LunaHook/LunaHook/engine32/SmartAdv.h @@ -0,0 +1,49 @@ +/* +smartadv.dll-> + BLOCK "StringFileInfo" + { + BLOCK "041103a4" + { + VALUE "CompanyName", "F&C Co.,Ltd." + VALUE "FileDescription", "Scenario Script Engine "SmartAdv"" + VALUE "FileVersion", "1.0.0.639" + VALUE "InternalName", "Scenario Script Engine" + VALUE "LegalCopyright", "Copyright (C) 2005-2007 F&C Co.,Ltd." + VALUE "ProductName", "SmartAdv" + } + } +*/ +/* +EXE-> +BLOCK "StringFileInfo" + { + BLOCK "041103a4" + { + VALUE "CompanyName", "F&C Co.,Ltd." + VALUE "FileDescription", "Advanced System "Overture"" + VALUE "FileVersion", "0.0.0.2001" + VALUE "InternalName", "NS-00 (Code: Zero-System)" + VALUE "LegalCopyright", "Copyright (C) 2005-2007 F&C Co.,Ltd." + VALUE "ProductName", "Overture" + } + } + +*/ +class SmartAdv : public ENGINE +{ +public: + SmartAdv() + { + check_by = CHECK_BY::CUSTOM; + check_by_target = []() + { + auto smartadv = GetModuleHandle(L"smartadv.dll"); + auto video = GetModuleHandle(L"video.dll"); + auto NSL = GetModuleHandle(L"NSL.dll"); + if (!smartadv || !video || !NSL) + return false; + return Util::SearchResourceString(L"Scenario Script Engine", smartadv); + }; + }; + bool attach_function(); +}; \ No newline at end of file diff --git a/src/cpp/LunaHook/LunaHook/enginecollection32.cpp b/src/cpp/LunaHook/LunaHook/enginecollection32.cpp index 412a73954d6..e84b7945bff 100644 --- a/src/cpp/LunaHook/LunaHook/enginecollection32.cpp +++ b/src/cpp/LunaHook/LunaHook/enginecollection32.cpp @@ -88,6 +88,7 @@ #include "engine32/AdobeAir.h" #include "engine32/DISCOVERY.h" #include "engine32/Retouch.h" +#include "engine32/SmartAdv.h" #include "engine32/Malie.h" #include "engine32/Live.h" #include "engine32/Jellyfish.h" @@ -442,5 +443,6 @@ std::vector check_engines() new TAKUYO, new MixwillSoft, new MerRouge, - new GROOVER}; + new GROOVER, + new SmartAdv}; } \ No newline at end of file diff --git a/src/cpp/LunaHook/LunaHook/util/util.cc b/src/cpp/LunaHook/LunaHook/util/util.cc index 04a41dbdba3..af53e457f0a 100644 --- a/src/cpp/LunaHook/LunaHook/util/util.cc +++ b/src/cpp/LunaHook/LunaHook/util/util.cc @@ -284,22 +284,23 @@ namespace Util } // Search string in rsrc section. This section usually contains version and copyright info. - bool SearchResourceString(LPCWSTR str) + bool SearchResourceString(LPCWSTR str, HMODULE hModule) { - uintptr_t hModule = (uintptr_t)GetModuleHandleW(nullptr); + if (!hModule) + hModule = GetModuleHandleW(nullptr); IMAGE_DOS_HEADER *DosHdr; IMAGE_NT_HEADERS *NtHdr; DosHdr = (IMAGE_DOS_HEADER *)hModule; uintptr_t rsrc, size; if (IMAGE_DOS_SIGNATURE == DosHdr->e_magic) { - NtHdr = (IMAGE_NT_HEADERS *)(hModule + DosHdr->e_lfanew); + NtHdr = (IMAGE_NT_HEADERS *)((uintptr_t)hModule + DosHdr->e_lfanew); if (IMAGE_NT_SIGNATURE == NtHdr->Signature) { rsrc = NtHdr->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress; if (rsrc) { - rsrc += hModule; + rsrc += (uintptr_t)hModule; if (IthGetMemoryRange((LPVOID)rsrc, &rsrc, &size) && SearchPattern(rsrc, size - 4, str, wcslen(str) << 1)) return true; diff --git a/src/cpp/LunaHook/LunaHook/util/util.h b/src/cpp/LunaHook/LunaHook/util/util.h index ed080999b8d..35c5196e3ae 100644 --- a/src/cpp/LunaHook/LunaHook/util/util.h +++ b/src/cpp/LunaHook/LunaHook/util/util.h @@ -43,7 +43,7 @@ namespace Util bool CheckFile_exits(LPCWSTR name, bool if_exits_also_ok); bool CheckFile(LPCWSTR name); - bool SearchResourceString(LPCWSTR str); + bool SearchResourceString(LPCWSTR str, HMODULE hModule=NULL); std::pair QueryModuleLimits(HMODULE module, uintptr_t addition = 0x1000, DWORD protect = PAGE_EXECUTE); std::vector SearchMemory(const void *bytes, short length, DWORD protect = PAGE_EXECUTE, uintptr_t minAddr = 0, uintptr_t maxAddr = -1ULL); diff --git a/src/cpp/common.hpp b/src/cpp/common.hpp index 025421f527f..08fe988b9bc 100644 --- a/src/cpp/common.hpp +++ b/src/cpp/common.hpp @@ -56,13 +56,13 @@ class ComImpl : public Bases... template void *get_interface(REFIID riid) { - if (riid == __uuidof(First)) + if (IsEqualGUID(riid, __uuidof(First))) return static_cast(this); if constexpr (sizeof...(Rest) > 0) { return get_interface(riid); } - else if (riid == __uuidof(IUnknown)) + else if (IsEqualGUID(riid, __uuidof(IUnknown))) return this; return nullptr; } @@ -98,6 +98,7 @@ class ComImpl : public Bases... AddRef(); return S_OK; } + virtual ~ComImpl() {} }; #ifdef WINXP diff --git a/src/cpp/shareddllproxy/voiceroid2/api_settings.cc b/src/cpp/shareddllproxy/voiceroid2/api_settings.cc index 13f67c9a3e1..0bfe90888a3 100644 --- a/src/cpp/shareddllproxy/voiceroid2/api_settings.cc +++ b/src/cpp/shareddllproxy/voiceroid2/api_settings.cc @@ -1,4 +1,4 @@ -#include "api_settings.h" +#include "api_settings.h" #include "ebyutil.h" namespace ebyroid diff --git a/src/cpp/version.cmake b/src/cpp/version.cmake index 0cb2b1869b9..7f6aff242ce 100644 --- a/src/cpp/version.cmake +++ b/src/cpp/version.cmake @@ -1,7 +1,7 @@ set(VERSION_MAJOR 7) -set(VERSION_MINOR 12) -set(VERSION_PATCH 4) +set(VERSION_MINOR 13) +set(VERSION_PATCH 0) set(VERSION_REVISION 0) set(LUNA_VERSION "{${VERSION_MAJOR},${VERSION_MINOR},${VERSION_PATCH},${VERSION_REVISION}}") add_library(VERSION_DEF ${CMAKE_CURRENT_LIST_DIR}/version_def.cpp) diff --git a/src/cpp/winsharedutils/applicationloopbackaudio/LoopbackCapture.cpp b/src/cpp/winsharedutils/applicationloopbackaudio/LoopbackCapture.cpp index 5735857de4a..783ad6c878b 100644 --- a/src/cpp/winsharedutils/applicationloopbackaudio/LoopbackCapture.cpp +++ b/src/cpp/winsharedutils/applicationloopbackaudio/LoopbackCapture.cpp @@ -1,4 +1,4 @@ - + #include "LoopbackCapture.h" HRESULT CLoopbackCapture::SetDeviceStateErrorIfFailed(HRESULT hr) diff --git a/src/cpp/winsharedutils/applicationloopbackaudio/LoopbackCapture.h b/src/cpp/winsharedutils/applicationloopbackaudio/LoopbackCapture.h index 12ae70e5871..ac515e22aad 100644 --- a/src/cpp/winsharedutils/applicationloopbackaudio/LoopbackCapture.h +++ b/src/cpp/winsharedutils/applicationloopbackaudio/LoopbackCapture.h @@ -1,4 +1,4 @@ -#pragma once +#pragma once #include #include @@ -8,7 +8,7 @@ #ifndef WINXP #include #else -#include"xpdef.hpp" +#include "xpdef.hpp" #endif #include "Common.h" @@ -16,83 +16,10 @@ // https://learn.microsoft.com/zh-cn/windows/uwp/cpp-and-winrt-apis/agile-objects // https://learn.microsoft.com/en-us/windows/win32/api/mmdeviceapi/nf-mmdeviceapi-activateaudiointerfaceasync -class CLoopbackCapture : public ComImpl +class CLoopbackCapture : public ComImpl { public: - // IMarshal - CComPtr marshaller_; - STDMETHOD(GetUnmarshalClass)(_In_ REFIID riid, - _In_opt_ void *pv, - _In_ DWORD dwDestContext, - _Reserved_ void *pvDestContext, - _In_ DWORD mshlflags, - _Out_ CLSID *pCid) override - { - if (marshaller_) - { - return marshaller_->GetUnmarshalClass(riid, pv, dwDestContext, pvDestContext, mshlflags, pCid); - } - return E_OUTOFMEMORY; - } - STDMETHOD(GetMarshalSizeMax)(_In_ REFIID riid, _In_opt_ void *pv, _In_ DWORD dwDestContext, - _Reserved_ void *pvDestContext, _In_ DWORD mshlflags, _Out_ DWORD *pSize) override - { - if (marshaller_) - { - return marshaller_->GetMarshalSizeMax(riid, pv, dwDestContext, pvDestContext, mshlflags, pSize); - } - return E_OUTOFMEMORY; - } - - STDMETHOD(MarshalInterface)(_In_ IStream *pStm, _In_ REFIID riid, _In_opt_ void *pv, _In_ DWORD dwDestContext, - _Reserved_ void *pvDestContext, _In_ DWORD mshlflags) override - { - if (marshaller_) - { - return marshaller_->MarshalInterface(pStm, riid, pv, dwDestContext, pvDestContext, mshlflags); - } - return E_OUTOFMEMORY; - } - STDMETHOD(UnmarshalInterface)(_In_ IStream *pStm, _In_ REFIID riid, _Outptr_ void **ppv) override - { - if (marshaller_) - { - return marshaller_->UnmarshalInterface(pStm, riid, ppv); - } - return E_OUTOFMEMORY; - } - - STDMETHOD(ReleaseMarshalData)(_In_ IStream *pStm) override - { - if (marshaller_) - { - return marshaller_->ReleaseMarshalData(pStm); - } - return E_OUTOFMEMORY; - } - - STDMETHOD(DisconnectObject)(_In_ DWORD dwReserved) override - { - if (marshaller_) - { - return marshaller_->DisconnectObject(dwReserved); - } - return E_OUTOFMEMORY; - } - - CLoopbackCapture() - { - CComPtr unknown; - if (SUCCEEDED(::CoCreateFreeThreadedMarshaler(nullptr, &unknown))) - { - unknown.QueryInterface(&marshaller_); - } - } - - // IMarshal - ~CLoopbackCapture(); - HRESULT StartCaptureAsync(DWORD processId, bool includeProcessTree); HRESULT StopCaptureAsync(); diff --git a/src/cpp/winsharedutils/applicationloopbackaudio/runer.cpp b/src/cpp/winsharedutils/applicationloopbackaudio/runer.cpp index 3f03349135a..7eab1234f7c 100644 --- a/src/cpp/winsharedutils/applicationloopbackaudio/runer.cpp +++ b/src/cpp/winsharedutils/applicationloopbackaudio/runer.cpp @@ -2,6 +2,7 @@ #include "LoopbackCapture.h" DECLARE_API HRESULT StartCaptureAsync(CLoopbackCapture **ptr) { + // 在win10及以前,不能同时启动多个(必须MFUnlockWorkQueue后才能下一个,否则m_AudioClient->Initialize会E_UNEXPECTED),win11可以同时启动多个 *ptr = nullptr; CComPtr _ = new CLoopbackCapture; if (!_) diff --git a/src/cpp/winsharedutils/mshtml/MWebBrowser.cpp b/src/cpp/winsharedutils/mshtml/MWebBrowser.cpp index ad396d318e4..c42ccafb3e9 100644 --- a/src/cpp/winsharedutils/mshtml/MWebBrowser.cpp +++ b/src/cpp/winsharedutils/mshtml/MWebBrowser.cpp @@ -742,8 +742,8 @@ STDMETHODIMP MWebBrowser::QueryService( { *ppvObject = NULL; - if (riid == __uuidof(IWindowForBindingUI) || - riid == __uuidof(IHttpSecurity)) + if (IsEqualGUID(riid, __uuidof(IWindowForBindingUI)) || + IsEqualGUID(riid, __uuidof(IHttpSecurity))) { *ppvObject = static_cast(this); } diff --git a/src/files/lang/ar.json b/src/files/lang/ar.json index 04cc7156a44..fb9121a3c34 100644 --- a/src/files/lang/ar.json +++ b/src/files/lang/ar.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/cht.json b/src/files/lang/cht.json index 8eaee677468..0488f57a673 100644 --- a/src/files/lang/cht.json +++ b/src/files/lang/cht.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/cs.json b/src/files/lang/cs.json index 2f015f84d90..70989588786 100644 --- a/src/files/lang/cs.json +++ b/src/files/lang/cs.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/de.json b/src/files/lang/de.json index 8c84808528a..2b2d59de875 100644 --- a/src/files/lang/de.json +++ b/src/files/lang/de.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/en.json b/src/files/lang/en.json index 1a4212095b4..4ee15e9b3ee 100644 --- a/src/files/lang/en.json +++ b/src/files/lang/en.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/es.json b/src/files/lang/es.json index 8bb64046b7a..44fc2e9eadb 100644 --- a/src/files/lang/es.json +++ b/src/files/lang/es.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/fr.json b/src/files/lang/fr.json index cdc906febe6..f8f3f096ff8 100644 --- a/src/files/lang/fr.json +++ b/src/files/lang/fr.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/it.json b/src/files/lang/it.json index ff4c75e5c90..2104b4e572c 100644 --- a/src/files/lang/it.json +++ b/src/files/lang/it.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/ja.json b/src/files/lang/ja.json index d4637e3a40d..8fe2aee736c 100644 --- a/src/files/lang/ja.json +++ b/src/files/lang/ja.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/ko.json b/src/files/lang/ko.json index f2b48a87486..73ca76f55d1 100644 --- a/src/files/lang/ko.json +++ b/src/files/lang/ko.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/nl.json b/src/files/lang/nl.json index a8b9687f2bd..49de7462df0 100644 --- a/src/files/lang/nl.json +++ b/src/files/lang/nl.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/pl.json b/src/files/lang/pl.json index feceec905ce..14998e00122 100644 --- a/src/files/lang/pl.json +++ b/src/files/lang/pl.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/pt.json b/src/files/lang/pt.json index b4bf20a6ba5..5a60665fe6f 100644 --- a/src/files/lang/pt.json +++ b/src/files/lang/pt.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/ru.json b/src/files/lang/ru.json index 9b553a6e00f..e7c91f8c032 100644 --- a/src/files/lang/ru.json +++ b/src/files/lang/ru.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/sv.json b/src/files/lang/sv.json index 61d3543ad17..c9132ec4a9d 100644 --- a/src/files/lang/sv.json +++ b/src/files/lang/sv.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/th.json b/src/files/lang/th.json index aec95155bf8..4df29da37f2 100644 --- a/src/files/lang/th.json +++ b/src/files/lang/th.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/tr.json b/src/files/lang/tr.json index 1a7d37da952..de91b9330a6 100644 --- a/src/files/lang/tr.json +++ b/src/files/lang/tr.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/uk.json b/src/files/lang/uk.json index a49c62ec64b..26a842ab53b 100644 --- a/src/files/lang/uk.json +++ b/src/files/lang/uk.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/vi.json b/src/files/lang/vi.json index ec16c47570f..be773bafdd8 100644 --- a/src/files/lang/vi.json +++ b/src/files/lang/vi.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file diff --git a/src/files/lang/zh.json b/src/files/lang/zh.json index 867d98c106b..6d3ae12201a 100644 --- a/src/files/lang/zh.json +++ b/src/files/lang/zh.json @@ -790,5 +790,7 @@ "行高": "", "倍": "", "地址表": "", - "使用翻译缓存": "" + "使用翻译缓存": "", + "添加失败": "", + "自动添加失败,是否手动添加?": "" } \ No newline at end of file