feat: 恢复nakuru使用

This commit is contained in:
RockChinQ 2024-02-08 13:12:33 +08:00
parent d86ad25f86
commit f9a3e99795
8 changed files with 123 additions and 59 deletions

View File

@ -1,14 +1,38 @@
from __future__ import annotations
# MessageSource的适配器
import typing
import abc
import mirai
from ..core import app
preregistered_adapters: list[typing.Type[MessageSourceAdapter]] = []
def adapter_class(
name: str
):
def decorator(cls: typing.Type[MessageSourceAdapter]) -> typing.Type[MessageSourceAdapter]:
cls.name = name
preregistered_adapters.append(cls)
return cls
return decorator
class MessageSourceAdapter(metaclass=abc.ABCMeta):
name: str
bot_account_id: int
def __init__(self, config: dict):
pass
config: dict
ap: app.Application
def __init__(self, config: dict, ap: app.Application):
self.config = config
self.ap = ap
async def send_message(
self,

View File

@ -14,13 +14,14 @@ from ..platform import adapter as msadapter
from ..core import app, entities as core_entities
from ..plugin import events
# 控制QQ消息输入输出的类
class PlatformManager:
adapter: msadapter.MessageSourceAdapter = None
bot_account_id: int = 0
@property
def bot_account_id(self):
return self.adapter.bot_account_id
# modern
ap: app.Application = None
@ -31,22 +32,43 @@ class PlatformManager:
async def initialize(self):
if self.ap.platform_cfg.data['platform-adapter'] == 'yiri-mirai':
from pkg.platform.sources.yirimirai import YiriMiraiAdapter
# if self.ap.platform_cfg.data['platform-adapter'] == 'yiri-mirai':
# from pkg.platform.sources.yirimirai import YiriMiraiAdapter
mirai_http_api_config = self.ap.platform_cfg.data['yiri-mirai-config']
self.bot_account_id = mirai_http_api_config['qq']
self.adapter = YiriMiraiAdapter(mirai_http_api_config)
elif self.ap.platform_cfg.data['platform-adapter'] == 'aiocqhttp':
from pkg.platform.sources.aiocqhttp import AiocqhttpAdapter
# mirai_http_api_config = self.ap.platform_cfg.data['yiri-mirai-config']
# self.adapter = YiriMiraiAdapter(mirai_http_api_config, self.ap)
# elif self.ap.platform_cfg.data['platform-adapter'] == 'nakuru':
# from pkg.platform.sources.nakuru import NakuruProjectAdapter
aiocqhttp_config = self.ap.platform_cfg.data['aiocqhttp-config']
self.adapter = AiocqhttpAdapter(aiocqhttp_config, self.ap)
elif self.ap.platform_cfg.data['platform-adapter'] == 'qq-botpy':
from pkg.platform.sources.qqbotpy import OfficialAdapter
# nakuru_config = self.ap.platform_cfg.data['nakuru-config']
# self.adapter = NakuruProjectAdapter(nakuru_config, self.ap)
# elif self.ap.platform_cfg.data['platform-adapter'] == 'aiocqhttp':
# from pkg.platform.sources.aiocqhttp import AiocqhttpAdapter
qqbotpy_config = self.ap.platform_cfg.data['qq-botpy-config']
self.adapter = OfficialAdapter(qqbotpy_config, self.ap)
# aiocqhttp_config = self.ap.platform_cfg.data['aiocqhttp-config']
# self.adapter = AiocqhttpAdapter(aiocqhttp_config, self.ap)
# elif self.ap.platform_cfg.data['platform-adapter'] == 'qq-botpy':
# from pkg.platform.sources.qqbotpy import OfficialAdapter
# qqbotpy_config = self.ap.platform_cfg.data['qq-botpy-config']
# self.adapter = OfficialAdapter(qqbotpy_config, self.ap)
from .sources import yirimirai, nakuru, aiocqhttp, qqbotpy
adapter_cls = None
for adapter in msadapter.preregistered_adapters:
if adapter.name == self.ap.platform_cfg.data['platform-adapter']:
adapter_cls = adapter
break
if adapter_cls is None:
raise Exception('未知的平台适配器: ' + self.ap.platform_cfg.data['platform-adapter'])
cfg_key = self.ap.platform_cfg.data['platform-adapter'] + '-config'
self.adapter = adapter_cls(
self.ap.platform_cfg.data[cfg_key],
self.ap
)
async def on_friend_message(event: FriendMessage):

View File

@ -191,6 +191,7 @@ class AiocqhttpEventConverter(adapter.EventConverter):
)
@adapter.adapter_class("aiocqhttp")
class AiocqhttpAdapter(adapter.MessageSourceAdapter):
bot: aiocqhttp.CQHttp
@ -243,7 +244,6 @@ class AiocqhttpAdapter(adapter.MessageSourceAdapter):
):
async def on_message(event: aiocqhttp.Event):
self.bot_account_id = event.self_id
self.ap.im_mgr.bot_account_id = event.self_id
try:
return await callback(self.event_converter.target2yiri(event))
except:

View File

@ -1,3 +1,5 @@
from __future__ import annotations
import asyncio
import typing
import traceback
@ -10,6 +12,7 @@ import nakuru.entities.components as nkc
from .. import adapter as adapter_model
from ...pipeline.longtext.strategies import forward
from ...core import app
class NakuruProjectMessageConverter(adapter_model.MessageConverter):
@ -96,7 +99,7 @@ class NakuruProjectMessageConverter(adapter_model.MessageConverter):
yiri_msg_list.append(mirai.AtAll())
else:
pass
logging.debug("转换后的消息链: " + str(yiri_msg_list))
# logging.debug("转换后的消息链: " + str(yiri_msg_list))
chain = mirai.MessageChain(yiri_msg_list)
return chain
@ -156,6 +159,7 @@ class NakuruProjectEventConverter(adapter_model.EventConverter):
raise Exception("未支持转换的事件类型: " + str(event))
@adapter_model.adapter_class("nakuru")
class NakuruProjectAdapter(adapter_model.MessageSourceAdapter):
"""nakuru-project适配器"""
bot: nakuru.CQHTTP
@ -166,34 +170,20 @@ class NakuruProjectAdapter(adapter_model.MessageSourceAdapter):
listener_list: list[dict]
def __init__(self, cfg: dict):
ap: app.Application
cfg: dict
def __init__(self, cfg: dict, ap: app.Application):
"""初始化nakuru-project的对象"""
self.bot = nakuru.CQHTTP(**cfg)
cfg['port'] = cfg['ws_port']
del cfg['ws_port']
self.cfg = cfg
self.ap = ap
self.listener_list = []
# nakuru库有bug这个接口没法带access_token会失败
# 所以目前自行发请求
self.bot = nakuru.CQHTTP(**self.cfg)
config = context.get_config_manager().data
import requests
resp = requests.get(
url="http://{}:{}/get_login_info".format(config['nakuru_config']['host'], config['nakuru_config']['http_port']),
headers={
'Authorization': "Bearer " + config['nakuru_config']['token'] if 'token' in config['nakuru_config']else ""
},
timeout=5,
proxies=None
)
if resp.status_code == 403:
logging.error("go-cqhttp拒绝访问请检查config.py中nakuru_config的token是否与go-cqhttp设置的access-token匹配")
raise Exception("go-cqhttp拒绝访问请检查config.py中nakuru_config的token是否与go-cqhttp设置的access-token匹配")
try:
self.bot_account_id = int(resp.json()['data']['user_id'])
except Exception as e:
logging.error("获取go-cqhttp账号信息失败: {}, 请检查是否已启动go-cqhttp并配置正确".format(e))
raise Exception("获取go-cqhttp账号信息失败: {}, 请检查是否已启动go-cqhttp并配置正确".format(e))
def send_message(
async def send_message(
self,
target_type: str,
target_id: str,
@ -226,9 +216,9 @@ class NakuruProjectAdapter(adapter_model.MessageSourceAdapter):
else:
raise Exception("Unknown target type: " + target_type)
asyncio.run(task)
await task
def reply_message(
async def reply_message(
self,
message_source: mirai.MessageEvent,
message: mirai.MessageChain,
@ -242,14 +232,14 @@ class NakuruProjectAdapter(adapter_model.MessageSourceAdapter):
)
)
if type(message_source) is mirai.GroupMessage:
self.send_message(
await self.send_message(
"group",
message_source.sender.group.id,
message,
converted=True
)
elif type(message_source) is mirai.FriendMessage:
self.send_message(
await self.send_message(
"person",
message_source.sender.id,
message,
@ -270,11 +260,11 @@ class NakuruProjectAdapter(adapter_model.MessageSourceAdapter):
callback: typing.Callable[[mirai.Event], None]
):
try:
logging.debug("注册监听器: " + str(event_type) + " -> " + str(callback))
# 包装函数
async def listener_wrapper(app: nakuru.CQHTTP, source: NakuruProjectAdapter.event_converter.yiri2target(event_type)):
callback(self.event_converter.target2yiri(source))
print(1111)
await callback(self.event_converter.target2yiri(source))
# 将包装函数和原函数的对应关系存入列表
self.listener_list.append(
@ -287,7 +277,6 @@ class NakuruProjectAdapter(adapter_model.MessageSourceAdapter):
# 注册监听器
self.bot.receiver(self.event_converter.yiri2target(event_type).__name__)(listener_wrapper)
logging.debug("注册完成")
except Exception as e:
traceback.print_exc()
raise e
@ -318,10 +307,26 @@ class NakuruProjectAdapter(adapter_model.MessageSourceAdapter):
self.bot.event[nakuru_event_name] = new_event_list
def run_sync(self):
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
self.bot.run()
async def run_async(self):
try:
import requests
resp = requests.get(
url="http://{}:{}/get_login_info".format(self.cfg['host'], self.cfg['http_port']),
headers={
'Authorization': "Bearer " + self.cfg['token'] if 'token' in self.cfg else ""
},
timeout=5,
proxies=None
)
if resp.status_code == 403:
raise Exception("go-cqhttp拒绝访问请检查config.py中nakuru_config的token是否与go-cqhttp设置的access-token匹配")
self.bot_account_id = int(resp.json()['data']['user_id'])
except Exception as e:
raise Exception("获取go-cqhttp账号信息失败, 请检查是否已启动go-cqhttp并配置正确")
await self.bot._run()
self.ap.logger.info("运行 Nakuru 适配器")
while True:
await asyncio.sleep(100)
def kill(self) -> bool:
return False

View File

@ -263,6 +263,7 @@ class OfficialEventConverter(adapter_model.EventConverter):
)
@adapter_model.adapter_class("qq-botpy")
class OfficialAdapter(adapter_model.MessageSourceAdapter):
"""QQ 官方消息适配器"""
bot: botpy.Client = None
@ -298,8 +299,6 @@ class OfficialAdapter(adapter_model.MessageSourceAdapter):
self.bot = botpy.Client(intents=intents)
# TODO 获取机器人id和昵称
async def send_message(
self,
target_type: str,

View File

@ -6,14 +6,18 @@ import mirai.models.bus
from mirai.bot import MiraiRunner
from .. import adapter as adapter_model
from ...core import app
@adapter_model.adapter_class("yiri-mirai")
class YiriMiraiAdapter(adapter_model.MessageSourceAdapter):
"""YiriMirai适配器"""
bot: mirai.Mirai
def __init__(self, config: dict):
def __init__(self, config: dict, ap: app.Application):
"""初始化YiriMirai的对象"""
self.ap = ap
self.config = config
if 'adapter' not in config or \
config['adapter'] == 'WebSocketAdapter':
self.bot = mirai.Mirai(
@ -111,6 +115,7 @@ class YiriMiraiAdapter(adapter_model.MessageSourceAdapter):
bus.unsubscribe(event_type, callback)
async def run_async(self):
self.bot_account_id = self.bot.qq
return await MiraiRunner(self.bot)._run()
async def kill(self) -> bool:

View File

@ -7,6 +7,12 @@
"verifyKey": "yirimirai",
"qq": 123456789
},
"nakuru-config": {
"host": "127.0.0.1",
"ws_port": 8080,
"http_port": 5700,
"token": ""
},
"aiocqhttp-config": {
"host": "127.0.0.1",
"port": 8080

View File

@ -1,6 +1,9 @@
{
"admin-sessions": [],
"network-proxies": {},
"network-proxies": {
"http": null,
"https": null
},
"report-usage": true,
"logging-level": "info",
"session-concurrency": {