Giter Club home page Giter Club logo

mirai-cpp's Introduction

mirai-cpp

Build

0x01 项目简介

mirai 是全开源 QQ 机器人 / QQ 协议支持库。(使用Kotlin编写)

mirai-api-http 提供一系列 HTTP API 以便其他语言使用 mirai。

本项目为 mirai-api-http 的 C++ 封装,方便使用 C++ 开发基于 mirai-api-http 的插件。

在使用 mirai-cpp 和基于 mirai-cpp 的插件之前,你需要配置好 mirai-console 并且安装 mirai-api-http 插件。

0x02 特性

  • C++17;
  • 内置所有依赖库;
  • 容易使用,丰富的示例;
  • 与 mirai-api-http 同步更新(使用相同版本号,保证兼容性);
  • 对 mirai-api-http 进行完全地封装(支持其所有功能、事件);

0x03 快速入门

使用 mirai-cpp 需要你熟悉 C++ 最基本的用法。

mirai-cpp 的工作依赖 mirai-api-http 的 http 适配器和 ws 适配器。mirai-cpp 通过 http 进行发送消息等操作,通过 ws 接收事件和消息。

下面的代码实现了一个最简单的”复读机“机器人,机器人账号收到任何好友私聊、群组消息或者临时消息,都会把同样的消息内容发送回去。

#include <iostream>
// 静态链接 mirai-cpp 要在引入头文件前定义这个宏
#define MIRAICPP_STATICLIB
#include <mirai.h>
using namespace std;
using namespace Cyan;
int main(int argc, char* argv[])
{
    MiraiBot bot;
    SessionOptions opts = SessionOptions::FromCommandLine(argc, argv);
    bot.Connect(opts);
    cout << "Bot working..." << endl;
    bot.On<Message>(
        [](Message m)
        {
            m.Reply(m.MessageChain);
        });
    char ch;
    while ((ch = getchar()) != 'q');
    bot.Disconnect();
}

你需要重点关注 MiraiBot 类以及它的 On<T> 函数。

MiraiBot 类提供了诸如发送消息、获取好友列表等函数,这个函数列表可以在 mirai-api-http 的文档里查到。

因为其中的函数数量比较多,而且作者精力有限,因此不提供详细的使用文档,具体如何使用请查看 MiraiBot 类的注释以及 examples 目录里的示例。

你可能想了解:

0x04 如何编译、调试 mirai-cpp

1. 快速尝试 (运行 examples、参与开发)

(1) 使用 Visual Studio

  1. 完整克隆/下载本仓库。

  2. 如图所示,使用 Visual Studio 2019/2022 直接打开这个文件夹。

使用 VS 直接打开 mirai-cpp 文件夹

  1. 如果要尝试 examples 请确保 MIRAI_CPP_BUILD_EXAMPLES 被勾上。

项目配置

勾上 MIRAI_CPP_BUILD_EXAMPLES

  1. 由于所有的 examples 都从命令行读取配置,在调试之前需要编辑一下调试命令行。

找到设置调试配置的菜单

  1. 根据你的 mirai-api-http 设置,填入以下配置。
"args": [
  "--hostname=localhost",
  "--port=8080",
  "--bot-qq=123456789",
  "--verify-key=VerifyKey"
]

编辑调试命令行

  1. 如果一切顺利,你可以直接运行我写好的示例,或者进行修改编写自己的机器人。

开始运行 examples

2. 创建自己的机器人项目

(1) 使用 CMake Project 模板

具体参考 mirai-cpp-template 的说明。

3. 其他使用方式

(1) 将程序移植、部署到 Linux 上

(以下内容基于 “快速尝试”,请先完成“快速尝试”。)

上面的内容介绍了如何在 Windows 上开发使用 mirai-cpp 的程序,下面来介绍如何将你的程序移植到 Linux 平台,以便将程序部署到 Linux 服务器上。

为了易于讲解与操作,以下内容在 WSL (Windows Subsystem for Linux) 上进行。这里不对如何安装 WSL 进行说明,关于如何安装 WSL 还请自行查阅资料。

打开在 “快速尝试” 中用到的项目。按照如图所示步骤,创建一个针对 WSL 平台的配置。因为我的 WSL 安装了 GCC 编译器,所以这里选择 WSL-GCC-Releas

创建WSL-GCC平台配置1

创建WSL-GCC平台配置2

如果一切顺利,等待 CMake 缓存生成成功后,即可编译出 Linux 平台的可执行文件。

(2) 使用 vcpkg 安装 mirai-cpp

不推荐,因精力有限 vcpkg 的更新可能不及时

要使用 vcpkg 管理 mirai-cpp,你需要将 https://github.com/cyanray/mirai-cpp-vcpkg-port 中的 mirai-cpp 文件夹复制到 vcpkg 安装目录下的 ports 文件夹中。

然后就可以使用 ./vcpkg install mirai-cpp:x86-windows mirai-cpp:x64-windows 安装 mirai-cpp。

0x05 项目依赖

本项目所有依赖都为 Header-Only 库,已经内置到本项目的 mirai/third-party 文件夹中。

  1. yhirose/cpp-httplib A C++ header-only HTTP/HTTPS server and client library.

  2. nlohmann/json JSON for Modern C++.

  3. progschj/ThreadPool A simple C++11 Thread Pool implementation.

  4. cyanray/LightWebSocketClient A simple cross-platform WebSocket client.

  5. Neargye/magic_enum Static reflection for enums (to string, from string, iteration) for modern C++, work with any enum type without any macro or boilerplate code.

0x06 参与开发

mirai-cpp 目前还有许多不足,欢迎提出 issues 或 pull requests。

0x07 以下项目正在使用 mirai-cpp

如果你愿意分享你开发的程序,欢迎提出 issues 或 pull requests 在下方分享你的程序

  1. MocliaParseBot: 基于Mirai-Api-Http和Mirai-cpp的全平台网络服务群QQ解析项目
  2. LGTBot-Mirai: 基于mirai-cpp的游戏裁判机器人,可以在聊天室中开展游戏
  3. MisakaBot: A QQ Bot based on mirai-cpp.

mirai-cpp's People

Contributors

cyanray avatar int-0x7fffffff avatar konjacq avatar misaka-20002 avatar numendacil avatar staswit avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

mirai-cpp's Issues

支持C++20

mirai-cpp在c++20下编译会报找不到 std::result_of 的错误。(来自于第三方库 ThreadPool)
根据cppreferencestd::result_of在C++17被标记为deprecated,C++20中被移除。

如果是C++20环境,把 std::result_of 修改成 std::invoke_result 就可以了。

mac版本编译失败

编译方式:
cmake ./ && make
平台:
macOS bigsur
日志
zmdyy0318@zmdyy0318deAir git % git clone https://github.com/cyanray/mirai-cpp.git
Cloning into 'mirai-cpp'...
remote: Enumerating objects: 277, done.
remote: Counting objects: 100% (277/277), done.
remote: Compressing objects: 100% (154/154), done.
remote: Total 2157 (delta 175), reused 198 (delta 120), pack-reused 1880
Receiving objects: 100% (2157/2157), 3.17 MiB | 1.47 MiB/s, done.
Resolving deltas: 100% (1523/1523), done.
zmdyy0318@zmdyy0318deAir git % cd mirai-cpp
zmdyy0318@zmdyy0318deAir mirai-cpp % mkdir build
zmdyy0318@zmdyy0318deAir mirai-cpp % cd build
zmdyy0318@zmdyy0318deAir build % cmake ../
-- The C compiler identification is AppleClang 12.0.0.12000032
-- The CXX compiler identification is AppleClang 12.0.0.12000032
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/zmdyy0318/git/mirai-cpp/build
zmdyy0318@zmdyy0318deAir build % make
Scanning dependencies of target mirai-cpp
[ 25%] Building CXX object CMakeFiles/mirai-cpp.dir/src/event_func.cpp.o
In file included from /Users/zmdyy0318/git/mirai-cpp/src/event_func.cpp:1:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/exception:81:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/cstdlib:85:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/stdlib.h:100:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/math.h:311:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/type_traits:1547:38: error:
implicit instantiation of undefined template
'std::__1::hashCyan::MiraiEvent'
: public integral_constant<bool, __is_empty(_Tp)> {};
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/unordered_map:425:18: note:
in instantiation of template class
'std::__1::is_empty<std::__1::hashCyan::MiraiEvent >' requested here
bool = is_empty<_Hash>::value && !__libcpp_is_final<_Hash>::value>
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/unordered_map:1760:13: note:
in instantiation of default argument for
'__unordered_map_hasher<Cyan::MiraiEvent,
std::__1::__hash_value_type<Cyan::MiraiEvent,
std::__1::function<std::__1::shared_ptrCyan::EventBase
(std::__1::shared_ptrCyan::EventBase)> >,
std::__1::hashCyan::MiraiEvent >' required here
typedef __unordered_map_hasher<key_type, __value_type, hasher> __hasher;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Users/zmdyy0318/git/mirai-cpp/include/mirai/mirai_bot.hpp:392:71: note: in
instantiation of template class
'std::__1::unordered_multimap<Cyan::MiraiEvent,
std::__1::function<std::__1::shared_ptrCyan::EventBase
(std::__1::shared_ptrCyan::EventBase)>,
std::__1::hashCyan::MiraiEvent, std::__1::equal_toCyan::MiraiEvent,
std::__1::allocator<std::__1::pair<const Cyan::MiraiEvent,
std::__1::function<std::__1::shared_ptrCyan::EventBase
(std::__1::shared_ptrCyan::EventBase)> > > >' requested here
...std::unordered_multimap<MiraiEvent, function<WeakEvent(WeakEvent)>> proc...
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/type_traits:428:50: note:
template is declared here
template struct _LIBCPP_TEMPLATE_VIS hash;
^
1 error generated.
make[2]: *** [CMakeFiles/mirai-cpp.dir/src/event_func.cpp.o] Error 1
make[1]: *** [CMakeFiles/mirai-cpp.dir/all] Error 2
make: *** [all] Error 2
zmdyy0318@zmdyy0318deAir build %

更新cpp-httplib以保证线程安全

项目里所用的httplib.h版本存在线程安全问题(不同线程同时调用send()会导致socket创建出现问题,见 #492),而原仓库在commit e022b8b给send函数加了锁,从而避免了这一问题(见 #679

(不过在多个线程里共用一个HttpClient感觉是不是也不太好?我觉得可能更好的方式是在程序调用SendMessage时不直接发送请求而是先把请求push到一个消息队列里,然后再MiraiBot单独开一个线程专门负责消息队列的处理。这样其实也就不用关心第三方库是否实现了thread-safety了

GetGroupMemberInfo未处理查找失败返回

改函数方法里,当http回复
"{"code":5,"msg":"指定对象不存在"}"
时,未捕获code值,直接使用json获取name
该函数代码如下
GroupMemberInfo MiraiBot::GetGroupMemberInfo(GID_t gid, QQ_t memberId)
{

stringstream api_url;
api_url
	<< "/memberInfo?sessionKey="
	<< sessionKey_
	<< "&target="
	<< int64_t(gid)
	<< "&memberId="
<< int64_t(memberId);
	auto res = http_client_.Get(api_url.str().data());
if (!res)
	throw std::runtime_error("网络错误");
if (res->status != 200)
	throw std::runtime_error("[mirai-api-http error]: " + res->body);
json re_json = json::parse(res->body);
GroupMemberInfo result;
result.Set(re_json);
return result;

}

新增一系列无异常的 Try* 模式的接口

比如发送消息(SendMessage),有时候并不在意它能不能发送成功(或者发送失败的原因),现在可以这样写:

try
{
    SendMessage(xxxx, xxxxx);
}
catch(...){}

可以尝试增加类似下面的API,简化一下:

bool TrySendMessage(QQ_t friend, const MessageChain& messages) noexcept;

Cyan::UID_t未重载"<"导致编译失败

如题,linux gcc9.3.0下:

[build] /usr/include/c++/9/bits/stl_function.h:386:20: error: no match for ‘operator<’ (operand types are ‘const Cyan::GID_t’ and ‘const Cyan::GID_t’)
[build]   386 |       { return __x < __y; }
[build]       |                ~~~~^~~~~

MSVC16.7.5下出现类似问题。
mirai-cpp/include/mirai/defs/qq_types.hpp中对Cyan::UID_t重载小于号后可以正常编译运行。

安装问题,cmake相关

跟着教程安装,安装到0x04 - 1.快速尝试 - (1)使用vs - 第四步:
为什么我vs里的调试是灰色的,点击不了?
上网查了下,好像是没有创建项目的原因,但cmake好像不需要创建项目?
我用文件夹打开,更改了examples设置,也重新保存了CMakeLists.txt文件生成了cmake,但还是没用?
对cmake和vs不太熟悉,求助QwQ

WebScoket模式下掉线无法重连

mirai-api-http 版本:1.9.6
mirai-cpp 版本:1.9.6

重启mirai-console后,mirai-cpp无法自动重连,提示 Connection closed!

在mirai-api-http v1.8.3 版本下正常。

原因:新版本的 mirai-api-http 发现SessionKey不存在或过期,会顺便把Websocket连接关闭。

Connect 失败

mirai-core 版本 2.7.0
mirai-api-http 版本:2.0.2
mirai-cpp 版本 2.0.2
目前的情况是调试跟踪在执行Connect函数时可以成功获取到sessionKey,但是在执行pmem->eventClient.Connect时的返回文本中显示了404,如果忽略这个问题也无法接收到事件响应,请问这个是我环境哪里出了问题吗?

链接ssl和crypto库并#define CPPHTTPLIB_OPENSSL_SUPPORT后,Auth函数报错std :: alloc

#ifndef CPPHTTPLIB_OPENSSL_SUPPORT
#define CPPHTTPLIB_OPENSSL_SUPPORT
#endif
....
	while (true) {
		try {
			std :: cout << "[INFO] Authorizing..." << std :: endl;
			bot.Auth("zql740125", 3466211762_qq);
			break;
		} catch (const std :: exception& ex) {
			std :: cout << "[ERROR] An error occured when authorizing the robot: " << ex.what() << std :: endl;
		}
		MiraiBot :: SleepSeconds(1);
		std :: cout << "[INFO] Re-authorizing..." << std :: endl;
	}

mirai-api-http注册成功,但是执行失败

mirai-cpp,mirai-http-api为2.0.2
注册命令成功,执行失败。
代码用的是examples/Command.cpp
这里我打印出了content和data.dump
输出。
Active code page: 65001
Bot working...
{"alias":["hi"],"description":"指令描述描述描述","name":"hello","sessionKey":"QLVadWkQ","usage":"/hello 你想说的话"}
application/json;charset=UTF-8
{"command":[{"text":"hello","type":"Plain"},{"text":"arg1","type":"Plain"},{"text":"arg2","type":"Plain"}],"sessionKey":"QLVadWkQ"}
application/json;charset=UTF-8
mirai-api-http 错误: Execute command error
错误码400,错误文本见mirai-api-http/mirai-api-http/src/main/kotlin/net/mamoe/mirai/api/http/adapter/internal/action/command.kt
请问有解决思路吗?

关于MessageChain == 比较的问题 [Bug?]

1

文档MessageChain部分中有

MessageChain a = MessageChain().Plain("你好!").Face(14);
MessageChain b = MessageChain().Plain("早安!").Face(14);
if(a==b) // true

这里a与b相等吗?(笔误?)

2

MessageChain().Plain("") == MessageChain().Plain("")

结果为false(Bug?)
MessageChain==实现部分的line88

if (messages_[i] != mc.messages_[i]) return false;

是两个指针在作比较,改成

if (*messages_[i] != *mc.messages_[i]) return false;

解决了该问题

拆分含有 Operator 且 Operator 可能为 Bot 的事件

背景

一些事件中,如群成员消息撤回事件(GroupRecallEvent),Operator 被定义为 GroupMember_t 类型的属性,表示引起该事件的操作者。
mirai-http 返回的这个事件的json,这个 Operator 可能为 null,表示 Operator 为 bot 自己。
然而,mirai-cpp最初为了简洁的设计,所有的事件类都没有用 getter/setter 编程样式,采用了直接暴露类成员的方式。(当事人表示非常后悔)
所以,现在的 mirai-cpp 无法处理 Operator 为 null 时的情况。

临时的解决方案

对于所有含有 Operator 且 Operator 可能为null的事件,都提供了一个 OperatorIsBot 的函数。读取 Operator 前,应该调用该函数,做一次判断,如果该函数返回 true,则不应该读取该事件的 Operator 成员。

临时解决方案存在的问题

如果忘了做判断,当 Operator 为null时直接读取 Operator,是不会有任何异常、报错出现的。(读取到的值都是没有意义的值)

其他的解决方案

  1. mirai-http 的 Operator 为 null 时,将 Operator 设置为 bot 的信息。(无法实现,当前无法根据 QQ_t 获取 GroupMember_t)
  2. 将编程样式改为 getter/setter 的编程样式(需要修改的地方太多了,影响太大)
  3. 将事件一分为二,如 GroupRecallEvent 可以拆分为 GroupRecallEvent 和 BotGroupRecallEvent 两个事件。而BotGroupRecallEvent 中不包含 Operator 属性。(需要修改事件系统)

未来的计划

暂时按照第三个解决方案进行,临时解决方案将废弃。

mirai-cpp v2.0

期末考试临近,暂无精力更新

mirai-cpp 目前对最新版本的mirai-api-http未做适配
如果无特别需要,建议使用 mirai-api-http v1.8.4(或以下)版本

使用Auth函数时抛出“网络错误”异常

	while (true)
	{
		try
		{
			bot.Auth("zql740125", 3466211762_qq);
			break;
		}
		catch (const std::exception& ex)
		{
			cout << ex.what() << endl;
		}
		MiraiBot::SleepSeconds(1);
	}

保证Authkey是正确的,QQ号也是正确的,mirai-console也在正常运行,可是依旧抛出“网络错误”的异常。保证网络没有问题。

请问是怎么回事呢?

提问:如何获取bot在群聊内的权限

权限是属于GroupMember下的一个变量
但是通过GetGroupMembers这个函数只能获取除bot外的群成员
请问怎样获取bot在特定群聊内的权限

也许有什么现成的函数可以直接获取?我反正没翻到(悲),可能是我眼瞎了罢

问题:Cyan::EventBase基类能否向例如Cyan::GroupMessage强制转换

这是一个疑问,网上实在搜不到解决方案了,来这里问问,不行的话直接关闭哈。
场景:
往函数里传递Cyan::EventBase &event, Cyan::MiraiEvent type两个参数,根据type类型强制把基类转换成派生类正常使用,减少代码冗余。在自行测试中,static_cast、dynamic_cast
均提示No matching conversion for static_cast from 'Cyan::EventBase' to 'Cyan::GroupMessage'

调试模式下接收图片会弹出错误,并使程序结束运行

本次测试mirai-cpp程序时,当mirai-api-http传递图片json消息时,由于缺少path,导致json解析报错,临时解决方法如下:

files:mirai-cpp/include/mirai/defs/messages/ImageMessage.hpp

替换:

virtual bool Set(const json& json) override
		{
			if (json["type"].is_null() || json["type"].get<string>() != this->GetType())
				throw std::runtime_error("给定的json不正确");
			if (!json["imageId"].is_null()) 
				imageId_ = json["imageId"].get<string>();
			if (!json["url"].is_null())
				url_ = json["url"].get<string>();
			if (!json["path"].is_null())
				path_ = json["path"].get<string>();
			return true;
		}

为:

virtual bool Set(const json& json) override
		{
			if (json["type"].is_null() || json["type"].get<string>() != this->GetType())
				throw std::runtime_error("给定的json不正确");
			if (!json["imageId"].is_null()) 
				imageId_ = json["imageId"].get<string>();
			if (!json["url"].is_null())
				url_ = json["url"].get<string>();
			else if (!json["path"].is_null())
				path_ = json["path"].get<string>();
			return true;
		}

websocket 连接正常,但是无法触发事件处理函数

你好。我在成功与mirai-apt-http建立连接之后尝试注册监听事件,但是事件发生后,注册的回调函数并没有被执行。在mirai主程序处能看到事件,并且不需要监听的发送消息功能也能正常使用,请问这是怎么回事呢?

Is there any reason change the return type of AtMe from book to void?

My code is using AtMe to check whether the bot is at by other qq users. But when I updated the mirai-cpp code to the latest version, my code compiled failed because the return type has been changed to void.

How can I achieve the above propose with the latest code?

        void GroupMessage::AtMe() const
	{
		auto at = MessageChain.GetAll<AtMessage>();
		auto it = std::find_if(at.begin(), at.end(), [&](AtMessage a) {return a.Target() == bot_->GetBotQQ(); });
		if (it != at.end()) return;
		else return;
	}

最新版本代码CPU占用率高

背景:最近自己编写的机器人,运行若干分钟后,消息回复延迟十分严重,可能要几小时才能收到回答

分支:master
commit hash:6051ea2b65f93

跑的是mirai-cpp-template的示例程序

top命令看到的情况(CentOS8,单核,2GB内存):
image

perf命令看到的结果:
image

统一源文件命名格式

都采用首字母大写的驼峰式命名。
目前是两种命名格式混用(还有一种是纯小写+下划线)。

不支持接收引用消息

inline MiraiEvent MiraiEventStr(const std::string& miraiEvent)
函数中,不支持type=Quote的引用消息,导致会输出在控制台
消息接收json:
{"groupId":XXXXXXXXX,"id":XXXX,"origin":[{"id":XXXX,"time":1609736372,"type":"Source"},{"text":"[动画表情]","type":"Plain"}],"senderId":XXXX,"targetId":XXXXXXXXX,"type":"Quote"}

事件处理循环不合理,导致事件不及时处理

关键在于mirai_bot.cpp的第950行

cv.wait(lock);     // 在这之前,应该检查 event_queue 是否为空

因为在处理事件时,event_queue 可能会被其他线程修改,此时 event_queue 不为空,应该继续往下走,而不是 wait 新的事件。如果直接 cv.wait,就只能等下一次 event_queue 被修改时,才会从 cv.wait 中返回。

修改后的代码:

......
unique_lock<mutex> lock(mutex_event_queue);
+if (event_queue.empty())
+{
    cv.wait(lock);
+}
if (event_queue.empty()) continue;
......

😫

发送语音消息时VoiceMessage::length_未初始化导致mirai-api-http可能返回400

当不使用UploadVoice而是直接填入Url/Path/Id属性发送语音时,由于length_变量未设置初始值将随机取值。虽然mirai-api-http那边的文档说不看length属性,但好像有概率length的上限超过了那边能接收的最大值从而返回 {"code": 400, “msg": "无效参数"}

验证方式:查看发送失败的请求内容为
{
"sessionKey": "xxxx"
"target": "xxxx"
"messageChain": [{
"base64": ""
"length": 16582373882432544079
"path": "path/to/amr"
"type": "Voice"
"url": ""
"voiceId": ""
}]
}
此时mirai-api-http返回{"code":400, "msg":"无效参数"}
把length属性改为较小值,例如
{
"sessionKey": "xxxx"
"target": "xxxx"
"messageChain": [{
"base64": ""
"length": 100
"path": "path/to/amr"
"type": "Voice"
"url": ""
"voiceId": ""
}]
}
则可以成功发送,返回{"code":0,"msg":"success","messageId":402}

mirai版本: 2.8.0-M1
mirai-http-api版本: 2.3.1

有时QQ客户端收不到消息

如题,有时在控制台显示发送了回复 但QQ客户端没有接收到 然后不知道怎么的又好了 过一会又不行了

拼写错误,解析json失败

SessionOptions.cpp
//[51]
if (json.contains("webscoketHostname"))
{
opt.WebSocketHostname = json["webscoketHostname"].get();
}
//[90]
if (json.contains("webscoketPort"))
{
opt.WebSocketPort = json["webscoketPort"].get();
}

使用上的问题

您好,我不熟悉使用VS,按照您的说明打开文件夹后,"Manage Configurations"处打开后是一个json文件,没有其他显示;并且右上角"使用启动项..."内也没有任何文字,Debug一栏内“Debug and Launch Settings for..."也是无法使用的状态。不知道是我哪里弄错了,希望您能给予指导,感谢。

提问

mah settings.yml:
host: 0.0.0.0
port: 12345
main.cpp:
MiraiBot bot("0.0.0.0", 12345);
为啥实际使用时一直说网络错误
平台是树莓派raspbian

有关LostConnectionCallback的一些问题

其实是代码上的一些疑问,如有打扰到十分抱歉

在WebSocketClient中,RecvLoop在执行到LostConnectionCallback时会被阻塞住,直到函数返回时再检测WebSocketClient::Status并退出(WebSocketClient.cpp)。这个时候如果LostConnectionCallback中调用类似于Connect这样的函数的话好像WebSocketClient::Status会被设置成open从而导致原RecvLoop并不会退出?

感觉应该可以在mirai_bot.cpp里把OnLostConnection改成单独分配一个线程用来执行回调函数以防止阻塞或者在WebSocketClient中把shutdown放在LostConnectionCallback后面执行?

Group_t 对象 json解析不对称

virtual bool Set(const json& j) override
{
GID = GID_t(j["id"].get<int64_t>());
Name = j["name"].get();
Permission = GroupPermissionStr(j["permission"].get());
return true;
}
virtual json ToJson() const override
{
json j = json::object();
j["id"] = int64_t(GID);
j["nickname"] = Name;
j["remark"] = GroupPermissionStr(Permission);
return j;
}

正确应为

virtual bool Set(const json& j) override
{
GID = GID_t(j["id"].get<int64_t>());
Name = j["name"].get();
Permission = GroupPermissionStr(j["permission"].get());
return true;
}
virtual json ToJson() const override
{
json j = json::object();
j["id"] = int64_t(GID);
j["name"] = Name;
j["permission"] = GroupPermissionStr(Permission);
return j;
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.