Using tasks instead of inlining certain client updates
This commit is contained in:
parent
71b2d734bd
commit
b40e1326cc
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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};
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
}
|
@ -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(
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
}
|
||||
|
||||
|
@ -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()) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
2
shared
@ -1 +1 @@
|
||||
Subproject commit 84a08c469b5fada3b4e0c9a63fcfa19d8c7b10dd
|
||||
Subproject commit 6e99fc1ab4934d1494c49bab83f47196deb6ad69
|
Loading…
x
Reference in New Issue
Block a user