Changed some stuff

This commit is contained in:
WolverinDEV 2020-03-09 18:28:49 +01:00
parent 6172628247
commit 7926a26091
42 changed files with 334 additions and 184 deletions

2
music

@ -1 +1 @@
Subproject commit ae7f8c7f3d4121704d229cd8995ec33e4824841b Subproject commit ad24c38923afe23d94452973337a416540e3c7aa

View File

@ -4,6 +4,7 @@ project(TeaSpeak-Server)
set(CMAKE_VERBOSE_MAKEFILE ON) set(CMAKE_VERBOSE_MAKEFILE ON)
#--allow-multiple-definition #--allow-multiple-definition
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -Wall -Wno-reorder -Wno-sign-compare -static-libgcc -static-libstdc++ -g -Wl,--no-whole-archive -pthread ${MEMORY_DEBUG_FLAGS} -Werror=return-type") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive -Wall -Wno-reorder -Wno-sign-compare -static-libgcc -static-libstdc++ -g -Wl,--no-whole-archive -pthread ${MEMORY_DEBUG_FLAGS} -Werror=return-type")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wl,--unresolved-symbols=ignore-all")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O3")
@ -43,7 +44,7 @@ set(SERVER_SOURCE_FILES
# MySQLLibSSLFix.c # MySQLLibSSLFix.c
src/client/ConnectedClient.cpp src/client/ConnectedClient.cpp
src/client/voice/PrecomputedPuzzles.cpp src/server/udp-server/PrecomputedPuzzles.cpp
src/client/voice/VoiceClient.cpp src/client/voice/VoiceClient.cpp
src/client/voice/VoiceClientHandschake.cpp src/client/voice/VoiceClientHandschake.cpp
src/client/voice/VoiceClientCommandHandler.cpp src/client/voice/VoiceClientCommandHandler.cpp
@ -160,7 +161,7 @@ if (COMPILE_WEB_CLIENT)
src/client/web/WSWebClient.cpp src/client/web/WSWebClient.cpp
src/client/web/SampleHandler.cpp src/client/web/SampleHandler.cpp
src/client/web/VoiceBridge.cpp src/client/web/VoiceBridge.cpp
src/client/command_handler/helpers.h src/music/PlaylistPermissions.cpp src/music/PlaylistPermissions.h src/lincense/LicenseService.cpp src/lincense/LicenseService.h src/groups/GroupManager.cpp src/groups/GroupManager.h src/groups/GroupAssignmentManager.cpp src/groups/GroupAssignmentManager.h src/groups/Group.cpp src/groups/Group.h src/services/VirtualServerInformation.cpp src/services/VirtualServerInformation.h src/vserver/VirtualServerManager.cpp src/vserver/VirtualServerManager.h) src/client/command_handler/helpers.h src/music/PlaylistPermissions.cpp src/music/PlaylistPermissions.h src/lincense/LicenseService.cpp src/lincense/LicenseService.h src/groups/GroupManager.cpp src/groups/GroupManager.h src/groups/GroupAssignmentManager.cpp src/groups/GroupAssignmentManager.h src/groups/Group.cpp src/groups/Group.h src/services/VirtualServerInformation.cpp src/services/VirtualServerInformation.h src/vserver/VirtualServerManager.cpp src/vserver/VirtualServerManager.h src/services/VirtualServerBroadcastService.cpp src/services/VirtualServerBroadcastService.h src/server/udp-server/UDPServer.cpp src/server/udp-server/UDPServer.h)
endif () endif ()
add_executable(PermHelper helpers/permgen.cpp) add_executable(PermHelper helpers/permgen.cpp)

View File

@ -231,13 +231,12 @@ inline sql::result load_permissions_v2(VirtualServerId server_id, v2::Permission
#define INSERT_COMMAND "INSERT INTO `permissions` (`serverId`, `type`, `id`, `channelId`, `permId`, `value`, `grant`, `flag_skip`, `flag_negate`) VALUES (:serverId, :type, :id, :chId, :permId, :value, :grant, :flag_skip, :flag_negate)" #define INSERT_COMMAND "INSERT INTO `permissions` (`serverId`, `type`, `id`, `channelId`, `permId`, `value`, `grant`, `flag_skip`, `flag_negate`) VALUES (:serverId, :type, :id, :chId, :permId, :value, :grant, :flag_skip, :flag_negate)"
#define DELETE_COMMAND "DELETE FROM `permissions` WHERE `serverId` = :serverId AND `type` = :type AND `id` = :id AND `permId` = :permId AND `channelId` = :chId" #define DELETE_COMMAND "DELETE FROM `permissions` WHERE `serverId` = :serverId AND `type` = :type AND `id` = :id AND `permId` = :permId AND `channelId` = :chId"
std::shared_ptr<v2::PermissionRegister> DatabaseHelper::loadClientPermissionManager(const std::shared_ptr<VirtualServer>& server, ClientDbId cldbid) { std::shared_ptr<v2::PermissionRegister> DatabaseHelper::loadClientPermissionManager(VirtualServerId server_id, ClientDbId cldbid) {
auto server_id = server ? server->getServerId() : 0;
#ifndef DISABLE_CACHING #ifndef DISABLE_CACHING
{ {
lock_guard<threads::Mutex> lock(permManagerLock); lock_guard<threads::Mutex> lock(permManagerLock);
for(auto permMgr : this->cachedPermissionManagers) for(auto permMgr : this->cachedPermissionManagers)
if(permMgr->cldbid == cldbid && permMgr->sid == (server ? server->getServerId() : 0)) { if(permMgr->cldbid == cldbid && permMgr->sid == server_id) {
auto ptr = permMgr->manager.lock(); auto ptr = permMgr->manager.lock();
if(!ptr){ if(!ptr){
this->cachedPermissionManagers.erase(std::find(this->cachedPermissionManagers.begin(), this->cachedPermissionManagers.end(), permMgr)); this->cachedPermissionManagers.erase(std::find(this->cachedPermissionManagers.begin(), this->cachedPermissionManagers.end(), permMgr));
@ -253,12 +252,12 @@ std::shared_ptr<v2::PermissionRegister> DatabaseHelper::loadClientPermissionMana
logTrace(server_id, "[Permission] Loading client permission manager for client {}", cldbid); logTrace(server_id, "[Permission] Loading client permission manager for client {}", cldbid);
auto permission_manager = std::make_shared<v2::PermissionRegister>(); auto permission_manager = std::make_shared<v2::PermissionRegister>();
bool loaded = false; bool loaded = false;
if(this->use_startup_cache && server) { if(this->use_startup_cache) {
shared_ptr<StartupCacheEntry> entry; shared_ptr<StartupCacheEntry> entry;
{ {
threads::MutexLock lock(this->startup_lock); threads::MutexLock lock(this->startup_lock);
for(const auto& entries : this->startup_entries) { for(const auto& entries : this->startup_entries) {
if(entries->sid == server->getServerId()) { if(entries->sid == server_id) {
entry = entries; entry = entries;
break; break;
} }
@ -267,10 +266,8 @@ std::shared_ptr<v2::PermissionRegister> DatabaseHelper::loadClientPermissionMana
if(entry) { if(entry) {
for(const auto& perm : entry->permissions) { for(const auto& perm : entry->permissions) {
if(perm->type == permission::SQL_PERM_USER && perm->id == cldbid) { if(perm->type == permission::SQL_PERM_USER && perm->id == cldbid) {
auto channel = perm->channelId > 0 ? server->getChannelTree()->findChannel(perm->channelId) : nullptr; if(perm->channelId > 0)
permission_manager->load_permission(perm->permission->type, {perm->value, perm->grant}, perm->channelId, perm->flag_skip, perm->flag_negate, perm->value != permNotGranted, perm->grant != permNotGranted);
if(channel)
permission_manager->load_permission(perm->permission->type, {perm->value, perm->grant}, channel->channelId(), perm->flag_skip, perm->flag_negate, perm->value != permNotGranted, perm->grant != permNotGranted);
else else
permission_manager->load_permission(perm->permission->type, {perm->value, perm->grant}, perm->flag_skip, perm->flag_negate, perm->value != permNotGranted, perm->grant != permNotGranted); permission_manager->load_permission(perm->permission->type, {perm->value, perm->grant}, perm->flag_skip, perm->flag_negate, perm->value != permNotGranted, perm->grant != permNotGranted);
} }
@ -281,10 +278,10 @@ std::shared_ptr<v2::PermissionRegister> DatabaseHelper::loadClientPermissionMana
if(!loaded) { if(!loaded) {
auto command = sql::command(this->sql, "SELECT `permId`, `value`, `channelId`, `grant`, `flag_skip`, `flag_negate` FROM `permissions` WHERE `serverId` = :serverId AND `type` = :type AND `id` = :id", auto command = sql::command(this->sql, "SELECT `permId`, `value`, `channelId`, `grant`, `flag_skip`, `flag_negate` FROM `permissions` WHERE `serverId` = :serverId AND `type` = :type AND `id` = :id",
variable{":serverId", server ? server->getServerId() : 0}, variable{":serverId", server_id},
variable{":type", permission::SQL_PERM_USER}, variable{":type", permission::SQL_PERM_USER},
variable{":id", cldbid}); variable{":id", cldbid});
LOG_SQL_CMD(load_permissions_v2(server ? server->getServerId() : 0, permission_manager.get(), command, true)); LOG_SQL_CMD(load_permissions_v2(server_id, permission_manager.get(), command, true));
} }
@ -303,12 +300,11 @@ std::shared_ptr<v2::PermissionRegister> DatabaseHelper::loadClientPermissionMana
} }
void DatabaseHelper::saveClientPermissions(const std::shared_ptr<ts::server::VirtualServer> &server, ts::ClientDbId client_dbid, const std::shared_ptr<ts::permission::v2::PermissionRegister> &permissions) { void DatabaseHelper::saveClientPermissions(VirtualServerId server_id, ts::ClientDbId client_dbid, const std::shared_ptr<ts::permission::v2::PermissionRegister> &permissions) {
const auto updates = permissions->flush_db_updates(); const auto updates = permissions->flush_db_updates();
if(updates.empty()) if(updates.empty())
return; return;
auto server_id = server ? server->getServerId() : 0;
for(auto& update : updates) { for(auto& update : updates) {
std::string query = update.flag_delete ? DELETE_COMMAND : (update.flag_db ? UPDATE_COMMAND : INSERT_COMMAND); std::string query = update.flag_delete ? DELETE_COMMAND : (update.flag_db ? UPDATE_COMMAND : INSERT_COMMAND);
@ -323,7 +319,7 @@ void DatabaseHelper::saveClientPermissions(const std::shared_ptr<ts::server::Vir
query query
); );
sql::command(this->sql, query, sql::command(this->sql, query,
variable{":serverId", server ? server->getServerId() : 0}, variable{":serverId", server_id},
variable{":id", client_dbid}, variable{":id", client_dbid},
variable{":chId", update.channel_id}, variable{":chId", update.channel_id},
variable{":type", permission::SQL_PERM_USER}, variable{":type", permission::SQL_PERM_USER},

View File

@ -91,8 +91,8 @@ namespace ts {
std::deque<std::shared_ptr<ClientDatabaseInfo>> queryDatabaseInfo(const std::shared_ptr<VirtualServer>&, const std::deque<ClientDbId>&); std::deque<std::shared_ptr<ClientDatabaseInfo>> queryDatabaseInfo(const std::shared_ptr<VirtualServer>&, const std::deque<ClientDbId>&);
std::deque<std::shared_ptr<ClientDatabaseInfo>> queryDatabaseInfoByUid(const std::shared_ptr<VirtualServer> &, std::deque<std::string>); std::deque<std::shared_ptr<ClientDatabaseInfo>> queryDatabaseInfoByUid(const std::shared_ptr<VirtualServer> &, std::deque<std::string>);
std::shared_ptr<permission::v2::PermissionRegister> loadClientPermissionManager(const std::shared_ptr<VirtualServer>&, ClientDbId); std::shared_ptr<permission::v2::PermissionRegister> loadClientPermissionManager(VirtualServerId, ClientDbId);
void saveClientPermissions(const std::shared_ptr<VirtualServer>&, ClientDbId , const std::shared_ptr<permission::v2::PermissionRegister>& /* permission manager */); void saveClientPermissions(VirtualServerId, ClientDbId , const std::shared_ptr<permission::v2::PermissionRegister>& /* permission manager */);
std::shared_ptr<permission::v2::PermissionRegister> loadChannelPermissions(const std::shared_ptr<VirtualServer>&, ChannelId); std::shared_ptr<permission::v2::PermissionRegister> loadChannelPermissions(const std::shared_ptr<VirtualServer>&, ChannelId);
void saveChannelPermissions(const std::shared_ptr<VirtualServer>&, ChannelId, const std::shared_ptr<permission::v2::PermissionRegister>& /* permission manager */); void saveChannelPermissions(const std::shared_ptr<VirtualServer>&, ChannelId, const std::shared_ptr<permission::v2::PermissionRegister>& /* permission manager */);

View File

@ -7,6 +7,7 @@
#include "src/client/ConnectedClient.h" #include "src/client/ConnectedClient.h"
#include "InstanceHandler.h" #include "InstanceHandler.h"
#include "src/server/file/FileServer.h" #include "src/server/file/FileServer.h"
#include "src/groups/Group.h"
using namespace std; using namespace std;
using namespace std::chrono; using namespace std::chrono;
@ -212,7 +213,7 @@ int GroupManager::insertGroupFromDb(int count, char **values, char **column) {
group->properties()[property::GROUP_NAME] = targetName; group->properties()[property::GROUP_NAME] = targetName;
group->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(this->server.lock(), group->groupId())); group->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(this->server.lock() ? this->server.lock()->getServerId() : 0, group->groupId(), (uint8_t) -1));
debugMessage(this->getServerId(), "Push back group -> " + to_string(group->groupId()) + " - " + group->name()); debugMessage(this->getServerId(), "Push back group -> " + to_string(group->groupId()) + " - " + group->name());
this->groups.push_back(group); this->groups.push_back(group);
@ -304,7 +305,7 @@ std::shared_ptr<Group> GroupManager::createGroup(GroupTarget target, GroupType t
std::shared_ptr<Group> group = std::make_shared<Group>(this, target, type, groupId); std::shared_ptr<Group> group = std::make_shared<Group>(this, target, type, groupId);
group->properties()[property::GROUP_NAME] = name; group->properties()[property::GROUP_NAME] = name;
group->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(this->server.lock(), group->groupId())); group->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(this->server.lock() ? this->server.lock()->getServerId() : 0, group->groupId(), (uint8_t) -1));
this->groups.push_back(group); this->groups.push_back(group);
return group; return group;
} }
@ -344,7 +345,7 @@ bool GroupManager::copyGroupPermissions(const shared_ptr<Group> &source, const s
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", 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(); 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->handle->server.lock()->getServerId() : 0, target->groupId(), (uint8_t) -1));
LOG_SQL_CMD(res); LOG_SQL_CMD(res);
return true; return true;
} }
@ -355,7 +356,7 @@ bool GroupManager::reloadGroupPermissions(std::shared_ptr<Group> group) {
return false; return false;
} }
group->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(this->server.lock(), group->groupId())); group->setPermissionManager(serverInstance->databaseHelper()->loadGroupPermissions(this->server.lock() ? this->server.lock()->getServerId() : 0, group->groupId(), (uint8_t) -1));
return true; return true;
} }
@ -457,11 +458,6 @@ std::deque<property::ClientProperties> GroupManager::update_server_group_propert
unique_lock chan_lock(client->channel_lock, defer_lock); unique_lock chan_lock(client->channel_lock, defer_lock);
if(channel_lock) if(channel_lock)
chan_lock.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());
} }
} }
@ -480,8 +476,6 @@ std::deque<property::ClientProperties> GroupManager::update_server_group_propert
unique_lock chan_lock(client->channel_lock, defer_lock); unique_lock chan_lock(client->channel_lock, defer_lock);
if(channel_lock) if(channel_lock)
chan_lock.lock(); chan_lock.lock();
client->cached_channel_group = group->group->groupId();
} }
} }

View File

@ -188,7 +188,7 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql) {
this->properties()[property::SERVERINSTANCE_MONTHLY_TIMESTAMP] = duration_cast<seconds>(system_clock::now().time_since_epoch()).count(); this->properties()[property::SERVERINSTANCE_MONTHLY_TIMESTAMP] = duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
} }
this->banMgr = new BanManager(this->getSql()); this->banMgr = new bans::BanManager(this->getSql());
this->banMgr->loadBans(); this->banMgr->loadBans();
this->web_list = make_shared<weblist::WebListManager>(); this->web_list = make_shared<weblist::WebListManager>();
@ -569,7 +569,7 @@ void InstanceHandler::save_group_permissions() {
auto permissions = group->permissions(); auto permissions = group->permissions();
if(permissions->require_db_updates()) { if(permissions->require_db_updates()) {
auto begin = system_clock::now(); auto begin = system_clock::now();
serverInstance->databaseHelper()->saveGroupPermissions(nullptr, group->groupId(), permissions); serverInstance->databaseHelper()->saveGroupPermissions(0, group->groupId(), permissions);
auto end = system_clock::now(); auto end = system_clock::now();
debugMessage(0, "Saved instance group permissions for group {} ({}) in {}ms", group->groupId(), group->name(), duration_cast<milliseconds>(end - begin).count()); debugMessage(0, "Saved instance group permissions for group {} ({}) in {}ms", group->groupId(), group->name(), duration_cast<milliseconds>(end - begin).count());
} }

View File

@ -45,7 +45,7 @@ namespace ts {
FileServer* getFileServer(){ return fileServer; } FileServer* getFileServer(){ return fileServer; }
QueryServer* getQueryServer(){ return queryServer; } QueryServer* getQueryServer(){ return queryServer; }
DatabaseHelper* databaseHelper(){ return this->dbHelper; } DatabaseHelper* databaseHelper(){ return this->dbHelper; }
BanManager* banManager(){ return this->banMgr; } bans::BanManager* banManager(){ return this->banMgr; }
ssl::SSLManager* sslManager(){ return this->sslMgr; } ssl::SSLManager* sslManager(){ return this->sslMgr; }
sql::SqlManager* getSql(){ return sql->sql(); } sql::SqlManager* getSql(){ return sql->sql(); }
@ -114,7 +114,7 @@ namespace ts {
QueryServer* queryServer = nullptr; QueryServer* queryServer = nullptr;
VirtualServerManager* voiceServerManager = nullptr; VirtualServerManager* voiceServerManager = nullptr;
DatabaseHelper* dbHelper = nullptr; DatabaseHelper* dbHelper = nullptr;
BanManager* banMgr = nullptr; bans::BanManager* banMgr = nullptr;
ssl::SSLManager* sslMgr = nullptr; ssl::SSLManager* sslMgr = nullptr;
ts::Properties* _properties = nullptr; ts::Properties* _properties = nullptr;

View File

@ -122,7 +122,7 @@ bool VirtualServer::unregisterClient(shared_ptr<ConnectedClient> cl, std::string
this->client_move(cl, nullptr, nullptr, reason, ViewReasonId::VREASON_SERVER_LEFT, false, chan_tree_lock); this->client_move(cl, nullptr, nullptr, reason, ViewReasonId::VREASON_SERVER_LEFT, false, chan_tree_lock);
} }
serverInstance->databaseHelper()->saveClientPermissions(this->ref(), cl->getClientDatabaseId(), cl->clientPermissions); serverInstance->databaseHelper()->saveClientPermissions(this->serverId, cl->getClientDatabaseId(), cl->clientPermissions);
cl->setClientId(0); cl->setClientId(0);
return true; return true;
} }

View File

@ -152,7 +152,7 @@ void VirtualServer::executeServerTick() {
if(cl->clientPermissions->require_db_updates()) { if(cl->clientPermissions->require_db_updates()) {
auto begin = system_clock::now(); auto begin = system_clock::now();
serverInstance->databaseHelper()->saveClientPermissions(this->ref(), cl->getClientDatabaseId(), cl->clientPermissions); serverInstance->databaseHelper()->saveClientPermissions(this->serverId, cl->getClientDatabaseId(), cl->clientPermissions);
auto end = system_clock::now(); auto end = system_clock::now();
debugMessage(this->serverId, "Saved client permissions for client {} ({}) in {}ms", cl->getClientDatabaseId(), cl->getDisplayName(), duration_cast<milliseconds>(end - begin).count()); debugMessage(this->serverId, "Saved client permissions for client {} ({}) in {}ms", cl->getClientDatabaseId(), cl->getDisplayName(), duration_cast<milliseconds>(end - begin).count());
} }
@ -250,7 +250,7 @@ void VirtualServer::executeServerTick() {
auto permissions = group->permissions(); auto permissions = group->permissions();
if(permissions->require_db_updates()) { if(permissions->require_db_updates()) {
auto begin = system_clock::now(); auto begin = system_clock::now();
serverInstance->databaseHelper()->saveGroupPermissions(this->ref(), group->groupId(), permissions); serverInstance->databaseHelper()->saveGroupPermissions(this->serverId, group->groupId(), permissions);
auto end = system_clock::now(); auto end = system_clock::now();
debugMessage(this->serverId, "Saved group permissions for group {} ({}) in {}ms", group->groupId(), group->name(), duration_cast<milliseconds>(end - begin).count()); debugMessage(this->serverId, "Saved group permissions for group {} ({}) in {}ms", group->groupId(), group->name(), duration_cast<milliseconds>(end - begin).count());
} }

View File

@ -792,7 +792,7 @@ vector<pair<ts::permission::PermissionType, ts::permission::v2::PermissionFlagge
} }
if(!cache->client_permissions) { if(!cache->client_permissions) {
cache->client_permissions = serverInstance->databaseHelper()->loadClientPermissionManager(self.lock(), client_dbid); cache->client_permissions = serverInstance->databaseHelper()->loadClientPermissionManager(this->serverId, client_dbid);
} }
bool have_skip_permission = false; bool have_skip_permission = false;

View File

@ -13,7 +13,7 @@ using namespace std::chrono;
using namespace ts::server; using namespace ts::server;
VirtualServerManager::VirtualServerManager(InstanceHandler* handle) : handle(handle) { VirtualServerManager::VirtualServerManager(InstanceHandler* handle) : handle(handle) {
this->puzzles = new protocol::PuzzleManager(); this->puzzles = new server::udp::PuzzleManager();
this->handshakeTickers = new threads::Scheduler(1, "handshake ticker"); this->handshakeTickers = new threads::Scheduler(1, "handshake ticker");
this->execute_loop = new event::EventExecutor("executor #"); this->execute_loop = new event::EventExecutor("executor #");
//this->join_loop = new event::EventExecutor("joiner #"); //this->join_loop = new event::EventExecutor("joiner #");

View File

@ -2,7 +2,7 @@
#include <deque> #include <deque>
#include <EventLoop.h> #include <EventLoop.h>
#include "client/voice/PrecomputedPuzzles.h" #include "src/server/udp-server/PrecomputedPuzzles.h"
#include "server/VoiceIOManager.h" #include "server/VoiceIOManager.h"
#include "VirtualServer.h" #include "VirtualServer.h"
@ -57,7 +57,7 @@ namespace ts {
bool createServerSnapshot(Command &cmd, std::shared_ptr<VirtualServer> server, int version, std::string &error); bool createServerSnapshot(Command &cmd, std::shared_ptr<VirtualServer> server, int version, std::string &error);
std::shared_ptr<VirtualServer> createServerFromSnapshot(std::shared_ptr<VirtualServer> old, std::string, uint16_t, const ts::Command &, std::string &); std::shared_ptr<VirtualServer> createServerFromSnapshot(std::shared_ptr<VirtualServer> old, std::string, uint16_t, const ts::Command &, std::string &);
protocol::PuzzleManager* rsaPuzzles() { return this->puzzles; } server::udp::PuzzleManager* rsaPuzzles() { return this->puzzles; }
event::EventExecutor* get_join_loop() { return this->join_loop; } event::EventExecutor* get_join_loop() { return this->join_loop; }
event::EventExecutor* get_executor_loop() { return this->execute_loop; } event::EventExecutor* get_executor_loop() { return this->execute_loop; }
@ -80,7 +80,7 @@ namespace ts {
InstanceHandler* handle; InstanceHandler* handle;
threads::Mutex instanceLock; threads::Mutex instanceLock;
std::deque<std::shared_ptr<VirtualServer>> instances; std::deque<std::shared_ptr<VirtualServer>> instances;
protocol::PuzzleManager* puzzles = nullptr; server::udp::PuzzleManager* puzzles = nullptr;
event::EventExecutor* execute_loop = nullptr; event::EventExecutor* execute_loop = nullptr;
event::EventExecutor* join_loop = nullptr; event::EventExecutor* join_loop = nullptr;

View File

@ -846,13 +846,13 @@ bool ConnectedClient::handleCommandFull(Command& cmd, bool disconnectOnFail) {
return true; return true;
} }
std::shared_ptr<BanRecord> ConnectedClient::resolveActiveBan(const std::string& ip_address) { std::shared_ptr<bans::BanRecord> ConnectedClient::resolveActiveBan(const std::string& ip_address) {
if(permission::v2::permission_granted(1, this->calculate_permission(permission::b_client_ignore_bans, 0))) return nullptr; if(permission::v2::permission_granted(1, this->calculate_permission(permission::b_client_ignore_bans, 0))) return nullptr;
//Check if manager banned //Check if manager banned
auto banManager = serverInstance->banManager(); auto banManager = serverInstance->banManager();
shared_ptr<BanRecord> banEntry = nullptr; shared_ptr<bans::BanRecord> banEntry = nullptr;
deque<shared_ptr<BanRecord>> entries; deque<shared_ptr<bans::BanRecord>> entries;
if (!banEntry) { if (!banEntry) {
banEntry = banManager->findBanByName(this->server->getServerId(), this->getDisplayName()); banEntry = banManager->findBanByName(this->server->getServerId(), this->getDisplayName());

View File

@ -8,6 +8,7 @@
#include "../channel/ClientChannelView.h" #include "../channel/ClientChannelView.h"
#include "DataClient.h" #include "DataClient.h"
#include "query/command3.h" #include "query/command3.h"
#include "src/manager/BanManager.h"
#define CLIENT_STR_LOG_PREFIX_(this) (std::string("[") + this->getLoggingPeerIp() + ":" + std::to_string(this->getPeerPort()) + "/" + this->getDisplayName() + " | " + std::to_string(this->getClientId()) + "]") #define CLIENT_STR_LOG_PREFIX_(this) (std::string("[") + this->getLoggingPeerIp() + ":" + std::to_string(this->getPeerPort()) + "/" + this->getDisplayName() + " | " + std::to_string(this->getClientId()) + "]")
#define CLIENT_STR_LOG_PREFIX CLIENT_STR_LOG_PREFIX_(this) #define CLIENT_STR_LOG_PREFIX CLIENT_STR_LOG_PREFIX_(this)
@ -244,7 +245,7 @@ namespace ts {
virtual void updateChannelClientProperties(bool /* lock channel tree */, bool /* notify our self */); virtual void updateChannelClientProperties(bool /* lock channel tree */, bool /* notify our self */);
void updateTalkRights(permission::PermissionValue talk_power); void updateTalkRights(permission::PermissionValue talk_power);
virtual std::shared_ptr<BanRecord> resolveActiveBan(const std::string& ip_address); virtual std::shared_ptr<bans::BanRecord> resolveActiveBan(const std::string& ip_address);
inline std::shared_ptr<stats::ConnectionStatistics> getConnectionStatistics() { inline std::shared_ptr<stats::ConnectionStatistics> getConnectionStatistics() {
return this->connectionStatistics; return this->connectionStatistics;
@ -295,7 +296,8 @@ namespace ts {
return this->_subscribed_playlist.lock() == playlist; return this->_subscribed_playlist.lock() == playlist;
} }
[[nodiscard]] inline auto lock_command_handling() { return std::lock_guard{this->command_lock}; } template <typename T = std::lock_guard<threads::Mutex>>
[[nodiscard]] inline auto lock_command_handling() { return T{this->command_lock}; }
void increase_join_state() { this->join_state_id++; } void increase_join_state() { this->join_state_id++; }
protected: protected:
std::weak_ptr<ConnectedClient> _this; std::weak_ptr<ConnectedClient> _this;

View File

@ -112,7 +112,7 @@ bool DataClient::loadDataForCurrentServer() { //TODO for query
} }
this->_properties->toggleSave(true); this->_properties->toggleSave(true);
this->clientPermissions = serverInstance->databaseHelper()->loadClientPermissionManager(ref_server, this->getClientDatabaseId()); this->clientPermissions = serverInstance->databaseHelper()->loadClientPermissionManager(ref_server ? ref_server->serverId : 0, this->getClientDatabaseId());
//Setup / fix stuff //Setup / fix stuff
if(!this->properties()[property::CLIENT_FLAG_AVATAR].as<string>().empty()){ if(!this->properties()[property::CLIENT_FLAG_AVATAR].as<string>().empty()){

View File

@ -98,6 +98,8 @@ namespace ts {
virtual bool loadDataForCurrentServer(); virtual bool loadDataForCurrentServer();
[[nodiscard]] inline std::shared_ptr<permission::v2::PermissionRegister> permissions() { return this->clientPermissions; }
protected: protected:
sql::SqlManager* sql; sql::SqlManager* sql;
std::shared_ptr<VirtualServer> server; std::shared_ptr<VirtualServer> server;

View File

@ -174,6 +174,7 @@ void SpeakingClient::handlePacketVoiceWhisper(const pipes::buffer_view& data, bo
#endif #endif
deque<shared_ptr<SpeakingClient>> available_clients; deque<shared_ptr<SpeakingClient>> available_clients;
auto type_id_string = std::to_string(type_id);
for(const auto& client : this->server->getClients()) { for(const auto& client : this->server->getClients()) {
auto speakingClient = dynamic_pointer_cast<SpeakingClient>(client); auto speakingClient = dynamic_pointer_cast<SpeakingClient>(client);
if(!speakingClient || client == this) continue; if(!speakingClient || client == this) continue;
@ -185,16 +186,15 @@ void SpeakingClient::handlePacketVoiceWhisper(const pipes::buffer_view& data, bo
if(type_id == 0) if(type_id == 0)
available_clients.push_back(speakingClient); available_clients.push_back(speakingClient);
else { else {
shared_lock client_lock(this->channel_lock); auto client_groups = client->properties()[property::CLIENT_SERVERGROUPS].as<std::string>();
for(const auto& id : client->cached_server_groups) { auto index = client_groups.find(client_groups);
if(id == type_id) { if(index == std::string::npos) continue;
available_clients.push_back(speakingClient); if(index != client_groups.length() && client_groups[index] != ',') continue;
break;
} available_clients.push_back(speakingClient);
}
} }
} else if(type == WhisperType::CHANNEL_GROUP) { } else if(type == WhisperType::CHANNEL_GROUP) {
if(client->cached_channel_group == type_id) if(client->properties()[property::CLIENT_CHANNEL_GROUP_ID].as_save<GroupId>() == type_id)
available_clients.push_back(speakingClient); available_clients.push_back(speakingClient);
} else if(type == WhisperType::CHANNEL_COMMANDER) { } else if(type == WhisperType::CHANNEL_COMMANDER) {
if(client->properties()[property::CLIENT_IS_CHANNEL_COMMANDER].as<bool>()) if(client->properties()[property::CLIENT_IS_CHANNEL_COMMANDER].as<bool>())

View File

@ -1654,7 +1654,7 @@ command_result ConnectedClient::handleCommandChannelClientPermList(Command &cmd)
ACTION_REQUIRES_PERMISSION(permission::b_virtualserver_channelclient_permission_list, 1, channel_id); ACTION_REQUIRES_PERMISSION(permission::b_virtualserver_channelclient_permission_list, 1, channel_id);
if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cmd["cldbid"])) return command_result{error::client_invalid_id}; if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cmd["cldbid"])) return command_result{error::client_invalid_id};
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cmd["cldbid"].as<ClientDbId>()); auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server ? this->server->serverId : 0, cmd["cldbid"].as<ClientDbId>());
Command res(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifychannelclientpermlist" : ""); Command res(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifychannelclientpermlist" : "");
@ -1714,7 +1714,7 @@ command_result ConnectedClient::handleCommandChannelClientDelPerm(Command &cmd)
auto channel = dynamic_pointer_cast<ServerChannel>(l_channel->entry); auto channel = dynamic_pointer_cast<ServerChannel>(l_channel->entry);
if(!channel) return command_result{error::vs_critical}; if(!channel) return command_result{error::vs_critical};
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cldbid); auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server ? this->server->serverId : 0, cldbid);
{ {
auto required_permissions = this->server->calculate_permission(permission::i_client_needed_permission_modify_power, cmd["cldbid"], ClientType::CLIENT_TEAMSPEAK, channel_id); auto required_permissions = this->server->calculate_permission(permission::i_client_needed_permission_modify_power, cmd["cldbid"], ClientType::CLIENT_TEAMSPEAK, channel_id);
ACTION_REQUIRES_PERMISSION(permission::i_client_permission_modify_power, required_permissions, channel_id); ACTION_REQUIRES_PERMISSION(permission::i_client_permission_modify_power, required_permissions, channel_id);
@ -1740,7 +1740,7 @@ command_result ConnectedClient::handleCommandChannelClientDelPerm(Command &cmd)
} }
} }
serverInstance->databaseHelper()->saveClientPermissions(this->server, cldbid, mgr); serverInstance->databaseHelper()->saveClientPermissions(this->server ? this->server->serverId : 0, cldbid, mgr);
if (!cll.empty()) { if (!cll.empty()) {
for (const auto &elm : cll) { for (const auto &elm : cll) {
if(elm->update_cached_permissions()) /* update cached calculated permissions */ if(elm->update_cached_permissions()) /* update cached calculated permissions */
@ -1784,7 +1784,7 @@ command_result ConnectedClient::handleCommandChannelClientAddPerm(Command &cmd)
auto channel = dynamic_pointer_cast<ServerChannel>(l_channel->entry); auto channel = dynamic_pointer_cast<ServerChannel>(l_channel->entry);
if(!channel) return command_result{error::vs_critical}; if(!channel) return command_result{error::vs_critical};
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cldbid); auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server ? this->server->serverId : 0, cldbid);
{ {
auto required_permissions = this->server->calculate_permission(permission::i_client_needed_permission_modify_power, cmd["cldbid"], ClientType::CLIENT_TEAMSPEAK, channel_id); auto required_permissions = this->server->calculate_permission(permission::i_client_needed_permission_modify_power, cmd["cldbid"], ClientType::CLIENT_TEAMSPEAK, channel_id);
ACTION_REQUIRES_PERMISSION(permission::i_client_permission_modify_power, required_permissions, channel_id); ACTION_REQUIRES_PERMISSION(permission::i_client_permission_modify_power, required_permissions, channel_id);
@ -1821,7 +1821,7 @@ command_result ConnectedClient::handleCommandChannelClientAddPerm(Command &cmd)
} }
} }
serverInstance->databaseHelper()->saveClientPermissions(this->server, cldbid, mgr); serverInstance->databaseHelper()->saveClientPermissions(this->server ? this->server->serverId : 0, cldbid, mgr);
if (!onlineClientInstances.empty()) if (!onlineClientInstances.empty())
for (const auto &elm : onlineClientInstances) { for (const auto &elm : onlineClientInstances) {
if (elm->update_cached_permissions()) /* update cached calculated permissions */ if (elm->update_cached_permissions()) /* update cached calculated permissions */

View File

@ -867,7 +867,7 @@ command_result ConnectedClient::handleCommandClientAddPerm(Command &cmd) {
auto cldbid = cmd["cldbid"].as<ClientDbId>(); auto cldbid = cmd["cldbid"].as<ClientDbId>();
if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cldbid)) if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cldbid))
return command_result{error::client_invalid_id}; return command_result{error::client_invalid_id};
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cldbid); auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server ? this->server->getServerId() : 0, cldbid);
ACTION_REQUIRES_GLOBAL_PERMISSION(permission::i_client_permission_modify_power, this->server->calculate_permission(permission::i_client_needed_permission_modify_power, cldbid, ClientType::CLIENT_TEAMSPEAK, 0)); ACTION_REQUIRES_GLOBAL_PERMISSION(permission::i_client_permission_modify_power, this->server->calculate_permission(permission::i_client_needed_permission_modify_power, cldbid, ClientType::CLIENT_TEAMSPEAK, 0));
auto max_value = this->calculate_permission(permission::i_permission_modify_power, 0, true); auto max_value = this->calculate_permission(permission::i_permission_modify_power, 0, true);
@ -897,7 +897,7 @@ command_result ConnectedClient::handleCommandClientAddPerm(Command &cmd) {
update_channels |= permission_is_client_property(permType); update_channels |= permission_is_client_property(permType);
} }
} }
serverInstance->databaseHelper()->saveClientPermissions(this->server, cldbid, mgr); serverInstance->databaseHelper()->saveClientPermissions(this->server ? this->server->getServerId() : 0, cldbid, mgr);
auto onlineClients = this->server->findClientsByCldbId(cldbid); auto onlineClients = this->server->findClientsByCldbId(cldbid);
if (!onlineClients.empty()) if (!onlineClients.empty())
for (const auto &elm : onlineClients) { for (const auto &elm : onlineClients) {
@ -919,7 +919,7 @@ command_result ConnectedClient::handleCommandClientDelPerm(Command &cmd) {
auto cldbid = cmd["cldbid"].as<ClientDbId>(); auto cldbid = cmd["cldbid"].as<ClientDbId>();
if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cldbid)) if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cldbid))
return command_result{error::client_invalid_id}; return command_result{error::client_invalid_id};
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cldbid); auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server ? this->server->serverId : 0, cldbid);
ACTION_REQUIRES_GLOBAL_PERMISSION(permission::i_client_permission_modify_power, this->server->calculate_permission(permission::i_client_needed_permission_modify_power, cldbid, ClientType::CLIENT_TEAMSPEAK, 0)); ACTION_REQUIRES_GLOBAL_PERMISSION(permission::i_client_permission_modify_power, this->server->calculate_permission(permission::i_client_needed_permission_modify_power, cldbid, ClientType::CLIENT_TEAMSPEAK, 0));
auto ignore_granted_values = permission::v2::permission_granted(1, this->calculate_permission(permission::b_permission_modify_power_ignore, 0)); auto ignore_granted_values = permission::v2::permission_granted(1, this->calculate_permission(permission::b_permission_modify_power_ignore, 0));
@ -943,7 +943,7 @@ command_result ConnectedClient::handleCommandClientDelPerm(Command &cmd) {
} }
} }
serverInstance->databaseHelper()->saveClientPermissions(this->server, cldbid, mgr); serverInstance->databaseHelper()->saveClientPermissions(this->server ? this->server->serverId : 0, cldbid, mgr);
if (!onlineClients.empty()) if (!onlineClients.empty())
for (const auto &elm : onlineClients) { for (const auto &elm : onlineClients) {
if(elm->update_cached_permissions()) /* update cached calculated permissions */ if(elm->update_cached_permissions()) /* update cached calculated permissions */
@ -962,7 +962,7 @@ command_result ConnectedClient::handleCommandClientPermList(Command &cmd) {
ACTION_REQUIRES_GLOBAL_PERMISSION(permission::b_virtualserver_client_permission_list, 1); ACTION_REQUIRES_GLOBAL_PERMISSION(permission::b_virtualserver_client_permission_list, 1);
if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cmd["cldbid"])) return command_result{error::client_invalid_id}; if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cmd["cldbid"])) return command_result{error::client_invalid_id};
auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cmd["cldbid"]); auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server ? this->server->getServerId() : 0, cmd["cldbid"]);
if (!this->notifyClientPermList(cmd["cldbid"], mgr, cmd.hasParm("permsid"))) return command_result{error::database_empty_result}; if (!this->notifyClientPermList(cmd["cldbid"], mgr, cmd.hasParm("permsid"))) return command_result{error::database_empty_result};
return command_result{error::ok}; return command_result{error::ok};
} }

View File

@ -1561,7 +1561,7 @@ command_result ConnectedClient::handleCommandPermOverview(Command &cmd) {
auto server_groups = this->server->getGroupManager()->getServerGroups(client_dbid, ClientType::CLIENT_TEAMSPEAK); auto server_groups = this->server->getGroupManager()->getServerGroups(client_dbid, ClientType::CLIENT_TEAMSPEAK);
auto channel_group = this->server->getGroupManager()->getChannelGroup(client_dbid, channel, true); auto channel_group = this->server->getGroupManager()->getChannelGroup(client_dbid, channel, true);
auto permission_manager = serverInstance->databaseHelper()->loadClientPermissionManager(this->getServer(), client_dbid); auto permission_manager = serverInstance->databaseHelper()->loadClientPermissionManager(this->getServerId(), client_dbid);
Command result(this->getExternalType() == ClientType::CLIENT_TEAMSPEAK ? "notifypermoverview" : ""); Command result(this->getExternalType() == ClientType::CLIENT_TEAMSPEAK ? "notifypermoverview" : "");
size_t index = 0; size_t index = 0;

View File

@ -1,44 +0,0 @@
#pragma once
#include <ThreadPool/Mutex.h>
#include <tommath.h>
#include <memory>
#include <deque>
namespace ts {
namespace server {
class ConnectedClient;
}
namespace protocol {
struct Puzzle {
mp_int x;
mp_int n;
int level;
mp_int result;
uint8_t data_x[64];
uint8_t data_n[64];
uint8_t data_result[64];
};
class PuzzleManager {
public:
PuzzleManager();
~PuzzleManager();
bool precomputePuzzles(size_t limit);
size_t precomputedPuzzleCount();
std::shared_ptr<Puzzle> nextPuzzle();
private:
void generatePuzzle();
threads::Mutex indexLock;
size_t cacheIndex = 0;
std::deque<std::shared_ptr<Puzzle>> cached;
};
}
}

View File

@ -13,7 +13,7 @@
#include "../ConnectedClient.h" #include "../ConnectedClient.h"
#include "protocol/CryptHandler.h" #include "protocol/CryptHandler.h"
#include "VoiceClientConnection.h" #include "VoiceClientConnection.h"
#include "PrecomputedPuzzles.h" #include "src/server/udp-server/PrecomputedPuzzles.h"
#include "../../lincense/TeamSpeakLicense.h" #include "../../lincense/TeamSpeakLicense.h"
//#define LOG_INCOMPING_PACKET_FRAGMENTS //#define LOG_INCOMPING_PACKET_FRAGMENTS
@ -42,7 +42,7 @@ namespace ts {
class VoiceClient : public SpeakingClient { class VoiceClient : public SpeakingClient {
friend class VirtualServer; friend class VirtualServer;
friend class VoiceServer; friend class VoiceServer;
friend class POWHandler; friend class ts::server::server::udp::POWHandler;
friend class ts::connection::VoiceClientConnection; friend class ts::connection::VoiceClientConnection;
friend class ConnectedClient; friend class ConnectedClient;
friend class io::IOServerHandler; friend class io::IOServerHandler;

View File

@ -80,4 +80,6 @@ namespace ts::server::groups {
public: public:
ChannelGroup(VirtualServerId /* server id */, GroupId /* id */, GroupType /* type */, std::string /* name */, std::shared_ptr<permission::v2::PermissionRegister> /* permissions */); ChannelGroup(VirtualServerId /* server id */, GroupId /* id */, GroupType /* type */, std::string /* name */, std::shared_ptr<permission::v2::PermissionRegister> /* permissions */);
}; };
} }
DEFINE_TRANSFORMS(ts::server::groups::GroupType, uint8_t);
DEFINE_TRANSFORMS(ts::server::groups::GroupNameMode, uint8_t);

View File

@ -332,7 +332,7 @@ GroupAssignmentResult GroupAssignmentManager::add_server_group(ClientDbId client
auto cache = std::make_unique<ClientCache>(); auto cache = std::make_unique<ClientCache>();
cache->client_database_id = client; cache->client_database_id = client;
cache->server_group_assignments.emplace_back(group); cache->server_group_assignments.emplace_back(group);
this->client_cache.push_back(cache); this->client_cache.push_back(std::move(cache));
} }
} }
@ -424,7 +424,7 @@ GroupAssignmentResult GroupAssignmentManager::set_channel_group(ClientDbId clien
auto cache = std::make_unique<ClientCache>(); auto cache = std::make_unique<ClientCache>();
cache->client_database_id = client; cache->client_database_id = client;
cache->channel_group_assignments.emplace_back(channel_id, group, temporary); cache->channel_group_assignments.emplace_back(channel_id, group, temporary);
this->client_cache.push_back(cache); this->client_cache.push_back(std::move(cache));
} else { } else {
return GroupAssignmentResult::SUCCESS; return GroupAssignmentResult::SUCCESS;
} }

View File

@ -32,6 +32,7 @@ namespace ts::server {
ChannelGroupAssignment(ChannelId channel_id, GroupId group_id, bool t) : channel_id{channel_id}, group_id{group_id}, temporary_assignment{t} { } ChannelGroupAssignment(ChannelId channel_id, GroupId group_id, bool t) : channel_id{channel_id}, group_id{group_id}, temporary_assignment{t} { }
ChannelGroupAssignment(const ChannelGroupAssignment& other) = default; ChannelGroupAssignment(const ChannelGroupAssignment& other) = default;
ChannelGroupAssignment(ChannelGroupAssignment&&) = default; ChannelGroupAssignment(ChannelGroupAssignment&&) = default;
ChannelGroupAssignment&operator=(const ChannelGroupAssignment&) = default;
ChannelId channel_id; ChannelId channel_id;
GroupId group_id; GroupId group_id;
@ -42,6 +43,7 @@ namespace ts::server {
explicit ServerGroupAssignment(GroupId group_id) : group_id{group_id} { } explicit ServerGroupAssignment(GroupId group_id) : group_id{group_id} { }
ServerGroupAssignment(const ServerGroupAssignment& other) = default; ServerGroupAssignment(const ServerGroupAssignment& other) = default;
ServerGroupAssignment(ServerGroupAssignment&&) = default; ServerGroupAssignment(ServerGroupAssignment&&) = default;
ServerGroupAssignment&operator=(const ServerGroupAssignment&) = default;
GroupId group_id; GroupId group_id;
}; };

View File

@ -275,7 +275,7 @@ void BanManager::trigger_ban(const std::shared_ptr<BanRecord>& record,
).executeLater().waitAndGetLater(LOG_SQL_CMD, {1, "future failed"}); ).executeLater().waitAndGetLater(LOG_SQL_CMD, {1, "future failed"});
} }
std::deque<std::shared_ptr<BanTrigger>> BanManager::trigger_list(const std::shared_ptr<ts::server::BanRecord> &record, ServerId server_id, ssize_t offset, ssize_t length) { std::deque<std::shared_ptr<BanTrigger>> BanManager::trigger_list(const std::shared_ptr<ts::server::bans::BanRecord> &record, ServerId server_id, ssize_t offset, ssize_t length) {
std::deque<std::shared_ptr<BanTrigger>> result; std::deque<std::shared_ptr<BanTrigger>> result;
if(offset < 0) offset = 0; if(offset < 0) offset = 0;

View File

@ -9,7 +9,7 @@
using namespace std; using namespace std;
using namespace std::chrono; using namespace std::chrono;
using namespace ts; using namespace ts;
using namespace ts::server; using namespace ts::server::server::udp;
//#define POW_DEBUG //#define POW_DEBUG
//#define POW_ERROR //#define POW_ERROR
@ -33,7 +33,7 @@ void POWHandler::execute_tick() {
}), this->pending_clients.end()); }), this->pending_clients.end());
} }
void POWHandler::delete_client(const std::shared_ptr<ts::server::POWHandler::Client> &client) { void POWHandler::delete_client(const std::shared_ptr<POWHandler::Client> &client) {
lock_guard lock(this->pending_clients_lock); lock_guard lock(this->pending_clients_lock);
auto it = find(this->pending_clients.begin(), this->pending_clients.end(), client); auto it = find(this->pending_clients.begin(), this->pending_clients.end(), client);
if(it != this->pending_clients.end()) if(it != this->pending_clients.end())
@ -127,7 +127,7 @@ void POWHandler::handle_datagram(int socket, const sockaddr_storage &address,msg
} }
} }
void POWHandler::send_data(const std::shared_ptr<ts::server::POWHandler::Client> &client, const pipes::buffer_view &buffer) { void POWHandler::send_data(const std::shared_ptr<POWHandler::Client> &client, const pipes::buffer_view &buffer) {
auto datagram = io::DatagramPacket::create(client->address, client->address_info, buffer.length() + MAC_SIZE + SERVER_HEADER_SIZE, nullptr); auto datagram = io::DatagramPacket::create(client->address, client->address_info, buffer.length() + MAC_SIZE + SERVER_HEADER_SIZE, nullptr);
if(!datagram) return; //Should never happen if(!datagram) return; //Should never happen
@ -144,7 +144,7 @@ void POWHandler::send_data(const std::shared_ptr<ts::server::POWHandler::Client>
this->server->send_datagram(client->socket, datagram); this->server->send_datagram(client->socket, datagram);
} }
void POWHandler::reset_client(const std::shared_ptr<ts::server::POWHandler::Client> &client) { void POWHandler::reset_client(const std::shared_ptr<POWHandler::Client> &client) {
uint8_t buffer[2] = {COMMAND_RESET, 0}; uint8_t buffer[2] = {COMMAND_RESET, 0};
this->send_data(client, pipes::buffer_view{buffer, 2}); this->send_data(client, pipes::buffer_view{buffer, 2});
client->state = LowHandshakeState::COOKIE_GET; client->state = LowHandshakeState::COOKIE_GET;
@ -161,7 +161,7 @@ inline void write_reversed(uint8_t* destination, uint8_t* source, size_t length)
*(--destination) = *(source++); *(--destination) = *(source++);
} }
void POWHandler::handle_cookie_get(const std::shared_ptr<ts::server::POWHandler::Client> &client, const pipes::buffer_view &buffer) { void POWHandler::handle_cookie_get(const std::shared_ptr<POWHandler::Client> &client, const pipes::buffer_view &buffer) {
if(buffer.length() != 21) { if(buffer.length() != 21) {
#ifdef POW_ERROR #ifdef POW_ERROR
debugMessage(this->get_server_id(), "[POW][{}][Cookie] Received an invalid packet with an invalid length. Expected {} bytes, but got {} bytes", net::to_string(client->address), 21, buffer.length()); debugMessage(this->get_server_id(), "[POW][{}][Cookie] Received an invalid packet with an invalid length. Expected {} bytes, but got {} bytes", net::to_string(client->address), 21, buffer.length());
@ -191,7 +191,7 @@ void POWHandler::handle_cookie_get(const std::shared_ptr<ts::server::POWHandler:
client->state = LowHandshakeState::PUZZLE_GET; client->state = LowHandshakeState::PUZZLE_GET;
} }
void POWHandler::handle_puzzle_get(const std::shared_ptr<ts::server::POWHandler::Client> &client, const pipes::buffer_view &buffer) { void POWHandler::handle_puzzle_get(const std::shared_ptr<POWHandler::Client> &client, const pipes::buffer_view &buffer) {
if(buffer.length() != 25) { if(buffer.length() != 25) {
#ifdef POW_ERROR #ifdef POW_ERROR
debugMessage(this->get_server_id(), "[POW][{}][Puzzle] Received an invalid puzzle request with an invalid length. Expected {} bytes, but got {} bytes", net::to_string(client->address), 25, buffer.length()); debugMessage(this->get_server_id(), "[POW][{}][Puzzle] Received an invalid puzzle request with an invalid length. Expected {} bytes, but got {} bytes", net::to_string(client->address), 25, buffer.length());
@ -211,7 +211,7 @@ void POWHandler::handle_puzzle_get(const std::shared_ptr<ts::server::POWHandler:
} }
if(!client->rsa_challenge) if(!client->rsa_challenge)
client->rsa_challenge = serverInstance->getVoiceServerManager()->rsaPuzzles()->nextPuzzle(); client->rsa_challenge = serverInstance->getVoiceServerManager()->rsaPuzzles()->next_puzzle();
/* send response */ /* send response */
{ {
@ -239,7 +239,7 @@ void POWHandler::handle_puzzle_get(const std::shared_ptr<ts::server::POWHandler:
client->state = LowHandshakeState::PUZZLE_SOLVE; client->state = LowHandshakeState::PUZZLE_SOLVE;
} }
void POWHandler::handle_puzzle_solve(const std::shared_ptr<ts::server::POWHandler::Client> &client, const pipes::buffer_view &buffer) { void POWHandler::handle_puzzle_solve(const std::shared_ptr<POWHandler::Client> &client, const pipes::buffer_view &buffer) {
if(buffer.length() < 301) { if(buffer.length() < 301) {
#ifdef POW_ERROR #ifdef POW_ERROR
debugMessage(this->get_server_id(), "[POW][{}][Puzzle] Received an invalid puzzle solution with an invalid length. Expected at least {} bytes, but got {} bytes", net::to_string(client->address), 301, buffer.length()); debugMessage(this->get_server_id(), "[POW][{}][Puzzle] Received an invalid puzzle solution with an invalid length. Expected at least {} bytes, but got {} bytes", net::to_string(client->address), 301, buffer.length());
@ -283,7 +283,7 @@ void POWHandler::handle_puzzle_solve(const std::shared_ptr<ts::server::POWHandle
} }
} }
shared_ptr<VoiceClient> POWHandler::register_verified_client(const std::shared_ptr <ts::server::POWHandler::Client> &client) { shared_ptr<ts::server::VoiceClient> POWHandler::register_verified_client(const std::shared_ptr <POWHandler::Client> &client) {
shared_ptr<VoiceClient> voice_client; shared_ptr<VoiceClient> voice_client;
{ {
lock_guard lock(this->server->connectionLock); lock_guard lock(this->server->connectionLock);

View File

@ -3,12 +3,12 @@
#include <mutex> #include <mutex>
#include <netinet/in.h> #include <netinet/in.h>
#include <pipes/buffer.h> #include <pipes/buffer.h>
#include <src/client/voice/PrecomputedPuzzles.h>
#include <Definitions.h> #include <Definitions.h>
#include "VoiceServer.h" #include "VoiceServer.h"
#include "src/VirtualServer.h" #include "src/VirtualServer.h"
#include "./udp-server/PrecomputedPuzzles.h"
namespace ts::server { namespace ts::server::server::udp {
class POWHandler { class POWHandler {
public: public:
enum LowHandshakeState : uint8_t { enum LowHandshakeState : uint8_t {
@ -38,7 +38,7 @@ namespace ts::server {
uint32_t client_version; uint32_t client_version;
std::shared_ptr<protocol::Puzzle> rsa_challenge; std::shared_ptr<Puzzle> rsa_challenge;
}; };
explicit POWHandler(VoiceServer* /* server */); explicit POWHandler(VoiceServer* /* server */);

View File

@ -11,11 +11,11 @@
#include "VoiceIOManager.h" #include "VoiceIOManager.h"
namespace ts { namespace ts {
namespace protocol {
class PuzzleManager;
}
namespace server { namespace server {
namespace server::udp {
class POWHandler;
}
class VirtualServer; class VirtualServer;
class ConnectedClient; class ConnectedClient;
class VoiceClient; class VoiceClient;
@ -33,7 +33,7 @@ namespace ts {
friend class VoiceClient; friend class VoiceClient;
friend class io::VoiceIOManager; friend class io::VoiceIOManager;
friend struct io::IOEventLoopEvents; friend struct io::IOEventLoopEvents;
friend class POWHandler; friend class server::udp::POWHandler;
public: public:
explicit VoiceServer(const std::shared_ptr<VirtualServer>& server); explicit VoiceServer(const std::shared_ptr<VirtualServer>& server);
~VoiceServer(); ~VoiceServer();

View File

@ -1,50 +1,50 @@
#include "PrecomputedPuzzles.h" #include "./PrecomputedPuzzles.h"
#include "../../Configuration.h" #include "src/Configuration.h"
#include "../ConnectedClient.h"
#include <tomcrypt.h> #include <tomcrypt.h>
using namespace std; using namespace std;
using namespace ts; using namespace ts::server::server::udp;
using namespace ts::protocol;
PuzzleManager::PuzzleManager() {} PuzzleManager::PuzzleManager() = default;
PuzzleManager::~PuzzleManager() {} PuzzleManager::~PuzzleManager() = default;
size_t PuzzleManager::precomputedPuzzleCount() { return this->cached.size(); } size_t PuzzleManager::precomputed_puzzle_count() {
std::lock_guard lock{this->cache_lock};
bool PuzzleManager::precomputePuzzles(size_t limit) { return this->cached_puzzles.size();
while(precomputedPuzzleCount() < limit) generatePuzzle();
return true;
} }
std::shared_ptr<Puzzle> PuzzleManager::nextPuzzle() { bool PuzzleManager::precompute_puzzles(size_t amount) {
this->indexLock.lock(); std::random_device rd{};
size_t index = this->cacheIndex++ % this->cached.size(); std::mt19937 mt{rd()};
this->indexLock.unlock();
return this->cached[index]; while(this->precomputed_puzzle_count() < amount)
this->generate_puzzle();
return this->precomputed_puzzle_count() > 0;
} }
inline void rndNum(mp_int *result, int byteLength){ std::shared_ptr<Puzzle> PuzzleManager::next_puzzle() {
uint8_t buffer[byteLength]; std::lock_guard lock{this->cache_lock};
return this->cached_puzzles[this->cache_index++ % this->cached_puzzles.size()];
}
for(int index = 0; index < byteLength; index++) { inline void random_number(std::mt19937& generator, mp_int *result, int length){
int rnd = rand(); std::uniform_int_distribution<uint8_t> dist{};
uint8_t urnd = static_cast<uint8_t>(rnd & 0xFF);
buffer[index] = urnd; //TODO more secure!
} uint8_t buffer[length];
for(auto& byte : buffer)
byte = dist(generator);
mp_zero(result); mp_zero(result);
mp_read_unsigned_bin(result, buffer, byteLength); mp_read_unsigned_bin(result, buffer, length);
} }
inline bool solvePuzzle(Puzzle *puzzle){ inline bool solve_puzzle(Puzzle *puzzle) {
mp_int exp{}; mp_int exp{};
mp_init(&exp); mp_init(&exp);
mp_2expt(&exp, puzzle->level); mp_2expt(&exp, puzzle->level);
if (mp_exptmod(&puzzle->x, &exp, &puzzle->n, &puzzle->result) != CRYPT_OK) { //Sometimes it fails (unknow why :D) if (mp_exptmod(&puzzle->x, &exp, &puzzle->n, &puzzle->result) != CRYPT_OK) { //Sometimes it fails (unknown why :D)
mp_clear(&exp); mp_clear(&exp);
return false; return false;
} }
@ -66,17 +66,17 @@ inline bool write_bin_data(mp_int& data, uint8_t* result, size_t length) {
return true; return true;
} }
void PuzzleManager::generatePuzzle() { void PuzzleManager::generate_puzzle(std::mt19937& random_generator) {
auto puzzle = new Puzzle{}; auto puzzle = new Puzzle{};
puzzle->level = ts::config::voice::RsaPuzzleLevel;
mp_init_multi(&puzzle->x, &puzzle->n, &puzzle->result, nullptr); mp_init_multi(&puzzle->x, &puzzle->n, &puzzle->result, nullptr);
generate_new: generate_new:
rndNum(&puzzle->x, 64); random_number(random_generator, &puzzle->x, 64);
rndNum(&puzzle->n, 64); random_number(random_generator, &puzzle->n, 64);
puzzle->level = ts::config::voice::RsaPuzzleLevel;
if(!solvePuzzle(puzzle)) if(!solve_puzzle(puzzle))
goto generate_new; goto generate_new;
auto valid_x = mp_unsigned_bin_size(&puzzle->x) <= 64; auto valid_x = mp_unsigned_bin_size(&puzzle->x) <= 64;
@ -94,7 +94,7 @@ void PuzzleManager::generatePuzzle() {
if(!write_bin_data(puzzle->result, puzzle->data_result, 64)) if(!write_bin_data(puzzle->result, puzzle->data_result, 64))
goto generate_new; goto generate_new;
this->cached.push_back(shared_ptr<Puzzle>(puzzle, [](Puzzle* elm){ this->cached_puzzles.push_back(shared_ptr<Puzzle>(puzzle, [](Puzzle* elm){
mp_clear_multi(&elm->n, &elm->x, &elm->result, nullptr); mp_clear_multi(&elm->n, &elm->x, &elm->result, nullptr);
delete elm; delete elm;
})); }));

View File

@ -0,0 +1,39 @@
#pragma once
#include <tommath.h>
#include <memory>
#include <vector>
#include <misc/spin_lock.h>
#include <random>
namespace ts::server::server::udp {
struct Puzzle {
mp_int x;
mp_int n;
int level;
mp_int result;
uint8_t data_x[64];
uint8_t data_n[64];
uint8_t data_result[64];
};
class PuzzleManager {
public:
PuzzleManager();
~PuzzleManager();
[[nodiscard]] bool precompute_puzzles(size_t amount);
[[nodiscard]] size_t precomputed_puzzle_count();
[[nodiscard]] std::shared_ptr<Puzzle> next_puzzle();
private:
void generate_puzzle(std::mt19937&);
size_t cache_index{0};
spin_lock cache_lock{};
std::vector<std::shared_ptr<Puzzle>> cached_puzzles{};
};
}

View File

@ -0,0 +1,5 @@
//
// Created by WolverinDEV on 07/03/2020.
//
#include "UDPServer.h"

View File

@ -0,0 +1,107 @@
#pragma once
#include <thread>
#include <event.h>
#include <vector>
#include <misc/spin_lock.h>
#include <Definitions.h>
#include <mutex>
namespace ts::server {
class VoiceClient;
}
namespace ts::server::server::udp {
struct datagram_packet {
union pktinfo_storage {
in_pktinfo v4;
in6_pktinfo v6;
};
datagram_packet* next_packet;
sockaddr_storage address;
pktinfo_storage address_info;
size_t data_length;
uint8_t data[0];
};
static_assert(std::is_trivially_destructible<datagram_packet>::value);
static_assert(std::is_trivially_constructible<datagram_packet>::value);
template <typename T, size_t N>
struct write_ring_queue {
std::array<T, N> memory{};
size_t current_index{0};
size_t filled_index{0};
[[nodiscard]] constexpr inline auto max_size() const { return N; }
[[nodiscard]] inline size_t current_size() const { return this->filled_index - this->current_index; }
[[nodiscard]] inline bool pop_entry(T& result) {
if(this->current_index >= this->filled_index) return false;
return this->memory[this->current_index++ % N];
}
[[nodiscard]] inline bool push_entry(T&& entry) {
if(this->filled_index - this->current_index >= N) return false;
this->memory[this->filled_index++ % N] = std::forward(entry);
return true;
}
};
struct io_loop;
struct io_loop_entry {
io_loop* io_loop{nullptr};
int file_descriptor{0};
event* event_read{};
event* event_write{};
spin_lock write_queue_lock{};
datagram_packet* dg_write_queue_head{nullptr};
datagram_packet* dg_write_queue_tail{nullptr};
write_ring_queue<std::weak_ptr<VoiceClient>, 1024 * 8> voice_write_queue{};
};
struct io_loop {
std::thread base_dispatcher{};
struct event_base* event_base{nullptr};
std::mutex entries_mutex{};
std::vector<io_loop_entry*> registered_entries{};
};
struct io_binding {
VirtualServerId server_id{0};
sockaddr_storage address{};
size_t loop_entry_index{0};
std::vector<io_loop_entry*> loop_entries{};
struct server_client {
std::shared_ptr<VoiceClient> client{};
ClientId client_id{0};
};
std::mutex client_lock{};
std::deque<server_client> known_clients{};
};
class Server {
public:
void schedule_client_write(const std::shared_ptr<VoiceClient>& /* client */);
void unregister_client(const std::shared_ptr<VoiceClient>& /* client */);
private:
std::mutex io_lock{};
std::vector<io_loop*> io_loops{};
std::mutex bindings_lock{};
std::vector<io_binding*> io_bindings{};
};
}

View File

@ -317,13 +317,14 @@ ClientMoveResult ClientChannelService::client_move(const std::shared_ptr<Connect
} }
client_channel_lock.unlock(); client_channel_lock.unlock();
/* both methods lock if they require stuff */ /* both methods lock if they require stuff */
this->notifyClientPropertyUpdates(target, client_updates, s_source_channel ? true : false); this->virtual_server_->broadcast_service().client_updated(target, client_updates, s_source_channel ? true : false);
TIMING_STEP(timings, "notify cpro"); TIMING_STEP(timings, "notify cpro");
if(s_target_channel) { if(s_target_channel) {
target->updateChannelClientProperties(false, s_source_channel ? true : false); target->updateChannelClientProperties(false, s_source_channel ? true : false);
TIMING_STEP(timings, "notify_t_pr"); TIMING_STEP(timings, "notify_t_pr");
} }
debugMessage(this->get_server_id(), "{} Client move timings: {}", CLIENT_STR_LOG_PREFIX_(target), TIMING_FINISH(timings)); debugMessage(this->get_server_id(), "{} Client move timings: {}", CLIENT_STR_LOG_PREFIX_(target), TIMING_FINISH(timings));
return ClientMoveResult ::SUCCESS;
} }
/* /*
@ -361,7 +362,7 @@ ChannelDeleteResult ClientChannelService::delete_channel(std::shared_ptr<ServerC
std::deque<std::unique_lock<threads::Mutex>> command_locks; std::deque<std::unique_lock<threads::Mutex>> command_locks;
for(const auto& client : clients) for(const auto& client : clients)
command_locks.push_back(std::move(std::unique_lock(client->get_channel_lock()))); command_locks.push_back(std::move(client->lock_command_handling<std::unique_lock<threads::Mutex>>()));
for(const auto& client : clients) { for(const auto& client : clients) {
auto result = this->client_move(client, default_channel, invoker, kick_message, ViewReasonId::VREASON_CHANNEL_KICK, true, tree_lock); auto result = this->client_move(client, default_channel, invoker, kick_message, ViewReasonId::VREASON_CHANNEL_KICK, true, tree_lock);

View File

@ -62,7 +62,7 @@ std::vector<std::pair<ts::permission::PermissionType, ts::permission::v2::Permis
cache->client_database_id = client_dbid; cache->client_database_id = client_dbid;
if(!cache->client_permissions) if(!cache->client_permissions)
cache->client_permissions = serverInstance->databaseHelper()->loadClientPermissionManager(this->virtual_server_->server_ref(), client_dbid); cache->client_permissions = serverInstance->databaseHelper()->loadClientPermissionManager(this->get_server_id(), client_dbid);
bool have_skip_permission = false; bool have_skip_permission = false;
int skip_permission_type = -1; /* -1 := unset | 0 := skip, not explicit | 1 := skip, explicit */ int skip_permission_type = -1; /* -1 := unset | 0 := skip, not explicit | 1 := skip, explicit */
@ -361,7 +361,7 @@ PermissionResetResult PermissionService::reset_server_permissions() {
client->notifyChannelGroupList(); client->notifyChannelGroupList();
} }
if(this->notifyClientPropertyUpdates(client, group_manager->assignments().update_client_group_properties(client, client->getChannelId()))) { if(this->virtual_server_->broadcast_service().client_updated(client, group_manager->assignments().update_client_group_properties(client, client->getChannelId()))) {
if(client->update_cached_permissions()) /* update cached calculated permissions */ if(client->update_cached_permissions()) /* update cached calculated permissions */
client->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ client->sendNeededPermissions(false); /* cached permissions had changed, notify the client */
} }

View File

@ -51,7 +51,7 @@ namespace ts::server::permissions {
ClientType type, ClientType type,
ChannelId channel, ChannelId channel,
bool granted, bool granted,
std::shared_ptr<CalculateCache> cache{nullptr} std::shared_ptr<CalculateCache> cache = nullptr
); );
std::vector<std::pair<permission::PermissionType, permission::v2::PermissionFlaggedValue>> calculate_client_permissions( std::vector<std::pair<permission::PermissionType, permission::v2::PermissionFlaggedValue>> calculate_client_permissions(
@ -60,7 +60,7 @@ namespace ts::server::permissions {
ClientType type, ClientType type,
ChannelId channel, ChannelId channel,
bool granted, bool granted,
std::shared_ptr<CalculateCache> cache{nullptr} std::shared_ptr<CalculateCache> cache = nullptr
); );
private: private:
vserver::VirtualServerBase* virtual_server_{nullptr}; vserver::VirtualServerBase* virtual_server_{nullptr};

View File

@ -0,0 +1,5 @@
//
// Created by WolverinDEV on 07/03/2020.
//
#include "VirtualServerBroadcastService.h"

View File

@ -0,0 +1,31 @@
#pragma once
#include <memory>
#include <deque>
#include <Properties.h>
namespace ts::server {
class ConnectedClient;
}
namespace ts::server::vserver {
class VirtualServerBase;
class BroadcastService {
public:
explicit BroadcastService(VirtualServerBase*);
bool client_updated(const std::shared_ptr<ConnectedClient>& /* client */,
const std::deque<std::shared_ptr<property::PropertyDescription>>& /* keys */, bool /* notify_client */ = true);
inline bool client_updated(const std::shared_ptr<ConnectedClient>& client, const std::deque<property::ClientProperties>& keys, bool notify_client = true) {
if(keys.empty()) return false;
std::deque<std::shared_ptr<property::PropertyDescription>> _keys{};
for(const auto& key : keys) _keys.push_back(property::impl::info<property::ClientProperties>(key));
return this->client_updated(client, _keys, notify_client);
};
private:
VirtualServerBase* virtual_server_;
};
}

View File

@ -11,5 +11,5 @@ InformationService::InformationService(ts::server::vserver::VirtualServerBase *h
InformationService::~InformationService() {} InformationService::~InformationService() {}
float InformationService::averagePing() { float InformationService::averagePing() {
return -2;
} }

View File

@ -7,6 +7,7 @@
#include "../client/ConnectedClient.h" #include "../client/ConnectedClient.h"
#include "VirtualServerBase.h" #include "VirtualServerBase.h"
#include <log/LogUtils.h> #include <log/LogUtils.h>
#include <src/InstanceHandler.h>
using namespace ts::server::vserver; using namespace ts::server::vserver;
@ -78,6 +79,9 @@ VirtualServerStopResult VirtualServerBase::stop_server() {
VirtualServerStartResult VirtualServerBase::start_server_(ts::rwshared_lock<ts::rw_mutex> &slock, std::string &error) { VirtualServerStartResult VirtualServerBase::start_server_(ts::rwshared_lock<ts::rw_mutex> &slock, std::string &error) {
//TODO: Load server permissions, etc //TODO: Load server permissions, etc
error = "Not implemented";
return VirtualServerStartResult::CUSTOM;
} }
VirtualServerClientRegisterResult VirtualServerBase::register_client(const std::shared_ptr<ConnectedClient> &client) { VirtualServerClientRegisterResult VirtualServerBase::register_client(const std::shared_ptr<ConnectedClient> &client) {
@ -201,14 +205,14 @@ void VirtualServerBase::unregister_client(const std::shared_ptr<ConnectedClient>
} }
{ {
if(!chan_tree_lock.owns_lock()) auto channel_clients_lock = this->lock_channel_clients();
chan_tree_lock.lock(); if(client->getChannel()) {//We dont have to make him invisible if he hasn't even a channel
auto result = this->channel_service().client_move(client, nullptr, nullptr, "", ViewReasonId::VREASON_SERVER_LEFT, false, channel_clients_lock);;
if(cl->currentChannel) //We dont have to make him invisible if he hasnt even a channel if(result != channels::ClientMoveResult::SUCCESS)
this->client_move(cl, nullptr, nullptr, reason, ViewReasonId::VREASON_SERVER_LEFT, false, chan_tree_lock); logCritical(this->server_id(), "Failed to unregister client {} from the server channel tree ({}).", client->getDisplayName(), (int) result);
}
} }
serverInstance->databaseHelper()->saveClientPermissions(this->ref(), cl->getClientDatabaseId(), cl->clientPermissions); serverInstance->databaseHelper()->saveClientPermissions(this->server_id(), client->getClientDatabaseId(), client->permissions());
cl->setClientId(0); client->setClientId(0);
return true;
} }

View File

@ -4,6 +4,7 @@
#include <lock/rw_mutex.h> #include <lock/rw_mutex.h>
#include <PermissionRegister.h> #include <PermissionRegister.h>
#include <sql/SqlQuery.h> #include <sql/SqlQuery.h>
#include <src/services/VirtualServerBroadcastService.h>
#include "../services/PermissionsService.h" #include "../services/PermissionsService.h"
#include "../services/ClientChannelService.h" #include "../services/ClientChannelService.h"
@ -93,7 +94,8 @@ do { \
[[nodiscard]] inline const std::shared_ptr<stats::ConnectionStatistics>& server_connection_statistics() { return this->server_connection_statistics_; } [[nodiscard]] inline const std::shared_ptr<stats::ConnectionStatistics>& server_connection_statistics() { return this->server_connection_statistics_; }
[[nodiscard]] inline permissions::PermissionService& permission_service() { return this->permission_service_; } [[nodiscard]] inline permissions::PermissionService& permission_service() { return this->permission_service_; }
[[nodiscard]] inline BroadcastService& broadcast_service() { return this->broadcast_service_; }
[[nodiscard]] inline channels::ClientChannelService& channel_service() { return this->channel_service_; } [[nodiscard]] inline channels::ClientChannelService& channel_service() { return this->channel_service_; }
[[nodiscard]] inline ts::rwshared_lock<ts::rw_mutex> lock_channel_clients() { return ts::rwshared_lock{this->channel_clients_lock_, ts::rw_lock_shared}; } [[nodiscard]] inline ts::rwshared_lock<ts::rw_mutex> lock_channel_clients() { return ts::rwshared_lock{this->channel_clients_lock_, ts::rw_lock_shared}; }
[[nodiscard]] inline std::mutex& client_nickname_lock() { return this->client_nickname_lock_; } [[nodiscard]] inline std::mutex& client_nickname_lock() { return this->client_nickname_lock_; }
@ -135,6 +137,7 @@ do { \
/* some services */ /* some services */
permissions::PermissionService permission_service_; permissions::PermissionService permission_service_;
channels::ClientChannelService channel_service_; channels::ClientChannelService channel_service_;
BroadcastService broadcast_service_;
struct { struct {
size_t count{0}; size_t count{0};

2
shared

@ -1 +1 @@
Subproject commit 0d0d7dd1924ee93bcbe4875c3cf007117d05e4d7 Subproject commit 9533fe8920ea82313dcd49a4e003f39e50c7d81e