Using tasks instead of inlining certain client updates

This commit is contained in:
WolverinDEV 2021-02-21 21:56:52 +01:00
parent 71b2d734bd
commit b40e1326cc
18 changed files with 265 additions and 221 deletions

View File

@ -72,12 +72,14 @@ void ConnectionStatistics::tick() {
this->total_statistics += current;
auto current_second = std::chrono::floor<std::chrono::seconds>(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;
}
}

View File

@ -53,7 +53,6 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql) {
logCritical(LOG_INSTANCE, "Instance task executor received exception: {}", message);
});
this->tick_manager = make_shared<threads::Scheduler>(config::threads::ticking, "tick task ");
this->statistics = make_shared<stats::ConnectionStatistics>(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<ts::server::InternalClient>(this->getSql(), nullptr, "serveradmin", true);
globalServerAdmin->initialize_weak_reference(this->globalServerAdmin);
this->globalServerAdmin = std::make_shared<ts::server::InternalClient>(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<InternalClient>(this->getSql(), nullptr, "Music Manager", false);
globalServerAdmin->initialize_weak_reference(this->_musicRoot);
dynamic_pointer_cast<InternalClient>(this->_musicRoot)->initialize_weak_reference(this->_musicRoot);
{
this->groupManager = std::make_shared<GroupManager>(nullptr, this->getSql());
@ -213,21 +212,6 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql) {
this->web_list = make_shared<weblist::WebListManager>();
}
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();

View File

@ -63,9 +63,6 @@ namespace ts {
std::chrono::time_point<std::chrono::system_clock> getStartTimestamp(){ return startTimestamp; }
void executeTick(VirtualServer*);
void cancelExecute(VirtualServer*);
bool reloadConfig(std::vector<std::string>& /* 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<stats::ConnectionStatistics> getStatistics(){ return statistics; }
std::shared_ptr<threads::Scheduler> scheduler(){ return this->tick_manager; }
std::shared_ptr<license::InstanceLicenseInfo> generateLicenseData();
std::shared_ptr<TeamSpeakLicense> 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::LicenseService> license_service_{nullptr};
std::shared_ptr<stats::ConnectionStatistics> statistics = nullptr;
std::shared_ptr<threads::Scheduler> tick_manager = nullptr;
std::shared_ptr<task_executor> general_task_executor_{nullptr};

View File

@ -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) {

View File

@ -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<bool>())
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 @@ vector<pair<ts::permission::PermissionType, ts::permission::v2::PermissionFlagge
bool skip_channel_permissions = channel_id == 0;
if(!skip_channel_permissions) {
/* look if somewhere is the skip permission flag set */
if(skip_permission_type == -1) /* initialize skip flag */
if(skip_permission_type == -1) {/* initialize skip flag */
calculate_skip();
}
skip_channel_permissions = have_skip_permission;
}
if(!skip_channel_permissions) {
@ -1213,10 +1225,9 @@ bool VirtualServer::resetPermissions(std::string& token) {
client->notifyChannelGroupList();
}
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;
}

View File

@ -21,6 +21,7 @@
#include "manager/LetterManager.h"
#include "Configuration.h"
#include "protocol/ringbuffer.h"
#include <misc/task_executor.h>
#include <tomcrypt.h>
#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();

View File

@ -10,10 +10,7 @@
#include "src/VirtualServer.h"
#include "voice/VoiceClient.h"
#include "../server/VoiceServer.h"
#include "../InstanceHandler.h"
#include "ConnectedClient.h"
#include <event.h>
using namespace std;
@ -44,7 +41,18 @@ void ConnectedClient::initialize_weak_reference(const std::shared_ptr<ConnectedC
this->task_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<ConnectionInfoData> 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<VirtualServer> 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<property::ClientProperties> 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<uint64_t>());
if((permission_talk_power.has_value ? permission_talk_power.value : 0) != this->properties()[property::CLIENT_TALK_POWER].as<uint64_t>()) { //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<property::ClientProperties> updated_client_properties;
{
auto old_talk_power = this->properties()[property::CLIENT_TALK_POWER].as_save<int64_t>();
auto new_talk_power = permission_talk_power.has_value ? permission_talk_power.value : 0;
auto update = this->properties()[property::CLIENT_IS_TALKER].as<bool>() || this->properties()[property::CLIENT_TALK_REQUEST].as<int64_t>() > 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<bool>();
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<IconId>()) + " to " + to_string(iconId));
if(this->properties()[property::CLIENT_ICON_ID].as<IconId>() != 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>() != 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>();
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<bool>() != 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<ChannelId> 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<bool>();
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<BanRecord> 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);

View File

@ -263,7 +263,6 @@ namespace ts {
virtual bool ignoresFlood() { return !this->block_flood; }
std::shared_ptr<ConnectionInfoData> request_connection_info(const std::shared_ptr<ConnectedClient> & /* 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<BanRecord> resolveActiveBan(const std::string& ip_address);
@ -283,9 +282,20 @@ namespace ts {
[[nodiscard]] inline std::vector<GroupId>& 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<std::shared_mutex> require_connected_state(bool blocking = false) {
@ -383,6 +393,7 @@ namespace ts {
std::weak_ptr<ts::music::Playlist> subscribed_playlist_{};
multi_shot_task task_update_needed_permissions{};
multi_shot_task task_update_channel_client_properties{};
bool loadDataForCurrentServer() override;

View File

@ -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<MusicClient>(target); \
if(!var) { \
send_message(serverInstance->musicRoot(), "Please select a music bot! (" + ts::config::music::command_prefix + "mbot select <id>)"); \
send_message(music_root, "Please select a music bot! (" + ts::config::music::command_prefix + "mbot select <id>)"); \
return true; \
} \
if(!ignore_disabled && var->properties()[property::CLIENT_DISABLED].as<bool>()) { \
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<void(const shared_ptr<ConnectedClient> &, const string &)> &send_message,
const shared_ptr<ConnectedClient>& target) {
auto music_root = dynamic_pointer_cast<ConnectedClient>(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<MusicClient>(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<bool>()) {
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<ClientDbId>(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 <playlist|pl>", permission::i_client_music_play_power);
permissionableCommand(this, ss, " " + ts::config::music::command_prefix + "mbot settings <playlist|bot> [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;
}

View File

@ -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<std::pair<permission::PermissionType, permission::v2::PermissionFlag
ChannelId channel,
bool granted,
std::shared_ptr<CalculateCache> cache) {
if(permissions.empty()) return {};
if(permissions.empty()) {
return {};
}
if(!cache)
if(!cache) {
cache = std::make_shared<CalculateCache>();
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(

View File

@ -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<CalculateCache> 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<std::pair<permission::PermissionType, permission::v2::PermissionFlaggedValue>> calculate_permissions(
const std::deque<permission::PermissionType>&,
ChannelId channel,

View File

@ -412,8 +412,7 @@ command_result ConnectedClient::handleCommandChannelGroupDel(Command &cmd) {
if (this->server) {
this->server->forEachClient([&](shared_ptr<ConnectedClient> 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<ConnectedClient> 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<ConnectedClient> 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<permission::PermissionValue>::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<ConnectedClient> 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<ConnectedClient> 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);

View File

@ -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 */
}

View File

@ -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()) {

View File

@ -238,8 +238,7 @@ command_result ConnectedClient::handleCommandServerEdit(Command &cmd) {
if (group_update)
target_server->forEachClient([&](const shared_ptr<ConnectedClient>& 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<ConnectedClient> 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<ConnectedClient> 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<ConnectedClient> 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<ConnectedClient> 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<ConnectedClient> 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;
}

View File

@ -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) {

View File

@ -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<QueryClient>(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<QueryClient>(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<QueryClient>(this->ref()), this->properties()[property::CLIENT_LOGIN_NAME].value(), old_server_id, this->getServerId());
return command_result{error::ok};
}

2
shared

@ -1 +1 @@
Subproject commit 84a08c469b5fada3b4e0c9a63fcfa19d8c7b10dd
Subproject commit 6e99fc1ab4934d1494c49bab83f47196deb6ad69