Compare commits
23 Commits
v4.3.6-bet
...
v4.3.8-bet
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5e46040db6 | ||
|
|
f2b04dd0f6 | ||
|
|
2177c1b40e | ||
|
|
d1f4cffe8f | ||
|
|
74ce441b90 | ||
|
|
5893aa2426 | ||
|
|
cb7e7bf9d4 | ||
|
|
fbfdc6aa12 | ||
|
|
e7b6743e10 | ||
|
|
ff4283e917 | ||
|
|
890886d62d | ||
|
|
fd75dda2b1 | ||
|
|
f22c1aeae3 | ||
|
|
d68d49a469 | ||
|
|
1900d4eaf5 | ||
|
|
02833209d5 | ||
| 2058c0218c | |||
|
|
8896e723eb | ||
|
|
edcc614833 | ||
|
|
23fe1ff0be | ||
|
|
19d1dc9f28 | ||
|
|
24b93cfcad | ||
|
|
d3298fac8a |
23
.github/workflows/build-app.yml
vendored
23
.github/workflows/build-app.yml
vendored
@@ -55,6 +55,8 @@ jobs:
|
|||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
pip install flake8 pytest
|
pip install flake8 pytest
|
||||||
pip install -r requirements.txt
|
pip install -r requirements.txt
|
||||||
|
choco install innosetup
|
||||||
|
echo "C:\Program Files (x86)\Inno Setup 6" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
|
||||||
- name: Lint with flake8
|
- name: Lint with flake8
|
||||||
run: |
|
run: |
|
||||||
# stop the build if there are Python syntax errors or undefined names
|
# stop the build if there are Python syntax errors or undefined names
|
||||||
@@ -71,14 +73,11 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
$MAIN_VERSION=(Get-Content -Path "version_info.txt" -TotalCount 1).Trim()
|
$MAIN_VERSION=(Get-Content -Path "version_info.txt" -TotalCount 1).Trim()
|
||||||
"AUTO_MAA_version=$MAIN_VERSION" | Out-File -FilePath $env:GITHUB_ENV -Append
|
"AUTO_MAA_version=$MAIN_VERSION" | Out-File -FilePath $env:GITHUB_ENV -Append
|
||||||
$UPDATER_VERSION=(Get-Content -Path "version_info.txt" -TotalCount 2 | Select-Object -Index 1).Trim()
|
|
||||||
"updater_version=$UPDATER_VERSION" | Out-File -FilePath $env:GITHUB_ENV -Append
|
|
||||||
- name: Upload Artifact
|
- name: Upload Artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
name: AUTO_MAA_${{ env.AUTO_MAA_version }}
|
name: AUTO_MAA_${{ env.AUTO_MAA_version }}
|
||||||
path: |
|
path: AUTO_MAA_${{ env.AUTO_MAA_version }}.zip
|
||||||
AUTO_MAA_${{ env.AUTO_MAA_version }}.zip
|
|
||||||
- name: Upload Version_Info Artifact
|
- name: Upload Version_Info Artifact
|
||||||
uses: actions/upload-artifact@v4
|
uses: actions/upload-artifact@v4
|
||||||
with:
|
with:
|
||||||
@@ -110,8 +109,11 @@ jobs:
|
|||||||
NAME="$(sed 's/\r$//g' <(head -n 1 version_info.txt))"
|
NAME="$(sed 's/\r$//g' <(head -n 1 version_info.txt))"
|
||||||
TAGNAME="$(sed 's/\r$//g' <(head -n 1 version_info.txt))"
|
TAGNAME="$(sed 's/\r$//g' <(head -n 1 version_info.txt))"
|
||||||
NOTES_MAIN="$(sed 's/\r$//g' <(tail -n +3 version_info.txt))"
|
NOTES_MAIN="$(sed 's/\r$//g' <(tail -n +3 version_info.txt))"
|
||||||
NOTES_TAIL="\`\`\`本release通过GitHub Actions自动构建\`\`\`"
|
NOTES="$NOTES_MAIN
|
||||||
NOTES="$NOTES_MAIN<br><br>$NOTES_TAIL"
|
|
||||||
|
[已有 Mirror酱 CDK ?前往 Mirror酱 高速下载](https://mirrorchyan.com/zh/projects?rid=AUTO_MAA)
|
||||||
|
|
||||||
|
\`\`\`本release通过GitHub Actions自动构建\`\`\`"
|
||||||
if [ "${{ github.ref_name }}" == "main" ]; then
|
if [ "${{ github.ref_name }}" == "main" ]; then
|
||||||
PRERELEASE_FLAG=""
|
PRERELEASE_FLAG=""
|
||||||
else
|
else
|
||||||
@@ -126,12 +128,3 @@ jobs:
|
|||||||
gh workflow run --repo $GITHUB_REPOSITORY mirrorchyan_release_note
|
gh workflow run --repo $GITHUB_REPOSITORY mirrorchyan_release_note
|
||||||
env:
|
env:
|
||||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
- name: Setup SSH Key
|
|
||||||
run: |
|
|
||||||
mkdir -p ~/.ssh
|
|
||||||
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
|
|
||||||
chmod 600 ~/.ssh/id_rsa
|
|
||||||
ssh-keyscan -H ${{ secrets.SERVER_IP }} >> ~/.ssh/known_hosts
|
|
||||||
- name: Upload Release to Server
|
|
||||||
run: |
|
|
||||||
scp -r artifacts/* ${{ secrets.SERVER_USER }}@${{ secrets.SERVER_IP }}:/home/user/files/AUTO_MAA/
|
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ from .core import QueueConfig, MaaConfig, MaaUserConfig, Task, TaskManager, Main
|
|||||||
from .models import MaaManager
|
from .models import MaaManager
|
||||||
from .services import Notify, Crypto, System
|
from .services import Notify, Crypto, System
|
||||||
from .ui import AUTO_MAA
|
from .ui import AUTO_MAA
|
||||||
from .utils import DownloadManager
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"QueueConfig",
|
"QueueConfig",
|
||||||
@@ -47,5 +46,4 @@ __all__ = [
|
|||||||
"Crypto",
|
"Crypto",
|
||||||
"System",
|
"System",
|
||||||
"AUTO_MAA",
|
"AUTO_MAA",
|
||||||
"DownloadManager",
|
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -260,8 +260,10 @@ class QueueConfig(QConfig):
|
|||||||
self.queueSet_AfterAccomplish = OptionsConfigItem(
|
self.queueSet_AfterAccomplish = OptionsConfigItem(
|
||||||
"QueueSet",
|
"QueueSet",
|
||||||
"AfterAccomplish",
|
"AfterAccomplish",
|
||||||
"None",
|
"NoAction",
|
||||||
OptionsValidator(["None", "KillSelf", "Sleep", "Hibernate", "Shutdown"]),
|
OptionsValidator(
|
||||||
|
["NoAction", "KillSelf", "Sleep", "Hibernate", "Shutdown"]
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
self.time_TimeEnabled_0 = ConfigItem(
|
self.time_TimeEnabled_0 = ConfigItem(
|
||||||
@@ -532,7 +534,12 @@ class MaaUserConfig(QConfig):
|
|||||||
self.Info_MedicineNumb = ConfigItem(
|
self.Info_MedicineNumb = ConfigItem(
|
||||||
"Info", "MedicineNumb", 0, RangeValidator(0, 1024)
|
"Info", "MedicineNumb", 0, RangeValidator(0, 1024)
|
||||||
)
|
)
|
||||||
self.Info_SeriesNumb = ConfigItem("Info", "SeriesNumb", 1, RangeValidator(1, 6))
|
self.Info_SeriesNumb = OptionsConfigItem(
|
||||||
|
"Info",
|
||||||
|
"SeriesNumb",
|
||||||
|
"1",
|
||||||
|
OptionsValidator(["1000", "6", "5", "4", "3", "2", "1", "-1"]),
|
||||||
|
)
|
||||||
self.Info_GameId = ConfigItem("Info", "GameId", "-")
|
self.Info_GameId = ConfigItem("Info", "GameId", "-")
|
||||||
self.Info_GameId_1 = ConfigItem("Info", "GameId_1", "-")
|
self.Info_GameId_1 = ConfigItem("Info", "GameId_1", "-")
|
||||||
self.Info_GameId_2 = ConfigItem("Info", "GameId_2", "-")
|
self.Info_GameId_2 = ConfigItem("Info", "GameId_2", "-")
|
||||||
@@ -617,11 +624,12 @@ class MaaUserConfig(QConfig):
|
|||||||
|
|
||||||
class AppConfig(GlobalConfig):
|
class AppConfig(GlobalConfig):
|
||||||
|
|
||||||
VERSION = "4.3.6.2"
|
VERSION = "4.3.8.2"
|
||||||
|
|
||||||
gameid_refreshed = Signal()
|
gameid_refreshed = Signal()
|
||||||
PASSWORD_refreshed = Signal()
|
PASSWORD_refreshed = Signal()
|
||||||
user_info_changed = Signal()
|
user_info_changed = Signal()
|
||||||
|
power_sign_changed = Signal()
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__()
|
super().__init__()
|
||||||
@@ -644,6 +652,7 @@ class AppConfig(GlobalConfig):
|
|||||||
"ALL": {"value": [], "text": []},
|
"ALL": {"value": [], "text": []},
|
||||||
"Today": {"value": [], "text": []},
|
"Today": {"value": [], "text": []},
|
||||||
}
|
}
|
||||||
|
self.power_sign = "NoAction"
|
||||||
self.if_ignore_silence = False
|
self.if_ignore_silence = False
|
||||||
self.if_database_opened = False
|
self.if_database_opened = False
|
||||||
|
|
||||||
@@ -1305,6 +1314,12 @@ class AppConfig(GlobalConfig):
|
|||||||
|
|
||||||
self.user_info_changed.emit()
|
self.user_info_changed.emit()
|
||||||
|
|
||||||
|
def set_power_sign(self, sign: str) -> None:
|
||||||
|
"""设置当前电源状态"""
|
||||||
|
|
||||||
|
self.power_sign = sign
|
||||||
|
self.power_sign_changed.emit()
|
||||||
|
|
||||||
def save_history(self, key: str, content: dict) -> None:
|
def save_history(self, key: str, content: dict) -> None:
|
||||||
"""保存历史记录"""
|
"""保存历史记录"""
|
||||||
|
|
||||||
|
|||||||
@@ -265,28 +265,14 @@ class _TaskManager(QObject):
|
|||||||
Config.queue_dict[name]["Config"].get(
|
Config.queue_dict[name]["Config"].get(
|
||||||
Config.queue_dict[name]["Config"].queueSet_AfterAccomplish
|
Config.queue_dict[name]["Config"].queueSet_AfterAccomplish
|
||||||
)
|
)
|
||||||
!= "None"
|
!= "NoAction"
|
||||||
|
and Config.power_sign == "NoAction"
|
||||||
):
|
):
|
||||||
|
Config.set_power_sign(
|
||||||
from app.ui import ProgressRingMessageBox
|
Config.queue_dict[name]["Config"].get(
|
||||||
|
Config.queue_dict[name]["Config"].queueSet_AfterAccomplish
|
||||||
mode_book = {
|
|
||||||
"Shutdown": "关机",
|
|
||||||
"Hibernate": "休眠",
|
|
||||||
"Sleep": "睡眠",
|
|
||||||
"KillSelf": "关闭AUTO_MAA",
|
|
||||||
}
|
|
||||||
|
|
||||||
choice = ProgressRingMessageBox(
|
|
||||||
Config.main_window,
|
|
||||||
f"{mode_book[Config.queue_dict[name]["Config"].get(Config.queue_dict[name]["Config"].queueSet_AfterAccomplish)]}倒计时",
|
|
||||||
)
|
|
||||||
if choice.exec():
|
|
||||||
System.set_power(
|
|
||||||
Config.queue_dict[name]["Config"].get(
|
|
||||||
Config.queue_dict[name]["Config"].queueSet_AfterAccomplish
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
def check_maa_version(self, v: str):
|
def check_maa_version(self, v: str):
|
||||||
"""检查MAA版本"""
|
"""检查MAA版本"""
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ class _MainTimer(QWidget):
|
|||||||
self.Timer = QTimer()
|
self.Timer = QTimer()
|
||||||
self.Timer.timeout.connect(self.timed_start)
|
self.Timer.timeout.connect(self.timed_start)
|
||||||
self.Timer.timeout.connect(self.set_silence)
|
self.Timer.timeout.connect(self.set_silence)
|
||||||
|
self.Timer.timeout.connect(self.check_power)
|
||||||
self.Timer.start(1000)
|
self.Timer.start(1000)
|
||||||
self.LongTimer = QTimer()
|
self.LongTimer = QTimer()
|
||||||
self.LongTimer.timeout.connect(self.long_timed_task)
|
self.LongTimer.timeout.connect(self.long_timed_task)
|
||||||
@@ -113,5 +114,27 @@ class _MainTimer(QWidget):
|
|||||||
logger.warning(f"FailSafeException: {e}")
|
logger.warning(f"FailSafeException: {e}")
|
||||||
self.if_FailSafeException = True
|
self.if_FailSafeException = True
|
||||||
|
|
||||||
|
def check_power(self):
|
||||||
|
|
||||||
|
if Config.power_sign != "NoAction" and not Config.running_list:
|
||||||
|
|
||||||
|
from app.ui import ProgressRingMessageBox
|
||||||
|
|
||||||
|
mode_book = {
|
||||||
|
"KillSelf": "退出软件",
|
||||||
|
"Sleep": "睡眠",
|
||||||
|
"Hibernate": "休眠",
|
||||||
|
"Shutdown": "关机",
|
||||||
|
}
|
||||||
|
|
||||||
|
choice = ProgressRingMessageBox(
|
||||||
|
Config.main_window, f"{mode_book[Config.power_sign]}倒计时"
|
||||||
|
)
|
||||||
|
if choice.exec():
|
||||||
|
System.set_power(Config.power_sign)
|
||||||
|
Config.set_power_sign("NoAction")
|
||||||
|
else:
|
||||||
|
Config.set_power_sign("NoAction")
|
||||||
|
|
||||||
|
|
||||||
MainTimer = _MainTimer()
|
MainTimer = _MainTimer()
|
||||||
|
|||||||
@@ -923,6 +923,8 @@ class MaaManager(QObject):
|
|||||||
latest_time = start_time
|
latest_time = start_time
|
||||||
for _ in logs[::-1]:
|
for _ in logs[::-1]:
|
||||||
try:
|
try:
|
||||||
|
if "如果长时间无进一步日志更新,可能需要手动干预。" in _:
|
||||||
|
continue
|
||||||
latest_time = datetime.strptime(_[1:20], "%Y-%m-%d %H:%M:%S")
|
latest_time = datetime.strptime(_[1:20], "%Y-%m-%d %H:%M:%S")
|
||||||
break
|
break
|
||||||
except ValueError:
|
except ValueError:
|
||||||
@@ -965,7 +967,7 @@ class MaaManager(QObject):
|
|||||||
else:
|
else:
|
||||||
self.maa_result = "MAA部分任务执行失败"
|
self.maa_result = "MAA部分任务执行失败"
|
||||||
|
|
||||||
elif "请「检查连接设置」或「尝试重启模拟器与 ADB」或「重启电脑」" in log:
|
elif "请 「检查连接设置」 → 「尝试重启模拟器与 ADB」 → 「重启电脑」" in log:
|
||||||
self.maa_result = "MAA的ADB连接异常"
|
self.maa_result = "MAA的ADB连接异常"
|
||||||
|
|
||||||
elif "未检测到任何模拟器" in log:
|
elif "未检测到任何模拟器" in log:
|
||||||
@@ -991,7 +993,7 @@ class MaaManager(QObject):
|
|||||||
elif mode == "人工排查":
|
elif mode == "人工排查":
|
||||||
if "完成任务: StartUp" in log:
|
if "完成任务: StartUp" in log:
|
||||||
self.maa_result = "Success!"
|
self.maa_result = "Success!"
|
||||||
elif "请「检查连接设置」或「尝试重启模拟器与 ADB」或「重启电脑」" in log:
|
elif "请 「检查连接设置」 → 「尝试重启模拟器与 ADB」 → 「重启电脑」" in log:
|
||||||
self.maa_result = "MAA的ADB连接异常"
|
self.maa_result = "MAA的ADB连接异常"
|
||||||
elif "未检测到任何模拟器" in log:
|
elif "未检测到任何模拟器" in log:
|
||||||
self.maa_result = "MAA未检测到任何模拟器"
|
self.maa_result = "MAA未检测到任何模拟器"
|
||||||
@@ -1278,9 +1280,9 @@ class MaaManager(QObject):
|
|||||||
) # 剩余理智关卡
|
) # 剩余理智关卡
|
||||||
data["Configurations"]["Default"][
|
data["Configurations"]["Default"][
|
||||||
"MainFunction.Series.Quantity"
|
"MainFunction.Series.Quantity"
|
||||||
] = str(
|
] = user_data["Info"][
|
||||||
user_data["Info"]["SeriesNumb"]
|
"SeriesNumb"
|
||||||
) # 连战次数
|
] # 连战次数
|
||||||
data["Configurations"]["Default"][
|
data["Configurations"]["Default"][
|
||||||
"Penguin.IsDrGrandet"
|
"Penguin.IsDrGrandet"
|
||||||
] = "False" # 博朗台模式
|
] = "False" # 博朗台模式
|
||||||
@@ -1382,9 +1384,9 @@ class MaaManager(QObject):
|
|||||||
) # 剩余理智关卡
|
) # 剩余理智关卡
|
||||||
data["Configurations"]["Default"][
|
data["Configurations"]["Default"][
|
||||||
"MainFunction.Series.Quantity"
|
"MainFunction.Series.Quantity"
|
||||||
] = str(
|
] = user_data["Info"][
|
||||||
user_data["Info"]["SeriesNumb"]
|
"SeriesNumb"
|
||||||
) # 连战次数
|
] # 连战次数
|
||||||
data["Configurations"]["Default"][
|
data["Configurations"]["Default"][
|
||||||
"GUI.UseAlternateStage"
|
"GUI.UseAlternateStage"
|
||||||
] = "True" # 备选关卡
|
] = "True" # 备选关卡
|
||||||
@@ -1392,6 +1394,17 @@ class MaaManager(QObject):
|
|||||||
"Fight.UseRemainingSanityStage"
|
"Fight.UseRemainingSanityStage"
|
||||||
] = "True" # 使用剩余理智
|
] = "True" # 使用剩余理智
|
||||||
|
|
||||||
|
# 基建模式
|
||||||
|
if (
|
||||||
|
data["Configurations"]["Default"]["Infrast.InfrastMode"]
|
||||||
|
== "Custom"
|
||||||
|
):
|
||||||
|
data["Configurations"]["Default"][
|
||||||
|
"Infrast.CustomInfrastPlanIndex"
|
||||||
|
] = user_data["Data"][
|
||||||
|
"CustomInfrastPlanIndex"
|
||||||
|
] # 自定义基建配置索引
|
||||||
|
|
||||||
# 人工排查配置
|
# 人工排查配置
|
||||||
elif "人工排查" in mode:
|
elif "人工排查" in mode:
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ v4.3
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
from PySide6.QtWidgets import QApplication, QWidget
|
from PySide6.QtWidgets import QApplication
|
||||||
import sys
|
import sys
|
||||||
import ctypes
|
import ctypes
|
||||||
import win32gui
|
import win32gui
|
||||||
@@ -87,7 +87,7 @@ class _SystemHandler:
|
|||||||
|
|
||||||
if sys.platform.startswith("win"):
|
if sys.platform.startswith("win"):
|
||||||
|
|
||||||
if mode == "None":
|
if mode == "NoAction":
|
||||||
|
|
||||||
logger.info("不执行系统电源操作")
|
logger.info("不执行系统电源操作")
|
||||||
|
|
||||||
@@ -115,7 +115,7 @@ class _SystemHandler:
|
|||||||
|
|
||||||
elif sys.platform.startswith("linux"):
|
elif sys.platform.startswith("linux"):
|
||||||
|
|
||||||
if mode == "None":
|
if mode == "NoAction":
|
||||||
|
|
||||||
logger.info("不执行系统电源操作")
|
logger.info("不执行系统电源操作")
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,9 @@ from qfluentwidgets import (
|
|||||||
SwitchButton,
|
SwitchButton,
|
||||||
IndicatorPosition,
|
IndicatorPosition,
|
||||||
Slider,
|
Slider,
|
||||||
|
ScrollArea,
|
||||||
|
Pivot,
|
||||||
|
PivotItem,
|
||||||
)
|
)
|
||||||
from qfluentwidgets.common.overload import singledispatchmethod
|
from qfluentwidgets.common.overload import singledispatchmethod
|
||||||
import os
|
import os
|
||||||
@@ -1128,6 +1131,84 @@ class QuantifiedItemCard(CardWidget):
|
|||||||
self.Layout.addWidget(self.Numb)
|
self.Layout.addWidget(self.Numb)
|
||||||
|
|
||||||
|
|
||||||
|
class PivotArea(ScrollArea):
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
# 创建中间容器并设置布局
|
||||||
|
self.center_container = QWidget()
|
||||||
|
self.center_layout = QHBoxLayout(self.center_container)
|
||||||
|
self.center_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.center_layout.setSpacing(0)
|
||||||
|
self.center_container.setStyleSheet("background: transparent; border: none;")
|
||||||
|
self.center_container.setFixedHeight(45)
|
||||||
|
|
||||||
|
self.pivot = self._Pivot(self)
|
||||||
|
self.pivot.ItemNumbChanged.connect(
|
||||||
|
lambda: QTimer.singleShot(
|
||||||
|
100,
|
||||||
|
lambda: (
|
||||||
|
self.center_container.setFixedWidth(
|
||||||
|
max(self.width() - 2, self.pivot.width())
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.center_layout.addStretch(1)
|
||||||
|
self.center_layout.addWidget(self.pivot)
|
||||||
|
self.center_layout.addStretch(1)
|
||||||
|
|
||||||
|
self.setWidgetResizable(False)
|
||||||
|
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||||
|
self.viewport().setCursor(Qt.ArrowCursor)
|
||||||
|
self.setStyleSheet("background: transparent; border: none;")
|
||||||
|
self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
|
||||||
|
self.setWidget(self.center_container)
|
||||||
|
|
||||||
|
def wheelEvent(self, event):
|
||||||
|
scroll_bar = self.horizontalScrollBar()
|
||||||
|
if scroll_bar.maximum() > 0:
|
||||||
|
delta = event.angleDelta().y()
|
||||||
|
scroll_bar.setValue(scroll_bar.value() - delta // 15)
|
||||||
|
event.ignore()
|
||||||
|
|
||||||
|
def resizeEvent(self, event):
|
||||||
|
super().resizeEvent(event)
|
||||||
|
|
||||||
|
self.center_container.setFixedWidth(max(self.width() - 2, self.pivot.width()))
|
||||||
|
QTimer.singleShot(
|
||||||
|
100,
|
||||||
|
lambda: (
|
||||||
|
self.center_container.setFixedWidth(
|
||||||
|
max(self.width() - 2, self.pivot.width())
|
||||||
|
)
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
class _Pivot(Pivot):
|
||||||
|
|
||||||
|
ItemNumbChanged = Signal()
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
def insertWidget(
|
||||||
|
self, index: int, routeKey: str, widget: PivotItem, onClick=None
|
||||||
|
):
|
||||||
|
super().insertWidget(index, routeKey, widget, onClick)
|
||||||
|
self.ItemNumbChanged.emit()
|
||||||
|
|
||||||
|
def removeWidget(self, routeKey: str):
|
||||||
|
super().removeWidget(routeKey)
|
||||||
|
self.ItemNumbChanged.emit()
|
||||||
|
|
||||||
|
def clear(self):
|
||||||
|
super().clear()
|
||||||
|
self.ItemNumbChanged.emit()
|
||||||
|
|
||||||
|
|
||||||
class QuickExpandGroupCard(ExpandGroupSettingCard):
|
class QuickExpandGroupCard(ExpandGroupSettingCard):
|
||||||
"""全局配置"""
|
"""全局配置"""
|
||||||
|
|
||||||
|
|||||||
@@ -33,8 +33,8 @@ from PySide6.QtWidgets import (
|
|||||||
QHBoxLayout,
|
QHBoxLayout,
|
||||||
)
|
)
|
||||||
from qfluentwidgets import (
|
from qfluentwidgets import (
|
||||||
|
BodyLabel,
|
||||||
CardWidget,
|
CardWidget,
|
||||||
Pivot,
|
|
||||||
ScrollArea,
|
ScrollArea,
|
||||||
FluentIcon,
|
FluentIcon,
|
||||||
HeaderCardWidget,
|
HeaderCardWidget,
|
||||||
@@ -44,13 +44,12 @@ from qfluentwidgets import (
|
|||||||
SubtitleLabel,
|
SubtitleLabel,
|
||||||
PushButton,
|
PushButton,
|
||||||
)
|
)
|
||||||
from PySide6.QtCore import Qt
|
|
||||||
from PySide6.QtGui import QTextCursor
|
from PySide6.QtGui import QTextCursor
|
||||||
from typing import List, Dict
|
from typing import List, Dict
|
||||||
|
|
||||||
|
|
||||||
from app.core import Config, TaskManager, Task, MainInfoBar
|
from app.core import Config, TaskManager, Task, MainInfoBar
|
||||||
from .Widget import StatefulItemCard, ComboBoxMessageBox
|
from .Widget import StatefulItemCard, ComboBoxMessageBox, PivotArea
|
||||||
|
|
||||||
|
|
||||||
class DispatchCenter(QWidget):
|
class DispatchCenter(QWidget):
|
||||||
@@ -60,13 +59,29 @@ class DispatchCenter(QWidget):
|
|||||||
|
|
||||||
self.setObjectName("调度中枢")
|
self.setObjectName("调度中枢")
|
||||||
|
|
||||||
self.pivot = Pivot(self)
|
self.multi_button = PushButton(FluentIcon.ADD, "添加任务", self)
|
||||||
|
self.multi_button.setToolTip("添加任务")
|
||||||
|
self.multi_button.clicked.connect(self.start_multi_task)
|
||||||
|
|
||||||
|
self.power_combox = ComboBox()
|
||||||
|
self.power_combox.addItem("无动作", userData="NoAction")
|
||||||
|
self.power_combox.addItem("退出软件", userData="KillSelf")
|
||||||
|
self.power_combox.addItem("睡眠", userData="Sleep")
|
||||||
|
self.power_combox.addItem("休眠", userData="Hibernate")
|
||||||
|
self.power_combox.addItem("关机", userData="Shutdown")
|
||||||
|
self.power_combox.setCurrentText("无动作")
|
||||||
|
self.power_combox.currentIndexChanged.connect(self.set_power_sign)
|
||||||
|
|
||||||
|
self.pivotArea = PivotArea(self)
|
||||||
|
self.pivot = self.pivotArea.pivot
|
||||||
|
|
||||||
self.stackedWidget = QStackedWidget(self)
|
self.stackedWidget = QStackedWidget(self)
|
||||||
self.Layout = QVBoxLayout(self)
|
self.stackedWidget.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.stackedWidget.setStyleSheet("background: transparent; border: none;")
|
||||||
|
|
||||||
self.script_list: Dict[str, DispatchBox] = {}
|
self.script_list: Dict[str, DispatchCenter.DispatchBox] = {}
|
||||||
|
|
||||||
dispatch_box = DispatchBox("主调度台", self)
|
dispatch_box = self.DispatchBox("主调度台", self)
|
||||||
self.script_list["主调度台"] = dispatch_box
|
self.script_list["主调度台"] = dispatch_box
|
||||||
self.stackedWidget.addWidget(self.script_list["主调度台"])
|
self.stackedWidget.addWidget(self.script_list["主调度台"])
|
||||||
self.pivot.addItem(
|
self.pivot.addItem(
|
||||||
@@ -76,7 +91,15 @@ class DispatchCenter(QWidget):
|
|||||||
icon=FluentIcon.CAFE,
|
icon=FluentIcon.CAFE,
|
||||||
)
|
)
|
||||||
|
|
||||||
self.Layout.addWidget(self.pivot, 0, Qt.AlignHCenter)
|
h_layout = QHBoxLayout()
|
||||||
|
h_layout.addWidget(self.multi_button)
|
||||||
|
h_layout.addWidget(self.pivotArea)
|
||||||
|
h_layout.addWidget(BodyLabel("全部完成后", self))
|
||||||
|
h_layout.addWidget(self.power_combox)
|
||||||
|
h_layout.setContentsMargins(11, 5, 11, 0)
|
||||||
|
|
||||||
|
self.Layout = QVBoxLayout(self)
|
||||||
|
self.Layout.addLayout(h_layout)
|
||||||
self.Layout.addWidget(self.stackedWidget)
|
self.Layout.addWidget(self.stackedWidget)
|
||||||
self.Layout.setContentsMargins(0, 0, 0, 0)
|
self.Layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
@@ -87,7 +110,7 @@ class DispatchCenter(QWidget):
|
|||||||
def add_board(self, task: Task) -> None:
|
def add_board(self, task: Task) -> None:
|
||||||
"""添加一个调度台界面"""
|
"""添加一个调度台界面"""
|
||||||
|
|
||||||
dispatch_box = DispatchBox(task.name, self)
|
dispatch_box = self.DispatchBox(task.name, self)
|
||||||
|
|
||||||
dispatch_box.top_bar.main_button.clicked.connect(
|
dispatch_box.top_bar.main_button.clicked.connect(
|
||||||
lambda: TaskManager.stop_task(task.name)
|
lambda: TaskManager.stop_task(task.name)
|
||||||
@@ -123,7 +146,6 @@ class DispatchCenter(QWidget):
|
|||||||
self.script_list["主调度台"].top_bar.Lable.show()
|
self.script_list["主调度台"].top_bar.Lable.show()
|
||||||
self.script_list["主调度台"].top_bar.object.hide()
|
self.script_list["主调度台"].top_bar.object.hide()
|
||||||
self.script_list["主调度台"].top_bar.mode.hide()
|
self.script_list["主调度台"].top_bar.mode.hide()
|
||||||
self.script_list["主调度台"].top_bar.multi_button.show()
|
|
||||||
self.script_list["主调度台"].top_bar.main_button.clicked.disconnect()
|
self.script_list["主调度台"].top_bar.main_button.clicked.disconnect()
|
||||||
self.script_list["主调度台"].top_bar.main_button.setText("中止任务")
|
self.script_list["主调度台"].top_bar.main_button.setText("中止任务")
|
||||||
self.script_list["主调度台"].top_bar.main_button.clicked.connect(
|
self.script_list["主调度台"].top_bar.main_button.clicked.connect(
|
||||||
@@ -154,7 +176,6 @@ class DispatchCenter(QWidget):
|
|||||||
self.script_list["主调度台"].top_bar.Lable.hide()
|
self.script_list["主调度台"].top_bar.Lable.hide()
|
||||||
self.script_list["主调度台"].top_bar.object.show()
|
self.script_list["主调度台"].top_bar.object.show()
|
||||||
self.script_list["主调度台"].top_bar.mode.show()
|
self.script_list["主调度台"].top_bar.mode.show()
|
||||||
self.script_list["主调度台"].top_bar.multi_button.hide()
|
|
||||||
self.script_list["主调度台"].top_bar.main_button.clicked.disconnect()
|
self.script_list["主调度台"].top_bar.main_button.clicked.disconnect()
|
||||||
self.script_list["主调度台"].top_bar.main_button.setText("开始任务")
|
self.script_list["主调度台"].top_bar.main_button.setText("开始任务")
|
||||||
self.script_list["主调度台"].top_bar.main_button.clicked.connect(
|
self.script_list["主调度台"].top_bar.main_button.clicked.connect(
|
||||||
@@ -208,301 +229,327 @@ class DispatchCenter(QWidget):
|
|||||||
self.script_list["主调度台"].top_bar.mode.addItems(["自动代理", "人工排查"])
|
self.script_list["主调度台"].top_bar.mode.addItems(["自动代理", "人工排查"])
|
||||||
self.script_list["主调度台"].top_bar.mode.setCurrentIndex(0)
|
self.script_list["主调度台"].top_bar.mode.setCurrentIndex(0)
|
||||||
|
|
||||||
|
def update_power_sign(self) -> None:
|
||||||
|
"""更新电源设置"""
|
||||||
|
|
||||||
class DispatchBox(QWidget):
|
mode_book = {
|
||||||
|
"NoAction": "无动作",
|
||||||
|
"KillSelf": "退出软件",
|
||||||
|
"Sleep": "睡眠",
|
||||||
|
"Hibernate": "休眠",
|
||||||
|
"Shutdown": "关机",
|
||||||
|
}
|
||||||
|
self.power_combox.currentIndexChanged.disconnect()
|
||||||
|
self.power_combox.setCurrentText(mode_book[Config.power_sign])
|
||||||
|
self.power_combox.currentIndexChanged.connect(self.set_power_sign)
|
||||||
|
|
||||||
def __init__(self, name: str, parent=None):
|
def set_power_sign(self) -> None:
|
||||||
super().__init__(parent)
|
"""设置所有任务完成后动作"""
|
||||||
|
|
||||||
self.setObjectName(name)
|
if not Config.running_list:
|
||||||
|
|
||||||
layout = QVBoxLayout()
|
self.power_combox.currentIndexChanged.disconnect()
|
||||||
|
self.power_combox.setCurrentText("无动作")
|
||||||
scrollArea = ScrollArea()
|
self.power_combox.currentIndexChanged.connect(self.set_power_sign)
|
||||||
scrollArea.setWidgetResizable(True)
|
logger.warning("没有正在运行的任务,无法设置任务完成后动作")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
content_widget = QWidget()
|
"warning",
|
||||||
content_layout = QVBoxLayout(content_widget)
|
"没有正在运行的任务",
|
||||||
|
"无法设置任务完成后动作",
|
||||||
self.top_bar = self.DispatchTopBar(self, name)
|
5000,
|
||||||
self.info = self.DispatchInfoCard(self)
|
|
||||||
|
|
||||||
content_layout.addWidget(self.top_bar)
|
|
||||||
content_layout.addWidget(self.info)
|
|
||||||
|
|
||||||
scrollArea.setWidget(content_widget)
|
|
||||||
|
|
||||||
layout.addWidget(scrollArea)
|
|
||||||
|
|
||||||
self.setLayout(layout)
|
|
||||||
|
|
||||||
class DispatchTopBar(CardWidget):
|
|
||||||
|
|
||||||
def __init__(self, parent=None, name: str = None):
|
|
||||||
super().__init__(parent)
|
|
||||||
|
|
||||||
Layout = QHBoxLayout(self)
|
|
||||||
|
|
||||||
if name == "主调度台":
|
|
||||||
|
|
||||||
self.Lable = SubtitleLabel("", self)
|
|
||||||
self.Lable.hide()
|
|
||||||
self.object = ComboBox()
|
|
||||||
self.object.setPlaceholderText("请选择调度对象")
|
|
||||||
self.mode = ComboBox()
|
|
||||||
self.mode.setPlaceholderText("请选择调度模式")
|
|
||||||
|
|
||||||
self.multi_button = PushButton("添加任务")
|
|
||||||
self.multi_button.clicked.connect(self.start_multi_task)
|
|
||||||
self.main_button = PushButton("开始任务")
|
|
||||||
self.main_button.clicked.connect(self.start_main_task)
|
|
||||||
self.multi_button.hide()
|
|
||||||
|
|
||||||
Layout.addWidget(self.Lable)
|
|
||||||
Layout.addWidget(self.object)
|
|
||||||
Layout.addWidget(self.mode)
|
|
||||||
Layout.addStretch(1)
|
|
||||||
Layout.addWidget(self.multi_button)
|
|
||||||
Layout.addWidget(self.main_button)
|
|
||||||
|
|
||||||
else:
|
|
||||||
|
|
||||||
self.Lable = SubtitleLabel(name, self)
|
|
||||||
self.main_button = PushButton("中止任务")
|
|
||||||
|
|
||||||
Layout.addWidget(self.Lable)
|
|
||||||
Layout.addStretch(1)
|
|
||||||
Layout.addWidget(self.main_button)
|
|
||||||
|
|
||||||
def start_main_task(self):
|
|
||||||
"""开始任务"""
|
|
||||||
|
|
||||||
if self.object.currentIndex() == -1:
|
|
||||||
logger.warning("未选择调度对象")
|
|
||||||
MainInfoBar.push_info_bar(
|
|
||||||
"warning", "未选择调度对象", "请选择后再开始任务", 5000
|
|
||||||
)
|
|
||||||
return None
|
|
||||||
|
|
||||||
if self.mode.currentIndex() == -1:
|
|
||||||
logger.warning("未选择调度模式")
|
|
||||||
MainInfoBar.push_info_bar(
|
|
||||||
"warning", "未选择调度模式", "请选择后再开始任务", 5000
|
|
||||||
)
|
|
||||||
return None
|
|
||||||
|
|
||||||
if self.object.currentData() in Config.running_list:
|
|
||||||
logger.warning(f"任务已存在:{self.object.currentData()}")
|
|
||||||
MainInfoBar.push_info_bar(
|
|
||||||
"warning", "任务已存在", self.object.currentData(), 5000
|
|
||||||
)
|
|
||||||
return None
|
|
||||||
|
|
||||||
if "调度队列" in self.object.currentData():
|
|
||||||
|
|
||||||
logger.info(f"用户添加任务:{self.object.currentData()}")
|
|
||||||
TaskManager.add_task(
|
|
||||||
f"{self.mode.currentText()}_主调度台",
|
|
||||||
self.object.currentData(),
|
|
||||||
Config.queue_dict[self.object.currentData()]["Config"].toDict(),
|
|
||||||
)
|
|
||||||
|
|
||||||
elif "脚本" in self.object.currentData():
|
|
||||||
|
|
||||||
if Config.member_dict[self.object.currentData()]["Type"] == "Maa":
|
|
||||||
|
|
||||||
logger.info(f"用户添加任务:{self.object.currentData()}")
|
|
||||||
TaskManager.add_task(
|
|
||||||
f"{self.mode.currentText()}_主调度台",
|
|
||||||
"自定义队列",
|
|
||||||
{"Queue": {"Member_1": self.object.currentData()}},
|
|
||||||
)
|
|
||||||
|
|
||||||
def start_multi_task(self):
|
|
||||||
"""开始任务"""
|
|
||||||
|
|
||||||
# 获取所有可用的队列和实例
|
|
||||||
text_list = []
|
|
||||||
data_list = []
|
|
||||||
for name, info in Config.queue_dict.items():
|
|
||||||
if name in Config.running_list:
|
|
||||||
continue
|
|
||||||
text_list.append(
|
|
||||||
"队列"
|
|
||||||
if info["Config"].get(info["Config"].queueSet_Name) == ""
|
|
||||||
else f"队列 - {info["Config"].get(info["Config"].queueSet_Name)}"
|
|
||||||
)
|
|
||||||
data_list.append(name)
|
|
||||||
|
|
||||||
for name, info in Config.member_dict.items():
|
|
||||||
if name in Config.running_list:
|
|
||||||
continue
|
|
||||||
text_list.append(
|
|
||||||
f"实例 - {info['Type']}"
|
|
||||||
if info["Config"].get(info["Config"].MaaSet_Name) == ""
|
|
||||||
else f"实例 - {info['Type']} - {info["Config"].get(info["Config"].MaaSet_Name)}"
|
|
||||||
)
|
|
||||||
data_list.append(name)
|
|
||||||
|
|
||||||
choice = ComboBoxMessageBox(
|
|
||||||
self.window(),
|
|
||||||
"选择一个对象以添加相应多开任务",
|
|
||||||
["选择调度对象"],
|
|
||||||
[text_list],
|
|
||||||
[data_list],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if choice.exec() and choice.input[0].currentIndex() != -1:
|
else:
|
||||||
|
|
||||||
if choice.input[0].currentData() in Config.running_list:
|
Config.set_power_sign(self.power_combox.currentData())
|
||||||
logger.warning(f"任务已存在:{choice.input[0].currentData()}")
|
|
||||||
MainInfoBar.push_info_bar(
|
|
||||||
"warning", "任务已存在", choice.input[0].currentData(), 5000
|
|
||||||
)
|
|
||||||
return None
|
|
||||||
|
|
||||||
if "调度队列" in choice.input[0].currentData():
|
def start_multi_task(self) -> None:
|
||||||
|
"""开始任务"""
|
||||||
|
|
||||||
|
# 获取所有可用的队列和实例
|
||||||
|
text_list = []
|
||||||
|
data_list = []
|
||||||
|
for name, info in Config.queue_dict.items():
|
||||||
|
if name in Config.running_list:
|
||||||
|
continue
|
||||||
|
text_list.append(
|
||||||
|
"队列"
|
||||||
|
if info["Config"].get(info["Config"].queueSet_Name) == ""
|
||||||
|
else f"队列 - {info["Config"].get(info["Config"].queueSet_Name)}"
|
||||||
|
)
|
||||||
|
data_list.append(name)
|
||||||
|
|
||||||
|
for name, info in Config.member_dict.items():
|
||||||
|
if name in Config.running_list:
|
||||||
|
continue
|
||||||
|
text_list.append(
|
||||||
|
f"实例 - {info['Type']}"
|
||||||
|
if info["Config"].get(info["Config"].MaaSet_Name) == ""
|
||||||
|
else f"实例 - {info['Type']} - {info["Config"].get(info["Config"].MaaSet_Name)}"
|
||||||
|
)
|
||||||
|
data_list.append(name)
|
||||||
|
|
||||||
|
choice = ComboBoxMessageBox(
|
||||||
|
self.window(),
|
||||||
|
"选择一个对象以添加相应多开任务",
|
||||||
|
["选择调度对象"],
|
||||||
|
[text_list],
|
||||||
|
[data_list],
|
||||||
|
)
|
||||||
|
|
||||||
|
if choice.exec() and choice.input[0].currentIndex() != -1:
|
||||||
|
|
||||||
|
if choice.input[0].currentData() in Config.running_list:
|
||||||
|
logger.warning(f"任务已存在:{choice.input[0].currentData()}")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"warning", "任务已存在", choice.input[0].currentData(), 5000
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
|
if "调度队列" in choice.input[0].currentData():
|
||||||
|
|
||||||
|
logger.info(f"用户添加任务:{choice.input[0].currentData()}")
|
||||||
|
TaskManager.add_task(
|
||||||
|
"自动代理_新调度台",
|
||||||
|
choice.input[0].currentData(),
|
||||||
|
Config.queue_dict[choice.input[0].currentData()]["Config"].toDict(),
|
||||||
|
)
|
||||||
|
|
||||||
|
elif "脚本" in choice.input[0].currentData():
|
||||||
|
|
||||||
|
if Config.member_dict[choice.input[0].currentData()]["Type"] == "Maa":
|
||||||
|
|
||||||
logger.info(f"用户添加任务:{choice.input[0].currentData()}")
|
logger.info(f"用户添加任务:{choice.input[0].currentData()}")
|
||||||
TaskManager.add_task(
|
TaskManager.add_task(
|
||||||
"自动代理_新调度台",
|
"自动代理_新调度台",
|
||||||
choice.input[0].currentData(),
|
f"自定义队列 - {choice.input[0].currentData()}",
|
||||||
Config.queue_dict[choice.input[0].currentData()][
|
{"Queue": {"Member_1": choice.input[0].currentData()}},
|
||||||
"Config"
|
|
||||||
].toDict(),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
elif "脚本" in choice.input[0].currentData():
|
class DispatchBox(QWidget):
|
||||||
|
|
||||||
if (
|
def __init__(self, name: str, parent=None):
|
||||||
Config.member_dict[choice.input[0].currentData()]["Type"]
|
|
||||||
== "Maa"
|
|
||||||
):
|
|
||||||
|
|
||||||
logger.info(f"用户添加任务:{choice.input[0].currentData()}")
|
|
||||||
TaskManager.add_task(
|
|
||||||
"自动代理_新调度台",
|
|
||||||
f"自定义队列 - {choice.input[0].currentData()}",
|
|
||||||
{"Queue": {"Member_1": choice.input[0].currentData()}},
|
|
||||||
)
|
|
||||||
|
|
||||||
class DispatchInfoCard(HeaderCardWidget):
|
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
|
|
||||||
self.setTitle("调度信息")
|
self.setObjectName(name)
|
||||||
|
|
||||||
self.task = self.TaskInfoCard(self)
|
layout = QVBoxLayout()
|
||||||
self.user = self.UserInfoCard(self)
|
|
||||||
self.log_text = self.LogCard(self)
|
|
||||||
|
|
||||||
self.viewLayout.addWidget(self.task)
|
scrollArea = ScrollArea()
|
||||||
self.viewLayout.addWidget(self.user)
|
scrollArea.setWidgetResizable(True)
|
||||||
self.viewLayout.addWidget(self.log_text)
|
scrollArea.setContentsMargins(0, 0, 0, 0)
|
||||||
|
scrollArea.setStyleSheet("background: transparent; border: none;")
|
||||||
|
|
||||||
self.viewLayout.setStretch(0, 1)
|
content_widget = QWidget()
|
||||||
self.viewLayout.setStretch(1, 1)
|
content_layout = QVBoxLayout(content_widget)
|
||||||
self.viewLayout.setStretch(2, 5)
|
|
||||||
|
|
||||||
def update_board(self, task_list: list, user_list: list, log: str):
|
self.top_bar = self.DispatchTopBar(self, name)
|
||||||
"""更新调度信息"""
|
self.info = self.DispatchInfoCard(self)
|
||||||
|
|
||||||
self.task.update_task(task_list)
|
content_layout.addWidget(self.top_bar)
|
||||||
self.user.update_user(user_list)
|
content_layout.addWidget(self.info)
|
||||||
self.log_text.text.setText(log)
|
|
||||||
|
|
||||||
class TaskInfoCard(HeaderCardWidget):
|
scrollArea.setWidget(content_widget)
|
||||||
|
|
||||||
|
layout.addWidget(scrollArea)
|
||||||
|
|
||||||
|
self.setLayout(layout)
|
||||||
|
|
||||||
|
class DispatchTopBar(CardWidget):
|
||||||
|
|
||||||
|
def __init__(self, parent=None, name: str = None):
|
||||||
|
super().__init__(parent)
|
||||||
|
|
||||||
|
Layout = QHBoxLayout(self)
|
||||||
|
|
||||||
|
if name == "主调度台":
|
||||||
|
|
||||||
|
self.Lable = SubtitleLabel("", self)
|
||||||
|
self.Lable.hide()
|
||||||
|
self.object = ComboBox()
|
||||||
|
self.object.setPlaceholderText("请选择调度对象")
|
||||||
|
self.mode = ComboBox()
|
||||||
|
self.mode.setPlaceholderText("请选择调度模式")
|
||||||
|
|
||||||
|
self.main_button = PushButton("开始任务")
|
||||||
|
self.main_button.clicked.connect(self.start_main_task)
|
||||||
|
|
||||||
|
Layout.addWidget(self.Lable)
|
||||||
|
Layout.addWidget(self.object)
|
||||||
|
Layout.addWidget(self.mode)
|
||||||
|
Layout.addStretch(1)
|
||||||
|
Layout.addWidget(self.main_button)
|
||||||
|
|
||||||
|
else:
|
||||||
|
|
||||||
|
self.Lable = SubtitleLabel(name, self)
|
||||||
|
self.main_button = PushButton("中止任务")
|
||||||
|
|
||||||
|
Layout.addWidget(self.Lable)
|
||||||
|
Layout.addStretch(1)
|
||||||
|
Layout.addWidget(self.main_button)
|
||||||
|
|
||||||
|
def start_main_task(self):
|
||||||
|
"""开始任务"""
|
||||||
|
|
||||||
|
if self.object.currentIndex() == -1:
|
||||||
|
logger.warning("未选择调度对象")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"warning", "未选择调度对象", "请选择后再开始任务", 5000
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
|
if self.mode.currentIndex() == -1:
|
||||||
|
logger.warning("未选择调度模式")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"warning", "未选择调度模式", "请选择后再开始任务", 5000
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
|
if self.object.currentData() in Config.running_list:
|
||||||
|
logger.warning(f"任务已存在:{self.object.currentData()}")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"warning", "任务已存在", self.object.currentData(), 5000
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
|
if "调度队列" in self.object.currentData():
|
||||||
|
|
||||||
|
logger.info(f"用户添加任务:{self.object.currentData()}")
|
||||||
|
TaskManager.add_task(
|
||||||
|
f"{self.mode.currentText()}_主调度台",
|
||||||
|
self.object.currentData(),
|
||||||
|
Config.queue_dict[self.object.currentData()]["Config"].toDict(),
|
||||||
|
)
|
||||||
|
|
||||||
|
elif "脚本" in self.object.currentData():
|
||||||
|
|
||||||
|
if Config.member_dict[self.object.currentData()]["Type"] == "Maa":
|
||||||
|
|
||||||
|
logger.info(f"用户添加任务:{self.object.currentData()}")
|
||||||
|
TaskManager.add_task(
|
||||||
|
f"{self.mode.currentText()}_主调度台",
|
||||||
|
"自定义队列",
|
||||||
|
{"Queue": {"Member_1": self.object.currentData()}},
|
||||||
|
)
|
||||||
|
|
||||||
|
class DispatchInfoCard(HeaderCardWidget):
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
def __init__(self, parent=None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self.setTitle("任务队列")
|
|
||||||
|
|
||||||
self.Layout = QVBoxLayout()
|
self.setTitle("调度信息")
|
||||||
self.viewLayout.addLayout(self.Layout)
|
|
||||||
self.viewLayout.setContentsMargins(3, 0, 3, 3)
|
|
||||||
|
|
||||||
self.task_cards: List[StatefulItemCard] = []
|
self.task = self.TaskInfoCard(self)
|
||||||
|
self.user = self.UserInfoCard(self)
|
||||||
|
self.log_text = self.LogCard(self)
|
||||||
|
|
||||||
def create_task(self, task_list: list):
|
self.viewLayout.addWidget(self.task)
|
||||||
"""创建任务队列"""
|
self.viewLayout.addWidget(self.user)
|
||||||
|
self.viewLayout.addWidget(self.log_text)
|
||||||
|
|
||||||
while self.Layout.count() > 0:
|
self.viewLayout.setStretch(0, 1)
|
||||||
item = self.Layout.takeAt(0)
|
self.viewLayout.setStretch(1, 1)
|
||||||
if item.spacerItem():
|
self.viewLayout.setStretch(2, 5)
|
||||||
self.Layout.removeItem(item.spacerItem())
|
|
||||||
elif item.widget():
|
|
||||||
item.widget().deleteLater()
|
|
||||||
|
|
||||||
self.task_cards = []
|
def update_board(self, task_list: list, user_list: list, log: str):
|
||||||
|
"""更新调度信息"""
|
||||||
|
|
||||||
for task in task_list:
|
self.task.update_task(task_list)
|
||||||
|
self.user.update_user(user_list)
|
||||||
|
self.log_text.text.setText(log)
|
||||||
|
|
||||||
self.task_cards.append(StatefulItemCard(task))
|
class TaskInfoCard(HeaderCardWidget):
|
||||||
self.Layout.addWidget(self.task_cards[-1])
|
|
||||||
|
|
||||||
self.Layout.addStretch(1)
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setTitle("任务队列")
|
||||||
|
|
||||||
def update_task(self, task_list: list):
|
self.Layout = QVBoxLayout()
|
||||||
"""更新任务队列"""
|
self.viewLayout.addLayout(self.Layout)
|
||||||
|
self.viewLayout.setContentsMargins(3, 0, 3, 3)
|
||||||
|
|
||||||
for i in range(len(task_list)):
|
self.task_cards: List[StatefulItemCard] = []
|
||||||
|
|
||||||
self.task_cards[i].update_status(task_list[i][1])
|
def create_task(self, task_list: list):
|
||||||
|
"""创建任务队列"""
|
||||||
|
|
||||||
class UserInfoCard(HeaderCardWidget):
|
while self.Layout.count() > 0:
|
||||||
|
item = self.Layout.takeAt(0)
|
||||||
|
if item.spacerItem():
|
||||||
|
self.Layout.removeItem(item.spacerItem())
|
||||||
|
elif item.widget():
|
||||||
|
item.widget().deleteLater()
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
self.task_cards = []
|
||||||
super().__init__(parent)
|
|
||||||
self.setTitle("用户队列")
|
|
||||||
|
|
||||||
self.Layout = QVBoxLayout()
|
for task in task_list:
|
||||||
self.viewLayout.addLayout(self.Layout)
|
|
||||||
self.viewLayout.setContentsMargins(3, 0, 3, 3)
|
|
||||||
|
|
||||||
self.user_cards: List[StatefulItemCard] = []
|
self.task_cards.append(StatefulItemCard(task))
|
||||||
|
self.Layout.addWidget(self.task_cards[-1])
|
||||||
|
|
||||||
def create_user(self, user_list: list):
|
self.Layout.addStretch(1)
|
||||||
"""创建用户队列"""
|
|
||||||
|
|
||||||
while self.Layout.count() > 0:
|
def update_task(self, task_list: list):
|
||||||
item = self.Layout.takeAt(0)
|
"""更新任务队列"""
|
||||||
if item.spacerItem():
|
|
||||||
self.Layout.removeItem(item.spacerItem())
|
|
||||||
elif item.widget():
|
|
||||||
item.widget().deleteLater()
|
|
||||||
|
|
||||||
self.user_cards = []
|
for i in range(len(task_list)):
|
||||||
|
|
||||||
for user in user_list:
|
self.task_cards[i].update_status(task_list[i][1])
|
||||||
|
|
||||||
self.user_cards.append(StatefulItemCard(user))
|
class UserInfoCard(HeaderCardWidget):
|
||||||
self.Layout.addWidget(self.user_cards[-1])
|
|
||||||
|
|
||||||
self.Layout.addStretch(1)
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setTitle("用户队列")
|
||||||
|
|
||||||
def update_user(self, user_list: list):
|
self.Layout = QVBoxLayout()
|
||||||
"""更新用户队列"""
|
self.viewLayout.addLayout(self.Layout)
|
||||||
|
self.viewLayout.setContentsMargins(3, 0, 3, 3)
|
||||||
|
|
||||||
for i in range(len(user_list)):
|
self.user_cards: List[StatefulItemCard] = []
|
||||||
|
|
||||||
self.user_cards[i].Label.setText(user_list[i][0])
|
def create_user(self, user_list: list):
|
||||||
self.user_cards[i].update_status(user_list[i][1])
|
"""创建用户队列"""
|
||||||
|
|
||||||
class LogCard(HeaderCardWidget):
|
while self.Layout.count() > 0:
|
||||||
|
item = self.Layout.takeAt(0)
|
||||||
|
if item.spacerItem():
|
||||||
|
self.Layout.removeItem(item.spacerItem())
|
||||||
|
elif item.widget():
|
||||||
|
item.widget().deleteLater()
|
||||||
|
|
||||||
def __init__(self, parent=None):
|
self.user_cards = []
|
||||||
super().__init__(parent)
|
|
||||||
self.setTitle("日志")
|
|
||||||
|
|
||||||
self.text = TextBrowser()
|
for user in user_list:
|
||||||
self.viewLayout.setContentsMargins(3, 0, 3, 3)
|
|
||||||
self.viewLayout.addWidget(self.text)
|
|
||||||
|
|
||||||
self.text.textChanged.connect(self.to_end)
|
self.user_cards.append(StatefulItemCard(user))
|
||||||
|
self.Layout.addWidget(self.user_cards[-1])
|
||||||
|
|
||||||
def to_end(self):
|
self.Layout.addStretch(1)
|
||||||
"""滚动到底部"""
|
|
||||||
|
|
||||||
self.text.moveCursor(QTextCursor.End)
|
def update_user(self, user_list: list):
|
||||||
self.text.ensureCursorVisible()
|
"""更新用户队列"""
|
||||||
|
|
||||||
|
for i in range(len(user_list)):
|
||||||
|
|
||||||
|
self.user_cards[i].Label.setText(user_list[i][0])
|
||||||
|
self.user_cards[i].update_status(user_list[i][1])
|
||||||
|
|
||||||
|
class LogCard(HeaderCardWidget):
|
||||||
|
|
||||||
|
def __init__(self, parent=None):
|
||||||
|
super().__init__(parent)
|
||||||
|
self.setTitle("日志")
|
||||||
|
|
||||||
|
self.text = TextBrowser()
|
||||||
|
self.viewLayout.setContentsMargins(3, 0, 3, 3)
|
||||||
|
self.viewLayout.addWidget(self.text)
|
||||||
|
|
||||||
|
self.text.textChanged.connect(self.to_end)
|
||||||
|
|
||||||
|
def to_end(self):
|
||||||
|
"""滚动到底部"""
|
||||||
|
|
||||||
|
self.text.moveCursor(QTextCursor.End)
|
||||||
|
self.text.ensureCursorVisible()
|
||||||
|
|||||||
@@ -21,24 +21,19 @@
|
|||||||
"""
|
"""
|
||||||
AUTO_MAA
|
AUTO_MAA
|
||||||
AUTO_MAA更新器
|
AUTO_MAA更新器
|
||||||
v1.2
|
v4.3
|
||||||
作者:DLmaster_361
|
作者:DLmaster_361
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
|
||||||
import json
|
|
||||||
import zipfile
|
import zipfile
|
||||||
import requests
|
import requests
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
import psutil
|
import psutil
|
||||||
import win32crypt
|
|
||||||
import base64
|
|
||||||
from packaging import version
|
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from PySide6.QtWidgets import QApplication, QDialog, QVBoxLayout
|
from PySide6.QtWidgets import QDialog, QVBoxLayout
|
||||||
from qfluentwidgets import (
|
from qfluentwidgets import (
|
||||||
ProgressBar,
|
ProgressBar,
|
||||||
IndeterminateProgressBar,
|
IndeterminateProgressBar,
|
||||||
@@ -46,7 +41,7 @@ from qfluentwidgets import (
|
|||||||
setTheme,
|
setTheme,
|
||||||
Theme,
|
Theme,
|
||||||
)
|
)
|
||||||
from PySide6.QtGui import QIcon, QCloseEvent
|
from PySide6.QtGui import QCloseEvent
|
||||||
from PySide6.QtCore import QThread, Signal, QTimer, QEventLoop
|
from PySide6.QtCore import QThread, Signal, QTimer, QEventLoop
|
||||||
|
|
||||||
from typing import List, Dict, Union
|
from typing import List, Dict, Union
|
||||||
@@ -237,14 +232,9 @@ class DownloadManager(QDialog):
|
|||||||
self.version = version
|
self.version = version
|
||||||
self.config = config
|
self.config = config
|
||||||
self.download_path = app_path / "DOWNLOAD_TEMP.zip" # 临时下载文件的路径
|
self.download_path = app_path / "DOWNLOAD_TEMP.zip" # 临时下载文件的路径
|
||||||
self.version_path = app_path / "resources/version.json"
|
|
||||||
self.download_process_dict: Dict[str, DownloadProcess] = {}
|
self.download_process_dict: Dict[str, DownloadProcess] = {}
|
||||||
self.timer_dict: Dict[str, QTimer] = {}
|
self.timer_dict: Dict[str, QTimer] = {}
|
||||||
|
|
||||||
self.setWindowTitle("AUTO_MAA更新器")
|
|
||||||
self.setWindowIcon(
|
|
||||||
QIcon(str(app_path / "resources/icons/AUTO_MAA_Updater.ico"))
|
|
||||||
)
|
|
||||||
self.resize(700, 70)
|
self.resize(700, 70)
|
||||||
|
|
||||||
setTheme(Theme.AUTO, lazy=True)
|
setTheme(Theme.AUTO, lazy=True)
|
||||||
@@ -266,14 +256,14 @@ class DownloadManager(QDialog):
|
|||||||
|
|
||||||
def run(self) -> None:
|
def run(self) -> None:
|
||||||
|
|
||||||
if self.name == "MAA":
|
if self.name == "AUTO_MAA":
|
||||||
self.download_task1()
|
|
||||||
elif self.name == "AUTO_MAA":
|
|
||||||
if self.config["mode"] == "Proxy":
|
if self.config["mode"] == "Proxy":
|
||||||
self.test_speed_task1()
|
self.test_speed_task1()
|
||||||
self.speed_test_accomplish.connect(self.download_task1)
|
self.speed_test_accomplish.connect(self.download_task1)
|
||||||
elif self.config["mode"] == "MirrorChyan":
|
elif self.config["mode"] == "MirrorChyan":
|
||||||
self.download_task1()
|
self.download_task1()
|
||||||
|
elif self.config["mode"] == "MirrorChyan":
|
||||||
|
self.download_task1()
|
||||||
|
|
||||||
def get_download_url(self, mode: str) -> Union[str, Dict[str, str]]:
|
def get_download_url(self, mode: str) -> Union[str, Dict[str, str]]:
|
||||||
"""获取下载链接"""
|
"""获取下载链接"""
|
||||||
@@ -300,9 +290,6 @@ class DownloadManager(QDialog):
|
|||||||
|
|
||||||
elif mode == "下载":
|
elif mode == "下载":
|
||||||
|
|
||||||
if self.name == "MAA":
|
|
||||||
return f"https://jp-download.fearr.xyz/MAA/MAA-{version_text(self.version)}-win-x64.zip"
|
|
||||||
|
|
||||||
if self.name == "AUTO_MAA":
|
if self.name == "AUTO_MAA":
|
||||||
|
|
||||||
if self.config["mode"] == "Proxy":
|
if self.config["mode"] == "Proxy":
|
||||||
@@ -325,6 +312,7 @@ class DownloadManager(QDialog):
|
|||||||
return f"{selected_url}https://github.com/DLmaster361/AUTO_MAA/releases/download/{version_text(self.version)}/AUTO_MAA_{version_text(self.version)}.zip"
|
return f"{selected_url}https://github.com/DLmaster361/AUTO_MAA/releases/download/{version_text(self.version)}/AUTO_MAA_{version_text(self.version)}.zip"
|
||||||
|
|
||||||
elif self.config["mode"] == "MirrorChyan":
|
elif self.config["mode"] == "MirrorChyan":
|
||||||
|
|
||||||
with requests.get(
|
with requests.get(
|
||||||
self.config["url"],
|
self.config["url"],
|
||||||
allow_redirects=True,
|
allow_redirects=True,
|
||||||
@@ -334,6 +322,14 @@ class DownloadManager(QDialog):
|
|||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
return response.url
|
return response.url
|
||||||
|
|
||||||
|
elif self.config["mode"] == "MirrorChyan":
|
||||||
|
|
||||||
|
with requests.get(
|
||||||
|
self.config["url"], allow_redirects=True, timeout=10, stream=True
|
||||||
|
) as response:
|
||||||
|
if response.status_code == 200:
|
||||||
|
return response.url
|
||||||
|
|
||||||
def test_speed_task1(self) -> None:
|
def test_speed_task1(self) -> None:
|
||||||
|
|
||||||
if self.isInterruptionRequested:
|
if self.isInterruptionRequested:
|
||||||
@@ -533,41 +529,25 @@ class DownloadManager(QDialog):
|
|||||||
self.zip_extract.start()
|
self.zip_extract.start()
|
||||||
self.zip_loop.exec()
|
self.zip_loop.exec()
|
||||||
|
|
||||||
self.update_info("正在删除已弃用的文件")
|
|
||||||
if (self.app_path / "changes.json").exists():
|
|
||||||
|
|
||||||
with (self.app_path / "changes.json").open(mode="r", encoding="utf-8") as f:
|
|
||||||
info: Dict[str, List[str]] = json.load(f)
|
|
||||||
|
|
||||||
if "deleted" in info:
|
|
||||||
for file_path in info["deleted"]:
|
|
||||||
if (self.app_path / file_path).exists():
|
|
||||||
(self.app_path / file_path).unlink()
|
|
||||||
|
|
||||||
(self.app_path / "changes.json").unlink()
|
|
||||||
|
|
||||||
self.update_info("正在删除临时文件")
|
self.update_info("正在删除临时文件")
|
||||||
self.update_progress(0, 0, 0)
|
self.update_progress(0, 0, 0)
|
||||||
|
if (self.app_path / "changes.json").exists():
|
||||||
|
(self.app_path / "changes.json").unlink()
|
||||||
if self.download_path.exists():
|
if self.download_path.exists():
|
||||||
self.download_path.unlink()
|
self.download_path.unlink()
|
||||||
|
|
||||||
# 主程序更新完成后打开对应程序
|
# 下载完成后打开对应程序
|
||||||
if not self.isInterruptionRequested and self.name == "AUTO_MAA":
|
if not self.isInterruptionRequested and self.name == "MAA":
|
||||||
subprocess.Popen(
|
|
||||||
[self.app_path / "AUTO_MAA.exe"],
|
|
||||||
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
|
|
||||||
| subprocess.DETACHED_PROCESS
|
|
||||||
| subprocess.CREATE_NO_WINDOW,
|
|
||||||
)
|
|
||||||
elif not self.isInterruptionRequested and self.name == "MAA":
|
|
||||||
subprocess.Popen(
|
subprocess.Popen(
|
||||||
[self.app_path / "MAA.exe"],
|
[self.app_path / "MAA.exe"],
|
||||||
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
|
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
|
||||||
| subprocess.DETACHED_PROCESS
|
| subprocess.DETACHED_PROCESS
|
||||||
| subprocess.CREATE_NO_WINDOW,
|
| subprocess.CREATE_NO_WINDOW,
|
||||||
)
|
)
|
||||||
|
if self.name == "AUTO_MAA":
|
||||||
self.update_info(f"{self.name}更新成功!")
|
self.update_info(f"即将安装{self.name}")
|
||||||
|
else:
|
||||||
|
self.update_info(f"{self.name}下载成功!")
|
||||||
self.update_progress(0, 100, 100)
|
self.update_progress(0, 100, 100)
|
||||||
self.download_accomplish.emit()
|
self.download_accomplish.emit()
|
||||||
|
|
||||||
@@ -609,147 +589,3 @@ class DownloadManager(QDialog):
|
|||||||
self.requestInterruption()
|
self.requestInterruption()
|
||||||
|
|
||||||
event.accept()
|
event.accept()
|
||||||
|
|
||||||
|
|
||||||
class AUTO_MAA_Downloader(QApplication):
|
|
||||||
def __init__(
|
|
||||||
self, app_path: Path, name: str, main_version: list, config: dict
|
|
||||||
) -> None:
|
|
||||||
super().__init__()
|
|
||||||
|
|
||||||
self.main = DownloadManager(app_path, name, main_version, config)
|
|
||||||
self.main.show()
|
|
||||||
self.main.run()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
|
|
||||||
# 获取软件自身的路径
|
|
||||||
app_path = Path(sys.argv[0]).resolve().parent
|
|
||||||
|
|
||||||
# 从本地版本信息文件获取当前版本信息
|
|
||||||
if (app_path / "resources/version.json").exists():
|
|
||||||
with (app_path / "resources/version.json").open(
|
|
||||||
mode="r", encoding="utf-8"
|
|
||||||
) as f:
|
|
||||||
current_version_info = json.load(f)
|
|
||||||
current_version = list(
|
|
||||||
map(int, current_version_info["main_version"].split("."))
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
current_version = [0, 0, 0, 0]
|
|
||||||
|
|
||||||
# 从本地配置文件获取更新信息
|
|
||||||
if (app_path / "config/config.json").exists():
|
|
||||||
with (app_path / "config/config.json").open(mode="r", encoding="utf-8") as f:
|
|
||||||
config = json.load(f)
|
|
||||||
if "Update" in config:
|
|
||||||
|
|
||||||
if "UpdateType" in config["Update"]:
|
|
||||||
update_type = config["Update"]["UpdateType"]
|
|
||||||
else:
|
|
||||||
update_type = "stable"
|
|
||||||
if "ProxyUrlList" in config["Update"]:
|
|
||||||
proxy_list = config["Update"]["ProxyUrlList"]
|
|
||||||
else:
|
|
||||||
proxy_list = []
|
|
||||||
if "ThreadNumb" in config["Update"]:
|
|
||||||
thread_numb = config["Update"]["ThreadNumb"]
|
|
||||||
else:
|
|
||||||
thread_numb = 8
|
|
||||||
if "MirrorChyanCDK" in config["Update"]:
|
|
||||||
mirrorchyan_CDK = (
|
|
||||||
win32crypt.CryptUnprotectData(
|
|
||||||
base64.b64decode(config["Update"]["MirrorChyanCDK"]),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
0,
|
|
||||||
)[1].decode("utf-8")
|
|
||||||
if config["Update"]["MirrorChyanCDK"]
|
|
||||||
else ""
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
mirrorchyan_CDK = ""
|
|
||||||
|
|
||||||
else:
|
|
||||||
update_type = "stable"
|
|
||||||
proxy_list = []
|
|
||||||
thread_numb = 8
|
|
||||||
mirrorchyan_CDK = ""
|
|
||||||
else:
|
|
||||||
update_type = "stable"
|
|
||||||
proxy_list = []
|
|
||||||
thread_numb = 8
|
|
||||||
mirrorchyan_CDK = ""
|
|
||||||
|
|
||||||
# 从远程服务器获取最新版本信息
|
|
||||||
for _ in range(3):
|
|
||||||
try:
|
|
||||||
response = requests.get(
|
|
||||||
f"https://mirrorchyan.com/api/resources/AUTO_MAA/latest?user_agent=AutoMaaDownloader¤t_version={version_text(current_version)}&cdk={mirrorchyan_CDK}&channel={update_type}",
|
|
||||||
timeout=10,
|
|
||||||
)
|
|
||||||
version_info: Dict[str, Union[int, str, Dict[str, str]]] = response.json()
|
|
||||||
break
|
|
||||||
except Exception as e:
|
|
||||||
err = e
|
|
||||||
time.sleep(0.1)
|
|
||||||
else:
|
|
||||||
sys.exit(f"获取版本信息时出错:\n{err}")
|
|
||||||
|
|
||||||
if version_info["code"] == 0:
|
|
||||||
|
|
||||||
if "url" in version_info["data"]:
|
|
||||||
download_config = {
|
|
||||||
"mode": "MirrorChyan",
|
|
||||||
"thread_numb": 1,
|
|
||||||
"url": version_info["data"]["url"],
|
|
||||||
}
|
|
||||||
else:
|
|
||||||
|
|
||||||
download_config = {"mode": "Proxy", "thread_numb": thread_numb}
|
|
||||||
else:
|
|
||||||
sys.exit(f"获取版本信息时出错:{version_info["msg"]}")
|
|
||||||
|
|
||||||
remote_version = list(
|
|
||||||
map(
|
|
||||||
int,
|
|
||||||
version_info["data"]["version_name"][1:].replace("-beta", "").split("."),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if download_config["mode"] == "Proxy":
|
|
||||||
for _ in range(3):
|
|
||||||
try:
|
|
||||||
response = requests.get(
|
|
||||||
"https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/download_info.json",
|
|
||||||
timeout=10,
|
|
||||||
)
|
|
||||||
download_info = response.json()
|
|
||||||
|
|
||||||
download_config["proxy_list"] = list(
|
|
||||||
set(proxy_list + download_info["proxy_list"])
|
|
||||||
)
|
|
||||||
download_config["download_dict"] = download_info["download_dict"]
|
|
||||||
break
|
|
||||||
except Exception as e:
|
|
||||||
err = e
|
|
||||||
time.sleep(0.1)
|
|
||||||
else:
|
|
||||||
sys.exit(f"获取代理信息时出错:{err}")
|
|
||||||
|
|
||||||
if (app_path / "changes.json").exists():
|
|
||||||
(app_path / "changes.json").unlink()
|
|
||||||
|
|
||||||
# 启动更新线程
|
|
||||||
if version.parse(version_text(remote_version)) > version.parse(
|
|
||||||
version_text(current_version)
|
|
||||||
):
|
|
||||||
app = AUTO_MAA_Downloader(
|
|
||||||
app_path,
|
|
||||||
"AUTO_MAA",
|
|
||||||
remote_version,
|
|
||||||
download_config,
|
|
||||||
)
|
|
||||||
sys.exit(app.exec())
|
|
||||||
@@ -69,6 +69,8 @@ class History(QWidget):
|
|||||||
|
|
||||||
scrollArea = ScrollArea()
|
scrollArea = ScrollArea()
|
||||||
scrollArea.setWidgetResizable(True)
|
scrollArea.setWidgetResizable(True)
|
||||||
|
scrollArea.setContentsMargins(0, 0, 0, 0)
|
||||||
|
scrollArea.setStyleSheet("background: transparent; border: none;")
|
||||||
scrollArea.setWidget(content_widget)
|
scrollArea.setWidget(content_widget)
|
||||||
layout = QVBoxLayout()
|
layout = QVBoxLayout()
|
||||||
layout.addWidget(self.history_top_bar)
|
layout.addWidget(self.history_top_bar)
|
||||||
|
|||||||
@@ -149,6 +149,8 @@ class Home(QWidget):
|
|||||||
layout = QVBoxLayout()
|
layout = QVBoxLayout()
|
||||||
scrollArea = ScrollArea()
|
scrollArea = ScrollArea()
|
||||||
scrollArea.setWidgetResizable(True)
|
scrollArea.setWidgetResizable(True)
|
||||||
|
scrollArea.setContentsMargins(0, 0, 0, 0)
|
||||||
|
scrollArea.setStyleSheet("background: transparent; border: none;")
|
||||||
scrollArea.setWidget(widget)
|
scrollArea.setWidget(widget)
|
||||||
layout.addWidget(scrollArea)
|
layout.addWidget(scrollArea)
|
||||||
self.setLayout(layout)
|
self.setLayout(layout)
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ v4.3
|
|||||||
from loguru import logger
|
from loguru import logger
|
||||||
from PySide6.QtWidgets import QApplication, QSystemTrayIcon
|
from PySide6.QtWidgets import QApplication, QSystemTrayIcon
|
||||||
from qfluentwidgets import (
|
from qfluentwidgets import (
|
||||||
qconfig,
|
|
||||||
Action,
|
Action,
|
||||||
SystemTrayMenu,
|
SystemTrayMenu,
|
||||||
SplashScreen,
|
SplashScreen,
|
||||||
@@ -182,7 +181,7 @@ class AUTO_MAA(MSFluentWindow):
|
|||||||
Action(
|
Action(
|
||||||
FluentIcon.POWER_BUTTON,
|
FluentIcon.POWER_BUTTON,
|
||||||
"退出主程序",
|
"退出主程序",
|
||||||
triggered=lambda: (self.window().close(), QApplication.quit()),
|
triggered=lambda: System.set_power("KillSelf"),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -193,6 +192,7 @@ class AUTO_MAA(MSFluentWindow):
|
|||||||
self.set_min_method()
|
self.set_min_method()
|
||||||
|
|
||||||
Config.user_info_changed.connect(self.member_manager.refresh_dashboard)
|
Config.user_info_changed.connect(self.member_manager.refresh_dashboard)
|
||||||
|
Config.power_sign_changed.connect(self.dispatch_center.update_power_sign)
|
||||||
TaskManager.create_gui.connect(self.dispatch_center.add_board)
|
TaskManager.create_gui.connect(self.dispatch_center.add_board)
|
||||||
TaskManager.connect_gui.connect(self.dispatch_center.connect_main_board)
|
TaskManager.connect_gui.connect(self.dispatch_center.connect_main_board)
|
||||||
Notify.push_info_bar.connect(MainInfoBar.push_info_bar)
|
Notify.push_info_bar.connect(MainInfoBar.push_info_bar)
|
||||||
@@ -247,10 +247,10 @@ class AUTO_MAA(MSFluentWindow):
|
|||||||
# 清理旧日志
|
# 清理旧日志
|
||||||
self.clean_old_logs()
|
self.clean_old_logs()
|
||||||
|
|
||||||
# 清理临时更新器
|
# 清理安装包
|
||||||
if (Config.app_path / "AUTO_Updater.active.exe").exists():
|
if (Config.app_path / "AUTO_MAA-Setup.exe").exists():
|
||||||
try:
|
try:
|
||||||
(Config.app_path / "AUTO_Updater.active.exe").unlink()
|
(Config.app_path / "AUTO_MAA-Setup.exe").unlink()
|
||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|||||||
@@ -35,9 +35,9 @@ from PySide6.QtWidgets import (
|
|||||||
QTableWidgetItem,
|
QTableWidgetItem,
|
||||||
QHeaderView,
|
QHeaderView,
|
||||||
)
|
)
|
||||||
|
from PySide6.QtGui import QIcon
|
||||||
from qfluentwidgets import (
|
from qfluentwidgets import (
|
||||||
Action,
|
Action,
|
||||||
Pivot,
|
|
||||||
ScrollArea,
|
ScrollArea,
|
||||||
FluentIcon,
|
FluentIcon,
|
||||||
MessageBox,
|
MessageBox,
|
||||||
@@ -48,16 +48,17 @@ from qfluentwidgets import (
|
|||||||
TableWidget,
|
TableWidget,
|
||||||
PrimaryToolButton,
|
PrimaryToolButton,
|
||||||
)
|
)
|
||||||
from PySide6.QtCore import Qt, Signal
|
from PySide6.QtCore import Signal
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List
|
from typing import List
|
||||||
import shutil
|
import shutil
|
||||||
|
import json
|
||||||
|
|
||||||
from app.core import Config, MainInfoBar, TaskManager, MaaConfig, MaaUserConfig, Network
|
from app.core import Config, MainInfoBar, TaskManager, MaaConfig, MaaUserConfig, Network
|
||||||
from app.services import Crypto
|
from app.services import Crypto
|
||||||
from app.utils import DownloadManager
|
from .downloader import DownloadManager
|
||||||
from .Widget import (
|
from .Widget import (
|
||||||
LineEditMessageBox,
|
LineEditMessageBox,
|
||||||
LineEditSettingCard,
|
LineEditSettingCard,
|
||||||
@@ -70,6 +71,7 @@ from .Widget import (
|
|||||||
SwitchSettingCard,
|
SwitchSettingCard,
|
||||||
PushAndSwitchButtonSettingCard,
|
PushAndSwitchButtonSettingCard,
|
||||||
PushAndComboBoxSettingCard,
|
PushAndComboBoxSettingCard,
|
||||||
|
PivotArea,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -314,68 +316,135 @@ class MemberManager(QWidget):
|
|||||||
def member_downloader(self):
|
def member_downloader(self):
|
||||||
"""脚本下载器"""
|
"""脚本下载器"""
|
||||||
|
|
||||||
|
if not Config.get(Config.update_MirrorChyanCDK):
|
||||||
|
|
||||||
|
logger.warning("脚本下载器未设置CDK")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"warning",
|
||||||
|
"未设置Mirror酱CDK",
|
||||||
|
"下载器依赖于Mirror酱,未设置CDK时无法使用",
|
||||||
|
5000,
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
|
# 从远程服务器获取应用列表
|
||||||
|
Network.set_info(
|
||||||
|
mode="get",
|
||||||
|
url="https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/apps_info.json",
|
||||||
|
)
|
||||||
|
Network.start()
|
||||||
|
Network.loop.exec()
|
||||||
|
if Network.stutus_code == 200:
|
||||||
|
apps_info = Network.response_json
|
||||||
|
else:
|
||||||
|
logger.warning(f"获取应用列表时出错:{Network.error_message}")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"warning",
|
||||||
|
"获取应用列表时出错",
|
||||||
|
f"网络错误:{Network.stutus_code}",
|
||||||
|
5000,
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
choice = ComboBoxMessageBox(
|
choice = ComboBoxMessageBox(
|
||||||
self.window(),
|
self.window(),
|
||||||
"选择一个脚本类型以下载相应脚本",
|
"选择一个脚本类型以下载相应脚本",
|
||||||
["选择脚本类型"],
|
["选择脚本类型"],
|
||||||
[["MAA"]],
|
[list(apps_info.keys())],
|
||||||
)
|
)
|
||||||
if choice.exec() and choice.input[0].currentIndex() != -1:
|
if choice.exec() and choice.input[0].currentIndex() != -1:
|
||||||
|
|
||||||
if choice.input[0].currentText() == "MAA":
|
app_name = choice.input[0].currentText()
|
||||||
|
app_rid = apps_info[app_name]["rid"]
|
||||||
|
|
||||||
(Config.app_path / "script/MAA").mkdir(parents=True, exist_ok=True)
|
(Config.app_path / f"script/{app_rid}").mkdir(parents=True, exist_ok=True)
|
||||||
folder = QFileDialog.getExistingDirectory(
|
folder = QFileDialog.getExistingDirectory(
|
||||||
self, "选择MAA下载目录", str(Config.app_path / "script/MAA")
|
self,
|
||||||
|
f"选择{app_name}下载目录",
|
||||||
|
str(Config.app_path / f"script/{app_rid}"),
|
||||||
|
)
|
||||||
|
if not folder:
|
||||||
|
logger.warning(f"选择{app_name}下载目录时未选择文件夹")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"warning", "警告", f"未选择{app_name}下载目录", 5000
|
||||||
)
|
)
|
||||||
if not folder:
|
return None
|
||||||
logger.warning("选择MAA下载目录时未选择文件夹")
|
|
||||||
MainInfoBar.push_info_bar(
|
# 从mirrorc服务器获取最新版本信息
|
||||||
"warning", "警告", "未选择MAA下载目录", 5000
|
Network.set_info(
|
||||||
)
|
mode="get",
|
||||||
return None
|
url=f"https://mirrorchyan.com/api/resources/{app_rid}/latest?user_agent=AutoMaaGui&cdk={Crypto.win_decryptor(Config.get(Config.update_MirrorChyanCDK))}&os={apps_info[app_name]["os"]}&arch={apps_info[app_name]["arch"]}&channel=stable",
|
||||||
|
)
|
||||||
|
Network.start()
|
||||||
|
Network.loop.exec()
|
||||||
|
if Network.stutus_code == 200:
|
||||||
|
app_info = Network.response_json
|
||||||
|
else:
|
||||||
|
|
||||||
|
if Network.response_json:
|
||||||
|
|
||||||
|
app_info = Network.response_json
|
||||||
|
|
||||||
|
if app_info["code"] != 0:
|
||||||
|
|
||||||
|
logger.error(f"获取版本信息时出错:{app_info["msg"]}")
|
||||||
|
|
||||||
|
error_remark_dict = {
|
||||||
|
1001: "获取版本信息的URL参数不正确",
|
||||||
|
7001: "填入的 CDK 已过期",
|
||||||
|
7002: "填入的 CDK 错误",
|
||||||
|
7003: "填入的 CDK 今日下载次数已达上限",
|
||||||
|
7004: "填入的 CDK 类型和待下载的资源不匹配",
|
||||||
|
7005: "填入的 CDK 已被封禁",
|
||||||
|
8001: "对应架构和系统下的资源不存在",
|
||||||
|
8002: "错误的系统参数",
|
||||||
|
8003: "错误的架构参数",
|
||||||
|
8004: "错误的更新通道参数",
|
||||||
|
1: app_info["msg"],
|
||||||
|
}
|
||||||
|
|
||||||
|
if app_info["code"] in error_remark_dict:
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"error",
|
||||||
|
"获取版本信息时出错",
|
||||||
|
error_remark_dict[app_info["code"]],
|
||||||
|
-1,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"error",
|
||||||
|
"获取版本信息时出错",
|
||||||
|
"意料之外的错误,请及时联系项目组以获取来自 Mirror 酱的技术支持",
|
||||||
|
-1,
|
||||||
|
)
|
||||||
|
|
||||||
# 从mirrorc服务器获取最新版本信息
|
|
||||||
Network.set_info(
|
|
||||||
mode="get",
|
|
||||||
url="https://mirrorchyan.com/api/resources/MAA/latest?user_agent=AutoMaaGui&os=win&arch=x64&channel=stable",
|
|
||||||
)
|
|
||||||
Network.start()
|
|
||||||
Network.loop.exec()
|
|
||||||
if Network.stutus_code == 200:
|
|
||||||
maa_info = Network.response_json
|
|
||||||
else:
|
|
||||||
choice = MessageBox(
|
|
||||||
"错误",
|
|
||||||
f"获取版本信息时出错:\n{Network.error_message}",
|
|
||||||
self.window(),
|
|
||||||
)
|
|
||||||
choice.cancelButton.hide()
|
|
||||||
choice.buttonLayout.insertStretch(1)
|
|
||||||
if choice.exec():
|
|
||||||
return None
|
return None
|
||||||
maa_version = list(
|
|
||||||
map(
|
|
||||||
int,
|
|
||||||
maa_info["data"]["version_name"][1:]
|
|
||||||
.replace("-beta", "")
|
|
||||||
.split("."),
|
|
||||||
)
|
|
||||||
)
|
|
||||||
while len(maa_version) < 4:
|
|
||||||
maa_version.append(0)
|
|
||||||
|
|
||||||
self.downloader = DownloadManager(
|
logger.warning(f"获取版本信息时出错:{Network.error_message}")
|
||||||
Path(folder),
|
MainInfoBar.push_info_bar(
|
||||||
"MAA",
|
"warning",
|
||||||
maa_version,
|
"获取版本信息时出错",
|
||||||
{
|
f"网络错误:{Network.stutus_code}",
|
||||||
"mode": "Proxy",
|
5000,
|
||||||
"thread_numb": Config.get(Config.update_ThreadNumb),
|
|
||||||
},
|
|
||||||
)
|
)
|
||||||
self.downloader.show()
|
return None
|
||||||
self.downloader.run()
|
|
||||||
|
self.downloader = DownloadManager(
|
||||||
|
Path(folder),
|
||||||
|
app_rid,
|
||||||
|
None,
|
||||||
|
{
|
||||||
|
"mode": "MirrorChyan",
|
||||||
|
"thread_numb": 1,
|
||||||
|
"url": app_info["data"]["url"],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
self.downloader.setWindowTitle("AUTO_MAA下载器 - Mirror酱渠道")
|
||||||
|
self.downloader.setWindowIcon(
|
||||||
|
QIcon(str(Config.app_path / "resources/icons/MirrorChyan.ico"))
|
||||||
|
)
|
||||||
|
self.downloader.show()
|
||||||
|
self.downloader.run()
|
||||||
|
|
||||||
def show_password(self):
|
def show_password(self):
|
||||||
|
|
||||||
@@ -416,13 +485,17 @@ class MemberManager(QWidget):
|
|||||||
|
|
||||||
self.setObjectName("脚本管理页面组")
|
self.setObjectName("脚本管理页面组")
|
||||||
|
|
||||||
self.pivot = Pivot(self)
|
self.pivotArea = PivotArea(self)
|
||||||
|
self.pivot = self.pivotArea.pivot
|
||||||
|
|
||||||
self.stackedWidget = QStackedWidget(self)
|
self.stackedWidget = QStackedWidget(self)
|
||||||
self.Layout = QVBoxLayout(self)
|
self.stackedWidget.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.stackedWidget.setStyleSheet("background: transparent; border: none;")
|
||||||
|
|
||||||
self.script_list: List[MemberManager.MemberSettingBox.MaaSettingBox] = []
|
self.script_list: List[MemberManager.MemberSettingBox.MaaSettingBox] = []
|
||||||
|
|
||||||
self.Layout.addWidget(self.pivot, 0, Qt.AlignHCenter)
|
self.Layout = QVBoxLayout(self)
|
||||||
|
self.Layout.addWidget(self.pivotArea)
|
||||||
self.Layout.addWidget(self.stackedWidget)
|
self.Layout.addWidget(self.stackedWidget)
|
||||||
self.Layout.setContentsMargins(0, 0, 0, 0)
|
self.Layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
@@ -494,6 +567,8 @@ class MemberManager(QWidget):
|
|||||||
|
|
||||||
scrollArea = ScrollArea()
|
scrollArea = ScrollArea()
|
||||||
scrollArea.setWidgetResizable(True)
|
scrollArea.setWidgetResizable(True)
|
||||||
|
scrollArea.setContentsMargins(0, 0, 0, 0)
|
||||||
|
scrollArea.setStyleSheet("background: transparent; border: none;")
|
||||||
|
|
||||||
content_widget = QWidget()
|
content_widget = QWidget()
|
||||||
content_layout = QVBoxLayout(content_widget)
|
content_layout = QVBoxLayout(content_widget)
|
||||||
@@ -942,9 +1017,14 @@ class MemberManager(QWidget):
|
|||||||
self.setObjectName("用户管理")
|
self.setObjectName("用户管理")
|
||||||
self.name = name
|
self.name = name
|
||||||
|
|
||||||
self.pivot = Pivot(self)
|
self.pivotArea = PivotArea(self)
|
||||||
|
self.pivot = self.pivotArea.pivot
|
||||||
|
|
||||||
self.stackedWidget = QStackedWidget(self)
|
self.stackedWidget = QStackedWidget(self)
|
||||||
self.Layout = QVBoxLayout(self)
|
self.stackedWidget.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.stackedWidget.setStyleSheet(
|
||||||
|
"background: transparent; border: none;"
|
||||||
|
)
|
||||||
|
|
||||||
self.script_list: List[
|
self.script_list: List[
|
||||||
MemberManager.MemberSettingBox.MaaSettingBox.UserManager.UserSettingBox.UserMemberSettingBox
|
MemberManager.MemberSettingBox.MaaSettingBox.UserManager.UserSettingBox.UserMemberSettingBox
|
||||||
@@ -955,7 +1035,8 @@ class MemberManager(QWidget):
|
|||||||
self.stackedWidget.addWidget(self.user_dashboard)
|
self.stackedWidget.addWidget(self.user_dashboard)
|
||||||
self.pivot.addItem(routeKey="用户仪表盘", text="用户仪表盘")
|
self.pivot.addItem(routeKey="用户仪表盘", text="用户仪表盘")
|
||||||
|
|
||||||
self.Layout.addWidget(self.pivot, 0, Qt.AlignHCenter)
|
self.Layout = QVBoxLayout(self)
|
||||||
|
self.Layout.addWidget(self.pivotArea)
|
||||||
self.Layout.addWidget(self.stackedWidget)
|
self.Layout.addWidget(self.stackedWidget)
|
||||||
self.Layout.setContentsMargins(0, 0, 0, 0)
|
self.Layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
@@ -1330,7 +1411,7 @@ class MemberManager(QWidget):
|
|||||||
self.card_InfrastMode = PushAndComboBoxSettingCard(
|
self.card_InfrastMode = PushAndComboBoxSettingCard(
|
||||||
icon=FluentIcon.CAFE,
|
icon=FluentIcon.CAFE,
|
||||||
title="基建模式",
|
title="基建模式",
|
||||||
content="配置文件仅在自定义基建中生效",
|
content="自定义基建配置文件未生效",
|
||||||
text="选择配置文件",
|
text="选择配置文件",
|
||||||
texts=[
|
texts=[
|
||||||
"常规模式",
|
"常规模式",
|
||||||
@@ -1369,15 +1450,16 @@ class MemberManager(QWidget):
|
|||||||
configItem=self.config.Info_MedicineNumb,
|
configItem=self.config.Info_MedicineNumb,
|
||||||
parent=self,
|
parent=self,
|
||||||
)
|
)
|
||||||
self.card_SeriesNumb = SpinBoxSettingCard(
|
self.card_SeriesNumb = ComboBoxSettingCard(
|
||||||
icon=FluentIcon.GAME,
|
icon=FluentIcon.GAME,
|
||||||
title="连战次数",
|
title="连战次数",
|
||||||
content="连战次数较大时建议搭配剩余理智关卡使用",
|
content="连战次数较大时建议搭配剩余理智关卡使用",
|
||||||
range=(1, 6),
|
texts=["AUTO", "6", "5", "4", "3", "2", "1", "不选择"],
|
||||||
qconfig=self.config,
|
qconfig=self.config,
|
||||||
configItem=self.config.Info_SeriesNumb,
|
configItem=self.config.Info_SeriesNumb,
|
||||||
parent=self,
|
parent=self,
|
||||||
)
|
)
|
||||||
|
self.card_SeriesNumb.comboBox.setMinimumWidth(150)
|
||||||
self.card_GameId = EditableComboBoxSettingCard(
|
self.card_GameId = EditableComboBoxSettingCard(
|
||||||
icon=FluentIcon.GAME,
|
icon=FluentIcon.GAME,
|
||||||
title="关卡选择",
|
title="关卡选择",
|
||||||
@@ -1480,6 +1562,9 @@ class MemberManager(QWidget):
|
|||||||
self.card_Mode.comboBox.currentIndexChanged.connect(
|
self.card_Mode.comboBox.currentIndexChanged.connect(
|
||||||
self.switch_mode
|
self.switch_mode
|
||||||
)
|
)
|
||||||
|
self.card_InfrastMode.comboBox.currentIndexChanged.connect(
|
||||||
|
self.switch_infrastructure
|
||||||
|
)
|
||||||
self.card_Annihilation.clicked.connect(
|
self.card_Annihilation.clicked.connect(
|
||||||
lambda: self.set_maa("Annihilation")
|
lambda: self.set_maa("Annihilation")
|
||||||
)
|
)
|
||||||
@@ -1493,6 +1578,7 @@ class MemberManager(QWidget):
|
|||||||
Config.PASSWORD_refreshed.connect(self.refresh_password)
|
Config.PASSWORD_refreshed.connect(self.refresh_password)
|
||||||
|
|
||||||
self.switch_mode()
|
self.switch_mode()
|
||||||
|
self.switch_infrastructure()
|
||||||
|
|
||||||
def switch_mode(self) -> None:
|
def switch_mode(self) -> None:
|
||||||
|
|
||||||
@@ -1510,6 +1596,27 @@ class MemberManager(QWidget):
|
|||||||
self.card_Annihilation.button.setVisible(True)
|
self.card_Annihilation.button.setVisible(True)
|
||||||
self.card_Routine.setVisible(True)
|
self.card_Routine.setVisible(True)
|
||||||
|
|
||||||
|
def switch_infrastructure(self) -> None:
|
||||||
|
|
||||||
|
if (
|
||||||
|
self.config.get(self.config.Info_InfrastMode)
|
||||||
|
== "Custom"
|
||||||
|
):
|
||||||
|
self.card_InfrastMode.button.setVisible(True)
|
||||||
|
with (
|
||||||
|
self.user_path
|
||||||
|
/ "Infrastructure/infrastructure.json"
|
||||||
|
).open(mode="r", encoding="utf-8") as f:
|
||||||
|
infrastructure = json.load(f)
|
||||||
|
self.card_InfrastMode.setContent(
|
||||||
|
f"当前基建配置:{infrastructure.get("title","未命名")}"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.card_InfrastMode.button.setVisible(False)
|
||||||
|
self.card_InfrastMode.setContent(
|
||||||
|
"自定义基建配置文件未生效"
|
||||||
|
)
|
||||||
|
|
||||||
def refresh_gameid(self):
|
def refresh_gameid(self):
|
||||||
|
|
||||||
self.card_GameId.reLoadOptions(
|
self.card_GameId.reLoadOptions(
|
||||||
@@ -1565,6 +1672,7 @@ class MemberManager(QWidget):
|
|||||||
self.user_path
|
self.user_path
|
||||||
/ "Infrastructure/infrastructure.json",
|
/ "Infrastructure/infrastructure.json",
|
||||||
)
|
)
|
||||||
|
self.switch_infrastructure()
|
||||||
else:
|
else:
|
||||||
logger.warning("未选择自定义基建文件")
|
logger.warning("未选择自定义基建文件")
|
||||||
MainInfoBar.push_info_bar(
|
MainInfoBar.push_info_bar(
|
||||||
|
|||||||
@@ -34,14 +34,12 @@ from PySide6.QtWidgets import (
|
|||||||
)
|
)
|
||||||
from qfluentwidgets import (
|
from qfluentwidgets import (
|
||||||
Action,
|
Action,
|
||||||
Pivot,
|
|
||||||
ScrollArea,
|
ScrollArea,
|
||||||
FluentIcon,
|
FluentIcon,
|
||||||
MessageBox,
|
MessageBox,
|
||||||
HeaderCardWidget,
|
HeaderCardWidget,
|
||||||
CommandBar,
|
CommandBar,
|
||||||
)
|
)
|
||||||
from PySide6.QtCore import Qt
|
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from app.core import QueueConfig, Config, MainInfoBar
|
from app.core import QueueConfig, Config, MainInfoBar
|
||||||
@@ -52,6 +50,7 @@ from .Widget import (
|
|||||||
TimeEditSettingCard,
|
TimeEditSettingCard,
|
||||||
NoOptionComboBoxSettingCard,
|
NoOptionComboBoxSettingCard,
|
||||||
HistoryCard,
|
HistoryCard,
|
||||||
|
PivotArea,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -305,15 +304,19 @@ class QueueManager(QWidget):
|
|||||||
|
|
||||||
self.setObjectName("调度队列管理")
|
self.setObjectName("调度队列管理")
|
||||||
|
|
||||||
self.pivot = Pivot(self)
|
self.pivotArea = PivotArea()
|
||||||
|
self.pivot = self.pivotArea.pivot
|
||||||
|
|
||||||
self.stackedWidget = QStackedWidget(self)
|
self.stackedWidget = QStackedWidget(self)
|
||||||
self.Layout = QVBoxLayout(self)
|
self.stackedWidget.setContentsMargins(0, 0, 0, 0)
|
||||||
|
self.stackedWidget.setStyleSheet("background: transparent; border: none;")
|
||||||
|
|
||||||
self.script_list: List[
|
self.script_list: List[
|
||||||
QueueManager.QueueSettingBox.QueueMemberSettingBox
|
QueueManager.QueueSettingBox.QueueMemberSettingBox
|
||||||
] = []
|
] = []
|
||||||
|
|
||||||
self.Layout.addWidget(self.pivot, 0, Qt.AlignHCenter)
|
self.Layout = QVBoxLayout(self)
|
||||||
|
self.Layout.addWidget(self.pivotArea)
|
||||||
self.Layout.addWidget(self.stackedWidget)
|
self.Layout.addWidget(self.stackedWidget)
|
||||||
self.Layout.setContentsMargins(0, 0, 0, 0)
|
self.Layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
|
||||||
@@ -380,6 +383,8 @@ class QueueManager(QWidget):
|
|||||||
|
|
||||||
scrollArea = ScrollArea()
|
scrollArea = ScrollArea()
|
||||||
scrollArea.setWidgetResizable(True)
|
scrollArea.setWidgetResizable(True)
|
||||||
|
scrollArea.setContentsMargins(0, 0, 0, 0)
|
||||||
|
scrollArea.setStyleSheet("background: transparent; border: none;")
|
||||||
|
|
||||||
content_widget = QWidget()
|
content_widget = QWidget()
|
||||||
content_layout = QVBoxLayout(content_widget)
|
content_layout = QVBoxLayout(content_widget)
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ v4.3
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
from loguru import logger
|
from loguru import logger
|
||||||
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout
|
from PySide6.QtWidgets import QWidget, QVBoxLayout
|
||||||
|
from PySide6.QtGui import QIcon
|
||||||
from PySide6.QtCore import Qt
|
from PySide6.QtCore import Qt
|
||||||
from qfluentwidgets import (
|
from qfluentwidgets import (
|
||||||
ScrollArea,
|
ScrollArea,
|
||||||
@@ -50,6 +51,7 @@ from typing import Dict, Union
|
|||||||
|
|
||||||
from app.core import Config, MainInfoBar, Network
|
from app.core import Config, MainInfoBar, Network
|
||||||
from app.services import Crypto, System, Notify
|
from app.services import Crypto, System, Notify
|
||||||
|
from .downloader import DownloadManager
|
||||||
from .Widget import (
|
from .Widget import (
|
||||||
SwitchSettingCard,
|
SwitchSettingCard,
|
||||||
RangeSettingCard,
|
RangeSettingCard,
|
||||||
@@ -101,6 +103,8 @@ class Setting(QWidget):
|
|||||||
|
|
||||||
scrollArea = ScrollArea()
|
scrollArea = ScrollArea()
|
||||||
scrollArea.setWidgetResizable(True)
|
scrollArea.setWidgetResizable(True)
|
||||||
|
scrollArea.setContentsMargins(0, 0, 0, 0)
|
||||||
|
scrollArea.setStyleSheet("background: transparent; border: none;")
|
||||||
scrollArea.setWidget(content_widget)
|
scrollArea.setWidget(content_widget)
|
||||||
layout = QVBoxLayout()
|
layout = QVBoxLayout()
|
||||||
layout.addWidget(scrollArea)
|
layout.addWidget(scrollArea)
|
||||||
@@ -277,6 +281,46 @@ class Setting(QWidget):
|
|||||||
Network.response_json
|
Network.response_json
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
|
if Network.response_json:
|
||||||
|
|
||||||
|
version_info = Network.response_json
|
||||||
|
|
||||||
|
if version_info["code"] != 0:
|
||||||
|
|
||||||
|
logger.error(f"获取版本信息时出错:{version_info["msg"]}")
|
||||||
|
|
||||||
|
error_remark_dict = {
|
||||||
|
1001: "获取版本信息的URL参数不正确",
|
||||||
|
7001: "填入的 CDK 已过期",
|
||||||
|
7002: "填入的 CDK 错误",
|
||||||
|
7003: "填入的 CDK 今日下载次数已达上限",
|
||||||
|
7004: "填入的 CDK 类型和待下载的资源不匹配",
|
||||||
|
7005: "填入的 CDK 已被封禁",
|
||||||
|
8001: "对应架构和系统下的资源不存在",
|
||||||
|
8002: "错误的系统参数",
|
||||||
|
8003: "错误的架构参数",
|
||||||
|
8004: "错误的更新通道参数",
|
||||||
|
1: version_info["msg"],
|
||||||
|
}
|
||||||
|
|
||||||
|
if version_info["code"] in error_remark_dict:
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"error",
|
||||||
|
"获取版本信息时出错",
|
||||||
|
error_remark_dict[version_info["code"]],
|
||||||
|
-1,
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"error",
|
||||||
|
"获取版本信息时出错",
|
||||||
|
"意料之外的错误,请及时联系项目组以获取来自 Mirror 酱的技术支持",
|
||||||
|
-1,
|
||||||
|
)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
logger.warning(f"获取版本信息时出错:{Network.error_message}")
|
logger.warning(f"获取版本信息时出错:{Network.error_message}")
|
||||||
MainInfoBar.push_info_bar(
|
MainInfoBar.push_info_bar(
|
||||||
"warning",
|
"warning",
|
||||||
@@ -286,41 +330,6 @@ class Setting(QWidget):
|
|||||||
)
|
)
|
||||||
return None
|
return None
|
||||||
|
|
||||||
if version_info["code"] != 0:
|
|
||||||
|
|
||||||
logger.error(f"获取版本信息时出错:{version_info["msg"]}")
|
|
||||||
|
|
||||||
error_remark_dict = {
|
|
||||||
1001: "获取版本信息的URL参数不正确",
|
|
||||||
7001: "填入的 CDK 已过期",
|
|
||||||
7002: "填入的 CDK 错误",
|
|
||||||
7003: "填入的 CDK 今日下载次数已达上限",
|
|
||||||
7004: "填入的 CDK 类型和待下载的资源不匹配",
|
|
||||||
7005: "填入的 CDK 已被封禁",
|
|
||||||
8001: "对应架构和系统下的资源不存在",
|
|
||||||
8002: "错误的系统参数",
|
|
||||||
8003: "错误的架构参数",
|
|
||||||
8004: "错误的更新通道参数",
|
|
||||||
1: version_info["msg"],
|
|
||||||
}
|
|
||||||
|
|
||||||
if version_info["code"] in error_remark_dict:
|
|
||||||
MainInfoBar.push_info_bar(
|
|
||||||
"error",
|
|
||||||
"获取版本信息时出错",
|
|
||||||
error_remark_dict[version_info["code"]],
|
|
||||||
-1,
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
MainInfoBar.push_info_bar(
|
|
||||||
"error",
|
|
||||||
"获取版本信息时出错",
|
|
||||||
"意料之外的错误,请及时联系项目组以获取来自 Mirror 酱的技术支持",
|
|
||||||
-1,
|
|
||||||
)
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
remote_version = list(
|
remote_version = list(
|
||||||
map(
|
map(
|
||||||
int,
|
int,
|
||||||
@@ -373,45 +382,72 @@ class Setting(QWidget):
|
|||||||
else:
|
else:
|
||||||
all_version_info[key] = value.copy()
|
all_version_info[key] = value.copy()
|
||||||
|
|
||||||
version_info = {
|
|
||||||
"更新总览": f"{main_version_info}\n\n{version_info_markdown(update_version_info)}",
|
|
||||||
"ALL~版本信息": version_info_markdown(all_version_info),
|
|
||||||
**{
|
|
||||||
version_text(list(map(int, k.split(".")))): version_info_markdown(v)
|
|
||||||
for k, v in version_info_json.items()
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
# 询问是否开始版本更新
|
# 询问是否开始版本更新
|
||||||
choice = NoticeMessageBox(self.window(), "版本更新", version_info)
|
choice = NoticeMessageBox(
|
||||||
|
self.window(),
|
||||||
|
"版本更新",
|
||||||
|
{
|
||||||
|
"更新总览": f"{main_version_info}\n\n{version_info_markdown(update_version_info)}",
|
||||||
|
"ALL~版本信息": version_info_markdown(all_version_info),
|
||||||
|
**{
|
||||||
|
version_text(
|
||||||
|
list(map(int, k.split(".")))
|
||||||
|
): version_info_markdown(v)
|
||||||
|
for k, v in version_info_json.items()
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
if choice.exec():
|
if choice.exec():
|
||||||
|
|
||||||
with Config.version_path.open(mode="r", encoding="utf-8") as f:
|
if "url" in version_info["data"]:
|
||||||
version_info = json.load(f)
|
download_config = {
|
||||||
version_info["main_version"] = Config.VERSION
|
"mode": "MirrorChyan",
|
||||||
with Config.version_path.open(mode="w", encoding="utf-8") as f:
|
"thread_numb": 1,
|
||||||
json.dump(version_info, f, ensure_ascii=False, indent=4)
|
"url": version_info["data"]["url"],
|
||||||
|
}
|
||||||
if (Config.app_path / "AUTO_Updater.exe").exists():
|
|
||||||
shutil.copy(
|
|
||||||
Config.app_path / "AUTO_Updater.exe",
|
|
||||||
Config.app_path / "AUTO_Updater.active.exe",
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
logger.error("更新器文件不存在")
|
|
||||||
MainInfoBar.push_info_bar(
|
|
||||||
"error", "更新器不存在", "请手动前往 GitHub 获取最新版本", -1
|
|
||||||
)
|
|
||||||
return None
|
|
||||||
|
|
||||||
subprocess.Popen(
|
# 从远程服务器获取代理信息
|
||||||
[Config.app_path / "AUTO_Updater.active.exe"],
|
Network.set_info(
|
||||||
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
|
mode="get",
|
||||||
| subprocess.DETACHED_PROCESS
|
url="https://gitee.com/DLmaster_361/AUTO_MAA/raw/server/download_info.json",
|
||||||
| subprocess.CREATE_NO_WINDOW,
|
)
|
||||||
|
Network.start()
|
||||||
|
Network.loop.exec()
|
||||||
|
if Network.stutus_code == 200:
|
||||||
|
download_info = Network.response_json
|
||||||
|
else:
|
||||||
|
logger.warning(f"获取应用列表时出错:{Network.error_message}")
|
||||||
|
MainInfoBar.push_info_bar(
|
||||||
|
"warning",
|
||||||
|
"获取应用列表时出错",
|
||||||
|
f"网络错误:{Network.stutus_code}",
|
||||||
|
5000,
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
|
download_config = {
|
||||||
|
"mode": "Proxy",
|
||||||
|
"thread_numb": Config.get(Config.update_ThreadNumb),
|
||||||
|
"proxy_list": list(
|
||||||
|
set(
|
||||||
|
Config.get(Config.update_ProxyUrlList)
|
||||||
|
+ download_info["proxy_list"]
|
||||||
|
)
|
||||||
|
),
|
||||||
|
"download_dict": download_info["download_dict"],
|
||||||
|
}
|
||||||
|
|
||||||
|
self.downloader = DownloadManager(
|
||||||
|
Config.app_path, "AUTO_MAA", remote_version, download_config
|
||||||
)
|
)
|
||||||
self.window().close()
|
self.downloader.setWindowTitle("AUTO_MAA更新器")
|
||||||
QApplication.quit()
|
self.downloader.setWindowIcon(
|
||||||
|
QIcon(str(Config.app_path / "resources/icons/AUTO_MAA_Updater.ico"))
|
||||||
|
)
|
||||||
|
self.downloader.download_accomplish.connect(self.start_setup)
|
||||||
|
self.downloader.show()
|
||||||
|
self.downloader.run()
|
||||||
|
|
||||||
elif (
|
elif (
|
||||||
if_show
|
if_show
|
||||||
@@ -432,6 +468,23 @@ class Setting(QWidget):
|
|||||||
else:
|
else:
|
||||||
MainInfoBar.push_info_bar("success", "更新检查", "已是最新版本~", 3000)
|
MainInfoBar.push_info_bar("success", "更新检查", "已是最新版本~", 3000)
|
||||||
|
|
||||||
|
def start_setup(self) -> None:
|
||||||
|
subprocess.Popen(
|
||||||
|
[
|
||||||
|
Config.app_path / "AUTO_MAA-Setup.exe",
|
||||||
|
"/SP-",
|
||||||
|
"/SILENT",
|
||||||
|
"/NOCANCEL",
|
||||||
|
"/FORCECLOSEAPPLICATIONS",
|
||||||
|
"/LANG=Chinese",
|
||||||
|
f"/DIR={Config.app_path}",
|
||||||
|
],
|
||||||
|
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
|
||||||
|
| subprocess.DETACHED_PROCESS
|
||||||
|
| subprocess.CREATE_NO_WINDOW,
|
||||||
|
)
|
||||||
|
System.set_power("KillSelf")
|
||||||
|
|
||||||
def show_notice(self, if_show: bool = False, if_first: bool = False) -> None:
|
def show_notice(self, if_show: bool = False, if_first: bool = False) -> None:
|
||||||
"""显示公告"""
|
"""显示公告"""
|
||||||
|
|
||||||
|
|||||||
88
app/utils/AUTO_MAA.iss
Normal file
88
app/utils/AUTO_MAA.iss
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
; Script generated by the Inno Setup Script Wizard.
|
||||||
|
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||||
|
|
||||||
|
#define MyAppName "AUTO_MAA"
|
||||||
|
#define MyAppVersion ""
|
||||||
|
#define MyAppPublisher "AUTO_MAA Team"
|
||||||
|
#define MyAppURL "https://doc.automaa.xyz/"
|
||||||
|
#define MyAppExeName "AUTO_MAA.exe"
|
||||||
|
#define MyAppPath ""
|
||||||
|
#define OutputDir ""
|
||||||
|
|
||||||
|
[Setup]
|
||||||
|
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
|
||||||
|
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
||||||
|
AppId={{D116A92A-E174-4699-B777-61C5FD837B19}
|
||||||
|
AppName={#MyAppName}
|
||||||
|
AppVersion={#MyAppVersion}
|
||||||
|
AppVerName={#MyAppName}
|
||||||
|
AppPublisher={#MyAppPublisher}
|
||||||
|
AppPublisherURL={#MyAppURL}
|
||||||
|
AppSupportURL={#MyAppURL}
|
||||||
|
AppUpdatesURL={#MyAppURL}
|
||||||
|
DefaultDirName=D:\{#MyAppName}
|
||||||
|
UninstallDisplayIcon={app}\{#MyAppExeName}
|
||||||
|
; "ArchitecturesAllowed=x64compatible" specifies that Setup cannot run
|
||||||
|
; on anything but x64 and Windows 11 on Arm.
|
||||||
|
ArchitecturesAllowed=x64compatible
|
||||||
|
; "ArchitecturesInstallIn64BitMode=x64compatible" requests that the
|
||||||
|
; install be done in "64-bit mode" on x64 or Windows 11 on Arm,
|
||||||
|
; meaning it should use the native 64-bit Program Files directory and
|
||||||
|
; the 64-bit view of the registry.
|
||||||
|
ArchitecturesInstallIn64BitMode=x64compatible
|
||||||
|
DisableProgramGroupPage=yes
|
||||||
|
LicenseFile={#MyAppPath}\LICENSE
|
||||||
|
; Remove the following line to run in administrative install mode (install for all users).
|
||||||
|
PrivilegesRequired=lowest
|
||||||
|
OutputDir={#OutputDir}
|
||||||
|
OutputBaseFilename=AUTO_MAA-Setup
|
||||||
|
SetupIconFile={#MyAppPath}\resources\icons\AUTO_MAA.ico
|
||||||
|
SolidCompression=yes
|
||||||
|
WizardStyle=modern
|
||||||
|
|
||||||
|
[Languages]
|
||||||
|
Name: "Chinese"; MessagesFile: "{#MyAppPath}\resources\docs\ChineseSimplified.isl"
|
||||||
|
Name: "English"; MessagesFile: "compiler:Default.isl"
|
||||||
|
|
||||||
|
[Tasks]
|
||||||
|
Name: "desktopicon"; Description: "{cm:CreateDesktopIcon}"; GroupDescription: "{cm:AdditionalIcons}"; Flags: unchecked
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
Source: "{#MyAppPath}\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "{#MyAppPath}\app\*"; DestDir: "{app}\app"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||||
|
Source: "{#MyAppPath}\resources\*"; DestDir: "{app}\resources"; Flags: ignoreversion recursesubdirs createallsubdirs
|
||||||
|
Source: "{#MyAppPath}\main.py"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "{#MyAppPath}\requirements.txt"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "{#MyAppPath}\README.md"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
Source: "{#MyAppPath}\LICENSE"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||||
|
|
||||||
|
[Icons]
|
||||||
|
Name: "{autoprograms}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
||||||
|
Name: "{autodesktop}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"; Tasks: desktopicon
|
||||||
|
|
||||||
|
[Run]
|
||||||
|
Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall
|
||||||
|
|
||||||
|
[Code]
|
||||||
|
var
|
||||||
|
DeleteDataQuestion: Boolean;
|
||||||
|
|
||||||
|
function InitializeUninstall: Boolean;
|
||||||
|
begin
|
||||||
|
DeleteDataQuestion := MsgBox('您确认要完全移除 AUTO_MAA 的所有用户数据文件与子组件吗?', mbConfirmation, MB_YESNO) = IDYES;
|
||||||
|
Result := True;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
|
||||||
|
begin
|
||||||
|
if CurUninstallStep = usPostUninstall then
|
||||||
|
begin
|
||||||
|
DelTree(ExpandConstant('{app}\app'), True, True, True);
|
||||||
|
DelTree(ExpandConstant('{app}\resources'), True, True, True);
|
||||||
|
if DeleteDataQuestion then
|
||||||
|
begin
|
||||||
|
DelTree(ExpandConstant('{app}'), True, True, True);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
@@ -29,6 +29,4 @@ __version__ = "4.2.0"
|
|||||||
__author__ = "DLmaster361 <DLmaster_361@163.com>"
|
__author__ = "DLmaster361 <DLmaster_361@163.com>"
|
||||||
__license__ = "GPL-3.0 license"
|
__license__ = "GPL-3.0 license"
|
||||||
|
|
||||||
from .downloader import DownloadManager
|
__all__ = []
|
||||||
|
|
||||||
__all__ = ["DownloadManager"]
|
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ if __name__ == "__main__":
|
|||||||
version = json.load(f)
|
version = json.load(f)
|
||||||
|
|
||||||
main_version_numb = list(map(int, version["main_version"].split(".")))
|
main_version_numb = list(map(int, version["main_version"].split(".")))
|
||||||
updater_version_numb = list(map(int, version["updater_version"].split(".")))
|
|
||||||
|
|
||||||
print("Packaging AUTO_MAA main program ...")
|
print("Packaging AUTO_MAA main program ...")
|
||||||
|
|
||||||
@@ -86,35 +85,10 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
print("AUTO_MAA main program packaging completed !")
|
print("AUTO_MAA main program packaging completed !")
|
||||||
|
|
||||||
print("Packaging AUTO_MAA update program ...")
|
print("start to create setup program ...")
|
||||||
|
|
||||||
shutil.copy(root_path / "app/utils/downloader.py", root_path)
|
|
||||||
os.system(
|
|
||||||
"powershell -Command python -m nuitka --standalone --onefile --mingw64"
|
|
||||||
" --enable-plugins=pyside6 --windows-console-mode=disable"
|
|
||||||
" --onefile-tempdir-spec='{TEMP}\\AUTO_MAA_Updater'"
|
|
||||||
" --windows-icon-from-ico=resources\\icons\\AUTO_MAA_Updater.ico"
|
|
||||||
" --company-name='AUTO_MAA Team' --product-name=AUTO_MAA"
|
|
||||||
f" --file-version={version["updater_version"]}"
|
|
||||||
f" --product-version={version["main_version"]}"
|
|
||||||
" --file-description='AUTO_MAA Component'"
|
|
||||||
" --copyright='Copyright © 2024-2025 DLmaster361'"
|
|
||||||
" --assume-yes-for-downloads --output-filename=AUTO_Updater"
|
|
||||||
" --remove-output downloader.py"
|
|
||||||
)
|
|
||||||
(root_path / "downloader.py").unlink()
|
|
||||||
|
|
||||||
print("AUTO_MAA update program packaging completed !")
|
|
||||||
|
|
||||||
(root_path / "AUTO_MAA").mkdir(parents=True, exist_ok=True)
|
(root_path / "AUTO_MAA").mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
print("Start to move AUTO_MAA program ...")
|
|
||||||
|
|
||||||
shutil.move(root_path / "AUTO_MAA.exe", root_path / "AUTO_MAA/")
|
shutil.move(root_path / "AUTO_MAA.exe", root_path / "AUTO_MAA/")
|
||||||
shutil.move(root_path / "AUTO_Updater.exe", root_path / "AUTO_MAA/")
|
|
||||||
|
|
||||||
print("Start to copy rescourses ...")
|
|
||||||
|
|
||||||
shutil.copytree(root_path / "app", root_path / "AUTO_MAA/app")
|
shutil.copytree(root_path / "app", root_path / "AUTO_MAA/app")
|
||||||
shutil.copytree(root_path / "resources", root_path / "AUTO_MAA/resources")
|
shutil.copytree(root_path / "resources", root_path / "AUTO_MAA/resources")
|
||||||
shutil.copy(root_path / "main.py", root_path / "AUTO_MAA/")
|
shutil.copy(root_path / "main.py", root_path / "AUTO_MAA/")
|
||||||
@@ -122,17 +96,38 @@ if __name__ == "__main__":
|
|||||||
shutil.copy(root_path / "README.md", root_path / "AUTO_MAA/")
|
shutil.copy(root_path / "README.md", root_path / "AUTO_MAA/")
|
||||||
shutil.copy(root_path / "LICENSE", root_path / "AUTO_MAA/")
|
shutil.copy(root_path / "LICENSE", root_path / "AUTO_MAA/")
|
||||||
|
|
||||||
print("Start to compress ...")
|
with (root_path / "app/utils/AUTO_MAA.iss").open(mode="r", encoding="utf-8") as f:
|
||||||
|
iss = f.read()
|
||||||
|
iss = (
|
||||||
|
iss.replace(
|
||||||
|
'#define MyAppVersion ""',
|
||||||
|
f'#define MyAppVersion "{version["main_version"]}"',
|
||||||
|
)
|
||||||
|
.replace(
|
||||||
|
'#define MyAppPath ""', f'#define MyAppPath "{root_path / "AUTO_MAA"}"'
|
||||||
|
)
|
||||||
|
.replace('#define OutputDir ""', f'#define OutputDir "{root_path}"')
|
||||||
|
)
|
||||||
|
with (root_path / "AUTO_MAA.iss").open(mode="w", encoding="utf-8") as f:
|
||||||
|
f.write(iss)
|
||||||
|
|
||||||
|
os.system(f'ISCC "{root_path / "AUTO_MAA.iss"}"')
|
||||||
|
|
||||||
|
(root_path / "AUTO_MAA_Setup").mkdir(parents=True, exist_ok=True)
|
||||||
|
shutil.move(root_path / "AUTO_MAA-Setup.exe", root_path / "AUTO_MAA_Setup")
|
||||||
|
|
||||||
shutil.make_archive(
|
shutil.make_archive(
|
||||||
base_name=root_path / f"AUTO_MAA_{version_text(main_version_numb)}",
|
base_name=root_path / f"AUTO_MAA_{version_text(main_version_numb)}",
|
||||||
format="zip",
|
format="zip",
|
||||||
root_dir=root_path / "AUTO_MAA",
|
root_dir=root_path / "AUTO_MAA_Setup",
|
||||||
base_dir=".",
|
base_dir=".",
|
||||||
)
|
)
|
||||||
shutil.rmtree(root_path / "AUTO_MAA")
|
|
||||||
|
|
||||||
print("compress completed !")
|
print("setup program created !")
|
||||||
|
|
||||||
|
(root_path / "AUTO_MAA.iss").unlink(missing_ok=True)
|
||||||
|
shutil.rmtree(root_path / "AUTO_MAA")
|
||||||
|
shutil.rmtree(root_path / "AUTO_MAA_Setup")
|
||||||
|
|
||||||
all_version_info = {}
|
all_version_info = {}
|
||||||
for v_i in version["version_info"].values():
|
for v_i in version["version_info"].values():
|
||||||
@@ -143,6 +138,6 @@ if __name__ == "__main__":
|
|||||||
all_version_info[key] = value.copy()
|
all_version_info[key] = value.copy()
|
||||||
|
|
||||||
(root_path / "version_info.txt").write_text(
|
(root_path / "version_info.txt").write_text(
|
||||||
f"{version_text(main_version_numb)}\n{version_text(updater_version_numb)}\n<!--{json.dumps(version["version_info"], ensure_ascii=False)}-->\n{version_info_markdown(all_version_info)}",
|
f"{version_text(main_version_numb)}\n\n<!--{json.dumps(version["version_info"], ensure_ascii=False)}-->\n{version_info_markdown(all_version_info)}",
|
||||||
encoding="utf-8",
|
encoding="utf-8",
|
||||||
)
|
)
|
||||||
|
|||||||
1
main.py
1
main.py
@@ -43,6 +43,7 @@ def main():
|
|||||||
|
|
||||||
window = AUTO_MAA()
|
window = AUTO_MAA()
|
||||||
window.show_ui("显示主窗口")
|
window.show_ui("显示主窗口")
|
||||||
|
window.show_ui("配置托盘")
|
||||||
window.start_up_task()
|
window.start_up_task()
|
||||||
sys.exit(application.exec())
|
sys.exit(application.exec())
|
||||||
|
|
||||||
|
|||||||
@@ -10,5 +10,4 @@ pycryptodome
|
|||||||
requests
|
requests
|
||||||
markdown
|
markdown
|
||||||
Jinja2
|
Jinja2
|
||||||
serverchan_sdk
|
|
||||||
nuitka
|
nuitka
|
||||||
403
resources/docs/ChineseSimplified.isl
Normal file
403
resources/docs/ChineseSimplified.isl
Normal file
@@ -0,0 +1,403 @@
|
|||||||
|
; *** Inno Setup version 6.4.0+ Chinese Simplified messages ***
|
||||||
|
;
|
||||||
|
; To download user-contributed translations of this file, go to:
|
||||||
|
; https://jrsoftware.org/files/istrans/
|
||||||
|
;
|
||||||
|
; Note: When translating this text, do not add periods (.) to the end of
|
||||||
|
; messages that didn't have them already, because on those messages Inno
|
||||||
|
; Setup adds the periods automatically (appending a period would result in
|
||||||
|
; two periods being displayed).
|
||||||
|
;
|
||||||
|
; Maintained by Zhenghan Yang
|
||||||
|
; Email: 847320916@QQ.com
|
||||||
|
; Translation based on network resource
|
||||||
|
; The latest Translation is on https://github.com/kira-96/Inno-Setup-Chinese-Simplified-Translation
|
||||||
|
;
|
||||||
|
|
||||||
|
[LangOptions]
|
||||||
|
; The following three entries are very important. Be sure to read and
|
||||||
|
; understand the '[LangOptions] section' topic in the help file.
|
||||||
|
LanguageName=简体中文
|
||||||
|
; If Language Name display incorrect, uncomment next line
|
||||||
|
; LanguageName=<7B80><4F53><4E2D><6587>
|
||||||
|
; About LanguageID, to reference link:
|
||||||
|
; https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-lcid/a9eac961-e77d-41a6-90a5-ce1a8b0cdb9c
|
||||||
|
LanguageID=$0804
|
||||||
|
; About CodePage, to reference link:
|
||||||
|
; https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers
|
||||||
|
LanguageCodePage=936
|
||||||
|
; If the language you are translating to requires special font faces or
|
||||||
|
; sizes, uncomment any of the following entries and change them accordingly.
|
||||||
|
;DialogFontName=
|
||||||
|
;DialogFontSize=8
|
||||||
|
;WelcomeFontName=Verdana
|
||||||
|
;WelcomeFontSize=12
|
||||||
|
;TitleFontName=Arial
|
||||||
|
;TitleFontSize=29
|
||||||
|
;CopyrightFontName=Arial
|
||||||
|
;CopyrightFontSize=8
|
||||||
|
|
||||||
|
[Messages]
|
||||||
|
|
||||||
|
; *** 应用程序标题
|
||||||
|
SetupAppTitle=安装
|
||||||
|
SetupWindowTitle=安装 - %1
|
||||||
|
UninstallAppTitle=卸载
|
||||||
|
UninstallAppFullTitle=%1 卸载
|
||||||
|
|
||||||
|
; *** Misc. common
|
||||||
|
InformationTitle=信息
|
||||||
|
ConfirmTitle=确认
|
||||||
|
ErrorTitle=错误
|
||||||
|
|
||||||
|
; *** SetupLdr messages
|
||||||
|
SetupLdrStartupMessage=现在将安装 %1。您想要继续吗?
|
||||||
|
LdrCannotCreateTemp=无法创建临时文件。安装程序已中止
|
||||||
|
LdrCannotExecTemp=无法执行临时目录中的文件。安装程序已中止
|
||||||
|
HelpTextNote=
|
||||||
|
|
||||||
|
; *** 启动错误消息
|
||||||
|
LastErrorMessage=%1。%n%n错误 %2: %3
|
||||||
|
SetupFileMissing=安装目录中缺少文件 %1。请修正这个问题或者获取程序的新副本。
|
||||||
|
SetupFileCorrupt=安装文件已损坏。请获取程序的新副本。
|
||||||
|
SetupFileCorruptOrWrongVer=安装文件已损坏,或是与这个安装程序的版本不兼容。请修正这个问题或获取新的程序副本。
|
||||||
|
InvalidParameter=无效的命令行参数:%n%n%1
|
||||||
|
SetupAlreadyRunning=安装程序正在运行。
|
||||||
|
WindowsVersionNotSupported=此程序不支持当前计算机运行的 Windows 版本。
|
||||||
|
WindowsServicePackRequired=此程序需要 %1 服务包 %2 或更高版本。
|
||||||
|
NotOnThisPlatform=此程序不能在 %1 上运行。
|
||||||
|
OnlyOnThisPlatform=此程序只能在 %1 上运行。
|
||||||
|
OnlyOnTheseArchitectures=此程序只能安装到为下列处理器架构设计的 Windows 版本中:%n%n%1
|
||||||
|
WinVersionTooLowError=此程序需要 %1 版本 %2 或更高。
|
||||||
|
WinVersionTooHighError=此程序不能安装于 %1 版本 %2 或更高。
|
||||||
|
AdminPrivilegesRequired=在安装此程序时您必须以管理员身份登录。
|
||||||
|
PowerUserPrivilegesRequired=在安装此程序时您必须以管理员身份或有权限的用户组身份登录。
|
||||||
|
SetupAppRunningError=安装程序发现 %1 当前正在运行。%n%n请先关闭正在运行的程序,然后点击“确定”继续,或点击“取消”退出。
|
||||||
|
UninstallAppRunningError=卸载程序发现 %1 当前正在运行。%n%n请先关闭正在运行的程序,然后点击“确定”继续,或点击“取消”退出。
|
||||||
|
|
||||||
|
; *** 启动问题
|
||||||
|
PrivilegesRequiredOverrideTitle=选择安装程序模式
|
||||||
|
PrivilegesRequiredOverrideInstruction=选择安装模式
|
||||||
|
PrivilegesRequiredOverrideText1=%1 可以为所有用户安装(需要管理员权限),或仅为您安装。
|
||||||
|
PrivilegesRequiredOverrideText2=%1 只能为您安装,或为所有用户安装(需要管理员权限)。
|
||||||
|
PrivilegesRequiredOverrideAllUsers=为所有用户安装(&A)
|
||||||
|
PrivilegesRequiredOverrideAllUsersRecommended=为所有用户安装(&A) (建议选项)
|
||||||
|
PrivilegesRequiredOverrideCurrentUser=只为我安装(&M)
|
||||||
|
PrivilegesRequiredOverrideCurrentUserRecommended=只为我安装(&M) (建议选项)
|
||||||
|
|
||||||
|
; *** 其他错误
|
||||||
|
ErrorCreatingDir=安装程序无法创建目录“%1”
|
||||||
|
ErrorTooManyFilesInDir=无法在目录“%1”中创建文件,因为里面包含太多文件
|
||||||
|
|
||||||
|
; *** 安装程序公共消息
|
||||||
|
ExitSetupTitle=退出安装程序
|
||||||
|
ExitSetupMessage=安装程序尚未完成。如果现在退出,将不会安装该程序。%n%n您之后可以再次运行安装程序完成安装。%n%n现在退出安装程序吗?
|
||||||
|
AboutSetupMenuItem=关于安装程序(&A)...
|
||||||
|
AboutSetupTitle=关于安装程序
|
||||||
|
AboutSetupMessage=%1 版本 %2%n%3%n%n%1 主页:%n%4
|
||||||
|
AboutSetupNote=
|
||||||
|
TranslatorNote=简体中文翻译由Kira(847320916@qq.com)维护。项目地址:https://github.com/kira-96/Inno-Setup-Chinese-Simplified-Translation
|
||||||
|
|
||||||
|
; *** 按钮
|
||||||
|
ButtonBack=< 上一步(&B)
|
||||||
|
ButtonNext=下一步(&N) >
|
||||||
|
ButtonInstall=安装(&I)
|
||||||
|
ButtonOK=确定
|
||||||
|
ButtonCancel=取消
|
||||||
|
ButtonYes=是(&Y)
|
||||||
|
ButtonYesToAll=全是(&A)
|
||||||
|
ButtonNo=否(&N)
|
||||||
|
ButtonNoToAll=全否(&O)
|
||||||
|
ButtonFinish=完成(&F)
|
||||||
|
ButtonBrowse=浏览(&B)...
|
||||||
|
ButtonWizardBrowse=浏览(&R)...
|
||||||
|
ButtonNewFolder=新建文件夹(&M)
|
||||||
|
|
||||||
|
; *** “选择语言”对话框消息
|
||||||
|
SelectLanguageTitle=选择安装语言
|
||||||
|
SelectLanguageLabel=选择安装时使用的语言。
|
||||||
|
|
||||||
|
; *** 公共向导文字
|
||||||
|
ClickNext=点击“下一步”继续,或点击“取消”退出安装程序。
|
||||||
|
BeveledLabel=
|
||||||
|
BrowseDialogTitle=浏览文件夹
|
||||||
|
BrowseDialogLabel=在下面的列表中选择一个文件夹,然后点击“确定”。
|
||||||
|
NewFolderName=新建文件夹
|
||||||
|
|
||||||
|
; *** “欢迎”向导页
|
||||||
|
WelcomeLabel1=欢迎使用 [name] 安装向导
|
||||||
|
WelcomeLabel2=现在将安装 [name/ver] 到您的电脑中。%n%n建议您在继续安装前关闭所有其他应用程序。
|
||||||
|
|
||||||
|
; *** “密码”向导页
|
||||||
|
WizardPassword=密码
|
||||||
|
PasswordLabel1=这个安装程序有密码保护。
|
||||||
|
PasswordLabel3=请输入密码,然后点击“下一步”继续。密码区分大小写。
|
||||||
|
PasswordEditLabel=密码(&P):
|
||||||
|
IncorrectPassword=您输入的密码不正确,请重新输入。
|
||||||
|
|
||||||
|
; *** “许可协议”向导页
|
||||||
|
WizardLicense=许可协议
|
||||||
|
LicenseLabel=请在继续安装前阅读以下重要信息。
|
||||||
|
LicenseLabel3=请仔细阅读下列许可协议。在继续安装前您必须同意这些协议条款。
|
||||||
|
LicenseAccepted=我同意此协议(&A)
|
||||||
|
LicenseNotAccepted=我不同意此协议(&D)
|
||||||
|
|
||||||
|
; *** “信息”向导页
|
||||||
|
WizardInfoBefore=信息
|
||||||
|
InfoBeforeLabel=请在继续安装前阅读以下重要信息。
|
||||||
|
InfoBeforeClickLabel=准备好继续安装后,点击“下一步”。
|
||||||
|
WizardInfoAfter=信息
|
||||||
|
InfoAfterLabel=请在继续安装前阅读以下重要信息。
|
||||||
|
InfoAfterClickLabel=准备好继续安装后,点击“下一步”。
|
||||||
|
|
||||||
|
; *** “用户信息”向导页
|
||||||
|
WizardUserInfo=用户信息
|
||||||
|
UserInfoDesc=请输入您的信息。
|
||||||
|
UserInfoName=用户名(&U):
|
||||||
|
UserInfoOrg=组织(&O):
|
||||||
|
UserInfoSerial=序列号(&S):
|
||||||
|
UserInfoNameRequired=您必须输入用户名。
|
||||||
|
|
||||||
|
; *** “选择目标目录”向导页
|
||||||
|
WizardSelectDir=选择目标位置
|
||||||
|
SelectDirDesc=您想将 [name] 安装在哪里?
|
||||||
|
SelectDirLabel3=安装程序将安装 [name] 到下面的文件夹中。
|
||||||
|
SelectDirBrowseLabel=点击“下一步”继续。如果您想选择其他文件夹,点击“浏览”。
|
||||||
|
DiskSpaceGBLabel=至少需要有 [gb] GB 的可用磁盘空间。
|
||||||
|
DiskSpaceMBLabel=至少需要有 [mb] MB 的可用磁盘空间。
|
||||||
|
CannotInstallToNetworkDrive=安装程序无法安装到一个网络驱动器。
|
||||||
|
CannotInstallToUNCPath=安装程序无法安装到一个 UNC 路径。
|
||||||
|
InvalidPath=您必须输入一个带驱动器卷标的完整路径,例如:%n%nC:\APP%n%n或UNC路径:%n%n\\server\share
|
||||||
|
InvalidDrive=您选定的驱动器或 UNC 共享不存在或不能访问。请选择其他位置。
|
||||||
|
DiskSpaceWarningTitle=磁盘空间不足
|
||||||
|
DiskSpaceWarning=安装程序至少需要 %1 KB 的可用空间才能安装,但选定驱动器只有 %2 KB 的可用空间。%n%n您一定要继续吗?
|
||||||
|
DirNameTooLong=文件夹名称或路径太长。
|
||||||
|
InvalidDirName=文件夹名称无效。
|
||||||
|
BadDirName32=文件夹名称不能包含下列任何字符:%n%n%1
|
||||||
|
DirExistsTitle=文件夹已存在
|
||||||
|
DirExists=文件夹:%n%n%1%n%n已经存在。您一定要安装到这个文件夹中吗?
|
||||||
|
DirDoesntExistTitle=文件夹不存在
|
||||||
|
DirDoesntExist=文件夹:%n%n%1%n%n不存在。您想要创建此文件夹吗?
|
||||||
|
|
||||||
|
; *** “选择组件”向导页
|
||||||
|
WizardSelectComponents=选择组件
|
||||||
|
SelectComponentsDesc=您想安装哪些程序组件?
|
||||||
|
SelectComponentsLabel2=选中您想安装的组件;取消您不想安装的组件。然后点击“下一步”继续。
|
||||||
|
FullInstallation=完全安装
|
||||||
|
; if possible don't translate 'Compact' as 'Minimal' (I mean 'Minimal' in your language)
|
||||||
|
CompactInstallation=简洁安装
|
||||||
|
CustomInstallation=自定义安装
|
||||||
|
NoUninstallWarningTitle=组件已存在
|
||||||
|
NoUninstallWarning=安装程序检测到下列组件已安装在您的电脑中:%n%n%1%n%n取消选中这些组件不会卸载它们。%n%n确定要继续吗?
|
||||||
|
ComponentSize1=%1 KB
|
||||||
|
ComponentSize2=%1 MB
|
||||||
|
ComponentsDiskSpaceGBLabel=当前选择的组件需要至少 [gb] GB 的磁盘空间。
|
||||||
|
ComponentsDiskSpaceMBLabel=当前选择的组件需要至少 [mb] MB 的磁盘空间。
|
||||||
|
|
||||||
|
; *** “选择附加任务”向导页
|
||||||
|
WizardSelectTasks=选择附加任务
|
||||||
|
SelectTasksDesc=您想要安装程序执行哪些附加任务?
|
||||||
|
SelectTasksLabel2=选择您想要安装程序在安装 [name] 时执行的附加任务,然后点击“下一步”。
|
||||||
|
|
||||||
|
; *** “选择开始菜单文件夹”向导页
|
||||||
|
WizardSelectProgramGroup=选择开始菜单文件夹
|
||||||
|
SelectStartMenuFolderDesc=安装程序应该在哪里放置程序的快捷方式?
|
||||||
|
SelectStartMenuFolderLabel3=安装程序将在下列“开始”菜单文件夹中创建程序的快捷方式。
|
||||||
|
SelectStartMenuFolderBrowseLabel=点击“下一步”继续。如果您想选择其他文件夹,点击“浏览”。
|
||||||
|
MustEnterGroupName=您必须输入一个文件夹名。
|
||||||
|
GroupNameTooLong=文件夹名或路径太长。
|
||||||
|
InvalidGroupName=无效的文件夹名字。
|
||||||
|
BadGroupName=文件夹名不能包含下列任何字符:%n%n%1
|
||||||
|
NoProgramGroupCheck2=不创建开始菜单文件夹(&D)
|
||||||
|
|
||||||
|
; *** “准备安装”向导页
|
||||||
|
WizardReady=准备安装
|
||||||
|
ReadyLabel1=安装程序准备就绪,现在可以开始安装 [name] 到您的电脑。
|
||||||
|
ReadyLabel2a=点击“安装”继续此安装程序。如果您想重新考虑或修改任何设置,点击“上一步”。
|
||||||
|
ReadyLabel2b=点击“安装”继续此安装程序。
|
||||||
|
ReadyMemoUserInfo=用户信息:
|
||||||
|
ReadyMemoDir=目标位置:
|
||||||
|
ReadyMemoType=安装类型:
|
||||||
|
ReadyMemoComponents=已选择组件:
|
||||||
|
ReadyMemoGroup=开始菜单文件夹:
|
||||||
|
ReadyMemoTasks=附加任务:
|
||||||
|
|
||||||
|
; *** TExtractionWizardPage wizard page and Extract7ZipArchive
|
||||||
|
ExtractionLabel=正在提取附加文件...
|
||||||
|
ButtonStopExtraction=停止提取(&S)
|
||||||
|
StopExtraction=您确定要停止提取吗?
|
||||||
|
ErrorExtractionAborted=提取已中止
|
||||||
|
ErrorExtractionFailed=提取失败:%1
|
||||||
|
|
||||||
|
; *** TDownloadWizardPage wizard page and DownloadTemporaryFile
|
||||||
|
DownloadingLabel=正在下载附加文件...
|
||||||
|
ButtonStopDownload=停止下载(&S)
|
||||||
|
StopDownload=您确定要停止下载吗?
|
||||||
|
ErrorDownloadAborted=下载已中止
|
||||||
|
ErrorDownloadFailed=下载失败:%1 %2
|
||||||
|
ErrorDownloadSizeFailed=获取下载大小失败:%1 %2
|
||||||
|
ErrorFileHash1=校验文件哈希失败:%1
|
||||||
|
ErrorFileHash2=无效的文件哈希:预期 %1,实际 %2
|
||||||
|
ErrorProgress=无效的进度:%1 / %2
|
||||||
|
ErrorFileSize=文件大小错误:预期 %1,实际 %2
|
||||||
|
|
||||||
|
; *** “正在准备安装”向导页
|
||||||
|
WizardPreparing=正在准备安装
|
||||||
|
PreparingDesc=安装程序正在准备安装 [name] 到您的电脑。
|
||||||
|
PreviousInstallNotCompleted=先前的程序安装或卸载未完成,您需要重启您的电脑以完成。%n%n在重启电脑后,再次运行安装程序以完成 [name] 的安装。
|
||||||
|
CannotContinue=安装程序不能继续。请点击“取消”退出。
|
||||||
|
ApplicationsFound=以下应用程序正在使用将由安装程序更新的文件。建议您允许安装程序自动关闭这些应用程序。
|
||||||
|
ApplicationsFound2=以下应用程序正在使用将由安装程序更新的文件。建议您允许安装程序自动关闭这些应用程序。安装完成后,安装程序将尝试重新启动这些应用程序。
|
||||||
|
CloseApplications=自动关闭应用程序(&A)
|
||||||
|
DontCloseApplications=不要关闭应用程序(&D)
|
||||||
|
ErrorCloseApplications=安装程序无法自动关闭所有应用程序。建议您在继续之前,关闭所有在使用需要由安装程序更新的文件的应用程序。
|
||||||
|
PrepareToInstallNeedsRestart=安装程序必须重启您的计算机。计算机重启后,请再次运行安装程序以完成 [name] 的安装。%n%n是否立即重新启动?
|
||||||
|
|
||||||
|
; *** “正在安装”向导页
|
||||||
|
WizardInstalling=正在安装
|
||||||
|
InstallingLabel=安装程序正在安装 [name] 到您的电脑,请稍候。
|
||||||
|
|
||||||
|
; *** “安装完成”向导页
|
||||||
|
FinishedHeadingLabel=[name] 安装完成
|
||||||
|
FinishedLabelNoIcons=安装程序已在您的电脑中安装了 [name]。
|
||||||
|
FinishedLabel=安装程序已在您的电脑中安装了 [name]。您可以通过已安装的快捷方式运行此应用程序。
|
||||||
|
ClickFinish=点击“完成”退出安装程序。
|
||||||
|
FinishedRestartLabel=为完成 [name] 的安装,安装程序必须重新启动您的电脑。要立即重启吗?
|
||||||
|
FinishedRestartMessage=为完成 [name] 的安装,安装程序必须重新启动您的电脑。%n%n要立即重启吗?
|
||||||
|
ShowReadmeCheck=是,我想查阅自述文件
|
||||||
|
YesRadio=是,立即重启电脑(&Y)
|
||||||
|
NoRadio=否,稍后重启电脑(&N)
|
||||||
|
; used for example as 'Run MyProg.exe'
|
||||||
|
RunEntryExec=运行 %1
|
||||||
|
; used for example as 'View Readme.txt'
|
||||||
|
RunEntryShellExec=查阅 %1
|
||||||
|
|
||||||
|
; *** “安装程序需要下一张磁盘”提示
|
||||||
|
ChangeDiskTitle=安装程序需要下一张磁盘
|
||||||
|
SelectDiskLabel2=请插入磁盘 %1 并点击“确定”。%n%n如果这个磁盘中的文件可以在下列文件夹之外的文件夹中找到,请输入正确的路径或点击“浏览”。
|
||||||
|
PathLabel=路径(&P):
|
||||||
|
FileNotInDir2=“%2”中找不到文件“%1”。请插入正确的磁盘或选择其他文件夹。
|
||||||
|
SelectDirectoryLabel=请指定下一张磁盘的位置。
|
||||||
|
|
||||||
|
; *** 安装状态消息
|
||||||
|
SetupAborted=安装程序未完成安装。%n%n请修正这个问题并重新运行安装程序。
|
||||||
|
AbortRetryIgnoreSelectAction=选择操作
|
||||||
|
AbortRetryIgnoreRetry=重试(&T)
|
||||||
|
AbortRetryIgnoreIgnore=忽略错误并继续(&I)
|
||||||
|
AbortRetryIgnoreCancel=关闭安装程序
|
||||||
|
|
||||||
|
; *** 安装状态消息
|
||||||
|
StatusClosingApplications=正在关闭应用程序...
|
||||||
|
StatusCreateDirs=正在创建目录...
|
||||||
|
StatusExtractFiles=正在解压缩文件...
|
||||||
|
StatusCreateIcons=正在创建快捷方式...
|
||||||
|
StatusCreateIniEntries=正在创建 INI 条目...
|
||||||
|
StatusCreateRegistryEntries=正在创建注册表条目...
|
||||||
|
StatusRegisterFiles=正在注册文件...
|
||||||
|
StatusSavingUninstall=正在保存卸载信息...
|
||||||
|
StatusRunProgram=正在完成安装...
|
||||||
|
StatusRestartingApplications=正在重启应用程序...
|
||||||
|
StatusRollback=正在撤销更改...
|
||||||
|
|
||||||
|
; *** 其他错误
|
||||||
|
ErrorInternal2=内部错误:%1
|
||||||
|
ErrorFunctionFailedNoCode=%1 失败
|
||||||
|
ErrorFunctionFailed=%1 失败;错误代码 %2
|
||||||
|
ErrorFunctionFailedWithMessage=%1 失败;错误代码 %2.%n%3
|
||||||
|
ErrorExecutingProgram=无法执行文件:%n%1
|
||||||
|
|
||||||
|
; *** 注册表错误
|
||||||
|
ErrorRegOpenKey=打开注册表项时出错:%n%1\%2
|
||||||
|
ErrorRegCreateKey=创建注册表项时出错:%n%1\%2
|
||||||
|
ErrorRegWriteKey=写入注册表项时出错:%n%1\%2
|
||||||
|
|
||||||
|
; *** INI 错误
|
||||||
|
ErrorIniEntry=在文件“%1”中创建 INI 条目时出错。
|
||||||
|
|
||||||
|
; *** 文件复制错误
|
||||||
|
FileAbortRetryIgnoreSkipNotRecommended=跳过此文件(&S) (不推荐)
|
||||||
|
FileAbortRetryIgnoreIgnoreNotRecommended=忽略错误并继续(&I) (不推荐)
|
||||||
|
SourceIsCorrupted=源文件已损坏
|
||||||
|
SourceDoesntExist=源文件“%1”不存在
|
||||||
|
ExistingFileReadOnly2=无法替换现有文件,它是只读的。
|
||||||
|
ExistingFileReadOnlyRetry=移除只读属性并重试(&R)
|
||||||
|
ExistingFileReadOnlyKeepExisting=保留现有文件(&K)
|
||||||
|
ErrorReadingExistingDest=尝试读取现有文件时出错:
|
||||||
|
FileExistsSelectAction=选择操作
|
||||||
|
FileExists2=文件已经存在。
|
||||||
|
FileExistsOverwriteExisting=覆盖已存在的文件(&O)
|
||||||
|
FileExistsKeepExisting=保留现有的文件(&K)
|
||||||
|
FileExistsOverwriteOrKeepAll=为所有冲突文件执行此操作(&D)
|
||||||
|
ExistingFileNewerSelectAction=选择操作
|
||||||
|
ExistingFileNewer2=现有的文件比安装程序将要安装的文件还要新。
|
||||||
|
ExistingFileNewerOverwriteExisting=覆盖已存在的文件(&O)
|
||||||
|
ExistingFileNewerKeepExisting=保留现有的文件(&K) (推荐)
|
||||||
|
ExistingFileNewerOverwriteOrKeepAll=为所有冲突文件执行此操作(&D)
|
||||||
|
ErrorChangingAttr=尝试更改下列现有文件的属性时出错:
|
||||||
|
ErrorCreatingTemp=尝试在目标目录创建文件时出错:
|
||||||
|
ErrorReadingSource=尝试读取下列源文件时出错:
|
||||||
|
ErrorCopying=尝试复制下列文件时出错:
|
||||||
|
ErrorReplacingExistingFile=尝试替换现有文件时出错:
|
||||||
|
ErrorRestartReplace=重启并替换失败:
|
||||||
|
ErrorRenamingTemp=尝试重命名下列目标目录中的一个文件时出错:
|
||||||
|
ErrorRegisterServer=无法注册 DLL/OCX:%1
|
||||||
|
ErrorRegSvr32Failed=RegSvr32 失败;退出代码 %1
|
||||||
|
ErrorRegisterTypeLib=无法注册类库:%1
|
||||||
|
|
||||||
|
; *** 卸载显示名字标记
|
||||||
|
; used for example as 'My Program (32-bit)'
|
||||||
|
UninstallDisplayNameMark=%1 (%2)
|
||||||
|
; used for example as 'My Program (32-bit, All users)'
|
||||||
|
UninstallDisplayNameMarks=%1 (%2, %3)
|
||||||
|
UninstallDisplayNameMark32Bit=32 位
|
||||||
|
UninstallDisplayNameMark64Bit=64 位
|
||||||
|
UninstallDisplayNameMarkAllUsers=所有用户
|
||||||
|
UninstallDisplayNameMarkCurrentUser=当前用户
|
||||||
|
|
||||||
|
; *** 安装后错误
|
||||||
|
ErrorOpeningReadme=尝试打开自述文件时出错。
|
||||||
|
ErrorRestartingComputer=安装程序无法重启电脑,请手动重启。
|
||||||
|
|
||||||
|
; *** 卸载消息
|
||||||
|
UninstallNotFound=文件“%1”不存在。无法卸载。
|
||||||
|
UninstallOpenError=文件“%1”不能被打开。无法卸载。
|
||||||
|
UninstallUnsupportedVer=此版本的卸载程序无法识别卸载日志文件“%1”的格式。无法卸载
|
||||||
|
UninstallUnknownEntry=卸载日志中遇到一个未知条目 (%1)
|
||||||
|
ConfirmUninstall=您确认要完全移除 %1 及其所有组件吗?
|
||||||
|
UninstallOnlyOnWin64=仅允许在 64 位 Windows 中卸载此程序。
|
||||||
|
OnlyAdminCanUninstall=仅使用管理员权限的用户能完成此卸载。
|
||||||
|
UninstallStatusLabel=正在从您的电脑中移除 %1,请稍候。
|
||||||
|
UninstalledAll=已顺利从您的电脑中移除 %1。
|
||||||
|
UninstalledMost=%1 卸载完成。%n%n有部分内容未能被删除,但您可以手动删除它们。
|
||||||
|
UninstalledAndNeedsRestart=为完成 %1 的卸载,需要重启您的电脑。%n%n立即重启电脑吗?
|
||||||
|
UninstallDataCorrupted=文件“%1”已损坏。无法卸载
|
||||||
|
|
||||||
|
; *** 卸载状态消息
|
||||||
|
ConfirmDeleteSharedFileTitle=删除共享的文件吗?
|
||||||
|
ConfirmDeleteSharedFile2=系统表示下列共享的文件已不有其他程序使用。您希望卸载程序删除这些共享的文件吗?%n%n如果删除这些文件,但仍有程序在使用这些文件,则这些程序可能出现异常。如果您不能确定,请选择“否”,在系统中保留这些文件以免引发问题。
|
||||||
|
SharedFileNameLabel=文件名:
|
||||||
|
SharedFileLocationLabel=位置:
|
||||||
|
WizardUninstalling=卸载状态
|
||||||
|
StatusUninstalling=正在卸载 %1...
|
||||||
|
|
||||||
|
; *** Shutdown block reasons
|
||||||
|
ShutdownBlockReasonInstallingApp=正在安装 %1。
|
||||||
|
ShutdownBlockReasonUninstallingApp=正在卸载 %1。
|
||||||
|
|
||||||
|
; The custom messages below aren't used by Setup itself, but if you make
|
||||||
|
; use of them in your scripts, you'll want to translate them.
|
||||||
|
|
||||||
|
[CustomMessages]
|
||||||
|
|
||||||
|
NameAndVersion=%1 版本 %2
|
||||||
|
AdditionalIcons=附加快捷方式:
|
||||||
|
CreateDesktopIcon=创建桌面快捷方式(&D)
|
||||||
|
CreateQuickLaunchIcon=创建快速启动栏快捷方式(&Q)
|
||||||
|
ProgramOnTheWeb=%1 网站
|
||||||
|
UninstallProgram=卸载 %1
|
||||||
|
LaunchProgram=运行 %1
|
||||||
|
AssocFileExtension=将 %2 文件扩展名与 %1 建立关联(&A)
|
||||||
|
AssocingFileExtension=正在将 %2 文件扩展名与 %1 建立关联...
|
||||||
|
AutoStartProgramGroupDescription=启动:
|
||||||
|
AutoStartProgram=自动启动 %1
|
||||||
|
AddonHostProgramNotFound=您选择的文件夹中无法找到 %1。%n%n您要继续吗?
|
||||||
BIN
resources/icons/MirrorChyan.ico
Normal file
BIN
resources/icons/MirrorChyan.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 17 KiB |
@@ -1,61 +1,31 @@
|
|||||||
{
|
{
|
||||||
"main_version": "4.3.6.2",
|
"main_version": "4.3.8.2",
|
||||||
"updater_version": "1.0.0.0",
|
|
||||||
"announcement": "\n## 新增功能\n- 屏蔽MuMu模拟器开屏广告功能上线\n- 更新器支持多线程下载\n- 添加强制关闭ADB与模拟器等增强任务项\n## 修复BUG\n- 修复统计信息HTML模板公招匹配错误\n- 修复密码显示按钮动画异常\n- 修复`检测到MAA未能实际执行任务`报错被异常屏蔽\n- 修复MAA超时判定异常失效\n## 程序优化\n- 关机等电源操作添加100s倒计时\n- 人工排查弹窗方法优化\n- 人工排查时自动屏蔽静默操作\n- 公告样式优化",
|
|
||||||
"version_info": {
|
"version_info": {
|
||||||
"4.3.6.2": {
|
"4.3.8.2": {
|
||||||
|
"修复bug": [
|
||||||
|
"日志分析忽略MAA超时提示"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"4.3.8.1": {
|
||||||
"新增功能": [
|
"新增功能": [
|
||||||
"新增`无人值守模式`"
|
"自定义基建显示配置名称 #46",
|
||||||
|
"主调度台添加仅一次电源任务"
|
||||||
],
|
],
|
||||||
"修复BUG": [
|
"修复bug": [
|
||||||
"修复软件窗口最大化异常问题",
|
"电源相关选项改为所有任务完成后生效",
|
||||||
"修复异常操作导致窗口离开屏幕后难以复原的问题",
|
"适配MAAv5.16.3的ADB报错信息更改"
|
||||||
"修正剩余理智关卡文案",
|
|
||||||
"修复隐藏到托盘时,托盘无法退出主程序的问题",
|
|
||||||
"修复Server酱网络异常导致的卡死问题"
|
|
||||||
],
|
],
|
||||||
"程序优化": [
|
"程序优化": [
|
||||||
"主窗口显示版本号"
|
"UI样式优化,进一步适配win10主题"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"4.3.6.1": {
|
"4.3.7.0": {
|
||||||
"新增功能": [
|
"新增功能": [
|
||||||
"单次自动代理任务中,已完成的子任务在重复执行时不再启用"
|
"下载器支持完整mirrorc列表"
|
||||||
]
|
|
||||||
},
|
|
||||||
"4.3.5.0": {
|
|
||||||
"新增功能": [
|
|
||||||
"用户设置中新增连战次数与剩余理智关卡两项配置项",
|
|
||||||
"支持自动代理时更新MAA"
|
|
||||||
],
|
|
||||||
"修复BUG": [
|
|
||||||
"适配MAAv5.16.0基建模式",
|
|
||||||
"适配自定义基建自动轮换功能"
|
|
||||||
],
|
],
|
||||||
"程序优化": [
|
"程序优化": [
|
||||||
"移除增效任务"
|
"重构更新逻辑,去除独立更新器"
|
||||||
]
|
|
||||||
},
|
|
||||||
"4.3.5.2": {
|
|
||||||
"修复BUG": [
|
|
||||||
"修复无法建立网络连接时软件卡死问题"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"4.3.5.1": {
|
|
||||||
"程序优化": [
|
|
||||||
"模拟器路径适配快捷方式"
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"proxy_list": [
|
|
||||||
"https://gitproxy.click/",
|
|
||||||
"https://cdn.moran233.xyz/",
|
|
||||||
"https://gh.llkk.cc/",
|
|
||||||
"https://github.akams.cn/",
|
|
||||||
"https://www.ghproxy.cn/",
|
|
||||||
"https://ghfast.top/"
|
|
||||||
],
|
|
||||||
"download_dict": {
|
|
||||||
"官方下载站-jp": "https://jp-download.fearr.xyz/AUTO_MAA/"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user