From 0e3aee4315d02110c8b3e7587778c471c5a65e05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wuyi=E6=97=A0=E7=96=91?= <444835641@qq.com> Date: Sat, 11 Mar 2023 17:04:19 +0800 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20=E5=85=BC=E5=AE=B9=E5=A4=9A?= =?UTF-8?q?=E7=A7=8D=E9=80=82=E9=85=8D=E5=99=A8=E3=80=81=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E6=94=B6=E5=8F=91=E6=B6=88=E6=81=AF=E6=A0=BC=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- GenshinUID/__init__.py | 46 +++++++++++-- GenshinUID/auto_install.py | 7 +- GenshinUID/client.py | 130 +++++++++++++++++++++++-------------- poetry.lock | 6 +- 4 files changed, 128 insertions(+), 61 deletions(-) diff --git a/GenshinUID/__init__.py b/GenshinUID/__init__.py index 588ee450..deb755c1 100644 --- a/GenshinUID/__init__.py +++ b/GenshinUID/__init__.py @@ -20,22 +20,55 @@ gsclient: Optional[GsClient] = None @get_message.handle() async def send_char_adv(ev: Event): if gsclient is None: - return await start_client() + return await connect() + + # 通用字段获取 sessions = ev.get_session_id().split('_') - group_id = sessions[-2] if len(sessions) >= 2 else None user_id = str(ev.get_user_id()) messages = ev.get_message() - bot_id = messages.__class__.__module__.split('.')[2] + raw_data = ev.__dict__ + group_id = sessions[-2] if len(sessions) >= 2 else None message: List[Message] = [] + + # ntchat + if '_message' in raw_data: + messages = raw_data['_message'] + group_id = str(raw_data['channel_id']) + # qqguild + elif not messages and 'message' in raw_data: + messages = raw_data['message'] + # ntchat + elif 'data' in raw_data: + if 'chatroom' in raw_data['data']['to_wxid']: + group_id = raw_data['data']['to_wxid'] + if 'image' in raw_data['data']: + message.append(Message('image', raw_data['data']['image'])) + if 'from_wxid' in raw_data['data']: + user_id = raw_data['data']['from_wxid'] + if 'at_user_list' in raw_data['data']: + _at_list = raw_data['data']['at_user_list'] + at_list = [Message('at', i) for i in _at_list] + message.extend(at_list) + bot_id = messages.__class__.__module__.split('.')[2] + + # 处理消息 for _msg in messages: if _msg.type == 'text': - message.append(Message('text', _msg.data['text'])) + message.append( + Message( + 'text', + _msg.data['text'] + if 'text' in _msg.data + else _msg.data['content'], + ) + ) elif _msg.type == 'image': message.append(Message('image', _msg.data['url'])) elif _msg.type == 'at': message.append(Message('at', _msg.data['qq'])) if not message: return + msg = MessageReceive( bot_id=bot_id, user_type='group' if group_id else 'direct', @@ -62,6 +95,11 @@ async def send_start_msg(matcher: Matcher): @driver.on_bot_connect async def start_client(): + await start() + await connect() + + +async def connect(): global gsclient try: gsclient = await GsClient().async_connect() diff --git a/GenshinUID/auto_install.py b/GenshinUID/auto_install.py index 3a36ebca..fe80c274 100644 --- a/GenshinUID/auto_install.py +++ b/GenshinUID/auto_install.py @@ -2,6 +2,7 @@ import asyncio import subprocess from git.repo import Repo +from nonebot.log import logger from pip._internal import main as pip_install from .path import CORE_PATH, GSUID_PATH @@ -28,10 +29,8 @@ async def _install(): async def install(): - done, _ = await asyncio.wait([_install()]) - for future in done: - if future.result is None: - return '安装出现错误, 请查看控制台信息!' + done = await asyncio.gather(_install()) + logger.info(done) return '安装成功...' diff --git a/GenshinUID/client.py b/GenshinUID/client.py index 40d706df..cd324b6d 100644 --- a/GenshinUID/client.py +++ b/GenshinUID/client.py @@ -3,15 +3,29 @@ import asyncio from typing import Dict, List, Union, Optional import websockets.client -from nonebot import get_bot from nonebot.log import logger from nonebot.adapters import Bot from msgspec import json as msgjson +from nonebot import get_bot, get_bots from websockets.exceptions import ConnectionClosedError from .models import MessageSend, MessageReceive BOT_ID = 'NoneBot2' +bots: Dict[str, str] = {} + + +def _get_bot(bot_id: str) -> Bot: + if 'onebot' in bot_id: + bot_id = 'onebot' + if bot_id not in bots: + for _bot_id in bots.keys(): + if bot_id in _bot_id: + bot_id = _bot_id + break + bot_real_id = bots[bot_id] + bot = get_bot(bot_real_id) + return bot class GsClient: @@ -29,53 +43,69 @@ class GsClient: async def recv_msg(self): try: - bot = get_bot() + global bots + _bots = get_bots() + for bot_real_id in _bots: + bot = _bots[bot_real_id] + bot_id = bot.type.lower().replace(' ', '') + bots[bot_id] = bot_real_id async for message in self.ws: - msg = msgjson.decode(message, type=MessageSend) - logger.info(f'【接收】[gsuid-core]: {msg}') - # 解析消息 - content = '' - image: Optional[str] = None - node = [] - if msg.content: - for _c in msg.content: - if _c.data: - if _c.type == 'text': - content += _c.data - elif _c.type == 'image': - image = _c.data - elif _c.type and _c.type.startswith('log'): - _type = _c.type.split('_')[-1].lower() - getattr(logger, _type)(_c.data) - elif _c.type == 'node': - node = _c.data - else: - pass + try: + msg = msgjson.decode(message, type=MessageSend) + logger.info( + f'【接收】[gsuid-core]: ' + f'{msg.bot_id} - {msg.target_type} - {msg.target_id}' + ) + # 解析消息 + if msg.bot_id == 'NoneBot2': + continue + bot = _get_bot(msg.bot_id) + content = '' + image: Optional[str] = None + node = [] + if msg.content: + for _c in msg.content: + if _c.data: + if _c.type == 'text': + content += _c.data + elif _c.type == 'image': + image = _c.data + elif _c.type and _c.type.startswith('log'): + _type = _c.type.split('_')[-1].lower() + getattr(logger, _type)(_c.data) + elif _c.type == 'node': + node = _c.data + else: + pass - # 根据bot_id字段发送消息 - # OneBot v11 & v12 - if msg.bot_id == 'onebot': - await onebot_send( - bot, - content, - image, - node, - msg.target_id, - msg.target_type, - ) - # ntchat - elif msg.bot_id == 'ntchat': - await ntchat_send(bot, content, image, node, msg.target_id) - # 频道 - elif msg.bot_id == 'qqguild': - await guild_send( - bot, - content, - image, - node, - msg.target_id, - msg.target_type, - ) + # 根据bot_id字段发送消息 + # OneBot v11 & v12 + if msg.bot_id == 'onebot': + await onebot_send( + bot, + content, + image, + node, + msg.target_id, + msg.target_type, + ) + # ntchat + elif msg.bot_id == 'ntchat': + await ntchat_send( + bot, content, image, node, msg.target_id + ) + # 频道 + elif msg.bot_id == 'qqguild': + await guild_send( + bot, + content, + image, + node, + msg.target_id, + msg.target_type, + ) + except Exception as e: + logger.error(e) except ConnectionClosedError: logger.warning(f'与[gsuid-core]断开连接! Bot_ID: {BOT_ID}') @@ -115,7 +145,7 @@ async def onebot_send( target_type: Optional[str], ): async def _send(content: Optional[str], image: Optional[str]): - result_image = f'[CQ:image,file=base64://{image}]' if image else '' + result_image = f'[CQ:image,file={image}]' if image else '' content = content if content else '' result_msg = content + result_image if target_type == 'group': @@ -148,7 +178,7 @@ async def onebot_send( if node: messages = [ to_json( - f'[CQ:image,file=base64://{_msg["data"]}]' + f'[CQ:image,file={_msg["data"]}]' if _msg['type'] == 'image' else _msg['data'], '小助手', @@ -173,7 +203,7 @@ async def guild_send( async def _send(content: Optional[str], image: Optional[str]): result = {} if image: - img_bytes = base64.b64decode(image) + img_bytes = base64.b64decode(image.replace('base64://', '')) result['file_image'] = img_bytes if content: result['content'] = content @@ -215,7 +245,7 @@ async def ntchat_send( await bot.call_api( 'send_image', to_wxid=target_id, - content=content, + file_path=image, ) if node: diff --git a/poetry.lock b/poetry.lock index 00b41ca2..8fc4ce2b 100644 --- a/poetry.lock +++ b/poetry.lock @@ -564,14 +564,14 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa [[package]] name = "platformdirs" -version = "3.1.0" +version = "3.1.1" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "platformdirs-3.1.0-py3-none-any.whl", hash = "sha256:13b08a53ed71021350c9e300d4ea8668438fb0046ab3937ac9a29913a1a1350a"}, - {file = "platformdirs-3.1.0.tar.gz", hash = "sha256:accc3665857288317f32c7bebb5a8e482ba717b474f3fc1d18ca7f9214be0cef"}, + {file = "platformdirs-3.1.1-py3-none-any.whl", hash = "sha256:e5986afb596e4bb5bde29a79ac9061aa955b94fca2399b7aaac4090860920dd8"}, + {file = "platformdirs-3.1.1.tar.gz", hash = "sha256:024996549ee88ec1a9aa99ff7f8fc819bb59e2c3477b410d90a16d32d6e707aa"}, ] [package.extras]