Skip to content
This repository was archived by the owner on Aug 16, 2024. It is now read-only.

Commit 1dc8ad0

Browse files
authored
Merge pull request #12 from cyanray/dev/cyanray
On方法支持重复监听同一事件;
2 parents b0d6687 + e5973fd commit 1dc8ad0

File tree

9 files changed

+207
-34
lines changed

9 files changed

+207
-34
lines changed

examples/RepeatMessage.cpp

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,29 +51,52 @@ system("chcp 65001");
5151
cout << "Bot Working..." << endl;
5252

5353
// 监听各类事件
54-
bot.OnEventReceived<GroupMessage>(
54+
bot.On<GroupMessage>(
5555
[&](GroupMessage m)
5656
{
5757
m.QuoteReply(m.MessageChain);
5858
});
59-
60-
bot.OnEventReceived<FriendMessage>(
59+
// 可以多次监听同一事件,每个处理函数都会被执行,但是不保证执行顺序
60+
bot.On<GroupMessage>(
61+
[&](GroupMessage m)
62+
{
63+
m.Reply("2222 " + m.MessageChain);
64+
});
65+
66+
bot.On<FriendMessage>(
6167
[&](FriendMessage m)
6268
{
6369
m.Reply("你好呀, " + m.MessageChain);
6470
});
6571

66-
bot.OnEventReceived<TempMessage>(
72+
bot.On<TempMessage>(
6773
[&](TempMessage m)
6874
{
6975
m.Reply(m.MessageChain);
7076
});
7177

78+
// 通用型消息
79+
// 收到 FriendMessage、GroupMessage、TempMessage 时都会调用它
80+
// 判断类型之后,也可调用对应的转换函数进行转换 (类型不正确将转换失败抛出异常)
81+
bot.On<Message>(
82+
[&](Message m)
83+
{
84+
m.Reply("Message事件可处理三种消息:" + m.MessageChain);
85+
86+
// 判断是否群组消息
87+
if(m.GetMessageType() == MessageType::GroupMessage)
88+
{
89+
GroupMessage gm = m.ToGroupMessage();
90+
// TODO: 针对群组消息的特别处理
91+
}
92+
93+
});
94+
7295

7396
// 记录轮询事件时的错误
7497
bot.EventLoop([](const char* errMsg)
7598
{
76-
cout << "轮询事件时出错: " << errMsg << endl;
99+
cout << "获取事件时出错: " << errMsg << endl;
77100
});
78101

79102
return 0;

include/events/event_interface.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#pragma once
22
#ifndef mirai_cpp_events_event_interface_hpp_H_
33
#define mirai_cpp_events_event_interface_hpp_H_
4-
#include "events_name.hpp"
4+
#include "mirai_event.hpp"
55
#include "defs/serializable.hpp"
66
#include "defs/qq_types.hpp"
77
namespace Cyan

include/events/event_processer.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
#include <functional>
66
#include <memory>
7-
#include "event_interface.hpp"
87

98
namespace Cyan
109
{

include/events/events.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#define mirai_cpp_events_events_hpp_H_
44

55
// 消息事件
6+
#include "message_event.hpp"
67
#include "friend_message.hpp"
78
#include "group_message.hpp"
89
#include "temp_message.hpp"
@@ -31,7 +32,7 @@
3132
#include "group_name_change.hpp"
3233
// 一些定义
3334
#include "event_processer.hpp"
34-
#include "events_name.hpp"
35+
#include "mirai_event.hpp"
3536
#include "event_interface.hpp"
3637

3738
#endif // !mirai_cpp_events_events_hpp_H_

include/events/message_event.hpp

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#pragma once
2+
#ifndef mirai_cpp_events_message_hpp_H_
3+
#define mirai_cpp_events_message_hpp_H_
4+
5+
#include <nlohmann/json.hpp>
6+
#include "defs/qq_types.hpp"
7+
#include "friend_message.hpp"
8+
#include "group_message.hpp"
9+
#include "temp_message.hpp"
10+
#include "event_interface.hpp"
11+
#include "exported.h"
12+
13+
namespace Cyan
14+
{
15+
16+
enum class MessageType
17+
{
18+
FriendMessage, // 好友消息
19+
GroupMessage, // 群组消息
20+
TempMessage // 临时消息
21+
};
22+
23+
// 通用消息事件 (可转换为 FriendMessage GroupMessage TempMessage)
24+
class EXPORTED Message : public EventBase
25+
{
26+
public:
27+
Cyan::MessageChain MessageChain;
28+
29+
static MiraiEvent GetMiraiEvent()
30+
{
31+
return MiraiEvent::Message;
32+
}
33+
34+
MessageType GetMessageType() const
35+
{
36+
return messageType_;
37+
}
38+
39+
FriendMessage ToFriendMessage() const
40+
{
41+
FriendMessage m;
42+
m.Set(json_);
43+
return m;
44+
}
45+
46+
GroupMessage ToGroupMessage() const
47+
{
48+
GroupMessage m;
49+
m.Set(json_);
50+
return m;
51+
}
52+
53+
TempMessage ToTempMessage() const
54+
{
55+
TempMessage m;
56+
m.Set(json_);
57+
return m;
58+
}
59+
60+
MessageId GetMessageId() const
61+
{
62+
return (this->MessageChain).GetMessageId();
63+
}
64+
65+
int64_t GetTimestamp() const
66+
{
67+
return (this->MessageChain).GetTimestamp();
68+
}
69+
70+
virtual void SetMiraiBot(MiraiBot* bot) override
71+
{
72+
this->bot_ = bot;
73+
}
74+
75+
MessageId Reply(const Cyan::MessageChain& mc) const;
76+
MessageId QuoteReply(const Cyan::MessageChain& mc) const;
77+
78+
virtual bool Set(const json& j) override
79+
{
80+
if (j["type"] == "FriendMessage")
81+
{
82+
messageType_ = MessageType::FriendMessage;
83+
friendMessage_.Set(j);
84+
friendMessage_.SetMiraiBot(bot_);
85+
}
86+
if (j["type"] == "GroupMessage")
87+
{
88+
messageType_ = MessageType::GroupMessage;
89+
groupMessage_.Set(j);
90+
groupMessage_.SetMiraiBot(bot_);
91+
}
92+
if (j["type"] == "TempMessage")
93+
{
94+
messageType_ = MessageType::TempMessage;
95+
tempMessage_.Set(j);
96+
tempMessage_.SetMiraiBot(bot_);
97+
}
98+
this->MessageChain.Set(j["messageChain"]);
99+
json_ = j;
100+
return true;
101+
}
102+
virtual json ToJson() const override
103+
{
104+
return json_;
105+
}
106+
private:
107+
MiraiBot* bot_;
108+
json json_;
109+
MessageType messageType_;
110+
FriendMessage friendMessage_;
111+
GroupMessage groupMessage_;
112+
TempMessage tempMessage_;
113+
};
114+
}
115+
116+
#endif // !mirai_cpp_events_message_hpp_H_

include/events/events_name.hpp renamed to include/events/mirai_event.hpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#pragma once
22
#ifndef mirai_cpp_events_events_name_hpp_H_
33
#define mirai_cpp_events_events_name_hpp_H_
4+
#include <string>
45

56
namespace Cyan
67
{
@@ -33,9 +34,10 @@ namespace Cyan
3334
MemberJoinRequestEvent, // 用户入群申请
3435
BotLeaveEventActive, // Bot 主动离开群
3536
BotLeaveEventKick, // Bot 被剔出群
37+
Message // 通用消息事件
3638
};
3739

38-
inline MiraiEvent MiraiEventStr(const string& miraiEvent)
40+
inline MiraiEvent MiraiEventStr(const std::string& miraiEvent)
3941
{
4042
if (miraiEvent == "FriendMessage") return MiraiEvent::FriendMessage;
4143
if (miraiEvent == "GroupMessage") return MiraiEvent::GroupMessage;
@@ -63,9 +65,9 @@ namespace Cyan
6365
return MiraiEvent::Default;
6466
}
6567

66-
inline string MiraiEventStr(MiraiEvent miraiEvent)
68+
inline std::string MiraiEventStr(MiraiEvent miraiEvent)
6769
{
68-
string result;
70+
std::string result;
6971
switch (miraiEvent)
7072
{
7173
case Cyan::MiraiEvent::FriendMessage:

include/mirai_bot.hpp

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ using std::string;
2020
using std::vector;
2121
using std::function;
2222
using nlohmann::json;
23-
using std::unordered_map;
2423

2524
// fu*k windows.h
2625
#ifdef max
@@ -337,31 +336,42 @@ namespace Cyan
337336
bool ws_enabled_;
338337
httplib::Client http_client_;
339338
ThreadPool pool_;
340-
unordered_map<MiraiEvent, function<WeakEvent(WeakEvent)>> processors_;
339+
std::unordered_multimap<MiraiEvent, function<WeakEvent(WeakEvent)>> processors_;
341340
};
342341

343342
template <typename T>
344343
MiraiBot& MiraiBot::OnEventReceived(const EventProcessor<T>& ep)
345344
{
346-
processors_.insert({
347-
T::GetMiraiEvent(),
348-
[=](WeakEvent we)
345+
auto func = [=](WeakEvent we)
346+
{
347+
// 这个lambda函数有两个作用
348+
// 1.创建类型为T的WeakEvent
349+
// 2.将传入的WeakEvent转化为类型T
350+
// 然后给 EventProcessor 使用
351+
if (we == nullptr)
352+
{
353+
std::shared_ptr<T> e = std::make_shared<T>();
354+
return std::dynamic_pointer_cast<EventBase>(e);
355+
}
356+
else
349357
{
350-
// 这个lambda函数有两个作用
351-
// 1.创建类型为T的WeakEvent
352-
// 2.将传入的WeakEvent转化为类型T
353-
// 然后给 EventProcessor 使用
354-
if (we == nullptr)
355-
{
356-
std::shared_ptr<T> e = std::make_shared<T>();
357-
return std::dynamic_pointer_cast<EventBase>(e);
358-
}
359-
else
360-
{
361-
ep(*(std::dynamic_pointer_cast<T>(we)));
362-
return we;
363-
}
364-
} });
358+
ep(*(std::dynamic_pointer_cast<T>(we)));
359+
return we;
360+
}
361+
};
362+
363+
// 特别处理通用消息事件
364+
if (T::GetMiraiEvent() == MiraiEvent::Message)
365+
{
366+
processors_.insert({ MiraiEvent::FriendMessage, func });
367+
processors_.insert({ MiraiEvent::GroupMessage, func });
368+
processors_.insert({ MiraiEvent::TempMessage, func });
369+
}
370+
else
371+
{
372+
processors_.insert({ T::GetMiraiEvent(), func });
373+
}
374+
365375
return *this;
366376
}
367377

src/event_func.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,26 @@ namespace Cyan
9494
return true;
9595
}
9696

97+
MessageId Message::Reply(const Cyan::MessageChain& mc) const
98+
{
99+
switch (messageType_)
100+
{
101+
case MessageType::FriendMessage: return friendMessage_.Reply(mc);
102+
case MessageType::GroupMessage: return groupMessage_.Reply(mc);
103+
case MessageType::TempMessage: return tempMessage_.Reply(mc);
104+
default: throw std::runtime_error("错误的 MessageType .");
105+
}
106+
}
107+
108+
MessageId Message::QuoteReply(const Cyan::MessageChain& mc) const
109+
{
110+
switch (messageType_)
111+
{
112+
case MessageType::FriendMessage: return friendMessage_.QuoteReply(mc);
113+
case MessageType::GroupMessage: return groupMessage_.QuoteReply(mc);
114+
case MessageType::TempMessage: return tempMessage_.QuoteReply(mc);
115+
default: throw std::runtime_error("错误的 MessageType .");
116+
}
117+
}
118+
97119
}

src/mirai_bot.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -827,10 +827,10 @@ namespace Cyan
827827
string event_name = ele["type"].get<string>();
828828
MiraiEvent mirai_event = MiraiEventStr(event_name);
829829
// 寻找能处理事件的 Processor
830-
auto pit = processors_.find(mirai_event);
831-
if (pit != processors_.end())
830+
auto range = processors_.equal_range(mirai_event);
831+
for (auto it = range.first; it != range.second; ++it)
832832
{
833-
auto executor = pit->second;
833+
auto executor = it->second;
834834
// 给 executor 传入 nullptr 可以创建一个 WeakEvent
835835
WeakEvent pevent = executor(nullptr);
836836
pevent->SetMiraiBot(this);

0 commit comments

Comments
 (0)