243 lines
14 KiB
C++
243 lines
14 KiB
C++
#include "Properties.h"
|
|
#include "query/Command.h"
|
|
#include <algorithm>
|
|
#include <src/server/QueryServer.h>
|
|
#include <src/VirtualServerManager.h>
|
|
#include <src/InstanceHandler.h>
|
|
#include "QueryClient.h"
|
|
#include <log/LogUtils.h>
|
|
|
|
using namespace std;
|
|
using namespace std::chrono;
|
|
using namespace ts;
|
|
using namespace ts::server;
|
|
|
|
extern ts::server::InstanceHandler* serverInstance;
|
|
|
|
bool QueryClient::eventActive(QueryEventGroup group, QueryEventSpecifier specifier) {
|
|
return (this->eventMask[group] & (1U << specifier)) > 0;
|
|
}
|
|
|
|
void QueryClient::toggleEvent(QueryEventGroup group, QueryEventSpecifier specifier, bool flag) {
|
|
if(flag)
|
|
this->eventMask[group] |= 1U << specifier;
|
|
else
|
|
this->eventMask[group] &= ~(1U << specifier);
|
|
}
|
|
|
|
void QueryClient::resetEventMask() {
|
|
memset(eventMask, 0, sizeof(eventMask) / sizeof(*eventMask) * sizeof(uint16_t));
|
|
}
|
|
|
|
bool QueryClient::notifyClientNeededPermissions() {
|
|
return true; //Query gets no needed permissions
|
|
}
|
|
|
|
#define CHK_EVENT(group, specifier) \
|
|
do { \
|
|
if(!this->eventActive(QueryEventGroup::group, QueryEventSpecifier::specifier)) return false; \
|
|
} while(0)
|
|
|
|
bool QueryClient::notifyServerUpdated(shared_ptr<ConnectedClient> ptr) {
|
|
CHK_EVENT(QEVENTGROUP_SERVER, QEVENTSPECIFIER_SERVER_EDIT);
|
|
return ConnectedClient::notifyServerUpdated(ptr);
|
|
}
|
|
|
|
bool QueryClient::notifyClientUpdated(const std::shared_ptr<ConnectedClient> &ptr, const std::deque<const property::PropertyDescription*> &deque, bool lock_channel_tree) {
|
|
CHK_EVENT(QEVENTGROUP_CLIENT_MISC, QEVENTSPECIFIER_CLIENT_MISC_UPDATE);
|
|
return ConnectedClient::notifyClientUpdated(ptr, deque, lock_channel_tree);
|
|
}
|
|
|
|
bool QueryClient::notifyClientPoke(std::shared_ptr<ConnectedClient> invoker, std::string msg) {
|
|
CHK_EVENT(QEVENTGROUP_CLIENT_MISC, QEVENTSPECIFIER_CLIENT_MISC_POKE);
|
|
return ConnectedClient::notifyClientPoke(invoker, msg);
|
|
}
|
|
|
|
bool QueryClient::notifyPluginCmd(std::string name, std::string msg, std::shared_ptr<ConnectedClient> sender) {
|
|
CHK_EVENT(QEVENTGROUP_CLIENT_MISC, QEVENTSPECIFIER_CLIENT_MISC_COMMAND);
|
|
return ConnectedClient::notifyPluginCmd(name, msg, sender);
|
|
}
|
|
|
|
bool QueryClient::notifyClientChatComposing(const shared_ptr<ConnectedClient> &ptr) {
|
|
CHK_EVENT(QEVENTGROUP_CHAT, QEVENTSPECIFIER_CHAT_COMPOSING);
|
|
return ConnectedClient::notifyClientChatComposing(ptr);
|
|
}
|
|
|
|
bool QueryClient::notifyClientChatClosed(const shared_ptr<ConnectedClient> &ptr) {
|
|
CHK_EVENT(QEVENTGROUP_CHAT, QEVENTSPECIFIER_CHAT_CLOSED);
|
|
return ConnectedClient::notifyClientChatClosed(ptr);
|
|
}
|
|
|
|
bool QueryClient::notifyTextMessage(ChatMessageMode mode, const shared_ptr<ConnectedClient> &sender, uint64_t targetId, ChannelId channel_id, const std::chrono::system_clock::time_point& tp, const string &textMessage) {
|
|
if(mode == ChatMessageMode::TEXTMODE_PRIVATE) CHK_EVENT(QEVENTGROUP_CHAT, QEVENTSPECIFIER_CHAT_MESSAGE_PRIVATE);
|
|
else if(mode == ChatMessageMode::TEXTMODE_CHANNEL) CHK_EVENT(QEVENTGROUP_CHAT, QEVENTSPECIFIER_CHAT_MESSAGE_CHANNEL);
|
|
else if(mode == ChatMessageMode::TEXTMODE_SERVER) CHK_EVENT(QEVENTGROUP_CHAT, QEVENTSPECIFIER_CHAT_MESSAGE_SERVER);
|
|
return ConnectedClient::notifyTextMessage(mode, sender, targetId, channel_id, tp, textMessage);
|
|
}
|
|
|
|
|
|
bool QueryClient::notifyServerGroupClientAdd(optional<ts::command_builder> &anOptional,
|
|
const shared_ptr<ConnectedClient> &ptr,
|
|
const shared_ptr<ConnectedClient> &sharedPtr, const GroupId &id) {
|
|
CHK_EVENT(QEVENTGROUP_CLIENT_GROUPS, QEVENTSPECIFIER_CLIENT_GROUPS_ADD);
|
|
return ConnectedClient::notifyServerGroupClientAdd(anOptional, ptr, sharedPtr, id);
|
|
}
|
|
|
|
bool QueryClient::notifyServerGroupClientRemove(optional<ts::command_builder> &anOptional,
|
|
const shared_ptr<ConnectedClient> &ptr,
|
|
const shared_ptr<ConnectedClient> &sharedPtr, const GroupId &id) {
|
|
CHK_EVENT(QEVENTGROUP_CLIENT_GROUPS, QEVENTSPECIFIER_CLIENT_GROUPS_REMOVE);
|
|
return ConnectedClient::notifyServerGroupClientRemove(anOptional, ptr, sharedPtr, id);
|
|
}
|
|
|
|
bool QueryClient::notifyClientChannelGroupChanged(optional<ts::command_builder> &anOptional,
|
|
const shared_ptr <ConnectedClient> &ptr,
|
|
const shared_ptr <ConnectedClient> &sharedPtr, const ChannelId &id,
|
|
const ChannelId &channelId, const GroupId &groupId) {
|
|
CHK_EVENT(QEVENTGROUP_CLIENT_GROUPS, QEVENTSPECIFIER_CLIENT_GROUPS_CHANNEL_CHANGED);
|
|
return ConnectedClient::notifyClientChannelGroupChanged(anOptional, ptr, sharedPtr, id, channelId, groupId);
|
|
}
|
|
|
|
bool QueryClient::notifyChannelMoved(const std::shared_ptr<BasicChannel> &channel, ChannelId order, const std::shared_ptr<ConnectedClient> &invoker) {
|
|
CHK_EVENT(QEVENTGROUP_CHANNEL, QEVENTSPECIFIER_CHANNEL_MOVE);
|
|
return ConnectedClient::notifyChannelMoved(channel, order, invoker);
|
|
}
|
|
|
|
bool QueryClient::notifyChannelCreate(const std::shared_ptr<BasicChannel> &channel, ChannelId orderId,
|
|
const std::shared_ptr<ConnectedClient> &invoker) {
|
|
CHK_EVENT(QEVENTGROUP_CHANNEL, QEVENTSPECIFIER_CHANNEL_CREATE);
|
|
return ConnectedClient::notifyChannelCreate(channel, orderId, invoker);
|
|
}
|
|
|
|
bool QueryClient::notifyChannelDescriptionChanged(std::shared_ptr<BasicChannel> channel) {
|
|
CHK_EVENT(QEVENTGROUP_CHANNEL, QEVENTSPECIFIER_CHANNEL_DESC_EDIT);
|
|
return ConnectedClient::notifyChannelDescriptionChanged(channel);
|
|
}
|
|
|
|
bool QueryClient::notifyChannelPasswordChanged(std::shared_ptr<BasicChannel> channel) {
|
|
CHK_EVENT(QEVENTGROUP_CHANNEL, QEVENTSPECIFIER_CHANNEL_PASSWORD_EDIT);
|
|
return ConnectedClient::notifyChannelPasswordChanged(channel);
|
|
}
|
|
|
|
bool QueryClient::notifyChannelEdited(const std::shared_ptr<BasicChannel> &ptr, const std::vector<property::ChannelProperties> &vector, const std::shared_ptr<ConnectedClient> &sharedPtr, bool b) {
|
|
CHK_EVENT(QEVENTGROUP_CHANNEL, QEVENTSPECIFIER_CHANNEL_EDIT);
|
|
return ConnectedClient::notifyChannelEdited(ptr, vector, sharedPtr, b);
|
|
}
|
|
|
|
bool QueryClient::notifyChannelDeleted(const std::deque<ChannelId> &deque, const std::shared_ptr<ConnectedClient> &ptr) {
|
|
CHK_EVENT(QEVENTGROUP_CHANNEL, QEVENTSPECIFIER_CHANNEL_DELETED);
|
|
return ConnectedClient::notifyChannelDeleted(deque, ptr);
|
|
}
|
|
|
|
bool QueryClient::notifyClientEnterView(const std::deque<std::shared_ptr<ConnectedClient>> &deque, const ViewReasonSystemT &t) {
|
|
if(!this->eventActive(QueryEventGroup::QEVENTGROUP_CLIENT_VIEW, QueryEventSpecifier::QEVENTSPECIFIER_CLIENT_VIEW_JOIN)) {
|
|
assert(mutex_locked(this->channel_lock));
|
|
this->visibleClients.insert(this->visibleClients.end(), deque.begin(), deque.end());
|
|
return true;
|
|
} else
|
|
return ConnectedClient::notifyClientEnterView(deque, t);
|
|
}
|
|
|
|
bool QueryClient::notifyClientEnterView(const std::shared_ptr<ts::server::ConnectedClient> &client, const std::shared_ptr<ts::server::ConnectedClient> &invoker, const std::string &string, const std::shared_ptr<ts::BasicChannel> &to,
|
|
ts::ViewReasonId reasonId, const std::shared_ptr<ts::BasicChannel> &from, bool lock) {
|
|
if(!this->eventActive(QueryEventGroup::QEVENTGROUP_CLIENT_VIEW, QueryEventSpecifier::QEVENTSPECIFIER_CLIENT_VIEW_JOIN)) {
|
|
assert(!lock);
|
|
this->visibleClients.push_back(client);
|
|
return true;
|
|
}
|
|
return ConnectedClient::notifyClientEnterView(client, invoker, string, to, reasonId, from, lock);
|
|
}
|
|
|
|
bool QueryClient::notifyClientMoved(const std::shared_ptr<ConnectedClient> &client, const std::shared_ptr<BasicChannel> &target_channel, ViewReasonId reason, std::string msg, std::shared_ptr<ConnectedClient> invoker, bool lock_channel_tree) {
|
|
return ConnectedClient::notifyClientMoved(client, target_channel, reason, msg, invoker, lock_channel_tree);
|
|
}
|
|
|
|
bool QueryClient::notifyClientLeftView(const std::shared_ptr<ConnectedClient> &client, const std::shared_ptr<BasicChannel> &target_channel, ViewReasonId reasonId, const std::string &reasonMessage, std::shared_ptr<ConnectedClient> invoker,
|
|
bool lock_channel_tree) {
|
|
if(!this->eventActive(QueryEventGroup::QEVENTGROUP_CLIENT_VIEW, QueryEventSpecifier::QEVENTSPECIFIER_CLIENT_VIEW_LEAVE)) {
|
|
this->visibleClients.erase(std::remove_if(this->visibleClients.begin(), this->visibleClients.end(), [&, client](const weak_ptr<ConnectedClient>& weak) {
|
|
auto c = weak.lock();
|
|
if(!c) {
|
|
logError(this->getServerId(), "{} Got \"dead\" client in visible client list! This can cause a remote client disconnect within the future!", CLIENT_STR_LOG_PREFIX);
|
|
return true;
|
|
}
|
|
return c == client;
|
|
}), this->visibleClients.end());
|
|
return true;
|
|
}
|
|
return ConnectedClient::notifyClientLeftView(client, target_channel, reasonId, reasonMessage, invoker, lock_channel_tree);
|
|
}
|
|
|
|
bool QueryClient::notifyClientLeftView(const std::deque<std::shared_ptr<ConnectedClient>> &clients, const std::string &string, bool b, const ViewReasonServerLeftT &t) {
|
|
if(!this->eventActive(QueryEventGroup::QEVENTGROUP_CLIENT_VIEW, QueryEventSpecifier::QEVENTSPECIFIER_CLIENT_VIEW_LEAVE)) {
|
|
this->visibleClients.erase(std::remove_if(this->visibleClients.begin(), this->visibleClients.end(), [&](const weak_ptr<ConnectedClient>& weak) {
|
|
auto c = weak.lock();
|
|
if(!c) {
|
|
logError(this->getServerId(), "{} Got \"dead\" client in visible client list! This can cause a remote client disconnect within the future!", CLIENT_STR_LOG_PREFIX);
|
|
return true;
|
|
}
|
|
return std::find(clients.begin(), clients.end(), c) != clients.end();
|
|
}), this->visibleClients.end());
|
|
return true;
|
|
}
|
|
return ConnectedClient::notifyClientLeftView(clients, string, b, t);
|
|
}
|
|
|
|
bool QueryClient::notifyClientLeftViewKicked(const std::shared_ptr<ConnectedClient> &client, const std::shared_ptr<BasicChannel> &target_channel, const std::string &message, std::shared_ptr<ConnectedClient> invoker, bool lock_channel_tree) {
|
|
if(!this->eventActive(QueryEventGroup::QEVENTGROUP_CLIENT_VIEW, QueryEventSpecifier::QEVENTSPECIFIER_CLIENT_VIEW_LEAVE)) {
|
|
this->visibleClients.erase(std::remove_if(this->visibleClients.begin(), this->visibleClients.end(), [&, client](const weak_ptr<ConnectedClient>& weak) {
|
|
auto c = weak.lock();
|
|
if(!c) {
|
|
logError(this->getServerId(), "{} Got \"dead\" client in visible client list! This can cause a remote client disconnect within the future!", CLIENT_STR_LOG_PREFIX);
|
|
return true;
|
|
}
|
|
return c == client;
|
|
}), this->visibleClients.end());
|
|
return true;
|
|
}
|
|
return ConnectedClient::notifyClientLeftViewKicked(client, target_channel, message, invoker, lock_channel_tree);
|
|
}
|
|
|
|
bool QueryClient::notifyClientLeftViewBanned(const std::shared_ptr<ConnectedClient> &client, const std::string &message, std::shared_ptr<ConnectedClient> invoker, size_t length, bool lock_channel_tree) {
|
|
if(!this->eventActive(QueryEventGroup::QEVENTGROUP_CLIENT_VIEW, QueryEventSpecifier::QEVENTSPECIFIER_CLIENT_VIEW_LEAVE)) {
|
|
this->visibleClients.erase(std::remove_if(this->visibleClients.begin(), this->visibleClients.end(), [&, client](const weak_ptr<ConnectedClient>& weak) {
|
|
auto c = weak.lock();
|
|
if(!c) {
|
|
logError(this->getServerId(), "{} Got \"dead\" client in visible client list! This can cause a remote client disconnect within the future!", CLIENT_STR_LOG_PREFIX);
|
|
return true;
|
|
}
|
|
return c == client;
|
|
}), this->visibleClients.end());
|
|
return true;
|
|
}
|
|
return ConnectedClient::notifyClientLeftViewBanned(client, message, invoker, length, lock_channel_tree);
|
|
}
|
|
|
|
bool QueryClient::notifyMusicQueueAdd(const std::shared_ptr<MusicClient> &bot, const std::shared_ptr<ts::music::SongInfo> &entry, int index, const std::shared_ptr<ConnectedClient> &invoker) {
|
|
CHK_EVENT(QEVENTGROUP_MUSIC, QEVENTSPECIFIER_MUSIC_QUEUE);
|
|
return ConnectedClient::notifyMusicQueueAdd(bot, entry, index, invoker);
|
|
}
|
|
|
|
bool QueryClient::notifyMusicQueueRemove(const std::shared_ptr<MusicClient> &bot, const std::deque<std::shared_ptr<music::SongInfo>> &entry, const std::shared_ptr<ConnectedClient> &invoker) {
|
|
CHK_EVENT(QEVENTGROUP_MUSIC, QEVENTSPECIFIER_MUSIC_QUEUE);
|
|
return ConnectedClient::notifyMusicQueueRemove(bot, entry, invoker);
|
|
}
|
|
|
|
bool QueryClient::notifyMusicQueueOrderChange(const std::shared_ptr<MusicClient> &bot, const std::shared_ptr<ts::music::SongInfo> &entry, int order, const std::shared_ptr<ConnectedClient> &invoker) {
|
|
CHK_EVENT(QEVENTGROUP_MUSIC, QEVENTSPECIFIER_MUSIC_QUEUE);
|
|
return ConnectedClient::notifyMusicQueueOrderChange(bot, entry, order, invoker);
|
|
}
|
|
|
|
|
|
bool QueryClient::notifyMusicPlayerSongChange(const std::shared_ptr<MusicClient> &bot, const shared_ptr<ts::music::SongInfo> &newEntry) {
|
|
CHK_EVENT(QEVENTGROUP_MUSIC, QEVENTSPECIFIER_MUSIC_PLAYER);
|
|
return ConnectedClient::notifyMusicPlayerSongChange(bot, newEntry);
|
|
}
|
|
|
|
bool QueryClient::notifyChannelSubscribed(const deque<shared_ptr<BasicChannel>> &) {
|
|
return false;
|
|
}
|
|
|
|
bool QueryClient::notifyChannelUnsubscribed(const deque<shared_ptr<BasicChannel>> &){
|
|
return false;
|
|
} |