Replaces tab with 4 spaces

This commit is contained in:
WolverinDEV
2020-01-24 02:57:58 +01:00
parent b2199c8d56
commit a651eb879e
114 changed files with 22120 additions and 22120 deletions
+356 -356
View File
@@ -20,12 +20,12 @@ Group::Group(GroupManager* handle, GroupTarget target, GroupType type, GroupId g
this->handle = handle;
this->_properties = new Properties();
this->_properties->register_property_type<property::GroupProperties>();
this->setPermissionManager(make_shared<permission::v2::PermissionManager>());
this->_properties->register_property_type<property::GroupProperties>();
this->setPermissionManager(make_shared<permission::v2::PermissionManager>());
this->properties()[property::GROUP_ID] = groupId;
this->properties()[property::GROUP_TYPE] = type;
/*
this->properties()[property::GROUP_ID] = groupId;
this->properties()[property::GROUP_TYPE] = type;
/*
this->_properties->registerProperty("sgid", groupId, PROP_GROUP_INIT_SERVER);
this->_properties->registerProperty("cgid", groupId, PROP_GROUP_INIT_CHANNEL);
this->_properties->registerProperty("gid", groupId, PROP_PRIVATE_TEMP);
@@ -60,27 +60,27 @@ Group::Group(GroupManager* handle, GroupTarget target, GroupType type, GroupId g
}
void Group::setPermissionManager(const std::shared_ptr<permission::v2::PermissionManager> &manager) {
this->_permissions = manager;
this->apply_properties_from_permissions();
this->_permissions = manager;
this->apply_properties_from_permissions();
}
void Group::apply_properties_from_permissions() {
{
auto permission = this->_permissions->permission_value_flagged(permission::i_icon_id);
this->properties()[property::GROUP_ICONID] = permission.has_value ? permission.value : 0;
}
{
auto permission = this->_permissions->permission_value_flagged(permission::i_group_show_name_in_tree);
this->properties()[property::GROUP_NAMEMODE] = permission.has_value ? permission.value : 0;
}
{
auto permission = this->_permissions->permission_value_flagged(permission::i_group_sort_id);
this->properties()[property::GROUP_SORTID] = permission.has_value ? permission.value : 0;
}
{
auto permission = this->_permissions->permission_value_flagged(permission::b_group_is_permanent);
this->properties()[property::GROUP_SAVEDB] = permission.has_value ? permission.value : 0;
}
{
auto permission = this->_permissions->permission_value_flagged(permission::i_icon_id);
this->properties()[property::GROUP_ICONID] = permission.has_value ? permission.value : 0;
}
{
auto permission = this->_permissions->permission_value_flagged(permission::i_group_show_name_in_tree);
this->properties()[property::GROUP_NAMEMODE] = permission.has_value ? permission.value : 0;
}
{
auto permission = this->_permissions->permission_value_flagged(permission::i_group_sort_id);
this->properties()[property::GROUP_SORTID] = permission.has_value ? permission.value : 0;
}
{
auto permission = this->_permissions->permission_value_flagged(permission::b_group_is_permanent);
this->properties()[property::GROUP_SAVEDB] = permission.has_value ? permission.value : 0;
}
}
Group::~Group() {
@@ -115,41 +115,41 @@ bool GroupManager::loadGroupFormDatabase(GroupId id) {
}
std::vector<std::shared_ptr<Group>> GroupManager::availableGroups(bool root) {
std::vector<std::shared_ptr<Group>> response;
for(const auto& group : this->groups)
response.push_back(group);
if(root && this->root){
auto elm = this->root->availableGroups();
for(const auto& e : elm)
response.push_back(e);
}
return response;
std::vector<std::shared_ptr<Group>> response;
for(const auto& group : this->groups)
response.push_back(group);
if(root && this->root){
auto elm = this->root->availableGroups();
for(const auto& e : elm)
response.push_back(e);
}
return response;
}
std::vector<std::shared_ptr<Group>> GroupManager::availableServerGroups(bool root){
std::vector<std::shared_ptr<Group>> response;
for(const auto& group : this->groups)
if(group->target() == GroupTarget::GROUPTARGET_SERVER)
response.push_back(group);
if(root && this->root){
auto elm = this->root->availableServerGroups();
for(const auto& e : elm)
response.push_back(e);
}
return response;
std::vector<std::shared_ptr<Group>> response;
for(const auto& group : this->groups)
if(group->target() == GroupTarget::GROUPTARGET_SERVER)
response.push_back(group);
if(root && this->root){
auto elm = this->root->availableServerGroups();
for(const auto& e : elm)
response.push_back(e);
}
return response;
}
std::vector<std::shared_ptr<Group>> GroupManager::availableChannelGroups(bool root) {
std::vector<std::shared_ptr<Group>> response;
for(const auto& group : this->groups)
if(group->target() == GroupTarget::GROUPTARGET_CHANNEL)
response.push_back(group);
if(root && this->root){
auto elm = this->root->availableChannelGroups(true);
for(const auto& e : elm)
response.push_back(e);
}
return response;
std::vector<std::shared_ptr<Group>> response;
for(const auto& group : this->groups)
if(group->target() == GroupTarget::GROUPTARGET_CHANNEL)
response.push_back(group);
if(root && this->root){
auto elm = this->root->availableChannelGroups(true);
for(const auto& e : elm)
response.push_back(e);
}
return response;
}
int GroupManager::insertGroupFromDb(int count, char **values, char **column) {
@@ -194,11 +194,11 @@ int GroupManager::insertGroupFromDb(int count, char **values, char **column) {
else if(strcmp(columns[index], "value") == 0)
value = values[index];
auto info = property::info<property::GroupProperties>(key);
if(info == property::GROUP_UNDEFINED) {
logError(this->getServerId(), "Invalid property for group: " + key);
return 0;
}
auto info = property::info<property::GroupProperties>(key);
if(info == property::GROUP_UNDEFINED) {
logError(this->getServerId(), "Invalid property for group: " + key);
return 0;
}
auto prop = g->properties()[info.property];
prop.setDbReference(true);
@@ -226,14 +226,14 @@ int GroupManager::insertGroupFromDb(int count, char **values, char **column) {
}
void GroupManager::handleChannelDeleted(const ChannelId& channel_id) {
unique_lock cache_lock(this->cacheLock);
auto cached_clients = std::vector<shared_ptr<CachedClient>>{this->cachedClients.begin(), this->cachedClients.end()};
cache_lock.unlock();
unique_lock cache_lock(this->cacheLock);
auto cached_clients = std::vector<shared_ptr<CachedClient>>{this->cachedClients.begin(), this->cachedClients.end()};
cache_lock.unlock();
for(auto& entry : cached_clients) {
lock_guard entry_lock(entry->lock);
entry->channel_groups.erase(channel_id);
}
for(auto& entry : cached_clients) {
lock_guard entry_lock(entry->lock);
entry->channel_groups.erase(channel_id);
}
}
bool GroupManager::isLocalGroup(std::shared_ptr<Group> gr) {
@@ -241,16 +241,16 @@ bool GroupManager::isLocalGroup(std::shared_ptr<Group> gr) {
}
std::shared_ptr<Group> GroupManager::defaultGroup(GroupTarget type, bool enforce_property) {
threads::MutexLock lock(this->cacheLock);
threads::MutexLock lock(this->cacheLock);
if(this->groups.empty()) return nullptr;
auto server = this->server.lock();
auto id =
server ?
server->properties()[type == GroupTarget::GROUPTARGET_SERVER ? property::VIRTUALSERVER_DEFAULT_SERVER_GROUP : property::VIRTUALSERVER_DEFAULT_CHANNEL_GROUP].as_save<GroupId>() :
serverInstance->properties()[property::SERVERINSTANCE_GUEST_SERVERQUERY_GROUP].as_save<GroupId>();
auto group = this->findGroupLocal(id);
if(group || enforce_property) return group;
auto server = this->server.lock();
auto id =
server ?
server->properties()[type == GroupTarget::GROUPTARGET_SERVER ? property::VIRTUALSERVER_DEFAULT_SERVER_GROUP : property::VIRTUALSERVER_DEFAULT_CHANNEL_GROUP].as_save<GroupId>() :
serverInstance->properties()[property::SERVERINSTANCE_GUEST_SERVERQUERY_GROUP].as_save<GroupId>();
auto group = this->findGroupLocal(id);
if(group || enforce_property) return group;
for(auto elm : this->groups)
if(elm->target() == type)
@@ -261,14 +261,14 @@ std::shared_ptr<Group> GroupManager::defaultGroup(GroupTarget type, bool enforce
std::shared_ptr<Group> GroupManager::findGroup(GroupId groupId) {
auto result = this->findGroupLocal(groupId);
if(!result && this->root) result = this->root->findGroup(groupId);
if(!result && this->root) result = this->root->findGroup(groupId);
return result;
}
std::shared_ptr<Group> GroupManager::findGroupLocal(GroupId groupId) {
for(const auto& elm : this->groups)
if(elm->groupId() == groupId) return elm;
return nullptr;
for(const auto& elm : this->groups)
if(elm->groupId() == groupId) return elm;
return nullptr;
}
std::vector<std::shared_ptr<Group>> GroupManager::findGroup(GroupTarget target, std::string name) {
@@ -283,18 +283,18 @@ std::vector<std::shared_ptr<Group>> GroupManager::findGroup(GroupTarget target,
}
ServerId GroupManager::getServerId() {
auto l = this->server.lock();
return l ? l->getServerId() : 0;
auto l = this->server.lock();
return l ? l->getServerId() : 0;
}
std::shared_ptr<Group> GroupManager::createGroup(GroupTarget target, GroupType type, std::string name) {
if(type != GROUP_TYPE_NORMAL && this->root) return root->createGroup(target, type, name);
auto rawId = generateGroupId(this->sql);
if(rawId <= 0) {
logError(this->getServerId(), "Could not create a new group! ({})", "Could not generate group id");
return nullptr;
}
auto rawId = generateGroupId(this->sql);
if(rawId <= 0) {
logError(this->getServerId(), "Could not create a new group! ({})", "Could not generate group id");
return nullptr;
}
auto groupId = (GroupId) rawId;
auto res = sql::command(this->sql, "INSERT INTO `groups` (`serverId`, `groupId`, `target`, `type`, `displayName`) VALUES (:sid, :gid, :target, :type, :name)",
variable{":sid", this->getServerId()}, variable{":gid", groupId}, variable{":target", target}, variable{":type", type}, variable{":name", name}).execute();
@@ -310,7 +310,7 @@ std::shared_ptr<Group> GroupManager::createGroup(GroupTarget target, GroupType t
}
GroupId GroupManager::copyGroup(std::shared_ptr<Group> group, GroupType type, std::string name, ServerId targetServerId) {
auto group_server = group->handle->getServerId();
auto group_server = group->handle->getServerId();
auto groupId = generateGroupId(this->sql);
auto print = LOG_SQL_CMD;
@@ -327,26 +327,26 @@ GroupId GroupManager::copyGroup(std::shared_ptr<Group> group, GroupType type, st
variable{":sid", targetServerId}, variable{":gid", groupId}, variable{":target", group->target()}, variable{":type", type}, variable{":name", name}).execute();
print(res);
if(targetServerId == (this->getServerId()))
if(targetServerId == (this->getServerId()))
this->loadGroupFormDatabase(groupId);
else if(this->root)
this->root->loadGroupFormDatabase(groupId);
else if(this->root)
this->root->loadGroupFormDatabase(groupId);
return groupId;
}
bool GroupManager::copyGroupPermissions(const shared_ptr<Group> &source, const shared_ptr<Group> &target) {
auto targetServer = target->handle->getServerId();
auto sourceServer = source->handle->getServerId();
auto targetServer = target->handle->getServerId();
auto sourceServer = source->handle->getServerId();
auto res = sql::command(this->sql, "DELETE FROM `permissions` WHERE `serverId` = :sid AND `type` = :type AND `id` = :id", variable{":sid", targetServer}, variable{":type", SQL_PERM_GROUP}, variable{":id", target->groupId()}).execute();
LOG_SQL_CMD(res);
auto res = sql::command(this->sql, "DELETE FROM `permissions` WHERE `serverId` = :sid AND `type` = :type AND `id` = :id", variable{":sid", targetServer}, variable{":type", SQL_PERM_GROUP}, variable{":id", target->groupId()}).execute();
LOG_SQL_CMD(res);
res = sql::command(this->sql, "INSERT INTO `permissions` (`serverId`, `type`, `id`, `channelId`, `permId`, `value`, `grant`) SELECT :tsid AS `serverId`, `type`, :target AS `id`, 0 AS `channelId`, `permId`, `value`,`grant` FROM `permissions` WHERE `serverId` = :ssid AND `type` = :type AND `id` = :source",
variable{":ssid", sourceServer}, variable{":tsid", targetServer}, variable{":type", SQL_PERM_GROUP}, variable{":source", source->groupId()}, variable{":target", target->groupId()}).execute();
target->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(target->handle->server.lock(), target->groupId()));
target->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(target->handle->server.lock(), target->groupId()));
LOG_SQL_CMD(res);
return true;
return true;
}
bool GroupManager::reloadGroupPermissions(std::shared_ptr<Group> group) {
@@ -373,19 +373,19 @@ bool GroupManager::renameGroup(std::shared_ptr<Group> group, std::string name) {
}
bool GroupManager::deleteAllGroups() {
LOG_SQL_CMD(sql::command(this->sql, "DELETE FROM `groups` WHERE `serverId` = :sid", variable{":sid", this->getServerId()}).execute());
LOG_SQL_CMD(sql::command(this->sql, "DELETE FROM `assignedGroups` WHERE `serverId` = :sid", variable{":sid", this->getServerId()}).execute());
LOG_SQL_CMD(sql::command(this->sql, "DELETE FROM `permissions` WHERE `serverId` = :sid AND `type` = :type", variable{":sid", this->getServerId()}, variable{":type", SQL_PERM_GROUP}).execute());
{
lock_guard cache_lock(this->cacheLock);
for(const auto& entry : this->cachedClients) {
lock_guard entry_lock(entry->lock);
entry->server_groups.clear();
entry->channel_groups.clear();
}
}
this->groups.clear();
return true;
LOG_SQL_CMD(sql::command(this->sql, "DELETE FROM `groups` WHERE `serverId` = :sid", variable{":sid", this->getServerId()}).execute());
LOG_SQL_CMD(sql::command(this->sql, "DELETE FROM `assignedGroups` WHERE `serverId` = :sid", variable{":sid", this->getServerId()}).execute());
LOG_SQL_CMD(sql::command(this->sql, "DELETE FROM `permissions` WHERE `serverId` = :sid AND `type` = :type", variable{":sid", this->getServerId()}, variable{":type", SQL_PERM_GROUP}).execute());
{
lock_guard cache_lock(this->cacheLock);
for(const auto& entry : this->cachedClients) {
lock_guard entry_lock(entry->lock);
entry->server_groups.clear();
entry->channel_groups.clear();
}
}
this->groups.clear();
return true;
}
bool GroupManager::deleteGroup(std::shared_ptr<Group> group) {
@@ -397,42 +397,42 @@ bool GroupManager::deleteGroup(std::shared_ptr<Group> group) {
this->groups.erase(std::find(this->groups.begin(), this->groups.end(), group));
/* erase the group out of our cache */
{
lock_guard cache_lock(this->cacheLock);
for(auto& entry : this->cachedClients) {
lock_guard entry_lock(entry->lock);
{
lock_guard cache_lock(this->cacheLock);
for(auto& entry : this->cachedClients) {
lock_guard entry_lock(entry->lock);
entry->server_groups.erase(std::remove_if(entry->server_groups.begin(), entry->server_groups.end(), [&](const std::shared_ptr<GroupAssignment>& group_assignment) {
return group_assignment->group == group;
}), entry->server_groups.end());
entry->server_groups.erase(std::remove_if(entry->server_groups.begin(), entry->server_groups.end(), [&](const std::shared_ptr<GroupAssignment>& group_assignment) {
return group_assignment->group == group;
}), entry->server_groups.end());
for(auto it = entry->channel_groups.begin(); it != entry->channel_groups.end();) {
if(it->second->group == group)
it = entry->channel_groups.erase(it);
else
it++;
}
}
}
for(auto it = entry->channel_groups.begin(); it != entry->channel_groups.end();) {
if(it->second->group == group)
it = entry->channel_groups.erase(it);
else
it++;
}
}
}
bool flag_sql = false;
auto res = sql::command(this->sql, "DELETE FROM `groups` WHERE `serverId` = :sid AND `groupId` = :gid", variable{":sid", this->getServerId()}, variable{":gid", group->groupId()}).execute();
LOG_SQL_CMD(res);
flag_sql |= !res;
LOG_SQL_CMD(res);
flag_sql |= !res;
res = sql::command(this->sql, "DELETE FROM `assignedGroups` WHERE `serverId` = :sid AND `groupId` = :gid", variable{":sid", this->getServerId()}, variable{":gid", group->groupId()}).execute();
LOG_SQL_CMD(res);
flag_sql |= !res;
LOG_SQL_CMD(res);
flag_sql |= !res;
flag_sql &= serverInstance->databaseHelper()->deleteGroupPermissions(this->server.lock(), group->groupId());
if(flag_sql)
logError(this->getServerId(), "Could not delete group {} ({}) from database. May leader to invalid data", group->name(), group->groupId());
flag_sql &= serverInstance->databaseHelper()->deleteGroupPermissions(this->server.lock(), group->groupId());
if(flag_sql)
logError(this->getServerId(), "Could not delete group {} ({}) from database. May leader to invalid data", group->name(), group->groupId());
return true;
}
int64_t GroupManager::generateGroupId(sql::SqlManager* sql) {
int64_t hightestGroupId = 0;
int64_t hightestGroupId = 0;
sql::command(sql, "SELECT `groupId` FROM `groups` ORDER BY `groupId` DESC LIMIT 1").query([](int64_t* ptr, int, char** values, char**){
*ptr = stoul(values[0]);
return 0;
@@ -441,125 +441,125 @@ int64_t GroupManager::generateGroupId(sql::SqlManager* sql) {
}
std::deque<property::ClientProperties> GroupManager::update_server_group_property(const shared_ptr<server::ConnectedClient> &client, bool channel_lock, const std::shared_ptr<BasicChannel>& channel) {
std::deque<property::ClientProperties> changed;
std::deque<property::ClientProperties> changed;
//Server groups
{
auto groups = this->getServerGroups(client->getClientDatabaseId(), client->getType());
string group_string;
for(const auto& group : groups)
if(group_string.empty()) group_string += to_string(group->group->groupId());
else group_string += "," + to_string(group->group->groupId());
if(client->properties()[property::CLIENT_SERVERGROUPS] != group_string) {
client->properties()[property::CLIENT_SERVERGROUPS] = group_string;
changed.push_back(property::CLIENT_SERVERGROUPS);
//Server groups
{
auto groups = this->getServerGroups(client->getClientDatabaseId(), client->getType());
string group_string;
for(const auto& group : groups)
if(group_string.empty()) group_string += to_string(group->group->groupId());
else group_string += "," + to_string(group->group->groupId());
if(client->properties()[property::CLIENT_SERVERGROUPS] != group_string) {
client->properties()[property::CLIENT_SERVERGROUPS] = group_string;
changed.push_back(property::CLIENT_SERVERGROUPS);
unique_lock chan_lock(client->channel_lock, defer_lock);
if(channel_lock)
chan_lock.lock();
unique_lock chan_lock(client->channel_lock, defer_lock);
if(channel_lock)
chan_lock.lock();
client->cached_server_groups.clear();
client->cached_server_groups.reserve(groups.size());
for(const auto& group : groups)
client->cached_server_groups.push_back(group->group->groupId());
}
client->cached_server_groups.clear();
client->cached_server_groups.reserve(groups.size());
for(const auto& group : groups)
client->cached_server_groups.push_back(group->group->groupId());
}
}
}
//Channel groups
if(channel){
shared_ptr<GroupAssignment> group = this->getChannelGroup(client->getClientDatabaseId(), channel, true);
if(client->properties()[property::CLIENT_CHANNEL_GROUP_INHERITED_CHANNEL_ID] != group->channelId) {
client->properties()[property::CLIENT_CHANNEL_GROUP_INHERITED_CHANNEL_ID] = group->channelId;
changed.push_back(property::CLIENT_CHANNEL_GROUP_INHERITED_CHANNEL_ID);
}
if(client->properties()[property::CLIENT_CHANNEL_GROUP_ID] != group->group->groupId()) {
client->properties()[property::CLIENT_CHANNEL_GROUP_ID] = group->group->groupId();
changed.push_back(property::CLIENT_CHANNEL_GROUP_ID);
//Channel groups
if(channel){
shared_ptr<GroupAssignment> group = this->getChannelGroup(client->getClientDatabaseId(), channel, true);
if(client->properties()[property::CLIENT_CHANNEL_GROUP_INHERITED_CHANNEL_ID] != group->channelId) {
client->properties()[property::CLIENT_CHANNEL_GROUP_INHERITED_CHANNEL_ID] = group->channelId;
changed.push_back(property::CLIENT_CHANNEL_GROUP_INHERITED_CHANNEL_ID);
}
if(client->properties()[property::CLIENT_CHANNEL_GROUP_ID] != group->group->groupId()) {
client->properties()[property::CLIENT_CHANNEL_GROUP_ID] = group->group->groupId();
changed.push_back(property::CLIENT_CHANNEL_GROUP_ID);
unique_lock chan_lock(client->channel_lock, defer_lock);
if(channel_lock)
chan_lock.lock();
unique_lock chan_lock(client->channel_lock, defer_lock);
if(channel_lock)
chan_lock.lock();
client->cached_channel_group = group->group->groupId();
}
}
client->cached_channel_group = group->group->groupId();
}
}
if(!changed.empty())
client->join_state_id++; /* groups have changed :) */
if(!changed.empty())
client->join_state_id++; /* groups have changed :) */
return changed;
return changed;
}
void GroupManager::cleanupAssignments(ClientDbId client) {
if(this->root)
this->root->cleanupAssignments(client);
if(this->root)
this->root->cleanupAssignments(client);
for(const auto& assignment : this->getAssignedServerGroups(client)) {
if(!assignment->group->is_permanent())
this->removeServerGroup(client, assignment->group);
if(!assignment->group->is_permanent())
this->removeServerGroup(client, assignment->group);
}
}
void GroupManager::enableCache(const ClientDbId& client_database_id) {
if(this->root)
this->root->enableCache(client_database_id);
this->root->enableCache(client_database_id);
unique_lock cache_lock(this->cacheLock);
/* test if we're already having the client */
for(auto& entry : this->cachedClients)
if(entry->client_database_id == client_database_id) {
entry->use_count++;
return; /* client already cached, no need to cache client */
}
if(entry->client_database_id == client_database_id) {
entry->use_count++;
return; /* client already cached, no need to cache client */
}
auto entry = std::make_shared<CachedClient>();
entry->client_database_id = client_database_id;
entry->use_count++;
entry->use_count++;
this->cachedClients.push_back(entry);
lock_guard client_cache_lock(entry->lock); /* lock the client because we're currently loading the cache. */
cache_lock.unlock();
lock_guard client_cache_lock(entry->lock); /* lock the client because we're currently loading the cache. */
cache_lock.unlock();
auto res = sql::command(this->sql, "SELECT `groupId`, `channelId`, `until` FROM `assignedGroups` WHERE `serverId` = :sid AND `cldbid` = :cldbid", variable{":sid", this->getServerId()}, variable{":cldbid", client_database_id})
.query([&](int length, std::string* value, std::string* column) {
.query([&](int length, std::string* value, std::string* column) {
shared_ptr<Group> group = nullptr;
time_point<system_clock> until;
ChannelId channelId = 0;
for(int index = 0; index < length; index++){
try {
if(column[index] == "groupId"){
group = this->findGroup(stoll(value[index]));
} else if(column[index] == "until"){
until = time_point<system_clock>() + milliseconds(stoll(value[index]));
} else if(column[index] == "channelId"){
channelId = stoll(value[index]);
} else {
logError(this->getServerId(), "Unknown column in group assignment query: {}", column[index]);
continue;
}
if(column[index] == "groupId"){
group = this->findGroup(stoll(value[index]));
} else if(column[index] == "until"){
until = time_point<system_clock>() + milliseconds(stoll(value[index]));
} else if(column[index] == "channelId"){
channelId = stoll(value[index]);
} else {
logError(this->getServerId(), "Unknown column in group assignment query: {}", column[index]);
continue;
}
} catch(std::exception& ex) {
logError(this->getServerId(), "Failed to load group assignment from database for client {}. Column {} contains an invalid value: {}", client_database_id, column[index], value[index]);
return 0;
logError(this->getServerId(), "Failed to load group assignment from database for client {}. Column {} contains an invalid value: {}", client_database_id, column[index], value[index]);
return 0;
}
}
if(!group) {
return 0;
return 0;
}
auto assignment = std::make_shared<GroupAssignment>();
assignment->group = group;
assignment->until = until;
assignment->parent = &*entry;
assignment->channelId = channelId;
assignment->server = this->getServerId();
assignment->channelId = channelId;
assignment->server = this->getServerId();
if(channelId == 0)
entry->server_groups.push_back(assignment);
entry->server_groups.push_back(assignment);
else
entry->channel_groups[channelId] = assignment;
entry->channel_groups[channelId] = assignment;
return 0;
});
}
@@ -567,17 +567,17 @@ void GroupManager::enableCache(const ClientDbId& client_database_id) {
//FIXME: This method till get far more often then it should be. We should add a flag if the group cache is loaded for each std::shared_ptr<ConnectedClient> instance
void GroupManager::disableCache(const ClientDbId& client_database_id) {
if(this->root) {
this->root->disableCache(client_database_id);
this->root->disableCache(client_database_id);
}
lock_guard cache_lock(this->cacheLock);
this->cachedClients.erase(std::remove_if(this->cachedClients.begin(), this->cachedClients.end(), [&](const std::shared_ptr<CachedClient>& client) {
if(client->client_database_id != client_database_id)
return false;
lock_guard cache_lock(this->cacheLock);
this->cachedClients.erase(std::remove_if(this->cachedClients.begin(), this->cachedClients.end(), [&](const std::shared_ptr<CachedClient>& client) {
if(client->client_database_id != client_database_id)
return false;
lock_guard client_lock{client->lock};
return (--client->use_count) == 0;
}), this->cachedClients.end());
lock_guard client_lock{client->lock};
return (--client->use_count) == 0;
}), this->cachedClients.end());
}
void GroupManager::clearCache() {
@@ -588,7 +588,7 @@ void GroupManager::clearCache() {
}
bool GroupManager::isClientCached(const ClientDbId& client_database_id) {
return this->resolve_cached_client(client_database_id) == nullptr;
return this->resolve_cached_client(client_database_id) == nullptr;
}
typedef std::vector<std::shared_ptr<GroupMember>> ResList;
@@ -635,13 +635,13 @@ vector<shared_ptr<GroupAssignment>> GroupManager::listGroupAssignments(ClientDbI
auto cached = resolve_cached_client(cldbId);
if(cached) {
{
lock_guard lock{cached->lock};
for(const auto &serverGroup : cached->server_groups)
result.push_back(serverGroup);
for(auto& channelGroup : cached->channel_groups)
result.push_back(channelGroup.second);
}
{
lock_guard lock{cached->lock};
for(const auto &serverGroup : cached->server_groups)
result.push_back(serverGroup);
for(auto& channelGroup : cached->channel_groups)
result.push_back(channelGroup.second);
}
if(this->root){
auto append = this->root->listGroupAssignments(cldbId);
@@ -654,7 +654,7 @@ vector<shared_ptr<GroupAssignment>> GroupManager::listGroupAssignments(ClientDbI
res = sql::command(this->sql, "SELECT `groupId`, `until`, `channelId` FROM `assignedGroups` WHERE `serverId` = :sid AND `cldbid` = :cldbid", variable{":sid", this->getServerId()}, variable{":cldbid", cldbId})
.query([&](int length, char** value, char** column){
.query([&](int length, char** value, char** column){
shared_ptr<Group> group = nullptr;
time_point<system_clock> until;
uint64_t channelId = 0;
@@ -696,152 +696,152 @@ vector<shared_ptr<GroupAssignment>> GroupManager::listGroupAssignments(ClientDbI
}
std::shared_ptr<CachedClient> GroupManager::resolve_cached_client(ClientDbId client_database_id) {
{
lock_guard lock(this->cacheLock);
for(auto& entry : this->cachedClients)
if(entry->client_database_id == client_database_id)
return entry;
}
{
lock_guard lock(this->cacheLock);
for(auto& entry : this->cachedClients)
if(entry->client_database_id == client_database_id)
return entry;
}
return nullptr;
return nullptr;
}
std::vector<std::shared_ptr<GroupAssignment>> GroupManager::getAssignedServerGroups(ClientDbId cldbid) {
auto cached = this->resolve_cached_client(cldbid);
sql::result res;
std::vector<std::shared_ptr<GroupAssignment>> result;
if(this->root) {
auto root = this->root->getAssignedServerGroups(cldbid);
result.insert(result.begin(), root.begin(), root.end());
}
auto cached = this->resolve_cached_client(cldbid);
sql::result res;
std::vector<std::shared_ptr<GroupAssignment>> result;
if(this->root) {
auto root = this->root->getAssignedServerGroups(cldbid);
result.insert(result.begin(), root.begin(), root.end());
}
if(cached) {
lock_guard cache_lock{cached->lock};
result.insert(result.end(), cached->server_groups.begin(), cached->server_groups.end());
return result;
}
if(cached) {
lock_guard cache_lock{cached->lock};
result.insert(result.end(), cached->server_groups.begin(), cached->server_groups.end());
return result;
}
debugMessage(this->getServerId(), "Query client groups for client {} on server {}.", cldbid, this->getServerId());
res = sql::command(this->sql, "SELECT `groupId`, `until` FROM `assignedGroups` WHERE `serverId` = :sid AND `cldbid` = :cldbid AND `channelId` = 0", variable{":sid", this->getServerId()}, variable{":cldbid", cldbid}).query([&](int length, char** value, char** column){
shared_ptr<Group> group = nullptr;
time_point<system_clock> until;
debugMessage(this->getServerId(), "Query client groups for client {} on server {}.", cldbid, this->getServerId());
res = sql::command(this->sql, "SELECT `groupId`, `until` FROM `assignedGroups` WHERE `serverId` = :sid AND `cldbid` = :cldbid AND `channelId` = 0", variable{":sid", this->getServerId()}, variable{":cldbid", cldbid}).query([&](int length, char** value, char** column){
shared_ptr<Group> group = nullptr;
time_point<system_clock> until;
for(int index = 0; index < length; index++){
if(value[index] == nullptr) {
logError(this->getServerId(), string() + "Invalid value at " + column[index]);
continue;
}
if(strcmp(column[index], "groupId") == 0 && value[index] != nullptr){
group = this->findGroup(stoll(value[index]));
} else if(strcmp(column[index], "until") == 0){
until = time_point<system_clock>() + milliseconds(stoll(value[index] == nullptr ? "0" : value[index]));
} else cerr << "Invalid column " << column[index] << endl;
}
if(!group)
return 0;
for(int index = 0; index < length; index++){
if(value[index] == nullptr) {
logError(this->getServerId(), string() + "Invalid value at " + column[index]);
continue;
}
if(strcmp(column[index], "groupId") == 0 && value[index] != nullptr){
group = this->findGroup(stoll(value[index]));
} else if(strcmp(column[index], "until") == 0){
until = time_point<system_clock>() + milliseconds(stoll(value[index] == nullptr ? "0" : value[index]));
} else cerr << "Invalid column " << column[index] << endl;
}
if(!group)
return 0;
shared_ptr<GroupAssignment> assignment = std::make_shared<GroupAssignment>();
assignment->parent = nullptr;
assignment->group = group;
assignment->until = until;
assignment->server = this->getServerId();
result.push_back(assignment);
return 0;
});
LOG_SQL_CMD(res);
return result;
shared_ptr<GroupAssignment> assignment = std::make_shared<GroupAssignment>();
assignment->parent = nullptr;
assignment->group = group;
assignment->until = until;
assignment->server = this->getServerId();
result.push_back(assignment);
return 0;
});
LOG_SQL_CMD(res);
return result;
}
std::vector<std::shared_ptr<GroupAssignment>> GroupManager::getServerGroups(ClientDbId cldbid, server::ClientType type) {
auto result = this->getAssignedServerGroups(cldbid);
if(result.empty()) return this->defaultServerGroupGroupAssignments(cldbid, type);
return result;
if(result.empty()) return this->defaultServerGroupGroupAssignments(cldbid, type);
return result;
}
std::vector<std::shared_ptr<GroupAssignment>> GroupManager::defaultServerGroupGroupAssignments(ClientDbId client, ClientType type) {
std::vector<std::shared_ptr<GroupAssignment>> result;
if(type == ClientType::CLIENT_QUERY && this->root) {
auto root = this->root->defaultServerGroupGroupAssignments(client, type);
result.insert(result.begin(), root.begin(), root.end());
} else if(type == ClientType::CLIENT_MUSIC) {
threads::MutexLock lock(this->cacheLock);
std::vector<std::shared_ptr<GroupAssignment>> result;
if(type == ClientType::CLIENT_QUERY && this->root) {
auto root = this->root->defaultServerGroupGroupAssignments(client, type);
result.insert(result.begin(), root.begin(), root.end());
} else if(type == ClientType::CLIENT_MUSIC) {
threads::MutexLock lock(this->cacheLock);
auto server = this->server.lock();
auto id =
server ?
server->properties()[property::VIRTUALSERVER_DEFAULT_MUSIC_GROUP].as_save<GroupId>() :
serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_MUSICDEFAULT_GROUP].as_save<GroupId>();
auto group = this->findGroupLocal(id);
if(group) {
result.push_back(std::make_shared<GroupAssignment>(nullptr, this->getServerId(), 0, group, time_point<system_clock>()));
return result;
}
}
result.push_back(std::make_shared<GroupAssignment>(nullptr, this->getServerId(), 0, this->defaultGroup(GroupTarget::GROUPTARGET_SERVER), time_point<system_clock>()));
return result;
auto server = this->server.lock();
auto id =
server ?
server->properties()[property::VIRTUALSERVER_DEFAULT_MUSIC_GROUP].as_save<GroupId>() :
serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_MUSICDEFAULT_GROUP].as_save<GroupId>();
auto group = this->findGroupLocal(id);
if(group) {
result.push_back(std::make_shared<GroupAssignment>(nullptr, this->getServerId(), 0, group, time_point<system_clock>()));
return result;
}
}
result.push_back(std::make_shared<GroupAssignment>(nullptr, this->getServerId(), 0, this->defaultGroup(GroupTarget::GROUPTARGET_SERVER), time_point<system_clock>()));
return result;
}
std::shared_ptr<GroupAssignment> GroupManager::getChannelGroupExact(ClientDbId cldbId, const std::shared_ptr<BasicChannel>& channel, bool assign_default) {
auto cached = resolve_cached_client(cldbId);
if(cached) {
lock_guard cache_lock(cached->lock);
if(cached->channel_groups.count(channel->channelId()) > 0) {
return cached->channel_groups[channel->channelId()];
} else
return assign_default ? this->defaultChannelGroupAssignment(cldbId, channel) : nullptr;
}
auto cached = resolve_cached_client(cldbId);
if(cached) {
lock_guard cache_lock(cached->lock);
if(cached->channel_groups.count(channel->channelId()) > 0) {
return cached->channel_groups[channel->channelId()];
} else
return assign_default ? this->defaultChannelGroupAssignment(cldbId, channel) : nullptr;
}
std::shared_ptr<GroupAssignment> result;
auto res = sql::command(this->sql, "SELECT `groupId`, `until` FROM `assignedGroups` WHERE `serverId` = :sid AND `cldbid` = :cldbid AND `channelId` = :chid", variable{":sid", this->getServerId()}, variable{":cldbid", cldbId}, variable{":chid", channel->channelId()}).query([&](int length, char** value, char** column){
shared_ptr<Group> group = nullptr;
time_point<system_clock> until;
std::shared_ptr<GroupAssignment> result;
auto res = sql::command(this->sql, "SELECT `groupId`, `until` FROM `assignedGroups` WHERE `serverId` = :sid AND `cldbid` = :cldbid AND `channelId` = :chid", variable{":sid", this->getServerId()}, variable{":cldbid", cldbId}, variable{":chid", channel->channelId()}).query([&](int length, char** value, char** column){
shared_ptr<Group> group = nullptr;
time_point<system_clock> until;
for(int index = 0; index < length; index++){
if(value[index] == nullptr) {
logError(this->getServerId(), string() + "Invalid value at " + column[index]);
continue;
}
if(strcmp(column[index], "groupId") == 0){
group = this->findGroup(stoll(value[index]));
} else if(strcmp(column[index], "until") == 0){
until = time_point<system_clock>() + milliseconds(stoll(value[index]));
} else cerr << "Invalid column " << column[index] << endl;
}
if(!group)
return 0;
for(int index = 0; index < length; index++){
if(value[index] == nullptr) {
logError(this->getServerId(), string() + "Invalid value at " + column[index]);
continue;
}
if(strcmp(column[index], "groupId") == 0){
group = this->findGroup(stoll(value[index]));
} else if(strcmp(column[index], "until") == 0){
until = time_point<system_clock>() + milliseconds(stoll(value[index]));
} else cerr << "Invalid column " << column[index] << endl;
}
if(!group)
return 0;
shared_ptr<GroupAssignment> assignment = std::make_shared<GroupAssignment>();
assignment->parent = nullptr;
assignment->group = group;
assignment->until = until;
assignment->server = this->getServerId();
assignment->channelId = channel->channelId();
result = std::move(assignment);
return 0;
});
(LOG_SQL_CMD)(res);
shared_ptr<GroupAssignment> assignment = std::make_shared<GroupAssignment>();
assignment->parent = nullptr;
assignment->group = group;
assignment->until = until;
assignment->server = this->getServerId();
assignment->channelId = channel->channelId();
result = std::move(assignment);
return 0;
});
(LOG_SQL_CMD)(res);
return !result && assign_default ? this->defaultChannelGroupAssignment(cldbId, channel) : result;
return !result && assign_default ? this->defaultChannelGroupAssignment(cldbId, channel) : result;
}
std::shared_ptr<GroupAssignment> GroupManager::getChannelGroup(ClientDbId cldbId, const shared_ptr<BasicChannel> &channel, bool assign_default) {
shared_ptr<GroupAssignment> group;
std::shared_ptr<BasicChannel> inheritance_channel = channel;
while(inheritance_channel && !group) {
group = this->getChannelGroupExact(cldbId, inheritance_channel, false);
if(!group) {
auto inheritance = inheritance_channel->permissions()->permission_value_flagged(permission::b_channel_group_inheritance_end);
if(inheritance.has_value && inheritance.value == 1)
break;
shared_ptr<GroupAssignment> group;
std::shared_ptr<BasicChannel> inheritance_channel = channel;
while(inheritance_channel && !group) {
group = this->getChannelGroupExact(cldbId, inheritance_channel, false);
if(!group) {
auto inheritance = inheritance_channel->permissions()->permission_value_flagged(permission::b_channel_group_inheritance_end);
if(inheritance.has_value && inheritance.value == 1)
break;
inheritance_channel = inheritance_channel->parent();
}
}
return !group && assign_default ? this->defaultChannelGroupAssignment(cldbId, channel) : group;
inheritance_channel = inheritance_channel->parent();
}
}
return !group && assign_default ? this->defaultChannelGroupAssignment(cldbId, channel) : group;
}
std::shared_ptr<GroupAssignment> GroupManager::defaultChannelGroupAssignment(ClientDbId cldbId, const std::shared_ptr<BasicChannel> &channel) {
return std::make_shared<GroupAssignment>(nullptr, this->getServerId(), channel->channelId(), this->defaultGroup(GroupTarget::GROUPTARGET_CHANNEL), time_point<system_clock>());
return std::make_shared<GroupAssignment>(nullptr, this->getServerId(), channel->channelId(), this->defaultGroup(GroupTarget::GROUPTARGET_CHANNEL), time_point<system_clock>());
}
void GroupManager::addServerGroup(ClientDbId cldbId, std::shared_ptr<Group> group, time_point<system_clock> until) {
@@ -855,8 +855,8 @@ void GroupManager::addServerGroup(ClientDbId cldbId, std::shared_ptr<Group> grou
auto cached = resolve_cached_client(cldbId);
if(cached) {
lock_guard cache_lock(cached->lock);
cached->server_groups.push_back(std::make_shared<GroupAssignment>(cached.get(), this->getServerId(), 0, group, until));
lock_guard cache_lock(cached->lock);
cached->server_groups.push_back(std::make_shared<GroupAssignment>(cached.get(), this->getServerId(), 0, group, until));
}
sql::command(this->sql, "INSERT INTO `assignedGroups` (`serverId`, `cldbid`, `groupId`, `channelId`, `until`) VALUES (:sid, :cldbid, :gid, :chid, :until)",
@@ -872,10 +872,10 @@ void GroupManager::removeServerGroup(ClientDbId cldbId, std::shared_ptr<Group> g
if(!this->hasServerGroupAssigned(cldbId, group)) return;
auto cached = resolve_cached_client(cldbId);
if(cached) {
lock_guard cache_lock(cached->lock);
cached->server_groups.erase(std::remove_if(cached->server_groups.begin(), cached->server_groups.end(), [&](const std::shared_ptr<GroupAssignment>& group_assignment) {
return group_assignment->group == group;
}), cached->server_groups.end());
lock_guard cache_lock(cached->lock);
cached->server_groups.erase(std::remove_if(cached->server_groups.begin(), cached->server_groups.end(), [&](const std::shared_ptr<GroupAssignment>& group_assignment) {
return group_assignment->group == group;
}), cached->server_groups.end());
}
sql::command(this->sql, "DELETE FROM `assignedGroups` WHERE `serverId` = :sid AND `cldbid` = :cldbid AND `groupId` = :gid AND `channelId` = :chid",
@@ -887,19 +887,19 @@ void GroupManager::removeServerGroup(ClientDbId cldbId, std::shared_ptr<Group> g
}
void GroupManager::setChannelGroup(ClientDbId cldbId, std::shared_ptr<Group> group, std::shared_ptr<BasicChannel> channel, time_point<system_clock> until) {
auto old_group = getChannelGroupExact(cldbId, channel, false);
if(old_group) {
if(old_group->group == group) return;
} else if(!group) return;
auto old_group = getChannelGroupExact(cldbId, channel, false);
if(old_group) {
if(old_group->group == group) return;
} else if(!group) return;
auto default_group = !group || group == this->defaultGroup(GroupTarget::GROUPTARGET_CHANNEL);
auto default_group = !group || group == this->defaultGroup(GroupTarget::GROUPTARGET_CHANNEL);
auto cached = resolve_cached_client(cldbId);
if(cached) {
lock_guard cache_lock(cached->lock);
if(default_group)
cached->channel_groups.erase(channel->channelId());
else
cached->channel_groups[channel->channelId()] = std::make_shared<GroupAssignment>(cached.get(), this->getServerId(), channel->channelId(), group, until);
lock_guard cache_lock(cached->lock);
if(default_group)
cached->channel_groups.erase(channel->channelId());
else
cached->channel_groups[channel->channelId()] = std::make_shared<GroupAssignment>(cached.get(), this->getServerId(), channel->channelId(), group, until);
}
sql::command(this->sql, "DELETE FROM `assignedGroups` WHERE `serverId` = :sid AND `cldbid` = :cldbid AND `channelId` = :chid",
@@ -908,13 +908,13 @@ void GroupManager::setChannelGroup(ClientDbId cldbId, std::shared_ptr<Group> gro
variable{":chid", channel->channelId()})
.executeLater().waitAndGetLater(LOG_SQL_CMD, {1, "future failed"});
if(!default_group) {
sql::command(this->sql, "INSERT INTO `assignedGroups` (`serverId`, `cldbid`, `groupId`, `channelId`, `until`) VALUES (:sid, :cldbid, :gid, :chid, :until)",
variable{":sid", this->getServerId()},
variable{":cldbid", cldbId},
variable{":gid", group->groupId()},
variable{":chid", channel->channelId()},
variable{":until", time_point_cast<milliseconds>(until).time_since_epoch().count()})
.executeLater().waitAndGetLater(LOG_SQL_CMD, {1, "future failed"});
}
if(!default_group) {
sql::command(this->sql, "INSERT INTO `assignedGroups` (`serverId`, `cldbid`, `groupId`, `channelId`, `until`) VALUES (:sid, :cldbid, :gid, :chid, :until)",
variable{":sid", this->getServerId()},
variable{":cldbid", cldbId},
variable{":gid", group->groupId()},
variable{":chid", channel->channelId()},
variable{":until", time_point_cast<milliseconds>(until).time_since_epoch().count()})
.executeLater().waitAndGetLater(LOG_SQL_CMD, {1, "future failed"});
}
}