From 7ba50a27dcf0afb5ac32c22705672ab3f9b5bb08 Mon Sep 17 00:00:00 2001 From: cyanray Date: Fri, 15 May 2020 10:56:11 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=90=8C=E4=B8=80?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6=E7=BB=91=E5=AE=9A=E5=A4=9A=E4=B8=AA=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E5=A4=84=E7=90=86=E5=87=BD=E6=95=B0;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/RepeatMessage.cpp | 16 +++++++++++----- include/mirai_bot.hpp | 3 +-- src/mirai_bot.cpp | 6 +++--- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/examples/RepeatMessage.cpp b/examples/RepeatMessage.cpp index 106f32e..2b4199f 100644 --- a/examples/RepeatMessage.cpp +++ b/examples/RepeatMessage.cpp @@ -51,19 +51,25 @@ system("chcp 65001"); cout << "Bot Working..." << endl; // 监听各类事件 - bot.OnEventReceived( + bot.On( [&](GroupMessage m) { m.QuoteReply(m.MessageChain); }); - - bot.OnEventReceived( + // 可以多次监听同一事件,不保证执行顺序 + bot.On( + [&](GroupMessage m) + { + m.Reply("2222 " + m.MessageChain); + }); + + bot.On( [&](FriendMessage m) { m.Reply("你好呀, " + m.MessageChain); }); - bot.OnEventReceived( + bot.On( [&](TempMessage m) { m.Reply(m.MessageChain); @@ -73,7 +79,7 @@ system("chcp 65001"); // 记录轮询事件时的错误 bot.EventLoop([](const char* errMsg) { - cout << "轮询事件时出错: " << errMsg << endl; + cout << "获取事件时出错: " << errMsg << endl; }); return 0; diff --git a/include/mirai_bot.hpp b/include/mirai_bot.hpp index 0272842..b9c8abf 100644 --- a/include/mirai_bot.hpp +++ b/include/mirai_bot.hpp @@ -20,7 +20,6 @@ using std::string; using std::vector; using std::function; using nlohmann::json; -using std::unordered_map; // fu*k windows.h #ifdef max @@ -337,7 +336,7 @@ namespace Cyan bool ws_enabled_; httplib::Client http_client_; ThreadPool pool_; - unordered_map> processors_; + std::unordered_multimap> processors_; }; template diff --git a/src/mirai_bot.cpp b/src/mirai_bot.cpp index 339e4f7..94cccff 100644 --- a/src/mirai_bot.cpp +++ b/src/mirai_bot.cpp @@ -827,10 +827,10 @@ namespace Cyan string event_name = ele["type"].get(); MiraiEvent mirai_event = MiraiEventStr(event_name); // 寻找能处理事件的 Processor - auto pit = processors_.find(mirai_event); - if (pit != processors_.end()) + auto range = processors_.equal_range(mirai_event); + for (auto it = range.first; it != range.second; ++it) { - auto executor = pit->second; + auto executor = it->second; // 给 executor 传入 nullptr 可以创建一个 WeakEvent WeakEvent pevent = executor(nullptr); pevent->SetMiraiBot(this); From 7bfbcf16e50b753f99d8b42130a4da5c92e26f17 Mon Sep 17 00:00:00 2001 From: cyanray Date: Fri, 15 May 2020 10:56:45 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=A4=BA=E4=BE=8B?= =?UTF-8?q?=E6=B3=A8=E9=87=8A;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/RepeatMessage.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/RepeatMessage.cpp b/examples/RepeatMessage.cpp index 2b4199f..c2dd4ad 100644 --- a/examples/RepeatMessage.cpp +++ b/examples/RepeatMessage.cpp @@ -56,7 +56,7 @@ system("chcp 65001"); { m.QuoteReply(m.MessageChain); }); - // 可以多次监听同一事件,不保证执行顺序 + // 可以多次监听同一事件,每个处理函数都会被执行,但是不保证执行顺序 bot.On( [&](GroupMessage m) { From 44fc00b00b3a4284fdf900df19422deb6d1ead6e Mon Sep 17 00:00:00 2001 From: cyanray Date: Fri, 15 May 2020 14:31:07 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E9=87=8D=E5=91=BD=E5=90=8Devents=5Fname.hp?= =?UTF-8?q?p=20-->=20mirai=5Fevent.hpp;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/events/event_interface.hpp | 2 +- include/events/event_processer.hpp | 1 - include/events/events.hpp | 2 +- include/events/{events_name.hpp => mirai_event.hpp} | 7 ++++--- 4 files changed, 6 insertions(+), 6 deletions(-) rename include/events/{events_name.hpp => mirai_event.hpp} (96%) diff --git a/include/events/event_interface.hpp b/include/events/event_interface.hpp index b8c5124..9b413dd 100644 --- a/include/events/event_interface.hpp +++ b/include/events/event_interface.hpp @@ -1,7 +1,7 @@ #pragma once #ifndef mirai_cpp_events_event_interface_hpp_H_ #define mirai_cpp_events_event_interface_hpp_H_ -#include "events_name.hpp" +#include "mirai_event.hpp" #include "defs/serializable.hpp" #include "defs/qq_types.hpp" namespace Cyan diff --git a/include/events/event_processer.hpp b/include/events/event_processer.hpp index daf3df0..3421931 100644 --- a/include/events/event_processer.hpp +++ b/include/events/event_processer.hpp @@ -4,7 +4,6 @@ #include #include -#include "event_interface.hpp" namespace Cyan { diff --git a/include/events/events.hpp b/include/events/events.hpp index 5ed204a..dfc7149 100644 --- a/include/events/events.hpp +++ b/include/events/events.hpp @@ -31,7 +31,7 @@ #include "group_name_change.hpp" // 一些定义 #include "event_processer.hpp" -#include "events_name.hpp" +#include "mirai_event.hpp" #include "event_interface.hpp" #endif // !mirai_cpp_events_events_hpp_H_ diff --git a/include/events/events_name.hpp b/include/events/mirai_event.hpp similarity index 96% rename from include/events/events_name.hpp rename to include/events/mirai_event.hpp index 078ab70..dffecc2 100644 --- a/include/events/events_name.hpp +++ b/include/events/mirai_event.hpp @@ -1,6 +1,7 @@ #pragma once #ifndef mirai_cpp_events_events_name_hpp_H_ #define mirai_cpp_events_events_name_hpp_H_ +#include namespace Cyan { @@ -35,7 +36,7 @@ namespace Cyan BotLeaveEventKick, // Bot 被剔出群 }; - inline MiraiEvent MiraiEventStr(const string& miraiEvent) + inline MiraiEvent MiraiEventStr(const std::string& miraiEvent) { if (miraiEvent == "FriendMessage") return MiraiEvent::FriendMessage; if (miraiEvent == "GroupMessage") return MiraiEvent::GroupMessage; @@ -63,9 +64,9 @@ namespace Cyan return MiraiEvent::Default; } - inline string MiraiEventStr(MiraiEvent miraiEvent) + inline std::string MiraiEventStr(MiraiEvent miraiEvent) { - string result; + std::string result; switch (miraiEvent) { case Cyan::MiraiEvent::FriendMessage: From 938bb224fb70e44202f9a0598e3c977f2409950a Mon Sep 17 00:00:00 2001 From: cyanray Date: Fri, 15 May 2020 15:12:34 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E9=80=9A=E7=94=A8?= =?UTF-8?q?=E6=B6=88=E6=81=AF=E4=BA=8B=E4=BB=B6=20Message=20(message=5Feve?= =?UTF-8?q?nt.hpp);?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/RepeatMessage.cpp | 17 +++++ include/events/events.hpp | 1 + include/events/message_event.hpp | 117 +++++++++++++++++++++++++++++++ include/events/mirai_event.hpp | 1 + include/mirai_bot.hpp | 36 +++++----- src/event_func.cpp | 22 ++++++ 6 files changed, 176 insertions(+), 18 deletions(-) create mode 100644 include/events/message_event.hpp diff --git a/examples/RepeatMessage.cpp b/examples/RepeatMessage.cpp index c2dd4ad..2176455 100644 --- a/examples/RepeatMessage.cpp +++ b/examples/RepeatMessage.cpp @@ -75,6 +75,23 @@ system("chcp 65001"); m.Reply(m.MessageChain); }); + // 通用型消息 + // 收到 FriendMessage、GroupMessage、TempMessage 时都会调用它 + // 判断类型之后,也可调用对应的转换函数进行转换 (类型不正确将转换失败抛出异常) + bot.On( + [&](Message m) + { + m.Reply("Message事件可处理三种消息:" + m.MessageChain); + + // 判断是否群组消息 + if(m.GetMessageType() == MessageType::GroupMessage) + { + GroupMessage gm = m.ToGroupMessage(); + // TODO: 针对群组消息的特别处理 + } + + }); + // 记录轮询事件时的错误 bot.EventLoop([](const char* errMsg) diff --git a/include/events/events.hpp b/include/events/events.hpp index dfc7149..d21987f 100644 --- a/include/events/events.hpp +++ b/include/events/events.hpp @@ -3,6 +3,7 @@ #define mirai_cpp_events_events_hpp_H_ // 消息事件 +#include "message_event.hpp" #include "friend_message.hpp" #include "group_message.hpp" #include "temp_message.hpp" diff --git a/include/events/message_event.hpp b/include/events/message_event.hpp new file mode 100644 index 0000000..ad96fb7 --- /dev/null +++ b/include/events/message_event.hpp @@ -0,0 +1,117 @@ +#pragma once +#ifndef mirai_cpp_events_message_hpp_H_ +#define mirai_cpp_events_message_hpp_H_ + +#include +#include "defs/qq_types.hpp" +#include "friend_message.hpp" +#include "group_message.hpp" +#include "temp_message.hpp" +#include "event_interface.hpp" +#include "exported.h" + +namespace Cyan +{ + + enum class MessageType + { + FriendMessage, // Ϣ + GroupMessage, // ȺϢ + TempMessage // ʱϢ + }; + + // ͨϢ¼ (תΪ FriendMessage GroupMessage TempMessage) + class EXPORTED Message : public EventBase + { + public: + Cyan::MessageChain MessageChain; + + static MiraiEvent GetMiraiEvent() + { + return MiraiEvent::Message; + } + + MessageType GetMessageType() const + { + return messageType_; + } + + FriendMessage ToFriendMessage() const + { + FriendMessage m; + m.Set(this->ToJson()); + return m; + } + + GroupMessage ToGroupMessage() const + { + GroupMessage m; + m.Set(this->ToJson()); + return m; + } + + TempMessage ToTempMessage() const + { + TempMessage m; + m.Set(this->ToJson()); + return m; + } + + MessageId GetMessageId() const + { + return (this->MessageChain).GetMessageId(); + } + + int64_t GetTimestamp() const + { + return (this->MessageChain).GetTimestamp(); + } + + virtual void SetMiraiBot(MiraiBot* bot) override + { + this->bot_ = bot; + } + + MessageId Reply(const Cyan::MessageChain& mc) const; + MessageId QuoteReply(const Cyan::MessageChain& mc) const; + + virtual bool Set(const json& j) override + { + if (j["type"] == "FriendMessage") + { + messageType_ = MessageType::FriendMessage; + friendMessage_.Set(j); + } + if (j["type"] == "GroupMessage") + { + messageType_ = MessageType::GroupMessage; + groupMessage_.Set(j); + } + if (j["type"] == "TempMessage") + { + messageType_ = MessageType::TempMessage; + tempMessage_.Set(j); + } + this->MessageChain.Set(j["messageChain"]); + return true; + } + virtual json ToJson() const override + { + switch (messageType_) + { + case MessageType::FriendMessage: return friendMessage_.ToJson(); + case MessageType::GroupMessage: return groupMessage_.ToJson(); + case MessageType::TempMessage: return tempMessage_.ToJson(); + default: throw std::runtime_error(" MessageType ."); + } + } + private: + MiraiBot* bot_; + MessageType messageType_; + FriendMessage friendMessage_; + GroupMessage groupMessage_; + TempMessage tempMessage_; + }; +} + +#endif // !mirai_cpp_events_message_hpp_H_ \ No newline at end of file diff --git a/include/events/mirai_event.hpp b/include/events/mirai_event.hpp index dffecc2..bda2c4e 100644 --- a/include/events/mirai_event.hpp +++ b/include/events/mirai_event.hpp @@ -34,6 +34,7 @@ namespace Cyan MemberJoinRequestEvent, // 用户入群申请 BotLeaveEventActive, // Bot 主动离开群 BotLeaveEventKick, // Bot 被剔出群 + Message // 通用消息事件 }; inline MiraiEvent MiraiEventStr(const std::string& miraiEvent) diff --git a/include/mirai_bot.hpp b/include/mirai_bot.hpp index b9c8abf..155b8b9 100644 --- a/include/mirai_bot.hpp +++ b/include/mirai_bot.hpp @@ -342,25 +342,25 @@ namespace Cyan template MiraiBot& MiraiBot::OnEventReceived(const EventProcessor& ep) { - processors_.insert({ - T::GetMiraiEvent(), - [=](WeakEvent we) + auto func = [=](WeakEvent we) + { + // 这个lambda函数有两个作用 + // 1.创建类型为T的WeakEvent + // 2.将传入的WeakEvent转化为类型T + // 然后给 EventProcessor 使用 + if (we == nullptr) + { + std::shared_ptr e = std::make_shared(); + return std::dynamic_pointer_cast(e); + } + else { - // 这个lambda函数有两个作用 - // 1.创建类型为T的WeakEvent - // 2.将传入的WeakEvent转化为类型T - // 然后给 EventProcessor 使用 - if (we == nullptr) - { - std::shared_ptr e = std::make_shared(); - return std::dynamic_pointer_cast(e); - } - else - { - ep(*(std::dynamic_pointer_cast(we))); - return we; - } - } }); + ep(*(std::dynamic_pointer_cast(we))); + return we; + } + }; + + processors_.insert({T::GetMiraiEvent(), func }); return *this; } diff --git a/src/event_func.cpp b/src/event_func.cpp index ccfe8ab..fad3d94 100644 --- a/src/event_func.cpp +++ b/src/event_func.cpp @@ -94,4 +94,26 @@ namespace Cyan return true; } + MessageId Message::Reply(const Cyan::MessageChain& mc) const + { + switch (messageType_) + { + case MessageType::FriendMessage: return friendMessage_.Reply(mc); + case MessageType::GroupMessage: return groupMessage_.Reply(mc); + case MessageType::TempMessage: return tempMessage_.Reply(mc); + default: throw std::runtime_error("错误的 MessageType ."); + } + } + + MessageId Message::QuoteReply(const Cyan::MessageChain& mc) const + { + switch (messageType_) + { + case MessageType::FriendMessage: return friendMessage_.QuoteReply(mc); + case MessageType::GroupMessage: return groupMessage_.QuoteReply(mc); + case MessageType::TempMessage: return tempMessage_.QuoteReply(mc); + default: throw std::runtime_error("错误的 MessageType ."); + } + } + } \ No newline at end of file From e5973fd72e0200bfeabbe95cb45c75cd83556331 Mon Sep 17 00:00:00 2001 From: cyanray Date: Fri, 15 May 2020 15:27:36 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=80=E4=BA=9B?= =?UTF-8?q?=E9=94=99=E8=AF=AF;?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/events/message_event.hpp | 27 +++++++++++++-------------- include/mirai_bot.hpp | 15 +++++++++++++-- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/include/events/message_event.hpp b/include/events/message_event.hpp index ad96fb7..6447552 100644 --- a/include/events/message_event.hpp +++ b/include/events/message_event.hpp @@ -15,12 +15,12 @@ namespace Cyan enum class MessageType { - FriendMessage, // Ϣ - GroupMessage, // ȺϢ - TempMessage // ʱϢ + FriendMessage, // 好友消息 + GroupMessage, // 群组消息 + TempMessage // 临时消息 }; - // ͨϢ¼ (תΪ FriendMessage GroupMessage TempMessage) + // 通用消息事件 (可转换为 FriendMessage GroupMessage TempMessage) class EXPORTED Message : public EventBase { public: @@ -39,21 +39,21 @@ namespace Cyan FriendMessage ToFriendMessage() const { FriendMessage m; - m.Set(this->ToJson()); + m.Set(json_); return m; } GroupMessage ToGroupMessage() const { GroupMessage m; - m.Set(this->ToJson()); + m.Set(json_); return m; } TempMessage ToTempMessage() const { TempMessage m; - m.Set(this->ToJson()); + m.Set(json_); return m; } @@ -81,32 +81,31 @@ namespace Cyan { messageType_ = MessageType::FriendMessage; friendMessage_.Set(j); + friendMessage_.SetMiraiBot(bot_); } if (j["type"] == "GroupMessage") { messageType_ = MessageType::GroupMessage; groupMessage_.Set(j); + groupMessage_.SetMiraiBot(bot_); } if (j["type"] == "TempMessage") { messageType_ = MessageType::TempMessage; tempMessage_.Set(j); + tempMessage_.SetMiraiBot(bot_); } this->MessageChain.Set(j["messageChain"]); + json_ = j; return true; } virtual json ToJson() const override { - switch (messageType_) - { - case MessageType::FriendMessage: return friendMessage_.ToJson(); - case MessageType::GroupMessage: return groupMessage_.ToJson(); - case MessageType::TempMessage: return tempMessage_.ToJson(); - default: throw std::runtime_error(" MessageType ."); - } + return json_; } private: MiraiBot* bot_; + json json_; MessageType messageType_; FriendMessage friendMessage_; GroupMessage groupMessage_; diff --git a/include/mirai_bot.hpp b/include/mirai_bot.hpp index 155b8b9..49c3e47 100644 --- a/include/mirai_bot.hpp +++ b/include/mirai_bot.hpp @@ -359,8 +359,19 @@ namespace Cyan return we; } }; - - processors_.insert({T::GetMiraiEvent(), func }); + + // 特别处理通用消息事件 + if (T::GetMiraiEvent() == MiraiEvent::Message) + { + processors_.insert({ MiraiEvent::FriendMessage, func }); + processors_.insert({ MiraiEvent::GroupMessage, func }); + processors_.insert({ MiraiEvent::TempMessage, func }); + } + else + { + processors_.insert({ T::GetMiraiEvent(), func }); + } + return *this; }