diff --git a/.gitignore b/.gitignore index 8818051..bce2619 100644 --- a/.gitignore +++ b/.gitignore @@ -665,3 +665,4 @@ FodyWeavers.xsd config.json res_data GsData.db +GenshinUID diff --git a/gsuid_core/aps.py b/gsuid_core/aps.py new file mode 100644 index 0000000..08a3ae6 --- /dev/null +++ b/gsuid_core/aps.py @@ -0,0 +1,17 @@ +from apscheduler.schedulers.asyncio import AsyncIOScheduler + +from gsuid_core.logger import logger + +scheduler = AsyncIOScheduler() + + +async def start_scheduler(): + if not scheduler.running: + scheduler.start() + logger.info('定时任务启动...') + + +async def shutdown_scheduler(): + if scheduler.running: + scheduler.shutdown() + logger.info('定时任务结束...') diff --git a/gsuid_core/bot.py b/gsuid_core/bot.py index cd47120..be666a8 100644 --- a/gsuid_core/bot.py +++ b/gsuid_core/bot.py @@ -1,12 +1,13 @@ import asyncio -from typing import List, Union, Optional +from typing import List, Union, Literal, Optional -from logger import logger from fastapi import WebSocket -from gs_logger import GsLogger -from segment import MessageSegment from msgspec import json as msgjson -from models import Message, MessageSend + +from gsuid_core.logger import logger +from gsuid_core.gs_logger import GsLogger +from gsuid_core.segment import MessageSegment +from gsuid_core.models import Message, MessageSend class Bot: @@ -21,6 +22,18 @@ class Bot: self.user_type: Optional[str] = None async def send(self, message: Union[Message, List[Message], str, bytes]): + await self.target_send( + message, + self.user_type, # type:ignore + self.group_id if self.group_id else self.user_id, + ) + + async def target_send( + self, + message: Union[Message, List[Message], str, bytes], + target_type: Literal['group', 'driect', 'channel', 'sub_channel'], + target_id: Optional[str], + ): if isinstance(message, Message): message = [message] elif isinstance(message, str): @@ -33,8 +46,8 @@ class Bot: send = MessageSend( content=message, bot_id=self.bot_id, - target_type=self.user_type, - target_id=self.group_id if self.group_id else self.user_id, + target_type=target_type, + target_id=target_id, ) logger.info(f'[发送消息] {send}') await self.bot.send_bytes(msgjson.encode(send)) diff --git a/gsuid_core/client.py b/gsuid_core/client.py index 614e4f5..447868f 100644 --- a/gsuid_core/client.py +++ b/gsuid_core/client.py @@ -36,7 +36,7 @@ class GsClient: intent = await self._input() msg = MessageReceive( bot_id='Nonebot', - user_type='DIRECT', + user_type='direct', user_pm=2, group_id=None, user_id='5253123', diff --git a/gsuid_core/core.py b/gsuid_core/core.py index d20069c..75b0d69 100644 --- a/gsuid_core/core.py +++ b/gsuid_core/core.py @@ -1,13 +1,18 @@ +import sys import asyncio +from pathlib import Path import uvicorn -from gss import gss -from config import core_config -from handler import handle_event -from models import MessageReceive from msgspec import json as msgjson from fastapi import FastAPI, WebSocket, WebSocketDisconnect +sys.path.append(str(Path(__file__).parents[1])) +from gsuid_core.gss import gss # noqa: E402 +from gsuid_core.config import core_config # noqa: E402 +from gsuid_core.handler import handle_event # noqa: E402 +from gsuid_core.models import MessageReceive # noqa: E402 +from gsuid_core.aps import start_scheduler, shutdown_scheduler # noqa: E402 + app = FastAPI() HOST = core_config.get_config('HOST') PORT = int(core_config.get_config('PORT')) @@ -32,5 +37,15 @@ async def websocket_endpoint(websocket: WebSocket, bot_id: str): await asyncio.gather(process(), start()) +@app.on_event('startup') +async def startup_event(): + await start_scheduler() + + +@app.on_event('shutdown') +async def shutdown_event(): + await shutdown_scheduler() + + if __name__ == "__main__": uvicorn.run(app, host=HOST, port=PORT) diff --git a/gsuid_core/gs_logger.py b/gsuid_core/gs_logger.py index 2a00cbd..cd7305d 100644 --- a/gsuid_core/gs_logger.py +++ b/gsuid_core/gs_logger.py @@ -1,10 +1,11 @@ from typing import Literal from fastapi import WebSocket -from models import MessageSend -from segment import MessageSegment from msgspec import json as msgjson +from gsuid_core.models import MessageSend +from gsuid_core.segment import MessageSegment + class GsLogger: def __init__(self, bot_id: str, ws: WebSocket): diff --git a/gsuid_core/gss.py b/gsuid_core/gss.py index f86aca6..b8c49a9 100644 --- a/gsuid_core/gss.py +++ b/gsuid_core/gss.py @@ -1,6 +1,16 @@ -from server import GsServer +from gsuid_core.aps import scheduler +from gsuid_core.server import GsServer gss = GsServer() if not gss.is_load: gss.is_load = True gss.load_plugins() + +repeat_jobs = {} +for i in scheduler.get_jobs(): + if i.name not in repeat_jobs: + repeat_jobs[i.name] = i + else: + scheduler.remove_job(i.id) + +del repeat_jobs diff --git a/gsuid_core/handler.py b/gsuid_core/handler.py index f370cfc..8ab2929 100644 --- a/gsuid_core/handler.py +++ b/gsuid_core/handler.py @@ -1,11 +1,10 @@ import asyncio -from bot import Bot -from trigger import Trigger -from config import core_config -from models import MessageContent, MessageReceive - from gsuid_core.sv import SL +from gsuid_core.bot import Bot +from gsuid_core.trigger import Trigger +from gsuid_core.config import core_config +from gsuid_core.models import MessageContent, MessageReceive config_masters = core_config.get_config('masters') config_superusers = core_config.get_config('superusers') diff --git a/gsuid_core/hook.py b/gsuid_core/hook.py deleted file mode 100644 index 3d4644c..0000000 --- a/gsuid_core/hook.py +++ /dev/null @@ -1,19 +0,0 @@ -from functools import wraps -from typing import Callable, Optional - -from gsuid_core.server import gss -from gsuid_core.logger import logger - - -def on_bot_connect(): - def deco(func: Callable) -> Callable: - gss.bot_connect_def.append(func) - - @wraps(func) - async def wrapper(*args, **kwargs) -> Optional[Callable]: - logger.info('@on_bot_connect已成功调用...') - return await func(*args, **kwargs) - - return wrapper - - return deco diff --git a/gsuid_core/models.py b/gsuid_core/models.py index a68d5d5..3397bbb 100644 --- a/gsuid_core/models.py +++ b/gsuid_core/models.py @@ -1,4 +1,4 @@ -from typing import Any, List, Optional +from typing import Any, List, Literal, Optional from msgspec import Struct @@ -10,7 +10,9 @@ class Message(Struct): class MessageReceive(Struct, frozen=True): bot_id: str = 'Bot' - user_type: Optional[str] = None + user_type: Optional[ + Literal['group', 'direct', 'channel', 'sub_channel'] + ] = None group_id: Optional[str] = None user_id: str = '' user_pm: int = 3 diff --git a/gsuid_core/segment.py b/gsuid_core/segment.py index 62618ec..9788b79 100644 --- a/gsuid_core/segment.py +++ b/gsuid_core/segment.py @@ -3,7 +3,8 @@ from base64 import b64encode from typing import List, Union, Literal from PIL import Image -from models import Message + +from gsuid_core.models import Message class MessageSegment: diff --git a/gsuid_core/server.py b/gsuid_core/server.py index 23ff01d..31a6a1e 100644 --- a/gsuid_core/server.py +++ b/gsuid_core/server.py @@ -4,11 +4,10 @@ import importlib from pathlib import Path from typing import Dict, Callable -from bot import Bot -from logger import logger from fastapi import WebSocket -sys.path.append(str(Path(__file__).parents[1])) +from gsuid_core.bot import Bot +from gsuid_core.logger import logger class GsServer: @@ -25,10 +24,12 @@ class GsServer: def __init__(self): if not self.is_initialized: - self.active_bot: Dict[str, WebSocket] = {} + self.active_ws: Dict[str, WebSocket] = {} + self.active_bot: Dict[str, Bot] = {} self.is_initialized = True def load_plugins(self): + logger.info('开始导入插件...') sys.path.append(str(Path(__file__).parents[1])) plug_path = Path(__file__).parent / 'plugins' # 遍历插件文件夹内所有文件 @@ -57,21 +58,23 @@ class GsServer: async def connect(self, websocket: WebSocket, bot_id: str) -> Bot: await websocket.accept() - self.active_bot[bot_id] = websocket + self.active_ws[bot_id] = websocket + self.active_bot[bot_id] = bot = Bot(bot_id, websocket) logger.info(f'{bot_id}已连接!') _task = [_def() for _def in self.bot_connect_def] asyncio.gather(*_task) - return Bot(bot_id, websocket) + return bot def disconnect(self, bot_id: str): + del self.active_ws[bot_id] del self.active_bot[bot_id] logger.warning(f'{bot_id}已中断!') async def send(self, message: str, bot_id: str): - await self.active_bot[bot_id].send_text(message) + await self.active_ws[bot_id].send_text(message) async def broadcast(self, message: str): - for bot_id in self.active_bot: + for bot_id in self.active_ws: await self.send(message, bot_id) @classmethod diff --git a/gsuid_core/sv.py b/gsuid_core/sv.py index 8ba4484..8bc1251 100644 --- a/gsuid_core/sv.py +++ b/gsuid_core/sv.py @@ -3,9 +3,9 @@ from __future__ import annotations from functools import wraps from typing import Dict, List, Tuple, Union, Literal, Callable, Optional -from logger import logger -from trigger import Trigger -from config import core_config +from gsuid_core.logger import logger +from gsuid_core.trigger import Trigger +from gsuid_core.config import core_config class SVList: diff --git a/gsuid_core/trigger.py b/gsuid_core/trigger.py index 537b41b..93b112c 100644 --- a/gsuid_core/trigger.py +++ b/gsuid_core/trigger.py @@ -1,6 +1,6 @@ from typing import Literal, Callable -from models import MessageContent +from gsuid_core.models import MessageContent class Trigger: