mirror of
https://github.com/HIllya51/LunaTranslator.git
synced 2024-12-28 08:04:13 +08:00
locale
This commit is contained in:
parent
b1159f5ede
commit
bc908638c7
@ -16,7 +16,7 @@ from myutils.config import (
|
||||
globalconfig,
|
||||
static_data,
|
||||
)
|
||||
from myutils.localetools import getgamecamptoolsname, localeswitchedrun
|
||||
from myutils.localetools import getgamecamptools, localeswitchedrun, maycreatesettings
|
||||
from myutils.hwnd import getExeIcon
|
||||
from myutils.wrapper import (
|
||||
Singleton_close,
|
||||
@ -66,6 +66,7 @@ from gui.usefulwidget import (
|
||||
MySwitch,
|
||||
auto_select_webview,
|
||||
Prompt_dialog,
|
||||
clearlayout,
|
||||
getsimplecombobox,
|
||||
D_getsimpleswitch,
|
||||
getspinbox,
|
||||
@ -751,6 +752,9 @@ class dialog_setting_game_internal(QWidget):
|
||||
self.methodtab = methodtab
|
||||
vbox.addWidget(methodtab)
|
||||
do()
|
||||
self.__launch_method.currentIndexChanged.emit(
|
||||
self.__launch_method.currentIndex()
|
||||
)
|
||||
|
||||
def openrefmainpage(self, key, idname, gameuid):
|
||||
try:
|
||||
@ -767,7 +771,7 @@ class dialog_setting_game_internal(QWidget):
|
||||
list(targetmod.keys()),
|
||||
globalconfig,
|
||||
"primitivtemetaorigin",
|
||||
internallist=list(targetmod.keys()),
|
||||
internal=list(targetmod.keys()),
|
||||
static=True,
|
||||
),
|
||||
)
|
||||
@ -823,31 +827,29 @@ class dialog_setting_game_internal(QWidget):
|
||||
layout.addWidget(w)
|
||||
|
||||
def starttab(self, formLayout: LFormLayout, gameuid):
|
||||
box = QGroupBox()
|
||||
settinglayout = LFormLayout()
|
||||
box.setLayout(settinglayout)
|
||||
|
||||
formLayout.addRow(
|
||||
"转区启动",
|
||||
getboxlayout(
|
||||
[
|
||||
getsimpleswitch(savehook_new_data[gameuid], "leuse"),
|
||||
getsimplecombobox(
|
||||
getgamecamptoolsname(uid2gamepath[gameuid]),
|
||||
savehook_new_data[gameuid],
|
||||
"localeswitcher",
|
||||
static=True,
|
||||
),
|
||||
]
|
||||
),
|
||||
)
|
||||
|
||||
formLayout.addRow(
|
||||
"命令行启动",
|
||||
getboxlayout(
|
||||
[
|
||||
getsimpleswitch(savehook_new_data[gameuid], "startcmduse"),
|
||||
getlineedit(savehook_new_data[gameuid], "startcmd"),
|
||||
]
|
||||
def __(box, layout, config, uid):
|
||||
clearlayout(layout)
|
||||
maycreatesettings(layout, config, uid)
|
||||
if layout.count() == 0:
|
||||
box.hide()
|
||||
else:
|
||||
box.show()
|
||||
|
||||
self.__launch_method = getsimplecombobox(
|
||||
[_.name for _ in getgamecamptools(uid2gamepath[gameuid])],
|
||||
savehook_new_data[gameuid],
|
||||
"launch_method",
|
||||
internal=[_.id for _ in getgamecamptools(uid2gamepath[gameuid])],
|
||||
callback=functools.partial(
|
||||
__, box, settinglayout, savehook_new_data[gameuid]
|
||||
),
|
||||
)
|
||||
formLayout.addRow("启动方式", self.__launch_method)
|
||||
formLayout.addRow(box)
|
||||
|
||||
formLayout.addRow(
|
||||
"自动切换到模式",
|
||||
@ -1367,7 +1369,7 @@ class dialog_setting_game_internal(QWidget):
|
||||
static_data["language_list_translator"],
|
||||
savehook_new_data[gameuid],
|
||||
"private_srclang_2",
|
||||
internallist=static_data["language_list_translator_inner"],
|
||||
internal=static_data["language_list_translator_inner"],
|
||||
),
|
||||
)
|
||||
formLayout2.addRow(
|
||||
@ -1376,7 +1378,7 @@ class dialog_setting_game_internal(QWidget):
|
||||
static_data["language_list_translator"],
|
||||
savehook_new_data[gameuid],
|
||||
"private_tgtlang_2",
|
||||
internallist=static_data["language_list_translator_inner"],
|
||||
internal=static_data["language_list_translator_inner"],
|
||||
),
|
||||
)
|
||||
|
||||
@ -1620,47 +1622,7 @@ def startgame(gameuid):
|
||||
)
|
||||
gobject.baseobject.starttextsource(use=_[mode], checked=True)
|
||||
|
||||
dirpath = os.path.dirname(game)
|
||||
|
||||
if savehook_new_data[gameuid]["startcmduse"]:
|
||||
usearg = savehook_new_data[gameuid]["startcmd"].format(exepath=game)
|
||||
windows.CreateProcess(
|
||||
None,
|
||||
usearg,
|
||||
None,
|
||||
None,
|
||||
False,
|
||||
0,
|
||||
None,
|
||||
dirpath,
|
||||
windows.STARTUPINFO(),
|
||||
)
|
||||
return
|
||||
if savehook_new_data[gameuid]["leuse"] == False or (
|
||||
game.lower()[-4:] not in [".lnk", ".exe"]
|
||||
):
|
||||
# 对于其他文件,需要AssocQueryStringW获取命令行才能正确le,太麻烦,放弃。
|
||||
windows.ShellExecute(None, "open", game, "", dirpath, windows.SW_SHOW)
|
||||
return
|
||||
|
||||
execheck3264 = game
|
||||
usearg = '"{}"'.format(game)
|
||||
if game.lower()[-4:] == ".lnk":
|
||||
exepath, args, iconpath, dirp = winsharedutils.GetLnkTargetPath(game)
|
||||
|
||||
if args != "":
|
||||
usearg = '"{}" {}'.format(exepath, args)
|
||||
elif exepath != "":
|
||||
usearg = '"{}"'.format(exepath)
|
||||
|
||||
if exepath != "":
|
||||
execheck3264 = exepath
|
||||
|
||||
if dirp != "":
|
||||
dirpath = dirp
|
||||
|
||||
localeswitcher = savehook_new_data[gameuid]["localeswitcher"]
|
||||
localeswitchedrun(execheck3264, localeswitcher, usearg, dirpath)
|
||||
localeswitchedrun(gameuid)
|
||||
|
||||
except:
|
||||
print_exc()
|
||||
@ -2085,7 +2047,7 @@ class dialog_savedgame_new(QWidget):
|
||||
globalconfig,
|
||||
"currvislistuid",
|
||||
self.resetcurrvislist,
|
||||
internallist=uid,
|
||||
internal=uid,
|
||||
static=True,
|
||||
),
|
||||
)
|
||||
@ -2398,22 +2360,18 @@ class dialog_savedgame_lagacy(QWidget):
|
||||
self.model.insertRow(
|
||||
row,
|
||||
[
|
||||
QStandardItem(),
|
||||
QStandardItem(),
|
||||
keyitem,
|
||||
QStandardItem((savehook_new_data[k]["title"])),
|
||||
],
|
||||
)
|
||||
self.table.setIndexWidget(
|
||||
self.model.index(row, 0), D_getsimpleswitch(savehook_new_data[k], "leuse")
|
||||
)
|
||||
self.table.setIndexWidget(
|
||||
self.model.index(row, 1),
|
||||
self.model.index(row, 0),
|
||||
functools.partial(self.delayloadicon, k),
|
||||
)
|
||||
|
||||
self.table.setIndexWidget(
|
||||
self.model.index(row, 2),
|
||||
self.model.index(row, 1),
|
||||
D_getIconButton(
|
||||
functools.partial(self.showsettingdialog, k), icon="fa.gear"
|
||||
),
|
||||
@ -2427,7 +2385,7 @@ class dialog_savedgame_lagacy(QWidget):
|
||||
|
||||
formLayout = QVBoxLayout(self) #
|
||||
model = LStandardItemModel()
|
||||
model.setHorizontalHeaderLabels(["转区", "", "设置", "游戏"]) # ,'HOOK'])
|
||||
model.setHorizontalHeaderLabels(["", "设置", "游戏"]) # ,'HOOK'])
|
||||
|
||||
self.model = model
|
||||
|
||||
|
@ -163,7 +163,7 @@ class edittrans(LMainWindow):
|
||||
[globalconfig["fanyi"][x]["name"] for x in globalconfig["fanyi"]],
|
||||
globalconfig,
|
||||
"realtime_edit_target",
|
||||
internallist=list(globalconfig["fanyi"]),
|
||||
internal=list(globalconfig["fanyi"]),
|
||||
)
|
||||
)
|
||||
qv.addWidget(submit)
|
||||
|
@ -13,6 +13,7 @@ from gui.usefulwidget import (
|
||||
getQMessageBox,
|
||||
D_getspinbox,
|
||||
D_getIconButton,
|
||||
clearlayout,
|
||||
getboxlayout,
|
||||
D_getcolorbutton,
|
||||
getcolorbutton,
|
||||
@ -89,23 +90,6 @@ class extrahtml(saveposwindow):
|
||||
self.show()
|
||||
|
||||
|
||||
def clearlayout(ll: QLayout):
|
||||
while ll.count():
|
||||
item = ll.takeAt(0)
|
||||
if not item:
|
||||
continue
|
||||
ll.removeItem(item)
|
||||
w = item.widget()
|
||||
if w:
|
||||
w.deleteLater()
|
||||
continue
|
||||
l = item.layout()
|
||||
if l:
|
||||
clearlayout(l)
|
||||
l.deleteLater()
|
||||
continue
|
||||
|
||||
|
||||
def createinternalfontsettings(self, forml: LFormLayout, group, _type):
|
||||
|
||||
globalconfig["rendertext_using_internal"][group] = _type
|
||||
@ -312,7 +296,7 @@ def _createseletengeinecombo(self):
|
||||
visengine,
|
||||
globalconfig,
|
||||
"rendertext_using",
|
||||
internallist=visengine_internal,
|
||||
internal=visengine_internal,
|
||||
callback=functools.partial(resetgroudswitchcallback, self),
|
||||
static=True,
|
||||
)
|
||||
|
@ -28,7 +28,7 @@ def setTablanglz(self):
|
||||
static_data["language_list_translator"],
|
||||
globalconfig,
|
||||
"srclang4",
|
||||
internallist=static_data[
|
||||
internal=static_data[
|
||||
"language_list_translator_inner"
|
||||
],
|
||||
),
|
||||
@ -39,7 +39,7 @@ def setTablanglz(self):
|
||||
static_data["language_list_translator"],
|
||||
globalconfig,
|
||||
"tgtlang4",
|
||||
internallist=static_data[
|
||||
internal=static_data[
|
||||
"language_list_translator_inner"
|
||||
],
|
||||
),
|
||||
@ -64,7 +64,7 @@ def setTablanglz(self):
|
||||
"languageuse2",
|
||||
callback=changelang,
|
||||
static=True,
|
||||
internallist=inner,
|
||||
internal=inner,
|
||||
),
|
||||
D_getIconButton(
|
||||
callback=lambda: os.startfile(
|
||||
|
@ -330,7 +330,7 @@ def gethookembedgrid(self):
|
||||
alltransvis,
|
||||
globalconfig["embedded"],
|
||||
"translator_2",
|
||||
internallist=alltrans,
|
||||
internal=alltrans,
|
||||
),
|
||||
],
|
||||
[
|
||||
|
@ -154,7 +154,7 @@ def setTab5lz(self):
|
||||
static_data["audioengine_vis"],
|
||||
globalconfig,
|
||||
"audioengine",
|
||||
internallist=static_data["audioengine"],
|
||||
internal=static_data["audioengine"],
|
||||
static=True,
|
||||
),
|
||||
],
|
||||
|
@ -713,8 +713,8 @@ def callbackwrap(d, k, call, _):
|
||||
print_exc()
|
||||
|
||||
|
||||
def comboboxcallbackwrap(internallist, d, k, call, _):
|
||||
_ = internallist[_]
|
||||
def comboboxcallbackwrap(internal, d, k, call, _):
|
||||
_ = internal[_]
|
||||
d[k] = _
|
||||
|
||||
if call:
|
||||
@ -724,8 +724,9 @@ def comboboxcallbackwrap(internallist, d, k, call, _):
|
||||
print_exc()
|
||||
|
||||
|
||||
@tryprint
|
||||
def getsimplecombobox(
|
||||
lst, d, k, callback=None, fixedsize=False, internallist=None, static=False
|
||||
lst, d, k, callback=None, fixedsize=False, internal=None, static=False, emit=False
|
||||
):
|
||||
if static:
|
||||
s = FocusCombo()
|
||||
@ -734,30 +735,29 @@ def getsimplecombobox(
|
||||
s = LFocusCombo()
|
||||
s.addItems(lst)
|
||||
|
||||
if internallist:
|
||||
if (k not in d) or (d[k] not in internallist):
|
||||
d[k] = internallist[0]
|
||||
s.setCurrentIndex(internallist.index(d[k]))
|
||||
if internal:
|
||||
if (k not in d) or (d[k] not in internal):
|
||||
d[k] = internal[0]
|
||||
|
||||
s.setCurrentIndex(internal.index(d[k]))
|
||||
s.currentIndexChanged.connect(
|
||||
functools.partial(comboboxcallbackwrap, internallist, d, k, callback)
|
||||
functools.partial(comboboxcallbackwrap, internal, d, k, callback)
|
||||
)
|
||||
else:
|
||||
if (k not in d) or (d[k] >= len(lst)):
|
||||
d[k] = 0
|
||||
|
||||
s.setCurrentIndex(d[k])
|
||||
s.currentIndexChanged.connect(functools.partial(callbackwrap, d, k, callback))
|
||||
|
||||
if fixedsize:
|
||||
s.setSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
|
||||
return s
|
||||
|
||||
|
||||
def D_getsimplecombobox(
|
||||
lst, d, k, callback=None, fixedsize=False, internallist=None, static=False
|
||||
lst, d, k, callback=None, fixedsize=False, internal=None, static=False
|
||||
):
|
||||
return lambda: getsimplecombobox(
|
||||
lst, d, k, callback, fixedsize, internallist, static
|
||||
)
|
||||
return lambda: getsimplecombobox(lst, d, k, callback, fixedsize, internal, static)
|
||||
|
||||
|
||||
def getlineedit(d, key, callback=None, readonly=False):
|
||||
@ -2022,3 +2022,20 @@ class SplitLine(QFrame):
|
||||
super().__init__(*argc)
|
||||
self.setStyleSheet("background-color: gray;")
|
||||
self.setFixedHeight(2)
|
||||
|
||||
|
||||
def clearlayout(ll: QLayout):
|
||||
while ll.count():
|
||||
item = ll.takeAt(0)
|
||||
if not item:
|
||||
continue
|
||||
ll.removeItem(item)
|
||||
w = item.widget()
|
||||
if w:
|
||||
w.deleteLater()
|
||||
continue
|
||||
l = item.layout()
|
||||
if l:
|
||||
clearlayout(l)
|
||||
l.deleteLater()
|
||||
continue
|
||||
|
@ -119,16 +119,14 @@ def getdefaultsavehook(title=None):
|
||||
# "private_tgtlang_2": 0,
|
||||
"follow_default_ankisettings": True,
|
||||
# "anki_DeckName":str
|
||||
"localeswitcher": 0,
|
||||
# "localeswitcher": 0,废弃
|
||||
"onloadautochangemode2": 0,
|
||||
"needinserthookcode": [],
|
||||
"embedablehook": [],
|
||||
"statistic_playtime": 0,
|
||||
"statistic_wordcount": 0,
|
||||
"statistic_wordcount_nodump": 0,
|
||||
"leuse": True,
|
||||
"startcmd": '"{exepath}"',
|
||||
"startcmduse": False,
|
||||
# "leuse": True, 废弃
|
||||
"hook": [],
|
||||
"inserthooktimeout": 1000,
|
||||
"needinserthookcode": [],
|
||||
@ -193,38 +191,36 @@ def getdefaultsavehook(title=None):
|
||||
oldlanguage = ["zh","ja","en","ru","es","ko","fr","cht","vi","tr","pl","uk","it","ar","th","bo","de","sv","nl"]
|
||||
# fmt: on
|
||||
_dfsavehook = getdefaultsavehook("")
|
||||
for uid in savehook_new_data:
|
||||
for gameconfig in savehook_new_data.values():
|
||||
if (
|
||||
("allow_tts_auto_names_v4" not in savehook_new_data[uid])
|
||||
and ("allow_tts_auto_names" in savehook_new_data[uid])
|
||||
and len(savehook_new_data[uid]["allow_tts_auto_names"])
|
||||
("allow_tts_auto_names_v4" not in gameconfig)
|
||||
and ("allow_tts_auto_names" in gameconfig)
|
||||
and len(gameconfig["allow_tts_auto_names"])
|
||||
):
|
||||
savehook_new_data[uid]["allow_tts_auto_names_v4"] = savehook_new_data[uid][
|
||||
gameconfig["allow_tts_auto_names_v4"] = gameconfig[
|
||||
"allow_tts_auto_names"
|
||||
].split("|")
|
||||
|
||||
if ("allow_tts_auto_names_v4" in savehook_new_data[uid]) and (
|
||||
"tts_skip_regex" not in savehook_new_data[uid]
|
||||
if ("allow_tts_auto_names_v4" in gameconfig) and (
|
||||
"tts_skip_regex" not in gameconfig
|
||||
):
|
||||
savehook_new_data[uid]["tts_skip_regex"] = []
|
||||
for name in savehook_new_data[uid]["allow_tts_auto_names_v4"]:
|
||||
savehook_new_data[uid]["tts_skip_regex"].append(
|
||||
gameconfig["tts_skip_regex"] = []
|
||||
for name in gameconfig["allow_tts_auto_names_v4"]:
|
||||
gameconfig["tts_skip_regex"].append(
|
||||
{"regex": False, "key": name, "condition": 0}
|
||||
)
|
||||
if ("private_srclang" in savehook_new_data[uid]) and (
|
||||
"private_srclang_2" not in savehook_new_data[uid]
|
||||
):
|
||||
savehook_new_data[uid]["private_srclang_2"] = oldlanguage[
|
||||
savehook_new_data[uid]["private_srclang"]
|
||||
]
|
||||
savehook_new_data[uid]["private_tgtlang_2"] = oldlanguage[
|
||||
savehook_new_data[uid]["private_tgtlang"]
|
||||
]
|
||||
if ("private_srclang" in gameconfig) and ("private_srclang_2" not in gameconfig):
|
||||
gameconfig["private_srclang_2"] = oldlanguage[gameconfig["private_srclang"]]
|
||||
gameconfig["private_tgtlang_2"] = oldlanguage[gameconfig["private_tgtlang"]]
|
||||
for __k, __v in _dfsavehook.items():
|
||||
if __k not in savehook_new_data[uid]:
|
||||
if __k not in gameconfig:
|
||||
if isinstance(__v, (list, dict)):
|
||||
__v = __v.copy()
|
||||
savehook_new_data[uid][__k] = __v
|
||||
gameconfig[__k] = __v
|
||||
|
||||
if not gameconfig.get("leuse", True):
|
||||
gameconfig.pop("leuse")
|
||||
gameconfig["launch_method"] = "direct"
|
||||
|
||||
|
||||
class __uid2gamepath:
|
||||
|
@ -1,26 +1,84 @@
|
||||
import windows, os
|
||||
import windows, os, winreg, winsharedutils, re
|
||||
from qtsymbols import *
|
||||
from myutils.config import savehook_new_data, uid2gamepath
|
||||
from gui.usefulwidget import (
|
||||
getlineedit,
|
||||
getsimplecombobox,
|
||||
getspinbox,
|
||||
getsimpleswitch,
|
||||
getspinbox,
|
||||
)
|
||||
from traceback import print_exc
|
||||
|
||||
|
||||
class leXX:
|
||||
class Launcher:
|
||||
name = ...
|
||||
id = ...
|
||||
|
||||
@staticmethod
|
||||
def run(bit, config, usearg, dirpath): ...
|
||||
def valid(self):
|
||||
return True
|
||||
|
||||
def run(self, gameexe, config): ...
|
||||
|
||||
def setting(self, layout, config): ...
|
||||
|
||||
|
||||
class LocaleEmulator(leXX):
|
||||
name = "Locale Emulator"
|
||||
class LEbase(Launcher):
|
||||
|
||||
@staticmethod
|
||||
def run(bit, config, usearg, dirpath):
|
||||
def runX(self, exe, usearg, dirpath, config): ...
|
||||
def run(self, game, config):
|
||||
dirpath = os.path.dirname(game)
|
||||
if game.lower()[-4:] not in [".lnk", ".exe"]:
|
||||
# 对于其他文件,需要AssocQueryStringW获取命令行才能正确le,太麻烦,放弃。
|
||||
windows.ShellExecute(None, "open", game, "", dirpath, windows.SW_SHOW)
|
||||
return
|
||||
|
||||
execheck3264 = game
|
||||
usearg = '"{}"'.format(game)
|
||||
if game.lower()[-4:] == ".lnk":
|
||||
exepath, args, iconpath, dirp = winsharedutils.GetLnkTargetPath(game)
|
||||
|
||||
if args != "":
|
||||
usearg = '"{}" {}'.format(exepath, args)
|
||||
elif exepath != "":
|
||||
usearg = '"{}"'.format(exepath)
|
||||
|
||||
if exepath != "":
|
||||
execheck3264 = exepath
|
||||
|
||||
if dirp != "":
|
||||
dirpath = dirp
|
||||
self.runX(execheck3264, usearg, dirpath, config)
|
||||
|
||||
|
||||
class le_internal(LEbase):
|
||||
name = "内置_Locale Emulator"
|
||||
id = "le_internal"
|
||||
|
||||
default = dict(
|
||||
LCID=0x11, CodePage=932, RedirectRegistry=False, HookUILanguageAPI=False
|
||||
)
|
||||
|
||||
def loaddf(self, config):
|
||||
for k, v in self.default.items():
|
||||
k = "LE_" + k
|
||||
if k in config:
|
||||
continue
|
||||
config[k] = v
|
||||
|
||||
def runX(self, exe, usearg, dirpath, config):
|
||||
shareddllproxy = os.path.abspath("./files/plugins/shareddllproxy32")
|
||||
|
||||
def _get(k):
|
||||
return config.get("LE_" + k, self.default[k])
|
||||
|
||||
param = '{ANSICodePage} {OEMCodePage} {LCID} "{dirname}" {RedirectRegistry} {HookUILanguageAPI}'.format(
|
||||
LCID=0x11,
|
||||
OEMCodePage=932,
|
||||
ANSICodePage=932,
|
||||
LCID=_get("LCID"),
|
||||
OEMCodePage=_get("CodePage"),
|
||||
ANSICodePage=_get("CodePage"),
|
||||
dirname=dirpath,
|
||||
RedirectRegistry=int(False),
|
||||
HookUILanguageAPI=int(False),
|
||||
RedirectRegistry=int(_get("RedirectRegistry")),
|
||||
HookUILanguageAPI=int(_get("HookUILanguageAPI")),
|
||||
)
|
||||
windows.CreateProcess(
|
||||
None,
|
||||
@ -34,26 +92,52 @@ class LocaleEmulator(leXX):
|
||||
windows.STARTUPINFO(),
|
||||
)
|
||||
|
||||
def setting(self, layout, config):
|
||||
self.loaddf(config)
|
||||
|
||||
class NTLEAS(leXX):
|
||||
name = "Ntleas"
|
||||
layout.addRow("LCID", getspinbox(0, 0xFFFFF, config, "LE_LCID"))
|
||||
layout.addRow("CodePage", getspinbox(0, 0xFFFFF, config, "LE_CodePage"))
|
||||
layout.addRow(
|
||||
"RedirectRegistry", getsimpleswitch(config, "LE_RedirectRegistry")
|
||||
)
|
||||
layout.addRow(
|
||||
"HookUILanguageAPI", getsimpleswitch(config, "LE_HookUILanguageAPI")
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def run(bit, config, usearg, dirpath):
|
||||
|
||||
class NTLEAS64(LEbase):
|
||||
name = "内置_Ntleas"
|
||||
id = "ntlea_internal"
|
||||
bit = 6
|
||||
|
||||
default = dict(LCID=0x411, CodePage=932, TimeZone=540)
|
||||
|
||||
def loaddf(self, config):
|
||||
for k, v in self.default.items():
|
||||
k = "NT_" + k
|
||||
if k in config:
|
||||
continue
|
||||
config[k] = v
|
||||
|
||||
def runX(self, exe, usearg, dirpath, config):
|
||||
shareddllproxy = os.path.abspath(
|
||||
("./files/plugins/shareddllproxy32", "./files/plugins/shareddllproxy64")[
|
||||
bit == 6
|
||||
self.bit == 6
|
||||
]
|
||||
)
|
||||
param = '{dwCompOption} {dwCodePage} {dwLCID} {dwTimeZone}'.format(
|
||||
|
||||
def _get(k):
|
||||
return config.get("NT_" + k, self.default[k])
|
||||
|
||||
param = "{dwCompOption} {dwCodePage} {dwLCID} {dwTimeZone}".format(
|
||||
dwCompOption=0,
|
||||
dwCodePage=932,
|
||||
dwLCID=0x411,
|
||||
dwTimeZone=-540,
|
||||
dwCodePage=_get("CodePage"),
|
||||
dwLCID=_get("LCID"),
|
||||
dwTimeZone=-_get("TimeZone"),
|
||||
)
|
||||
windows.CreateProcess(
|
||||
None,
|
||||
'"{}" {} {} {}'.format(shareddllproxy, "ntleas", param,usearg),
|
||||
'"{}" {} {} {}'.format(shareddllproxy, "ntleas", param, usearg),
|
||||
None,
|
||||
None,
|
||||
False,
|
||||
@ -63,19 +147,43 @@ class NTLEAS(leXX):
|
||||
windows.STARTUPINFO(),
|
||||
)
|
||||
|
||||
def setting(self, layout, config):
|
||||
self.loaddf(config)
|
||||
|
||||
class LocaleRemulator(leXX):
|
||||
name = "Locale Remulator"
|
||||
layout.addRow("LCID", getspinbox(0, 0xFFFFF, config, "NT_LCID"))
|
||||
layout.addRow("CodePage", getspinbox(0, 0xFFFFF, config, "NT_CodePage"))
|
||||
layout.addRow("TimeZone", getspinbox(0, 0xFFFFF, config, "NT_TimeZone"))
|
||||
|
||||
@staticmethod
|
||||
def run(bit, config, usearg, dirpath):
|
||||
|
||||
class NTLEAS32(NTLEAS64):
|
||||
bit = 3
|
||||
|
||||
|
||||
class lr_internal(LEbase):
|
||||
name = "内置_Locale Remulator"
|
||||
id = "lr_internal"
|
||||
|
||||
default = dict(LCID=0x411, CodePage=932, TimeZone=540, HookIME=False, HookLCID=True)
|
||||
|
||||
def loaddf(self, config):
|
||||
for k, v in self.default.items():
|
||||
k = "LR_" + k
|
||||
if k in config:
|
||||
continue
|
||||
config[k] = v
|
||||
|
||||
def runX(self, exe, usearg, dirpath, config):
|
||||
shareddllproxy = os.path.abspath("./files/plugins/shareddllproxy32")
|
||||
|
||||
def _get(k):
|
||||
return config.get("LR_" + k, self.default[k])
|
||||
|
||||
param = "{CodePage} {LCID} {Bias} {HookIME} {HookLCID}".format(
|
||||
LCID=0x0411,
|
||||
CodePage=932,
|
||||
Bias=540,
|
||||
HookIME=0,
|
||||
HookLCID=1,
|
||||
LCID=_get("LCID"),
|
||||
CodePage=_get("CodePage"),
|
||||
Bias=_get("TimeZone"),
|
||||
HookIME=int(_get("HookIME")),
|
||||
HookLCID=int(_get("HookLCID")),
|
||||
)
|
||||
windows.CreateProcess(
|
||||
None,
|
||||
@ -89,9 +197,307 @@ class LocaleRemulator(leXX):
|
||||
windows.STARTUPINFO(),
|
||||
)
|
||||
|
||||
def setting(self, layout, config):
|
||||
self.loaddf(config)
|
||||
|
||||
x86tools = [LocaleEmulator, LocaleRemulator, NTLEAS]
|
||||
x64tools = [LocaleRemulator, NTLEAS]
|
||||
layout.addRow("LCID", getspinbox(0, 0xFFFFF, config, "LR_LCID"))
|
||||
layout.addRow("CodePage", getspinbox(0, 0xFFFFF, config, "LR_CodePage"))
|
||||
layout.addRow("TimeZone", getspinbox(0, 0xFFFFF, config, "LR_TimeZone"))
|
||||
layout.addRow("HookIME", getsimpleswitch(config, "LR_HookIME"))
|
||||
layout.addRow("HookLCID", getsimpleswitch(config, "LR_HookLCID"))
|
||||
|
||||
|
||||
class le_installed(LEbase):
|
||||
name = "Locale Emulator"
|
||||
id = "le_installed"
|
||||
|
||||
def fundleproc(self):
|
||||
|
||||
for key in [winreg.HKEY_LOCAL_MACHINE, winreg.HKEY_CURRENT_USER]:
|
||||
try:
|
||||
k = winreg.OpenKeyEx(
|
||||
key,
|
||||
r"Software\Classes\CLSID\{C52B9871-E5E9-41FD-B84D-C5ACADBEC7AE}\InprocServer32",
|
||||
0,
|
||||
winreg.KEY_QUERY_VALUE,
|
||||
)
|
||||
|
||||
LEContextMenuHandler: str = winreg.QueryValueEx(k, "CodeBase")[0]
|
||||
winreg.CloseKey(k)
|
||||
if not LEContextMenuHandler.startswith("file:///"):
|
||||
continue
|
||||
LEContextMenuHandler = LEContextMenuHandler[8:]
|
||||
LEProc = os.path.join(
|
||||
os.path.dirname(LEContextMenuHandler), "LEProc.exe"
|
||||
)
|
||||
if not os.path.exists(LEProc):
|
||||
continue
|
||||
return LEProc
|
||||
except:
|
||||
continue
|
||||
return None
|
||||
|
||||
def valid(self):
|
||||
return (self.fundleproc() is not None) and (len(self.profiles()[1]) > 0)
|
||||
|
||||
def profiles(self, exe=None):
|
||||
_Names = []
|
||||
_Guids = []
|
||||
|
||||
def parseone(xmlpath):
|
||||
Names, Guids = [], []
|
||||
with open(xmlpath, "r", encoding="utf8") as ff:
|
||||
for Name, Guid in re.findall('Name="(.*?)" Guid="(.*?)"', ff.read()):
|
||||
Names.append(Name)
|
||||
Guids.append(Guid)
|
||||
return Names, Guids
|
||||
|
||||
finds = [os.path.join(os.path.dirname(self.fundleproc()), "LEConfig.xml")]
|
||||
if exe:
|
||||
finds.append(exe + ".le.config")
|
||||
for f in finds:
|
||||
try:
|
||||
Names, Guids = parseone(f)
|
||||
_Guids += Guids
|
||||
_Names += Names
|
||||
except:
|
||||
pass
|
||||
|
||||
return _Names, _Guids
|
||||
|
||||
def runX(self, exe, usearg, dirpath, config):
|
||||
LEProc = self.fundleproc()
|
||||
if not LEProc:
|
||||
return
|
||||
guids = self.profiles(config["gamepath"])[1]
|
||||
guid = config.get("leguid", None)
|
||||
if guid not in guids:
|
||||
guids = guids[0]
|
||||
arg = '"{}" -runas {} {}'.format(LEProc, guid, usearg)
|
||||
windows.CreateProcess(
|
||||
None,
|
||||
arg,
|
||||
None,
|
||||
None,
|
||||
False,
|
||||
0,
|
||||
None,
|
||||
dirpath,
|
||||
windows.STARTUPINFO(),
|
||||
)
|
||||
|
||||
def setting(self, layout, config):
|
||||
Names, Guids = self.profiles(config["gamepath"])
|
||||
layout.addRow(
|
||||
"Profile",
|
||||
getsimplecombobox(Names, config, "leguid", internal=Guids),
|
||||
)
|
||||
|
||||
|
||||
class lr_installed(LEbase):
|
||||
name = "Locale Remulator"
|
||||
id = "lr_installed"
|
||||
|
||||
def fundleproc(self):
|
||||
|
||||
try:
|
||||
k = winreg.OpenKeyEx(
|
||||
winreg.HKEY_LOCAL_MACHINE,
|
||||
r"SOFTWARE\Classes\LRSubMenus.LRSubMenuExtension\CLSID",
|
||||
0,
|
||||
winreg.KEY_QUERY_VALUE,
|
||||
)
|
||||
CLSID: str = winreg.QueryValueEx(k, "")[0]
|
||||
|
||||
winreg.CloseKey(k)
|
||||
k = winreg.OpenKeyEx(
|
||||
winreg.HKEY_LOCAL_MACHINE,
|
||||
rf"Software\Classes\CLSID\{CLSID}\InprocServer32",
|
||||
0,
|
||||
winreg.KEY_QUERY_VALUE,
|
||||
)
|
||||
|
||||
LRSubMenuExtension: str = winreg.QueryValueEx(k, "CodeBase")[0]
|
||||
winreg.CloseKey(k)
|
||||
if not LRSubMenuExtension.startswith("file:///"):
|
||||
return None
|
||||
LRSubMenuExtension = LRSubMenuExtension[8:]
|
||||
LRProc = os.path.join(os.path.dirname(LRSubMenuExtension), "LRProc.exe")
|
||||
if not os.path.exists(LRProc):
|
||||
return None
|
||||
return LRProc
|
||||
except:
|
||||
|
||||
return None
|
||||
|
||||
def valid(self):
|
||||
return (self.fundleproc() is not None) and (len(self.profiles()[1]) > 0)
|
||||
|
||||
def profiles(self):
|
||||
|
||||
Names, Guids = [], []
|
||||
try:
|
||||
|
||||
with open(
|
||||
os.path.join(os.path.dirname(self.fundleproc()), "LRConfig.xml"),
|
||||
"r",
|
||||
encoding="utf8",
|
||||
) as ff:
|
||||
for Name, Guid in re.findall('Name="(.*?)" Guid="(.*?)"', ff.read()):
|
||||
Names.append(Name)
|
||||
Guids.append(Guid)
|
||||
except:
|
||||
pass
|
||||
return Names, Guids
|
||||
|
||||
def runX(self, exe, usearg, dirpath, config):
|
||||
LEProc = self.fundleproc()
|
||||
if not LEProc:
|
||||
return
|
||||
guids = self.profiles()[1]
|
||||
guid = config.get("lrguid", None)
|
||||
if guid not in guids:
|
||||
guids = guids[0]
|
||||
arg = '"{}" {} {}'.format(LEProc, guid, usearg)
|
||||
windows.CreateProcess(
|
||||
None,
|
||||
arg,
|
||||
None,
|
||||
None,
|
||||
False,
|
||||
0,
|
||||
None,
|
||||
dirpath,
|
||||
windows.STARTUPINFO(),
|
||||
)
|
||||
|
||||
def setting(self, layout, config):
|
||||
Names, Guids = self.profiles()
|
||||
layout.addRow(
|
||||
"Profile",
|
||||
getsimplecombobox(Names, config, "lrguid", internal=Guids),
|
||||
)
|
||||
|
||||
|
||||
class ntleas_installed(LEbase):
|
||||
name = "Ntleas"
|
||||
id = "ntleas_installed"
|
||||
bit64 = True
|
||||
|
||||
def fundleproc(self):
|
||||
|
||||
try:
|
||||
CLSID = "{9C31DD66-412C-4B28-BD17-1F0BEBE29E8B}"
|
||||
|
||||
k = winreg.OpenKeyEx(
|
||||
winreg.HKEY_LOCAL_MACHINE,
|
||||
rf"Software\Classes\CLSID\{CLSID}\InprocServer32",
|
||||
0,
|
||||
winreg.KEY_QUERY_VALUE,
|
||||
)
|
||||
|
||||
LRSubMenuExtension: str = winreg.QueryValueEx(k, "")[0]
|
||||
winreg.CloseKey(k)
|
||||
LRProc = os.path.join(
|
||||
os.path.dirname(LRSubMenuExtension),
|
||||
["x86", "x64"][self.bit64],
|
||||
"ntleas.exe",
|
||||
)
|
||||
if not os.path.exists(LRProc):
|
||||
return None
|
||||
return LRProc
|
||||
except:
|
||||
return None
|
||||
|
||||
def valid(self):
|
||||
return self.fundleproc() is not None
|
||||
|
||||
def runX(self, exe, usearg, dirpath, config):
|
||||
LEProc = self.fundleproc()
|
||||
if not LEProc:
|
||||
return
|
||||
|
||||
arg = '"{}" {} {}'.format(
|
||||
LEProc,
|
||||
usearg,
|
||||
config.get("ntleasparam", '"C932" "L1041" "FMS PGothic" "P4"'),
|
||||
)
|
||||
windows.CreateProcess(
|
||||
None,
|
||||
arg,
|
||||
None,
|
||||
None,
|
||||
False,
|
||||
0,
|
||||
None,
|
||||
dirpath,
|
||||
windows.STARTUPINFO(),
|
||||
)
|
||||
|
||||
def setting(self, layout, config):
|
||||
if "ntleasparam" not in config:
|
||||
config["ntleasparam"] = '"C932" "L1041" "FMS PGothic" "P4"'
|
||||
|
||||
layout.addRow(
|
||||
"params",
|
||||
getlineedit(config, "ntleasparam"),
|
||||
)
|
||||
|
||||
|
||||
class ntleas_installed32(ntleas_installed):
|
||||
bit64 = False
|
||||
|
||||
|
||||
class CommandLine(Launcher):
|
||||
name = "命令行启动"
|
||||
id = "cmd"
|
||||
|
||||
def run(self, gameexe, config):
|
||||
dirpath = os.path.dirname(gameexe)
|
||||
|
||||
usearg = config.get("startcmd", "{exepath}").format(exepath=gameexe)
|
||||
windows.CreateProcess(
|
||||
None,
|
||||
usearg,
|
||||
None,
|
||||
None,
|
||||
False,
|
||||
0,
|
||||
None,
|
||||
dirpath,
|
||||
windows.STARTUPINFO(),
|
||||
)
|
||||
|
||||
def setting(self, layout, config):
|
||||
if "startcmd" not in config:
|
||||
config["startcmd"] = "{exepath}"
|
||||
|
||||
layout.addRow(
|
||||
"命令行启动",
|
||||
getlineedit(config, "startcmd"),
|
||||
)
|
||||
|
||||
|
||||
class Direct(Launcher):
|
||||
name = "直接启动"
|
||||
id = "direct"
|
||||
|
||||
def run(self, gameexe, argsdict):
|
||||
dirpath = os.path.dirname(gameexe)
|
||||
windows.ShellExecute(None, "open", gameexe, "", dirpath, windows.SW_SHOW)
|
||||
|
||||
|
||||
x86tools = [
|
||||
le_internal,
|
||||
lr_internal,
|
||||
NTLEAS32,
|
||||
le_installed,
|
||||
lr_installed,
|
||||
ntleas_installed32,
|
||||
CommandLine,
|
||||
Direct,
|
||||
]
|
||||
x64tools = [lr_internal, NTLEAS64, lr_installed, ntleas_installed, CommandLine, Direct]
|
||||
|
||||
|
||||
def getgamecamptools(gameexe):
|
||||
@ -100,18 +506,36 @@ def getgamecamptools(gameexe):
|
||||
_methods = x64tools
|
||||
else:
|
||||
_methods = x86tools
|
||||
return _methods
|
||||
ms = []
|
||||
for _ in _methods:
|
||||
if not _().valid():
|
||||
continue
|
||||
ms.append(_)
|
||||
return ms
|
||||
|
||||
|
||||
def getgamecamptoolsname(gameexe):
|
||||
return [_.name for _ in getgamecamptools(gameexe)]
|
||||
def fundlauncher(_id):
|
||||
for _ in x86tools + x64tools:
|
||||
if _.id != _id:
|
||||
continue
|
||||
return _
|
||||
return None
|
||||
|
||||
|
||||
def localeswitchedrun(gameexe, idx, usearg, dirpath):
|
||||
b = windows.GetBinaryType(gameexe)
|
||||
def localeswitchedrun(gameuid):
|
||||
config = savehook_new_data[gameuid]
|
||||
launch_method = config.get("launch_method", None)
|
||||
gameexe = uid2gamepath[gameuid]
|
||||
tools = getgamecamptools(gameexe)
|
||||
if idx < 0 or idx >= len(tools):
|
||||
idx = 0
|
||||
ids = [_.id for _ in getgamecamptools(uid2gamepath[gameuid])]
|
||||
if launch_method not in ids:
|
||||
index = 0
|
||||
else:
|
||||
index = ids.index(launch_method)
|
||||
tool: Launcher = tools[index]()
|
||||
tool.run(gameexe, config)
|
||||
|
||||
tool = tools[idx]
|
||||
tool.run(b, 0, usearg, dirpath)
|
||||
|
||||
def maycreatesettings(layout, config, launcherid):
|
||||
launcher = fundlauncher(launcherid)()
|
||||
launcher.setting(layout, config)
|
||||
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "لصق",
|
||||
"首尾": "الرأس والذيل",
|
||||
"包含": "احتواء",
|
||||
"删除图片文件": "حذف ملف الصورة"
|
||||
"删除图片文件": "حذف ملف الصورة",
|
||||
"启动方式": "طريقة البدء",
|
||||
"直接启动": "بدء التشغيل مباشرة"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "粘貼",
|
||||
"首尾": "首尾",
|
||||
"包含": "包含",
|
||||
"删除图片文件": "删除圖片檔案"
|
||||
"删除图片文件": "删除圖片檔案",
|
||||
"启动方式": "啟動管道",
|
||||
"直接启动": "直接啟動"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "pasta",
|
||||
"首尾": "Konec k konci",
|
||||
"包含": "obsahovat",
|
||||
"删除图片文件": "Smazat obrázkové soubory"
|
||||
"删除图片文件": "Smazat obrázkové soubory",
|
||||
"启动方式": "Metoda spuštění",
|
||||
"直接启动": "Přímo spustit"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "Paste",
|
||||
"首尾": "Ende zu Ende",
|
||||
"包含": "enthalten",
|
||||
"删除图片文件": "Bilddateien löschen"
|
||||
"删除图片文件": "Bilddateien löschen",
|
||||
"启动方式": "Startmethode",
|
||||
"直接启动": "Direkt starten"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "paste",
|
||||
"首尾": "End to end",
|
||||
"包含": "contain",
|
||||
"删除图片文件": "Delete image files"
|
||||
"删除图片文件": "Delete image files",
|
||||
"启动方式": "Startup method",
|
||||
"直接启动": "Directly start"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "Pegar",
|
||||
"首尾": "De principio a fin",
|
||||
"包含": "Contiene",
|
||||
"删除图片文件": "Eliminar archivos de imagen"
|
||||
"删除图片文件": "Eliminar archivos de imagen",
|
||||
"启动方式": "Modo de arranque",
|
||||
"直接启动": "Arranque directo"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "Coller",
|
||||
"首尾": "Première queue",
|
||||
"包含": "Contient",
|
||||
"删除图片文件": "Supprimer un fichier image"
|
||||
"删除图片文件": "Supprimer un fichier image",
|
||||
"启动方式": "Mode de démarrage",
|
||||
"直接启动": "Démarrage direct"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "pasta",
|
||||
"首尾": "Fine a fine",
|
||||
"包含": "contiene",
|
||||
"删除图片文件": "Elimina file immagine"
|
||||
"删除图片文件": "Elimina file immagine",
|
||||
"启动方式": "Metodo di avvio",
|
||||
"直接启动": "Avvia direttamente"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "貼り付け",
|
||||
"首尾": "首尾",
|
||||
"包含": "含める",
|
||||
"删除图片文件": "画像ファイルを削除"
|
||||
"删除图片文件": "画像ファイルを削除",
|
||||
"启动方式": "起動モード",
|
||||
"直接启动": "ダイレクトスタート"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "붙여넣기",
|
||||
"首尾": "수미",
|
||||
"包含": "포함",
|
||||
"删除图片文件": "그림 파일 삭제"
|
||||
"删除图片文件": "그림 파일 삭제",
|
||||
"启动方式": "시작 방법",
|
||||
"直接启动": "직접 시작"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "plakken",
|
||||
"首尾": "End to end",
|
||||
"包含": "bevatten",
|
||||
"删除图片文件": "Afbeeldingsbestanden verwijderen"
|
||||
"删除图片文件": "Afbeeldingsbestanden verwijderen",
|
||||
"启动方式": "Opstartmethode",
|
||||
"直接启动": "Direct starten"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "pasta",
|
||||
"首尾": "Koniec do końca",
|
||||
"包含": "zawierać",
|
||||
"删除图片文件": "Usuń pliki obrazów"
|
||||
"删除图片文件": "Usuń pliki obrazów",
|
||||
"启动方式": "Metoda uruchomienia",
|
||||
"直接启动": "Bezpośredni start"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "colar",
|
||||
"首尾": "De ponta a ponta",
|
||||
"包含": "contém",
|
||||
"删除图片文件": "Apagar os ficheiros de imagem"
|
||||
"删除图片文件": "Apagar os ficheiros de imagem",
|
||||
"启动方式": "Método de arranque",
|
||||
"直接启动": "Iniciar directamente"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "Вставить",
|
||||
"首尾": "Голова и хвост",
|
||||
"包含": "Включение",
|
||||
"删除图片文件": "Удалить файл изображения"
|
||||
"删除图片文件": "Удалить файл изображения",
|
||||
"启动方式": "Режим запуска",
|
||||
"直接启动": "Прямой запуск"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "klistra",
|
||||
"首尾": "Slut till slut",
|
||||
"包含": "innehåller",
|
||||
"删除图片文件": "Ta bort bildfiler"
|
||||
"删除图片文件": "Ta bort bildfiler",
|
||||
"启动方式": "Startmetod",
|
||||
"直接启动": "Starta direkt"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "วางบน",
|
||||
"首尾": "หัวหาง",
|
||||
"包含": "ประกอบด้วย",
|
||||
"删除图片文件": "ลบไฟล์รูปภาพ"
|
||||
"删除图片文件": "ลบไฟล์รูปภาพ",
|
||||
"启动方式": "วิธีการเริ่มต้น",
|
||||
"直接启动": "เริ่มต้นโดยตรง"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "Yapıştır",
|
||||
"首尾": "Sonuna kadar",
|
||||
"包含": "içerir",
|
||||
"删除图片文件": "Resim dosyalarını sil"
|
||||
"删除图片文件": "Resim dosyalarını sil",
|
||||
"启动方式": "Başlangıç yöntemi",
|
||||
"直接启动": "Direkten başla"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "вставити",
|
||||
"首尾": "Кінець до кінця",
|
||||
"包含": "містити",
|
||||
"删除图片文件": "Вилучити файли зображення"
|
||||
"删除图片文件": "Вилучити файли зображення",
|
||||
"启动方式": "Метод запуску",
|
||||
"直接启动": "Прямо запустити"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "Dán",
|
||||
"首尾": "Trang chủ",
|
||||
"包含": "Bao gồm",
|
||||
"删除图片文件": "Xoá tập tin ảnh"
|
||||
"删除图片文件": "Xoá tập tin ảnh",
|
||||
"启动方式": "Cách bắt đầu",
|
||||
"直接启动": "Khởi động trực tiếp"
|
||||
}
|
@ -838,5 +838,7 @@
|
||||
"粘贴": "",
|
||||
"首尾": "",
|
||||
"包含": "",
|
||||
"删除图片文件": ""
|
||||
"删除图片文件": "",
|
||||
"启动方式": "",
|
||||
"直接启动": ""
|
||||
}
|
@ -28,8 +28,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/version)
|
||||
include(generate_product_version)
|
||||
|
||||
set(VERSION_MAJOR 5)
|
||||
set(VERSION_MINOR 20)
|
||||
set(VERSION_PATCH 1)
|
||||
set(VERSION_MINOR 21)
|
||||
set(VERSION_PATCH 0)
|
||||
|
||||
add_library(pch pch.cpp)
|
||||
target_precompile_headers(pch PUBLIC pch.h)
|
||||
|
Loading…
x
Reference in New Issue
Block a user