Skip to content
This repository was archived by the owner on Aug 16, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 28 additions & 5 deletions examples/RepeatMessage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,29 +51,52 @@ system("chcp 65001");
cout << "Bot Working..." << endl;

// 监听各类事件
bot.OnEventReceived<GroupMessage>(
bot.On<GroupMessage>(
[&](GroupMessage m)
{
m.QuoteReply(m.MessageChain);
});

bot.OnEventReceived<FriendMessage>(
// 可以多次监听同一事件,每个处理函数都会被执行,但是不保证执行顺序
bot.On<GroupMessage>(
[&](GroupMessage m)
{
m.Reply("2222 " + m.MessageChain);
});

bot.On<FriendMessage>(
[&](FriendMessage m)
{
m.Reply("你好呀, " + m.MessageChain);
});

bot.OnEventReceived<TempMessage>(
bot.On<TempMessage>(
[&](TempMessage m)
{
m.Reply(m.MessageChain);
});

// 通用型消息
// 收到 FriendMessage、GroupMessage、TempMessage 时都会调用它
// 判断类型之后,也可调用对应的转换函数进行转换 (类型不正确将转换失败抛出异常)
bot.On<Message>(
[&](Message m)
{
m.Reply("Message事件可处理三种消息:" + m.MessageChain);

// 判断是否群组消息
if(m.GetMessageType() == MessageType::GroupMessage)
{
GroupMessage gm = m.ToGroupMessage();
// TODO: 针对群组消息的特别处理
}

});


// 记录轮询事件时的错误
bot.EventLoop([](const char* errMsg)
{
cout << "轮询事件时出错: " << errMsg << endl;
cout << "获取事件时出错: " << errMsg << endl;
});

return 0;
Expand Down
2 changes: 1 addition & 1 deletion include/events/event_interface.hpp
Original file line number Diff line number Diff line change
@@ -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
Expand Down
1 change: 0 additions & 1 deletion include/events/event_processer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

#include <functional>
#include <memory>
#include "event_interface.hpp"

namespace Cyan
{
Expand Down
3 changes: 2 additions & 1 deletion include/events/events.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -31,7 +32,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_
116 changes: 116 additions & 0 deletions include/events/message_event.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#pragma once
#ifndef mirai_cpp_events_message_hpp_H_
#define mirai_cpp_events_message_hpp_H_

#include <nlohmann/json.hpp>
#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(json_);
return m;
}

GroupMessage ToGroupMessage() const
{
GroupMessage m;
m.Set(json_);
return m;
}

TempMessage ToTempMessage() const
{
TempMessage m;
m.Set(json_);
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);
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
{
return json_;
}
private:
MiraiBot* bot_;
json json_;
MessageType messageType_;
FriendMessage friendMessage_;
GroupMessage groupMessage_;
TempMessage tempMessage_;
};
}

#endif // !mirai_cpp_events_message_hpp_H_
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once
#ifndef mirai_cpp_events_events_name_hpp_H_
#define mirai_cpp_events_events_name_hpp_H_
#include <string>

namespace Cyan
{
Expand Down Expand Up @@ -33,9 +34,10 @@ namespace Cyan
MemberJoinRequestEvent, // 用户入群申请
BotLeaveEventActive, // Bot 主动离开群
BotLeaveEventKick, // Bot 被剔出群
Message // 通用消息事件
};

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;
Expand Down Expand Up @@ -63,9 +65,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:
Expand Down
50 changes: 30 additions & 20 deletions include/mirai_bot.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -337,31 +336,42 @@ namespace Cyan
bool ws_enabled_;
httplib::Client http_client_;
ThreadPool pool_;
unordered_map<MiraiEvent, function<WeakEvent(WeakEvent)>> processors_;
std::unordered_multimap<MiraiEvent, function<WeakEvent(WeakEvent)>> processors_;
};

template <typename T>
MiraiBot& MiraiBot::OnEventReceived(const EventProcessor<T>& 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<T> e = std::make_shared<T>();
return std::dynamic_pointer_cast<EventBase>(e);
}
else
{
// 这个lambda函数有两个作用
// 1.创建类型为T的WeakEvent
// 2.将传入的WeakEvent转化为类型T
// 然后给 EventProcessor 使用
if (we == nullptr)
{
std::shared_ptr<T> e = std::make_shared<T>();
return std::dynamic_pointer_cast<EventBase>(e);
}
else
{
ep(*(std::dynamic_pointer_cast<T>(we)));
return we;
}
} });
ep(*(std::dynamic_pointer_cast<T>(we)));
return we;
}
};

// 特别处理通用消息事件
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;
}

Expand Down
22 changes: 22 additions & 0 deletions src/event_func.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 .");
}
}

}
6 changes: 3 additions & 3 deletions src/mirai_bot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -827,10 +827,10 @@ namespace Cyan
string event_name = ele["type"].get<string>();
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);
Expand Down