This commit is contained in:
恍兮惚兮 2024-04-14 11:24:13 +08:00
parent 9f1f9cb1e0
commit f75172923d
28 changed files with 474 additions and 119 deletions

View File

@ -15,8 +15,10 @@ from myutils.config import (
import zipfile import zipfile
from myutils.utils import ( from myutils.utils import (
minmaxmoveobservefunc, minmaxmoveobservefunc,
parsemayberegexreplace,
kanjitrans, kanjitrans,
checkifnewgame, checkifnewgame,
getfilemd5,
stringfyerror, stringfyerror,
) )
from myutils.wrapper import threader from myutils.wrapper import threader
@ -41,7 +43,6 @@ import windows
import re, gobject import re, gobject
import winsharedutils import winsharedutils
from myutils.post import POSTSOLVE from myutils.post import POSTSOLVE
from myutils.vnrshareddict import vnrshareddict
from gui.usefulwidget import Prompt, getQMessageBox from gui.usefulwidget import Prompt, getQMessageBox
@ -70,6 +71,8 @@ class MAINUI:
self.isrunning = True self.isrunning = True
self.solvegottextlock = threading.Lock() self.solvegottextlock = threading.Lock()
self.outputers = {} self.outputers = {}
self.processmethods = []
self.zhanweifu = 0
@property @property
def textsource(self): def textsource(self):
@ -87,93 +90,47 @@ class MAINUI:
self.currentmd5 = "0" if _ is None else _.md5 self.currentmd5 = "0" if _ is None else _.md5
@threader @threader
def loadvnrshareddict(self, _=None): def safeloadprocessmodels(self):
vnrshareddict(self) for model in ["noundict", "gongxiangcishu", "transerrorfix", "myprocess"]:
try:
if model == "myprocess":
mm = "myprocess"
checkpath = "./userconfig/myprocess.py"
else:
mm = "transoptimi." + model
checkpath = "./LunaTranslator/transoptimi/" + model + ".py"
if os.path.exists(checkpath) == False:
continue
klass = importlib.import_module(mm).Process()
process_before = klass.process_before
process_after = klass.process_after
self.processmethods.append(klass)
except:
print_exc()
def solvebeforetrans(self, content): def solvebeforetrans(self, content):
contexts = []
zhanweifu = 0 for i in range(len(self.processmethods)):
mp1 = {} try:
mp2 = {} if self.processmethods[i].using:
mp3 = {} content, context = self.processmethods[i].process_before(content)
if noundictconfig["use"]:
for key in noundictconfig["dict"]:
usedict = False
if type(noundictconfig["dict"][key]) == str:
usedict = True
else: else:
for i in range(len(noundictconfig["dict"][key]) // 2): context = None
if noundictconfig["dict"][key][i * 2] in ["0", self.currentmd5]: except:
usedict = True context = None
break print_exc()
contexts.append(context)
if usedict and key in content: return content, contexts
xx = "{{{}}}".format(zhanweifu)
content = content.replace(key, xx)
mp1[xx] = key
zhanweifu += 1
if globalconfig["gongxiangcishu"]["use"]:
for key, value in self.sorted_vnrshareddict_pre:
if key in content:
content = content.replace(key, value["text"])
for key, value in self.sorted_vnrshareddict:
if key in content:
# print(key)
# if self.vnrshareddict[key]['src']==self.vnrshareddict[key]['tgt']:
# content=content.replace(key,self.vnrshareddict[key]['text'])
# else:
xx = "{{{}}}".format(zhanweifu)
content = content.replace(key, xx)
mp2[xx] = key
zhanweifu += 1
return content, (mp1, mp2, mp3)
def parsemayberegexreplace(self, dict, res):
for item in dict:
if item["regex"]:
res = re.sub(
codecs.escape_decode(bytes(item["key"], "utf-8"))[0].decode(
"utf-8"
),
codecs.escape_decode(bytes(item["value"], "utf-8"))[0].decode(
"utf-8"
),
res,
)
else:
res = res.replace(item["key"], item["value"])
return res
def solveaftertrans(self, res, mp): def solveaftertrans(self, res, mp):
mp1, mp2, mp3 = mp for i in range(len(self.processmethods)):
# print(res,mp)#hello
if noundictconfig["use"]: context = mp[i]
for key in mp1: try:
reg = re.compile(re.escape(key), re.IGNORECASE) if self.processmethods[i].using:
if type(noundictconfig["dict"][mp1[key]]) == str: res = self.processmethods[i].process_after(res, context)
v = noundictconfig["dict"][mp1[key]] except:
elif type(noundictconfig["dict"][mp1[key]]) == list: print_exc()
v = ""
for i in range(len(noundictconfig["dict"][mp1[key]]) // 2):
if noundictconfig["dict"][mp1[key]][i * 2] in [
"0",
self.currentmd5,
]:
v = noundictconfig["dict"][mp1[key]][i * 2 + 1]
break
res = reg.sub(v, res)
if globalconfig["gongxiangcishu"]["use"]:
for key in mp2:
reg = re.compile(re.escape(key), re.IGNORECASE)
res = reg.sub(self.vnrshareddict[mp2[key]]["text"], res)
for key, value in self.sorted_vnrshareddict_post:
if key in res:
res = res.replace(key, value["text"])
if transerrorfixdictconfig["use"]:
res = self.parsemayberegexreplace(transerrorfixdictconfig["dict_v2"], res)
return res return res
def _POSTSOLVE(self, s): def _POSTSOLVE(self, s):
@ -447,7 +404,7 @@ class MAINUI:
def ttsrepair(self, text, usedict): def ttsrepair(self, text, usedict):
if usedict["tts_repair"]: if usedict["tts_repair"]:
text = self.parsemayberegexreplace(usedict["tts_repair_regex"], text) text = parsemayberegexreplace(usedict["tts_repair_regex"], text)
return text return text
def readcurrent(self, force=False): def readcurrent(self, force=False):
@ -826,7 +783,7 @@ class MAINUI:
gobject.overridestdio() gobject.overridestdio()
self.loadvnrshareddict() self.safeloadprocessmodels()
self.prepare() self.prepare()
self.startxiaoxueguan() self.startxiaoxueguan()
self.starthira() self.starthira()

View File

@ -119,7 +119,7 @@ class rangeselct(QMainWindow):
# desktop = desktop.united(QDesktopWidget().screenGeometry(i)) # desktop = desktop.united(QDesktopWidget().screenGeometry(i))
desktop = QApplication.primaryScreen().virtualGeometry() desktop = QApplication.primaryScreen().virtualGeometry()
self.setGeometry(desktop) self.setGeometry(desktop)
self.rectlabel.resize(desktop.size()) self.rectlabel.setGeometry(desktop)
self.setCursor(Qt.CrossCursor) self.setCursor(Qt.CrossCursor)
self.is_drawing = False self.is_drawing = False
self.setMouseTracking(True) self.setMouseTracking(True)

View File

@ -254,7 +254,6 @@ def setTab7_lazy(self):
getsimpleswitch( getsimpleswitch(
globalconfig["gongxiangcishu"], globalconfig["gongxiangcishu"],
"use", "use",
callback=gobject.baseobject.loadvnrshareddict,
), ),
getcolorbutton( getcolorbutton(
globalconfig, globalconfig,
@ -265,7 +264,7 @@ def setTab7_lazy(self):
globalconfig["gongxiangcishu"], globalconfig["gongxiangcishu"],
"path", "path",
"共享辞书", "共享辞书",
gobject.baseobject.loadvnrshareddict, None,
False, False,
"*.xml", "*.xml",
), ),
@ -279,6 +278,17 @@ def setTab7_lazy(self):
"", "",
"", "",
], ],
[
("使用自定义优化", 6),
getsimpleswitch(globalconfig, "selfdefinedprocesspair"),
getcolorbutton(
globalconfig,
"",
callback=lambda: selectdebugfile("./userconfig/myprocess.py"),
icon="fa.gear",
constcolor="#FF69B4",
),
],
] ]
if globalconfig["languageuse"] == 2: # en if globalconfig["languageuse"] == 2: # en
grids2 += [ grids2 += [

View File

@ -537,10 +537,24 @@ class QUnFrameWindow(resizableframeless):
self.setontopthread() self.setontopthread()
return super().showEvent(a0) return super().showEvent(a0)
def canceltop(self, hwnd=windows.HWND_NOTOPMOST): def canceltop(self):
windows.SetWindowPos( windows.SetWindowPos(
int(int(self.winId())), int(self.winId()),
hwnd, windows.HWND_NOTOPMOST,
0,
0,
0,
0,
windows.SWP_NOACTIVATE | windows.SWP_NOSIZE | windows.SWP_NOMOVE,
)
HWNDStyleEx = windows.GetWindowLong(int(self.winId()), windows.GWL_EXSTYLE)
windows.SetWindowLong(
int(self.winId()), windows.GWL_EXSTYLE, HWNDStyleEx & ~windows.WS_EX_TOPMOST
)
windows.SetWindowPos(
int(self.winId()),
windows.GetForegroundWindow(),
0, 0,
0, 0,
0, 0,
@ -549,8 +563,17 @@ class QUnFrameWindow(resizableframeless):
) )
def settop(self): def settop(self):
if (
windows.GetWindowLong(int(self.winId()), windows.GWL_EXSTYLE)
& windows.WS_EX_TOPMOST
) == 0:
self.canceltop()
HWNDStyleEx = windows.GetWindowLong(int(self.winId()), windows.GWL_EXSTYLE)
windows.SetWindowLong(
int(self.winId()), windows.GWL_EXSTYLE, HWNDStyleEx | windows.WS_EX_TOPMOST
)
windows.SetWindowPos( windows.SetWindowPos(
int(int(self.winId())), int(self.winId()),
windows.HWND_TOPMOST, windows.HWND_TOPMOST,
0, 0,
0, 0,
@ -569,12 +592,8 @@ class QUnFrameWindow(resizableframeless):
pid = windows.GetWindowThreadProcessId(hwnd) pid = windows.GetWindowThreadProcessId(hwnd)
if pid == os.getpid(): if pid == os.getpid():
pass pass
elif globalconfig["focusnotop"]: elif globalconfig["focusnotop"] and self.thistimenotsetop:
try: pass
if gobject.baseobject.textsource.hwnd in [0, hwnd]:
self.settop()
except:
self.settop()
else: else:
self.settop() self.settop()
except: except:
@ -660,6 +679,7 @@ class QUnFrameWindow(resizableframeless):
self.document.contentsChanged.connect(self.textAreaChanged) self.document.contentsChanged.connect(self.textAreaChanged)
self.set_color_transparency() self.set_color_transparency()
self.refreshtoolicon() self.refreshtoolicon()
self.thistimenotsetop = False
def set_color_transparency(self): def set_color_transparency(self):
self.translate_text.setStyleSheet( self.translate_text.setStyleSheet(

View File

@ -311,14 +311,32 @@ from translator.basetranslator import basetrans
class TS(basetrans): class TS(basetrans):
def translate(self,content): def translate(self,content):
#在这里编写 #在这里编写
return content""" return content
"""
) )
elif path == "./userconfig/mypost.py": elif path == "./userconfig/mypost.py":
ff.write( ff.write(
""" """
def POSTSOLVE(line): def POSTSOLVE(line):
#请在这里编写自定义处理 #请在这里编写自定义处理
return line""" return line
"""
)
elif path == "./userconfig/myprocess.py":
ff.write(
"""
class Process:
@property
def using(self):
return True
def process_before(self, text):
context = {}
return text, context
def process_after(self, res, context):
return res
"""
) )
os.startfile(p) os.startfile(p)
return p return p
@ -407,9 +425,14 @@ def minmaxmoveobservefunc(self):
if globalconfig["keepontop"] and globalconfig["focusnotop"]: if globalconfig["keepontop"] and globalconfig["focusnotop"]:
if _focusp == os.getpid(): if _focusp == os.getpid():
pass pass
elif _focusp in gobject.baseobject.textsource.pids: elif (
len(gobject.baseobject.textsource.pids) == 0
or _focusp in gobject.baseobject.textsource.pids
):
gobject.baseobject.translation_ui.thistimenotsetop = False
gobject.baseobject.translation_ui.settop() gobject.baseobject.translation_ui.settop()
else: else:
gobject.baseobject.translation_ui.thistimenotsetop = True
gobject.baseobject.translation_ui.canceltop() gobject.baseobject.translation_ui.canceltop()
if _focusp != windows.GetWindowThreadProcessId( if _focusp != windows.GetWindowThreadProcessId(
gobject.baseobject.textsource.hwnd gobject.baseobject.textsource.hwnd
@ -483,3 +506,16 @@ class autosql(sqlite3.Connection):
def __del__(self): def __del__(self):
self.close() self.close()
def parsemayberegexreplace(dict, res):
for item in dict:
if item["regex"]:
res = re.sub(
codecs.escape_decode(bytes(item["key"], "utf-8"))[0].decode("utf-8"),
codecs.escape_decode(bytes(item["value"], "utf-8"))[0].decode("utf-8"),
res,
)
else:
res = res.replace(item["key"], item["value"])
return res

View File

@ -0,0 +1,160 @@
from traceback import print_exc
import json
from translator.basetranslator import basetrans
"""
{'response_id': 'f6299ecb-b90a-4582-84e9-3c5c5c586919', 'text': 'In Chinese characters, "Monday" is written as: 星期一\n\nIs there anything else you would like me to translate for you?', 'generation_id': '998f2d14-1af7-4ec3-8699-b164c67a6900', 'chat_history': [{'role': 'USER', 'message': 'translate it to chinese'}, {'role': 'CHATBOT', 'message': 'ok'}, {'role': 'USER', 'message': 'today is monday'}, {'role': 'CHATBOT', 'message': 'In Chinese characters, "Monday" is written as: 星期一\n\nIs there anything else you would like me to translate for you?'}], 'finish_reason': 'COMPLETE', 'meta': {'api_version': {'version': '1'}, 'billed_units': {'input_tokens': 10, 'output_tokens': 29}, 'tokens': {'input_tokens': 82, 'output_tokens': 29}}}
{"is_finished":false,"event_type":"stream-start","generation_id":"2c3aeaf6-8e34-479e-84ce-a669d01a6e02"}
{"is_finished":false,"event_type":"text-generation","text":"In"}
{"is_finished":false,"event_type":"text-generation","text":" Chinese"}
{"is_finished":false,"event_type":"text-generation","text":","}
{"is_finished":false,"event_type":"text-generation","text":" \""}
{"is_finished":false,"event_type":"text-generation","text":"Monday"}
{"is_finished":false,"event_type":"text-generation","text":"\""}
{"is_finished":false,"event_type":"text-generation","text":" is"}
{"is_finished":false,"event_type":"text-generation","text":" translated"}
{"is_finished":false,"event_type":"text-generation","text":" as"}
{"is_finished":false,"event_type":"text-generation","text":" \""}
{"is_finished":false,"event_type":"text-generation","text":"星期"}
{"is_finished":false,"event_type":"text-generation","text":""}
{"is_finished":false,"event_type":"text-generation","text":"\""}
{"is_finished":false,"event_type":"text-generation","text":" ("}
{"is_finished":false,"event_type":"text-generation","text":"X"}
{"is_finished":false,"event_type":"text-generation","text":"īng"}
{"is_finished":false,"event_type":"text-generation","text":"q"}
{"is_finished":false,"event_type":"text-generation","text":"ī"}
{"is_finished":false,"event_type":"text-generation","text":" y"}
{"is_finished":false,"event_type":"text-generation","text":"ī"}
{"is_finished":false,"event_type":"text-generation","text":")."}
{"is_finished":false,"event_type":"text-generation","text":" Have"}
{"is_finished":false,"event_type":"text-generation","text":" a"}
{"is_finished":false,"event_type":"text-generation","text":" great"}
{"is_finished":false,"event_type":"text-generation","text":" Monday"}
{"is_finished":false,"event_type":"text-generation","text":"!"}
{"is_finished":true,"event_type":"stream-end","response":{"response_id":"b7b03042-b877-4f25-bece-59b3ba9f4e2a","text":"In Chinese, \"Monday\" is translated as \"星期一\" (Xīngqī yī). Have a great Monday!","generation_id":"2c3aeaf6-8e34-479e-84ce-a669d01a6e02","chat_history":[{"role":"USER","message":"translate it to chinese"},{"role":"CHATBOT","message":"ok"},{"role":"USER","message":"today is monday"},{"role":"CHATBOT","message":"In Chinese, \"Monday\" is translated as \"星期一\" (Xīngqī yī). Have a great Monday!"}],"finish_reason":"COMPLETE","meta":{"api_version":{"version":"1"},"billed_units":{"input_tokens":10,"output_tokens":26},"tokens":{"input_tokens":82,"output_tokens":26}}},"finish_reason":"COMPLETE"}
"""
class TS(basetrans):
def langmap(self):
return {
"zh": "Simplified Chinese",
"ja": "Japanese",
"en": "English",
"ru": "Russian",
"es": "Spanish",
"ko": "Korean",
"fr": "French",
"cht": "Traditional Chinese",
"vi": "Vietnamese",
"tr": "Turkish",
"pl": "Polish",
"uk": "Ukrainian",
"it": "Italian",
"ar": "Arabic",
"th": "Thai",
}
def __init__(self, typename):
self.context = []
super().__init__(typename)
def inittranslator(self):
self.api_key = None
def checkv1(self, api_url):
if api_url[-4:] == "/v1/":
api_url = api_url[:-1]
elif api_url[-3:] == "/v1":
pass
elif api_url[-1] == "/":
api_url += "v1"
else:
api_url += "/v1"
return api_url
def translate(self, query):
self.checkempty(["SECRET_KEY", "model"])
self.contextnum = int(self.config["附带上下文个数"])
try:
temperature = float(self.config["Temperature"])
except:
temperature = 0.3
if self.config["使用自定义promt"]:
message = [{"role": "USER", "content": self.config["自定义promt"]}]
else:
message = [
{
"role": "USER",
"message": "translate from {} to {}".format(
self.srclang, self.tgtlang
),
},
]
message.append(
{
"role": "CHATBOT",
"message": "ok",
}
)
for _i in range(min(len(self.context) // 2, self.contextnum)):
i = (
len(self.context) // 2
- min(len(self.context) // 2, self.contextnum)
+ _i
)
message.append(self.context[i * 2])
message.append(self.context[i * 2 + 1])
headers = {"Authorization": "Bearer " + self.multiapikeycurrent["SECRET_KEY"]}
usingstream = self.config["流式输出"]
data = dict(
model=self.config["model"],
chat_history=message,
message=query,
# optional
max_tokens=2048,
n=1,
stop=None,
top_p=1,
temperature=temperature,
stream=usingstream,
)
response = self.session.post(
"https://api.cohere.ai/v1/chat",
headers=headers,
json=data,
stream=usingstream,
)
if usingstream:
message = ""
for chunk in response.iter_lines():
response_data = chunk.decode("utf-8").strip()
if not response_data:
continue
try:
json_data = json.loads(response_data)
t = json_data["event_type"]
if t == "text-generation":
msg = json_data["text"]
yield msg
message += msg
elif t == "stream-end":
break
except:
print_exc()
raise Exception(response_data)
else:
try:
message = response.json()["text"]
yield message
except:
raise Exception(response.text)
self.context.append({"role": "USER", "message": query})
self.context.append({"role": "CHATBOT", "message": message})

View File

@ -1,6 +1,6 @@
from myutils.config import globalconfig from myutils.config import globalconfig
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import os import os, gobject, re
def vnrshareddict(self): def vnrshareddict(self):
@ -84,3 +84,53 @@ def vnrshareddict(self):
self.sorted_vnrshareddict_post = [ self.sorted_vnrshareddict_post = [
(key, self.vnrshareddict_post[key]) for key in keys (key, self.vnrshareddict_post[key]) for key in keys
] ]
class Process:
@property
def using(self):
return globalconfig["gongxiangcishu"]["use"]
def __init__(self) -> None:
self.status = None
self.checkchange()
def checkchange(self):
s = (
globalconfig["gongxiangcishu"]["use"],
globalconfig["gongxiangcishu"]["path"],
)
if self.status != s:
self.status = s
vnrshareddict(self)
def process_before(self, content):
self.checkchange()
context = {}
for key, value in self.sorted_vnrshareddict_pre:
if key in content:
content = content.replace(key, value["text"])
for key, value in self.sorted_vnrshareddict:
if key in content:
# print(key)
# if self.vnrshareddict[key]['src']==self.vnrshareddict[key]['tgt']:
# content=content.replace(key,self.vnrshareddict[key]['text'])
# else:
xx = "{{{}}}".format(gobject.baseobject.zhanweifu)
content = content.replace(key, xx)
context[xx] = key
gobject.baseobject.zhanweifu += 1
return content, context
def process_after(self, res, context):
for key in context:
reg = re.compile(re.escape(key), re.IGNORECASE)
res = reg.sub(self.vnrshareddict[context[key]]["text"], res)
for key, value in self.sorted_vnrshareddict_post:
if key in res:
res = res.replace(key, value["text"])
return res

View File

@ -0,0 +1,48 @@
from myutils.config import noundictconfig
import gobject, re
class Process:
@property
def using(self):
return noundictconfig["use"]
def process_before(self, content):
mp1 = {}
for key in noundictconfig["dict"]:
usedict = False
if type(noundictconfig["dict"][key]) == str:
usedict = True
else:
for i in range(len(noundictconfig["dict"][key]) // 2):
if noundictconfig["dict"][key][i * 2] in [
"0",
gobject.baseobject.currentmd5,
]:
usedict = True
break
if usedict and key in content:
xx = "{{{}}}".format(gobject.baseobject.zhanweifu)
content = content.replace(key, xx)
mp1[xx] = key
gobject.baseobject.zhanweifu += 1
return content, mp1
def process_after(self, res, mp1):
for key in mp1:
reg = re.compile(re.escape(key), re.IGNORECASE)
if type(noundictconfig["dict"][mp1[key]]) == str:
v = noundictconfig["dict"][mp1[key]]
elif type(noundictconfig["dict"][mp1[key]]) == list:
v = ""
for i in range(len(noundictconfig["dict"][mp1[key]]) // 2):
if noundictconfig["dict"][mp1[key]][i * 2] in [
"0",
gobject.baseobject.currentmd5,
]:
v = noundictconfig["dict"][mp1[key]][i * 2 + 1]
break
res = reg.sub(v, res)
return res

View File

@ -0,0 +1,16 @@
from myutils.config import transerrorfixdictconfig
from myutils.utils import parsemayberegexreplace
class Process:
@property
def using(self):
return transerrorfixdictconfig["use"]
def process_before(self, content):
return content, {}
def process_after(self, res, mp1):
res = parsemayberegexreplace(transerrorfixdictconfig["dict_v2"], res)
return res

View File

@ -123,6 +123,7 @@
"localeswitchmethod": 0, "localeswitchmethod": 0,
"hide_not_exists":false, "hide_not_exists":false,
"startgamenototop":true, "startgamenototop":true,
"selfdefinedprocesspair":false,
"extra_space":0, "extra_space":0,
"fonttype": "Arial", "fonttype": "Arial",
"fonttype2": "Arial", "fonttype2": "Arial",
@ -1122,6 +1123,12 @@
"name": "ChatGPT", "name": "ChatGPT",
"is_gpt_like":true "is_gpt_like":true
}, },
"cohere": {
"type": "api",
"use": false,
"color": "blue",
"name": "cohere"
},
"claude": { "claude": {
"type": "api", "type": "api",
"use": false, "use": false,

View File

@ -1,5 +1,5 @@
{ {
"version":"v2.45.4", "version":"v2.45.5",
"themes":{ "themes":{
"dark":[ "dark":[
{"file":"dark1.qss","name":"PyQtDarkTheme"}, {"file":"dark1.qss","name":"PyQtDarkTheme"},

View File

@ -334,6 +334,42 @@
} }
} }
}, },
"cohere": {
"args": {
"SECRET_KEY": "",
"Temperature": 0.3,
"model":"command-r",
"附带上下文个数":0,
"使用自定义promt":false,
"自定义promt":"",
"流式输出":false
}
,
"argstype":{
"流式输出":{
"type": "switch"
},
"使用自定义promt":{
"type":"switch"
},
"附带上下文个数":{
"type":"intspin",
"min":0,
"max":10,
"step":1
},
"使用说明":{
"type":"label",
"islink":false
},
"Temperature":{
"type":"spin",
"min":0,
"max":1,
"step":0.1
}
}
},
"jb7": { "jb7": {
"args": { "args": {
"路径": "", "路径": "",

View File

@ -763,5 +763,6 @@
"备份到": "النسخ الاحتياطي", "备份到": "النسخ الاحتياطي",
"左移": "تحول اليسار", "左移": "تحول اليسار",
"右移": "حق التحول", "右移": "حق التحول",
"启动游戏不修改顺序": "بدء اللعبة دون تعديل النظام" "启动游戏不修改顺序": "بدء اللعبة دون تعديل النظام",
"使用自定义优化": "استخدام التخصيص الأمثل"
} }

View File

@ -763,5 +763,6 @@
"备份到": "備份到", "备份到": "備份到",
"左移": "左移", "左移": "左移",
"右移": "右移", "右移": "右移",
"启动游戏不修改顺序": "啟動遊戲不修改順序" "启动游戏不修改顺序": "啟動遊戲不修改順序",
"使用自定义优化": "使用自定義優化"
} }

View File

@ -763,5 +763,6 @@
"备份到": "Back up to", "备份到": "Back up to",
"左移": "Left shift", "左移": "Left shift",
"右移": "Right shift", "右移": "Right shift",
"启动游戏不修改顺序": "Start the game without changing the order" "启动游戏不修改顺序": "Start the game without changing the order",
"使用自定义优化": "Use custom optimization"
} }

View File

@ -763,5 +763,6 @@
"备份到": "Copia de Seguridad a", "备份到": "Copia de Seguridad a",
"左移": "Desplazamiento a la izquierda", "左移": "Desplazamiento a la izquierda",
"右移": "A la derecha", "右移": "A la derecha",
"启动游戏不修改顺序": "Iniciar el juego sin modificar el orden" "启动游戏不修改顺序": "Iniciar el juego sin modificar el orden",
"使用自定义优化": "Usar optimizaciones personalizadas"
} }

View File

@ -763,5 +763,6 @@
"备份到": "Sauvegarder à", "备份到": "Sauvegarder à",
"左移": "Déplacement à gauche", "左移": "Déplacement à gauche",
"右移": "Déplacement à droite", "右移": "Déplacement à droite",
"启动游戏不修改顺序": "Lancer le jeu sans modifier l'ordre" "启动游戏不修改顺序": "Lancer le jeu sans modifier l'ordre",
"使用自定义优化": "Utiliser l'optimisation personnalisée"
} }

View File

@ -763,5 +763,6 @@
"备份到": "Torna a", "备份到": "Torna a",
"左移": "Spostamento sinistro", "左移": "Spostamento sinistro",
"右移": "Spostamento destro", "右移": "Spostamento destro",
"启动游戏不修改顺序": "Inizia il gioco senza cambiare l'ordine" "启动游戏不修改顺序": "Inizia il gioco senza cambiare l'ordine",
"使用自定义优化": "Usa ottimizzazione personalizzata"
} }

View File

@ -763,5 +763,6 @@
"备份到": "バックアップ先", "备份到": "バックアップ先",
"左移": "左へ移動", "左移": "左へ移動",
"右移": "右へ移動", "右移": "右へ移動",
"启动游戏不修改顺序": "ゲームを起動しても順序は変更されません" "启动游戏不修改顺序": "ゲームを起動しても順序は変更されません",
"使用自定义优化": "カスタム最適化の使用"
} }

View File

@ -763,5 +763,6 @@
"备份到": "백업 대상", "备份到": "백업 대상",
"左移": "왼쪽 이동", "左移": "왼쪽 이동",
"右移": "오른쪽 이동", "右移": "오른쪽 이동",
"启动游戏不修改顺序": "게임을 시작하면 순서를 수정하지 않습니다." "启动游戏不修改顺序": "게임을 시작하면 순서를 수정하지 않습니다.",
"使用自定义优化": "사용자 정의 최적화 사용"
} }

View File

@ -763,5 +763,6 @@
"备份到": "Powrót do", "备份到": "Powrót do",
"左移": "Przesunięcie w lewo", "左移": "Przesunięcie w lewo",
"右移": "Prawa zmiana", "右移": "Prawa zmiana",
"启动游戏不修改顺序": "Rozpocznij grę bez zmiany kolejności" "启动游戏不修改顺序": "Rozpocznij grę bez zmiany kolejności",
"使用自定义优化": "Użyj niestandardowej optymalizacji"
} }

View File

@ -763,5 +763,6 @@
"备份到": "Резервное копирование", "备份到": "Резервное копирование",
"左移": "Переместить налево", "左移": "Переместить налево",
"右移": "Направо.", "右移": "Направо.",
"启动游戏不修改顺序": "Запустить игру без изменения порядка" "启动游戏不修改顺序": "Запустить игру без изменения порядка",
"使用自定义优化": "Использовать пользовательскую оптимизацию"
} }

View File

@ -763,5 +763,6 @@
"备份到": "สำรองข้อมูลไปยัง", "备份到": "สำรองข้อมูลไปยัง",
"左移": "เลื่อนซ้าย", "左移": "เลื่อนซ้าย",
"右移": "ย้ายขวา", "右移": "ย้ายขวา",
"启动游戏不修改顺序": "เริ่มเกมโดยไม่มีการปรับเปลี่ยนลำดับ" "启动游戏不修改顺序": "เริ่มเกมโดยไม่มีการปรับเปลี่ยนลำดับ",
"使用自定义优化": "ใช้การปรับแต่งให้เหมาะสม"
} }

View File

@ -763,5 +763,6 @@
"备份到": "Geri dön.", "备份到": "Geri dön.",
"左移": "Sol vardiyası", "左移": "Sol vardiyası",
"右移": "Sağ değişiklik", "右移": "Sağ değişiklik",
"启动游戏不修改顺序": "Düzeni değiştirmeden oyunu başlat" "启动游戏不修改顺序": "Düzeni değiştirmeden oyunu başlat",
"使用自定义优化": "Özel optimizasyon kullan"
} }

View File

@ -763,5 +763,6 @@
"备份到": "Назад до", "备份到": "Назад до",
"左移": "Ліва зміна", "左移": "Ліва зміна",
"右移": "Права зміна", "右移": "Права зміна",
"启动游戏不修改顺序": "Почати гру без зміни порядку" "启动游戏不修改顺序": "Почати гру без зміни порядку",
"使用自定义优化": "Використовувати нетипову оптимізацію"
} }

View File

@ -763,5 +763,6 @@
"备份到": "Sao lưu vào", "备份到": "Sao lưu vào",
"左移": "Dịch trái", "左移": "Dịch trái",
"右移": "Dịch phải", "右移": "Dịch phải",
"启动游戏不修改顺序": "Bắt đầu trò chơi Không thay đổi thứ tự" "启动游戏不修改顺序": "Bắt đầu trò chơi Không thay đổi thứ tự",
"使用自定义优化": "Sử dụng Custom Optimization"
} }

View File

@ -763,5 +763,6 @@
"备份到": "", "备份到": "",
"左移": "", "左移": "",
"右移": "", "右移": "",
"启动游戏不修改顺序": "" "启动游戏不修改顺序": "",
"使用自定义优化": ""
} }

View File

@ -35,7 +35,7 @@ for f in ['LunaTranslator_admin.exe','LunaTranslator.exe']:
shutil.copytree(r'.\files',rf'{targetdir}\files') shutil.copytree(r'.\files',rf'{targetdir}\files')
shutil.copy(r'..\LICENSE',targetdir) shutil.copy(r'..\LICENSE',targetdir)
for f in ['hiraparse','ocrengines','translator','cishu','tts','network','textoutput']: for f in ['transoptimi','hiraparse','ocrengines','translator','cishu','tts','network','textoutput']:
shutil.copytree(rf'.\LunaTranslator\{f}',rf'{targetdir_in}\{f}') shutil.copytree(rf'.\LunaTranslator\{f}',rf'{targetdir_in}\{f}')
def remove(f): def remove(f):