改写战斗中替换group的逻辑

This commit is contained in:
Elaina 2024-10-13 01:24:58 +08:00
commit 7f89eb0db8
3890 changed files with 82290 additions and 0 deletions

View file

@ -0,0 +1,105 @@
import json
from datetime import datetime, timedelta
from queue import Queue
from threading import Event
from typing import TYPE_CHECKING, Any, Optional
import requests
import yaml
from pydantic import BaseModel
from yamlcore import CoreDumper, CoreLoader
from mower.utils.config.conf import Conf
from mower.utils.config.plan import PlanModel
from mower.utils.path import get_path
if TYPE_CHECKING:
from mower.utils.device.device import Device
from mower.utils.recognize import Recognizer
conf_path = get_path("@app/conf.yml")
plan_path = get_path("@app/plan.json")
def save_conf():
with conf_path.open("w", encoding="utf8") as f:
yaml.dump(
conf.model_dump(),
f,
Dumper=CoreDumper,
encoding="utf-8",
default_flow_style=False,
allow_unicode=True,
)
def load_conf():
global conf
if not conf_path.is_file():
conf_path.parent.mkdir(exist_ok=True)
conf = Conf()
save_conf()
return
with conf_path.open("r", encoding="utf-8") as f:
conf = Conf(**yaml.load(f, Loader=CoreLoader))
conf: Conf
load_conf()
def save_plan():
with plan_path.open("w", encoding="utf-8") as f:
json.dump(plan.model_dump(exclude_none=True), f, ensure_ascii=False, indent=2)
def load_plan():
global plan
if not plan_path.is_file():
plan_path.parent.mkdir(exist_ok=True)
plan = PlanModel()
save_plan()
return
with plan_path.open("r", encoding="utf-8") as f:
plan = PlanModel(**json.load(f))
plan: PlanModel
load_plan()
stop_mower = Event()
stop_maa = Event()
idle: bool = True
operators = {}
# 日志
log_queue = Queue()
wh = None
class DroidCast(BaseModel):
session: Any = requests.Session()
port: int = 0
process: Any = None
droidcast = DroidCast()
screenshot_time: datetime = datetime.now() - timedelta(
milliseconds=conf.screenshot_interval
)
screenshot_avg: Optional[int] = None
screenshot_count: int = 0
device: Optional["Device"] = None
recog: Optional["Recognizer"] = None
# 常量
APP_ACTIVITY_NAME = "com.u8.sdk.U8UnityContext"
MAX_RETRYTIME = 5
MNT_COMPATIBILITY_MODE = False
MNT_PORT = 20937

573
mower/utils/config/conf.py Normal file
View file

@ -0,0 +1,573 @@
from pydantic import BaseModel, model_validator
from pydantic_core import PydanticUndefined
class ConfModel(BaseModel):
@model_validator(mode="before")
@classmethod
def nested_defaults(cls, data):
for name, field in cls.model_fields.items():
if name not in data:
if field.default is PydanticUndefined:
data[name] = field.annotation()
else:
data[name] = field.default
return data
class CluePart(ConfModel):
class CreditFightConf(ConfModel):
direction: str = "Right"
"部署方向"
operator: str = "风笛"
"使用干员"
squad: int = 1
"编队序号"
x: int = 5
"横坐标"
y: int = 3
"纵坐标"
maa_credit_fight: bool = True
"信用作战开关"
credit_fight: CreditFightConf
"信用作战设置"
enable_party: int = 1
"线索收集"
leifeng_mode: int = 1
"雷锋模式"
maa_mall_blacklist: str = "加急许可,碳,碳素,家具零件"
"黑名单"
maa_mall_buy: str = "招聘许可,技巧概要·卷2"
"优先购买"
maa_mall_ignore_blacklist_when_full: bool = False
"信用溢出时无视黑名单"
class EmailPart(ConfModel):
class CustomSMTPServerConf(ConfModel):
enable: bool = False
"启用自定义邮箱"
server: str = ""
"SMTP服务器"
encryption: str = "starttls"
"加密方式"
ssl_port: int = 587
"端口号"
mail_enable: int = 0
"邮件提醒"
account: str = ""
"邮箱用户名"
pass_code: str = ""
"邮箱密码"
recipient: list[str] = []
"收件人"
custom_smtp_server: CustomSMTPServerConf
"自定义邮箱"
mail_subject: str = "[Mower通知]"
"标题前缀"
notification_level: str = "INFO"
"邮件通知等级"
class ExtraPart(ConfModel):
class WebViewConf(ConfModel):
port: int = 58000
"端口号"
width: int = 1450
"窗口宽度"
height: int = 850
"窗口高度"
token: str = ""
"远程连接密钥"
scale: float = 1
"网页缩放"
tray: bool = True
"托盘图标"
class WaitingSceneConf(ConfModel):
CONNECTING: tuple[int, int] = (1000, 15)
UNKNOWN: tuple[int, int] = (0, 10)
UNKNOWN_WITH_NAVBAR: tuple[int, int] = (0, 5)
LOADING: tuple[int, int] = (3000, 60)
LOGIN_LOADING: tuple[int, int] = (3000, 30)
LOGIN_MAIN_NOENTRY: tuple[int, int] = (3000, 30)
OPERATOR_ONGOING: tuple[int, int] = (10000, 300)
start_automatically: bool = False
"启动后自动开始任务"
webview: WebViewConf
"GUI相关设置"
theme: str = "light"
"界面主题"
screenshot_interval: int = 500
"截图最短间隔(毫秒)"
screenshot: float = 24
"截图保留时长(小时)"
waiting_scene_v2: WaitingSceneConf
"等待时间"
max_workers: int = 4
"头像、半身像识别线程数"
class LongTaskPart(ConfModel):
class RogueConf(ConfModel):
squad: str = ""
"分队"
roles: str = ""
"职业"
core_char: str = ""
"干员"
use_support: bool = False
"开局干员使用助战"
use_nonfriend_support: bool = False
"开局干员使用非好友助战"
mode: int = 1
"策略"
refresh_trader_with_dice: bool = False
"刷新商店(指路鳞)"
expected_collapsal_paradigms: list[str] = [
"目空一些",
"睁眼瞎",
"图像损坏",
"一抹黑",
]
"需要刷的坍缩范式"
class ReclamationAlgorithmConf(ConfModel):
timeout: int = 30
"生息演算和隐秘战线的超时时间"
class SecretFrontConf(ConfModel):
target: str = "结局A"
"隐秘战线结局"
class SignInConf(ConfModel):
enable: bool = True
"签到活动开关"
maa_rg_enable: int = 0
"大型任务"
maa_long_task_type: str = "rogue"
"大型任务类型"
maa_rg_sleep_max: str = "0:00"
"开始时间"
maa_rg_sleep_min: str = "0:00"
"停止时间"
maa_rg_theme: str = "Mizuki"
"肉鸽主题"
rogue: RogueConf
"肉鸽设置"
reclamation_algorithm: ReclamationAlgorithmConf
"生息演算"
secret_front: SecretFrontConf
"隐秘战线结局"
sign_in: SignInConf
"签到活动"
class MaaPart(ConfModel):
maa_path: str = "D:\\MAA-v4.13.0-win-x64"
maa_conn_preset: str = "General"
maa_touch_option: str = "maatouch"
class RecruitPart(ConfModel):
recruit_enable: bool = True
"公招开关"
recruit_robot: bool = True
"保留支援机械标签"
recruitment_permit: int = 30
"三星招募阈值"
recruit_gap: float = 9
"启动间隔"
recruit_auto_5: int = 1
"五星招募策略,1自动,2手动"
recruit_auto_only5: bool = False
"五星词条组合唯一时自动选择"
class RegularTaskPart(ConfModel):
class MaaDailyPlan(BaseModel):
medicine: int = 0
stage: list[str]
weekday: str
class MaaDailyPlan1(BaseModel):
stage: str | list[str]
周一: int
周二: int
周三: int
周四: int
周五: int
周六: int
周日: int
check_mail_enable: bool = True
"领取邮件奖励"
maa_enable: bool = True
"日常任务"
maa_gap: float = 3
"日常任务间隔"
maa_expiring_medicine: bool = True
"自动使用将要过期(约3天)的理智药"
exipring_medicine_on_weekend: bool = False
"仅在周末使用将要过期的理智药"
maa_eat_stone: bool = False
"无限吃源石"
maa_weekly_plan: list[MaaDailyPlan] = [
{"medicine": 0, "stage": [""], "weekday": "周一"},
{"medicine": 0, "stage": [""], "weekday": "周二"},
{"medicine": 0, "stage": [""], "weekday": "周三"},
{"medicine": 0, "stage": [""], "weekday": "周四"},
{"medicine": 0, "stage": [""], "weekday": "周五"},
{"medicine": 0, "stage": [""], "weekday": "周六"},
{"medicine": 0, "stage": [""], "weekday": "周日"},
]
"周计划"
maa_weekly_plan1: list[MaaDailyPlan1] = [
{
"stage": ["点x删除"],
"周一": 1,
"周二": 1,
"周三": 1,
"周四": 1,
"周五": 1,
"周六": 1,
"周日": 1,
},
{
"stage": ["把鼠标放到问号上查看帮助"],
"周一": 1,
"周二": 1,
"周三": 1,
"周四": 1,
"周五": 1,
"周六": 1,
"周日": 1,
},
{
"stage": ["自定义关卡3"],
"周一": 1,
"周二": 1,
"周三": 1,
"周四": 1,
"周五": 1,
"周六": 1,
"周日": 1,
},
{
"stage": ["Annihilation"],
"周一": 1,
"周二": 1,
"周三": 1,
"周四": 1,
"周五": 1,
"周六": 1,
"周日": 1,
},
{
"stage": ["1-7"],
"周一": 1,
"周二": 1,
"周三": 1,
"周四": 1,
"周五": 1,
"周六": 1,
"周日": 1,
},
{
"stage": ["LS-6"],
"周一": 1,
"周二": 1,
"周三": 1,
"周四": 1,
"周五": 1,
"周六": 1,
"周日": 1,
},
{
"stage": ["CE-6"],
"周一": 0,
"周二": 1,
"周三": 0,
"周四": 1,
"周五": 0,
"周六": 1,
"周日": 1,
},
{
"stage": ["AP-5"],
"周一": 1,
"周二": 0,
"周三": 0,
"周四": 1,
"周五": 0,
"周六": 1,
"周日": 1,
},
{
"stage": ["SK-6"],
"周一": 1,
"周二": 0,
"周三": 1,
"周四": 0,
"周五": 1,
"周六": 1,
"周日": 0,
},
{
"stage": ["CA-5"],
"周一": 0,
"周二": 1,
"周三": 1,
"周四": 0,
"周五": 1,
"周六": 0,
"周日": 1,
},
{
"stage": ["PR-A-2"],
"周一": 1,
"周二": 0,
"周三": 0,
"周四": 1,
"周五": 1,
"周六": 0,
"周日": 1,
},
{
"stage": ["PR-A-2"],
"周一": 1,
"周二": 0,
"周三": 0,
"周四": 1,
"周五": 1,
"周六": 0,
"周日": 1,
},
{
"stage": ["PR-B-2"],
"周一": 1,
"周二": 1,
"周三": 0,
"周四": 0,
"周五": 1,
"周六": 1,
"周日": 0,
},
{
"stage": ["PR-B-1"],
"周一": 1,
"周二": 1,
"周三": 0,
"周四": 0,
"周五": 1,
"周六": 1,
"周日": 0,
},
{
"stage": ["PR-C-2"],
"周一": 0,
"周二": 0,
"周三": 1,
"周四": 1,
"周五": 0,
"周六": 1,
"周日": 1,
},
{
"stage": ["PR-C-1"],
"周一": 0,
"周二": 0,
"周三": 1,
"周四": 1,
"周五": 0,
"周六": 1,
"周日": 1,
},
{
"stage": ["PR-D-2"],
"周一": 0,
"周二": 1,
"周三": 1,
"周四": 0,
"周五": 0,
"周六": 1,
"周日": 1,
},
{
"stage": ["PR-D-1"],
"周一": 0,
"周二": 1,
"周三": 1,
"周四": 0,
"周五": 0,
"周六": 1,
"周日": 1,
},
]
"周计划(新)"
maa_depot_enable: bool = False
"仓库物品混合读取"
visit_friend: bool = True
"访问好友"
report_enable: bool = True
"读取基报"
class RIICPart(ConfModel):
class RunOrderGrandetModeConf(ConfModel):
enable: bool = True
"葛朗台跑单开关"
buffer_time: int = 15
"缓冲时间"
back_to_index: bool = False
"跑单前返回基建首页"
drone_count_limit: int = 100
"无人机使用阈值"
drone_room: str = ""
"无人机使用房间"
drone_interval: float = 3
"无人机加速间隔"
free_blacklist: str = ""
"宿舍黑名单"
reload_room: str = ""
"搓玉补货房间"
run_order_delay: float = 3
"跑单前置延时"
resting_threshold: float = 0.65
"心情阈值"
run_order_grandet_mode: RunOrderGrandetModeConf
"葛朗台跑单"
free_room: bool = False
"宿舍不养闲人模式"
class SimulatorPart(ConfModel):
class SimulatorConf(ConfModel):
name: str = ""
"名称"
index: str | int = "-1"
"多开编号"
simulator_folder: str = ""
"文件夹"
wait_time: int = 30
"启动时间"
hotkey: str = ""
"老板键"
class CustomScreenshotConf(ConfModel):
command: str = "adb -s 127.0.0.1:5555 shell screencap -p 2>/dev/null"
"截图命令"
enable: bool = False
"是否启用自定义截图"
class TapToLaunchGameConf(ConfModel):
enable: bool = False
"点击屏幕启动游戏"
x: int = 0
"横坐标"
y: int = 0
"纵坐标"
class DroidCastConf(ConfModel):
enable: bool = True
"使用DroidCast截图"
rotate: bool = False
"将截图旋转180度"
adb: str = "127.0.0.1:16384"
"ADB连接地址"
simulator: SimulatorConf
"模拟器"
maa_adb_path: str = "D:\\Program Files\\Nox\\bin\\adb.exe"
"ADB路径"
close_simulator_when_idle: bool = False
"任务结束后关闭游戏"
package_type: int = 1
"游戏服务器"
custom_screenshot: CustomScreenshotConf
"自定义截图"
tap_to_launch_game: TapToLaunchGameConf
"点击屏幕启动游戏"
exit_game_when_idle: bool = True
"任务结束后退出游戏"
close_simulator_when_idle: bool = False
"任务结束后关闭模拟器"
fix_mumu12_adb_disconnect: bool = False
"关闭MuMu模拟器12时结束adb进程"
touch_method: str = "scrcpy"
"触控模式"
droidcast: DroidCastConf
"DroidCast截图设置"
class SKLandPart(ConfModel):
class SKLandAccount(BaseModel):
account: str = ""
"账号"
password: str = ""
"密码"
cultivate_select: bool = True
"服务器"
isCheck: bool = True
"签到"
sign_in_bilibili: bool = False
"官服签到"
sign_in_official: bool = False
"B服签到"
skland_enable: bool = False
"森空岛签到"
skland_info: list[SKLandAccount] = []
"森空岛账号"
class Conf(
CluePart,
EmailPart,
ExtraPart,
LongTaskPart,
MaaPart,
RecruitPart,
RegularTaskPart,
RIICPart,
SimulatorPart,
SKLandPart,
):
@property
def APPNAME(self):
return (
"com.hypergryph.arknights"
if self.package_type == 1
else "com.hypergryph.arknights.bilibili"
)
@property
def RG(self):
return self.maa_rg_enable == 1 and self.maa_long_task_type == "rogue"
@property
def SSS(self):
return self.maa_rg_enable == 1 and self.maa_long_task_type == "sss"
@property
def RA(self):
return self.maa_rg_enable == 1 and self.maa_long_task_type == "ra"
@property
def SF(self):
return self.maa_rg_enable == 1 and self.maa_long_task_type == "sf"
@property
def run_order_buffer_time(self):
"""
> 0 葛朗台跑单的缓冲时间
<= 0 无人机跑单
"""
if self.run_order_grandet_mode.enable:
return self.run_order_grandet_mode.buffer_time
return -1

112
mower/utils/config/plan.py Normal file
View file

@ -0,0 +1,112 @@
from __future__ import annotations
from typing import Optional
from pydantic import BaseModel
class PlanConf(BaseModel):
ling_xi: int = 1
"令夕模式,1感知 2烟火 3均衡"
max_resting_count: int = 0
"最大组人数"
exhaust_require: str = ""
"耗尽"
rest_in_full: str = ""
"回满"
resting_priority: str = ""
"低优先级"
workaholic: str = ""
"0心情工作(主力宿舍黑名单)"
refresh_trading: str = ""
"跑单时间刷新干员"
class BackupPlanConf(PlanConf):
free_blacklist: str = ""
"(非主力)宿舍黑名单"
class Plans(BaseModel):
agent: str
group: str = ""
replacement: list[str] = []
class Facility(BaseModel):
name: str = ""
plans: list[Plans] = []
product: Optional[str] = None
class Plan1(BaseModel):
central: Optional[Facility] = None
"控制中枢"
meeting: Optional[Facility] = None
"会客室"
factory: Optional[Facility] = None
"加工站"
contact: Optional[Facility] = None
"办公室"
train: Optional[Facility] = None
"训练室"
dormitory_1: Optional[Facility] = None
dormitory_2: Optional[Facility] = None
dormitory_3: Optional[Facility] = None
dormitory_4: Optional[Facility] = None
room_1_1: Optional[Facility] = None
room_1_2: Optional[Facility] = None
room_1_3: Optional[Facility] = None
room_2_1: Optional[Facility] = None
room_2_2: Optional[Facility] = None
room_2_3: Optional[Facility] = None
room_3_1: Optional[Facility] = None
room_3_2: Optional[Facility] = None
room_3_3: Optional[Facility] = None
class Task(BaseModel):
central: Optional[list[str]] = None
"控制中枢"
meeting: Optional[list[str]] = None
"会客室"
factory: Optional[list[str]] = None
"加工站"
contact: Optional[list[str]] = None
"办公室"
train: Optional[list[str]] = None
"训练室"
dormitory_1: Optional[list[str]] = None
dormitory_2: Optional[list[str]] = None
dormitory_3: Optional[list[str]] = None
dormitory_4: Optional[list[str]] = None
room_1_1: Optional[list[str]] = None
room_1_2: Optional[list[str]] = None
room_1_3: Optional[list[str]] = None
room_2_1: Optional[list[str]] = None
room_2_2: Optional[list[str]] = None
room_2_3: Optional[list[str]] = None
room_3_1: Optional[list[str]] = None
room_3_2: Optional[list[str]] = None
room_3_3: Optional[list[str]] = None
class Trigger(BaseModel):
left: str | Trigger = ""
operator: str = ""
right: str | Trigger = ""
class BackupPlan(BaseModel):
conf: BackupPlanConf = {}
plan: Plan1 = {}
task: Task = {}
trigger: Trigger = {}
trigger_timing: str = "AFTER_PLANNING"
class PlanModel(BaseModel):
default: str = "plan1"
plan1: Plan1 = Plan1()
conf: PlanConf = PlanConf()
backup_plans: list[BackupPlan] = []