From b40e1326cc9c0ad32c6c1da007d151dd3cdbc49d Mon Sep 17 00:00:00 2001 From: WolverinDEV Date: Sun, 21 Feb 2021 21:56:52 +0100 Subject: [PATCH] Using tasks instead of inlining certain client updates --- server/src/ConnectionStatistics.cpp | 6 +- server/src/InstanceHandler.cpp | 41 ++--- server/src/InstanceHandler.h | 7 +- server/src/TS3ServerClientManager.cpp | 3 +- server/src/VirtualServer.cpp | 25 ++- server/src/VirtualServer.h | 3 + server/src/client/ConnectedClient.cpp | 155 ++++++++++-------- server/src/client/ConnectedClient.h | 13 +- .../ConnectedClientTextCommandHandler.cpp | 55 ++++--- server/src/client/DataClient.cpp | 33 ++-- server/src/client/DataClient.h | 16 ++ server/src/client/command_handler/channel.cpp | 40 ++--- server/src/client/command_handler/client.cpp | 10 +- server/src/client/command_handler/misc.cpp | 9 +- server/src/client/command_handler/server.cpp | 37 ++--- server/src/client/query/QueryClient.cpp | 2 +- .../src/client/query/QueryClientCommands.cpp | 29 ++-- shared | 2 +- 18 files changed, 265 insertions(+), 221 deletions(-) diff --git a/server/src/ConnectionStatistics.cpp b/server/src/ConnectionStatistics.cpp index 380e110..8fbbe04 100644 --- a/server/src/ConnectionStatistics.cpp +++ b/server/src/ConnectionStatistics.cpp @@ -72,12 +72,14 @@ void ConnectionStatistics::tick() { this->total_statistics += current; auto current_second = std::chrono::floor(now.time_since_epoch()).count(); - if(statistics_minute_offset == 0) + if(statistics_minute_offset == 0) { statistics_minute_offset = current_second; + } /* fill all "lost" with the current bandwidth as well */ - while(statistics_minute_offset <= current_second) + while(statistics_minute_offset <= current_second) { this->statistics_minute[statistics_minute_offset++ % this->statistics_minute.size()] = current_normalized; + } this->last_second_tick = now; } } diff --git a/server/src/InstanceHandler.cpp b/server/src/InstanceHandler.cpp index 4c8d49d..48afe3f 100644 --- a/server/src/InstanceHandler.cpp +++ b/server/src/InstanceHandler.cpp @@ -53,7 +53,6 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql) { logCritical(LOG_INSTANCE, "Instance task executor received exception: {}", message); }); - this->tick_manager = make_shared(config::threads::ticking, "tick task "); this->statistics = make_shared(nullptr); std::string error_message{}; @@ -122,12 +121,12 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql) { this->properties()[property::SERVERINSTANCE_PERMISSIONS_VERSION] = this->sql->get_permissions_version(); - globalServerAdmin = std::make_shared(this->getSql(), nullptr, "serveradmin", true); - globalServerAdmin->initialize_weak_reference(this->globalServerAdmin); + this->globalServerAdmin = std::make_shared(this->getSql(), nullptr, "serveradmin", true); + this->globalServerAdmin->initialize_weak_reference(this->globalServerAdmin); ts::server::DatabaseHelper::assignDatabaseId(this->getSql(), 0, globalServerAdmin); this->_musicRoot = std::make_shared(this->getSql(), nullptr, "Music Manager", false); - globalServerAdmin->initialize_weak_reference(this->_musicRoot); + dynamic_pointer_cast(this->_musicRoot)->initialize_weak_reference(this->_musicRoot); { this->groupManager = std::make_shared(nullptr, this->getSql()); @@ -213,21 +212,6 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql) { this->web_list = make_shared(); } -void InstanceHandler::executeTick(VirtualServer* server) { - auto str = "server_" + to_string(server->getServerId()); - if(!this->tick_manager->schedule(str, std::bind(&VirtualServer::executeServerTick, server), milliseconds(500))) { - logCritical(LOG_INSTANCE, "Could not schedule server ticking task!"); - } -} - -void InstanceHandler::cancelExecute(VirtualServer* server) { - auto str = "server_" + to_string(server->getServerId()); - if(!this->tick_manager->cancelTask(str)){ - logError(LOG_INSTANCE, "Could not stop server tick task!"); - } -} - - InstanceHandler::~InstanceHandler() { delete this->_properties; delete this->banMgr; @@ -238,7 +222,6 @@ InstanceHandler::~InstanceHandler() { _musicRoot = nullptr; statistics = nullptr; - tick_manager = nullptr; } inline string strip(std::string message) { @@ -417,7 +400,14 @@ FwIDAQAB startTimestamp = system_clock::now(); this->voiceServerManager->executeAutostart(); - this->scheduler()->schedule(INSTANCE_TICK_NAME, bind(&InstanceHandler::tickInstance, this), milliseconds{500}); + this->general_task_executor()->schedule_repeating( + this->tick_task_id, + "instance ticker", + std::chrono::milliseconds{500}, + [&](const auto&) { + this->tickInstance(); + } + ); return true; } @@ -431,8 +421,11 @@ void InstanceHandler::stopInstance() { this->web_list->enabled = false; this->server_command_executor_->shutdown(); + /* TODO: Block on canceling. */ + this->general_task_executor()->cancel_task(this->tick_task_id); + this->tick_task_id = 0; + threads::MutexLock lock_tick(this->lock_tick); - this->scheduler()->cancelTask(INSTANCE_TICK_NAME); debugMessage(LOG_INSTANCE, "Stopping all virtual servers"); if (this->voiceServerManager) @@ -470,7 +463,9 @@ void InstanceHandler::stopInstance() { void InstanceHandler::tickInstance() { threads::MutexLock lock(this->lock_tick); - if(!this->active) return; + if(!this->active) { + return; + } auto now = system_clock::now(); diff --git a/server/src/InstanceHandler.h b/server/src/InstanceHandler.h index 163281e..96417a5 100644 --- a/server/src/InstanceHandler.h +++ b/server/src/InstanceHandler.h @@ -63,9 +63,6 @@ namespace ts { std::chrono::time_point getStartTimestamp(){ return startTimestamp; } - void executeTick(VirtualServer*); - void cancelExecute(VirtualServer*); - bool reloadConfig(std::vector& /* errors */, bool /* reload file */); void setWebCertRoot(const std::string& /* key */, const std::string& /* certificate */, const std::string& /* revision */); @@ -79,7 +76,6 @@ namespace ts { [[nodiscard]] inline const auto& general_task_executor(){ return this->general_task_executor_; } std::shared_ptr getStatistics(){ return statistics; } - std::shared_ptr scheduler(){ return this->tick_manager; } std::shared_ptr generateLicenseData(); std::shared_ptr getTeamSpeakLicense() { return this->teamspeak_license; } @@ -116,6 +112,8 @@ namespace ts { std::condition_variable activeCon; bool active = false; + task_id tick_task_id{}; + std::chrono::system_clock::time_point startTimestamp; std::chrono::system_clock::time_point sqlTestTimestamp; std::chrono::system_clock::time_point speachUpdateTimestamp; @@ -152,7 +150,6 @@ namespace ts { std::shared_ptr license_service_{nullptr}; std::shared_ptr statistics = nullptr; - std::shared_ptr tick_manager = nullptr; std::shared_ptr general_task_executor_{nullptr}; diff --git a/server/src/TS3ServerClientManager.cpp b/server/src/TS3ServerClientManager.cpp index 38675c8..2a7654a 100644 --- a/server/src/TS3ServerClientManager.cpp +++ b/server/src/TS3ServerClientManager.cpp @@ -532,8 +532,7 @@ void VirtualServer::client_move( } if (s_target_channel) { - if(target->update_client_needed_permissions()) /* update cached calculated permissions */ - target->sendNeededPermissions(false); + target->task_update_needed_permissions.enqueue(); TIMING_STEP(timings, "perm gr upd"); if(s_source_channel) { diff --git a/server/src/VirtualServer.cpp b/server/src/VirtualServer.cpp index 921d3d4..9c72191 100644 --- a/server/src/VirtualServer.cpp +++ b/server/src/VirtualServer.cpp @@ -503,8 +503,18 @@ bool VirtualServer::start(std::string& error) { #endif } - //Startup ticking - serverInstance->executeTick(this); + auto weak_this = this->self; + serverInstance->general_task_executor()->schedule_repeating( + this->tick_task_id, + "server tick " + std::to_string(this->serverId), + std::chrono::milliseconds {500}, + [weak_this](const auto& scheduled){ + auto ref_self = weak_this.lock(); + if(ref_self) { + ref_self->executeServerTick(); + } + } + ); if(this->properties()[property::VIRTUALSERVER_WEBLIST_ENABLED].as()) serverInstance->getWebList()->enable_report(this->self.lock()); @@ -591,7 +601,8 @@ void VirtualServer::stop(const std::string& reason, bool disconnect_query) { } this->music_manager_->disconnectBots(); - serverInstance->cancelExecute(this); + serverInstance->general_task_executor()->cancel_task(this->tick_task_id); + this->tick_task_id = 0; if(this->udpVoiceServer) this->udpVoiceServer->stop(); this->udpVoiceServer = nullptr; @@ -1001,8 +1012,9 @@ vectornotifyChannelGroupList(); } if(this->notifyClientPropertyUpdates(client, this->getGroupManager()->update_server_group_property(client, true, client->getChannel()))) { - if(client->update_client_needed_permissions()) /* update cached calculated permissions */ - client->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ + client->task_update_needed_permissions.enqueue(); } - client->updateChannelClientProperties(true, true); + client->task_update_channel_client_properties.enqueue(); } return true; } diff --git a/server/src/VirtualServer.h b/server/src/VirtualServer.h index f7c13a4..690cc61 100644 --- a/server/src/VirtualServer.h +++ b/server/src/VirtualServer.h @@ -21,6 +21,7 @@ #include "manager/LetterManager.h" #include "Configuration.h" #include "protocol/ringbuffer.h" +#include #include #undef byte @@ -302,6 +303,8 @@ namespace ts { //Locks by tick, start and stop threads::Mutex stateLock; ServerState::value state = ServerState::OFFLINE; + + task_id tick_task_id{}; std::chrono::system_clock::time_point lastTick; void executeServerTick(); diff --git a/server/src/client/ConnectedClient.cpp b/server/src/client/ConnectedClient.cpp index f1c9966..4e4ebb9 100644 --- a/server/src/client/ConnectedClient.cpp +++ b/server/src/client/ConnectedClient.cpp @@ -10,10 +10,7 @@ #include "src/VirtualServer.h" #include "voice/VoiceClient.h" -#include "../server/VoiceServer.h" #include "../InstanceHandler.h" -#include "ConnectedClient.h" - #include using namespace std; @@ -44,7 +41,18 @@ void ConnectedClient::initialize_weak_reference(const std::shared_ptrtask_update_needed_permissions = multi_shot_task{serverInstance->general_task_executor(), "update permissions for " + this->getLoggingPeerIp(), [weak_self]{ auto self = weak_self.lock(); if(self) { - self->update_client_needed_permissions(); + auto permissions_changed = self->update_client_needed_permissions(); + logTrace(self->getServerId(), "{} Updated client permissions. Permissions changed: {}", CLIENT_STR_LOG_PREFIX_(self), permissions_changed); + if(permissions_changed) { + self->sendNeededPermissions(true); + } + } + }}; + + this->task_update_channel_client_properties = multi_shot_task{serverInstance->general_task_executor(), "update channel properties for " + this->getLoggingPeerIp(), [weak_self]{ + auto self = weak_self.lock(); + if(self) { + self->updateChannelClientProperties(true, true); } }}; } @@ -102,98 +110,98 @@ std::shared_ptr ConnectedClient::request_connection_info(con return info.data; } -//Attention the client should be only read only locked! void ConnectedClient::updateChannelClientProperties(bool lock_channel_tree, bool notify_self) { - /* this->server may be null! */ - shared_ptr server_ref = this->server; + /* The server and the current channel might change while executing this method! */ + auto server_ref = this->server; + auto channel = this->currentChannel; auto permissions = this->calculate_permissions({ permission::i_client_talk_power, permission::b_client_ignore_antiflood, permission::i_channel_view_power, - permission::b_channel_ignore_view_power - }, this->currentChannel ? this->currentChannel->channelId() : 0); + permission::b_channel_ignore_view_power, + permission::i_icon_id, + permission::b_client_is_priority_speaker, + }, channel ? channel->channelId() : 0); permission::v2::PermissionFlaggedValue permission_talk_power{0, false}, permission_ignore_antiflood{0, false}, permission_channel_view_power{0, false}, - permission_channel_ignore_view_power{0, false}; + permission_channel_ignore_view_power{0, false}, + permission_icon_id{0, false}, + permission_client_is_priority_speaker{0, false}; + for(const auto& perm : permissions) { - if(perm.first == permission::i_client_talk_power) + if(perm.first == permission::i_client_talk_power) { permission_talk_power = perm.second; - else if(perm.first == permission::b_client_ignore_antiflood) + } else if(perm.first == permission::b_client_ignore_antiflood) { permission_ignore_antiflood = perm.second; - else if(perm.first == permission::i_channel_view_power) + } else if(perm.first == permission::i_channel_view_power) { permission_channel_view_power = perm.second; - else if(perm.first == permission::b_channel_ignore_view_power) + } else if(perm.first == permission::b_channel_ignore_view_power) { permission_channel_ignore_view_power = perm.second; - else sassert(false); + } else if(perm.first == permission::i_icon_id) { + permission_icon_id = perm.second; + } else if(perm.first == permission::b_client_is_priority_speaker) { + permission_client_is_priority_speaker = perm.second; + } else { + sassert(false); + } } - deque notifyList; - debugMessage(this->getServerId(), "{} Got a channel talk power of {} Talk power set is {}", CLIENT_STR_LOG_PREFIX, permission_talk_power.has_value ? permission_talk_power.value : 0, this->properties()[property::CLIENT_TALK_POWER].as()); - if((permission_talk_power.has_value ? permission_talk_power.value : 0) != this->properties()[property::CLIENT_TALK_POWER].as()) { //We do not have to update tp if there's no channel - this->properties()[property::CLIENT_TALK_POWER] = (permission_talk_power.has_value ? permission_talk_power.value : 0); - notifyList.emplace_back(property::CLIENT_TALK_POWER); + std::deque updated_client_properties; + { + auto old_talk_power = this->properties()[property::CLIENT_TALK_POWER].as_save(); + auto new_talk_power = permission_talk_power.has_value ? permission_talk_power.value : 0; - auto update = this->properties()[property::CLIENT_IS_TALKER].as() || this->properties()[property::CLIENT_TALK_REQUEST].as() > 0; - if(update && this->currentChannel) { - if(this->currentChannel->talk_power_granted(permission_talk_power)) { - this->properties()[property::CLIENT_IS_TALKER] = 0; - this->properties()[property::CLIENT_TALK_REQUEST] = 0; - this->properties()[property::CLIENT_TALK_REQUEST_MSG] = ""; - notifyList.emplace_back(property::CLIENT_IS_TALKER); - notifyList.emplace_back(property::CLIENT_TALK_REQUEST); - notifyList.emplace_back(property::CLIENT_TALK_REQUEST_MSG); + debugMessage(this->getServerId(), "{} Recalculated talk power. New value: {} Old value: {}", CLIENT_STR_LOG_PREFIX, new_talk_power, old_talk_power); + if(old_talk_power != new_talk_power) { + this->properties()[property::CLIENT_TALK_POWER] = new_talk_power; + updated_client_properties.emplace_back(property::CLIENT_TALK_POWER); + + auto retract_request = this->properties()[property::CLIENT_IS_TALKER].as(); + if(!retract_request && channel) { + retract_request = channel->talk_power_granted(permission_talk_power); + } + + if(retract_request) { + if(this->properties()[property::CLIENT_IS_TALKER].update_value(0)) { + updated_client_properties.emplace_back(property::CLIENT_IS_TALKER); + } + + if(this->properties()[property::CLIENT_TALK_REQUEST].update_value(0)) { + updated_client_properties.emplace_back(property::CLIENT_TALK_REQUEST); + } + + if(this->properties()[property::CLIENT_TALK_REQUEST_MSG].update_value("")) { + updated_client_properties.emplace_back(property::CLIENT_TALK_REQUEST_MSG); + } } } } - IconId iconId = 0; - auto local_permissions = this->clientPermissions; - if(local_permissions) { - permission::v2::PermissionFlaggedValue value{0, false}; - auto permission_flags = local_permissions->permission_flags(permission::i_icon_id); - if(permission_flags.channel_specific && this->currentChannel) { - auto val = local_permissions->channel_permission(permission::i_icon_id, this->currentChannel->channelId()); - value = {val.values.value, val.flags.value_set}; - } - if(!value.has_value) - value = local_permissions->permission_value_flagged(permission::i_icon_id); - if(value.has_value) - iconId = value.value; - } - logTrace(this->getServerId(), "[CLIENT] Updating client icon from " + to_string(this->properties()[property::CLIENT_ICON_ID].as()) + " to " + to_string(iconId)); - if(this->properties()[property::CLIENT_ICON_ID].as() != iconId) { -#if 0 - if(server_ref && iconId != 0) { - auto dir = serverInstance->getFileServer()->iconDirectory(server_ref); - if(!serverInstance->getFileServer()->iconExists(server_ref, iconId)) { - logMessage(this->getServerId(), "[FILE] Missing client icon (" + to_string(iconId) + ")."); - iconId = 0; - } - } -#endif - if(this->properties()[property::CLIENT_ICON_ID].as() != iconId) { - this->properties()[property::CLIENT_ICON_ID] = (IconId) iconId; - notifyList.emplace_back(property::CLIENT_ICON_ID); + { + IconId current_icon_id = this->properties()[property::CLIENT_ICON_ID].as_save(); + IconId new_icon_id{permission_icon_id.has_value ? (IconId) permission_icon_id.value : 0}; + if(this->properties()[property::CLIENT_ICON_ID].update_value(new_icon_id)) { + logTrace(this->getServerId(), "{} Updating client icon from {} to {}", CLIENT_STR_LOG_PREFIX, current_icon_id, new_icon_id); + updated_client_properties.emplace_back(property::CLIENT_ICON_ID); } } - auto pSpeaker = this->clientPermissions ? this->clientPermissions->channel_permission(permission::b_client_is_priority_speaker, this->getChannelId()) : permission::v2::empty_channel_permission; - auto pSpeakerGranted = permission::v2::permission_granted(1, {pSpeaker.values.value, pSpeaker.flags.value_set}); - if(properties()[property::CLIENT_IS_PRIORITY_SPEAKER].as() != pSpeakerGranted){ - properties()[property::CLIENT_IS_PRIORITY_SPEAKER] = pSpeakerGranted; - notifyList.emplace_back(property::CLIENT_IS_PRIORITY_SPEAKER); + auto pSpeakerGranted = permission::v2::permission_granted(1, permission_client_is_priority_speaker); + if(properties()[property::CLIENT_IS_PRIORITY_SPEAKER].update_value(pSpeakerGranted)){ + updated_client_properties.emplace_back(property::CLIENT_IS_PRIORITY_SPEAKER); } block_flood = !permission::v2::permission_granted(1, permission_ignore_antiflood); - if(server_ref) - server_ref->notifyClientPropertyUpdates(this->ref(), notifyList, notify_self); - this->updateTalkRights(permission_talk_power); + if(server_ref) { + server_ref->notifyClientPropertyUpdates(this->ref(), updated_client_properties, notify_self); + } - if((this->channels_view_power != permission_channel_view_power || this->channels_ignore_view != permission_channel_ignore_view_power) && notify_self && this->currentChannel && server_ref) { + this->updateTalkRights(permission_talk_power); + if((this->channels_view_power != permission_channel_view_power || this->channels_ignore_view != permission_channel_ignore_view_power) && notify_self && channel && server_ref) { this->channels_view_power = permission_channel_view_power; this->channels_ignore_view = permission_channel_ignore_view_power; @@ -207,9 +215,9 @@ void ConnectedClient::updateChannelClientProperties(bool lock_channel_tree, bool } /* might have been changed since we locked the tree */ - if(this->currentChannel) { + if(channel) { deque deleted; - for(const auto& update_entry : this->channels->update_channel_path(server_ref->channelTree->tree_head(), server_ref->channelTree->find_linked_entry(this->currentChannel->channelId()))) { + for(const auto& update_entry : this->channels->update_channel_path(server_ref->channelTree->tree_head(), server_ref->channelTree->find_linked_entry(channel->channelId()))) { if(update_entry.first) { this->notifyChannelShow(update_entry.second->channel(), update_entry.second->previous_channel); } else { @@ -226,8 +234,10 @@ void ConnectedClient::updateChannelClientProperties(bool lock_channel_tree, bool void ConnectedClient::updateTalkRights(permission::v2::PermissionFlaggedValue talk_power) { bool flag = false; flag |= this->properties()[property::CLIENT_IS_TALKER].as(); - if(!flag && this->currentChannel) { - flag = this->currentChannel->talk_power_granted(talk_power); + + auto current_channel = this->currentChannel; + if(!flag && current_channel) { + flag = current_channel->talk_power_granted(talk_power); } this->allowedToTalk = flag; } @@ -937,10 +947,11 @@ std::shared_ptr ConnectedClient::resolveActiveBan(const std::string& } bool ConnectedClient::update_client_needed_permissions() { - auto values = this->calculate_permissions(permission::neededPermissions, this->currentChannel? this->currentChannel->channelId() : 0); /* copy the channel here so it does not change */ + /* The server and/or the channel might change while we're executing this method */ + auto currentChannel = this->currentChannel; + auto values = this->calculate_permissions(permission::neededPermissions, currentChannel ? currentChannel->channelId() : 0); auto updated = false; - { lock_guard cached_lock(this->client_needed_permissions_lock); diff --git a/server/src/client/ConnectedClient.h b/server/src/client/ConnectedClient.h index 0543a2e..30654fa 100644 --- a/server/src/client/ConnectedClient.h +++ b/server/src/client/ConnectedClient.h @@ -263,7 +263,6 @@ namespace ts { virtual bool ignoresFlood() { return !this->block_flood; } std::shared_ptr request_connection_info(const std::shared_ptr & /* receiver */, bool& /* send temporary (no client response yet) */); - virtual void updateChannelClientProperties(bool /* lock channel tree */, bool /* notify our self */); void updateTalkRights(permission::v2::PermissionFlaggedValue talk_power); virtual std::shared_ptr resolveActiveBan(const std::string& ip_address); @@ -283,9 +282,20 @@ namespace ts { [[nodiscard]] inline std::vector& current_server_groups() { return this->cached_server_groups; } [[nodiscard]] inline GroupId& current_channel_group() { return this->cached_channel_group; } + /** + * Attention: This method should never be called directly (except in some edge cases)! + * Use `task_update_channel_client_properties` instead to schedule an update. + */ + virtual void updateChannelClientProperties(bool /* lock channel tree */, bool /* notify our self */); + /* * permission stuff */ + /** + * Attention: This method should never be called directly! + * Use `task_update_needed_permissions` instead to schedule an update. + * @returns `true` is a permission updated happened. + */ bool update_client_needed_permissions(); std::shared_lock require_connected_state(bool blocking = false) { @@ -383,6 +393,7 @@ namespace ts { std::weak_ptr subscribed_playlist_{}; multi_shot_task task_update_needed_permissions{}; + multi_shot_task task_update_channel_client_properties{}; bool loadDataForCurrentServer() override; diff --git a/server/src/client/ConnectedClientTextCommandHandler.cpp b/server/src/client/ConnectedClientTextCommandHandler.cpp index c68b128..4bd4264 100644 --- a/server/src/client/ConnectedClientTextCommandHandler.cpp +++ b/server/src/client/ConnectedClientTextCommandHandler.cpp @@ -36,18 +36,18 @@ do { \ return true; \ } while(false) -#define TLEN(index) if(arguments.size() < index) ERR(serverInstance->musicRoot(), "Invalid argument count"); +#define TLEN(index) if(arguments.size() < index) ERR(music_root, "Invalid argument count"); #define TARG(index, type) (arguments.size() > index && arguments[index] == type) -#define TMUSIC(bot) if(!bot->current_player()) ERR(serverInstance->musicRoot(), "Im not playing a song!"); +#define TMUSIC(bot) if(!bot->current_player()) ERR(music_root, "Im not playing a song!"); #define GBOT(var, ignore_disabled) \ auto var = this->selectedBot.lock(); \ if(!var) var = dynamic_pointer_cast(target); \ if(!var) { \ - send_message(serverInstance->musicRoot(), "Please select a music bot! (" + ts::config::music::command_prefix + "mbot select )"); \ + send_message(music_root, "Please select a music bot! (" + ts::config::music::command_prefix + "mbot select )"); \ return true; \ } \ if(!ignore_disabled && var->properties()[property::CLIENT_DISABLED].as()) { \ - send_message(serverInstance->musicRoot(), strobf("This bot has been disabled. Upgrade your TeaSpeak license to use more bots.").string()); \ + send_message(music_root, strobf("This bot has been disabled. Upgrade your TeaSpeak license to use more bots.").string()); \ return true; \ } @@ -100,20 +100,20 @@ bool ConnectedClient::handleTextMessage(ChatMessageMode mode, std::string text, #define PERM_CHECK_BOT(perm, reqperm, err) \ if(bot->properties()[property::CLIENT_OWNER] != this->getClientDatabaseId() && \ !permission::v2::permission_granted(bot->calculate_permission(permission::reqperm, bot->getChannelId()), this->calculate_permission(permission::perm, bot->getChannelId()))) { \ - send_message(serverInstance->musicRoot(), err); \ + send_message(music_root, err); \ return true; \ } //TODO: Correct error message print! #define HANDLE_CMD_ERROR(_message) \ - send_message(serverInstance->musicRoot(), string(_message) + ": action failed"); + send_message(music_root, string(_message) + ": action failed"); /* if(result.extraProperties.count("extra_msg") > 0) \ - send_message(serverInstance->musicRoot(), string(_message) + ": " + result.extraProperties["extra_msg"]); \ + send_message(music_root, string(_message) + ": " + result.extraProperties["extra_msg"]); \ else if(result.extraProperties.count("failed_permid") > 0) \ - send_message(serverInstance->musicRoot(), string(_message) + ". (Missing permission " + permission::resolvePermissionData((permission::PermissionType) stoull(result.extraProperties["failed_permid"]))->name + ")"); \ + send_message(music_root, string(_message) + ". (Missing permission " + permission::resolvePermissionData((permission::PermissionType) stoull(result.extraProperties["failed_permid"]))->name + ")"); \ else \ - send_message(serverInstance->musicRoot(), string(_message) + ": " + result.error.message); + send_message(music_root, string(_message) + ": " + result.error.message); */ #define JOIN_ARGS(variable, index) \ @@ -150,9 +150,10 @@ bool ConnectedClient::handle_text_command( const function &, const string &)> &send_message, const shared_ptr& target) { + auto music_root = dynamic_pointer_cast(serverInstance->musicRoot()); if (command == "mbot") { if(!config::music::enabled) { - send_message(serverInstance->musicRoot(), "Music bots are not enabled! Enable them via the server config!"); + send_message(music_root, "Music bots are not enabled! Enable them via the server config!"); return true; } if (TARG(0, "create")) { @@ -163,7 +164,7 @@ bool ConnectedClient::handle_text_command( HANDLE_CMD_ERROR("Failed to create music bot"); return true; } - send_message(serverInstance->musicRoot(), "Bot created"); + send_message(music_root, "Bot created"); return true; } else if (TARG(0, "list")) { bool server = false; @@ -172,19 +173,19 @@ bool ConnectedClient::handle_text_command( string locationStr = server ? "on this server" : "in this channel"; if(!permission::v2::permission_granted(1, this->calculate_permission(server ? permission::b_client_music_server_list : permission::b_client_music_channel_list, this->getChannelId()))) { - send_message(serverInstance->musicRoot(), "You don't have the permission to list all music bots " + locationStr); + send_message(music_root, "You don't have the permission to list all music bots " + locationStr); return true; } auto mbots = this->server->getClientsByChannel(server ? nullptr : this->currentChannel); if (mbots.empty()) - send_message(serverInstance->musicRoot(), "There are no music bots " + locationStr); + send_message(music_root, "There are no music bots " + locationStr); else { - send_message(serverInstance->musicRoot(), "There are " + to_string(mbots.size()) + " music bots " + locationStr + ":"); + send_message(music_root, "There are " + to_string(mbots.size()) + " music bots " + locationStr + ":"); for (const auto &mbot : mbots) { if(mbot->properties()[property::CLIENT_DISABLED].as()) { - send_message(serverInstance->musicRoot(), " - [color=red]" + to_string(mbot->getClientDatabaseId()) + " | " + mbot->getDisplayName() + " [DISABLED][/color]"); + send_message(music_root, " - [color=red]" + to_string(mbot->getClientDatabaseId()) + " | " + mbot->getDisplayName() + " [DISABLED][/color]"); } else { - send_message(serverInstance->musicRoot(), " - [color=green]" + to_string(mbot->getClientDatabaseId()) + " | " + mbot->getDisplayName() + "[/color]"); + send_message(music_root, " - [color=green]" + to_string(mbot->getClientDatabaseId()) + " | " + mbot->getDisplayName() + "[/color]"); } } } @@ -192,21 +193,21 @@ bool ConnectedClient::handle_text_command( } else if (TARG(0, "select")) { TLEN(2); if(arguments[1].find_first_not_of("0123456789") != std::string::npos) { - send_message(serverInstance->musicRoot(), "Invalid bot id"); + send_message(music_root, "Invalid bot id"); return true; } auto botId = static_cast(stoll(arguments[1])); auto bot = this->server->music_manager_->findBotById(botId); - if (!bot) ERR(serverInstance->musicRoot(), "Could not find target bot"); + if (!bot) ERR(music_root, "Could not find target bot"); if(bot->properties()[property::CLIENT_OWNER] != this->getClientDatabaseId() && !permission::v2::permission_granted(1, this->calculate_permission(permission::b_client_music_channel_list, this->getChannelId())) && !permission::v2::permission_granted(1, this->calculate_permission(permission::b_client_music_server_list, this->getChannelId()))) { //No perms for listing - send_message(serverInstance->musicRoot(), "You don't have the permission to select a music bot"); + send_message(music_root, "You don't have the permission to select a music bot"); return true; } this->selectedBot = bot; - send_message(serverInstance->musicRoot(), "You successfully select the bot " + to_string(botId) + " | " + bot->getDisplayName()); + send_message(music_root, "You successfully select the bot " + to_string(botId) + " | " + bot->getDisplayName()); return true; } else if (TARG(0, "rename")) { TLEN(2); @@ -225,7 +226,7 @@ bool ConnectedClient::handle_text_command( result.release_data(); return true; } - send_message(serverInstance->musicRoot(), "Name successfully changed!"); + send_message(music_root, "Name successfully changed!"); return true; } else if (TARG(0, "delete")) { GBOT(bot, true); @@ -460,7 +461,7 @@ bool ConnectedClient::handle_text_command( for(const auto& fmt : prots) ss << " - " << fmt << endl; } - send_message(serverInstance->musicRoot(), ss.str()); + send_message(music_root, ss.str()); return true; } else if(TARG(0, "settings")) { GBOT(bot, false); @@ -513,7 +514,7 @@ bool ConnectedClient::handle_text_command( result.release_data(); return true; } - send_message(serverInstance->musicRoot(), "Property successfully changed!"); + send_message(music_root, "Property successfully changed!"); return true; } @@ -566,7 +567,7 @@ bool ConnectedClient::handle_text_command( return true; } } else if (command == "help") { - //send_message(serverInstance->musicRoot(), " ̶.̶̶m̶̶b̶̶o̶̶t̶̶ ̶̶f̶̶o̶̶r̶̶m̶̶a̶̶t̶̶s (Not supported yet)"); + //send_message(music_root, " ̶.̶̶m̶̶b̶̶o̶̶t̶̶ ̶̶f̶̶o̶̶r̶̶m̶̶a̶̶t̶̶s (Not supported yet)"); stringstream ss; ss << "Available music bot commands: ([color=green]green[/color] = permission granted | [color=red]red[/color] = insufficient permissions)" << endl; @@ -597,7 +598,7 @@ bool ConnectedClient::handle_text_command( permissionableCommand(this, ss, " " + ts::config::music::command_prefix + "mbot ", permission::i_client_music_play_power); permissionableCommand(this, ss, " " + ts::config::music::command_prefix + "mbot settings [name] [value]", permission::i_client_music_modify_power); - send_message(serverInstance->musicRoot(), ss.str()); + send_message(music_root, ss.str()); return true; } else if (command == "dummy") { if(TARG(0, "timerevent")) { @@ -772,8 +773,8 @@ bool ConnectedClient::handle_text_command( } } - send_message(serverInstance->musicRoot(), "Invalid channel command."); - send_message(serverInstance->musicRoot(), "Type " + ts::config::music::command_prefix + "help for a command overview"); + send_message(music_root, "Invalid channel command."); + send_message(music_root, "Type " + ts::config::music::command_prefix + "help for a command overview"); return false; } \ No newline at end of file diff --git a/server/src/client/DataClient.cpp b/server/src/client/DataClient.cpp index ab8599e..eb4333d 100644 --- a/server/src/client/DataClient.cpp +++ b/server/src/client/DataClient.cpp @@ -39,8 +39,9 @@ constexpr static std::string_view kClientLoadCommand{R"( bool DataClient::loadDataForCurrentServer() { auto uniqueId = this->getUid(); - if(uniqueId.empty()) + if(uniqueId.empty()) { return false; + } auto ref_server = this->server; auto server_id = ref_server ? ref_server->getServerId() : 0; @@ -100,8 +101,9 @@ bool DataClient::loadDataForCurrentServer() { } if(!ref_server) { - if(this->getType() == ClientType::CLIENT_WEB || this->getType() == ClientType::CLIENT_TEAMSPEAK) + if(this->getType() == ClientType::CLIENT_WEB || this->getType() == ClientType::CLIENT_TEAMSPEAK) { logCritical(LOG_INSTANCE, "Got a voice or web client, which is unbound to any server!"); + } return false; } @@ -129,8 +131,9 @@ bool DataClient::loadDataForCurrentServer() { } #endif - if(ref_server) + if(ref_server) { this->properties()[property::CLIENT_UNREAD_MESSAGES] = ref_server->letters->unread_letter_count(this->getUid()); + } return true; } @@ -140,20 +143,30 @@ std::vector cache) { - if(permissions.empty()) return {}; + if(permissions.empty()) { + return {}; + } - if(!cache) + if(!cache) { cache = std::make_shared(); - if(!cache->client_permissions) /* so we don't have to load that shit later */ + } + + if(!cache->client_permissions) { + /* so we don't have to load that shit later */ cache->client_permissions = this->clientPermissions; - if(channel == -1) - channel = this->currentChannel ? this->currentChannel->channelId() : 0; + } + + if(channel == -1) { + auto current_channel = this->currentChannel; + channel = current_channel ? current_channel->channelId() : 0; + } auto ref_server = this->server; - if(ref_server) + if(ref_server) { return ref_server->calculate_permissions(permissions, this->getClientDatabaseId(), this->getType(), channel, granted, cache); - else + } else { return serverInstance->calculate_permissions(permissions, this->getClientDatabaseId(), this->getType(), channel, granted, cache); + } } permission::v2::PermissionFlaggedValue DataClient::calculate_permission( diff --git a/server/src/client/DataClient.h b/server/src/client/DataClient.h index 2872187..f3e25d6 100644 --- a/server/src/client/DataClient.h +++ b/server/src/client/DataClient.h @@ -65,6 +65,14 @@ namespace ts { PropertyWrapper properties(){ return { this->_properties }; } /* main permission calculate function */ + /** + * Calculate the given permissions. + * This method can be called from everywhere without any locking needed. + * @param channel + * @param granted + * @param cache + * @return + */ permission::v2::PermissionFlaggedValue calculate_permission( permission::PermissionType, ChannelId channel, @@ -72,6 +80,14 @@ namespace ts { std::shared_ptr cache = nullptr ); + /** + * Calculate the given permissions. + * This method can be called from everywhere without any locking needed. + * @param channel + * @param granted + * @param cache + * @return + */ std::vector> calculate_permissions( const std::deque&, ChannelId channel, diff --git a/server/src/client/command_handler/channel.cpp b/server/src/client/command_handler/channel.cpp index 6b32fcc..8e32470 100644 --- a/server/src/client/command_handler/channel.cpp +++ b/server/src/client/command_handler/channel.cpp @@ -412,8 +412,7 @@ command_result ConnectedClient::handleCommandChannelGroupDel(Command &cmd) { if (this->server) { this->server->forEachClient([&](shared_ptr cl) { if (this->server->notifyClientPropertyUpdates(cl, this->server->groups->update_server_group_property(cl, true, cl->getChannel()))) { - if (cl->update_client_needed_permissions()) /* update cached calculated permissions */ - cl->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ + cl->task_update_needed_permissions.enqueue(); } cl->notifyChannelGroupList(); }); @@ -559,15 +558,12 @@ command_result ConnectedClient::handleCommandChannelGroupAddPerm(Command &cmd) { this->server->forEachClient([channelGroup](shared_ptr cl) { unique_lock client_channel_lock(cl->channel_lock); /* while we're updating groups we dont want to change anything! */ if (cl->channelGroupAssigned(channelGroup, cl->getChannel())) { - if (cl->update_client_needed_permissions()) { - cl->sendNeededPermissions(false); /* update the needed permissions */ - } + cl->task_update_needed_permissions.enqueue(); cl->join_state_id++; /* join permission may changed, all channels need to be recalculate dif needed */ } client_channel_lock.unlock(); - /* Must be outside of the lock since updateChannelClientProperties may causes client talk power updates */ - cl->updateChannelClientProperties(true, true); + cl->task_update_channel_client_properties.enqueue(); }); } @@ -609,14 +605,12 @@ command_result ConnectedClient::handleCommandChannelGroupDelPerm(Command &cmd) { this->server->forEachClient([channelGroup](shared_ptr cl) { unique_lock client_channel_lock(cl->channel_lock); /* while we're updating groups we dont want to change anything! */ if (cl->channelGroupAssigned(channelGroup, cl->getChannel())) { - if (cl->update_client_needed_permissions()) /* update cached calculated permissions */ - cl->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ + cl->task_update_needed_permissions.enqueue(); cl->join_state_id++; /* join permission may changed, all channels need to be recalculate dif needed */ } client_channel_lock.unlock(); - /* Must be outside of the lock since updateChannelClientProperties may causes client talk power updates */ - cl->updateChannelClientProperties(true, true); + cl->task_update_channel_client_properties.enqueue(); }); } @@ -1796,7 +1790,7 @@ ts::command_result ConnectedClient::execute_channel_edit(ChannelId& channel_id, /* we've to change the permission as well */ auto talk_power = converter::from_string_view(value); - channel->permissions()->set_permission(permission::i_client_talk_power, + channel->permissions()->set_permission(permission::i_client_needed_talk_power, { talk_power, talk_power }, permission::v2::PermissionUpdateType::set_value, permission::v2::PermissionUpdateType::do_nothing, @@ -1923,11 +1917,11 @@ ts::command_result ConnectedClient::execute_channel_edit(ChannelId& channel_id, } if(updating_talk_power) { - client->updateChannelClientProperties(false, true); + client->task_update_channel_client_properties.enqueue(); } } - /* Channel create was successfull. Release delete struct. */ + /* Channel create was successful. Release delete struct. */ temporary_created_channel.channel = nullptr; return command_result{error::ok}; }; @@ -2170,7 +2164,9 @@ command_result ConnectedClient::handleCommandChannelAddPerm(Command &cmd) { continue; } - return ts::command_result{error::channel_default_require_visible}; + if(ppermission.permission()->type == permission::i_channel_needed_view_power) { + return ts::command_result{error::channel_default_require_visible}; + } } } @@ -2198,7 +2194,7 @@ command_result ConnectedClient::handleCommandChannelAddPerm(Command &cmd) { if ((updateClients || update_join_permissions) && this->server) { this->server->forEachClient([&](std::shared_ptr cl) { if (updateClients && cl->currentChannel == channel) { - cl->updateChannelClientProperties(true, true); + cl->task_update_channel_client_properties.enqueue(); } if (update_join_permissions) { @@ -2247,7 +2243,7 @@ command_result ConnectedClient::handleCommandChannelDelPerm(Command &cmd) { if ((updateClients || update_join_permissions) && this->server) { this->server->forEachClient([&](std::shared_ptr cl) { if (updateClients && cl->currentChannel == channel) - cl->updateChannelClientProperties(true, true); + cl->task_update_channel_client_properties.enqueue(); if (update_join_permissions) cl->join_state_id++; }); @@ -2354,11 +2350,10 @@ command_result ConnectedClient::handleCommandChannelClientDelPerm(Command &cmd) auto onlineClients = this->server->findClientsByCldbId(cldbid); if (!onlineClients.empty()) { for (const auto &elm : onlineClients) { - if (elm->update_client_needed_permissions()) /* update cached calculated permissions */ - elm->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ + elm->task_update_needed_permissions.enqueue(); if (elm->currentChannel == channel) { - elm->updateChannelClientProperties(true, true); + elm->task_update_channel_client_properties.enqueue(); } else if (update_view) { unique_lock client_channel_lock(this->channel_lock); @@ -2423,11 +2418,10 @@ command_result ConnectedClient::handleCommandChannelClientAddPerm(Command &cmd) auto onlineClients = this->server->findClientsByCldbId(cldbid); if (!onlineClients.empty()) for (const auto &elm : onlineClients) { - if (elm->update_client_needed_permissions()) /* update cached calculated permissions */ - elm->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ + elm->task_update_needed_permissions.enqueue(); if (elm->currentChannel == channel) { - elm->updateChannelClientProperties(true, true); + elm->task_update_channel_client_properties.enqueue(); } else if (update_view) { unique_lock client_channel_lock(this->channel_lock); diff --git a/server/src/client/command_handler/client.cpp b/server/src/client/command_handler/client.cpp index 27091e2..d8e8ff1 100644 --- a/server/src/client/command_handler/client.cpp +++ b/server/src/client/command_handler/client.cpp @@ -976,10 +976,9 @@ command_result ConnectedClient::handleCommandClientAddPerm(Command &cmd) { auto onlineClients = this->server->findClientsByCldbId(cldbid); if (!onlineClients.empty()) for (const auto &elm : onlineClients) { - if(elm->update_client_needed_permissions()) /* update cached calculated permissions */ - elm->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ + elm->task_update_needed_permissions.enqueue(); if(update_channels) - elm->updateChannelClientProperties(true, true); + elm->task_update_channel_client_properties.enqueue(); elm->join_state_id++; /* join permission may changed, all channels need to be recalculate dif needed */ } @@ -1019,10 +1018,9 @@ command_result ConnectedClient::handleCommandClientDelPerm(Command &cmd) { auto onlineClients = this->server->findClientsByCldbId(cldbid); if (!onlineClients.empty()) for (const auto &elm : onlineClients) { - if(elm->update_client_needed_permissions()) /* update cached calculated permissions */ - elm->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ + elm->task_update_needed_permissions.enqueue(); if(update_channels) - elm->updateChannelClientProperties(true, true); + elm->task_update_channel_client_properties.enqueue(); elm->join_state_id++; /* join permission may changed, all channels need to be recalculate dif needed */ } diff --git a/server/src/client/command_handler/misc.cpp b/server/src/client/command_handler/misc.cpp index 25e3635..c474722 100644 --- a/server/src/client/command_handler/misc.cpp +++ b/server/src/client/command_handler/misc.cpp @@ -506,8 +506,7 @@ command_result ConnectedClient::handleCommandSetClientChannelGroup(Command &cmd) shared_lock client_channel_lock_r(targetClient->channel_lock); auto result = this->server->notifyClientPropertyUpdates(targetClient, updates); if (result) { - if(targetClient->update_client_needed_permissions()) /* update cached calculated permissions */ - targetClient->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ + targetClient->task_update_needed_permissions.enqueue(); if(targetClient->properties()[property::CLIENT_CHANNEL_GROUP_INHERITED_CHANNEL_ID] == channel->channelId()) { //Only if group assigned over the channel for (const auto &viewer : this->server->getClients()) { @@ -519,7 +518,8 @@ command_result ConnectedClient::handleCommandSetClientChannelGroup(Command &cmd) } } } - targetClient->updateChannelClientProperties(false, true); + + targetClient->task_update_channel_client_properties.enqueue(); } if(old_group) { @@ -1103,8 +1103,7 @@ command_result ConnectedClient::handleCommandTokenUse(Command &cmd) { } if (this->server->notifyClientPropertyUpdates(this->ref(), this->server->groups->update_server_group_property(this->ref(), true, this->getChannel()))) { - if(this->update_client_needed_permissions()) /* update cached calculated permissions */ - this->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ + this->task_update_needed_permissions.enqueue(); { for (auto &viewer : this->server->getClients()) { diff --git a/server/src/client/command_handler/server.cpp b/server/src/client/command_handler/server.cpp index dab5c9e..463e40d 100644 --- a/server/src/client/command_handler/server.cpp +++ b/server/src/client/command_handler/server.cpp @@ -238,8 +238,7 @@ command_result ConnectedClient::handleCommandServerEdit(Command &cmd) { if (group_update) target_server->forEachClient([&](const shared_ptr& client) { if(target_server->notifyClientPropertyUpdates(client, target_server->groups->update_server_group_property(client, true, client->getChannel()))) { - if(client->update_client_needed_permissions()) /* update cached calculated permissions */ - client->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ + client->task_update_needed_permissions.enqueue(); } }); @@ -579,8 +578,7 @@ command_result ConnectedClient::handleCommandServerGroupDel(Command &cmd) { if(this->server) this->server->forEachClient([&](shared_ptr cl) { if(this->server->notifyClientPropertyUpdates(cl, this->server->groups->update_server_group_property(cl, true, cl->getChannel()))) { - if(cl->update_client_needed_permissions()) /* update cached calculated permissions */ - cl->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ + cl->task_update_needed_permissions.enqueue(); } cl->notifyServerGroupList(); }); @@ -729,9 +727,8 @@ command_result ConnectedClient::handleCommandServerGroupAddClient(Command &cmd) for(const auto& group : applied_groups) client->notifyServerGroupClientAdd(this->ref(), targetClient, group); } - if(targetClient->update_client_needed_permissions()) /* update cached calculated permissions */ - targetClient->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ - targetClient->updateChannelClientProperties(true, true); + targetClient->task_update_needed_permissions.enqueue(); + targetClient->task_update_channel_client_properties.enqueue(); } } } @@ -868,9 +865,8 @@ command_result ConnectedClient::handleCommandServerGroupDelClient(Command &cmd) for(const auto& group : applied_groups) client->notifyServerGroupClientRemove(this->ref(), targetClient, group); } - if(targetClient->update_client_needed_permissions()) /* update cached calculated permissions */ - targetClient->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ - targetClient->updateChannelClientProperties(true, true); + targetClient->task_update_needed_permissions.enqueue(); + targetClient->task_update_channel_client_properties.enqueue(); } } } @@ -954,10 +950,9 @@ command_result ConnectedClient::handleCommandServerGroupAddPerm(Command &cmd) { }); server->forEachClient([serverGroup, update_talk_power](shared_ptr cl) { if (cl->serverGroupAssigned(serverGroup)) { - if(cl->update_client_needed_permissions()) /* update cached calculated permissions */ - cl->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ + cl->task_update_needed_permissions.enqueue(); if (update_talk_power) - cl->updateChannelClientProperties(true, true); + cl->task_update_channel_client_properties.enqueue(); cl->join_state_id++; /* join permission may changed, all channels need to be recalculate dif needed */ } }); @@ -1019,10 +1014,9 @@ command_result ConnectedClient::handleCommandServerGroupDelPerm(Command &cmd) { server->forEachClient([serverGroup, update_talk_power](shared_ptr cl) { if (cl->serverGroupAssigned(serverGroup)) { - if(cl->update_client_needed_permissions()) /* update cached calculated permissions */ - cl->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ + cl->task_update_needed_permissions.enqueue(); if (update_talk_power) - cl->updateChannelClientProperties(true, true); + cl->task_update_channel_client_properties.enqueue(); cl->join_state_id++; /* join permission may changed, all channels need to be recalculate dif needed */ } }); @@ -1095,11 +1089,9 @@ command_result ConnectedClient::handleCommandServerGroupAutoAddPerm(ts::Command& ref_server->forEachClient([groups, update_clients](shared_ptr cl) { for(const auto& serverGroup : groups) { if (cl->serverGroupAssigned(serverGroup)) { - if(cl->update_client_needed_permissions()) {/* update cached calculated permissions */ - cl->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ - } + cl->task_update_needed_permissions.enqueue(); if (update_clients) { - cl->updateChannelClientProperties(true, true); + cl->task_update_channel_client_properties.enqueue(); } cl->join_state_id++; /* join permission may changed, all channels need to be recalculate if needed */ break; @@ -1175,10 +1167,9 @@ command_result ConnectedClient::handleCommandServerGroupAutoDelPerm(ts::Command& ref_server->forEachClient([groups, update_clients](shared_ptr cl) { for(const auto& serverGroup : groups) { if (cl->serverGroupAssigned(serverGroup)) { - if(cl->update_client_needed_permissions()) /* update cached calculated permissions */ - cl->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ + cl->task_update_needed_permissions.enqueue(); if (update_clients) - cl->updateChannelClientProperties(true, true); + cl->task_update_channel_client_properties.enqueue(); cl->join_state_id++; /* join permission may changed, all channels need to be recalculate dif needed */ break; } diff --git a/server/src/client/query/QueryClient.cpp b/server/src/client/query/QueryClient.cpp index c641f9d..aa52eb8 100644 --- a/server/src/client/query/QueryClient.cpp +++ b/server/src/client/query/QueryClient.cpp @@ -154,7 +154,7 @@ void QueryClient::postInitialize() { } } - this->update_client_needed_permissions(); + this->task_update_needed_permissions.enqueue(); } void QueryClient::send_message(const std::string_view& message) { diff --git a/server/src/client/query/QueryClientCommands.cpp b/server/src/client/query/QueryClientCommands.cpp index 4072a9e..531c7a4 100644 --- a/server/src/client/query/QueryClientCommands.cpp +++ b/server/src/client/query/QueryClientCommands.cpp @@ -286,17 +286,18 @@ command_result QueryClient::handleCommandLogin(Command& cmd) { unique_lock tree_lock(this->server->channel_tree_lock); if(joined_channel) this->server->client_move(this->ref(), joined_channel, nullptr, "", ViewReasonId::VREASON_USER_ACTION, false, tree_lock); - } else if(!permission::v2::permission_granted(1, this->calculate_permission(permission::b_virtualserver_select_godmode, 1))) + } else if(!permission::v2::permission_granted(1, this->calculate_permission(permission::b_virtualserver_select_godmode, 1))) { this->server->assignDefaultChannel(this->ref(), true); - else - this->update_client_needed_permissions(); + } else { + this->task_update_needed_permissions.enqueue(); + } } else { serverInstance->getGroupManager()->enableCache(this->getClientDatabaseId()); - this->update_client_needed_permissions(); + this->task_update_needed_permissions.enqueue(); } this->properties()[property::CLIENT_TOTALCONNECTIONS]++; - this->updateChannelClientProperties(true, true); + this->task_update_channel_client_properties.enqueue(); serverInstance->action_logger()->query_authenticate_logger.log_query_authenticate(this->getServerId(), std::dynamic_pointer_cast(this->ref()), username, log::QueryAuthenticateResult::SUCCESS); return command_result{error::ok}; @@ -342,14 +343,14 @@ command_result QueryClient::handleCommandLogout(Command &) { } else if(!permission::v2::permission_granted(1, this->calculate_permission(permission::b_virtualserver_select_godmode, 1))) { this->server->assignDefaultChannel(this->ref(), true); } else { - this->update_client_needed_permissions(); + this->task_update_needed_permissions.enqueue(); } } else { serverInstance->getGroupManager()->enableCache(this->getClientDatabaseId()); - this->update_client_needed_permissions(); + this->task_update_needed_permissions.enqueue(); } - this->updateChannelClientProperties(true, true); + this->task_update_channel_client_properties.enqueue(); serverInstance->action_logger()->query_authenticate_logger.log_query_authenticate(this->getServerId(), std::dynamic_pointer_cast(this->ref()), "", log::QueryAuthenticateResult::SUCCESS); return command_result{error::ok}; @@ -412,15 +413,17 @@ command_result QueryClient::handleCommandServerSelect(Command &cmd) { } auto negated_enforce_join = permission::v2::permission_granted(1, this->calculate_permission(permission::b_virtualserver_select_godmode, 1)); - if(!negated_enforce_join) + if(!negated_enforce_join) { this->server->assignDefaultChannel(this->ref(), true); - else - this->update_client_needed_permissions(); + } else { + this->task_update_needed_permissions.enqueue(); + } } else { serverInstance->getGroupManager()->enableCache(this->getClientDatabaseId()); - this->update_client_needed_permissions(); + this->task_update_needed_permissions.enqueue(); } - this->updateChannelClientProperties(true, true); + + this->task_update_channel_client_properties.enqueue(); serverInstance->action_logger()->query_logger.log_query_switch(std::dynamic_pointer_cast(this->ref()), this->properties()[property::CLIENT_LOGIN_NAME].value(), old_server_id, this->getServerId()); return command_result{error::ok}; } diff --git a/shared b/shared index 84a08c4..6e99fc1 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit 84a08c469b5fada3b4e0c9a63fcfa19d8c7b10dd +Subproject commit 6e99fc1ab4934d1494c49bab83f47196deb6ad69