diff --git a/.gitignore b/.gitignore
index 22ff604d4..c8e14cbdb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -24,6 +24,8 @@
!ui.png
!window.py
!window.spec
+!i18n.pro
+!requirements-i18n.txt
src/explore_task_data/__pycache__/normal_task_11.cpython-39.pyc
*.pyc
*.xml
diff --git a/core/picture.py b/core/picture.py
index aa79c7497..ed9c56add 100644
--- a/core/picture.py
+++ b/core/picture.py
@@ -1,6 +1,6 @@
import time
from core import color, image
-
+from module.main_story import change_acc_auto
def co_detect(self, rgb_ends=None, rgb_possibles=None, img_ends=None, img_possibles=None, skip_first_screenshot=False,
tentitive_click=False, tentitivex=1238, tentitivey=45, max_fail_cnt=10, rgb_pop_ups=None,
@@ -118,6 +118,8 @@ def deal_with_pop_ups(self, rgb_pop_ups, img_pop_ups):
if color.judgeRGBFeature(self, position):
self.logger.info("find : " + position)
if position == "fighting_feature":
+ self.logger.info("Enter fight, wait fight auto end")
+ change_acc_auto(self)
img_possibles = {
"normal_task_mission-operating-task-info-notice": (995, 101),
"normal_task_end-turn": (890, 162),
diff --git a/develop_tools/auto_translate.py b/develop_tools/auto_translate.py
new file mode 100644
index 000000000..8882f9fe3
--- /dev/null
+++ b/develop_tools/auto_translate.py
@@ -0,0 +1,175 @@
+import os
+import subprocess
+import translators as ts
+
+from bs4 import BeautifulSoup
+from lxml import etree
+from gui.util.language import Language
+
+
+class Handler:
+ def set_next(self, request):
+ request.handlers.pop(0)
+ if request.handlers:
+ request.handlers[0].handle(request)
+
+ def handle(self, request):
+ pass
+
+
+class Request:
+ def __init__(self, handlers: list[Handler],
+ qt_language: Language,
+ translator: str = 'bing',
+ from_lang: str = 'auto',
+ to_lang: str = 'en'):
+ """
+ Parameters
+ ----------
+ handlers: list[Handler]
+ a list of handlers that represent the files to translate.
+
+ qt_language: Language
+ the memeber of the enum Language to translate
+
+ translator: str
+ see https://github.com/uliontse/translators
+
+ from_lang: str
+ see https://github.com/uliontse/translators
+
+ to_lang: str
+ see https://github.com/uliontse/translators
+ """
+ self.qt_language = qt_language
+ self.strLang = qt_language.value.name()
+ self.handlers = handlers
+ self.translator = translator
+ self.from_lang = from_lang
+ self.to_lang = to_lang
+
+ def translate_text(self, text):
+ text = ts.translate_text(text, self.translator, self.from_lang, self.to_lang)
+ print(text)
+ return text
+
+ def translate_html(self, html_text):
+ return ts.translate_html(html_text, self.translator, self.from_lang, self.to_lang)
+
+ def process(self):
+ self.handlers[0].handle(self)
+
+
+class Pylupdate5Handler(Handler):
+ def handle(self, request):
+ result = subprocess.run(['pylupdate5', 'i18n.pro'], capture_output=True, text=True)
+ print(result.stdout)
+ self.set_next(request)
+
+
+class XmlHandler(Handler):
+ """Translate ts files"""
+ def handle(self, request):
+ # Load the XML from a file
+ input_file = os.path.join('../gui/i18n/', f'{request.strLang}.ts')
+ output_file = os.path.join('../gui/i18n/', f'{request.strLang}.ts')
+
+ tree = etree.parse(input_file)
+ root = tree.getroot()
+
+ # Find all 'source' tags and translate their text
+ for source in root.iter('source'):
+
+ # Find the 'translation' tag within the parent 'message' tag
+ translation = source.getparent().find('translation')
+
+ # Check the 'type' attribute of the 'translation' tag
+ if 'type' in translation.attrib:
+ if translation.attrib['type'] == 'obsolete':
+ # Delete the parent 'message' tag if 'type' is 'obsolete'
+ source.getparent().getparent().remove(source.getparent())
+ elif translation.attrib['type'] == 'unfinished' and not translation.text:
+ # Update the 'translation' tag if 'type' is not 'obsolete'
+ translation.text = request.translate_text(source.text)
+ else:
+ # Don't update the 'translation' tag if 'type' attribute doesn't exist
+ continue
+
+ # Write the updated XML back to the file
+ tree.write(output_file, encoding='utf8')
+ self.set_next(request)
+
+
+class HtmlHandler(Handler):
+ """Generate descriptions"""
+ def translate_mission_types(self, request, input_dir, output_dir):
+ input_path = os.path.join(input_dir, '各区域所需队伍属性.html')
+ output_path = os.path.join(output_dir, request.translate_text('各区域所需队伍属性') + '.html')
+
+ translations = {
+ '爆发': 'Explosive',
+ '贯穿': 'Piercing',
+ '神秘': 'Mystic',
+ '振动': 'Sonic'
+ }
+
+ with open(input_path, 'r') as f:
+ text = f.read()
+
+ for original, translated in translations.items():
+ text = text.replace(original, translated)
+
+ with open(output_path, 'w') as f:
+ f.write(text)
+
+ def handle(self, request):
+ input_dir = '../src/descriptions/'
+ output_dir = f'src/descriptions/{request.strLang}'
+ # Ensure the output directory exists
+ if not os.path.exists(output_dir):
+ os.makedirs(output_dir)
+
+ # Iterate over all files in the input directory
+ for filename in os.listdir(input_dir):
+ if request.strLang == 'en_us' and filename == '各区域所需队伍属性.html':
+ self.translate_mission_types(request, input_dir, output_dir)
+ continue
+
+ if filename.endswith('.html'):
+ # Parse the HTML file with BeautifulSoup
+ with open(os.path.join(input_dir, filename), 'r') as f:
+ html = f.read()
+ translated_html = request.translate_html(html)
+ soup = BeautifulSoup(translated_html, 'lxml')
+ prettyHTML = soup.prettify()
+
+ # Write the translated HTML to the output directory
+ name, extension = os.path.splitext(filename)
+ output_name = f'{request.translate_text(name)}.html'
+ with open(os.path.join(output_dir, output_name), 'w') as f:
+ f.write(prettyHTML)
+
+
+class LreleaseHandler(Handler):
+ def handle(self, request):
+ directory = os.path.join(os.getcwd(), '../gui', 'i18n')
+ result = subprocess.run(['lrelease', f'{request.strLang}.ts'], cwd=directory, capture_output=True, text=True)
+ print(result.stdout)
+ self.set_next(request)
+
+
+if __name__ == "__main__":
+ pylupdate = Pylupdate5Handler()
+ gui = XmlHandler()
+ descriptions = HtmlHandler()
+ lrelease = LreleaseHandler()
+
+ # request_en = Request([pylupdate, gui, descriptions, lrelease], Language.ENGLISH, 'bing', 'zh-Hans', 'en')
+ # request_en.process()
+
+ request_en = Request([pylupdate, gui, lrelease], Language.ENGLISH, 'bing', 'zh-Hans', 'en')
+ request_en.process()
+
+ request_jp = Request([gui], Language.JAPANESE, 'bing', 'zh-Hans', 'ja')
+ request_jp.process()
+
diff --git a/develop_tools/explore_task_data_generator.py b/develop_tools/explore_task_data_generator.py
index 09ed2a488..564f4d850 100644
--- a/develop_tools/explore_task_data_generator.py
+++ b/develop_tools/explore_task_data_generator.py
@@ -1,5 +1,5 @@
# this script is used to generate explore task data which can be used
-# in function common_gird_method in module.explore_normal_task, the function is under this line
+# in function common_gird_method which is under this line in module.explore_normal_task
from module.explore_normal_task import common_gird_method
diff --git a/docs/i18n.md b/docs/i18n.md
new file mode 100644
index 000000000..a2c04c8b1
--- /dev/null
+++ b/docs/i18n.md
@@ -0,0 +1,184 @@
+# i18n Guide
+
+## Requirements
+
+- [Qt Linguist](https://github.com/thurask/Qt-Linguist/releases)
+- [OPTIONAL]
+```
+pip install -r requirements-i18n.txt
+```
+
+## Translation
+
+### Adding a New Language
+To include a new language, add a new member to the Language enum representing the language with its corresponding QLocale object. Then, update the combobox method to return a list of language names based on the enum members order. For example, to add Japanese:
+```
+class Language(Enum):
+ """ Language enumeration """
+
+ CHINESE_SIMPLIFIED = QLocale(QLocale.Chinese, QLocale.China)
+ ENGLISH = QLocale(QLocale.English, QLocale.UnitedStates)
+ JAPANESE = QLocale(QLocale.Japanese, QLocale.Japan)
+
+ def combobox():
+ return ['简体中文', 'English', '日本語']
+```
+
+Run the Python file; it will print the language acronym:
+
+```
+ja_JP
+```
+
+Open `i18n.pro` and modify the `TRANSLATION` variable by appending `gui/i18n/` + acronym:
+
+```pro
+TRANSLATIONS += gui/i18n/en_US.ts \
+ gui/i18n/ja_JP.ts \
+```
+
+Execute the following command to generate `.ts` files:
+
+```
+pylupdate5 i18n.pro
+```
+
+OPTIONAL: `auto_translate.py`
+
+Utilize `argostranslate` to accelerate translations after installing the necessary packages from `requirements-i18n.txt`. Note that while translations may not be perfect, they can speed up the process.
+
+Simply create a new `Request` instance at the end of `auto_translate.py` and invoke its `process` method.
+
+The `Request` constructor is as follows:
+
+```python
+class Request:
+ from_code = "zh"
+
+ def __init__(self, handlers: list[Handler], language: Language, argos_model: str):
+ """
+ Parameters
+ ----------
+ handlers: list[Handler]
+ a list of handlers that represent the files to translate.
+
+ language: Language
+ the memeber of the enum Language to translate
+
+ argos_model: str
+ The argos model to load for translation
+ """
+```
+
+Then:
+
+```python
+model = ModelHandler()
+ts = XmlHandler()
+descriptions = HtmlHandler()
+
+request_jp = Request([model, ts, descriptions], Language.JAPANESE, 'ja')
+request_jp.process()
+```
+
+This means that `.ts` and description files will be generated. You can adjust the list of handlers as needed, but `model` must always be the first element.
+
+Also, in case no model exists for your language, you could create a new subclass of Request, override its translate method to use another Python library, and omit ModelHandler from the list of handlers.
+
+Open `Qt Linguist`, load the `.ts` file, and manually translate. This step will require some time.
+
+Afterward, navigate to `gui/i18n` and execute the following command:
+
+```
+lrelease ja_JP.ts
+```
+
+This will produce the `.qm` files.
+
+## `baasTranslator`
+
+### Problems
+In normal scenarios, the `tr` method of `QObject` is used for translation, inherited by most PyQt5 classes. However, this approach isn't always possible for `baas` due to:
+
+- Widget text being generated from JSON files
+- Need to retain user input (e.g., combobox selections) in Chinese within config files
+
+### Solution
+To address this:
+
+- `ConfigTranslation`: a `QObject` subclass with a dictionary attribute mapping text enclosed in `self.tr` to itself:
+
+```python
+...
+self.entries = {
+ # display
+ self.tr("每日特别委托"): "每日特别委托",
+...
+```
+
+- Utilize a specific instance of `QTranslator` named `baasTranslator` from `gui/util/translator.py` as `bt`, employing its methods:
+
+ - `tr(context, sourceText)`
+ - `undo(text)`
+
+For instance, `bt.tr('ConfigTranslation', '国际服')` will produce its translation, 'Global', and `bt.undo('Global')` will revert it to '国际服'. This functionality is already implemented in `get` and `set` method of `ConfigSet`.
+
+In essence, `tr` accesses the `.qm` file to retrieve translations based on the `ConfigTranslation` context, while `undo` retrieves the value from the mapped dictionary where the translation was stored.
+
+Note that contexts other than `'ConfigTranslation'` are accessible. For example:
+
+```python
+class Layout(TemplateLayout):
+ def __init__(self, parent=None, config=None):
+ configItems = [
+ {
+ 'label': '一键反和谐',
+ 'type': 'button',
+ 'selection': self.fhx,
+ 'key': None
+ },
+...
+ super().__init__(parent=parent, configItems=configItems, config=config)
+```
+
+Suppose you want to translate the `label` and `selection` but can't access the `tr` method directly since you must first invoke the parent constructor and wish to avoid extensive modifications. Here's a solution:
+
+```python
+class Layout(TemplateLayout):
+ def __init__(self, parent=None, config=None):
+ OtherConfig = QObject()
+ configItems = [
+ {
+ 'label': OtherConfig.tr('一键反和谐'),
+ 'type': 'button',
+ 'selection': self.fhx,
+ 'key': None
+ },
+...
+ super().__init__(parent=parent, configItems=configItems, config=config, context="OtherConfig")
+```
+
+1. Add a new `context` parameter to the `TemplateLayout` constructor.
+2. Create an instance of `QObject` named `OtherConfig`. This establishes a new context when generating the `.ts` files, allowing you to pass `'OtherConfig'` to the `TemplateLayout` constructor.
+
+Now, accessing translations in `TemplateLayout` becomes straightforward:
+
+```python
+class TemplateLayout(QWidget):
+ patch_signal = pyqtSignal(str)
+
+ def __init__(self, configItems: Union[list[ConfigItem], list[dict]], parent=None, config=None, context=None):
+...
+ labelComponent = QLabel(bt.tr(context, cfg.label), self)
+```
+
+## Adding new GUI .py files
+Please ensure to include the file path of the new GUI .py files into the `i18n.pro` file's `SOURCES` variable, taking care to use the correct slashes. For instance, if you're adding `table.py` located in `gui/components`, it should be appended like this:
+
+```
+SOURCES += \
+ gui/components/table.py \
+```
+
+## Adding new Config value
+When adding a new config value that appears on the GUI and needs translation, update the `ConfigTranslation` dictionary by adding a new key-value pair. For comboboxes, make sure to include all options.
diff --git a/gui/components/dialog_panel.py b/gui/components/dialog_panel.py
index 97e28a6e3..55c8bfd54 100644
--- a/gui/components/dialog_panel.py
+++ b/gui/components/dialog_panel.py
@@ -7,10 +7,10 @@ class SaveSettingMessageBox(MessageBoxBase):
def __init__(self, parent=None):
super().__init__(parent)
- self.titleLabel = SubtitleLabel('新建配置', self)
+ self.titleLabel = SubtitleLabel(self.tr('新建配置'), self)
self.pathLineEdit = LineEdit(self)
- self.pathLineEdit.setPlaceholderText('输入新建的配置名:')
+ self.pathLineEdit.setPlaceholderText(self.tr('输入新建的配置名:'))
self.pathLineEdit.setClearButtonEnabled(True)
# add widget to view layout
@@ -18,8 +18,8 @@ def __init__(self, parent=None):
self.viewLayout.addWidget(self.pathLineEdit)
# change the text of button
- self.yesButton.setText('确定')
- self.cancelButton.setText('取消')
+ self.yesButton.setText(self.tr('确定'))
+ self.cancelButton.setText(self.tr('取消'))
self.widget.setMinimumWidth(350)
self.yesButton.setDisabled(True)
diff --git a/gui/components/expand/arenaPriority.py b/gui/components/expand/arenaPriority.py
index b7558ec76..77af2b35a 100644
--- a/gui/components/expand/arenaPriority.py
+++ b/gui/components/expand/arenaPriority.py
@@ -15,12 +15,12 @@ def __init__(self, parent=None, config=None):
self.hBoxLayout = QVBoxLayout(self)
self.lay_1 = QHBoxLayout(self)
self.lay_2 = QHBoxLayout(self)
- self.label_1 = QLabel('输入你需要对手比你低几级,高几级则填负数:', self)
- self.label_2 = QLabel('输入你最多需要刷新几次:', self)
+ self.label_1 = QLabel(self.tr('输入你需要对手比你低几级,高几级则填负数:'), self)
+ self.label_2 = QLabel(self.tr('输入你最多需要刷新几次:'), self)
self.input_1 = LineEdit(self)
self.input_2 = LineEdit(self)
- self.accept_1 = QPushButton('确定', self)
- self.accept_2 = QPushButton('确定', self)
+ self.accept_1 = QPushButton(self.tr('确定'), self)
+ self.accept_2 = QPushButton(self.tr('确定'), self)
self.level_diff = self.config.get('ArenaLevelDiff')
validator_1 = QIntValidator(-50, 50)
@@ -54,9 +54,9 @@ def __init__(self, parent=None, config=None):
def __accept_1(self):
self.level_diff = int(self.input_1.text())
self.config.set('ArenaLevelDiff', self.level_diff)
- notification.success('设置成功', f'你需要对手比你低{self.level_diff}级', self.config)
+ notification.success(self.tr('设置成功'), f'{self.tr("你需要对手比你低")}{self.level_diff}{"级"}', self.config)
def __accept_2(self, _=None):
self.refresh_times = int(self.input_2.text())
self.config.set('maxArenaRefreshTimes', self.refresh_times)
- notification.success('设置成功', f'你最大刷新次数设置为:{self.refresh_times}', self.config)
+ notification.success(self.tr('设置成功'), f'{self.tr("你最大刷新次数设置为:")}{self.refresh_times}', self.config)
diff --git a/gui/components/expand/arenaShopPriority.py b/gui/components/expand/arenaShopPriority.py
index 00ae9fa87..3b82148cc 100644
--- a/gui/components/expand/arenaShopPriority.py
+++ b/gui/components/expand/arenaShopPriority.py
@@ -2,6 +2,8 @@
from PyQt5.QtWidgets import QWidget, QLabel, QPushButton, QHBoxLayout, QVBoxLayout
from qfluentwidgets import FlowLayout, CheckBox, LineEdit
+from gui.util.translator import baasTranslator as bt
+
class Layout(QWidget):
def __init__(self, parent=None, config=None):
@@ -18,17 +20,17 @@ def __init__(self, parent=None, config=None):
self.setFixedHeight(400)
self.setStyleSheet('Demo{background: white} QPushButton{padding: 5px 10px; font:15px "Microsoft YaHei"}')
- self.label = QLabel('刷新次数', self)
+ self.label = QLabel(self.tr('刷新次数'), self)
self.input = LineEdit(self)
self.input.setValidator(QIntValidator(0, 3))
self.input.setText(self.config.get('TacticalChallengeShopRefreshTime'))
- self.accept = QPushButton('确定', self)
+ self.accept = QPushButton(self.tr('确定'), self)
self.boxes = []
for i in range(0, goods_count):
t_cbx = CheckBox(self)
t_cbx.setChecked(self.goods[i] == 1)
- ccs = QLabel(self.default_goods[i][0], self)
+ ccs = QLabel(bt.tr('ConfigTranslation', self.default_goods[i][0]), self)
ccs.setFixedWidth(110)
price_text = str(self.default_goods[i][1])
price_label = QLabel(price_text, self)
diff --git a/gui/components/expand/cafeInvite.py b/gui/components/expand/cafeInvite.py
index b0ff46fe5..e8f8cd2bb 100644
--- a/gui/components/expand/cafeInvite.py
+++ b/gui/components/expand/cafeInvite.py
@@ -2,6 +2,8 @@
from PyQt5.QtWidgets import QWidget, QLabel, QHBoxLayout, QVBoxLayout, QPushButton
from qfluentwidgets import ComboBox, LineEdit, CheckBox
+from gui.util.translator import baasTranslator as bt
+
class Layout(QWidget):
def __init__(self, parent=None, config=None):
@@ -16,35 +18,41 @@ def __init__(self, parent=None, config=None):
self.lay3_ = QHBoxLayout(self) # 第二咖啡厅邀请学生名字
self.lay6 = QHBoxLayout(self) # 是否有二号咖啡厅
- self.layCollectReward = self.labeledCheckBoxTemplate('是否领取奖励:', 'cafe_reward_collect_hour_reward')
- self.layUseInvitationTicket = self.labeledCheckBoxTemplate('是否使用邀请券:', 'cafe_reward_use_invitation_ticket')
- self.layInviteLowestAffection = self.labeledCheckBoxTemplate('优先邀请券好感等级低的学生:', 'cafe_reward_lowest_affection_first')
- self.layEnableExchangeStudent = self.labeledCheckBoxTemplate('是否允许学生更换服饰:', 'cafe_reward_allow_exchange_student')
-
+ self.layCollectReward = self.labeledCheckBoxTemplate(self.tr('是否领取奖励:'), 'cafe_reward_collect_hour_reward')
+ self.layUseInvitationTicket = self.labeledCheckBoxTemplate(self.tr('是否使用邀请券:'), 'cafe_reward_use_invitation_ticket')
+ self.layInviteLowestAffection = self.labeledCheckBoxTemplate(self.tr('优先邀请券好感等级低的学生:'), 'cafe_reward_lowest_affection_first')
+ self.layEnableExchangeStudent = self.labeledCheckBoxTemplate(self.tr('是否允许学生更换服饰:'), 'cafe_reward_allow_exchange_student')
if self.config.server_mode == 'JP' or self.config.server_mode == 'Global':
-
- self.label_3 = QLabel('是否有二号咖啡厅:', self)
+ self.label_3 = QLabel(self.tr('是否有二号咖啡厅:'), self)
self.second_switch = CheckBox(self)
self.second_switch.setChecked(self.config.get('cafe_reward_has_no2_cafe'))
self.lay6.addWidget(self.label_3, 1, Qt.AlignLeft)
self.lay6.addWidget(self.second_switch, 0, Qt.AlignRight)
- self.layEnableDuplicateInvite = self.labeledCheckBoxTemplate('是否允许重复邀请:', 'cafe_reward_allow_duplicate_invite')
+ self.layEnableDuplicateInvite = self.labeledCheckBoxTemplate(self.tr('是否允许重复邀请:'), 'cafe_reward_allow_duplicate_invite')
- self.pat_styles = ['拖动礼物']
+ # self.pat_styles = [self.tr('拖动礼物')]
+ self.pat_styles = [bt.tr('ConfigTranslation', '拖动礼物')]
self.student_name = []
- self.label1 = QLabel('列表选择你要添加邀请的学生,修改后请点击确定:', self)
+ self.label1 = QLabel(self.tr('列表选择你要添加邀请的学生,修改后请点击确定:'), self)
for i in range(0, len(self.config.static_config['student_names'])):
if self.config.static_config['student_names'][i][self.config.server_mode + '_implementation']:
self.student_name.append(
self.config.static_config['student_names'][i][self.config.server_mode + '_name'])
+
+ # Store student name for hard_task_combobox in mainlinePriority
+ if not bt.isChinese():
+ cn_name = self.config.static_config['student_names'][i]['CN_name']
+ tranlasted_name = self.student_name[-1]
+ bt.addStudent(cn_name, tranlasted_name)
+
self.input1 = ComboBox(self)
- self.input1.addItem("添加学生")
+ self.input1.addItem(self.tr("添加学生"))
self.input = LineEdit(self)
self.input.setFixedWidth(650)
- self.ac_btn = QPushButton('确定', self)
+ self.ac_btn = QPushButton(self.tr('确定'), self)
self.favor_student1 = self.config.get('favorStudent1')
self.input1.addItems(self.student_name)
@@ -52,10 +60,10 @@ def __init__(self, parent=None, config=None):
self.config.set('favorStudent1', self.favor_student1)
self.input.setText(','.join(self.favor_student1))
- self.label2 = QLabel('选择摸头方式:', self)
+ self.label2 = QLabel(self.tr('选择摸头方式:'), self)
self.input2 = ComboBox(self)
- self.pat_style = self.config.get('patStyle') or '普通'
+ self.pat_style = self.config.get('patStyle') or bt.tr('ConfigTranslation', '普通')
self.input2.addItems(self.pat_styles)
self.input2.setText(self.pat_style)
self.input2.setCurrentIndex(self.pat_styles.index(self.pat_style))
@@ -88,7 +96,7 @@ def __init__(self, parent=None, config=None):
self.__init_Signals_and_Slots()
def __add_student_name_in_the_last(self):
- if self.input1.currentText() == '添加学生':
+ if self.input1.currentText() == self.tr('添加学生'):
return
self.favor_student1.append(self.input1.currentText())
self.favor_student1 = self.check_valid_student_names()
@@ -96,7 +104,7 @@ def __add_student_name_in_the_last(self):
self.input.setText(','.join(self.favor_student1))
def __add_student_name_in_the_last_second(self):
- if self.input4.currentText() == '添加学生':
+ if self.input4.currentText() == self.tr('添加学生'):
return
self.favor_student2.append(self.input4.currentText())
self.favor_student2 = self.check_valid_student_names_()
@@ -167,12 +175,12 @@ def Slot_for_no_2_cafe_Checkbox(self, state):
sub_layout.removeItem(item)
def set_buttons_for_no2_cafe(self):
- self.label4 = QLabel('选择第二咖啡厅邀请的学生', self)
+ self.label4 = QLabel(self.tr('选择第二咖啡厅邀请的学生'), self)
self.input4 = ComboBox(self)
- self.input4.addItem("添加学生")
+ self.input4.addItem(self.tr("添加学生"))
self.input_ = LineEdit(self)
self.input_.setFixedWidth(650)
- self.ac_btn_ = QPushButton('确定', self)
+ self.ac_btn_ = QPushButton(self.tr('确定'), self)
self.favor_student2 = self.config.get('favorStudent2')
self.input4.addItems(self.student_name)
self.favor_student2 = self.check_valid_student_names_()
diff --git a/gui/components/expand/createPriority.py b/gui/components/expand/createPriority.py
index 46604b108..9dd225cd6 100644
--- a/gui/components/expand/createPriority.py
+++ b/gui/components/expand/createPriority.py
@@ -16,11 +16,11 @@ def __init__(self, parent=None, config=None):
self.lay3 = QHBoxLayout(self)
self.layout_for_acc_ticket = QHBoxLayout(self)
- self.label = QLabel('目前制造物品优先级,排在前面的会优先选择', self)
+ self.label = QLabel(self.tr('目前制造物品优先级,排在前面的会优先选择'), self)
self.input1 = QLabel(self)
self.input2 = LineEdit(self)
- self.accept = QPushButton('确定', self)
- self.label_for_use_acc_ticket_check_box = QLabel('是否使用加速券', self)
+ self.accept = QPushButton(self.tr('确定'), self)
+ self.label_for_use_acc_ticket_check_box = QLabel(self.tr('是否使用加速券'), self)
self.use_acc_ticket_checkbox = CheckBox(self)
self.use_acc_ticket_checkbox.setChecked(self.config.get('use_acceleration_ticket'))
self.use_acc_ticket_checkbox.stateChanged.connect(self.Slot_for_use_acc_ticket_check_box)
diff --git a/gui/components/expand/emulatorConfig.py b/gui/components/expand/emulatorConfig.py
index 07405e4bf..1474afaa4 100644
--- a/gui/components/expand/emulatorConfig.py
+++ b/gui/components/expand/emulatorConfig.py
@@ -1,43 +1,47 @@
from functools import partial
+from PyQt5.QtCore import QObject
from PyQt5.QtWidgets import QFileDialog, QLabel, QHBoxLayout
from qfluentwidgets import LineEdit, PushButton, ComboBox
from .expandTemplate import TemplateLayout
+from gui.util import notification
+from gui.util.translator import baasTranslator as bt
+
class Layout(TemplateLayout):
def __init__(self, parent=None, config=None):
+ EmulatorConfig = QObject()
configItems = [
{
- 'label': '在运行Baas时打开模拟器(启动模拟器的功能开关,关闭后不会启动模拟器)',
+ 'label': EmulatorConfig.tr('在运行Baas时打开模拟器(启动模拟器的功能开关,关闭后不会启动模拟器)'),
'key': 'open_emulator_stat',
'type': 'switch'
},
{
- 'label': '是否模拟器多开(打开后无视已经启动的模拟器进程,将再启动一个模拟器))',
+ 'label': EmulatorConfig.tr('是否模拟器多开(打开后无视已经启动的模拟器进程,将再启动一个模拟器))'),
'key': 'multi_emulator_check',
'type': 'switch'
},
{
- 'label': '等待模拟器启动时间(模拟器从开始启动到桌面加载完成的时间(秒),一般默认)',
+ 'label': EmulatorConfig.tr('等待模拟器启动时间(模拟器从开始启动到桌面加载完成的时间(秒),一般默认)'),
'type': 'text',
'key': 'emulator_wait_time'
},
{
- 'label': '是否启用内建的自动扫描模拟器功能(开启后将自动识别系统内已安装的模拟器)',
+ 'label': EmulatorConfig.tr('是否启用内建的自动扫描模拟器功能(开启后将自动识别系统内已安装的模拟器)'),
'type': 'switch',
'key': 'emulatorIsMultiInstance'
}
]
- super().__init__(parent=parent, configItems=configItems, config=config)
+ super().__init__(parent=parent, configItems=configItems, config=config, context='EmulatorConfig')
if not self.config.get('emulatorIsMultiInstance'):
self._createNotMultiComponent()
else:
self._createMultiComponent()
self.vBoxLayout.children()[3].itemAt(2).widget().checkedChanged.connect(self._soltForEmulatorIsMultiInstanced)
-
def _choose_file(self, line_edit):
file_dialog = QFileDialog()
file_dialog.setFileMode(QFileDialog.ExistingFile)
@@ -51,15 +55,15 @@ def _choose_file(self, line_edit):
self.config.set('program_address', file_path)
def _createNotMultiComponent(self):
- labelComponent = QLabel('选择模拟器地址', self)
+ labelComponent = QLabel(self.tr('选择模拟器地址'), self)
addressKey = 'program_address'
inputComponent = LineEdit(self)
inputComponent.setFixedWidth(500) # 设置文本框的固定宽度
inputComponent.setText(str(self.config.get(addressKey)))
- confirmButton = PushButton('确定', self)
+ confirmButton = PushButton(self.tr('确定'), self)
confirmButton.setFixedWidth(80) # 设置确定按钮的固定宽度
confirmButton.clicked.connect(partial(self._commit, addressKey, inputComponent, labelComponent))
- selectButton = PushButton('选择', self)
+ selectButton = PushButton(self.tr('选择'), self)
selectButton.setFixedWidth(80) # 设置选择按钮的固定宽度
selectButton.clicked.connect(partial(self._choose_file, inputComponent))
self.emulatorNotMultiAddressHLayout = QHBoxLayout(self)
@@ -75,8 +79,8 @@ def _createMultiComponent(self):
'bluestacks_nxt_cn': '蓝叠模拟器',
'bluestacks_nxt': '蓝叠国际版'
}
- emulatorLabelComponent = QLabel('选择模拟器类型', self)
- multiInstanceNumber = QLabel('多开号', self)
+ emulatorLabelComponent = QLabel(self.tr('选择模拟器类型'), self)
+ multiInstanceNumber = QLabel(self.tr('多开号'), self)
currentInstanceNumber = self.config.get('emulatorMultiInstanceNumber')
multiInstanceNumberInputComponent = LineEdit(self)
multiInstanceNumberInputComponent.setText(str(currentInstanceNumber))
@@ -84,7 +88,7 @@ def _createMultiComponent(self):
currentMultiEmulatorName = self.config.get('multiEmulatorName')
chooseMultiEmulatorCombobox = ComboBox(self)
values = self.multiMap.keys()
- chooseMultiEmulatorCombobox.addItems([self.multiMap[key] for key in values])
+ chooseMultiEmulatorCombobox.addItems([bt.tr('ConfigTranslation', self.multiMap[key]) for key in values])
chooseMultiEmulatorCombobox.setCurrentIndex(list(values).index(currentMultiEmulatorName))
chooseMultiEmulatorCombobox.currentIndexChanged.connect(self._slotForMultiInstanceComboBoxIndexChanged)
multiInstanceNumberInputComponent.setFixedWidth(80)
diff --git a/gui/components/expand/eventMapConfig.py b/gui/components/expand/eventMapConfig.py
index f3ab3759f..e48bb38e9 100644
--- a/gui/components/expand/eventMapConfig.py
+++ b/gui/components/expand/eventMapConfig.py
@@ -1,27 +1,30 @@
+from PyQt5.QtCore import QObject
from .expandTemplate import TemplateLayout
class Layout(TemplateLayout):
def __init__(self, parent=None, config=None):
+ # name it EventMapConfig to have context with same name
+ EventMapConfig = QObject()
configItems = [
{
- 'label': '推故事',
+ 'label': EventMapConfig.tr('推故事'),
'type': 'button',
'selection': self.activity_story
},
{
- 'label': '推任务',
+ 'label': EventMapConfig.tr('推任务'),
'type': 'button',
'selection': self.activity_mission
},
{
- 'label': '推挑战',
+ 'label': EventMapConfig.tr('推挑战'),
'type': 'button',
'selection': self.activity_challenge
},
]
self.main_thread = config.get_main_thread()
- super().__init__(parent=parent, configItems=configItems, config=config)
+ super().__init__(parent=parent, configItems=configItems, config=config, context='EventMapConfig')
def activity_story(self):
import threading
diff --git a/gui/components/expand/expandTemplate.py b/gui/components/expand/expandTemplate.py
index 7adc836eb..d01f3549e 100644
--- a/gui/components/expand/expandTemplate.py
+++ b/gui/components/expand/expandTemplate.py
@@ -8,6 +8,7 @@
from core.utils import delay
from gui.util import notification
from gui.util.config_set import ConfigSet
+from gui.util.translator import baasTranslator as bt
class ConfigItem:
@@ -26,7 +27,7 @@ def __init__(self, **kwargs):
class TemplateLayout(QWidget):
patch_signal = pyqtSignal(str)
- def __init__(self, configItems: Union[list[ConfigItem], list[dict]], parent=None, config=None):
+ def __init__(self, configItems: Union[list[ConfigItem], list[dict]], parent=None, config=None, context=None):
super().__init__(parent=parent)
self.config = config
if isinstance(configItems[0], dict):
@@ -44,7 +45,7 @@ def __init__(self, configItems: Union[list[ConfigItem], list[dict]], parent=None
confirmButton = None
selectButton = None
optionPanel = QHBoxLayout(self)
- labelComponent = QLabel(cfg.label, self)
+ labelComponent = QLabel(bt.tr(context, cfg.label), self)
optionPanel.addWidget(labelComponent, 0, Qt.AlignLeft)
optionPanel.addStretch(1)
if cfg.type == 'switch':
@@ -55,23 +56,25 @@ def __init__(self, configItems: Union[list[ConfigItem], list[dict]], parent=None
elif cfg.type == 'combo':
currentKey = cfg.key
inputComponent = ComboBox(self)
+ cfg.selection = [bt.tr(context, x) for x in cfg.selection] if context else cfg.selection
inputComponent.addItems(cfg.selection)
inputComponent.setCurrentIndex(cfg.selection.index(self.config.get(currentKey)))
inputComponent.currentIndexChanged.connect(
partial(self._commit, currentKey, inputComponent, labelComponent))
elif cfg.type == 'button':
- inputComponent = PushButton('执行', self)
+ # impossible to translate without specifying TemplateLayout context
+ text = bt.tr('TemplateLayout', self.tr('执行'))
+ inputComponent = PushButton(text, self)
inputComponent.clicked.connect(cfg.selection)
elif cfg.type == 'text':
currentKey = cfg.key
inputComponent = LineEdit(self)
inputComponent.setText(str(self.config.get(currentKey)))
self.patch_signal.connect(inputComponent.setText)
- confirmButton = PushButton('确定', self)
+ confirmButton = PushButton(self.tr('确定'), self)
confirmButton.clicked.connect(partial(self._commit, currentKey, inputComponent, labelComponent))
elif cfg.type == 'label':
inputComponent = QLabel(cfg.selection, self)
-
else:
raise ValueError(f'Unknown config type: {cfg.type}')
optionPanel.addWidget(inputComponent, 0, Qt.AlignRight)
@@ -92,7 +95,7 @@ def _commit(self, key, target, labelTarget):
value = target.text()
assert value is not None
self.config.update(key, value)
- notification.success('设置成功', f'{labelTarget.text()}已经被设置为:{value}', self.config)
+ notification.success(self.tr('设置成功'), f'{labelTarget.text()}{self.tr("已经被设置为:")}{value}', self.config)
class ConfigItemV2(ConfigItem):
diff --git a/gui/components/expand/exploreConfig.py b/gui/components/expand/exploreConfig.py
index da36127be..008b6ad71 100644
--- a/gui/components/expand/exploreConfig.py
+++ b/gui/components/expand/exploreConfig.py
@@ -1,4 +1,4 @@
-from PyQt5.QtCore import Qt
+from PyQt5.QtCore import Qt, QObject
from PyQt5.QtWidgets import QHBoxLayout, QLabel
from qfluentwidgets import LineEdit, PushButton
@@ -8,55 +8,56 @@
class Layout(TemplateLayout):
def __init__(self, parent=None, config=None):
+ ExploreConfig = QObject()
self.config = config
configItems = [
{
- 'label': '是否手动boss战(进入关卡后暂停等待手操)',
+ 'label': ExploreConfig.tr('是否手动boss战(进入关卡后暂停等待手操)'),
'key': 'manual_boss',
'type': 'switch'
},
{
- 'label': '是否不强制打到sss(启用后跳过已通过但未sss的关卡)',
+ 'label': ExploreConfig.tr('是否不强制打到sss(启用后跳过已通过但未sss的关卡)'),
'key': 'explore_normal_task_force_sss',
'type': 'switch'
},
{
- 'label': '开启后强制打每一个指定的关卡(不管是否sss)',
+ 'label': ExploreConfig.tr('开启后强制打每一个指定的关卡(不管是否sss)'),
'key': 'explore_normal_task_force_each_fight',
'type': 'switch'
},
{
- 'label': '爆发一队',
+ 'label': ExploreConfig.tr('爆发一队'),
'key': 'burst1',
'selection': ['1', '2', '3', '4'],
'type': 'combo'
},
{
- 'label': '爆发二队',
+ 'label': ExploreConfig.tr('爆发二队'),
'key': 'burst2',
'selection': ['1', '2', '3', '4'],
'type': 'combo'
},
{
- 'label': '贯穿一队',
+ 'label': ExploreConfig.tr('贯穿一队'),
'key': 'pierce1',
'selection': ['1', '2', '3', '4'],
'type': 'combo'
},
{
- 'label': '贯穿二队',
+ 'label': ExploreConfig.tr('贯穿二队'),
'key': 'pierce2',
'selection': ['1', '2', '3', '4'],
'type': 'combo'
},
{
- 'label': '神秘一队',
+ 'label': ExploreConfig.tr('神秘一队'),
'key': 'mystic1',
'selection': ['1', '2', '3', '4'],
'type': 'combo'
},
{
- 'label': '神秘二队',
+ 'label': ExploreConfig.tr('神秘二队'),
'key': 'mystic2',
'selection': ['1', '2', '3', '4'],
'type': 'combo'
@@ -65,27 +66,26 @@ def __init__(self, parent=None, config=None):
if self.config.server_mode == 'JP' or self.config.server_mode == 'Global':
configItems.extend([
{
- 'label': '振动一队',
+ 'label': ExploreConfig.tr('振动一队'),
'key': 'shock1',
'selection': ['1', '2', '3', '4'],
'type': 'combo'
},
{
- 'label': '振动二队',
+ 'label': ExploreConfig.tr('振动二队'),
'key': 'shock2',
'selection': ['1', '2', '3', '4'],
'type': 'combo'
}
])
-
- super().__init__(parent=parent, configItems=configItems, config=config)
+ super().__init__(parent=parent, configItems=configItems, config=config, context='ExploreConfig')
self.push_card = QHBoxLayout(self)
self.push_card_label = QHBoxLayout(self)
self.label_tip_push = QLabel(
- '推图选项 请在下面填写要推的图,填写方式见-普通图自动推图说明-', self)
+ '' + self.tr('推图选项') + ' ' + self.tr('请在下面填写要推的图,填写方式见-普通图自动推图说明-'), self)
self.input_push = LineEdit(self)
- self.accept_push = PushButton('开始推图', self)
+ self.accept_push = PushButton(self.tr('开始推图'), self)
self.input_push.setText(
self.config.get('explore_normal_task_regions').__str__().replace('[', '').replace(']', ''))
@@ -110,7 +110,7 @@ def __init__(self, parent=None, config=None):
def _accept_push(self):
self.config.set('explore_normal_task_regions', self.input_push.text())
value = self.input_push.text()
- notification.success('普通关推图', f'你的普通关配置已经被设置为:{value},正在推普通关。', self.config)
+ notification.success(self.tr('普通关推图'), f'{self.tr("你的普通关配置已经被设置为:")}{value},{self.tr("正在推普通关。")}', self.config)
sig = self.config.get_signal('update_signal')
sig.emit(['普通关推图'])
import threading
diff --git a/gui/components/expand/featureSwitch.py b/gui/components/expand/featureSwitch.py
index 39835777e..b71a5f3c2 100644
--- a/gui/components/expand/featureSwitch.py
+++ b/gui/components/expand/featureSwitch.py
@@ -10,41 +10,42 @@
SubtitleLabel
from gui.components.expand.expandTemplate import TemplateLayoutV2
+from gui.util.translator import baasTranslator as bt
class DetailSettingMessageBox(MessageBoxBase):
def __init__(self, detail_config: dict, all_label_list: list, parent=None, cs=None):
super().__init__(parent)
- self.titleLabel = SubtitleLabel('配置详情', self)
+ self.titleLabel = SubtitleLabel(self.tr('配置详情'), self)
configItems = [
{
- 'label': '优先级',
+ 'label': self.tr('优先级'),
'dataType': 'int',
'key': 'priority'
},
{
- 'label': '执行间隔',
+ 'label': self.tr('执行间隔'),
'dataType': 'int',
'key': 'interval',
},
{
- 'label': '每日重置',
+ 'label': self.tr('每日重置'),
'dataType': 'list',
'key': 'daily_reset',
},
{
- 'label': '禁用时间段',
+ 'label': self.tr('禁用时间段'),
'dataType': 'list',
'key': 'disabled_time_range',
},
{
- 'label': '前置任务',
+ 'label': self.tr('前置任务'),
'dataType': 'list',
'key': 'pre_task',
'presets': []
},
{
- 'label': '后置任务',
+ 'label': self.tr('后置任务'),
'dataType': 'list',
'key': 'post_task',
'presets': []
@@ -55,8 +56,8 @@ def __init__(self, detail_config: dict, all_label_list: list, parent=None, cs=No
self.viewLayout.addWidget(self.titleLabel)
self.viewLayout.addWidget(self.configWidget)
- self.yesButton.setText('确定')
- self.cancelButton.setText('取消')
+ self.yesButton.setText(self.tr('确定'))
+ self.cancelButton.setText(self.tr('取消'))
self.widget.setMinimumWidth(350)
@@ -75,20 +76,20 @@ def __init__(self, parent=None, config=None):
self.vBox = QVBoxLayout(self)
self.option_layout = QHBoxLayout(self)
- self.all_check_box = PushButton('全部(不)启用', self)
+ self.all_check_box = PushButton(self.tr('全部(不)启用'), self)
self.all_check_box.clicked.connect(self.all_check)
self.option_layout.addWidget(self.all_check_box)
self.option_layout.addStretch(1)
- self.op_2 = PushButton('刷新执行时间', self)
+ self.op_2 = PushButton(self.tr('刷新执行时间'), self)
self.option_layout.addWidget(self.op_2)
self.op_2.clicked.connect(self._refresh)
self.option_layout.addStretch(1)
- self.label_3 = CaptionLabel('排序方式:', self)
+ self.label_3 = CaptionLabel(self.tr('排序方式:'), self)
self.op_3 = ComboBox(self)
- self.op_3.addItems(['默认排序', '按下次执行时间排序'])
+ self.op_3.addItems([self.tr('默认排序'), self.tr('按下次执行时间排序')])
self.op_3.currentIndexChanged.connect(self._sort)
self.option_layout.addWidget(self.label_3)
@@ -99,7 +100,7 @@ def __init__(self, parent=None, config=None):
self.tableView.setRowCount(len(self.qLabels))
self.tableView.setColumnCount(4)
self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
- self.tableView.setHorizontalHeaderLabels(['事件', '下次刷新时间', '启用', '更多配置'])
+ self.tableView.setHorizontalHeaderLabels([self.tr('事件'), self.tr('下次刷新时间'), self.tr('启用'), self.tr('更多配置')])
self.tableView.setColumnWidth(0, 175)
self.tableView.setColumnWidth(1, 175)
self.tableView.setColumnWidth(2, 50)
@@ -124,8 +125,7 @@ def _init_components(self, config_list):
cbx_layout.addWidget(t_cbx, 1, Qt.AlignCenter)
cbx_layout.setContentsMargins(30, 0, 0, 0)
cbx_wrapper.setLayout(cbx_layout)
-
- t_ccs = CaptionLabel(self.labels[i])
+ t_ccs = CaptionLabel(bt.tr('ConfigTranslation', self.labels[i]))
t_ncs = LineEdit(self)
t_ncs.setText(str(datetime.fromtimestamp(self.next_ticks[i])).split('.')[0])
t_ncs.textChanged.connect(self._update_config)
@@ -135,7 +135,7 @@ def _init_components(self, config_list):
self.boxes.append(cbx_wrapper)
self.check_boxes.append(t_cbx)
- t_cfbs = PushButton('详细配置', self)
+ t_cfbs = PushButton(self.tr('详细配置'), self)
t_cfbs.clicked.connect(partial(self._update_detail, i))
cfbs_wrapper = QWidget()
cfbs_layout = QHBoxLayout()
@@ -168,7 +168,7 @@ def _sort(self):
self.tableView.setRowCount(len(temp))
self.tableView.setColumnCount(4)
self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
- self.tableView.setHorizontalHeaderLabels(['事件', '下次刷新时间', '启用', '更多配置'])
+ self.tableView.setHorizontalHeaderLabels([self.tr('事件'), self.tr('下次刷新时间'), self.tr('启用'), self.tr('更多配置')])
# mode 0: default, mode 1: by next_tick
if self.op_3.currentIndex() == 0:
@@ -178,7 +178,7 @@ def _sort(self):
self._crt_order_config = temp
# Add components to table
for ind, unit in enumerate(temp):
- t_ccs = CaptionLabel(unit['event_name'])
+ t_ccs = CaptionLabel(bt.tr('ConfigTranslation', unit['event_name']))
self.tableView.setCellWidget(ind, 0, t_ccs)
self.qLabels.append(t_ccs)
@@ -199,7 +199,7 @@ def _sort(self):
self.tableView.setCellWidget(ind, 2, cbx_wrapper)
self.check_boxes.append(t_cbx)
- t_cfbs = PushButton('详细配置', self)
+ t_cfbs = PushButton(self.tr('详细配置'), self)
t_cfbs.clicked.connect(partial(self._update_detail, ind))
cfbs_wrapper = QWidget()
cfbs_layout = QHBoxLayout()
@@ -215,7 +215,7 @@ def _sort(self):
def _update_config(self):
for i in range(len(self.enable_list)):
dic = {
- 'event_name': self.qLabels[i].text(),
+ 'event_name': bt.undo(self.qLabels[i].text()),
'next_tick': self.get_next_tick(self.times[i].text()),
'enabled': self.check_boxes[i].isChecked()
}
@@ -237,7 +237,7 @@ def _update_detail(self, index):
}
all_label_list = [
- [x['event_name'], x['func_name']]
+ [bt.tr('ConfigTranslation', x['event_name']), x['func_name']]
for x in self._event_config
]
@@ -279,7 +279,7 @@ def _refresh_time(self):
for item in changed_map:
for i in range(len(self.qLabels)):
- if self.qLabels[i].text() == item[0]:
+ if bt.undo(self.qLabels[i].text()) == item[0]:
self.times[i].blockSignals(True)
self.times[i].setText(str(datetime.fromtimestamp(item[1])))
self.times[i].blockSignals(False)
diff --git a/gui/components/expand/hardTaskConfig.py b/gui/components/expand/hardTaskConfig.py
index bfc174652..8df9ba780 100644
--- a/gui/components/expand/hardTaskConfig.py
+++ b/gui/components/expand/hardTaskConfig.py
@@ -1,40 +1,40 @@
-from PyQt5.QtCore import Qt
+from PyQt5.QtCore import Qt, QObject
from PyQt5.QtWidgets import QHBoxLayout, QLabel
from qfluentwidgets import LineEdit, PushButton
from .expandTemplate import TemplateLayout
from ...util import notification
-
class Layout(TemplateLayout):
def __init__(self, parent=None, config=None):
+ HardTaskConfig = QObject()
configItems = [
{
- 'label': '打到SSS',
+ 'label': HardTaskConfig.tr('打到SSS'),
'key': 'explore_hard_task_need_sss',
'type': 'switch'
},
{
- 'label': '拿礼物',
+ 'label': HardTaskConfig.tr('拿礼物'),
'key': 'explore_hard_task_need_present',
'type': 'switch'
},
{
- 'label': '完成成就任务',
+ 'label': HardTaskConfig.tr('完成成就任务'),
'key': 'explore_hard_task_need_task',
'type': 'switch'
}
]
- super().__init__(parent=parent, configItems=configItems, config=config)
+ super().__init__(parent=parent, configItems=configItems, config=config, context="HardTaskConfig")
self.push_card = QHBoxLayout(self)
self.push_card_label = QHBoxLayout(self)
self.label_tip_push = QLabel(
- '困难图队伍属性和普通图相同(见普通图推图设置),请按照帮助中说明选择推困难图关卡并按对应图设置队伍',
+ self.tr('困难图队伍属性和普通图相同(见普通图推图设置),请按照帮助中说明选择推困难图关卡并按对应图设置队伍'),
self)
self.input_push = LineEdit(self)
- self.accept_push = PushButton('开始推图', self)
+ self.accept_push = PushButton(self.tr('开始推图'), self)
self.input_push.setText(self.config.get('explore_hard_task_list'))
self.input_push.setFixedWidth(700)
@@ -58,7 +58,7 @@ def __init__(self, parent=None, config=None):
def _accept_push(self):
value = self.input_push.text()
self.config.set('explore_hard_task_list', value)
- notification.success('困难关推图', f'你的困难关配置已经被设置为:{value},正在推困难关。', self.config)
+ notification.success(self.tr('困难关推图'), f'{self.tr("你的困难关配置已经被设置为:")}{value},{self.tr("正在推困难关。")}', self.config)
import threading
threading.Thread(target=self.action).start()
diff --git a/gui/components/expand/mainlinePriority.py b/gui/components/expand/mainlinePriority.py
index 8c793db75..643d5ed59 100644
--- a/gui/components/expand/mainlinePriority.py
+++ b/gui/components/expand/mainlinePriority.py
@@ -3,6 +3,8 @@
from qfluentwidgets import LineEdit, ComboBox
from gui.util import notification
+from gui.util.translator import baasTranslator as bt
+
class Layout(QWidget):
def __init__(self, parent=None, config=None):
@@ -15,24 +17,24 @@ def __init__(self, parent=None, config=None):
self.lay1_hard = QHBoxLayout(self)
self.lay2_hard = QHBoxLayout(self)
- self.label = QLabel('普通关卡与次数(如"1-1-1,1-2-3"表示关卡1-1打一次,然后关卡1-2打三次):', self)
+ self.label = QLabel(self.tr('普通关卡与次数(如"1-1-1,1-2-3"表示关卡1-1打一次,然后关卡1-2打三次):'), self)
self.input = LineEdit(self)
- self.accept = QPushButton('确定', self)
- self.label_hard = QLabel('困难关卡设置同上,(注意:次数最多为3),逗号均为英文逗号,日服、国际服可填max:', self)
+ self.accept = QPushButton(self.tr('确定'), self)
+ self.label_hard = QLabel(self.tr('困难关卡设置同上,注意:次数最多为3),逗号均为英文逗号,日服、国际服可填max:'), self)
self.input_hard = LineEdit(self)
- self.accept_hard = QPushButton('确定', self)
+ self.accept_hard = QPushButton(self.tr('确定'), self)
self.hard_task_combobox = ComboBox(self)
self.each_student_task_number_dict = {
- "根据学生添加关卡": [],
- "爱丽丝宝贝": [],
+ self.tr("根据学生添加关卡"): [],
+ self.tr("爱丽丝宝贝"): [],
}
for i in range(0, len(self.config.static_config["hard_task_student_material"])):
- self.each_student_task_number_dict.setdefault(self.config.static_config["hard_task_student_material"][i][1],
- [])
+ translated_name = bt.getStudent(self.config.static_config["hard_task_student_material"][i][1])
+ self.each_student_task_number_dict.setdefault(translated_name, [])
temp = self.config.static_config["hard_task_student_material"][i][0] + "-3"
- (self.each_student_task_number_dict[self.config.static_config["hard_task_student_material"][i][1]].append(
- temp))
+ (self.each_student_task_number_dict[translated_name].append(temp))
+
for key in self.each_student_task_number_dict.keys():
self.hard_task_combobox.addItem(key)
self.hard_task_combobox.currentIndexChanged.connect(self.__hard_task_combobox_change)
@@ -90,9 +92,9 @@ def __accept_main(self):
for i in range(0, len(input_content)):
temp.append(readOneNormalTask(input_content[i]))
self.config.set("unfinished_normal_tasks", temp) # refresh the config unfinished_normal_tasks
- notification.success('设置成功', f'你的普通关卡已经被设置为:{input_content}', self.config)
+ notification.success(self.tr('设置成功'), f'{self.tr("你的普通关卡已经被设置为:")}{input_content}', self.config)
except Exception as e:
- notification.error('设置失败', f'请检查输入格式是否正确,错误信息:{e}', self.config)
+ notification.error(self.tr('设置失败'), f'{self.tr("请检查输入格式是否正确,错误信息:")}{e}', self.config)
def __accept_hard(self):
try:
@@ -104,12 +106,12 @@ def __accept_hard(self):
for i in range(0, len(input_content)):
temp.append(readOneHardTask(input_content[i]))
self.config.set("unfinished_hard_tasks", temp) # refresh the config unfinished_hard_tasks
- notification.success('设置成功', f'你的困难关卡已经被设置为:{input_content}', self.config)
+ notification.success(self.tr('设置成功'), f'{self.tr("你的困难关卡已经被设置为:")}{input_content}', self.config)
except Exception as e:
- notification.error('设置失败', f'请检查输入格式是否正确,错误信息:{e}', self.config)
+ notification.error(self.tr('设置失败'), f'{self.tr("请检查输入格式是否正确,错误信息:")}{e}', self.config)
def __hard_task_combobox_change(self):
- if self.hard_task_combobox.currentText() == "根据学生添加关卡":
+ if self.hard_task_combobox.currentText() == self.tr("根据学生添加关卡"):
return
st = ""
if self.input_hard.text() != "":
diff --git a/gui/components/expand/otherConfig.py b/gui/components/expand/otherConfig.py
index cf0dabd58..35330900b 100644
--- a/gui/components/expand/otherConfig.py
+++ b/gui/components/expand/otherConfig.py
@@ -1,29 +1,31 @@
+from PyQt5.QtCore import QObject
from .expandTemplate import TemplateLayout
class Layout(TemplateLayout):
def __init__(self, parent=None, config=None):
+ OtherConfig = QObject()
configItems = [
{
- 'label': '一键反和谐',
+ 'label': OtherConfig.tr('一键反和谐'),
'type': 'button',
'selection': self.fhx,
'key': None
},
{
- 'label': '修复Mumu无法登录日服',
+ 'label': OtherConfig.tr('修复Mumu无法登录日服'),
'type': 'button',
'selection': self.mumu_JP_login_fixer,
'key': None
},
{
- 'label': '显示首页头图(下次启动时生效)',
+ 'label': OtherConfig.tr('显示首页头图(下次启动时生效)'),
'type': 'switch',
'key': 'bannerVisibility'
}
]
- super().__init__(parent=parent, configItems=configItems, config=config)
+ super().__init__(parent=parent, configItems=configItems, config=config, context="OtherConfig")
def mumu_JP_login_fixer(self):
self.config.get_main_thread().start_mumu_JP_login_fixer()
diff --git a/gui/components/expand/proceedPlot.py b/gui/components/expand/proceedPlot.py
index eb57b1f17..c87a29f4f 100644
--- a/gui/components/expand/proceedPlot.py
+++ b/gui/components/expand/proceedPlot.py
@@ -1,35 +1,37 @@
from .expandTemplate import TemplateLayout
+from PyQt5.QtCore import QObject
class Layout(TemplateLayout):
def __init__(self, parent=None, config=None):
+ ProceedPlot = QObject()
configItems = [
{
- 'label': '主线剧情需要推的章节数',
+ 'label': ProceedPlot.tr('主线剧情需要推的章节数'),
'type': 'text',
'key': 'main_story_regions'
},
{
- 'label': '开始推主线剧情',
+ 'label': ProceedPlot.tr('开始推主线剧情'),
'type': 'button',
'selection': self.proceed_main_plot,
'key': None
},
{
- 'label': '开始推小组剧情',
+ 'label': ProceedPlot.tr('开始推小组剧情'),
'type': 'button',
'selection': self.proceed_group_plot,
'key': None
},
{
- 'label': '开始推支线剧情',
+ 'label': ProceedPlot.tr('开始推支线剧情'),
'type': 'button',
'selection': self.proceed_branch_plot,
'key': None
}
]
self.main_thread = config.get_main_thread()
- super().__init__(parent=parent, configItems=configItems, config=config)
+ super().__init__(parent=parent, configItems=configItems, config=config, context="ProceedPlot")
def proceed_main_plot(self):
import threading
diff --git a/gui/components/expand/pushConfig.py b/gui/components/expand/pushConfig.py
index d17337449..ad37f5d5f 100644
--- a/gui/components/expand/pushConfig.py
+++ b/gui/components/expand/pushConfig.py
@@ -1,28 +1,30 @@
from .expandTemplate import TemplateLayout
+from PyQt5.QtCore import QObject
class Layout(TemplateLayout):
def __init__(self, parent=None, config=None):
+ PushConfig = QObject()
configItems = [ {
- 'label': '在运行出错时推送',
+ 'label': PushConfig.tr('在运行出错时推送'),
'key': 'push_after_error',
'type': 'switch'
},
{
- 'label': '在全部任务完成时推送',
+ 'label': PushConfig.tr('在全部任务完成时推送'),
'key': 'push_after_completion',
'type': 'switch'
},
{
- 'label': 'json 推送',
+ 'label': PushConfig.tr('json 推送'),
'type': 'text',
'key': 'push_json'
},
{
- 'label': 'ServerChan推送',
+ 'label': PushConfig.tr('ServerChan推送'),
'type': 'text',
'key': 'push_serverchan'
}
]
- super().__init__(parent=parent, configItems=configItems, config=config)
+ super().__init__(parent=parent, configItems=configItems, config=config, context="PushConfig")
diff --git a/gui/components/expand/schedulePriority.py b/gui/components/expand/schedulePriority.py
index 4b7618c18..1dbafdfd7 100644
--- a/gui/components/expand/schedulePriority.py
+++ b/gui/components/expand/schedulePriority.py
@@ -1,4 +1,4 @@
-from PyQt5.QtCore import Qt
+from PyQt5.QtCore import Qt, QTranslator, QLocale
from PyQt5.QtGui import QIntValidator
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QLabel, QVBoxLayout
from qfluentwidgets import LineEdit, CheckBox
@@ -18,7 +18,7 @@ def __init__(self, parent=None, config=None):
self.needed_levels = self.config.get('lesson_each_region_object_priority')
self.check_config_validation()
self.vBoxLayout = QVBoxLayout(self)
- self.relationship_check_box_description = QLabel('优先做好感等级多的日程', self)
+ self.relationship_check_box_description = QLabel(self.tr('优先做好感等级多的日程'), self)
self.relationship_check_box = CheckBox('', self)
self.relationship_check_box.setChecked(self.config.get('lesson_relationship_first'))
self.hBoxLayout = QHBoxLayout(self)
@@ -71,7 +71,7 @@ def Slot_for_lesson_time_change(self, _):
res.append(int(self.lesson_time_input[i].text()))
self.priority_list = res
self.config.set('lesson_times', self.priority_list)
- return notification.success('日程次数', f'日程次数设置成功为:{self.priority_list}', self.config)
+ return notification.success(self.tr('日程次数'), f'{self.tr("日程次数设置成功为:")}{self.priority_list}', self.config)
def __init_Signals_and_Slots(self):
self.relationship_check_box.stateChanged.connect(self.Slot_for_relationship_check_box)
@@ -95,13 +95,13 @@ def __init_relationship_check_box_layout(self):
def __init_region_name_layout(self):
temp = QVBoxLayout(self)
- temp.addWidget(QLabel("区域名称", self), 0, Qt.AlignLeft)
+ temp.addWidget(QLabel(self.tr("区域名称"), self), 0, Qt.AlignLeft)
for i in range(0, len(self.lesson_names)):
temp.addWidget(QLabel(self.lesson_names[i], self), 0, Qt.AlignLeft)
self.hBoxLayout.addLayout(temp)
def __init_lesson_level_layout(self):
- name = ["初级", "普通", "高级", "特级"]
+ name = [self.tr("初级"), self.tr("普通"), self.tr("高级"), self.tr("特级")]
for i in range(0, 4):
temp = QVBoxLayout(self)
temp.setContentsMargins(0, 5, 0, 5)
@@ -113,7 +113,7 @@ def __init_lesson_level_layout(self):
def __init_lesson_times_layout(self):
temp = QVBoxLayout(self)
- temp.addWidget(QLabel("日程次数", self), 0, Qt.AlignLeft)
+ temp.addWidget(QLabel(self.tr("日程次数"), self), 0, Qt.AlignLeft)
for i in range(0, len(self.lesson_names)):
temp.addWidget(self.lesson_time_input[i], 0, Qt.AlignLeft)
self.hBoxLayout.addLayout(temp)
diff --git a/gui/components/expand/scriptConfig.py b/gui/components/expand/scriptConfig.py
index 5b01be521..acf23d934 100644
--- a/gui/components/expand/scriptConfig.py
+++ b/gui/components/expand/scriptConfig.py
@@ -13,7 +13,7 @@ def __init__(self, parent=None, config=None):
super().__init__(parent=parent)
self.config = config
self.info_widget = self.parent().parent().parent()
- self.serverLabel = QLabel('请填写您的截图间隔:', self)
+ self.serverLabel = QLabel(self.tr('请填写您的截图间隔:'), self)
self.screenshot_box = LineEdit(self)
validator = QDoubleValidator(0.0, 65535.0, 2, self)
self.screenshot_box.setValidator(validator)
@@ -33,4 +33,4 @@ def __init__(self, parent=None, config=None):
def _save_port(self, changed_text=None):
self.config.set('screenshot_interval', changed_text)
- notification.success('截图间隔', f'你的截图间隔已经被设置为:{changed_text}', self.config)
+ notification.success(self.tr('截图间隔'), f'{self.tr("你的截图间隔已经被设置为:")}{changed_text}', self.config)
diff --git a/gui/components/expand/serverConfig.py b/gui/components/expand/serverConfig.py
index 08b46ad61..1da6f507e 100644
--- a/gui/components/expand/serverConfig.py
+++ b/gui/components/expand/serverConfig.py
@@ -1,3 +1,4 @@
+from PyQt5.QtCore import QObject
from PyQt5.QtWidgets import QHeaderView, QTableWidgetItem
from qfluentwidgets import TableWidget
@@ -14,25 +15,26 @@ def get_address_from_str(st):
class Layout(TemplateLayout):
def __init__(self, parent=None, config=None):
+ ServerConfig = QObject()
configItems = [
{
- 'label': '请选择您的服务器,请慎重切换服务器,切换服务器后请重新启动脚本',
+ 'label': ServerConfig.tr('请选择您的服务器,请慎重切换服务器,切换服务器后请重新启动脚本'),
'type': 'combo',
'key': 'server',
- 'selection': ['官服', 'B服', '国际服', '日服']
+ 'selection': [ServerConfig.tr('官服'), ServerConfig.tr('B服'), ServerConfig.tr('国际服'), ServerConfig.tr('日服')]
},
{
- 'label': '请填写您的adb端口号',
+ 'label': ServerConfig.tr('请填写您的adb端口号'),
'type': 'text',
'key': 'adbPort'
},
{
- 'label': '检测adb地址(检测目前开启的模拟器adb地址)',
+ 'label': ServerConfig.tr('检测adb地址(检测目前开启的模拟器adb地址)'),
'type': 'button',
'selection': self.detect_adb_addr,
}
]
- super().__init__(parent=parent, configItems=configItems, config=config)
+ super().__init__(parent=parent, configItems=configItems, config=config, context='ServerConfig')
self.tableView = TableWidget(self)
self.tableView.setFixedHeight(100)
@@ -55,7 +57,7 @@ def detect_adb_addr_thread(self):
import device_operation
results = device_operation.autosearch()
if len(results) == 0:
- results = ["自动查询模拟器失败!请尝试手动输入端口"]
+ results = [self.tr("自动查询模拟器失败!请尝试手动输入端口")]
self.tableView.setRowCount(len(results))
for i in range(len(results)):
self.tableView.setItem(i, 0, QTableWidgetItem(results[i]))
@@ -63,7 +65,7 @@ def detect_adb_addr_thread(self):
except Exception as e:
print(e)
self.tableView.setRowCount(1)
- self.tableView.setItem(0, 0, QTableWidgetItem("adb地址获取失败"))
+ self.tableView.setItem(0, 0, QTableWidgetItem(self.tr("adb地址获取失败")))
# import device_operation
# results = device_operation.autosearch()
diff --git a/gui/components/expand/shopPriority.py b/gui/components/expand/shopPriority.py
index 2d42d5f60..14d73fcdf 100644
--- a/gui/components/expand/shopPriority.py
+++ b/gui/components/expand/shopPriority.py
@@ -2,6 +2,8 @@
from PyQt5.QtWidgets import QWidget, QLabel, QPushButton, QHBoxLayout, QVBoxLayout
from qfluentwidgets import FlowLayout, CheckBox, LineEdit
+from gui.util.translator import baasTranslator as bt
+
class Layout(QWidget):
def __init__(self, parent=None, config=None):
@@ -20,24 +22,24 @@ def __init__(self, parent=None, config=None):
self.setFixedHeight(700)
self.setStyleSheet('Demo{background: white} QPushButton{padding: 5px 10px; font:15px "Microsoft YaHei"}')
- self.label = QLabel('刷新次数', self)
+ self.label = QLabel(self.tr('刷新次数'), self)
self.label.setFixedWidth(160)
self.input = LineEdit(self)
self.input.setValidator(QIntValidator(0, 5))
print(self.config.get('CommonShopRefreshTime'))
self.input.setText(str(self.config.get('CommonShopRefreshTime')))
- self.accept = QPushButton('确定', self)
+ self.accept = QPushButton(self.tr('确定'), self)
self.boxes = []
for i in range(len(self.goods)):
t_cbx = CheckBox(self)
t_cbx.setChecked(self.goods[i] == 1)
- ccs = QLabel(self.default_goods[i][0], self)
+ ccs = QLabel(bt.tr('ConfigTranslation', self.default_goods[i][0]), self)
ccs.setFixedWidth(150)
price_text = str(self.default_goods[i][1])
if self.default_goods[i][2] == 'creditpoints':
- price_text += '信用点'
+ price_text += self.tr('信用点')
else:
- price_text += '青辉石'
+ price_text += self.tr('青辉石')
price_label = QLabel(price_text, self)
price_label.setFixedWidth(150)
wrapper_widget = QWidget()
@@ -66,4 +68,3 @@ def __accept(self, input_content=None):
def __check_server(self):
if len(self.config.get('CommonShopList')) != len(self.default_goods):
self.config.set('CommonShopList', len(self.default_goods) * [0])
-
diff --git a/gui/components/expand/sweepCountConfig.py b/gui/components/expand/sweepCountConfig.py
index 28c4402ab..2e06e5f5b 100644
--- a/gui/components/expand/sweepCountConfig.py
+++ b/gui/components/expand/sweepCountConfig.py
@@ -1,12 +1,14 @@
+from PyQt5.QtCore import QObject
from .expandTemplate import TemplateLayout
class Layout(TemplateLayout):
def __init__(self, parent=None, config=None):
+ SweepCountConfig = QObject()
sweep_label_description = {
- 'CN': '各区域扫荡次数以英文逗号分隔',
- 'Global': '各区域扫荡次数以英文逗号分隔,扫荡次数可以为max',
- 'JP': '各区域扫荡次数以英文逗号分隔,扫荡次数可以为max',
+ 'CN': SweepCountConfig.tr('各区域扫荡次数以英文逗号分隔'),
+ 'Global': SweepCountConfig.tr('各区域扫荡次数以英文逗号分隔,扫荡次数可以为max'),
+ 'JP': SweepCountConfig.tr('各区域扫荡次数以英文逗号分隔,扫荡次数可以为max'),
}
configItems = [
{
@@ -14,57 +16,57 @@ def __init__(self, parent=None, config=None):
'type': 'label'
},
{
- 'label': '悬赏委托扫荡',
+ 'label': SweepCountConfig.tr('悬赏委托扫荡'),
'type': 'text',
'key': 'rewarded_task_times'
},
{
- 'label': '学园交流会扫荡',
+ 'label': SweepCountConfig.tr('学园交流会扫荡'),
'type': 'text',
'key': 'scrimmage_times'
},
{
- 'label': '活动关卡扫荡关卡',
+ 'label': SweepCountConfig.tr('活动关卡扫荡关卡'),
'type': 'text',
'key': 'activity_sweep_task_number'
},
{
- 'label': '活动关卡扫荡次数',
+ 'label': SweepCountConfig.tr('活动关卡扫荡次数'),
'type': 'text',
'key': 'activity_sweep_times'
},
{
- 'label': '特殊委托扫荡',
+ 'label': SweepCountConfig.tr('特殊委托扫荡'),
'type': 'text',
'key': 'special_task_times'
},
]
additional_items = [
{
- 'label': '国服购买邀请券可在商店购买中实现',
+ 'label': SweepCountConfig.tr('国服购买邀请券可在商店购买中实现'),
'type': 'label'
}
]
if config.server_mode in ['JP', 'Global']:
additional_items = [
{
- 'label': '用券数目设置,下拉框选择',
+ 'label': SweepCountConfig.tr('用券数目设置,下拉框选择'),
'type': 'label'
},
{
- 'label': '悬赏委托扫荡券购买次数',
+ 'label': SweepCountConfig.tr('悬赏委托扫荡券购买次数'),
'type': 'combo',
'key': 'purchase_rewarded_task_ticket_times',
'selection': ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', 'max']
},
{
- 'label': '日程券购买次数',
+ 'label': SweepCountConfig.tr('日程券购买次数'),
'type': 'combo',
'key': 'purchase_lesson_ticket_times',
'selection': ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', 'max']
},
{
- 'label': '学园交流会扫荡券购买次数',
+ 'label': SweepCountConfig.tr('学园交流会扫荡券购买次数'),
'type': 'combo',
'key': 'purchase_scrimmage_ticket_times',
'selection': ['0', '1', '2', '3', '4', 'max']
@@ -72,4 +74,4 @@ def __init__(self, parent=None, config=None):
]
for item in additional_items:
configItems.append(item)
- super().__init__(parent=parent, configItems=configItems, config=config)
+ super().__init__(parent=parent, configItems=configItems, config=config, context='SweepCountConfig')
diff --git a/gui/components/expand/totalForceFightPriority.py b/gui/components/expand/totalForceFightPriority.py
index c954a7b75..776875239 100644
--- a/gui/components/expand/totalForceFightPriority.py
+++ b/gui/components/expand/totalForceFightPriority.py
@@ -11,8 +11,7 @@ def __init__(self, parent=None, config=None):
self.config = config
self.info_widget = self.parent()
self.hBoxLayout = QHBoxLayout(self)
- # self.label = QLabel('输入最高难度', self)
- self.label = QLabel('最高难度', self)
+ self.label = QLabel(self.tr('最高难度'), self)
self.input = ComboBox(self)
self.difficulties = self.config.static_config['total_assault_difficulties'][self.config.server_mode]
self.input.addItems(self.difficulties)
@@ -33,4 +32,4 @@ def __init__(self, parent=None, config=None):
def __accept(self):
self.config.set('totalForceFightDifficulty', self.input.text())
- notification.success('设置成功', f'你的总力战最高难度已经被设置为:{self.input.text()}', self.config)
+ notification.success(self.tr('设置成功'), f'{self.tr("你的总力战最高难度已经被设置为:")}{self.input.text()}', self.config)
diff --git a/gui/components/template_card.py b/gui/components/template_card.py
index 35cbdb2d8..d4f3a1785 100644
--- a/gui/components/template_card.py
+++ b/gui/components/template_card.py
@@ -5,6 +5,8 @@
IndicatorPosition, LineEdit
from qfluentwidgets import FluentIcon as FIF
+from gui.util.translator import baasTranslator as bt
+
class TemplateSettingCard(ExpandSettingCard):
""" Folder list setting card """
@@ -12,7 +14,9 @@ class TemplateSettingCard(ExpandSettingCard):
# statusChanged = pyqtSignal(bool)
# timeChanged = pyqtSignal(str)
- def __init__(self, title: str = '', content: str = None, parent=None, sub_view=None, config=None):
+ def __init__(self, title: str = '', content: str = None, parent=None, sub_view=None, config=None, context=None):
+ if context is not None:
+ title, content = bt.tr(context, title), bt.tr(context, content)
super().__init__(FIF.CHECKBOX, title, content, parent)
# Card Top Widgets
# self.status_switch = SwitchButton(self.tr('Off'), self, IndicatorPosition.RIGHT)
@@ -56,7 +60,9 @@ def setChecked(self, isChecked: bool):
class SimpleSettingCard(ExpandSettingCard):
""" Folder list setting card """
- def __init__(self, sub_view, title: str = '', content: str = None, parent=None, config=None):
+ def __init__(self, sub_view, title: str = '', content: str = None, parent=None, config=None, context=None):
+ if context is not None:
+ title, content = bt.tr(context, title), bt.tr(context, content)
super().__init__(FIF.CHECKBOX, title, content, parent)
self.expand_view = sub_view.Layout(self, config)
self._adjustViewSize()
diff --git a/gui/fragments/history.py b/gui/fragments/history.py
index 2f92b997e..8ca8386e2 100644
--- a/gui/fragments/history.py
+++ b/gui/fragments/history.py
@@ -21,11 +21,11 @@ def __init__(self):
# hide index column
self.table_view.verticalHeader().setVisible(False)
- self.table_view.setHorizontalHeaderLabels(['内容', '贡献者', '提交时间', '提交信息'])
+ self.table_view.setHorizontalHeaderLabels([self.tr('内容'), self.tr('贡献者'), self.tr('提交时间'), self.tr('提交信息')])
self.table_view.setObjectName('HistoryTable' + random.randint(0, 100000).__str__())
threading.Thread(target=self.fetch_update_info, daemon=True).start()
- self.addSubInterface(icon=FIF.CARE_RIGHT_SOLID, interface=self.table_view, text='更新日志')
+ self.addSubInterface(icon=FIF.CARE_RIGHT_SOLID, interface=self.table_view, text=self.tr('更新日志'))
self.show()
diff --git a/gui/fragments/home.py b/gui/fragments/home.py
index 15042a4a3..7fd150dea 100644
--- a/gui/fragments/home.py
+++ b/gui/fragments/home.py
@@ -15,8 +15,10 @@
)
from core.notification import notify
+from gui.util.translator import baasTranslator as bt
from window import Window
+
MAIN_BANNER = 'gui/assets/banner_home_bg.png'
@@ -50,10 +52,10 @@ def __init__(self, parent: Window = None, config=None):
self.info_box.setFixedHeight(45)
self.infoLayout = QHBoxLayout(self.info_box)
- title = f'蔚蓝档案自动脚本 {self.config.get("name")}'
+ title = self.tr("蔚蓝档案自动脚本") + f' {self.config.get("name")}'
self.banner_visible = self.config.get('bannerVisibility')
self.label = SubtitleLabel(title, self)
- self.info = SubtitleLabel('无任务', self)
+ self.info = SubtitleLabel(self.tr('无任务'), self)
setFont(self.label, 24)
setFont(self.info, 24)
@@ -74,7 +76,7 @@ def __init__(self, parent: Window = None, config=None):
self.tr('启动'),
FIF.CARE_RIGHT_SOLID,
self.tr('档案,启动'),
- '开始你的档案之旅',
+ self.tr('开始你的档案之旅'),
self
)
@@ -124,9 +126,9 @@ def call_update(self, data=None, parent=None):
if data:
if type(data[0]) is dict:
- self.info.setText(f'正在运行:{self.event_map[data[0]["func_name"]]}')
+ self.info.setText(self.tr("正在运行:") + bt.tr('ConfigTranslation', self.event_map[data[0]["func_name"]]))
else:
- self.info.setText(f'正在运行:{data[0]}')
+ self.info.setText(self.tr("正在运行:") + bt.tr('ConfigTranslation', data[0]))
_main_thread_ = self.config.get_main_thread()
_baas_thread_ = _main_thread_.get_baas_thread()
if _baas_thread_ is not None:
@@ -151,8 +153,9 @@ def call_update(self, data=None, parent=None):
print("Empty JSON data")
def set_button_state(self, state):
+ state = bt.tr('MainThread', state)
self.startup_card.button.setText(state)
- self._main_thread_attach.running = True if state == "停止" else False
+ self._main_thread_attach.running = True if state == bt.tr("MainThread", "停止") else False
def __initLayout(self):
self.expandLayout.setSpacing(28)
@@ -209,7 +212,7 @@ def __init__(self, config):
def run(self):
self.running = True
- self.display('停止')
+ self.display(self.tr("停止"))
self._init_script()
self._main_thread.logger.info("Starting Blue Archive Auto Script...")
self._main_thread.send('start')
@@ -218,7 +221,7 @@ def stop_play(self):
self.running = False
if self._main_thread is None:
return
- self.display('启动')
+ self.display(self.tr("启动"))
self._main_thread.send('stop')
self.exit(0)
@@ -238,20 +241,20 @@ def display(self, text):
def start_hard_task(self):
self._init_script()
self.update_signal.emit(['困难关推图'])
- self.display('停止')
+ self.display(self.tr("停止"))
if self._main_thread.send('solve', 'explore_hard_task'):
- notify(title='BAAS', body='困难图推图已完成')
- self.update_signal.emit(['无任务'])
- self.display('启动')
+ notify(title='BAAS', body=self.tr('困难图推图已完成'))
+ self.update_signal.emit([self.tr('无任务')])
+ self.display(self.tr("启动"))
def start_normal_task(self):
self._init_script()
- self.update_signal.emit(['普通关推图'])
- self.display('停止')
+ self.update_signal.emit([self.tr('普通关推图')])
+ self.display(self.tr('停止'))
if self._main_thread.send('solve', 'explore_normal_task'):
- notify(title='BAAS', body='普通图推图已完成')
- self.update_signal.emit(['无任务'])
- self.display('启动')
+ notify(title='BAAS', body=self.tr('普通图推图已完成'))
+ self.update_signal.emit([self.tr('无任务')])
+ self.display(self.tr('启动'))
def start_mumu_JP_login_fixer(self):
self._init_script()
@@ -263,67 +266,67 @@ def start_mumu_JP_login_fixer(self):
def start_fhx(self):
self._init_script()
if self._main_thread.send('solve', 'de_clothes'):
- notify(title='BAAS', body='反和谐成功,请重启BA下载资源')
+ notify(title='BAAS', body=self.tr('反和谐成功,请重启BA下载资源'))
def start_main_story(self):
self._init_script()
- self.update_signal.emit(['自动主线剧情'])
- self.display('停止')
+ self.update_signal.emit([self.tr('自动主线剧情')])
+ self.display(self.tr('停止'))
if self._main_thread.send('solve', 'main_story'):
if self._main_thread.flag_run:
- notify(title='BAAS', body='主线剧情已完成')
- self.update_signal.emit(['无任务'])
- self.display('启动')
+ notify(title='BAAS', body=self.tr('主线剧情已完成'))
+ self.update_signal.emit([self.tr('无任务')])
+ self.display(self.tr('启动'))
def start_group_story(self):
self._init_script()
- self.update_signal.emit(['自动小组剧情'])
- self.display('停止')
+ self.update_signal.emit([self.tr('自动小组剧情')])
+ self.display(self.tr('停止'))
if self._main_thread.send('solve', 'group_story'):
if self._main_thread.flag_run:
- notify(title='BAAS', body='小组剧情已完成')
+ notify(title='BAAS', body=self.tr('小组剧情已完成'))
self.display('启动')
- self.update_signal.emit(['无任务'])
+ self.update_signal.emit([self.tr('无任务')])
def start_mini_story(self):
self._init_script()
- self.display('停止')
- self.update_signal.emit(['自动支线剧情'])
+ self.display(self.tr('停止'))
+ self.update_signal.emit([self.tr('自动支线剧情')])
if self._main_thread.send('solve', 'mini_story'):
if self._main_thread.flag_run:
- notify(title='BAAS', body='支线剧情已完成')
- self.display('启动')
- self.update_signal.emit(['无任务'])
+ notify(title='BAAS', body=self.tr('支线剧情已完成'))
+ self.display(self.tr('启动'))
+ self.update_signal.emit([self.tr('无任务')])
def start_explore_activity_story(self):
self._init_script()
- self.display('停止')
- self.update_signal.emit(['自动活动剧情'])
+ self.display(self.tr('停止'))
+ self.update_signal.emit([self.tr('自动活动剧情')])
if self._main_thread.send('solve', 'explore_activity_story'):
if self._main_thread.flag_run:
- notify(title='BAAS', body='活动剧情已完成')
- self.display('启动')
- self.update_signal.emit(['无任务'])
+ notify(title='BAAS', body=self.tr('活动剧情已完成'))
+ self.display(self.tr('启动'))
+ self.update_signal.emit([self.tr('无任务')])
def start_explore_activity_mission(self):
self._init_script()
- self.display('停止')
- self.update_signal.emit(['自动活动任务'])
+ self.display(self.tr('停止'))
+ self.update_signal.emit([self.tr('自动活动任务')])
if self._main_thread.send('solve', 'explore_activity_mission'):
if self._main_thread.flag_run:
- notify(title='BAAS', body='活动任务已完成')
- self.display('启动')
- self.update_signal.emit(['无任务'])
+ notify(title='BAAS', body=self.tr('活动任务已完成'))
+ self.display(self.tr('启动'))
+ self.update_signal.emit([self.tr('无任务')])
def start_explore_activity_challenge(self):
self._init_script()
- self.update_signal.emit(['自动活动挑战'])
- self.display('停止')
+ self.update_signal.emit([self.tr('自动活动挑战')])
+ self.display(self.tr('停止'))
if self._main_thread.send('solve', 'explore_activity_challenge'):
if self._main_thread.flag_run:
- notify(title='BAAS', body='活动挑战推图已完成')
- self.display('启动')
- self.update_signal.emit(['无任务'])
+ notify(title='BAAS', body=self.tr('活动挑战推图已完成'))
+ self.display(self.tr('启动'))
+ self.update_signal.emit([self.tr('无任务')])
def get_baas_thread(self):
return self._main_thread
diff --git a/gui/fragments/process.py b/gui/fragments/process.py
index e4d3da974..bcf8abdd6 100644
--- a/gui/fragments/process.py
+++ b/gui/fragments/process.py
@@ -8,6 +8,8 @@
from qfluentwidgets import (ScrollArea, TitleLabel, SubtitleLabel, ListWidget, StrongBodyLabel)
from gui.components import expand
+from gui.util.translator import baasTranslator as bt
+
lock = threading.Lock()
DISPLAY_CONFIG_PATH = './config/display.json'
@@ -81,15 +83,17 @@ def refresh_status(self):
crt_task = self.baas_thread.scheduler.getCurrentTaskName()
task_list = self.baas_thread.scheduler.getWaitingTaskList()
print(crt_task, task_list)
- crt_task = crt_task if crt_task else "暂无正在执行的任务"
- task_list = [task for task in task_list] if task_list else ["暂无队列中的任务"]
- self.on_status.setText(crt_task)
+
+ crt_task = crt_task if crt_task else self.tr("暂无正在执行的任务")
+ task_list = [bt.tr('ConfigTranslation', task) for task in task_list] if task_list else [self.tr("暂无队列中的任务")]
+ self.on_status.setText(bt.tr('ConfigTranslation', crt_task))
+
self.listWidget.clear()
self.listWidget.addItems(task_list)
else:
- self.on_status.setText("暂无正在执行的任务")
+ self.on_status.setText(self.tr("暂无正在执行的任务"))
self.listWidget.clear()
- self.listWidget.addItems(["暂无队列中的任务"])
+ self.listWidget.addItems([self.tr("暂无队列中的任务")])
main_thread = self.config.get_main_thread()
self.baas_thread = main_thread.get_baas_thread() if main_thread else None
time.sleep(2)
diff --git a/gui/fragments/readme.py b/gui/fragments/readme.py
index a6e916a38..167adf672 100644
--- a/gui/fragments/readme.py
+++ b/gui/fragments/readme.py
@@ -4,6 +4,8 @@
from qfluentwidgets import FluentIcon as FIF, FluentWindow, TextEdit
import os
+from gui.util.translator import baasTranslator as bt
+
class ReadMeInterface(QFrame):
def __init__(self, content: str):
@@ -24,7 +26,7 @@ def __init__(self):
super().__init__()
docs = []
- path = './src/descriptions/'
+ path = self.getPath()
for file in os.listdir(path):
filepath = os.path.join(path, file)
filename = file.split('.')[0]
@@ -36,6 +38,10 @@ def __init__(self):
self.addSubInterface(interface=ReadMeInterface(doc['content']), icon=FIF.TAG, text=doc['title'])
self.show()
+ def getPath(self):
+ directory = f'./src/descriptions/{bt.stringLang}'
+ if os.path.isdir(directory):
+ return directory
if __name__ == '__main__':
import sys
diff --git a/gui/fragments/settings.py b/gui/fragments/settings.py
index 1ca8093a0..310d30d8b 100644
--- a/gui/fragments/settings.py
+++ b/gui/fragments/settings.py
@@ -4,11 +4,14 @@
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget
-from qfluentwidgets import (ExpandLayout, ScrollArea, TitleLabel, SettingCardGroup)
+from qfluentwidgets import (ComboBoxSettingCard, ExpandLayout, FluentIcon as FIF, ScrollArea, TitleLabel, SettingCardGroup)
+import window
from gui.components import expand
from gui.components.template_card import SimpleSettingCard
-
+from gui.util.language import Language
+from gui.util import notification
+from gui.util.translator import baasTranslator as bt
class SettingsFragment(ScrollArea):
def __init__(self, parent=None, config=None):
@@ -16,31 +19,40 @@ def __init__(self, parent=None, config=None):
self.config = config
self.scrollWidget = QWidget()
self.expandLayout = ExpandLayout(self.scrollWidget)
- self.settingLabel = TitleLabel(self.tr(f"普通设置 {self.config['name']}"), self.scrollWidget)
+ self.settingLabel = TitleLabel(self.tr(f"普通设置") + f' {self.config["name"]}', self.scrollWidget)
self.basicGroup = SettingCardGroup(
self.tr("基本"), self.scrollWidget)
self.basicGroupItems = [
+ ComboBoxSettingCard(
+ bt.cfg.language,
+ FIF.LANGUAGE,
+ self.tr('语言'),
+ self.tr('设置界面的首选语言'),
+ texts=Language.combobox(),
+ parent=self.basicGroup
+ ),
+
SimpleSettingCard(
- title='应用相关设置',
- content='选择你的服务器平台,设置你的端口(不知道端口请设置为0)',
+ title=self.tr('应用相关设置'),
+ content=self.tr('选择你的服务器平台,设置你的端口(不知道端口请设置为0)'),
sub_view=expand.__dict__['serverConfig'],
parent=self.basicGroup,
config=self.config
),
SimpleSettingCard(
- title='脚本相关设置',
- content='根据你的电脑配置,调整相应的参数。',
+ title=self.tr('脚本相关设置'),
+ content=self.tr('根据你的电脑配置,调整相应的参数。'),
sub_view=expand.__dict__['scriptConfig'],
parent=self.basicGroup,
config=self.config
),
SimpleSettingCard(
- title="模拟器启动设置",
- content="设置启动模拟器的路径",
+ title=self.tr("模拟器启动设置"),
+ content=self.tr("设置启动模拟器的路径"),
sub_view=expand.__dict__['emulatorConfig'],
parent=self.basicGroup,
config=self.config
@@ -52,48 +64,48 @@ def __init__(self, parent=None, config=None):
self.exploreGroupItems = [
SimpleSettingCard(
- title='普通图推图设置',
- content='根据你的推图需求,调整相应的参数。',
+ title=self.tr('普通图推图设置'),
+ content=self.tr('根据你的推图需求,调整相应的参数。'),
sub_view=expand.__dict__['exploreConfig'],
parent=self.exploreGroup,
config=self.config
),
SimpleSettingCard(
- title='困难图推图设置',
- content='根据你所需困难图刷关,设置参数。',
+ title=self.tr('困难图推图设置'),
+ content=self.tr('根据你所需困难图刷关,设置参数。'),
sub_view=expand.__dict__['hardTaskConfig'],
parent=self.exploreGroup,
config=self.config
),
SimpleSettingCard(
- title='推剧情',
- content='主线剧情,小组剧情,支线剧情',
+ title=self.tr('推剧情'),
+ content=self.tr('主线剧情,小组剧情,支线剧情'),
sub_view=expand.__dict__['proceedPlot'],
parent=self.exploreGroup,
config=self.config
),
SimpleSettingCard(
- title='活动图设置',
- content='推故事,推任务,推挑战',
+ title=self.tr('活动图设置'),
+ content=self.tr('推故事,推任务,推挑战'),
sub_view=expand.__dict__['eventMapConfig'],
parent=self.exploreGroup,
config=self.config
),
SimpleSettingCard(
- title='其他设置',
- content='其他的一些小功能与设置',
+ title=self.tr('其他设置'),
+ content=self.tr('其他的一些小功能与设置'),
sub_view=expand.__dict__['otherConfig'],
parent=self.exploreGroup,
config=self.config
),
SimpleSettingCard(
- title='推送设置',
- content='推送信息',
+ title=self.tr('推送设置'),
+ content=self.tr('推送信息'),
sub_view=expand.__dict__['pushConfig'],
parent=self.exploreGroup,
config=self.config
@@ -102,6 +114,7 @@ def __init__(self, parent=None, config=None):
self.__initLayout()
self.object_name = md5(f'{time.time()}%{random()}'.encode('utf-8')).hexdigest()
self.setObjectName(self.object_name)
+ self.__connectSignalToSlot()
def __initLayout(self):
self.expandLayout.setSpacing(28)
@@ -122,3 +135,18 @@ def __initLayout(self):
self.expandLayout.addWidget(self.exploreGroup)
self.setWidget(self.scrollWidget)
+
+ def __showRestartTooltip(self):
+ """ show restart tooltip """
+ if time.time() - window.LAST_NOTICE_TIME < 0.1:
+ return
+ notification.success(
+ 'Language updated successfully',
+ 'It will take effect after restart',
+ self.config
+ )
+ window.LAST_NOTICE_TIME = time.time()
+
+ def __connectSignalToSlot(self):
+ """ connect signal to slot """
+ bt.cfg.appRestartSig.connect(self.__showRestartTooltip)
diff --git a/gui/fragments/switch.py b/gui/fragments/switch.py
index 2a17b9b7a..6f43d5256 100644
--- a/gui/fragments/switch.py
+++ b/gui/fragments/switch.py
@@ -25,7 +25,7 @@ def __init__(self, parent=None, config=None):
# 创建一个ExpandLayout实例作为滚动区域的布局管理器
self.expandLayout = ExpandLayout(self.scrollWidget)
# 创建一个标题为“调度设置”的TitleLabel实例
- self.settingLabel = TitleLabel(self.tr(f"配置设置 {self.config['name']}"), self.scrollWidget)
+ self.settingLabel = TitleLabel(self.tr(f"配置设置") + f" {self.config['name']}", self.scrollWidget)
# 初始化basicGroup变量,_setting_cards列表
self.basicGroup = None
self._setting_cards = []
@@ -102,7 +102,8 @@ def _create_card(self, name: str, tip: str, setting_name: str) -> TemplateSettin
content=tip,
parent=self.basicGroup,
sub_view=expand.__dict__[setting_name] if setting_name else None,
- config=self.config
+ config=self.config,
+ context='ConfigTranslation'
) # 创建TemplateSettingCard实例
# _switch_card.status_switch.setChecked(enabled) # 设置状态开关的选中状态
# _switch_card.statusChanged.connect(lambda x: self._change_status(name, x)) # 连接状态开关的状态更改信号和_change_status()方法
diff --git a/gui/i18n/en_US.qm b/gui/i18n/en_US.qm
new file mode 100644
index 000000000..3260ad423
Binary files /dev/null and b/gui/i18n/en_US.qm differ
diff --git a/gui/i18n/en_US.ts b/gui/i18n/en_US.ts
new file mode 100644
index 000000000..e9b57dd47
--- /dev/null
+++ b/gui/i18n/en_US.ts
@@ -0,0 +1,1416 @@
+
+
+
Auto clear mainline plot settings
+Autoplay can help walk the grid. But... some battles in the Final Episode cannot be fought automatically.
+Numbers and the corresponding Episode
+1 -> Episode I
+2 -> Episode II
+3 -> Episode III
+4 -> Episode IV
+5 -> Final Episode
+6 -> Episode V
+Use "," to separate the numbers to indicate each episode needed to be cleared.
+Example:
+1,2,3
+Means clear Episode I, Episode III, Final Episode sequentially.
+Default configuration(fill nothing in the box and click 'run' button):
+CN : 1,2,3,4
+Global : 1,2,3,4,5,4
+JP: 1,2,3,4,5,4,6
++
For Stimulator multi-instance, please check yourself.+
Single Emulator Port
1. MuMu: 7555
2. Blue stacks/LDPlayer: 5555 (If you use Blue stack emulator check if adb port debug function is open in the settings)
3. NoxPlayer: 62001 / 59865
4. Mumu12:16384
5. memuplay: 21503
+ + diff --git a/src/descriptions/en_US/Description of normal graphs.html b/src/descriptions/en_US/Description of normal graphs.html new file mode 100644 index 000000000..4704f220d --- /dev/null +++ b/src/descriptions/en_US/Description of normal graphs.html @@ -0,0 +1,173 @@ + + + + +
+ Description of normal graphs: +
++ 1. Description of use: +
++ (1): Must + + + Unlock + + + Automatically end rounds and + + + Autofight. + + + (automated detection and opening) +
++ (2): Supported level main line ordinary + + + 4 - 25 + + +
++ (3): Teams move click coordinates and routes when BAAS slides are fixed and all moves are only one click, and because of the number of teams in the Blue Archive slides, the numbering coordinates and the order of movement vary according to the team. +
++ (4): As (3), when automatically extrapolating + + + You have to make sure the selection team numbers are smaller and bigger. + + I don't know. + + + +
++ + + (5): BAAS will choose the basis + + + < Normal Thumbnail Settings > + + + + + the selected group properties + + + + and + + + ♪ Team logic ♪ + + + Find the right configuration for the slide + +
++ The first of the corresponding properties in the following diagrams is [1] and the second is [2]. +
++ Team logic: +
++ 1 Prioritize the selection of the remaining team numbers on the basis of the relationship of restraint and gradually reduce the relationship of attribution to the remaining counterpart. +
++ 2 When selecting a team (4 - the team number) > = the number of remaining teams required. +
++ 3 Gradual reduction of the relationship of restraint among the [1] counterparts, if no assurance is provided for 1 or 2 +
++ 4 If some teams have been selected and 4 - the maximum number of these teams > = the number of remaining teams required, the remaining teams will be filled with an optional number. +
++ 5 None of the above conditions are met, and the selected team number is 1, 2, 3 +
++ + Example: + +
++ Selecting the order of the 23 [Explosion, Crossing] task force +
++ One team, one team. +
++ If an outbreak is numbered 3 and not selected in the above order, select 4 as the second +
++ Choose 12 as the final team if not elected +
++ + + Description of normal graph push-chart level: + + +
++ + 1. If + + + Could not close temporary folder: %s + + + , each number to be filled indicates the area to be pushed, and the program will judge whether each level in the area is to be hit according to whether the current level is sss + +
++ + Example: + +
++ + 15, 16, 14 + +
++ + This represents a roll-down of figure 15,16,14. + +
++ + 2. + + + If + + + Enable mandatory hits at each specified level + + + , enter a number to push the relevant card in the area once and enter a number-number to specify level + +
++ + Example: + +
++ + 15, 16-3 + +
++ + 15-1, 15-2, 15-3, 15-4, 15-5, 16-3 + +
+ + diff --git a/src/descriptions/en_US/Difficult Chart Configuration Description.html b/src/descriptions/en_US/Difficult Chart Configuration Description.html new file mode 100644 index 000000000..de6c80f23 --- /dev/null +++ b/src/descriptions/en_US/Difficult Chart Configuration Description.html @@ -0,0 +1,9 @@ + + + + +The hardship map is used in the same way as the team logic and normal figure, and some of the difficult maps require three teams, all of which have the same attributes as the first for the region.+
Fill in the following instructions:
The string that should be filled in the slide level should not exceed the characters or words "-", "sss", "present", "task", ",", and numbers
Split into several strings after commas
No keyword "sss", "present", "task"
Example: 15,12-2
Three switches (15-1, 15-2, 15-3, 12-2) according to the difficult map settings will be called to sss/take presents/take challenge tasks
2. A number and a string separated by "-"
Example: 15-sss-present
Will be called to sss with gifts (15-1, 15-2, 15-3)
3. Two numbers (specify the corresponding level)
Example: 15-3-sss-task
They'll call 15-3 to sss and complete the challenge.
4. Examples
Switches are all open, fill in: 7,8-sss, 9-3-task
It is indicated that the calls (7-1, 7-2, 7-3) to sss, the gifts and the challenging tasks, (8-1, 8-2, 8-3) to sss, 9-3
Note: Baas will automatically determine whether the level has reached sss, whether it has taken a gift or, if it has reached sss or has taken a gift, skips the level.
Guide for activity sweep fill in:
+Sweep One Quest:
+Sweep Quest Number : 1 Integer in 1 - Maximum difficulty in current activity.
+Number of sweeps:
+1. Integer Means sweep times
+2. Decimal 0.5 indicates that the current AP*0.5 will be used to sweep the quest
+3. Score 1/3 = using current AP*(1/3) to sweep the quest
+Sweep Multiple Quests. :
+Use ',' to join multiple quests, which means sweep them in turn
+Example:
+Sweep Quset:
+9, 10, 11
+Number of sweeps:
+0.5, 3, 1/3
+AP: 999
+Means sweep in turn.
+Quest 9 (999 * 0.5) / 20 = 25 times
+Quest 10 3 times
+Quest 11 (999 * 1/3) / 20 = 16 times
+ + diff --git a/src/descriptions/en_US/Internal settings in BlueArchive game (first-use must read).html b/src/descriptions/en_US/Internal settings in BlueArchive game (first-use must read).html new file mode 100644 index 000000000..c3e7877bb --- /dev/null +++ b/src/descriptions/en_US/Internal settings in BlueArchive game (first-use must read).html @@ -0,0 +1,37 @@ + + + + +Blanche Files Game Internal Settings :
+** Required** :
+Option - > Graphics : Vertical Battle Screen Text Box : Off
+Recollection Lobby : Don't choose Ako, Aru, Wakamo
+Language(Global Server) : English
+Recommended Selection (does not affect script running)
+Resolution | +Highest | +
FPS | +60 | +
Accelerate rendering mode | +Compatibility | +
Post-processing | +ON | +
Anti-aliasing | +ON | +
+ + diff --git a/src/descriptions/en_US/Normal Sweeping Scanning Description.html b/src/descriptions/en_US/Normal Sweeping Scanning Description.html new file mode 100644 index 000000000..6314c8b75 --- /dev/null +++ b/src/descriptions/en_US/Normal Sweeping Scanning Description.html @@ -0,0 +1,68 @@ + + + + +
+ Each sweep configuration is like 'region ' - 'task number ' - 'sweep times ' +
++ Organisation + + Regional + + 'region' + + Level + + "task-number" + + Number of sweeps + + @sweeptimes +
++ Each configuration is separated by ', ' +
++ 1. + + + Available Sweep Levels + + + : +
++ All maps after Academy 1 and 5 +
++ 2. + + + Special description + + +
++ International, `sweep times' can be `max' +
++ The tutorial requires 'region' as a fixed string'tutorian' +
++ BAAS calculates whether the current level can be cleaned, depending on the current physical strength and the level of the level. +
++ Example: +
++ When the international uniform is physically adequate +
++ TUTORIAL-1-20, 15-3, 20-3-max +
++ It means cleaning the curriculum 1 20 times, then cleaning 15-3, 3 times, and then all the physical sweeps 20-3 times. +
+ + diff --git a/src/descriptions/en_US/Task force attributes required by region.html b/src/descriptions/en_US/Task force attributes required by region.html new file mode 100644 index 000000000..d04a49ad7 --- /dev/null +++ b/src/descriptions/en_US/Task force attributes required by region.html @@ -0,0 +1,8 @@ + + + + + +25 [ Sonic , Piercing ]
24 [ Sonic , Explosive ]
23 [ Explosive , Piercing ]
22 [ Piercing , Mystic ]
21 [ Mystic , Explosive ]
20 [ Explosive , Piercing ]
19 [ Piercing , Mystic ]
18 [ Mystic , Explosive ]
17 [ Explosive , Piercing ]
16 [ Piercing , Mystic ]
15 [ Mystic , Mystic ]
14 [ Explosive , Mystic ]
13 [ Piercing , Piercing ]
12 [ Mystic , Explosive ]
11 [ Piercing , Mystic ]
10 [ Explosive , Mystic ]
9 [ Explosive , Piercing ]
8 [ Piercing , Piercing ]
7 [ Explosive , Explosive ]
6 [ Piercing , Piercing ]
5 [ Explosive ]
4 [ Piercing ]
3 [ Piercing ]
2 [ Explosive ]
1 [ Explosive ]
+ + Let's think about it before we report it: + +
++ + 1. This question has never arisen before and can I try to solve it myself (Baidu, curriculum). + +
++ + It can't be solved. + +
++ + 2. The question arises whether I am running every time. + +
++ + 3. How can I provide sufficient information for others to help me solve the problem? + +
++ + 4. The distribution of colour maps within the qq group may be more attractive to others to help solve problems. + +
++ + + Type of problem versus corresponding + + Reporting (yellow necessary) + + + +
++ + I'm stuck on page XXX! : + +
++ + (1). + + 1280 x 720 games when stuck + + + (Mumu on F9) + + +
++ (2). Baas Logshot +
++ (3). Try to switch pages to see if they only get stuck on this page +
++ + I can't move it! : + +
++ (1) Attempts to repulse the observation of one or two times whether each time the card is in one position. +
++ + + (1). Recording the complete video from the "start-up slide" to the time of the stop, with attention to the simulator and the Bas log interface being recorded on the same screen. + + +
++ + I set up the XXX configuration but didn't fight! I didn't set up XXX but I did! : + +
++ (1) Read the configuration instructions carefully to see if they correctly understand how to fill them out. +
++ + + (2) Configure screenshots and program logs. + + +
diff --git "a/src/descriptions/ja_JP/Azur Archives Game Internals (\345\210\235\343\202\201\343\201\246\350\252\255\343\202\200\343\203\246\343\203\274\343\202\266\343\203\274\343\201\257\345\277\205\350\252\255).html" "b/src/descriptions/ja_JP/Azur Archives Game Internals (\345\210\235\343\202\201\343\201\246\350\252\255\343\202\200\343\203\246\343\203\274\343\202\266\343\203\274\343\201\257\345\277\205\350\252\255).html" new file mode 100644 index 000000000..a4252f900 --- /dev/null +++ "b/src/descriptions/ja_JP/Azur Archives Game Internals (\345\210\235\343\202\201\343\201\246\350\252\255\343\202\200\343\203\246\343\203\274\343\202\266\343\203\274\343\201\257\345\277\205\350\252\255).html" @@ -0,0 +1,92 @@ + + + + + ++ アズールアーカイブ + + ゲーム内の設定 + + : +
++ + + **必須** + + + : +
++ + オプション - >画像 + + :戦闘画面の上下の黒いバー:オフ +
++ + 記憶の殿堂 + + :赤穂、愛瑠、若茂は選ばない +
++ + 国際言語 + + :英語 +
++ + 推奨 + + (スクリプトの実行には影響しません) +
++ 解決 + | ++ 最高 + | +
+ フレーム + | ++ 60 + | +
+ 高速レンダリングモード + | ++ コンパチ + | +
+ 後処理 + | ++ 親切 + | +
+ アンチエイリアシング + | ++ 親切 + | +
+
+ + diff --git "a/src/descriptions/ja_JP/\343\202\250\343\202\271\343\202\253\343\203\254\343\203\274\343\202\267\343\203\247\343\203\263\343\201\256\343\202\254\343\202\244\343\203\211\343\203\251\343\202\244\343\203\263(\351\207\215\350\246\201).html" "b/src/descriptions/ja_JP/\343\202\250\343\202\271\343\202\253\343\203\254\343\203\274\343\202\267\343\203\247\343\203\263\343\201\256\343\202\254\343\202\244\343\203\211\343\203\251\343\202\244\343\203\263(\351\207\215\350\246\201).html" new file mode 100644 index 000000000..ee2b2dc07 --- /dev/null +++ "b/src/descriptions/ja_JP/\343\202\250\343\202\271\343\202\253\343\203\254\343\203\274\343\202\267\343\203\247\343\203\263\343\201\256\343\202\254\343\202\244\343\203\211\343\203\251\343\202\244\343\203\263(\351\207\215\350\246\201).html" @@ -0,0 +1,96 @@ + + ++ + 問題を報告する前に、次の点を考慮してください。 + +
++ + 1.この問題は以前に発生しましたか、そして私はそれを自分で解決しようとすることができますか(Baidu、チュートリアル)。 + +
++ + 解決できない場合 + +
++ + 2.今走るたびにこの問題が発生しますか? + +
++ + 3. 他の人が問題を解決するのを助けるのに十分な情報を提供するにはどうすればいいですか? + +
++ + 4. QQグループにカラーチャートを投稿すると、問題の解決に役立つ他の人にとってより魅力的になる場合があります。 + +
++ + + 問題の種類と対応 + + レポートの内容(黄色が必要) + + + +
++ + 1. XXXページで立ち往生して動かない! : + +
++ + (1). + + スタック時の1280x720ゲーム画面 + + + (MuMuがF9を押すスクリーンショット) + + +
++ (2). Baasログのスクリーンショット +
++ (3). ページを切り替えてみて、このページでしか動かなくなるかどうかを確認してみてください +
++ + 2.絵を押して、格子が立ち往生して動けなくなったら歩きました! : + +
++ (1). もう一度1〜2回押してみて、毎回1つの位置に動かないか確認します。 +
++ + + 「プッシュ開始」をクリックしてから動かなくなったときまでのビデオを録画し、エミュレーターゲームインターフェイスとBaasログインターフェイスの同じ画面記録に注意してください。 + + +
++ + 3. XXX設定をセットアップしましたが、ヒットしませんでした! / XXXをセットしてないのに当たった! : + +
++ (1). 設定手順を注意深く読んで、正しく入力する方法を理解しているかどうかを確認してください。 +
++ + + (2). 設定とプログラムログのスクリーンショット。 + + +
+ + \ No newline at end of file diff --git "a/src/descriptions/ja_JP/\344\270\200\350\210\254\347\232\204\343\201\252\343\202\250\343\203\237\343\203\245\343\203\254\343\203\274\343\202\277 ADB \343\202\242\343\203\211\343\203\254\343\202\271.html" "b/src/descriptions/ja_JP/\344\270\200\350\210\254\347\232\204\343\201\252\343\202\250\343\203\237\343\203\245\343\203\254\343\203\274\343\202\277 ADB \343\202\242\343\203\211\343\203\254\343\202\271.html" new file mode 100644 index 000000000..6655babe7 --- /dev/null +++ "b/src/descriptions/ja_JP/\344\270\200\350\210\254\347\232\204\343\201\252\343\202\250\343\203\237\343\203\245\343\203\254\343\203\274\343\202\277 ADB \343\202\242\343\203\211\343\203\254\343\202\271.html" @@ -0,0 +1,8 @@ + + ++
+複数のポートはご自身でご確認ください+
シミュレータポートを1つ開く
1.MuMu:7555
2.ブルースタック/サンダーボルト:5555(開いているadbポートデバッグ機能を確認するためのBlueStacksエミュレーター)
3.ナイトゴッド:62001/59865
4.むむ12:16384
5. MEmu: 21503
+ + \ No newline at end of file diff --git "a/src/descriptions/ja_JP/\345\220\204\345\234\260\345\237\237\343\201\253\345\277\205\350\246\201\343\201\252\343\203\201\343\203\274\343\203\240\345\261\236\346\200\247.html" "b/src/descriptions/ja_JP/\345\220\204\345\234\260\345\237\237\343\201\253\345\277\205\350\246\201\343\201\252\343\203\201\343\203\274\343\203\240\345\261\236\346\200\247.html" new file mode 100644 index 000000000..f43f0e5e8 --- /dev/null +++ "b/src/descriptions/ja_JP/\345\220\204\345\234\260\345\237\237\343\201\253\345\277\205\350\246\201\343\201\252\343\203\201\343\203\274\343\203\240\345\261\236\346\200\247.html" @@ -0,0 +1,165 @@ + + + + + +
+ + + 26 [ ミスティック , アウトブレイク ] + + +
+
+
+
+ 25[ 振動 , スルー ]
+
+
+
+
+
+ 24[ 振動 ・ 破裂 ]
+
+
+
+
+
+ 23[ 発生 、 を通じて ]
+
+
+
+
+
+ 22 [ スルー , ミステリー ]
+
+
+
+
+
+ 21[ ミステリー , アウトブレイク ]
+
+
+
+
+
+ 20[ 発生 ・ 通し ]
+
+
+
+
+
+ 19[ 通し , ミスティック ]
+
+
+
+
+
+ 18[ ミスティック , アウトブレイク ]
+
+
+
+
+
+ 17[ 発生 , 浸透]
+
+
+
+
+
+ 16[ 通し 、 ミスティック ]
+
+
+
+
+
+ 15[ ミステリー , ミステリー ]
+
+
+
+
+
+ 14[ アウトブレイク , ミステリー ]
+
+
+
+
+
+ 13[ スルー , スルー ]
+
+
+
+
+
+ 12[ ミステリー , アウトブレイク ]
+
+
+
+
+
+ 11[ スルー , ミステリー ]
+
+
+
+
+
+ 10[ アウトブレイク , ミステリー ]
+
+
+
+
+
+ 9 [ 発生 、 を通じて ]
+
+
+
+
+
+ 8 [ 貫通 、 貫通 ]
+
+
+
+
+
+ 7 [ アウトブレイク , アウトブレイク ]
+
+
+
+
+
+ 6 [ スルー 、 スルー ]
+
+
+
+
+
+ 5 [ アウトブレイク ]
+
+
+
+
+
+ 4 [ から ]
+
+
+
+
+
+ 3 [ から ]
+
+
+
+
+
+ 2 [ アウトブレイク ]
+
+
+
+
+
+ 1 [ アウトブレイク ]
+
+
+
+ + + メインストーリーのパラメータ設定 + + +
++ + + プロットの自動プッシュは、グリッドの移動に役立ちます + + + だがしかし + + + 最終章では、一部の戦闘が自動でプレイできない + + +
++ + 番号はチャプターマッピングに対応 + +
++ + 1:チャプター1 + +
++ + 2: チャプター2 + +
++ + 3: チャプター3 + +
++ + 4:チャプター4 + +
++ + 5:最終章 + +
++ + 6: チャプター5 + +
++ + プッシュするチャプタは、""で区切って順番に示されます。 + +
++ + 例: + +
++ + 135年 + +
++ + 第1章、第3章、最終章が順番に押されるということです + +
++ + 何も残さないと、デフォルト設定が使用されます + +
++ + 代表ユニフォーム:1、2、3 + +
++ + 国際: 1, 2, 3, 4, 5, 4 + +
++ + 毎日: 1, 2, 3, 4, 5, 4, 6 + +
++
+ + + スケジュール設定の入力に関するヘルプ: + + +
++ 1.優先度:キューに2つ以上のタスクがある場合、優先度の低いタスクが優先されます +
++ 2.実行間隔:整数0は1日の間隔を意味します。 +
++ 3.デイリーリセット: +
++ 対応するタスクをこれらの時刻に実行します (複数のタイムスタンプをコンマで区切ることができます)。 +
++ [[Ha, Mark, S]]の形式に入力します。 + + + (UTC時間) + + +
++ + + 例 + + :[ [ 0 , 0 , 0 ] , [ 20 , 0 , 0 ] ] + +
++ + 表示:北京時間(UTC + 8)8時、4時の固定実行 + +
++ 4.無効期間: +
++ 無効になっているすべての期間にタスクを実行しない (複数の期間をカンマで区切って指定できます) +
++ [ [ [ h1, m1, s1 ] , [ h2 , m2 , s1 ] ] の形式 に入力します。 + + + (UTC時間) + + +
++ + + 例 + + :[ [ 0 , 0 , 0 ] , [ 24, 0 , 0 ] ] + +
++ + 一日中やらないということ + +
++ 5. プレタスク、ポストタスク:プレタスクのすべてのタスクをタスクの前(後)に実行します +
+ + diff --git "a/src/descriptions/ja_JP/\351\200\232\345\270\270\343\201\256\343\203\200\343\202\244\343\202\242\343\202\260\343\203\251\343\203\240\343\202\271\343\202\244\343\203\274\343\203\227\343\202\222\345\237\213\343\202\201\343\202\213\346\211\213\351\240\206.html" "b/src/descriptions/ja_JP/\351\200\232\345\270\270\343\201\256\343\203\200\343\202\244\343\202\242\343\202\260\343\203\251\343\203\240\343\202\271\343\202\244\343\203\274\343\203\227\343\202\222\345\237\213\343\202\201\343\202\213\346\211\213\351\240\206.html" new file mode 100644 index 000000000..ad8341585 --- /dev/null +++ "b/src/descriptions/ja_JP/\351\200\232\345\270\270\343\201\256\343\203\200\343\202\244\343\202\242\343\202\260\343\203\251\343\203\240\343\202\271\343\202\244\343\203\274\343\203\227\343\202\222\345\237\213\343\202\201\343\202\213\346\211\213\351\240\206.html" @@ -0,0 +1,69 @@ + + + + + ++ 各スイープ構成は、「Regin」-「Tasknon」-「Whiptims」のような形をしています。 +
++ 示す + + 地域 + + 'Regian' & Embuspu; + + レベル + + 'Tasker-Nongber' & Embusp; + + スイープの数 + + 'Swiptims' & Embuspu; +
++ 各構成は ',' で区切られます +
++ 1. + + + スイープレベルが利用可能です + + + : +
++ チュートリアル - 1 すべてのマップの後に 5 つのマップがある +
++ 2. + + + 特別な指示 + + +
++ 国際的、日本の「スニプティム」は「マックス」になることができます +
++ チュートリアルでは、文字列 'Tutoriar' を修正するために 'Regian' が必要です +
++ BAASは、現在のスタミナとレベルスタミナに基づいて現在のレベルをスイープできるかどうかを計算し、不足しているレベルや「最大」の数でスイープされたレベルは直接終了します +
++ 例: +
++ 国際線サービスで十分な場合 +
++ チュートリアル-1-20,15-3-3,20-3-MAX +
++ 最初にチュートリアル-1を20回クリーンアップし、次に15-3、3回スイープしてから、すべてのスタミナを20-3スイープすることを示します +
+ + diff --git "a/src/descriptions/ja_JP/\351\200\232\345\270\270\343\201\256\345\233\263\343\201\256\350\252\254\346\230\216\343\201\257\350\207\252\345\213\225\347\232\204\343\201\253\343\203\227\343\203\203\343\202\267\343\203\245\343\201\225\343\202\214\343\201\276\343\201\231.html" "b/src/descriptions/ja_JP/\351\200\232\345\270\270\343\201\256\345\233\263\343\201\256\350\252\254\346\230\216\343\201\257\350\207\252\345\213\225\347\232\204\343\201\253\343\203\227\343\203\203\343\202\267\343\203\245\343\201\225\343\202\214\343\201\276\343\201\231.html" new file mode 100644 index 000000000..1f8eddcd5 --- /dev/null +++ "b/src/descriptions/ja_JP/\351\200\232\345\270\270\343\201\256\345\233\263\343\201\256\350\252\254\346\230\216\343\201\257\350\207\252\345\213\225\347\232\204\343\201\253\343\203\227\343\203\203\343\202\267\343\203\245\343\201\225\343\202\214\343\201\276\343\201\231.html" @@ -0,0 +1,197 @@ + + ++
++ 通常の図の自動プッシュの説明: +
++ 1.使用説明書: +
++ (1):必須 + + + アンロック + + + 自動的にラウンドを終了し、 + + + オートバトル + + + (自動検出してオン) +
++ (2):対応レベルのメインストーリーは正常 + + + 4 - 25 + + +
++ (3):BAASがマップを押すと、チームはクリック座標とルートを移動し、ブルーファイルゲームに複数のチームがある場合、ゲーム内のチームの数、サイズ座標、移動順序によって異なるため、すべての動きは1回しかクリックされません。 +
++ (4):(3)により、画像が自動的にプッシュされた場合 + + + 選択したチームの数が最小から最大であることを確認する必要があります + + 。 + + + +
++ + + (5):BAASはに従って選択します + + + 通常の画像プッシュ画像設定<> + + + + + 選択したチーム属性 + + + + そして + + + <チーム選択ロジック> + + + マップをプッシュするための適切な構成を見つける + +
++ + (6):プッシュ + + + 拍車 + + + レベルは保証される必要があります< + + + + 指定されたすべてのレベルを適用 + + + + >オプション + + + シャットダウン + + + +
++ 最初の属性は [1] で、2 番目の属性は [2] であることに注意してください。 +
++ チーム選択ロジック: +
++ 1 優先保証[1] 拘束関係に基づいて残りのチーム番号を選択し、残りの対応するチーム属性の拘束関係を徐々に減らします。 +
++ 2 チームを選択する場合 (4 - チーム番号) > = 必要な残りのチーム数。 +
++ 3 1と2が保証できない場合は、対応するチームの拘束関係を徐々に減らす[1] +
++ 4 一部のチームが選択され、4 - これらのチームの最大数 >= 残りの必須チーム数の場合、残りのチームはオプションの番号の順に入力されます。 +
++ 5 上記の条件のいずれも満たされない場合、1、2、3... 選択したチームに番号を付ける +
++ + 例: + +
++ 「23フィギュア[バースト、スルー]」のチームを選択する際の順番を試してみてください。 +
++ 最初のチームから抜け出す、最初のチームを通して->最初のチームから抜け出す、2番目のチームを通して->最初のチームから抜け出す、2番目のチームを抜ける->... +
++ ファーストチーム番号が3で、上記の順番で選ばれなかった場合は、4がセカンドチームとして選ばれる +
++ まだ選ばれていない場合は、1 2が最終チームとして選ばれます +
++ + + 通常のマッププッシュのレベルを埋めるための手順: + + +
++ + 1. もし + + + 特定のレベルごとに強制プレイが有効になっていません + + + 記入する各数字は押すエリアを示し、現在のレベルがSSSであるかどうかに応じて、エリア内の各レベルをプレイするかどうかをプログラムが判断します + +
++ + 例: + +
++ + 15,16,14 + +
++ + 15、16、14を順番に押すということです。 + +
++ + 2. + + + もし + + + 特定の各レベルを強制的にプレイできます + + + で、領域内のすべてのレベルを一度プッシュする数値を入力し、指定したレベルを示す数値 - 数値を入力します + +
++ + 例: + +
++ + 15,16-3 + +
++ + これは、15-1、15-2、15-3、15-4、15-5、16-3を順番にプレイすることを意味します + +
+ + \ No newline at end of file diff --git "a/src/descriptions/ja_JP/\351\233\243\346\230\223\345\272\246\345\233\263\346\247\213\346\210\220\343\201\256\350\252\254\346\230\216.html" "b/src/descriptions/ja_JP/\351\233\243\346\230\223\345\272\246\345\233\263\346\247\213\346\210\220\343\201\256\350\252\254\346\230\216.html" new file mode 100644 index 000000000..d79f3ff8a --- /dev/null +++ "b/src/descriptions/ja_JP/\351\233\243\346\230\223\345\272\246\345\233\263\346\247\213\346\210\220\343\201\256\350\252\254\346\230\216.html" @@ -0,0 +1,10 @@ + + + + + +難易度マップの使用方法は、チーム選択ロジックやノーマルマップと同じで、一部の難易度マップには3つのチームが必要であり、3番目のチームの属性は、そのエリアに必要な属性の最初の属性と同じです+
プッシュマップレベルに入力する手順:
プッシュマップレベルに入力される文字列は、これらの文字または単語 "-"、"s"、"precent"、"tasker"、"、"、および数字を超えてはなりません
コンマで分割し、複数の文字列に変換
1.文字列にキーワード「sss」、「present」、「task」がありません
例: 15、12-2
難易度マップに合わせて、マップ設定の3つのスイッチ(15-1、15-2、15-3、12-2)を押して、SSS/プレゼントをもらう/チャレンジタスクをクリアする
2. 数字の後に文字列が続き、"-"で区切られます。
例:15-sss-present
SSSに(15-1、15-2、15-3)ヒットしてプレゼントをもらう
3. 2つの数字(対応するレベルに割り当てられています)
例: 15-3-sss-task
SSSに15-3ヒットし、チャレンジを完了します
4. 事例紹介
スイッチがすべてオンになっているので、7,8-SSS、9-3-taskと入力します。
これは、(7-1、7-2、7-3)がSSSに当たり、ギフトをもらってチャレンジタスクを完了し、(8-1、8-2、8-3)がSSSにヒットし、9-3がチャレンジタスクを完了することを意味します
注:Baasは、レベルがsssにヒットしたかどうか、ギフトを受け取ったかどうかを自動的に判断し、sssがヒットしたかギフトを受け取った場合、レベルはスキップされます。
25[ 振动 , 贯穿 ]
24[ 振动 , 爆发 ]
23[ 爆发 , 贯穿 ]
22[ 贯穿 , 神秘 ]
21[ 神秘 , 爆发 ]
20[ 爆发 , 贯穿 ]
19[ 贯穿 , 神秘 ]
18[ 神秘 , 爆发 ]
17[ 爆发 , 贯穿 ]
16[ 贯穿 , 神秘 ]
15[ 神秘 , 神秘 ]
14[ 爆发 , 神秘 ]
13[ 贯穿 , 贯穿 ]
12[ 神秘 , 爆发 ]
11[ 贯穿 , 神秘 ]
10[ 爆发 , 神秘 ]
9 [ 爆发 , 贯穿 ]
8 [ 贯穿 , 贯穿 ]
7 [ 爆发 , 爆发 ]
6 [ 贯穿 , 贯穿 ]
5 [ 爆发 ]
4 [ 贯穿 ]
3 [ 贯穿 ]
2 [ 爆发 ]
1 [ 爆发 ]
困难图使用说明与选队逻辑和普通图相同,一些困难图需要三支队伍,第三支队伍的属性均与该区域所需属性的第一个属性相同+
推图关卡填写说明:
推图关卡中填写的字符串不应该超出这些字符或单词 "-" , "sss", "present", "task", "," , 和数字
按逗号拆分后转化为若干字符串
1.字符串没有关键字"sss","present","task"
例子:15,12-2
根据困难图推图设置中三个的开关 将(15-1,15-2,15-3,12-2)打到sss/拿礼物/完成挑战任务
2.一个数字并跟字符串,且用"-"分隔
例子: 15-sss-present
会将(15-1,15-2,15-3)打到sss并拿礼物
3.两个数字(指定到对应关卡)
例子:15-3-sss-task
会将15-3打到sss并且完成挑战任务
4.例子
开关都开启,填写: 7,8-sss,9-3-task
表示依次执行(7-1,7-2,7-3)打到sss,拿礼物并完成挑战任务,(8-1,8-2,8-3)打到sss,9-3完成挑战任务
注:Baas会自动判断关卡是否已经打到sss,是否拿了礼物,如果已经打到sss或拿了礼物,则跳过该关卡。
+
多开端口请自行查询+
单开模拟器端口
1.MuMu:7555
2.蓝叠/雷电:5555 (蓝叠模拟器要检查打开adb端口调试功能)
3.夜神:62001 / 59865
4.Mumu12:16384
5.逍遥:21503
diff --git "a/src/descriptions/zh_CN/\346\231\256\351\200\232\345\233\276\346\211\253\350\215\241\345\241\253\345\206\231\350\257\264\346\230\216.html" "b/src/descriptions/zh_CN/\346\231\256\351\200\232\345\233\276\346\211\253\350\215\241\345\241\253\345\206\231\350\257\264\346\230\216.html" new file mode 100644 index 000000000..d64dfe9d9 --- /dev/null +++ "b/src/descriptions/zh_CN/\346\231\256\351\200\232\345\233\276\346\211\253\350\215\241\345\241\253\345\206\231\350\257\264\346\230\216.html" @@ -0,0 +1,20 @@ + + + + + +
每个扫荡配置形如 ’region’ - ‘task number’ - ‘sweep times’
+表示区域'region' 关卡 ‘task-number’ 扫荡次数 ‘sweep times’
+每个配置都用‘,’ 隔开
+1.可用扫荡关卡:
+教程-1与5图后 所有地图
+2.特殊说明
+国际服,日服 ‘sweep times’ 可以为 'max'
+教程需要'region'为固定字符串'tutorial'
+BAAS会根据当前体力和关卡体力计算当前关卡能否扫荡,不足或扫荡完次数为'max'的关卡会直接退出
+例:
+国际服体力充足情况下
+tutorial-1-20,15-3-3,20-3-max
+表示先清理教程-1 20次 ,然后扫荡15-3,3次 ,然后所有体力扫荡20-3
+ + diff --git "a/src/descriptions/zh_CN/\346\231\256\351\200\232\345\233\276\350\207\252\345\212\250\346\216\250\345\233\276\350\257\264\346\230\216.html" "b/src/descriptions/zh_CN/\346\231\256\351\200\232\345\233\276\350\207\252\345\212\250\346\216\250\345\233\276\350\257\264\346\230\216.html" new file mode 100644 index 000000000..d2a520e33 --- /dev/null +++ "b/src/descriptions/zh_CN/\346\231\256\351\200\232\345\233\276\350\207\252\345\212\250\346\216\250\345\233\276\350\257\264\346\230\216.html" @@ -0,0 +1,35 @@ + + + + + +普通图自动推图说明:
+1.使用说明:
+(1):必须解锁自动结束回合和自动战斗(自动检测并开启)
+(2):支持的关卡主线普通4 - 25
+(3):BAAS推图时队伍移动点击坐标和路线是固定的,且所有移动只会点击一次,由于碧蓝档案游戏推图时若有多支队伍,则会根据队伍在游戏内编号大小坐标和移动次序不同。
+(4):由于(3),自动推图时必须保证选择队的伍编号由小到大 。
+(5):BAAS会选择根据<普通图推图设置>中选择的队伍属性和<选队逻辑>寻找合适配置进行推图
+记下列各图对应属性中第一个属性为[1],第二属性为[2]。
+选队逻辑:
+1 优先保证[1]克制关系基础上选择剩余队伍编号,逐渐降低剩余对应队伍属性克制关系。
+2 选择一个队伍时 (4 - 该队伍编号)>= 剩余需要队伍数量。
+3 若无法保证1和2,逐渐降低[1]对应队伍克制关系
+4 如果已选出某些队伍,且 4-这些队伍中最大编号 >= 剩余需要队伍数量,则剩余队伍由可选编号依次填充。
+5 上述条件均不满足,则以1, 2 , 3... 为选择的队伍编号
+例:
+为 "23图 [ 爆发 , 贯穿 ]" 选择队伍时 尝试顺序
+爆发一队,贯穿一队 -> 爆发一队,贯穿二队 -> 爆发一队,爆发二队 -> ...
+如果爆发一队编号为3且按上述顺序未选出,则选择4为第二支队伍
+还未选出则选择 1 2 为最终队伍
+普通图推图关卡填写说明:
+1.如果未启用强制打每一个指定关卡,填写的每一个数字表示要推图的区域,程序会根据当前关卡是否sss判断该区域每一关是否要打
+例:
+15,16,14
+表示依次推15,16,14图。
+2.如果启用强制打每一个指定关卡,则输入一个数字表示推该区域所有关卡一次,输入 数字-数字表示指定关卡
+例:
+15,16-3
+表示依次打15-1,15-2,15-3,15-4,15-5,16-3
+ + diff --git "a/src/descriptions/zh_CN/\346\264\273\345\212\250\346\211\253\350\215\241\345\241\253\345\206\231\350\257\264\346\230\216.html" "b/src/descriptions/zh_CN/\346\264\273\345\212\250\346\211\253\350\215\241\345\241\253\345\206\231\350\257\264\346\230\216.html" new file mode 100644 index 000000000..a0b4a4aeb --- /dev/null +++ "b/src/descriptions/zh_CN/\346\264\273\345\212\250\346\211\253\350\215\241\345\241\253\345\206\231\350\257\264\346\230\216.html" @@ -0,0 +1,26 @@ + + + + + +活动图扫荡填写说明:
+扫荡一关:
+活动关卡扫荡关卡填写:1 - 最高难度 间一个 整数
+扫荡次数:
+1. 整数 表示扫荡次数
+2. 小数 0.5 表示使用当前 体力*0.5 的 体力扫荡该关卡
+3. 分数 1/3 表示使用当前体力的1/3扫荡该关卡
+扫荡多关:
+将多个扫荡一关的关卡和次数用 ',' 隔开,表示依次扫荡这些关卡
+例:
+扫荡关卡:
+9,10,11
+扫荡次数:
+0.5,3,1/3
+体力: 999
+表示依次扫荡
+第9关 (999 * 0.5) / 20 = 25次
+第10关 3 次
+第11关 (999 * 1/3)/ 20 = 16次
+ + diff --git "a/src/descriptions/zh_CN/\347\242\247\350\223\235\346\241\243\346\241\210\346\270\270\346\210\217\345\206\205\351\203\250\350\256\276\347\275\256\357\274\210\345\210\235\346\254\241\344\275\277\347\224\250\345\277\205\350\257\273\357\274\211.html" "b/src/descriptions/zh_CN/\347\242\247\350\223\235\346\241\243\346\241\210\346\270\270\346\210\217\345\206\205\351\203\250\350\256\276\347\275\256\357\274\210\345\210\235\346\254\241\344\275\277\347\224\250\345\277\205\350\257\273\357\274\211.html" new file mode 100644 index 000000000..1de923e7f --- /dev/null +++ "b/src/descriptions/zh_CN/\347\242\247\350\223\235\346\241\243\346\241\210\346\270\270\346\210\217\345\206\205\351\203\250\350\256\276\347\275\256\357\274\210\345\210\235\346\254\241\344\275\277\347\224\250\345\277\205\350\257\273\357\274\211.html" @@ -0,0 +1,38 @@ + + + + + +碧蓝档案游戏内部设置:
+**必选**:
+选项->图像:战斗画面上下黑边:OFF
+记忆大厅:不选取亚子,爱露,若藻
+国际服语言:英文
+推荐选取(不影响脚本运行)
+分辨率 | +最高 | +
帧 | +60 | +
加速渲染模式 | +兼容 | +
后期处理 | +ON | +
抗锯齿 | +ON | +
+ + diff --git "a/src/descriptions/zh_CN/\350\207\252\345\212\250\344\270\273\347\272\277\345\211\247\346\203\205\350\257\264\346\230\216.html" "b/src/descriptions/zh_CN/\350\207\252\345\212\250\344\270\273\347\272\277\345\211\247\346\203\205\350\257\264\346\230\216.html" new file mode 100644 index 000000000..907c08871 --- /dev/null +++ "b/src/descriptions/zh_CN/\350\207\252\345\212\250\344\270\273\347\272\277\345\211\247\346\203\205\350\257\264\346\230\216.html" @@ -0,0 +1,27 @@ + + + + + +
主线剧情参数设置
+自动推剧情可以帮助走格子 但是 最终章一些战斗无法自动打
+数字与章节对应表
+1:第一章
+2:第二章
+3:第三章
+4:第四章
+5:最终章
+6:第五章
+用","隔开数字表示依次要推的章节
+例:
+1,3,5
+表示依次推第一章,第三章,最终章
+什么都不填会用默认配置
+国服:1,2,3
+国际服:1,2,3,4,5,4
+日服:1,2,3,4,5,4,6
++
上报问题前请思考:
+1.这个问题以前有没有出现过,我是否能自己尝试解决(Baidu,教程)。
+如果不能解决
+2.我现在是否每次运行都出现这个问题。
+3.我该如何提供足够的信息来让其他人帮我解决问题。
+4.在qq群内发色图或许更能吸引他人帮你解决问题。
+问题类型与对应汇报内容(黄色必要)
+1.我卡在XXX页面不动了!:
+(1).卡住时1280x720游戏画面(MuMu按F9截图)
+(2).Baas日志截图
+(3).尝试切换页面,看一下是否只会卡在这个页面
+2.我推图走格子卡住不动了!:
+(1).尝试重新推1-2次观察是否每次都是卡在一个位置。
+(1).录制完整从点击"开始推图"到卡住时视频,注意模拟器游戏界面和Baas日志界面同屏录制。
+3.我设置了XXX配置但是没有打! / 我没设置XXX但是打了!:
+(1).仔细阅读配置说明,查看是否正确理解该怎么填写。
+(2).配置截图与程序日志截图。
diff --git a/src/descriptions_en_US/1) Common Emulator Adb addresses.html b/src/descriptions_en_US/1) Common Emulator Adb addresses.html new file mode 100644 index 000000000..a6c6eb1ed --- /dev/null +++ b/src/descriptions_en_US/1) Common Emulator Adb addresses.html @@ -0,0 +1,40 @@ + + + + + + +For multiple instance ports, please refer to specific guides for the appropriate port numbers.
+**Mandatory**:
+Settings -> Graphics: Combat Screen Top and Bottom Black Bars: OFF
+Memorial Lobby: Do not select Azi, Elu, Wakamo
+Global Server Language: English
+Recommended Settings (Does not affect script operation)
+Resolution | +Very High | +
---|---|
FPS | +60 | +
Accelerated Rendering Mode | +Compatibility | +
Post-processing | +ON | +
Anti-aliasing | +ON | +
Each sweeping configuration is in the form of 'area - stage number - sweep times'.
+This represents area 'area', stage 'stage number', and sweep times 'sweep times'.
+Each configuration is separated by ','.
+After Tutorial-1 and 5-5, all maps are available for sweeping.
+For Global and Japanese servers, 'sweep times' can be specified as 'max'.
+Tutorial requires 'area' to be the fixed string 'tutorial'.
+BAAS will calculate whether the current stage can be swept based on current AP and stage AP. Insufficient AP or 'max' sweep times will result in skipping.
+Assuming sufficient AP on the Global server:
+tutorial-1-20,15-3-3,20-3-max
+This means first sweep Tutorial-1 20 times, then sweep 15-3 for 3 times, and finally sweep all available stamina on 20-3.
+Sweeping a Single Stage:
+For sweeping event stages, specify: 1 - highest difficulty as an integer.
+Sweeping Frequency:
+1. Integer indicates the number of times to sweep.
+2. Decimal like 0.5 indicates sweeping with current AP * 0.5.
+3. Fraction like 1/3 indicates sweeping with 1/3 of current AP.
+Separate multiple stages and sweep counts with ',', indicating sweeping these stages sequentially.
+Example:
+Sweeping Stages:
+9,10,11
+Sweeping Counts:
+0.5,3,1/3
+AP: 999
+Represents sweeping:
+Stage 9: (999 * 0.5) / 20 = 25 times
+Stage 10: 3 times
+Stage 11: (999 * 1/3) / 20 = 16 times
+5) Clear Stage Logic & Instructions:
+ +1. Usage Instructions:
++ (1) Unlock auto end-turn and + auto battle (automatically detected and activated). +
+(2) Supports campaign mainline levels 4 - 25.
++ (3) When BAAS clear stages, units movement coordinates and routes are fixed. All movements are single-clicks + because in Blue Archive, if there are multiple units, they are arranged based on the units's + internal numbering coordinates and order of movements. +
++ (4) Due to (3), during automatic clear, it is + essential to ensure that unit numbers are in ascending order + . +
+(5) BAAS will select units based on <Clear Normal Mission Settings> + and Unit Selection Logic to find suitable configurations for the stage.
+ +Note down the first type of each area corresponding to [1] and the second type corresponding to [2].
+ +Unit Selection Logic:
+Example:
+
+ For "Area 23 [Burst, Penetrate]," unit selection sequence:
+ Explosive Unit 1, Piercing Unit 1 -> Explosive Unit 1, Piercing Unit 2 -> Explosive Unit 1, Explosive Unit 2 -> ...
+
If Explosive Unit 1 is number 3 and not selected in the above sequence, then select Unit 4 as the second unit.
+If still not selected, then Unit 1 and 2 will be the final units.
+ +Explanation for Clear Normal Mission Options:
++ If forced to play each specified stage is disabled, each number + entered represents the area to be cleared. The program will determine whether each stage in this area needs to + be cleared based on the current stage. +
+Example:
+15,16,14
+Represents playing stages 15, 16, and 14 sequentially.
+ ++ If forced to play each stage is enabled, enter a number + to clear all stages in that area once, or enter a number-range to specify stages. +
+Example:
+15,16-3
+Represents playing levels 15-1, 15-2, 15-3, 15-4, 15-5, and 16-3 sequentially.
+ + diff --git a/src/descriptions_en_US/6) Clear Hard and Normal Stages.html b/src/descriptions_en_US/6) Clear Hard and Normal Stages.html new file mode 100644 index 000000000..5594082a0 --- /dev/null +++ b/src/descriptions_en_US/6) Clear Hard and Normal Stages.html @@ -0,0 +1,55 @@ + + + + + + +Hard stages use the same unit types as Normal stages. Some Hard stages require 3 units, and the 3rd unit's type should match the 1st unit type required for that area.
+1. Strings without the keywords "sss", "present", "task":
+ Example: 15,12-2
+ Clear (15-1, 15-2, 15-3, 12-2) based on Hard stage settings.
2. A number followed by strings, separated by "-":
+ Example: 15-sss-present
+ Clear (15-1, 15-2, 15-3) while aiming "sss"(3 stars) and getting gifts.
3. Two numbers (specified for corresponding stages):
+ Example: 15-3-sss-task
+ Clear 15-3 to reach "sss" and complete challenge tasks.
4. Example:
+ All switches are on, fill in: 7,8-sss,9-3-task
+ Clear (7-1, 7-2, 7-3) while aiming "sss" and completing tasks. Clear (8-1, 8-2, 8-3) while aiming "sss" and completing the 9-3 challenge task.
Note: Baas will automatically check if a stage has reached "sss" or if gifts have been obtained. If these conditions are met, the stage will be skipped.
+25 [Sonic, Piercing]
+24 [Sonic, Explosive]
+23 [Explosive, Piercing]
+22 [Piercing, Mystic]
+21 [Mystic, Explosive]
+20 [Explosive, Piercing]
+19 [Piercing, Mystic]
+18 [Mystic, Explosive]
+17 [Explosive, Piercing]
+16 [Piercing, Mystic]
+15 [Mystic, Mystic]
+14 [Explosive, Mystic]
+13 [Piercing, Piercing]
+12 [Mystic, Explosive]
+11 [Piercing, Mystic]
+10 [Explosive, Mystic]
+9 [Explosive, Piercing]
+8 [Piercing, Piercing]
+7 [Explosive, Explosive]
+6 [Piercing, Piercing]
+5 [Explosive]
+4 [Piercing]
+3 [Piercing]
+2 [Explosive]
+1 [Explosive]
+ + diff --git a/src/descriptions_en_US/8) Main Story Parameters Setting.html b/src/descriptions_en_US/8) Main Story Parameters Setting.html new file mode 100644 index 000000000..001dc7dd8 --- /dev/null +++ b/src/descriptions_en_US/8) Main Story Parameters Setting.html @@ -0,0 +1,45 @@ + + + + + + +Baas can automatically progress through the story, but some battles in the final chapter cannot be automated.
+Number-to-Chapter Reference:
+1: Chapter 1
+2: Chapter 2
+3: Chapter 3
+4: Chapter 4
+5: Final Chapter
+6: Chapter 5
+Separate chapter numbers with "," to indicate the sequence to progress through.
+Example:
+1,3,5
+Progress through Chapter 1, Chapter 3, and the Final Chapter sequentially.
+Leaving it blank will use default configurations.
+For different servers:
+CN Server: 1,2,3
+Global Server: 1,2,3,4,5,4
+JP Server: 1,2,3,4,5,4,6
+Before Reporting an Issue, Consider:
+1. Has this issue occurred before? Can I attempt to resolve it myself (using Baidu or tutorials)?
+If Unable to Resolve:
+2. Is this issue happening consistently every time I run?
+3. How can I provide enough information to help others assist me in solving the problem?
+4. Posting colorful images in the QQ group might attract more help to solve the problem.
+Issue Types and Corresponding Reporting Contents (Yellow highlights are necessary)
+1. I'm stuck on the XXX page and can't proceed!
+(1). Take a screenshot of the 1280x720 game screen when stuck (Press F9 in MuMu to capture)
+(2). Capture Baas logs
+(3). Try switching pages to see if it's consistently stuck on this page
+2. I'm stuck while progressing through the grid!
+(1). Try restarting and observing 1-2 times to see if it gets stuck at the same spot.
+(1). Record a complete video from clicking "Start Mission" until getting stuck, ensuring both the emulator game interface and Baas log interface are captured in the video.
+3. I configured XXX but it didn't work! / I didn't configure XXX but it worked!
+(1). Read the configuration instructions carefully to ensure correct understanding of how to fill them.
+(2). Provide screenshots of the configuration and Baas logs.
+ + diff --git a/src/explore_task_data/main_story/main_story.py b/src/explore_task_data/main_story/main_story.py index b9b83eedf..40f680ecb 100644 --- a/src/explore_task_data/main_story/main_story.py +++ b/src/explore_task_data/main_story/main_story.py @@ -2,7 +2,7 @@ "Operation-Recapture-Schale-2": { "will-fight": False, "start": [], - "actions": [ + "action": [ {'t': 'click', 'p': (571, 370), 'wait-over': True, 'desc': "upper right"}, {'t': 'click', 'p': (687, 373), 'wait-over': True, 'desc': "right"}, @@ -20,7 +20,7 @@ (693, 305), (645, 564) ], - "actions": [ + "action": [ {'t': 'click', 'p': (378, 422), 'wait-over': True, 'desc': "1 left"}, {'t': 'click', 'p': (698, 308), 'wait-over': True, 'desc': "2 upper right"}, {'t': 'click', 'p': (701, 472), 'wait-over': True, 'desc': "3 lower right"}, @@ -35,7 +35,7 @@ "The-First-Sanctum-Abydos-Desert-District": { "will-fight": True, "start": [], - "actions": [ + "action": [ {'t': 'click', 'p': (576, 368), 'wait-over': True, 'desc': "1 upper right"}, {'t': 'click', 'p': (698, 473), 'wait-over': True, 'desc': "2 lower right"}, {'t': 'click', 'p': (758, 391), 'ec': True, 'desc': "1 right"}, @@ -45,7 +45,7 @@ "The-Second-Sanctum-Millennium-Ruins-District": { "will-fight": True, "start": [], - "actions": [ + "action": [ {'t': 'click', 'p': (574, 365), 'wait-over': True, 'desc': "1 upper right"}, {'t': 'click', 'p': (759, 388), 'wait-over': True, 'desc': "2 right"}, @@ -59,7 +59,7 @@ "The-Third-Sanctum-Abandoned-Amusement-Park": { "will-fight": True, "start": [], - "actions": [ + "action": [ {'t': 'click', 'p': (562, 534), 'ec': True, 'desc': "1 lower right"}, {'t': 'click', 'p': (845, 499), 'wait-over': True, 'desc': "2 lower right"}, @@ -73,7 +73,7 @@ "The-Forth-Sanctum-Basilica-in-the-Catacomb": { "will-fight": True, "start": [], - "actions": [ + "action": [ {'t': 'click', 'p': (570, 541), 'ec': True, 'desc': "1 lower right"}, {'t': 'click', 'p': (680, 302), 'wait-over': True, 'desc': "2 right"}, @@ -84,7 +84,7 @@ "The-Fifth-Sanctum-Outskirts-of-the-City-of-Eridu": { "will-fight": True, "start": [], - "actions": [ + "action": [ {'t': 'click', 'p': (410, 483), 'wait-over': True, 'desc': "1 right"}, {'t': 'end-turn'}, @@ -95,7 +95,7 @@ "The-Final-Defense-Operation-Schale": { "will-fight": True, "start": [], - "actions": [ + "action": [ {'t': 'click', 'p': (641, 467), 'wait-over': True, 'desc': "1 right"}, {'t': 'end-turn'}, @@ -106,7 +106,7 @@ "Rush": { "will-fight": True, "start": [], - "actions": [ + "action": [ {'t': 'click', 'p': (637, 425), "ec": True, 'desc': "1 upper right"}, {'t': 'click', 'p': (458, 341), 'wait-over': True, 'desc': "2 upper left"}, {'t': 'click', 'p': (761, 391), 'wait-over': True, 'desc': "3 right"}, @@ -116,7 +116,7 @@ {'t': 'click', 'p': (615, 332), 'wait-over': True, 'desc': "1 upper right"}, {'t': 'click', 'p': (662, 361), 'wait-over': True, 'desc': "1 upper right"}, - {'end-turn'}, + {'t': 'end-turn'}, ] } } diff --git a/src/rgb_feature/rgb_feature_CN.json b/src/rgb_feature/rgb_feature_CN.json index 0e9901ca7..29ab0f89c 100644 --- a/src/rgb_feature/rgb_feature_CN.json +++ b/src/rgb_feature/rgb_feature_CN.json @@ -16,7 +16,7 @@ "formation_edit2":[[[121,201],[121,285],[121,357],[121,432],[9,201],[9,285],[9,357],[9,432]],[[235,255,235,255,235,255],[34,54,59,79,89,109],[235,255,235,255,235,255],[235,255,235,255,235,255],[235,255,235,255,235,255],[34,54,59,79,89,109],[235,255,235,255,235,255],[235,255,235,255,235,255]]], "formation_edit3":[[[121,201],[121,285],[121,357],[121,432],[9,201],[9,285],[9,357],[9,432]],[[235,255,235,255,235,255],[235,255,235,255,235,255],[34,54,59,79,89,109],[235,255,235,255,235,255],[235,255,235,255,235,255],[235,255,235,255,235,255],[34,54,59,79,89,109],[235,255,235,255,235,255]]], "formation_edit4":[[[121,201],[121,285],[121,357],[121,432],[9,201],[9,285],[9,357],[9,432]],[[235,255,235,255,235,255],[235,255,235,255,235,255],[235,255,235,255,235,255],[34,54,59,79,89,109],[235,255,235,255,235,255],[235,255,235,255,235,255],[235,255,235,255,235,255],[34,54,59,79,89,109]]], - "fighting_feature": [[[834, 694], [782, 678], [811,681]],[[35, 75, 187, 207, 235, 255],[0,67, 57,98,120, 200],[0,67, 57,99,120, 200]]], + "fighting_feature": [[[834, 694], [782, 678], [811,681]],[[35, 75, 187, 227, 235, 255],[0,67, 57,98,120, 200],[0,67, 57,99,120, 200]]], "total_assault_rank_info":[[[131,167],[613,174],[673,174],[1115,183]],[[245,255,245,255,245,255],[245,255,245,255,245,255],[159,179,214,234,234,254],[159,179,214,234,234,254]]], "total_assault_accumulated_point_reward": [[[131,167],[613,174],[673,174],[1115,183],[121,242],[352,235],[109, 308],[370, 306]],[[159,179,214,234,234,254],[159,179,214,234,234,254],[245,255,245,255,245,255],[245,255,245,255,245,255],[245,255,245,255,245,255],[245,255,245,255,245,255],[41,61,64,84,95,115],[41,61,64,84,95,115]]], "total_assault_rank_reward": [[[131,167],[613,174],[673,174],[1115,183],[121,242],[352,235],[109, 308],[370, 306]],[[159,179,214,234,234,254],[159,179,214,234,234,254],[245,255,245,255,245,255],[245,255,245,255,245,255],[41,61,64,84,95,115],[41,61,64,84,95,115],[245,255,245,255,245,255],[245,255,245,255,245,255]]], diff --git a/src/rgb_feature/rgb_feature_JP.json b/src/rgb_feature/rgb_feature_JP.json index af1fcb52b..661910105 100644 --- a/src/rgb_feature/rgb_feature_JP.json +++ b/src/rgb_feature/rgb_feature_JP.json @@ -16,7 +16,7 @@ "formation_edit2":[[[121,201],[121,285],[121,357],[121,432],[9,201],[9,285],[9,357],[9,432]],[[235,255,235,255,235,255],[34,54,59,79,89,109],[235,255,235,255,235,255],[235,255,235,255,235,255],[235,255,235,255,235,255],[34,54,59,79,89,109],[235,255,235,255,235,255],[235,255,235,255,235,255]]], "formation_edit3":[[[121,201],[121,285],[121,357],[121,432],[9,201],[9,285],[9,357],[9,432]],[[235,255,235,255,235,255],[235,255,235,255,235,255],[34,54,59,79,89,109],[235,255,235,255,235,255],[235,255,235,255,235,255],[235,255,235,255,235,255],[34,54,59,79,89,109],[235,255,235,255,235,255]]], "formation_edit4":[[[121,201],[121,285],[121,357],[121,432],[9,201],[9,285],[9,357],[9,432]],[[235,255,235,255,235,255],[235,255,235,255,235,255],[235,255,235,255,235,255],[34,54,59,79,89,109],[235,255,235,255,235,255],[235,255,235,255,235,255],[235,255,235,255,235,255],[34,54,59,79,89,109]]], - "fighting_feature": [[[834, 694], [782, 678], [814,668]],[[35, 75, 187, 207, 235, 255],[0,57, 57,92,120, 200],[0,57, 57,92,120, 200]]], + "fighting_feature": [[[834, 694], [782, 678], [811,681]],[[35, 75, 187, 227, 235, 255],[0,57, 57,92,120, 200],[0,57, 57,92,120, 200]]], "total_assault_rank_info":[[[131,167],[613,174],[673,174],[1115,183]],[[245,255,245,255,245,255],[245,255,245,255,245,255],[159,179,214,234,234,254],[159,179,214,234,234,254]]], "total_assault_accumulated_point_reward": [[[131,167],[613,174],[673,174],[1115,183],[121,242],[352,235],[109, 308],[370, 306]],[[159,179,214,234,234,254],[159,179,214,234,234,254],[245,255,245,255,245,255],[245,255,245,255,245,255],[245,255,245,255,245,255],[245,255,245,255,245,255],[41,61,64,84,95,115],[41,61,64,84,95,115]]], "total_assault_rank_reward": [[[131,167],[613,174],[673,174],[1115,183],[121,242],[352,235],[109, 308],[370, 306]],[[159,179,214,234,234,254],[159,179,214,234,234,254],[245,255,245,255,245,255],[245,255,245,255,245,255],[41,61,64,84,95,115],[41,61,64,84,95,115],[245,255,245,255,245,255],[245,255,245,255,245,255]]], diff --git a/window.py b/window.py index 2448e34ce..bef511031 100644 --- a/window.py +++ b/window.py @@ -7,19 +7,21 @@ import threading from functools import partial -from PyQt5.QtCore import Qt, QSize, QPoint, pyqtSignal +from PyQt5.QtCore import Qt, QLocale, QSize, QTranslator, QPoint, pyqtSignal from PyQt5.QtGui import QIcon, QColor from PyQt5.QtWidgets import QApplication, QHBoxLayout -from qfluentwidgets import FluentIcon as FIF, SplashScreen, MSFluentWindow, TabBar, \ - MSFluentTitleBar, MessageBox, TransparentToolButton +from qfluentwidgets import FluentIcon as FIF, FluentTranslator, SplashScreen, MSFluentWindow, TabBar, \ + MSFluentTitleBar, MessageBox, InfoBar, InfoBarIcon, InfoBarPosition, TransparentToolButton from qfluentwidgets import (SubtitleLabel, setFont, setThemeColor) from core import default_config from gui.components.dialog_panel import SaveSettingMessageBox from gui.fragments.process import ProcessFragment from gui.fragments.readme import ReadMeWindow + from gui.util import notification from gui.util.config_set import ConfigSet +from gui.util.translator import baasTranslator as bt # sys.stderr = open('error.log', 'w+', encoding='utf-8') # sys.stdout = open('output.log', 'w+', encoding='utf-8') @@ -27,7 +29,7 @@ # Offer the error to the error.log ICON_DIR = 'gui/assets/logo.png' - +LAST_NOTICE_TIME = 0 def update_config_reserve_old(config_old, config_new): # 保留旧配置原有的键,添加新配置中没有的,删除新配置中没有的键 for key in config_new: @@ -208,7 +210,7 @@ def __init__(self, parent): self.historyButton.clicked.connect(self.onHistoryButtonClicked) self.searchButton = TransparentToolButton(FIF.HELP.icon(), self) - self.searchButton.setToolTip('帮助') + self.searchButton.setToolTip(self.tr('帮助')) self.searchButton.clicked.connect(self.onHelpButtonClicked) # self.tabBar.tabCloseRequested.connect(self.tabRemoveRequest) @@ -299,10 +301,10 @@ def call_update(self): def initNavigation(self): self.navi_btn_list = [ - self.addSubInterface(self.homeInterface, FIF.HOME, '主页'), - self.addSubInterface(self.processInterface, FIF.CALENDAR, '调度'), - self.addSubInterface(self.schedulerInterface, FIF.CALENDAR, '配置'), - self.addSubInterface(self.settingInterface, FIF.SETTING, '设置') + self.addSubInterface(self.homeInterface, FIF.HOME, self.tr('主页')), + self.addSubInterface(self.processInterface, FIF.CALENDAR, self.tr('调度')), + self.addSubInterface(self.schedulerInterface, FIF.CALENDAR, self.tr('配置')), + self.addSubInterface(self.settingInterface, FIF.SETTING, self.tr('设置')) ] for ind, btn in enumerate(self.navi_btn_list): @@ -336,7 +338,7 @@ def closeEvent(self, event): @staticmethod def showHelpModal(): helpModal = ReadMeWindow() - helpModal.setWindowTitle('帮助') + helpModal.setWindowTitle(helpModal.tr('帮助')) helpModal.setWindowIcon(QIcon(ICON_DIR)) helpModal.resize(800, 600) helpModal.setFocus() @@ -381,7 +383,7 @@ def onTabAddRequested(self): if addDialog.exec_(): text = addDialog.pathLineEdit.text() if text in list(map(lambda x: x.config['name'], self.config_dir_list)): - notification.error('设置失败', f'名为“{text}”的配置已经存在!', self) + notification.error(self.tr('设置失败'), f'{self.tr("名为")}“{text}”{self.tr("的配置已经存在!")}', self) return serial_name = str(int(datetime.datetime.now().timestamp())) os.mkdir(f'./config/{serial_name}') @@ -409,8 +411,8 @@ def onTabAddRequested(self): def onTabCloseRequested(self, i0): config_name = self._sub_list[0][i0].config["name"] - title = f'是否要删除配置:{config_name}?' - content = """你需要在确认后重启BAAS以完成更改。""" + title = self.tr('是否要删除配置:') + f' {config_name}?' + content = self.tr("""你需要在确认后重启BAAS以完成更改。""") closeRequestBox = MessageBox(title, content, self) if closeRequestBox.exec(): shutil.rmtree(f'./config/{self._sub_list[0][i0].config.config_dir}') @@ -444,6 +446,16 @@ def start(): QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) app = QApplication(sys.argv) + + # internationalization + translator = FluentTranslator(bt.locale) + bt.load("gui/i18n/" + bt.stringLang) + + app.installTranslator(translator) + app.installTranslator(bt) + + bt.loadCfgTranslation() + w = Window() # 聚焦窗口 w.setFocus(True)