/*
* 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 .
*/
#ifndef MIRAICPPLUGIN_MESSAGE_DISPATCHER_H
#define MIRAICPPLUGIN_MESSAGE_DISPATCHER_H
#include
#include
#include
#include
#include
#include
#include
#include
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 arguments;
};
/**
* @brief 消息处理过程的定义,签名为const SingleInstruction& -> void
*/
using InstructionProcedure = std::function;
// 全局数据结构定义
/**
* @brief 消息队列
*/
extern std::queue messageQueue;
/**
* @brief 控制消息队列更改的互斥锁
*/
extern std::mutex messageQueueMutex;
/**
* @brief 控制消息队列更改的条件变量
*/
extern std::condition_variable msgQueueCondVariable;
/**
* @brief 消息处理函数映射表
*/
extern std::unordered_map> 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
split(const std::string& str, char delim);
}
// 打开命名空间std,并对InstructionType定义std::hash特化
namespace std{
template<>
struct hash{
size_t operator() (const MessageDispatcher::InstructionType& instruction) const {
return std::hash()(static_cast(instruction));
}
};
}
#endif //MIRAICPPLUGIN_MESSAGE_DISPATCHER_H