cyanray / mirai-cpp Goto Github PK
View Code? Open in Web Editor NEW本项目为 mirai-api-http 的 C++ 封装,方便使用 C++ 开发基于 mirai-api-http 插件。
License: GNU Affero General Public License v3.0
本项目为 mirai-api-http 的 C++ 封装,方便使用 C++ 开发基于 mirai-api-http 插件。
License: GNU Affero General Public License v3.0
最新的 mirai-cpp 好像是 v2
并且 v1 的代码好像无法在 v2 上使用
当不使用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
如题
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
请问有解决思路吗?
一些事件中,如群成员消息撤回事件(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,是不会有任何异常、报错出现的。(读取到的值都是没有意义的值)
暂时按照第三个解决方案进行,临时解决方案将废弃。
您好,我不熟悉使用VS,按照您的说明打开文件夹后,"Manage Configurations"处打开后是一个json文件,没有其他显示;并且右上角"使用启动项..."内也没有任何文字,Debug一栏内“Debug and Launch Settings for..."也是无法使用的状态。不知道是我哪里弄错了,希望您能给予指导,感谢。
#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-cpp在c++20下编译会报找不到 std::result_of 的错误。(来自于第三方库 ThreadPool)
根据cppreference,std::result_of在C++17被标记为deprecated,C++20中被移除。
如果是C++20环境,把 std::result_of 修改成 std::invoke_result 就可以了。
其实是代码上的一些疑问,如有打扰到十分抱歉
在WebSocketClient中,RecvLoop在执行到LostConnectionCallback时会被阻塞住,直到函数返回时再检测WebSocketClient::Status并退出(WebSocketClient.cpp)。这个时候如果LostConnectionCallback中调用类似于Connect这样的函数的话好像WebSocketClient::Status会被设置成open从而导致原RecvLoop并不会退出?
感觉应该可以在mirai_bot.cpp里把OnLostConnection改成单独分配一个线程用来执行回调函数以防止阻塞或者在WebSocketClient中把shutdown放在LostConnectionCallback后面执行?
如题,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
重载小于号后可以正常编译运行。
mirai-core 版本 2.7.0
mirai-api-http 版本:2.0.2
mirai-cpp 版本 2.0.2
目前的情况是调试跟踪在执行Connect函数时可以成功获取到sessionKey,但是在执行pmem->eventClient.Connect时的返回文本中显示了404,如果忽略这个问题也无法接收到事件响应,请问这个是我环境哪里出了问题吗?
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码
如题,有时在控制台显示发送了回复 但QQ客户端没有接收到 然后不知道怎么的又好了 过一会又不行了
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;
}
在使用httplib::Client进行POST时提示error C2079: “cli”使用未定义的 class“httplib::Client”
请问本项目是否(部分)兼容c语言?
不用在mirai-console上操作直接使用cpp函数调用通过号与密码进行登录。这种
比如发送消息(SendMessage),有时候并不在意它能不能发送成功(或者发送失败的原因),现在可以这样写:
try
{
SendMessage(xxxx, xxxxx);
}
catch(...){}
可以尝试增加类似下面的API,简化一下:
bool TrySendMessage(QQ_t friend, const MessageChain& messages) noexcept;
有些群不需要让bot相应,需要对接收的GroupMessage的群号进行判断,故希望能加个获取消息所在的群号
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;
}
支持获取群头像/QQ头像 (MiraiImage格式)
mah settings.yml:
host: 0.0.0.0
port: 12345
main.cpp:
MiraiBot bot("0.0.0.0", 12345);
为啥实际使用时一直说网络错误
平台是树莓派raspbian
当然,不简化也可以用,
等我变得勤奋了,就这么做吧!
跟着教程安装,安装到0x04 - 1.快速尝试 - (1)使用vs - 第四步:
为什么我vs里的调试是灰色的,点击不了?
上网查了下,好像是没有创建项目的原因,但cmake好像不需要创建项目?
我用文件夹打开,更改了examples设置,也重新保存了CMakeLists.txt文件生成了cmake,但还是没用?
对cmake和vs不太熟悉,求助QwQ
你好。我在成功与mirai-apt-http建立连接之后尝试注册监听事件,但是事件发生后,注册的回调函数并没有被执行。在mirai主程序处能看到事件,并且不需要监听的发送消息功能也能正常使用,请问这是怎么回事呢?
https://github.com/Slontia/lgtbot-mirai
LGTBot-Mirai:基于mirai-cpp的游戏裁判机器人,可以在聊天室中开展游戏
使用大佬的项目很久了,十分感谢🙏
我应该怎么登录qq号呢
本次测试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;
}
权限是属于GroupMember下的一个变量
但是通过GetGroupMembers这个函数只能获取除bot外的群成员
请问怎样获取bot在特定群聊内的权限
也许有什么现成的函数可以直接获取?我反正没翻到(悲),可能是我眼瞎了罢
编译方式:
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 %
MessageChain a = MessageChain().Plain("你好!").Face(14);
MessageChain b = MessageChain().Plain("早安!").Face(14);
if(a==b) // true
这里a与b相等吗?(笔误?)
MessageChain().Plain("") == MessageChain().Plain("")
结果为false(Bug?)
在MessageChain==实现部分的line88
if (messages_[i] != mc.messages_[i]) return false;
是两个指针在作比较,改成
if (*messages_[i] != *mc.messages_[i]) return false;
解决了该问题
如题
期末考试临近,暂无精力更新
mirai-cpp 目前对最新版本的mirai-api-http未做适配
如果无特别需要,建议使用 mirai-api-http v1.8.4(或以下)版本
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连接关闭。
两个 MessageChain 里各自有两种以上的 IMessage 类型。
怎么将两个 MessageChain 相接成一个 MessageChain 呢?
SessionOptions.cpp
//[51]
if (json.contains("webscoketHostname"))
{
opt.WebSocketHostname = json["webscoketHostname"].get();
}
//[90]
if (json.contains("webscoketPort"))
{
opt.WebSocketPort = json["webscoketPort"].get();
}
太难用了,而且文档也没有
关键在于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;
......
😫
理论上可以实现。
都采用首字母大写的驼峰式命名。
目前是两种命名格式混用(还有一种是纯小写+下划线)。
如题,我成功发送了一个json,但是客户端没有显示
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也在正常运行,可是依旧抛出“网络错误”的异常。保证网络没有问题。
请问是怎么回事呢?
这样设计,就可以根据mirai-api-http的版本号选择mirai-cpp,保证兼容性。
这是一个疑问,网上实在搜不到解决方案了,来这里问问,不行的话直接关闭哈。
场景:
往函数里传递Cyan::EventBase &event, Cyan::MiraiEvent type两个参数,根据type类型强制把基类转换成派生类正常使用,减少代码冗余。在自行测试中,static_cast、dynamic_cast
均提示No matching conversion for static_cast from 'Cyan::EventBase' to 'Cyan::GroupMessage'
改函数方法里,当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;
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.