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
from myutils.utils import (
minmaxmoveobservefunc,
parsemayberegexreplace,
kanjitrans,
checkifnewgame,
getfilemd5,
stringfyerror,
)
from myutils.wrapper import threader
@ -41,7 +43,6 @@ import windows
import re, gobject
import winsharedutils
from myutils.post import POSTSOLVE
from myutils.vnrshareddict import vnrshareddict
from gui.usefulwidget import Prompt, getQMessageBox
@ -70,6 +71,8 @@ class MAINUI:
self.isrunning = True
self.solvegottextlock = threading.Lock()
self.outputers = {}
self.processmethods = []
self.zhanweifu = 0
@property
def textsource(self):
@ -87,93 +90,47 @@ class MAINUI:
self.currentmd5 = "0" if _ is None else _.md5
@threader
def loadvnrshareddict(self, _=None):
vnrshareddict(self)
def safeloadprocessmodels(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):
zhanweifu = 0
mp1 = {}
mp2 = {}
mp3 = {}
if noundictconfig["use"]:
for key in noundictconfig["dict"]:
usedict = False
if type(noundictconfig["dict"][key]) == str:
usedict = True
contexts = []
for i in range(len(self.processmethods)):
try:
if self.processmethods[i].using:
content, context = self.processmethods[i].process_before(content)
else:
for i in range(len(noundictconfig["dict"][key]) // 2):
if noundictconfig["dict"][key][i * 2] in ["0", self.currentmd5]:
usedict = True
break
if usedict and key in content:
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
context = None
except:
context = None
print_exc()
contexts.append(context)
return content, contexts
def solveaftertrans(self, res, mp):
mp1, mp2, mp3 = mp
# print(res,mp)#hello
if noundictconfig["use"]:
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",
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)
for i in range(len(self.processmethods)):
context = mp[i]
try:
if self.processmethods[i].using:
res = self.processmethods[i].process_after(res, context)
except:
print_exc()
return res
def _POSTSOLVE(self, s):
@ -447,7 +404,7 @@ class MAINUI:
def ttsrepair(self, text, usedict):
if usedict["tts_repair"]:
text = self.parsemayberegexreplace(usedict["tts_repair_regex"], text)
text = parsemayberegexreplace(usedict["tts_repair_regex"], text)
return text
def readcurrent(self, force=False):
@ -826,7 +783,7 @@ class MAINUI:
gobject.overridestdio()
self.loadvnrshareddict()
self.safeloadprocessmodels()
self.prepare()
self.startxiaoxueguan()
self.starthira()

View File

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

View File

@ -254,7 +254,6 @@ def setTab7_lazy(self):
getsimpleswitch(
globalconfig["gongxiangcishu"],
"use",
callback=gobject.baseobject.loadvnrshareddict,
),
getcolorbutton(
globalconfig,
@ -265,7 +264,7 @@ def setTab7_lazy(self):
globalconfig["gongxiangcishu"],
"path",
"共享辞书",
gobject.baseobject.loadvnrshareddict,
None,
False,
"*.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
grids2 += [

View File

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

View File

@ -311,14 +311,32 @@ from translator.basetranslator import basetrans
class TS(basetrans):
def translate(self,content):
#在这里编写
return content"""
return content
"""
)
elif path == "./userconfig/mypost.py":
ff.write(
"""
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)
return p
@ -407,9 +425,14 @@ def minmaxmoveobservefunc(self):
if globalconfig["keepontop"] and globalconfig["focusnotop"]:
if _focusp == os.getpid():
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()
else:
gobject.baseobject.translation_ui.thistimenotsetop = True
gobject.baseobject.translation_ui.canceltop()
if _focusp != windows.GetWindowThreadProcessId(
gobject.baseobject.textsource.hwnd
@ -483,3 +506,16 @@ class autosql(sqlite3.Connection):
def __del__(self):
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
import xml.etree.ElementTree as ET
import os
import os, gobject, re
def vnrshareddict(self):
@ -84,3 +84,53 @@ def vnrshareddict(self):
self.sorted_vnrshareddict_post = [
(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,
"hide_not_exists":false,
"startgamenototop":true,
"selfdefinedprocesspair":false,
"extra_space":0,
"fonttype": "Arial",
"fonttype2": "Arial",
@ -1122,6 +1123,12 @@
"name": "ChatGPT",
"is_gpt_like":true
},
"cohere": {
"type": "api",
"use": false,
"color": "blue",
"name": "cohere"
},
"claude": {
"type": "api",
"use": false,

View File

@ -1,5 +1,5 @@
{
"version":"v2.45.4",
"version":"v2.45.5",
"themes":{
"dark":[
{"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": {
"args": {
"路径": "",

View File

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

View File

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

View File

@ -763,5 +763,6 @@
"备份到": "Back up to",
"左移": "Left 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",
"左移": "Desplazamiento a la izquierda",
"右移": "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 à",
"左移": "Déplacement à gauche",
"右移": "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",
"左移": "Spostamento sinistro",
"右移": "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",
"左移": "Przesunięcie w lewo",
"右移": "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.",
"左移": "Sol vardiyası",
"右移": "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",
"左移": "Dịch trá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.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}')
def remove(f):