Lucas-Bot/src/MessageDispatcher.h

190 lines
5.5 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* This file is part of Lucas' Bot.
*
* Lucas' Bot is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
Lucas' Bot is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
for more details.
You should have received a copy of the GNU Affero General Public License along
with Lucas' Bot. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef MIRAICPPLUGIN_MESSAGE_DISPATCHER_H
#define MIRAICPPLUGIN_MESSAGE_DISPATCHER_H
#include <MiraiCP.hpp>
#include <string>
#include <unordered_map>
#include <mutex>
#include <thread>
#include <queue>
#include <condition_variable>
#include <functional>
namespace MessageDispatcher {
// 全局类型定义
/**
* @brief 指令前缀
*/
constexpr char instructionPrefix = '.';
/**
* @brief 消息类型
* 对应MiraiCP的文档说明
*/
enum class MessageType {
MarketFace = -5,
OnlineForwardedMessage = -4,
OnlineAudio = -3,
QuoteReply = -2,
UnSupportMessage = -1,
PlainText = 0,
At = 1,
AtAll = 2,
Image = 3,
App = 4,
Service = 5,
File = 6,
Face = 7,
FlashImage = 8,
MusicShare = 9
};
/**
* @brief 指令类型,根据不同的指令类型注册不同的消息处理程序
*/
enum class InstructionType{
Repeat, // 复读
CommercialAccount, // 营销号
UselessParagraph, // 废话
Trash, // 垃圾
Sick, // 发病
KFCCrazyThursday, // 疯狂星期四V我50
TouhouProject, // 东方Project
SignOn, // 签到
Fishing, // 钓鱼
Working, // 打工
FiveThousandMega, // 5000兆表情包生成
Menu, // 菜单
About, // 关于
NotImplemented, // 未实现
OtherMessage // 普通聊天消息
};
/**
* @brief 结构体 SingleInstruction
* 代表单条指令的结构
*/
struct SingleInstruction {
const MiraiCP::GroupMessageEvent& event;
InstructionType type;
std::vector<std::string> arguments;
};
/**
* @brief 消息处理过程的定义签名为const SingleInstruction& -> void
*/
using InstructionProcedure = std::function<void(const SingleInstruction&)>;
// 全局数据结构定义
/**
* @brief 消息队列
*/
extern std::queue<MiraiCP::GroupMessageEvent> messageQueue;
/**
* @brief 控制消息队列更改的互斥锁
*/
extern std::mutex messageQueueMutex;
/**
* @brief 控制消息队列更改的条件变量
*/
extern std::condition_variable msgQueueCondVariable;
/**
* @brief 消息处理函数映射表
*/
extern std::unordered_map<InstructionType, InstructionProcedure,
std::hash<InstructionType>> instructionProcedureMap;
// 接口
/**
* @brief produceMessage 适用于producer的接口往消息队列末尾放入一条消息
* @param event 待处理的消息
*/
void produceMessage(const MiraiCP::GroupMessageEvent& event);
/**
* @brief translateMessage 将文字消息转换为SingleInstruction结构
* @param event 待处理的群消息
* @return 代表转换后的单条指令
*/
SingleInstruction translateMessage(const MiraiCP::GroupMessageEvent& event);
/**
* @brief 查询text字符串对应的指令信息
* @param text 待查询的字符串
* @return 若text与某一条指令匹配返回对应的指令
* 若text不与任意一条指令匹配返回InstructionType::NotImplemented
*/
InstructionType queryInstructionTypeFromText(const std::string& text);
/**
* @brief 将单条指令送往对应的指令处理程序
* @param instruction 待处理的消息
*/
void dispatchInstruction(const SingleInstruction& instruction);
/**
* @brief 对给定的指令类型,注册对应的指令处理程序
* @param instructionType 指令类型
* @param instructionProcedure 指令处理程序
*/
void registerInstructionProcedure(InstructionType instructionType,
InstructionProcedure instructionProcedure);
/**
* @brief 对未注册指令处理程序的指令类型,默认的处理程序
* @param instruction 指令
*/
void defaultInstructionProcedure(const SingleInstruction& instruction);
/**
* @brief 消费者线程函数,从消息队列队头取出消息并处理
*/
[[noreturn]]
void consumerThreadFunction();
/**
* @brief 根据delim将str切割并存储在返回值的vector中
* @param str 将被分割的字符串
* @param delimiter 分隔符
* @return 切割完成后的字符串组成的vector
*/
std::vector<std::string>
split(const std::string& str, char delim);
}
// 打开命名空间std并对InstructionType定义std::hash特化
namespace std{
template<>
struct hash<MessageDispatcher::InstructionType>{
size_t operator() (const MessageDispatcher::InstructionType& instruction) const {
return std::hash<int>()(static_cast<int>(instruction));
}
};
}
#endif //MIRAICPPLUGIN_MESSAGE_DISPATCHER_H