diff --git a/app/api/dispatch.py b/app/api/dispatch.py index 68a7b50..041d70f 100644 --- a/app/api/dispatch.py +++ b/app/api/dispatch.py @@ -38,7 +38,12 @@ async def add_task(task: TaskCreateIn = Body(...)) -> TaskCreateOut: try: task_id = await TaskManager.add_task(task.mode, task.taskId) except Exception as e: - return TaskCreateOut(code=500, status="error", message=str(e), websocketId="") + return TaskCreateOut( + code=500, + status="error", + message=f"{type(e).__name__}: {str(e)}", + websocketId="", + ) return TaskCreateOut(websocketId=str(task_id)) @@ -48,19 +53,22 @@ async def stop_task(task: DispatchIn = Body(...)) -> OutBase: try: await TaskManager.stop_task(task.taskId) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() -@router.websocket("/ws/{taskId}") +@router.websocket("/ws/{websocketId}") async def websocket_endpoint( - websocket: WebSocket, taskId: str = Path(..., description="要连接的任务ID") + websocket: WebSocket, + websocketId: str = Path(..., description="要连接的WebSocket ID"), ): await websocket.accept() try: - uid = uuid.UUID(taskId) + uid = uuid.UUID(websocketId) except ValueError: - await websocket.close(code=1008, reason="无效的任务ID") + await websocket.close(code=1008, reason="无效的WebSocket ID") return if uid in TaskManager.connection_events and uid not in TaskManager.websocket_dict: diff --git a/app/api/info.py b/app/api/info.py index a7438dc..2dc06bc 100644 --- a/app/api/info.py +++ b/app/api/info.py @@ -42,7 +42,9 @@ async def get_stage_combox( raw_data = await Config.get_stage_info(stage.type) data = [ComboBoxItem(**item) for item in raw_data] if raw_data else [] except Exception as e: - return ComboBoxOut(code=500, status="error", message=str(e), data=[]) + return ComboBoxOut( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}", data=[] + ) return ComboBoxOut(data=data) @@ -58,7 +60,9 @@ async def get_script_combox() -> ComboBoxOut: raw_data = await Config.get_script_combox() data = [ComboBoxItem(**item) for item in raw_data] if raw_data else [] except Exception as e: - return ComboBoxOut(code=500, status="error", message=str(e), data=[]) + return ComboBoxOut( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}", data=[] + ) return ComboBoxOut(data=data) @@ -74,7 +78,9 @@ async def get_task_combox() -> ComboBoxOut: raw_data = await Config.get_task_combox() data = [ComboBoxItem(**item) for item in raw_data] if raw_data else [] except Exception as e: - return ComboBoxOut(code=500, status="error", message=str(e), data=[]) + return ComboBoxOut( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}", data=[] + ) return ComboBoxOut(data=data) @@ -84,7 +90,9 @@ async def get_notice_info() -> InfoOut: try: data = await Config.get_server_info("notice") except Exception as e: - return InfoOut(code=500, status="error", message=str(e), data={}) + return InfoOut( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}", data={} + ) return InfoOut(data=data) @@ -96,7 +104,9 @@ async def get_apps_info() -> InfoOut: try: data = await Config.get_server_info("apps_info") except Exception as e: - return InfoOut(code=500, status="error", message=str(e), data={}) + return InfoOut( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}", data={} + ) return InfoOut(data=data) @@ -107,5 +117,10 @@ async def add_overview() -> InfoOut: try: data = await Config.get_stage_info("Info") except Exception as e: - return InfoOut(code=500, status="error", message=str(e), data={"ALL": []}) + return InfoOut( + code=500, + status="error", + message=f"{type(e).__name__}: {str(e)}", + data={"ALL": []}, + ) return InfoOut(data={"ALL": data}) diff --git a/app/api/plan.py b/app/api/plan.py index 40420b5..ed300e0 100644 --- a/app/api/plan.py +++ b/app/api/plan.py @@ -45,7 +45,13 @@ async def get_plan(plan: PlanGetIn = Body(...)) -> PlanGetOut: try: index, data = await Config.get_plan(plan.planId) except Exception as e: - return PlanGetOut(code=500, status="error", message=str(e), index=[], data={}) + return PlanGetOut( + code=500, + status="error", + message=f"{type(e).__name__}: {str(e)}", + index=[], + data={}, + ) return PlanGetOut(index=index, data=data) @@ -57,7 +63,9 @@ async def update_plan(plan: PlanUpdateIn = Body(...)) -> OutBase: try: await Config.update_plan(plan.planId, plan.data) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() @@ -67,7 +75,9 @@ async def delete_plan(plan: PlanDeleteIn = Body(...)) -> OutBase: try: await Config.del_plan(plan.planId) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() @@ -79,5 +89,7 @@ async def reorder_plan(plan: PlanReorderIn = Body(...)) -> OutBase: try: await Config.reorder_plan(plan.indexList) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() diff --git a/app/api/queue.py b/app/api/queue.py index 75e5a22..8fb39de 100644 --- a/app/api/queue.py +++ b/app/api/queue.py @@ -33,8 +33,17 @@ router = APIRouter(prefix="/api/queue", tags=["调度队列管理"]) ) async def add_queue() -> QueueCreateOut: - uid, config = await Config.add_queue() - data = QueueConfig(**(await config.toDict())) + try: + uid, config = await Config.add_queue() + data = QueueConfig(**(await config.toDict())) + except Exception as e: + return QueueCreateOut( + code=500, + status="error", + message=f"{type(e).__name__}: {str(e)}", + queueId="", + data=QueueConfig(**{}), + ) return QueueCreateOut(queueId=str(uid), data=data) @@ -48,7 +57,13 @@ async def get_queues(queue: QueueGetIn = Body(...)) -> QueueGetOut: index = [QueueIndexItem(**_) for _ in index] data = {uid: QueueConfig(**cfg) for uid, cfg in config.items()} except Exception as e: - return QueueGetOut(code=500, status="error", message=str(e), index=[], data={}) + return QueueGetOut( + code=500, + status="error", + message=f"{type(e).__name__}: {str(e)}", + index=[], + data={}, + ) return QueueGetOut(index=index, data=data) @@ -62,7 +77,9 @@ async def update_queue(queue: QueueUpdateIn = Body(...)) -> OutBase: queue.queueId, queue.data.model_dump(exclude_unset=True) ) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() @@ -72,7 +89,9 @@ async def delete_queue(queue: QueueDeleteIn = Body(...)) -> OutBase: try: await Config.del_queue(queue.queueId) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() @@ -82,10 +101,32 @@ async def reorder_queue(script: QueueReorderIn = Body(...)) -> OutBase: try: await Config.reorder_queue(script.indexList) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() +@router.post( + "/time/get", summary="查询定时项", response_model=TimeSetGetOut, status_code=200 +) +async def get_time_set(time: TimeSetGetIn = Body(...)) -> TimeSetGetOut: + + try: + index, data = await Config.get_time_set(time.queueId, time.timeSetId) + index = [TimeSetIndexItem(**_) for _ in index] + data = {uid: TimeSet(**cfg) for uid, cfg in data.items()} + except Exception as e: + return TimeSetGetOut( + code=500, + status="error", + message=f"{type(e).__name__}: {str(e)}", + index=[], + data={}, + ) + return TimeSetGetOut(index=index, data=data) + + @router.post( "/time/add", summary="添加定时项", response_model=TimeSetCreateOut, status_code=200 ) @@ -106,7 +147,9 @@ async def update_time_set(time: TimeSetUpdateIn = Body(...)) -> OutBase: time.queueId, time.timeSetId, time.data.model_dump(exclude_unset=True) ) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() @@ -118,22 +161,46 @@ async def delete_time_set(time: TimeSetDeleteIn = Body(...)) -> OutBase: try: await Config.del_time_set(time.queueId, time.timeSetId) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() @router.post( - "/time/order", summary="重新排序时间设置", response_model=OutBase, status_code=200 + "/time/order", summary="重新排序定时项", response_model=OutBase, status_code=200 ) async def reorder_time_set(time: TimeSetReorderIn = Body(...)) -> OutBase: try: await Config.reorder_time_set(time.queueId, time.indexList) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() +@router.post( + "/item/get", summary="查询队列项", response_model=QueueItemGetOut, status_code=200 +) +async def get_item(item: QueueItemGetIn = Body(...)) -> QueueItemGetOut: + + try: + index, data = await Config.get_queue_item(item.queueId, item.queueItemId) + index = [QueueItemIndexItem(**_) for _ in index] + data = {uid: QueueItem(**cfg) for uid, cfg in data.items()} + except Exception as e: + return QueueItemGetOut( + code=500, + status="error", + message=f"{type(e).__name__}: {str(e)}", + index=[], + data={}, + ) + return QueueItemGetOut(index=index, data=data) + + @router.post( "/item/add", summary="添加队列项", @@ -157,7 +224,9 @@ async def update_item(item: QueueItemUpdateIn = Body(...)) -> OutBase: item.queueId, item.queueItemId, item.data.model_dump(exclude_unset=True) ) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() @@ -169,7 +238,9 @@ async def delete_item(item: QueueItemDeleteIn = Body(...)) -> OutBase: try: await Config.del_queue_item(item.queueId, item.queueItemId) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() @@ -181,5 +252,7 @@ async def reorder_item(item: QueueItemReorderIn = Body(...)) -> OutBase: try: await Config.reorder_queue_item(item.queueId, item.indexList) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() diff --git a/app/api/scripts.py b/app/api/scripts.py index 96d57f8..4ac36a2 100644 --- a/app/api/scripts.py +++ b/app/api/scripts.py @@ -20,6 +20,7 @@ # Contact: DLmaster_361@163.com +import uuid from fastapi import APIRouter, Body from app.core import Config @@ -28,13 +29,27 @@ from app.models.schema import * router = APIRouter(prefix="/api/scripts", tags=["脚本管理"]) +SCRIPT_BOOK = {"MaaConfig": MaaConfig, "GeneralConfig": GeneralConfig} +USER_BOOK = {"MaaConfig": MaaUserConfig, "GeneralConfig": GeneralUserConfig} + + @router.post( "/add", summary="添加脚本", response_model=ScriptCreateOut, status_code=200 ) async def add_script(script: ScriptCreateIn = Body(...)) -> ScriptCreateOut: - uid, config = await Config.add_script(script.type) - return ScriptCreateOut(scriptId=str(uid), data=await config.toDict()) + try: + uid, config = await Config.add_script(script.type) + data = SCRIPT_BOOK[type(config).__name__](**(await config.toDict())) + except Exception as e: + return ScriptCreateOut( + code=500, + status="error", + message=f"{type(e).__name__}: {str(e)}", + scriptId="", + data=GeneralConfig(**{}), + ) + return ScriptCreateOut(scriptId=str(uid), data=data) @router.post( @@ -44,8 +59,21 @@ async def get_scripts(script: ScriptGetIn = Body(...)) -> ScriptGetOut: try: index, data = await Config.get_script(script.scriptId) + index = [ScriptIndexItem(**_) for _ in index] + data = { + uid: SCRIPT_BOOK[next((_.type for _ in index if _.uid == uid), "General")]( + **cfg + ) + for uid, cfg in data.items() + } except Exception as e: - return ScriptGetOut(code=500, status="error", message=str(e), index=[], data={}) + return ScriptGetOut( + code=500, + status="error", + message=f"{type(e).__name__}: {str(e)}", + index=[], + data={}, + ) return ScriptGetOut(index=index, data=data) @@ -55,9 +83,13 @@ async def get_scripts(script: ScriptGetIn = Body(...)) -> ScriptGetOut: async def update_script(script: ScriptUpdateIn = Body(...)) -> OutBase: try: - await Config.update_script(script.scriptId, script.data) + await Config.update_script( + script.scriptId, script.data.model_dump(exclude_unset=True) + ) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() @@ -67,7 +99,9 @@ async def delete_script(script: ScriptDeleteIn = Body(...)) -> OutBase: try: await Config.del_script(script.scriptId) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() @@ -77,17 +111,56 @@ async def reorder_script(script: ScriptReorderIn = Body(...)) -> OutBase: try: await Config.reorder_script(script.indexList) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() +@router.post( + "/user/get", summary="查询用户", response_model=UserGetOut, status_code=200 +) +async def get_user(user: UserGetIn = Body(...)) -> UserGetOut: + + try: + index, data = await Config.get_user(user.scriptId, user.userId) + index = [UserIndexItem(**_) for _ in index] + data = { + uid: USER_BOOK[ + type(Config.ScriptConfig[uuid.UUID(user.scriptId)]).__name__ + ](**cfg) + for uid, cfg in data.items() + } + except Exception as e: + return UserGetOut( + code=500, + status="error", + message=f"{type(e).__name__}: {str(e)}", + index=[], + data={}, + ) + return UserGetOut(index=index, data=data) + + @router.post( "/user/add", summary="添加用户", response_model=UserCreateOut, status_code=200 ) async def add_user(user: UserInBase = Body(...)) -> UserCreateOut: - uid, config = await Config.add_user(user.scriptId) - return UserCreateOut(userId=str(uid), data=await config.toDict()) + try: + uid, config = await Config.add_user(user.scriptId) + data = USER_BOOK[type(Config.ScriptConfig[uuid.UUID(user.scriptId)]).__name__]( + **(await config.toDict()) + ) + except Exception as e: + return UserCreateOut( + code=500, + status="error", + message=f"{type(e).__name__}: {str(e)}", + userId="", + data=GeneralUserConfig(**{}), + ) + return UserCreateOut(userId=str(uid), data=data) @router.post( @@ -96,9 +169,13 @@ async def add_user(user: UserInBase = Body(...)) -> UserCreateOut: async def update_user(user: UserUpdateIn = Body(...)) -> OutBase: try: - await Config.update_user(user.scriptId, user.userId, user.data) + await Config.update_user( + user.scriptId, user.userId, user.data.model_dump(exclude_unset=True) + ) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() @@ -110,7 +187,9 @@ async def delete_user(user: UserDeleteIn = Body(...)) -> OutBase: try: await Config.del_user(user.scriptId, user.userId) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() @@ -122,5 +201,7 @@ async def reorder_user(user: UserReorderIn = Body(...)) -> OutBase: try: await Config.reorder_user(user.scriptId, user.indexList) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() diff --git a/app/api/setting.py b/app/api/setting.py index 5b59af4..0da21bb 100644 --- a/app/api/setting.py +++ b/app/api/setting.py @@ -36,7 +36,10 @@ async def get_scripts() -> SettingGetOut: data = await Config.get_setting() except Exception as e: return SettingGetOut( - code=500, status="error", message=str(e), data=GlobalConfig(**{}) + code=500, + status="error", + message=f"{type(e).__name__}: {str(e)}", + data=GlobalConfig(**{}), ) return SettingGetOut(data=GlobalConfig(**data)) @@ -48,5 +51,7 @@ async def update_script(script: SettingUpdateIn = Body(...)) -> OutBase: try: await Config.update_setting(script.data.model_dump(exclude_unset=True)) except Exception as e: - return OutBase(code=500, status="error", message=str(e)) + return OutBase( + code=500, status="error", message=f"{type(e).__name__}: {str(e)}" + ) return OutBase() diff --git a/app/core/config.py b/app/core/config.py index 3004420..ed101e6 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -596,8 +596,8 @@ class GeneralConfig(ConfigBase): self.Script_ErrorLog = ConfigItem("Script", "ErrorLog", "") self.Game_Enabled = ConfigItem("Game", "Enabled", False, BoolValidator()) - self.Game_Style = ConfigItem( - "Game", "Style", "Emulator", OptionsValidator(["Emulator", "Client"]) + self.Game_Type = ConfigItem( + "Game", "Type", "Emulator", OptionsValidator(["Emulator", "Client"]) ) self.Game_Path = ConfigItem("Game", "Path", ".", FileValidator()) self.Game_Arguments = ConfigItem("Game", "Arguments", "") @@ -738,6 +738,29 @@ class AppConfig(GlobalConfig): await self.ScriptConfig.setOrder([uuid.UUID(_) for _ in index_list]) + async def get_user( + self, script_id: str, user_id: Optional[str] + ) -> tuple[list, dict]: + """获取用户配置""" + + logger.info(f"获取用户配置:{script_id} - {user_id}") + + uid = uuid.UUID(script_id) + sc = self.ScriptConfig[uid] + + if isinstance(sc, (MaaConfig | GeneralConfig)): + if user_id is None: + data = await sc.UserData.toDict() + else: + data = await sc.UserData.get(uuid.UUID(user_id)) + else: + logger.error(f"Unsupported script config type: {type(sc)}") + raise TypeError(f"Unsupported script config type: {type(sc)}") + + index = data.pop("instances", []) + + return list(index), data + async def add_user(self, script_id: str) -> tuple[uuid.UUID, ConfigBase]: """添加用户配置""" @@ -796,6 +819,57 @@ class AppConfig(GlobalConfig): await script_config.UserData.setOrder([uuid.UUID(_) for _ in index_list]) await self.ScriptConfig.save() + async def add_plan( + self, script: Literal["MaaPlan"] + ) -> tuple[uuid.UUID, ConfigBase]: + """添加计划表""" + + logger.info(f"添加计划表:{script}") + + return await self.PlanConfig.add(CLASS_BOOK[script]) + + async def get_plan(self, plan_id: Optional[str]) -> tuple[list, dict]: + """获取计划表配置""" + + logger.info(f"获取计划表配置:{plan_id}") + + if plan_id is None: + data = await self.PlanConfig.toDict() + else: + data = await self.PlanConfig.get(uuid.UUID(plan_id)) + + index = data.pop("instances", []) + + return list(index), data + + async def update_plan(self, plan_id: str, data: Dict[str, Dict[str, Any]]) -> None: + """更新计划表配置""" + + logger.info(f"更新计划表配置:{plan_id}") + + uid = uuid.UUID(plan_id) + + for group, items in data.items(): + for name, value in items.items(): + logger.debug(f"更新计划表配置:{plan_id} - {group}.{name} = {value}") + await self.PlanConfig[uid].set(group, name, value) + + await self.PlanConfig.save() + + async def del_plan(self, plan_id: str) -> None: + """删除计划表配置""" + + logger.info(f"删除计划表配置:{plan_id}") + + await self.PlanConfig.remove(uuid.UUID(plan_id)) + + async def reorder_plan(self, index_list: list[str]) -> None: + """重新排序计划表""" + + logger.info(f"重新排序计划表:{index_list}") + + await self.PlanConfig.setOrder([uuid.UUID(_) for _ in index_list]) + async def add_queue(self) -> tuple[uuid.UUID, ConfigBase]: """添加调度队列""" @@ -849,6 +923,29 @@ class AppConfig(GlobalConfig): await self.QueueConfig.setOrder([uuid.UUID(_) for _ in index_list]) + async def get_time_set( + self, queue_id: str, time_set_id: Optional[str] + ) -> tuple[list, dict]: + """获取时间设置配置""" + + logger.info(f"Get time set of queue: {queue_id} - {time_set_id}") + + uid = uuid.UUID(queue_id) + qc = self.QueueConfig[uid] + + if isinstance(qc, QueueConfig): + if time_set_id is None: + data = await qc.TimeSet.toDict() + else: + data = await qc.TimeSet.get(uuid.UUID(time_set_id)) + else: + logger.error(f"Unsupported queue config type: {type(qc)}") + raise TypeError(f"Unsupported queue config type: {type(qc)}") + + index = data.pop("instances", []) + + return list(index), data + async def add_time_set(self, queue_id: str) -> tuple[uuid.UUID, ConfigBase]: """添加时间设置配置""" @@ -905,57 +1002,29 @@ class AppConfig(GlobalConfig): await queue_config.TimeSet.setOrder([uuid.UUID(_) for _ in index_list]) await self.QueueConfig.save() - async def add_plan( - self, script: Literal["MaaPlan"] - ) -> tuple[uuid.UUID, ConfigBase]: - """添加计划表""" + async def get_queue_item( + self, queue_id: str, queue_item_id: Optional[str] + ) -> tuple[list, dict]: + """获取队列项配置""" - logger.info(f"添加计划表:{script}") + logger.info(f"Get queue item of queue: {queue_id} - {queue_item_id}") - return await self.PlanConfig.add(CLASS_BOOK[script]) + uid = uuid.UUID(queue_id) + qc = self.QueueConfig[uid] - async def get_plan(self, plan_id: Optional[str]) -> tuple[list, dict]: - """获取计划表配置""" - - logger.info(f"获取计划表配置:{plan_id}") - - if plan_id is None: - data = await self.PlanConfig.toDict() + if isinstance(qc, QueueConfig): + if queue_item_id is None: + data = await qc.QueueItem.toDict() + else: + data = await qc.QueueItem.get(uuid.UUID(queue_item_id)) else: - data = await self.PlanConfig.get(uuid.UUID(plan_id)) + logger.error(f"Unsupported queue config type: {type(qc)}") + raise TypeError(f"Unsupported queue config type: {type(qc)}") index = data.pop("instances", []) return list(index), data - async def update_plan(self, plan_id: str, data: Dict[str, Dict[str, Any]]) -> None: - """更新计划表配置""" - - logger.info(f"更新计划表配置:{plan_id}") - - uid = uuid.UUID(plan_id) - - for group, items in data.items(): - for name, value in items.items(): - logger.debug(f"更新计划表配置:{plan_id} - {group}.{name} = {value}") - await self.PlanConfig[uid].set(group, name, value) - - await self.PlanConfig.save() - - async def del_plan(self, plan_id: str) -> None: - """删除计划表配置""" - - logger.info(f"删除计划表配置:{plan_id}") - - await self.PlanConfig.remove(uuid.UUID(plan_id)) - - async def reorder_plan(self, index_list: list[str]) -> None: - """重新排序计划表""" - - logger.info(f"重新排序计划表:{index_list}") - - await self.PlanConfig.setOrder([uuid.UUID(_) for _ in index_list]) - async def add_queue_item(self, queue_id: str) -> tuple[uuid.UUID, ConfigBase]: """添加队列项配置""" diff --git a/app/models/schema.py b/app/models/schema.py index b95f535..d369746 100644 --- a/app/models/schema.py +++ b/app/models/schema.py @@ -21,7 +21,7 @@ from pydantic import BaseModel, Field -from typing import Dict, Any, List, Optional, Literal +from typing import Any, Dict, List, Union, Optional, Literal class OutBase(BaseModel): @@ -133,6 +133,21 @@ class GlobalConfig(BaseModel): Update: Optional[GlobalConfig_Update] = Field(None, description="更新相关配置") +class QueueIndexItem(BaseModel): + uid: str = Field(..., description="唯一标识符") + type: Literal["QueueConfig"] = Field(..., description="配置类型") + + +class QueueItemIndexItem(BaseModel): + uid: str = Field(..., description="唯一标识符") + type: Literal["QueueItem"] = Field(..., description="配置类型") + + +class TimeSetIndexItem(BaseModel): + uid: str = Field(..., description="唯一标识符") + type: Literal["TimeSet"] = Field(..., description="配置类型") + + class QueueItem_Info(BaseModel): ScriptId: Optional[str] = Field( None, description="任务所对应的脚本ID, 为None时表示未选择" @@ -152,11 +167,6 @@ class TimeSet(BaseModel): Info: Optional[TimeSet_Info] = Field(None, description="时间项") -class QueueIndexItem(BaseModel): - uid: str = Field(..., description="唯一标识符") - type: Literal["QueueConfig"] = Field(..., description="配置类型") - - class QueueConfig_Info(BaseModel): Name: Optional[str] = Field(None, description="队列名称") TimeEnabled: Optional[bool] = Field(None, description="是否启用定时") @@ -169,188 +179,119 @@ class QueueConfig_Info(BaseModel): class QueueConfig(BaseModel): - Info: Optional[QueueConfig_Info] = Field(None, description="队列信息") -# class MaaUserConfig(ConfigBase): -# """MAA用户配置""" - -# def __init__(self) -> None: -# super().__init__() - -# self.Info_Name = ConfigItem("Info", "Name", "新用户") -# self.Info_Id = ConfigItem("Info", "Id", "") -# self.Info_Mode = ConfigItem( -# "Info", "Mode", "简洁", OptionsValidator(["简洁", "详细"]) -# ) -# self.Info_StageMode = ConfigItem("Info", "StageMode", "固定") -# self.Info_Server = ConfigItem( -# "Info", -# "Server", -# "Official", -# OptionsValidator( -# ["Official", "Bilibili", "YoStarEN", "YoStarJP", "YoStarKR", "txwy"] -# ), -# ) -# self.Info_Status = ConfigItem("Info", "Status", True, BoolValidator()) -# self.Info_RemainedDay = ConfigItem( -# "Info", "RemainedDay", -1, RangeValidator(-1, 1024) -# ) -# self.Info_Annihilation = ConfigItem( -# "Info", -# "Annihilation", -# "Annihilation", -# OptionsValidator( -# [ -# "Close", -# "Annihilation", -# "Chernobog@Annihilation", -# "LungmenOutskirts@Annihilation", -# "LungmenDowntown@Annihilation", -# ] -# ), -# ) -# self.Info_Routine = ConfigItem("Info", "Routine", True, BoolValidator()) -# self.Info_InfrastMode = ConfigItem( -# "Info", -# "InfrastMode", -# "Normal", -# OptionsValidator(["Normal", "Rotation", "Custom"]), -# ) -# self.Info_Password = ConfigItem("Info", "Password", "", EncryptValidator()) -# self.Info_Notes = ConfigItem("Info", "Notes", "无") -# self.Info_MedicineNumb = ConfigItem( -# "Info", "MedicineNumb", 0, RangeValidator(0, 1024) -# ) -# self.Info_SeriesNumb = ConfigItem( -# "Info", -# "SeriesNumb", -# "0", -# OptionsValidator(["0", "6", "5", "4", "3", "2", "1", "-1"]), -# ) -# self.Info_Stage = ConfigItem("Info", "Stage", "-") -# self.Info_Stage_1 = ConfigItem("Info", "Stage_1", "-") -# self.Info_Stage_2 = ConfigItem("Info", "Stage_2", "-") -# self.Info_Stage_3 = ConfigItem("Info", "Stage_3", "-") -# self.Info_Stage_Remain = ConfigItem("Info", "Stage_Remain", "-") -# self.Info_IfSkland = ConfigItem("Info", "IfSkland", False, BoolValidator()) -# self.Info_SklandToken = ConfigItem("Info", "SklandToken", "") - -# self.Data_LastProxyDate = ConfigItem("Data", "LastProxyDate", "2000-01-01") -# self.Data_LastAnnihilationDate = ConfigItem( -# "Data", "LastAnnihilationDate", "2000-01-01" -# ) -# self.Data_LastSklandDate = ConfigItem("Data", "LastSklandDate", "2000-01-01") -# self.Data_ProxyTimes = ConfigItem( -# "Data", "ProxyTimes", 0, RangeValidator(0, 1024) -# ) -# self.Data_IfPassCheck = ConfigItem("Data", "IfPassCheck", True, BoolValidator()) -# self.Data_CustomInfrastPlanIndex = ConfigItem( -# "Data", "CustomInfrastPlanIndex", "0" -# ) - -# self.Task_IfWakeUp = ConfigItem("Task", "IfWakeUp", True, BoolValidator()) -# self.Task_IfRecruiting = ConfigItem( -# "Task", "IfRecruiting", True, BoolValidator() -# ) -# self.Task_IfBase = ConfigItem("Task", "IfBase", True, BoolValidator()) -# self.Task_IfCombat = ConfigItem("Task", "IfCombat", True, BoolValidator()) -# self.Task_IfMall = ConfigItem("Task", "IfMall", True, BoolValidator()) -# self.Task_IfMission = ConfigItem("Task", "IfMission", True, BoolValidator()) -# self.Task_IfAutoRoguelike = ConfigItem( -# "Task", "IfAutoRoguelike", False, BoolValidator() -# ) -# self.Task_IfReclamation = ConfigItem( -# "Task", "IfReclamation", False, BoolValidator() -# ) - -# self.Notify_Enabled = ConfigItem("Notify", "Enabled", False, BoolValidator()) -# self.Notify_IfSendStatistic = ConfigItem( -# "Notify", "IfSendStatistic", False, BoolValidator() -# ) -# self.Notify_IfSendSixStar = ConfigItem( -# "Notify", "IfSendSixStar", False, BoolValidator() -# ) -# self.Notify_IfSendMail = ConfigItem( -# "Notify", "IfSendMail", False, BoolValidator() -# ) -# self.Notify_ToAddress = ConfigItem("Notify", "ToAddress", "") -# self.Notify_IfServerChan = ConfigItem( -# "Notify", "IfServerChan", False, BoolValidator() -# ) -# self.Notify_ServerChanKey = ConfigItem("Notify", "ServerChanKey", "") -# self.Notify_IfCompanyWebHookBot = ConfigItem( -# "Notify", "IfCompanyWebHookBot", False, BoolValidator() -# ) -# self.Notify_CompanyWebHookBotUrl = ConfigItem( -# "Notify", "CompanyWebHookBotUrl", "" -# ) - -# def get_plan_info(self) -> Dict[str, Union[str, int]]: -# """获取当前的计划下信息""" - -# if self.get("Info", "StageMode") == "固定": -# return { -# "MedicineNumb": self.get("Info", "MedicineNumb"), -# "SeriesNumb": self.get("Info", "SeriesNumb"), -# "Stage": self.get("Info", "Stage"), -# "Stage_1": self.get("Info", "Stage_1"), -# "Stage_2": self.get("Info", "Stage_2"), -# "Stage_3": self.get("Info", "Stage_3"), -# "Stage_Remain": self.get("Info", "Stage_Remain"), -# } -# else: -# plan = Config.PlanConfig[uuid.UUID(self.get("Info", "StageMode"))] -# if isinstance(plan, MaaPlanConfig): -# return { -# "MedicineNumb": plan.get_current_info("MedicineNumb").getValue(), -# "SeriesNumb": plan.get_current_info("SeriesNumb").getValue(), -# "Stage": plan.get_current_info("Stage").getValue(), -# "Stage_1": plan.get_current_info("Stage_1").getValue(), -# "Stage_2": plan.get_current_info("Stage_2").getValue(), -# "Stage_3": plan.get_current_info("Stage_3").getValue(), -# "Stage_Remain": plan.get_current_info("Stage_Remain").getValue(), -# } -# else: -# raise ValueError("Invalid plan type") +class ScriptIndexItem(BaseModel): + uid: str = Field(..., description="唯一标识符") + type: Literal["MaaConfig", "GeneralConfig"] = Field(..., description="配置类型") -# class MaaConfig(ConfigBase): -# """MAA配置""" +class UserIndexItem(BaseModel): + uid: str = Field(..., description="唯一标识符") + type: Literal["MaaUserConfig", "GeneralUserConfig"] = Field( + ..., description="配置类型" + ) -# def __init__(self) -> None: -# super().__init__() -# self.Info_Name = ConfigItem("Info", "Name", "") -# self.Info_Path = ConfigItem("Info", "Path", ".", FolderValidator()) +class MaaUserConfig_Info(BaseModel): + Name: Optional[str] = Field(None, description="用户名") + Id: Optional[str] = Field(None, description="用户ID") + Mode: Optional[Literal["简洁", "详细"]] = Field(None, description="用户配置模式") + StageMode: Optional[str] = Field(None, description="关卡配置模式") + Server: Optional[ + Literal["Official", "Bilibili", "YoStarEN", "YoStarJP", "YoStarKR", "txwy"] + ] = Field(None, description="服务器") + Status: Optional[bool] = Field(None, description="用户状态") + RemainedDay: Optional[int] = Field(None, description="剩余天数") + Annihilation: Optional[ + Literal[ + "Close", + "Annihilation", + "Chernobog@Annihilation", + "LungmenOutskirts@Annihilation", + "LungmenDowntown@Annihilation", + ] + ] = Field(None, description="剿灭模式") + Routine: Optional[bool] = Field(None, description="是否启用日常") + InfrastMode: Optional[Literal["Normal", "Rotation", "Custom"]] = Field( + None, description="基建模式" + ) + Password: Optional[str] = Field(None, description="密码") + Notes: Optional[str] = Field(None, description="备注") + MedicineNumb: Optional[int] = Field(None, description="吃理智药数量") + SeriesNumb: Optional[Literal["0", "6", "5", "4", "3", "2", "1", "-1"]] = Field( + None, description="连战次数" + ) + Stage: Optional[str] = Field(None, description="关卡选择") + Stage_1: Optional[str] = Field(None, description="备选关卡 - 1") + Stage_2: Optional[str] = Field(None, description="备选关卡 - 2") + Stage_3: Optional[str] = Field(None, description="备选关卡 - 3") + Stage_Remain: Optional[str] = Field(None, description="剩余理智关卡") + IfSkland: Optional[bool] = Field(None, description="是否启用森空岛签到") + SklandToken: Optional[str] = Field(None, description="SklandToken") -# self.Run_TaskTransitionMethod = ConfigItem( -# "Run", -# "TaskTransitionMethod", -# "ExitEmulator", -# OptionsValidator(["NoAction", "ExitGame", "ExitEmulator"]), -# ) -# self.Run_ProxyTimesLimit = ConfigItem( -# "Run", "ProxyTimesLimit", 0, RangeValidator(0, 1024) -# ) -# self.Run_ADBSearchRange = ConfigItem( -# "Run", "ADBSearchRange", 0, RangeValidator(0, 3) -# ) -# self.Run_RunTimesLimit = ConfigItem( -# "Run", "RunTimesLimit", 3, RangeValidator(1, 1024) -# ) -# self.Run_AnnihilationTimeLimit = ConfigItem( -# "Run", "AnnihilationTimeLimit", 40, RangeValidator(1, 1024) -# ) -# self.Run_RoutineTimeLimit = ConfigItem( -# "Run", "RoutineTimeLimit", 10, RangeValidator(1, 1024) -# ) -# self.Run_AnnihilationWeeklyLimit = ConfigItem( -# "Run", "AnnihilationWeeklyLimit", True, BoolValidator() -# ) -# self.UserData = MultipleConfig([MaaUserConfig]) +class MaaUserConfig_Data(BaseModel): + LastProxyDate: Optional[str] = Field(None, description="上次代理日期") + LastAnnihilationDate: Optional[str] = Field(None, description="上次剿灭日期") + LastSklandDate: Optional[str] = Field(None, description="上次森空岛签到日期") + ProxyTimes: Optional[int] = Field(None, description="代理次数") + IfPassCheck: Optional[bool] = Field(None, description="是否通过人工排查") + + +class MaaUserConfig_Task(BaseModel): + IfWakeUp: Optional[bool] = Field(None, description="开始唤醒") + IfRecruiting: Optional[bool] = Field(None, description="自动公招") + IfBase: Optional[bool] = Field(None, description="基建换班") + IfCombat: Optional[bool] = Field(None, description="刷理智") + IfMall: Optional[bool] = Field(None, description="获取信用及购物") + IfMission: Optional[bool] = Field(None, description="领取奖励") + IfAutoRoguelike: Optional[bool] = Field(None, description="自动肉鸽") + IfReclamation: Optional[bool] = Field(None, description="生息演算") + + +class UserConfig_Notify(BaseModel): + Enabled: Optional[bool] = Field(None, description="是否启用通知") + IfSendStatistic: Optional[bool] = Field(None, description="是否发送统计信息") + IfSendSixStar: Optional[bool] = Field(None, description="是否发送高资喜报") + IfSendMail: Optional[bool] = Field(None, description="是否发送邮件通知") + ToAddress: Optional[str] = Field(None, description="邮件接收地址") + IfServerChan: Optional[bool] = Field(None, description="是否使用Server酱推送") + ServerChanKey: Optional[str] = Field(None, description="ServerChanKey") + IfCompanyWebHookBot: Optional[bool] = Field(None, description="是否使用Webhook推送") + CompanyWebHookBotUrl: Optional[str] = Field(None, description="企微Webhook Bot URL") + + +class MaaUserConfig(BaseModel): + Info: Optional[MaaUserConfig_Info] = Field(None, description="基础信息") + Data: Optional[MaaUserConfig_Data] = Field(None, description="用户数据") + Task: Optional[MaaUserConfig_Task] = Field(None, description="任务列表") + Notify: Optional[UserConfig_Notify] = Field(None, description="单独通知") + + +class MaaConfig_Info(BaseModel): + Name: Optional[str] = Field(None, description="脚本名称") + Path: Optional[str] = Field(None, description="脚本路径") + + +class MaaConfig_Run(BaseModel): + TaskTransitionMethod: Optional[Literal["NoAction", "ExitGame", "ExitEmulator"]] = ( + Field(None, description="简洁任务间切换方式") + ) + ProxyTimesLimit: Optional[int] = Field(None, description="每日代理次数限制") + ADBSearchRange: Optional[int] = Field(None, description="ADB端口搜索范围") + RunTimesLimit: Optional[int] = Field(None, description="重试次数限制") + AnnihilationTimeLimit: Optional[int] = Field(None, description="剿灭超时限制") + RoutineTimeLimit: Optional[int] = Field(None, description="日常超时限制") + AnnihilationWeeklyLimit: Optional[bool] = Field( + None, description="剿灭每周仅代理至上限" + ) + + +class MaaConfig(BaseModel): + Info: Optional[MaaConfig_Info] = Field(None, description="脚本基础信息") + Run: Optional[MaaConfig_Run] = Field(None, description="脚本运行配置") # class MaaPlanConfig(ConfigBase): @@ -429,120 +370,82 @@ class QueueConfig(BaseModel): # raise ValueError("The mode is invalid.") -# class GeneralUserConfig(ConfigBase): -# """通用子配置""" +class GeneralUserConfig_Info(BaseModel): -# def __init__(self) -> None: -# super().__init__() - -# self.Info_Name = ConfigItem("Info", "Name", "新配置") -# self.Info_Status = ConfigItem("Info", "Status", True, BoolValidator()) -# self.Info_RemainedDay = ConfigItem( -# "Info", "RemainedDay", -1, RangeValidator(-1, 1024) -# ) -# self.Info_IfScriptBeforeTask = ConfigItem( -# "Info", "IfScriptBeforeTask", False, BoolValidator() -# ) -# self.Info_ScriptBeforeTask = ConfigItem( -# "Info", "ScriptBeforeTask", "", FileValidator() -# ) -# self.Info_IfScriptAfterTask = ConfigItem( -# "Info", "IfScriptAfterTask", False, BoolValidator() -# ) -# self.Info_ScriptAfterTask = ConfigItem( -# "Info", "ScriptAfterTask", "", FileValidator() -# ) -# self.Info_Notes = ConfigItem("Info", "Notes", "无") - -# self.Data_LastProxyDate = ConfigItem("Data", "LastProxyDate", "2000-01-01") -# self.Data_ProxyTimes = ConfigItem( -# "Data", "ProxyTimes", 0, RangeValidator(0, 1024) -# ) - -# self.Notify_Enabled = ConfigItem("Notify", "Enabled", False, BoolValidator()) -# self.Notify_IfSendStatistic = ConfigItem( -# "Notify", "IfSendStatistic", False, BoolValidator() -# ) -# self.Notify_IfSendMail = ConfigItem( -# "Notify", "IfSendMail", False, BoolValidator() -# ) -# self.Notify_ToAddress = ConfigItem("Notify", "ToAddress", "") -# self.Notify_IfServerChan = ConfigItem( -# "Notify", "IfServerChan", False, BoolValidator() -# ) -# self.Notify_ServerChanKey = ConfigItem("Notify", "ServerChanKey", "") -# self.Notify_IfCompanyWebHookBot = ConfigItem( -# "Notify", "IfCompanyWebHookBot", False, BoolValidator() -# ) -# self.Notify_CompanyWebHookBotUrl = ConfigItem( -# "Notify", "CompanyWebHookBotUrl", "" -# ) + Name: Optional[str] = Field(None, description="用户名") + Status: Optional[bool] = Field(None, description="用户状态") + RemainedDay: Optional[int] = Field(None, description="剩余天数") + IfScriptBeforeTask: Optional[bool] = Field(None, description="是否在任务前执行脚本") + ScriptBeforeTask: Optional[str] = Field(None, description="任务前脚本路径") + IfScriptAfterTask: Optional[bool] = Field(None, description="是否在任务后执行脚本") + ScriptAfterTask: Optional[str] = Field(None, description="任务后脚本路径") + Notes: Optional[str] = Field(None, description="备注") -# class GeneralConfig(ConfigBase): -# """通用配置""" +class GeneralUserConfig_Data(BaseModel): + LastProxyDate: Optional[str] = Field(None, description="上次代理日期") + ProxyTimes: Optional[int] = Field(None, description="代理次数") -# def __init__(self) -> None: -# super().__init__() -# self.Info_Name = ConfigItem("Info", "Name", "") -# self.Info_RootPath = ConfigItem("Info", "RootPath", ".", FileValidator()) +class GeneralUserConfig(BaseModel): + Info: Optional[GeneralUserConfig_Info] = Field(None, description="用户信息") + Data: Optional[GeneralUserConfig_Data] = Field(None, description="用户数据") + Notify: Optional[UserConfig_Notify] = Field(None, description="单独通知") -# self.Script_ScriptPath = ConfigItem( -# "Script", "ScriptPath", ".", FileValidator() -# ) -# self.Script_Arguments = ConfigItem("Script", "Arguments", "") -# self.Script_IfTrackProcess = ConfigItem( -# "Script", "IfTrackProcess", False, BoolValidator() -# ) -# self.Script_ConfigPath = ConfigItem( -# "Script", "ConfigPath", ".", FileValidator() -# ) -# self.Script_ConfigPathMode = ConfigItem( -# "Script", "ConfigPathMode", "File", OptionsValidator(["File", "Folder"]) -# ) -# self.Script_UpdateConfigMode = ConfigItem( -# "Script", -# "UpdateConfigMode", -# "Never", -# OptionsValidator(["Never", "Success", "Failure", "Always"]), -# ) -# self.Script_LogPath = ConfigItem("Script", "LogPath", ".", FileValidator()) -# self.Script_LogPathFormat = ConfigItem("Script", "LogPathFormat", "%Y-%m-%d") -# self.Script_LogTimeStart = ConfigItem( -# "Script", "LogTimeStart", 1, RangeValidator(1, 1024) -# ) -# self.Script_LogTimeEnd = ConfigItem( -# "Script", "LogTimeEnd", 1, RangeValidator(1, 1024) -# ) -# self.Script_LogTimeFormat = ConfigItem( -# "Script", "LogTimeFormat", "%Y-%m-%d %H:%M:%S" -# ) -# self.Script_SuccessLog = ConfigItem("Script", "SuccessLog", "") -# self.Script_ErrorLog = ConfigItem("Script", "ErrorLog", "") -# self.Game_Enabled = ConfigItem("Game", "Enabled", False, BoolValidator()) -# self.Game_Style = ConfigItem( -# "Game", "Style", "Emulator", OptionsValidator(["Emulator", "Client"]) -# ) -# self.Game_Path = ConfigItem("Game", "Path", ".", FileValidator()) -# self.Game_Arguments = ConfigItem("Game", "Arguments", "") -# self.Game_WaitTime = ConfigItem("Game", "WaitTime", 0, RangeValidator(0, 1024)) -# self.Game_IfForceClose = ConfigItem( -# "Game", "IfForceClose", False, BoolValidator() -# ) +class GeneralConfig_Info(BaseModel): + Name: Optional[str] = Field(None, description="脚本名称") + RootPath: Optional[str] = Field(None, description="脚本根目录") -# self.Run_ProxyTimesLimit = ConfigItem( -# "Run", "ProxyTimesLimit", 0, RangeValidator(0, 1024) -# ) -# self.Run_RunTimesLimit = ConfigItem( -# "Run", "RunTimesLimit", 3, RangeValidator(1, 1024) -# ) -# self.Run_RunTimeLimit = ConfigItem( -# "Run", "RunTimeLimit", 10, RangeValidator(1, 1024) -# ) -# self.UserData = MultipleConfig([GeneralUserConfig]) +class GeneralConfig_Script(BaseModel): + ScriptPath: Optional[str] = Field(None, description="脚本可执行文件路径") + Arguments: Optional[str] = Field(None, description="脚本启动附加命令参数") + IfTrackProcess: Optional[bool] = Field(None, description="是否追踪脚本子进程") + ConfigPath: Optional[str] = Field(None, description="配置文件路径") + ConfigPathMode: Optional[Literal["File", "Folder"]] = Field( + None, description="配置文件类型: 单个文件, 文件夹" + ) + UpdateConfigMode: Optional[Literal["Never", "Success", "Failure", "Always"]] = ( + Field( + None, + description="更新配置时机, 从不, 仅成功时, 仅失败时, 任务结束时", + ) + ) + LogPath: Optional[str] = Field(None, description="日志文件路径") + LogPathFormat: Optional[str] = Field(None, description="日志文件名格式") + LogTimeStart: Optional[int] = Field(None, description="日志时间戳开始位置") + LogTimeEnd: Optional[int] = Field(None, description="日志时间戳结束位置") + LogTimeFormat: Optional[str] = Field(None, description="日志时间戳格式") + SuccessLog: Optional[str] = Field(None, description="成功时日志") + ErrorLog: Optional[str] = Field(None, description="错误时日志") + + +class GeneralConfig_Game(BaseModel): + Enabled: Optional[bool] = Field(None, description="游戏/模拟器相关功能是否启用") + Type: Optional[Literal["Emulator", "Client"]] = Field( + None, description="类型: 模拟器, PC端" + ) + Path: Optional[str] = Field(None, description="游戏/模拟器程序路径") + Arguments: Optional[str] = Field(None, description="游戏/模拟器启动参数") + WaitTime: Optional[int] = Field(None, description="游戏/模拟器等待启动时间") + IfForceClose: Optional[bool] = Field( + None, description="是否强制关闭游戏/模拟器进程" + ) + + +class GeneralConfig_Run(BaseModel): + ProxyTimesLimit: Optional[int] = Field(None, description="每日代理次数限制") + RunTimesLimit: Optional[int] = Field(None, description="重试次数限制") + RunTimeLimit: Optional[int] = Field(None, description="日志超时限制") + + +class GeneralConfig(BaseModel): + + Info: Optional[GeneralConfig_Info] = Field(None, description="脚本基础信息") + Script: Optional[GeneralConfig_Script] = Field(None, description="脚本配置") + Game: Optional[GeneralConfig_Game] = Field(None, description="游戏配置") + Run: Optional[GeneralConfig_Run] = Field(None, description="运行配置") class ScriptCreateIn(BaseModel): @@ -553,21 +456,25 @@ class ScriptCreateIn(BaseModel): class ScriptCreateOut(OutBase): scriptId: str = Field(..., description="新创建的脚本ID") - data: Dict[str, Any] = Field(..., description="脚本配置数据") + data: Union[MaaConfig, GeneralConfig] = Field(..., description="脚本配置数据") class ScriptGetIn(BaseModel): - scriptId: Optional[str] = Field(None, description="脚本ID,仅在模式为Single时需要") + scriptId: Optional[str] = Field( + None, description="脚本ID, 未携带时表示获取所有脚本数据" + ) class ScriptGetOut(OutBase): - index: List[Dict[str, str]] = Field(..., description="脚本索引列表") - data: Dict[str, Any] = Field(..., description="脚本列表或单个脚本数据") + index: List[ScriptIndexItem] = Field(..., description="脚本索引列表") + data: Dict[str, Union[MaaConfig, GeneralConfig]] = Field( + ..., description="脚本数据字典, key来自于index列表的uid" + ) class ScriptUpdateIn(BaseModel): scriptId: str = Field(..., description="脚本ID") - data: Dict[str, Dict[str, Any]] = Field(..., description="脚本更新数据") + data: Union[MaaConfig, GeneralConfig] = Field(..., description="脚本更新数据") class ScriptDeleteIn(BaseModel): @@ -582,14 +489,31 @@ class UserInBase(BaseModel): scriptId: str = Field(..., description="所属脚本ID") +class UserGetIn(UserInBase): + userId: Optional[str] = Field( + None, description="用户ID, 未携带时表示获取所有用户数据" + ) + + +class UserGetOut(OutBase): + index: List[UserIndexItem] = Field(..., description="用户索引列表") + data: Dict[str, Union[MaaUserConfig, GeneralUserConfig]] = Field( + ..., description="用户数据字典, key来自于index列表的uid" + ) + + class UserCreateOut(OutBase): userId: str = Field(..., description="新创建的用户ID") - data: Dict[str, Any] = Field(..., description="用户配置数据") + data: Union[MaaUserConfig, GeneralUserConfig] = Field( + ..., description="用户配置数据" + ) class UserUpdateIn(UserInBase): userId: str = Field(..., description="用户ID") - data: Dict[str, Dict[str, Any]] = Field(..., description="用户更新数据") + data: Union[MaaUserConfig, GeneralUserConfig] = Field( + ..., description="用户更新数据" + ) class UserDeleteIn(UserInBase): @@ -644,7 +568,9 @@ class QueueGetIn(BaseModel): class QueueGetOut(OutBase): index: List[QueueIndexItem] = Field(..., description="队列索引列表") - data: Dict[str, QueueConfig] = Field(..., description="队列列表或单个队列数据") + data: Dict[str, QueueConfig] = Field( + ..., description="队列数据字典, key来自于index列表的uid" + ) class QueueUpdateIn(BaseModel): @@ -664,6 +590,19 @@ class QueueSetInBase(BaseModel): queueId: str = Field(..., description="所属队列ID") +class TimeSetGetIn(QueueSetInBase): + timeSetId: Optional[str] = Field( + None, description="时间设置ID, 未携带时表示获取所有时间设置数据" + ) + + +class TimeSetGetOut(OutBase): + index: List[TimeSetIndexItem] = Field(..., description="时间设置索引列表") + data: Dict[str, TimeSet] = Field( + ..., description="时间设置数据字典, key来自于index列表的uid" + ) + + class TimeSetCreateOut(OutBase): timeSetId: str = Field(..., description="新创建的时间设置ID") data: TimeSet = Field(..., description="时间设置配置数据") @@ -682,6 +621,19 @@ class TimeSetReorderIn(QueueSetInBase): indexList: List[str] = Field(..., description="时间设置ID列表,按新顺序排列") +class QueueItemGetIn(QueueSetInBase): + queueItemId: Optional[str] = Field( + None, description="队列项ID, 未携带时表示获取所有队列项数据" + ) + + +class QueueItemGetOut(OutBase): + index: List[QueueItemIndexItem] = Field(..., description="队列项索引列表") + data: Dict[str, QueueItem] = Field( + ..., description="队列项数据字典, key来自于index列表的uid" + ) + + class QueueItemCreateOut(OutBase): queueItemId: str = Field(..., description="新创建的队列项ID") data: QueueItem = Field(..., description="队列项配置数据") diff --git a/app/task/general.py b/app/task/general.py index 8c91a87..6389fbf 100644 --- a/app/task/general.py +++ b/app/task/general.py @@ -316,7 +316,7 @@ class GeneralManager: break # 更新静默进程标记有效时间 - if self.script_config.get("Game", "Style") == "Emulator": + if self.script_config.get("Game", "Type") == "Emulator": logger.info( f"更新静默进程标记:{self.game_path},标记有效时间:{datetime.now() + timedelta(seconds=self.script_config.get('Game', 'WaitTime') + 10)}" )