diff --git a/git-teaspeak b/git-teaspeak index 8d025ec..883a2f1 160000 --- a/git-teaspeak +++ b/git-teaspeak @@ -1 +1 @@ -Subproject commit 8d025ece01e81d23f965c0284e38b6743bbc6b5a +Subproject commit 883a2f1433576c75d5731d80681886795fb5c41b diff --git a/server/src/DatabaseHelper.cpp b/server/src/DatabaseHelper.cpp index 855a6ba..29b56f4 100644 --- a/server/src/DatabaseHelper.cpp +++ b/server/src/DatabaseHelper.cpp @@ -558,9 +558,9 @@ void DatabaseHelper::saveChannelPermissions(const std::shared_ptr DatabaseHelper::default_properties_client(std::shared_ptr properties, ClientType type){ +std::shared_ptr DatabaseHelper::default_properties_client(std::shared_ptr properties, ClientType type){ if(!properties) - properties = make_shared(); + properties = make_shared(); properties->register_property_type(); properties->register_property_type(); @@ -658,8 +658,8 @@ inline sql::result load_properties(ServerId sid, deque DatabaseHelper::loadServerProperties(const std::shared_ptr& server) { - auto props = std::make_shared(); +std::shared_ptr DatabaseHelper::loadServerProperties(const std::shared_ptr& server) { + auto props = std::make_shared(); props->register_property_type(); (*props)[property::VIRTUALSERVER_HOST] = config::binding::DefaultVoiceHost; @@ -732,8 +732,8 @@ std::shared_ptr DatabaseHelper::loadServerProperties(const std::shar return props; } -std::shared_ptr DatabaseHelper::loadPlaylistProperties(const std::shared_ptr& server, PlaylistId id) { - auto props = std::make_shared(); +std::shared_ptr DatabaseHelper::loadPlaylistProperties(const std::shared_ptr& server, PlaylistId id) { + auto props = std::make_shared(); props->register_property_type(); (*props)[property::PLAYLIST_ID] = id; @@ -805,9 +805,9 @@ std::shared_ptr DatabaseHelper::loadPlaylistProperties(const std::sh return props; } -std::shared_ptr DatabaseHelper::loadChannelProperties(const shared_ptr& server, ChannelId channel) { +std::shared_ptr DatabaseHelper::loadChannelProperties(const shared_ptr& server, ChannelId channel) { ServerId serverId = server ? server->getServerId() : 0U; - auto props = std::make_shared(); + auto props = std::make_shared(); props->register_property_type(); if(server) { @@ -886,7 +886,7 @@ std::shared_ptr DatabaseHelper::loadChannelProperties(const shared_p return props; } -std::shared_ptr DatabaseHelper::loadClientProperties(const std::shared_ptr& server, ClientDbId cldbid, ClientType type) { +std::shared_ptr DatabaseHelper::loadClientProperties(const std::shared_ptr& server, ClientDbId cldbid, ClientType type) { auto props = DatabaseHelper::default_properties_client(nullptr, type); if(server) { props->operator[](property::CLIENT_DESCRIPTION) = server->properties()[property::VIRTUALSERVER_DEFAULT_CLIENT_DESCRIPTION].value(); @@ -945,8 +945,11 @@ std::shared_ptr DatabaseHelper::loadClientProperties(const std::shar logTrace(server ? server->getServerId() : 0, "[Property] Not saving property '" + std::string{prop.type().name} + "', changed for " + to_string(cldbid) + " (New value: " + prop.value() + ")"); return; } - if(!prop.get_handle()) return; - if(!prop.get_handle()->isSaveEnabled()) return; + + auto handle = prop.get_handle(); + if(!handle || !handle->isSaveEnabled()) { + return; + } if(!prop.hasDbReference() && (prop.default_value() == prop.value())) return; //No changes to default value prop.setModified(false); diff --git a/server/src/DatabaseHelper.h b/server/src/DatabaseHelper.h index 8dae742..3a54c10 100644 --- a/server/src/DatabaseHelper.h +++ b/server/src/DatabaseHelper.h @@ -68,7 +68,7 @@ namespace ts::server { struct StartupCacheEntry; class DatabaseHelper { public: - static std::shared_ptr default_properties_client(std::shared_ptr /* properties */, ClientType /* type */); + static std::shared_ptr default_properties_client(std::shared_ptr /* properties */, ClientType /* type */); static bool assignDatabaseId(sql::SqlManager *, ServerId serverId, std::shared_ptr); explicit DatabaseHelper(sql::SqlManager*); @@ -104,10 +104,10 @@ namespace ts::server { std::shared_ptr loadPlaylistPermissions(const std::shared_ptr&, PlaylistId /* playlist id */); void savePlaylistPermissions(const std::shared_ptr&, PlaylistId, const std::shared_ptr& /* permission manager */); - std::shared_ptr loadServerProperties(const std::shared_ptr&); //Read and write - std::shared_ptr loadPlaylistProperties(const std::shared_ptr&, PlaylistId); //Read and write - std::shared_ptr loadChannelProperties(const std::shared_ptr&, ChannelId); //Read and write - std::shared_ptr loadClientProperties(const std::shared_ptr&, ClientDbId, ClientType); + std::shared_ptr loadServerProperties(const std::shared_ptr&); //Read and write + std::shared_ptr loadPlaylistProperties(const std::shared_ptr&, PlaylistId); //Read and write + std::shared_ptr loadChannelProperties(const std::shared_ptr&, ChannelId); //Read and write + std::shared_ptr loadClientProperties(const std::shared_ptr&, ClientDbId, ClientType); void deleteGroupArtifacts(ServerId, GroupId); bool deleteChannelPermissions(const std::shared_ptr&, ChannelId); diff --git a/server/src/FileServerHandler.cpp b/server/src/FileServerHandler.cpp index 4fb641d..4bccb4d 100644 --- a/server/src/FileServerHandler.cpp +++ b/server/src/FileServerHandler.cpp @@ -14,7 +14,9 @@ using namespace ts::server::file; FileServerHandler::FileServerHandler(ts::server::InstanceHandler *instance) : instance_{instance} {} bool FileServerHandler::initialize(std::string &error) { - if(!file::initialize(error, serverInstance->properties()[property::SERVERINSTANCE_FILETRANSFER_HOST].as(), serverInstance->properties()[property::SERVERINSTANCE_FILETRANSFER_PORT].as())) { + if(!file::initialize(error, + serverInstance->properties()[property::SERVERINSTANCE_FILETRANSFER_HOST].value(), + serverInstance->properties()[property::SERVERINSTANCE_FILETRANSFER_PORT].as_or(30303))) { return false; } @@ -46,21 +48,21 @@ void FileServerHandler::callback_transfer_registered(const std::shared_ptrexpected_file_size - transfer->file_offset; if(transfer->direction == transfer::Transfer::DIRECTION_UPLOAD) { - server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_UPLOADED] += (int64_t) bytes; - server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED] += (int64_t) bytes; + server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_UPLOADED].increment_by(bytes); + server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED].increment_by(bytes); } else { - server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED] += (int64_t) bytes; - server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED] += (int64_t) bytes; + server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED].increment_by(bytes); + server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED].increment_by(bytes); } auto client = server->find_client_by_id(transfer->client_id); if(client && client->getUid() == transfer->client_unique_id) { if(transfer->direction == transfer::Transfer::DIRECTION_UPLOAD) { - client->properties()[property::CLIENT_TOTAL_BYTES_UPLOADED] += (int64_t) bytes; - client->properties()[property::CLIENT_MONTH_BYTES_UPLOADED] += (int64_t) bytes; + client->properties()[property::CLIENT_TOTAL_BYTES_UPLOADED].increment_by(bytes); + client->properties()[property::CLIENT_MONTH_BYTES_UPLOADED].increment_by(bytes); } else { - client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED] += (int64_t) bytes; - client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED] += (int64_t) bytes; + client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED].increment_by(bytes); + client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED].increment_by(bytes); } } } @@ -76,21 +78,21 @@ void FileServerHandler::callback_transfer_aborted(const std::shared_ptrdirection == transfer::Transfer::DIRECTION_UPLOAD) { - server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_UPLOADED] += -bytes_left; - server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED] += -bytes_left; + server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_UPLOADED].increment_by(-bytes_left); + server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED].increment_by(-bytes_left); } else { - server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED] += -bytes_left; - server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED] += -bytes_left; + server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED].increment_by(-bytes_left); + server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED].increment_by(-bytes_left); } auto client = server->find_client_by_id(transfer->client_id); if(client && client->getUid() == transfer->client_unique_id) { if(transfer->direction == transfer::Transfer::DIRECTION_UPLOAD) { - client->properties()[property::CLIENT_TOTAL_BYTES_UPLOADED] += -bytes_left; - client->properties()[property::CLIENT_MONTH_BYTES_UPLOADED] += -bytes_left; + client->properties()[property::CLIENT_TOTAL_BYTES_UPLOADED].increment_by(-bytes_left); + client->properties()[property::CLIENT_MONTH_BYTES_UPLOADED].increment_by(-bytes_left); } else { - client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED] += -bytes_left; - client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED] += -bytes_left; + client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED].increment_by(-bytes_left); + client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED].increment_by(-bytes_left); } ts::command_builder notify{"notifystatusfiletransfer"}; diff --git a/server/src/Group.cpp b/server/src/Group.cpp index ab8507d..19ed935 100644 --- a/server/src/Group.cpp +++ b/server/src/Group.cpp @@ -18,7 +18,7 @@ Group::Group(GroupManager* handle, GroupTarget target, GroupType type, GroupId g memtrack::allocated(this); this->handle = handle; - this->_properties = new Properties(); + this->_properties = std::make_shared(); this->_properties->register_property_type(); this->setPermissionManager(make_shared()); @@ -83,7 +83,6 @@ void Group::apply_properties_from_permissions() { } Group::~Group() { - delete this->_properties; memtrack::freed(this); } @@ -262,8 +261,9 @@ std::shared_ptr GroupManager::defaultGroup(GroupTarget type, bool enforce 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() : - serverInstance->properties()[property::SERVERINSTANCE_GUEST_SERVERQUERY_GROUP].as_save(); + server->properties()[type == GroupTarget::GROUPTARGET_SERVER ? property::VIRTUALSERVER_DEFAULT_SERVER_GROUP + : property::VIRTUALSERVER_DEFAULT_CHANNEL_GROUP].as_or(0) : + serverInstance->properties()[property::SERVERINSTANCE_GUEST_SERVERQUERY_GROUP].as_or(0); auto group = this->findGroupLocal(id); if(group || enforce_property) return group; @@ -821,8 +821,8 @@ std::vector> GroupManager::defaultServerGroupGr auto server = this->server.lock(); auto id = server ? - server->properties()[property::VIRTUALSERVER_DEFAULT_MUSIC_GROUP].as_save() : - serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_MUSICDEFAULT_GROUP].as_save(); + server->properties()[property::VIRTUALSERVER_DEFAULT_MUSIC_GROUP].as_or(0) : + serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_MUSICDEFAULT_GROUP].as_or(0); auto group = this->findGroupLocal(id); if(group) { result.push_back(std::make_shared(nullptr, this->getServerId(), 0, group, time_point())); diff --git a/server/src/InstanceHandler.cpp b/server/src/InstanceHandler.cpp index 16dba77..b8e5eb2 100644 --- a/server/src/InstanceHandler.cpp +++ b/server/src/InstanceHandler.cpp @@ -67,7 +67,7 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql), permission_hel this->action_logger_->finalize(); } - this->_properties = new Properties(); + this->_properties = std::make_shared(); this->_properties->register_property_type(); this->properties()[property::SERVERINSTANCE_FILETRANSFER_PORT] = ts::config::binding::DefaultFilePort; this->properties()[property::SERVERINSTANCE_FILETRANSFER_HOST] = ts::config::binding::DefaultFileHost; @@ -205,8 +205,12 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql), permission_hel this->save_channel_permissions(); } } - if(!this->default_tree->getDefaultChannel()) this->default_tree->setDefaultChannel(this->default_tree->findChannel("[cspacer04]Default Channel", nullptr)); - if(!this->default_tree->getDefaultChannel()) this->default_tree->setDefaultChannel(*this->default_tree->channels().begin()); + if(!this->default_tree->getDefaultChannel()) { + this->default_tree->setDefaultChannel(this->default_tree->findChannel("[cspacer04]Default Channel", nullptr)); + } + if(!this->default_tree->getDefaultChannel()) { + this->default_tree->setDefaultChannel(*this->default_tree->channels().begin()); + } assert(this->default_tree->getDefaultChannel()); } @@ -215,7 +219,7 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql), permission_hel } - if(this->properties()[property::SERVERINSTANCE_MONTHLY_TIMESTAMP].as() == 0) { + if(this->properties()[property::SERVERINSTANCE_MONTHLY_TIMESTAMP].as_or(0) == 0) { debugMessage(LOG_INSTANCE, "Setting up monthly reset timestamp!"); this->properties()[property::SERVERINSTANCE_MONTHLY_TIMESTAMP] = duration_cast(system_clock::now().time_since_epoch()).count(); } @@ -225,7 +229,6 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql), permission_hel } InstanceHandler::~InstanceHandler() { - delete this->_properties; delete this->banMgr; delete this->dbHelper; @@ -330,8 +333,8 @@ bool InstanceHandler::startInstance() { } { - auto query_bindings_string = this->properties()[property::SERVERINSTANCE_QUERY_HOST].as(); - auto query_port = this->properties()[property::SERVERINSTANCE_QUERY_PORT].as(); + auto query_bindings_string = this->properties()[property::SERVERINSTANCE_QUERY_HOST].value(); + auto query_port = this->properties()[property::SERVERINSTANCE_QUERY_PORT].as_or(0); auto query_bindings = net::resolve_bindings(query_bindings_string, query_port); deque> bindings; @@ -503,7 +506,8 @@ void InstanceHandler::tickInstance() { { ALARM_TIMER(t, "InstanceHandler::tickInstance -> statistics tick [monthly]", milliseconds(2)); - auto month_timestamp = system_clock::time_point() + seconds(this->properties()[property::SERVERINSTANCE_MONTHLY_TIMESTAMP].as()); + auto month_timestamp = system_clock::time_point() + seconds( + this->properties()[property::SERVERINSTANCE_MONTHLY_TIMESTAMP].as_or(0)); auto time_t_old = system_clock::to_time_t(month_timestamp); auto time_t_new = system_clock::to_time_t(system_clock::now()); @@ -562,9 +566,9 @@ void InstanceHandler::tickInstance() { this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_ALIVE] = this->calculateSpokenTime().count(); this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_TOTAL] = - this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_ALIVE].as_save() + - this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_DELETED].as_save() + - this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_VARIANZ].as_save(); + this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_ALIVE].as_or(0) + + this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_DELETED].as_or(0) + + this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_VARIANZ].as_or(0); } } @@ -647,10 +651,10 @@ std::shared_ptr InstanceHandler::gener request->metrics.web_clients_online = report.clients_web; request->metrics.bots_online = report.bots; request->metrics.queries_online = report.queries; - request->metrics.speech_total = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_TOTAL].as(); - request->metrics.speech_varianz = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_VARIANZ].as(); - request->metrics.speech_online = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_ALIVE].as(); - request->metrics.speech_dead = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_DELETED].as(); + request->metrics.speech_total = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_TOTAL].as_or(0); + request->metrics.speech_varianz = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_VARIANZ].as_or(0); + request->metrics.speech_online = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_ALIVE].as_or(0); + request->metrics.speech_dead = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_DELETED].as_or(0); static std::string null_str{"\0\0\0\0\0\0\0\0", 8}; /* we need at least some characters */ request->web_certificate_revision = this->web_cert_revision.empty() ? null_str : this->web_cert_revision; @@ -673,11 +677,11 @@ std::shared_ptr InstanceHandler::gener { /* unique id */ auto property_unique_id = this->properties()[property::SERVERINSTANCE_UNIQUE_ID]; - if(property_unique_id.as().empty()) + if(property_unique_id.value().empty()) property_unique_id = rnd_string(64); auto hash = digest::sha256(request->info.uname); - hash = digest::sha256(hash + property_unique_id.as() + get_mac_address()); + hash = digest::sha256(hash + property_unique_id.value() + get_mac_address()); request->info.unique_id = base64::encode(hash); } } @@ -896,7 +900,7 @@ bool InstanceHandler::validate_default_groups() { { auto property = this->properties()[property::SERVERINSTANCE_ADMIN_SERVERQUERY_GROUP]; - auto group_id = property.as_save(); + auto group_id = property.as_or(0); debugMessage(LOG_INSTANCE, "Instance admin query group id {}", group_id); auto group_instance = this->group_manager_->server_groups()->find_group(GroupCalculateMode::GLOBAL, group_id); @@ -924,7 +928,7 @@ bool InstanceHandler::validate_default_groups() { { auto property = this->properties()[property::SERVERINSTANCE_GUEST_SERVERQUERY_GROUP]; - auto group_id = property.as_save(); + auto group_id = property.as_or(0); debugMessage(LOG_INSTANCE, "Instance guest query group id {}", group_id); auto group_instance = this->group_manager_->server_groups()->find_group(GroupCalculateMode::GLOBAL, group_id); diff --git a/server/src/InstanceHandler.h b/server/src/InstanceHandler.h index 1cbc329..9798894 100644 --- a/server/src/InstanceHandler.h +++ b/server/src/InstanceHandler.h @@ -73,9 +73,8 @@ namespace ts { bool startInstance(); void stopInstance(); - ts::Properties& properties(){ - return *_properties; - } + inline PropertyWrapper properties() { return PropertyWrapper{this->_properties}; } + inline const PropertyWrapper properties() const { return PropertyWrapper{this->_properties}; } std::shared_ptr getInitialServerAdmin(){ return globalServerAdmin; } const auto& group_manager(){ return this->group_manager_; } @@ -106,16 +105,16 @@ namespace ts { [[nodiscard]] inline const auto& general_task_executor(){ return this->general_task_executor_; } - std::shared_ptr getStatistics(){ return statistics; } - std::shared_ptr generateLicenseData(); + [[nodiscard]] inline std::shared_ptr getStatistics(){ return statistics; } + [[nodiscard]] std::shared_ptr generateLicenseData(); - std::shared_ptr getTeamSpeakLicense() { return this->teamspeak_license; } - std::shared_ptr getDefaultServerProperties() { return this->default_server_properties; } - std::shared_ptr getWebIoLoop() { return this->web_event_loop; } - std::shared_ptr getWebList() { return this->web_list; } + [[nodiscard]] inline std::shared_ptr getTeamSpeakLicense() { return this->teamspeak_license; } + [[nodiscard]] inline PropertyWrapper getDefaultServerProperties() { return PropertyWrapper{this->default_server_properties}; } + [[nodiscard]] inline std::shared_ptr getWebIoLoop() { return this->web_event_loop; } + [[nodiscard]] inline std::shared_ptr getWebList() { return this->web_list; } - std::shared_ptr getPermissionMapper() { return this->permission_mapper; } - std::shared_ptr getConversationIo() { return this->conversation_io; } + [[nodiscard]] inline std::shared_ptr getPermissionMapper() { return this->permission_mapper; } + [[nodiscard]] inline std::shared_ptr getConversationIo() { return this->conversation_io; } [[nodiscard]] inline const auto& server_command_executor() { return this->server_command_executor_; } [[nodiscard]] inline const auto& permission_helper() { return this->permission_helper_; } @@ -146,7 +145,7 @@ namespace ts { file::FileServerHandler* file_server_handler_{nullptr}; std::unique_ptr action_logger_{nullptr}; - ts::Properties* _properties = nullptr; + std::shared_ptr _properties{}; std::shared_ptr server_command_executor_{}; @@ -154,7 +153,7 @@ namespace ts { std::shared_ptr web_event_loop = nullptr; std::shared_ptr web_list = nullptr; - std::shared_ptr default_server_properties = nullptr; + std::shared_ptr default_server_properties = nullptr; std::shared_mutex default_tree_lock; std::shared_ptr default_tree = nullptr; diff --git a/server/src/ServerManagerSnapshotDeploy.cpp b/server/src/ServerManagerSnapshotDeploy.cpp index 4d76f87..212c2e8 100644 --- a/server/src/ServerManagerSnapshotDeploy.cpp +++ b/server/src/ServerManagerSnapshotDeploy.cpp @@ -782,14 +782,14 @@ bool VirtualServerManager::createServerSnapshot(Command &cmd, shared_ptrproperties().list_properties(property::FLAG_SNAPSHOT)) { + for(const auto& serverProperty : server->properties()->list_properties(property::FLAG_SNAPSHOT)) { if(version == 0) { switch (serverProperty.type().property_index) { case property::VIRTUALSERVER_DOWNLOAD_QUOTA: case property::VIRTUALSERVER_UPLOAD_QUOTA: case property::VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH: case property::VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH: - cmd[index][std::string{serverProperty.type().name}] = (uint64_t) serverProperty.as_save(); + cmd[index][std::string{serverProperty.type().name}] = (uint64_t) serverProperty.as_or(0); default: break; } @@ -803,13 +803,14 @@ bool VirtualServerManager::createServerSnapshot(Command &cmd, shared_ptrgetChannelTree()->channels()) { - for(const auto& channelProperty : channel->properties().list_properties(property::FLAG_SNAPSHOT)) { - if(channelProperty.type() == property::CHANNEL_ID) - cmd[index]["channel_id"] = channelProperty.as(); - else if(channelProperty.type() == property::CHANNEL_PID) - cmd[index]["channel_pid"] = channelProperty.as(); - else - cmd[index][std::string{channelProperty.type().name}] = channelProperty.as(); + for(const auto& channelProperty : channel->properties()->list_properties(property::FLAG_SNAPSHOT)) { + if(channelProperty.type() == property::CHANNEL_ID) { + cmd[index]["channel_id"] = channelProperty.value(); + } else if(channelProperty.type() == property::CHANNEL_PID) { + cmd[index]["channel_pid"] = channelProperty.value(); + } else { + cmd[index][std::string{channelProperty.type().name}] = channelProperty.value(); + } } index++; } diff --git a/server/src/TS3ServerClientManager.cpp b/server/src/TS3ServerClientManager.cpp index 8259c9e..3bf61b2 100644 --- a/server/src/TS3ServerClientManager.cpp +++ b/server/src/TS3ServerClientManager.cpp @@ -76,12 +76,12 @@ bool VirtualServer::registerClient(shared_ptr client) { if(client->getType() == ClientType::CLIENT_TEAMSPEAK || client->getType() == ClientType::CLIENT_WEB) { - this->properties()[property::VIRTUALSERVER_CLIENT_CONNECTIONS] ++; //increase manager connections + this->properties()[property::VIRTUALSERVER_CLIENT_CONNECTIONS].increment_by(1); //increase manager connections this->properties()[property::VIRTUALSERVER_LAST_CLIENT_CONNECT] = duration_cast(system_clock::now().time_since_epoch()).count(); } else if(client->getType() == ClientType::CLIENT_QUERY) { this->properties()[property::VIRTUALSERVER_LAST_QUERY_CONNECT] = duration_cast(system_clock::now().time_since_epoch()).count(); - this->properties()[property::VIRTUALSERVER_QUERY_CLIENT_CONNECTIONS] ++; //increase manager connections + this->properties()[property::VIRTUALSERVER_QUERY_CLIENT_CONNECTIONS].increment_by(1); //increase manager connections } return true; @@ -567,7 +567,8 @@ void VirtualServer::client_move( this->groups->setChannelGroup(target->getClientDatabaseId(), nullptr, s_source_channel); } - auto update = target->properties()[property::CLIENT_IS_TALKER].as() || target->properties()[property::CLIENT_TALK_REQUEST].as() > 0; + auto update = target->properties()[property::CLIENT_IS_TALKER].as_or(false) || + target->properties()[property::CLIENT_TALK_REQUEST].as_or(0) > 0; if(update) { target->properties()[property::CLIENT_IS_TALKER] = 0; target->properties()[property::CLIENT_TALK_REQUEST] = 0; diff --git a/server/src/TS3ServerHeartbeat.cpp b/server/src/TS3ServerHeartbeat.cpp index 4352f98..59f0f00 100644 --- a/server/src/TS3ServerHeartbeat.cpp +++ b/server/src/TS3ServerHeartbeat.cpp @@ -99,8 +99,8 @@ void VirtualServer::executeServerTick() { { BEGIN_TIMINGS(); - auto flood_decrease = this->properties()[property::VIRTUALSERVER_ANTIFLOOD_POINTS_TICK_REDUCE].as(); - auto flood_block = this->properties()[property::VIRTUALSERVER_ANTIFLOOD_POINTS_NEEDED_IP_BLOCK].as(); + auto flood_decrease = this->properties()[property::VIRTUALSERVER_ANTIFLOOD_POINTS_TICK_REDUCE].as_or(0); + auto flood_block = this->properties()[property::VIRTUALSERVER_ANTIFLOOD_POINTS_NEEDED_IP_BLOCK].as_or(0); bool flag_update_spoken = this->spoken_time_timestamp + seconds(30) < system_clock::now(); @@ -183,11 +183,10 @@ void VirtualServer::executeServerTick() { if(server_channel->client_count() > 0 || !this->getClientsByChannelRoot(channel, true).empty()) continue; - seconds deleteTimeout(0); - if(channel->properties().hasProperty(property::CHANNEL_DELETE_DELAY)) - deleteTimeout = seconds(channel->properties()[property::CHANNEL_DELETE_DELAY].as()); + seconds deleteTimeout{channel->properties()[property::CHANNEL_DELETE_DELAY].as_or(0)}; - auto last_left = time_point() + milliseconds(channel->properties()[property::CHANNEL_LAST_LEFT].as()); + auto last_left = time_point() + milliseconds( + channel->properties()[property::CHANNEL_LAST_LEFT].as_or(0)); auto channel_created = channel->createdTimestamp(); if(system_clock::now() - last_left < deleteTimeout) continue; //One second stay diff --git a/server/src/VirtualServer.cpp b/server/src/VirtualServer.cpp index a07350f..f0c2a7f 100644 --- a/server/src/VirtualServer.cpp +++ b/server/src/VirtualServer.cpp @@ -55,19 +55,19 @@ bool VirtualServer::initialize(bool test_properties) { this->_properties = serverInstance->databaseHelper()->loadServerProperties(self.lock()); this->_properties->registerNotifyHandler([&](Property& prop){ if(prop.type() == property::VIRTUALSERVER_DISABLE_IP_SAVING) { - this->_disable_ip_saving = prop.as(); + this->_disable_ip_saving = prop.as_or(false); return; } else if(prop.type() == property::VIRTUALSERVER_CODEC_ENCRYPTION_MODE) { - this->_voice_encryption_mode = prop.as(); + this->_voice_encryption_mode = prop.as_or(0); return; } else if(prop.type() == property::VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH) { auto file_vs = file::server()->find_virtual_server(this->getServerId()); if(!file_vs) return; - file_vs->max_networking_upload_bandwidth(prop.as_save([]{ return -1; })); + file_vs->max_networking_upload_bandwidth(prop.as_or(-1)); } else if(prop.type() == property::VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH) { auto file_vs = file::server()->find_virtual_server(this->getServerId()); if(!file_vs) return; - file_vs->max_networking_download_bandwidth(prop.as_save([]{ return -1; })); + file_vs->max_networking_download_bandwidth(prop.as_or(-1)); } std::string sql{}; if(prop.type() == property::VIRTUALSERVER_HOST) @@ -118,7 +118,8 @@ bool VirtualServer::initialize(bool test_properties) { return; } - serverInstance->action_logger()->toggle_logging_group(server_id, action_type, prop.as_save([]{ return true; })); + serverInstance->action_logger()->toggle_logging_group(server_id, action_type, + prop.as_or(true)); }; for(const property::VirtualServerProperties& property : { @@ -129,7 +130,7 @@ bool VirtualServer::initialize(bool test_properties) { property::VIRTUALSERVER_LOG_QUERY, property::VIRTUALSERVER_LOG_PERMISSIONS }) { - auto prop = this->_properties->find(property::PROP_TYPE_SERVER, property); + auto prop = this->_properties->get(property::PROP_TYPE_SERVER, property); sync_property(prop); } @@ -138,10 +139,10 @@ bool VirtualServer::initialize(bool test_properties) { }); } - if(!properties()[property::VIRTUALSERVER_KEYPAIR].as().empty()){ + if(!properties()[property::VIRTUALSERVER_KEYPAIR].value().empty()){ debugMessage(this->serverId, "Importing server keypair"); this->_serverKey = new ecc_key; - auto bytes = base64::decode(properties()[property::VIRTUALSERVER_KEYPAIR].as()); + auto bytes = base64::decode(properties()[property::VIRTUALSERVER_KEYPAIR].value()); int err; if((err = ecc_import(reinterpret_cast(bytes.data()), bytes.length(), this->_serverKey)) != CRYPT_OK){ logError(this->getServerId(), "Cant import key. ({} => {})", err, error_to_string(err)); @@ -218,7 +219,7 @@ bool VirtualServer::initialize(bool test_properties) { if(!channelTree->getDefaultChannel()) channelTree->setDefaultChannel(*channelTree->channels().begin()); auto default_channel = channelTree->getDefaultChannel(); assert(default_channel); - if(default_channel->properties()[property::CHANNEL_FLAG_PASSWORD].as()) + if(default_channel->properties()[property::CHANNEL_FLAG_PASSWORD].as_or(false)) default_channel->properties()[property::CHANNEL_FLAG_PASSWORD] = false; this->tokenManager = new token::TokenManager(this->sql, this->getServerId()); @@ -261,7 +262,7 @@ bool VirtualServer::initialize(bool test_properties) { } if (initialize_groups) { - if(!this->properties()[property::VIRTUALSERVER_AUTOGENERATED_PRIVILEGEKEY].as().empty()) { + if(!this->properties()[property::VIRTUALSERVER_AUTOGENERATED_PRIVILEGEKEY].value().empty()) { logCritical(this->getServerId(), "Missing default groups. Applying permission reset!"); } @@ -285,11 +286,14 @@ bool VirtualServer::initialize(bool test_properties) { server_statistics_ = make_shared(serverInstance->getStatistics()); - this->serverRoot = std::make_shared(this->sql, self.lock(), this->properties()[property::VIRTUALSERVER_NAME].as(), false); + this->serverRoot = std::make_shared(this->sql, self.lock(), + this->properties()[property::VIRTUALSERVER_NAME].value(), false); this->serverRoot->initialize_weak_reference(this->serverRoot); - this->properties().registerNotifyHandler([&](Property& property) { - if(property.type() == property::VIRTUALSERVER_NAME) static_pointer_cast(this->serverRoot)->properties()[property::CLIENT_NICKNAME] = property.as(); + this->properties()->registerNotifyHandler([&](Property& property) { + if(property.type() == property::VIRTUALSERVER_NAME) { + static_pointer_cast(this->serverRoot)->properties()[property::CLIENT_NICKNAME] = property.value(); + } }); this->serverRoot->server = nullptr; @@ -322,8 +326,10 @@ bool VirtualServer::initialize(bool test_properties) { this->properties()[property::VIRTUALSERVER_FILEBASE] = file::server()->file_base_path(); - file_vs->max_networking_download_bandwidth(this->properties()[property::VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH].as_save([]{ return -1; })); - file_vs->max_networking_upload_bandwidth(this->properties()[property::VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH].as_save([]{ return -1; })); + file_vs->max_networking_download_bandwidth( + this->properties()[property::VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH].as_or(-1)); + file_vs->max_networking_upload_bandwidth( + this->properties()[property::VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH].as_or(-1)); } this->channelTree->printChannelTree([&](std::string msg){ debugMessage(this->serverId, msg); }); @@ -441,7 +447,7 @@ bool VirtualServer::start(std::string& error) { } } - auto host = this->properties()[property::VIRTUALSERVER_HOST].as(); + auto host = this->properties()[property::VIRTUALSERVER_HOST].value(); if(config::binding::enforce_default_voice_host) host = config::binding::DefaultVoiceHost; @@ -450,7 +456,7 @@ bool VirtualServer::start(std::string& error) { this->stop("failed to start", true); return false; } - if(this->properties()[property::VIRTUALSERVER_PORT].as() <= 0){ + if(this->properties()[property::VIRTUALSERVER_PORT].as_or(0) <= 0){ error = "invalid port"; this->stop("failed to start", true); return false; @@ -463,7 +469,7 @@ bool VirtualServer::start(std::string& error) { sockaddr_in addr{}; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; - addr.sin_port = htons(this->properties()[property::VIRTUALSERVER_PORT].as()); + addr.sin_port = htons(this->properties()[property::VIRTUALSERVER_PORT].as_or(0)); if(!evaluateAddress4(address, addr.sin_addr)) { logError(this->serverId, "Fail to resolve v4 address info for \"{}\"", address); continue; @@ -474,7 +480,7 @@ bool VirtualServer::start(std::string& error) { sockaddr_in6 addr{}; memset(&addr, 0, sizeof(addr)); addr.sin6_family = AF_INET6; - addr.sin6_port = htons(this->properties()[property::VIRTUALSERVER_PORT].as()); + addr.sin6_port = htons(this->properties()[property::VIRTUALSERVER_PORT].as_or(0)); if(!evaluateAddress6(address, addr.sin6_addr)) { logError(this->serverId, "Fail to resolve v6 address info for \"{}\"", address); continue; @@ -504,11 +510,11 @@ bool VirtualServer::start(std::string& error) { if(ts::config::web::activated && serverInstance->sslManager()->web_ssl_options()) { string web_host_string = this->properties()[property::VIRTUALSERVER_WEB_HOST]; if(web_host_string.empty()) - web_host_string = this->properties()[property::VIRTUALSERVER_HOST].as(); + web_host_string = this->properties()[property::VIRTUALSERVER_HOST].as_or(0); - auto web_port = this->properties()[property::VIRTUALSERVER_WEB_PORT].as(); + auto web_port = this->properties()[property::VIRTUALSERVER_WEB_PORT].as_or(0); if(web_port == 0) - web_port = this->properties()[property::VIRTUALSERVER_PORT].as(); + web_port = this->properties()[property::VIRTUALSERVER_PORT].as_or(0); startTimestamp = std::chrono::system_clock::now(); #ifdef COMPILE_WEB_CLIENT @@ -687,6 +693,7 @@ OnlineClientReport VirtualServer::onlineStats() { switch (cl->getType()) { case CLIENT_TEAMSPEAK: + case CLIENT_TEASPEAK: response.clients_ts++; break; case CLIENT_WEB: @@ -698,6 +705,8 @@ OnlineClientReport VirtualServer::onlineStats() { case CLIENT_MUSIC: response.bots++; break; + case CLIENT_INTERNAL: + case MAX: default: break; } @@ -846,7 +855,7 @@ bool VirtualServer::notifyServerEdited(std::shared_ptr invoker, logError(this->getServerId(), "Tried to broadcast a server update with an unknown info: " + key); continue; } - cmd[key] = properties()[info].as(); + cmd[key] = properties()[info].value(); } this->forEachClient([&cmd](shared_ptr client){ client->sendCommand(cmd); @@ -1128,7 +1137,7 @@ permission::v2::PermissionFlaggedValue VirtualServer::calculate_permission( } bool VirtualServer::verifyServerPassword(std::string password, bool hashed) { - if(!this->properties()[property::VIRTUALSERVER_FLAG_PASSWORD].as()) return true; + if(!this->properties()[property::VIRTUALSERVER_FLAG_PASSWORD].as_or(false)) return true; if(password.empty()) return false; if(!hashed){ @@ -1137,7 +1146,7 @@ bool VirtualServer::verifyServerPassword(std::string password, bool hashed) { password = base64_encode(string(buffer, SHA_DIGEST_LENGTH)); } - return password == this->properties()[property::VIRTUALSERVER_PASSWORD].as(); + return password == this->properties()[property::VIRTUALSERVER_PASSWORD].value(); } VirtualServer::NetworkReport VirtualServer::generate_network_report() { @@ -1184,12 +1193,17 @@ bool VirtualServer::resetPermissions(std::string& new_permission_token) { } //Server admin - auto default_server_admin = serverInstance->group_manager()->findGroup(serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_SERVERADMIN_GROUP].as()); - auto default_server_music = serverInstance->group_manager()->findGroup(serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_MUSICDEFAULT_GROUP].as()); - auto default_server_guest = serverInstance->group_manager()->findGroup(serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_SERVERDEFAULT_GROUP].as()); + auto default_server_admin = serverInstance->group_manager()->findGroup( + serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_SERVERADMIN_GROUP].as_or(0)); + auto default_server_music = serverInstance->group_manager()->findGroup( + serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_MUSICDEFAULT_GROUP].as_or(0)); + auto default_server_guest = serverInstance->group_manager()->findGroup( + serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_SERVERDEFAULT_GROUP].as_or(0)); - auto default_channel_admin = serverInstance->group_manager()->findGroup(serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_CHANNELADMIN_GROUP].as()); - auto default_channel_guest = serverInstance->group_manager()->findGroup(serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_CHANNELDEFAULT_GROUP].as()); + auto default_channel_admin = serverInstance->group_manager()->findGroup( + serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_CHANNELADMIN_GROUP].as_or(0)); + auto default_channel_guest = serverInstance->group_manager()->findGroup( + serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_CHANNELDEFAULT_GROUP].as_or(0)); if(!default_server_guest) { logCritical(0, "Missing default server guest template group!"); @@ -1291,7 +1305,8 @@ void VirtualServer::ensureValidDefaultGroups() { this->properties()[property::VIRTUALSERVER_DEFAULT_CHANNEL_GROUP] = default_channel_group->groupId(); } - auto admin_channel_group = this->group_manager()->findGroupLocal(this->properties()[property::VIRTUALSERVER_DEFAULT_CHANNEL_ADMIN_GROUP].as_save()); + auto admin_channel_group = this->group_manager()->findGroupLocal( + this->properties()[property::VIRTUALSERVER_DEFAULT_CHANNEL_ADMIN_GROUP].as_or(0)); if(!admin_channel_group) { logError(this->serverId, "Missing server's default channel admin group! (Id: {})", this->properties()[property::VIRTUALSERVER_DEFAULT_CHANNEL_ADMIN_GROUP].value()); @@ -1310,7 +1325,7 @@ void VirtualServer::send_text_message(const std::shared_ptr &chann auto now = chrono::system_clock::now(); bool conversation_private; - auto conversation_mode = channel->properties()[property::CHANNEL_CONVERSATION_MODE].as(); + auto conversation_mode = channel->properties()[property::CHANNEL_CONVERSATION_MODE].as_or(ChannelConversationMode::CHANNELCONVERSATIONMODE_PRIVATE); if(conversation_mode == ChannelConversationMode::CHANNELCONVERSATIONMODE_NONE) { /* nothing to do */ return; @@ -1318,7 +1333,7 @@ void VirtualServer::send_text_message(const std::shared_ptr &chann conversation_private = conversation_mode == ChannelConversationMode::CHANNELCONVERSATIONMODE_PRIVATE; } - auto flag_password = channel->properties()[property::CHANNEL_FLAG_PASSWORD].as(); + auto flag_password = channel->properties()[property::CHANNEL_FLAG_PASSWORD].as_or(false); for(const auto& client : this->getClients()) { if(client->connectionState() != ConnectionState::CONNECTED) continue; diff --git a/server/src/VirtualServer.h b/server/src/VirtualServer.h index b3834e3..7e3e5b1 100644 --- a/server/src/VirtualServer.h +++ b/server/src/VirtualServer.h @@ -185,7 +185,8 @@ namespace ts { ecc_key* serverKey(){ return _serverKey; } std::string publicServerKey(); - Properties& properties(){ return *this->_properties; } + inline PropertyWrapper properties() { return PropertyWrapper{this->_properties}; } + inline const PropertyWrapper properties() const { return PropertyWrapper{this->_properties}; } inline sql::SqlManager * getSql(){ return this->sql; } sql::AsyncSqlPool* getSqlPool(){ return this->sql->pool; } @@ -343,7 +344,7 @@ namespace ts { //General server properties ecc_key* _serverKey = nullptr; - std::shared_ptr _properties; + std::shared_ptr _properties; int _voice_encryption_mode = 2; /* */ ServerChannelTree* channelTree = nullptr; diff --git a/server/src/VirtualServerManager.cpp b/server/src/VirtualServerManager.cpp index 6ee6adb..d26856b 100644 --- a/server/src/VirtualServerManager.cpp +++ b/server/src/VirtualServerManager.cpp @@ -131,7 +131,7 @@ bool VirtualServerManager::initialize(bool autostart) { this->instances.push_back(server); } - if(autostart && server->properties()[property::VIRTUALSERVER_AUTOSTART].as()) { + if(autostart && server->properties()[property::VIRTUALSERVER_AUTOSTART].as_or(false)) { logMessage(server->getServerId(), "Starting server"); string msg; try { @@ -201,7 +201,7 @@ uint16_t VirtualServerManager::next_available_port(const std::string& host_strin unallowed_ports.reserve(instances.size()); for(const auto& instance : instances) { - unallowed_ports.push_back(instance->properties()[property::VIRTUALSERVER_PORT].as()); + unallowed_ports.push_back(instance->properties()[property::VIRTUALSERVER_PORT].as_or(0)); auto vserver = instance->getVoiceServer(); if(instance->running() && vserver) { @@ -230,12 +230,18 @@ uint16_t VirtualServerManager::next_available_port(const std::string& host_strin switch (net::address_available(baddress, net::binding_type::TCP)) { case net::binding_result::ADDRESS_USED: goto next_port; + + case net::binding_result::ADDRESS_FREE: + case net::binding_result::INTERNAL_ERROR: default: break; /* if we've an internal error we ignore it */ } switch (net::address_available(baddress, net::binding_type::UDP)) { case net::binding_result::ADDRESS_USED: goto next_port; + + case net::binding_result::ADDRESS_FREE: + case net::binding_result::INTERNAL_ERROR: default: break; /* if we've an internal error we ignore it */ } @@ -249,7 +255,7 @@ uint16_t VirtualServerManager::next_available_port(const std::string& host_strin } ts::ServerId VirtualServerManager::next_available_server_id(bool& success) { - auto server_id_base = this->handle->properties()[property::SERVERINSTANCE_VIRTUAL_SERVER_ID_INDEX].as(); + auto server_id_base = this->handle->properties()[property::SERVERINSTANCE_VIRTUAL_SERVER_ID_INDEX].as_or(0); /* ensure we're not using 0xFFFF (This is the snapshot server) */ if(server_id_base > 65530) { success = false; @@ -292,7 +298,7 @@ ServerReport VirtualServerManager::report() { result.avariable++; if(sr->running()) { result.online++; - result.slots += sr->properties()[property::VIRTUALSERVER_MAXCLIENTS].as(); + result.slots += sr->properties()[property::VIRTUALSERVER_MAXCLIENTS].as_or(0); result.onlineClients += sr->onlineClients(); result.onlineChannels += sr->onlineChannels(); } @@ -324,7 +330,7 @@ size_t VirtualServerManager::runningServers() { size_t VirtualServerManager::usedSlots() { size_t res = 0; for(const auto& sr : this->serverInstances()) - res += sr->properties()[property::VIRTUALSERVER_MAXCLIENTS].as(); + res += sr->properties()[property::VIRTUALSERVER_MAXCLIENTS].as_or(0); return res; } @@ -410,7 +416,7 @@ bool VirtualServerManager::deleteServer(shared_ptr server) { server->state = ServerState::DELETING; } - this->handle->properties()[property::SERVERINSTANCE_SPOKEN_TIME_DELETED] += server->properties()[property::VIRTUALSERVER_SPOKEN_TIME].as(); + this->handle->properties()[property::SERVERINSTANCE_SPOKEN_TIME_DELETED].increment_by(server->properties()[property::VIRTUALSERVER_SPOKEN_TIME].as_or(0)); this->delete_server_in_db(server->serverId, false); this->handle->databaseHelper()->handleServerDelete(server->serverId); @@ -441,7 +447,7 @@ void VirtualServerManager::executeAutostart() { threads::MutexLock l(this->instanceLock); auto lastStart = system_clock::time_point(); for(const auto& server : this->instances){ - if(!server->running() && server->properties()[property::VIRTUALSERVER_AUTOSTART].as()){ + if(!server->running() && server->properties()[property::VIRTUALSERVER_AUTOSTART].as_or(false)){ threads::self::sleep_until(lastStart + milliseconds(10)); //Don't start all server at the same point (otherwise all servers would tick at the same moment) lastStart = system_clock::now(); logMessage(server->getServerId(), "Starting server"); diff --git a/server/src/channel/ClientChannelView.cpp b/server/src/channel/ClientChannelView.cpp index 15eb0a1..82b976a 100644 --- a/server/src/channel/ClientChannelView.cpp +++ b/server/src/channel/ClientChannelView.cpp @@ -98,7 +98,7 @@ std::shared_ptr ClientChannelView::find_channel(const std::shared_ptr while(heads.front()) { auto parent = heads.front()->parent(); - if(!parent && heads.front()->properties()[property::CHANNEL_PID].as() != 0) { + if(!parent && heads.front()->properties()[property::CHANNEL_PID].as_or(0) != 0) { head = this->find_linked_entry(channel->channelId(), nullptr);//We're searching for a deleted head! So lets iterate over everything deep_search = true; break; diff --git a/server/src/channel/ServerChannel.cpp b/server/src/channel/ServerChannel.cpp index 74ef71d..a39863b 100644 --- a/server/src/channel/ServerChannel.cpp +++ b/server/src/channel/ServerChannel.cpp @@ -54,7 +54,7 @@ size_t ServerChannel::client_count() { return result; } -void ServerChannel::setProperties(const std::shared_ptr &ptr) { +void ServerChannel::setProperties(const std::shared_ptr &ptr) { BasicChannel::setProperties(ptr); } @@ -92,7 +92,7 @@ std::shared_ptr ServerChannelTree::createChannel(ChannelId parentI /* TODO: Speed up (skip the database query) */ auto properties = serverInstance->databaseHelper()->loadChannelProperties(this->server_ref.lock(), channel->channelId()); - for(const auto& prop : channel->properties().list_properties()) { + for(const auto& prop : channel->properties()->list_properties()) { if(prop.isModified()) { //Copy the already set properties (*properties)[prop.type()] = prop.value(); } @@ -135,11 +135,12 @@ bool ServerChannelTree::initializeTempParents() { auto channel = dynamic_pointer_cast(linked_channel->entry); assert(channel); - if(channel->properties().hasProperty(property::CHANNEL_PID) && channel->properties()[property::CHANNEL_PID].as() != 0){ + if(channel->properties()[property::CHANNEL_PID].as_or(0) != 0){ if(!channel->parent()) linked_channel->parent = findLinkedChannelByPool(this->tmpChannelList, channel->properties()[property::CHANNEL_PID]); if(!channel->parent()){ - logError(this->getServerId(), "Invalid channel parent (Channel does not exists). Channel id: {} ({}) Missing parent id: {}", channel->channelId(), channel->name(), channel->properties()[property::CHANNEL_PID].as()); + logError(this->getServerId(), "Invalid channel parent (Channel does not exists). Channel id: {} ({}) Missing parent id: {}", channel->channelId(), channel->name(), + channel->properties()[property::CHANNEL_PID].as_or(0)); logError(this->getServerId(), "Resetting parent"); channel->properties()[property::CHANNEL_PID] = 0; } @@ -314,7 +315,7 @@ inline std::shared_ptr buildChannelTree(ServerId serv } auto evaluated_parent_id = channel->parent() ? channel->parent()->channelId() : 0; - if(evaluated_parent_id != channel->properties()[property::CHANNEL_PID].as()) { + if(evaluated_parent_id != channel->properties()[property::CHANNEL_PID].as_or(0)) { debugMessage(serverId, "Fixed parent id for channel {} ({}). New parent channel {}", entry->entry->channelId(), channel->name(), evaluated_parent_id); channel->properties()[property::CHANNEL_PID] = evaluated_parent_id; } diff --git a/server/src/channel/ServerChannel.h b/server/src/channel/ServerChannel.h index d951972..118fd01 100644 --- a/server/src/channel/ServerChannel.h +++ b/server/src/channel/ServerChannel.h @@ -22,7 +22,7 @@ namespace ts { ServerChannel(uint32_t rtc_channel_id, ChannelId parentId, ChannelId channelId); ~ServerChannel() override; - void setProperties(const std::shared_ptr &ptr) override; + void setProperties(const std::shared_ptr &ptr) override; uint32_t rtc_channel_id; diff --git a/server/src/client/ConnectedClient.cpp b/server/src/client/ConnectedClient.cpp index 00e6277..2f7e034 100644 --- a/server/src/client/ConnectedClient.cpp +++ b/server/src/client/ConnectedClient.cpp @@ -146,7 +146,7 @@ void ConnectedClient::updateChannelClientProperties(bool lock_channel_tree, bool std::deque updated_client_properties; { - auto old_talk_power = this->properties()[property::CLIENT_TALK_POWER].as_save(); + auto old_talk_power = this->properties()[property::CLIENT_TALK_POWER].as_or(0); auto new_talk_power = permission_talk_power.has_value ? permission_talk_power.value : 0; debugMessage(this->getServerId(), "{} Recalculated talk power. New value: {} Old value: {}", CLIENT_STR_LOG_PREFIX, new_talk_power, old_talk_power); @@ -154,7 +154,7 @@ void ConnectedClient::updateChannelClientProperties(bool lock_channel_tree, bool this->properties()[property::CLIENT_TALK_POWER] = new_talk_power; updated_client_properties.emplace_back(property::CLIENT_TALK_POWER); - auto retract_request = this->properties()[property::CLIENT_IS_TALKER].as(); + auto retract_request = this->properties()[property::CLIENT_IS_TALKER].as_or(false); if(!retract_request && channel) { retract_request = channel->talk_power_granted(permission_talk_power); } @@ -176,7 +176,7 @@ void ConnectedClient::updateChannelClientProperties(bool lock_channel_tree, bool } { - IconId current_icon_id = this->properties()[property::CLIENT_ICON_ID].as_save(); + IconId current_icon_id = this->properties()[property::CLIENT_ICON_ID].as_or(0); IconId new_icon_id{ 0}; auto local_permissions = this->clientPermissions; @@ -254,7 +254,7 @@ void ConnectedClient::updateChannelClientProperties(bool lock_channel_tree, bool void ConnectedClient::updateTalkRights(permission::v2::PermissionFlaggedValue talk_power) { bool flag = false; - flag |= this->properties()[property::CLIENT_IS_TALKER].as(); + flag |= this->properties()[property::CLIENT_IS_TALKER].as_or(false); auto current_channel = this->currentChannel; if(!flag && current_channel) { @@ -274,7 +274,8 @@ void ConnectedClient::increaseFloodPoints(uint16_t num) { bool ConnectedClient::shouldFloodBlock() { if(!this->server) return false; if(!this->block_flood) return false; - return this->floodPoints > this->server->properties()[property::VIRTUALSERVER_ANTIFLOOD_POINTS_NEEDED_COMMAND_BLOCK].as(); + return this->floodPoints > + this->server->properties()[property::VIRTUALSERVER_ANTIFLOOD_POINTS_NEEDED_COMMAND_BLOCK].as_or(150); } std::deque> ConnectedClient::subscribeChannel(const std::deque>& targets, bool lock_channel, bool enforce) { @@ -677,11 +678,11 @@ inline void send_channels(ConnectedClient* client, ChannelIT begin, const Channe continue; } - for (const auto &elm : channel->properties().list_properties(property::FLAG_CHANNEL_VIEW, client->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) { + for (const auto &elm : channel->properties()->list_properties(property::FLAG_CHANNEL_VIEW, client->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) { if(elm.type() == property::CHANNEL_ORDER) builder.put_unchecked(index, elm.type().name, override_orderid ? 0 : (*begin)->previous_channel); else - builder.put_unchecked(index, elm.type().name, elm.as()); + builder.put_unchecked(index, elm.type().name, elm.value()); } begin++; @@ -758,7 +759,7 @@ void ConnectedClient::sendChannelDescription(const std::shared_ptr auto limit = this->getType() == CLIENT_TEAMSPEAK ? 8192 : 131130; - auto description = channel->properties()[property::CHANNEL_DESCRIPTION].as(); + auto description = channel->properties()[property::CHANNEL_DESCRIPTION].value(); Command cmd("notifychanneledited"); cmd["cid"] = channel->channelId(); cmd["reasonid"] = 9; @@ -774,20 +775,20 @@ void ConnectedClient::tick_server(const std::chrono::system_clock::time_point &t if(this->lastOnlineTimestamp.time_since_epoch().count() == 0) { this->lastOnlineTimestamp = time; } else if(time - this->lastOnlineTimestamp > seconds(120)) { - this->properties()[property::CLIENT_MONTH_ONLINE_TIME] += duration_cast(time - lastOnlineTimestamp).count(); - this->properties()[property::CLIENT_TOTAL_ONLINE_TIME] += duration_cast(time - lastOnlineTimestamp).count(); + this->properties()[property::CLIENT_MONTH_ONLINE_TIME].increment_by(duration_cast(time - lastOnlineTimestamp).count()); + this->properties()[property::CLIENT_TOTAL_ONLINE_TIME].increment_by(duration_cast(time - lastOnlineTimestamp).count()); lastOnlineTimestamp = time; } if(time - this->lastTransfareTimestamp > seconds(5)) { lastTransfareTimestamp = time; auto update = this->connectionStatistics->mark_file_bytes(); if(update.first > 0) { - this->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED] += update.first; - this->properties()[property::CLIENT_TOTAL_BYTES_DOWNLOADED] += update.first; + this->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED].increment_by(update.first); + this->properties()[property::CLIENT_TOTAL_BYTES_DOWNLOADED].increment_by(update.first); } if(update.second > 0) { - this->properties()[property::CLIENT_MONTH_BYTES_UPLOADED] += update.second; - this->properties()[property::CLIENT_TOTAL_BYTES_UPLOADED] += update.second; + this->properties()[property::CLIENT_MONTH_BYTES_UPLOADED].increment_by(update.second); + this->properties()[property::CLIENT_TOTAL_BYTES_UPLOADED].increment_by(update.second); } } } @@ -799,16 +800,16 @@ void ConnectedClient::tick_server(const std::chrono::system_clock::time_point &t void ConnectedClient::sendServerInit() { Command command("initserver"); - for(const auto& prop : this->server->properties().list_properties(property::FLAG_SERVER_VIEW, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) { + for(const auto& prop : this->server->properties()->list_properties(property::FLAG_SERVER_VIEW, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) { command[std::string{prop.type().name}] = prop.value(); } command["virtualserver_maxclients"] = 32; //Server stuff - command["client_talk_power"] = this->properties()[property::CLIENT_TALK_POWER].as(); - command["client_needed_serverquery_view_power"] = this->properties()[property::CLIENT_NEEDED_SERVERQUERY_VIEW_POWER].as(); - command["client_myteamspeak_id"] = this->properties()[property::CLIENT_MYTEAMSPEAK_ID].as(); - command["client_integrations"] = this->properties()[property::CLIENT_INTEGRATIONS].as(); + command["client_talk_power"] = this->properties()[property::CLIENT_TALK_POWER].value(); + command["client_needed_serverquery_view_power"] = this->properties()[property::CLIENT_NEEDED_SERVERQUERY_VIEW_POWER].value(); + command["client_myteamspeak_id"] = this->properties()[property::CLIENT_MYTEAMSPEAK_ID].value(); + command["client_integrations"] = this->properties()[property::CLIENT_INTEGRATIONS].value(); if(ts::config::server::DefaultServerLicense == LicenseType::LICENSE_AUTOMATIC_INSTANCE){ if(serverInstance->getVoiceServerManager()->usedSlots() <= 32) @@ -818,9 +819,9 @@ void ConnectedClient::sendServerInit() { else command["lt"] = LicenseType::LICENSE_HOSTING; } else if(ts::config::server::DefaultServerLicense == LicenseType::LICENSE_AUTOMATIC_SERVER){ - if(this->server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as() <= 32) + if(this->server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as_or(0) <= 32) command["lt"] = LicenseType::LICENSE_NONE; - else if(this->server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as() <= 512) + else if(this->server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as_or(0) <= 512) command["lt"] = LicenseType::LICENSE_NPL; else command["lt"] = LicenseType::LICENSE_HOSTING; diff --git a/server/src/client/ConnectedClientNotifyHandler.cpp b/server/src/client/ConnectedClientNotifyHandler.cpp index eeb7a1f..3aac6ba 100644 --- a/server/src/client/ConnectedClientNotifyHandler.cpp +++ b/server/src/client/ConnectedClientNotifyHandler.cpp @@ -422,7 +422,7 @@ bool ConnectedClient::notifyClientUpdated(const std::shared_ptr response["clid"] = client_id; for (const auto &prop : props) { if(lastOnlineTimestamp.time_since_epoch().count() > 0 && (*prop == property::CLIENT_TOTAL_ONLINE_TIME || *prop == property::CLIENT_MONTH_ONLINE_TIME)) - response[prop->name] = client->properties()[prop].as() + duration_cast(system_clock::now() - client->lastOnlineTimestamp).count(); + response[prop->name] = client->properties()[prop].as_or(0) + duration_cast(system_clock::now() - client->lastOnlineTimestamp).count(); else response[prop->name] = client->properties()[prop].value(); } @@ -471,7 +471,7 @@ bool ConnectedClient::notifyChannelMoved(const std::shared_ptr &ch bool ConnectedClient::notifyChannelCreate(const std::shared_ptr &channel, ChannelId orderId, const std::shared_ptr &invoker) { Command notify("notifychannelcreated"); - for (auto &prop : channel->properties().list_properties(property::FLAG_CHANNEL_VARIABLE | property::FLAG_CHANNEL_VIEW, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) { + for (auto &prop : channel->properties()->list_properties(property::FLAG_CHANNEL_VARIABLE | property::FLAG_CHANNEL_VIEW, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) { if(prop.type() == property::CHANNEL_ORDER) notify[prop.type().name] = orderId; else if(prop.type() == property::CHANNEL_DESCRIPTION) @@ -536,7 +536,7 @@ bool ConnectedClient::notifyChannelShow(const std::shared_ptr result = this->notifyChannelCreate(channel, orderId, this->server->serverRoot); } else { Command notify("notifychannelshow"); - for (auto &prop : channel->properties().list_properties(property::FLAG_CHANNEL_VARIABLE | property::FLAG_CHANNEL_VIEW, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) { + for (auto &prop : channel->properties()->list_properties(property::FLAG_CHANNEL_VARIABLE | property::FLAG_CHANNEL_VIEW, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) { if(prop.type() == property::CHANNEL_ORDER) { notify[prop.type().name] = orderId; } else if(prop.type() == property::CHANNEL_DESCRIPTION) { @@ -688,7 +688,7 @@ bool ConnectedClient::notifyChannelEdited( } else if(prop == property::CHANNEL_DESCRIPTION) { send_description_change = true; } else { - notify[prop_info.name] = channel->properties()[prop].as(); + notify[prop_info.name] = channel->properties()[prop].value(); property_count++; } } @@ -730,7 +730,7 @@ bool ConnectedClient::notifyChannelDeleted(const deque& channel_ids, bool ConnectedClient::notifyServerUpdated(std::shared_ptr invoker) { Command response("notifyserverupdated"); - for (const auto& elm : this->server->properties().list_properties(property::FLAG_SERVER_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) { + for (const auto& elm : this->server->properties()->list_properties(property::FLAG_SERVER_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) { if(elm.type() == property::VIRTUALSERVER_MIN_WINPHONE_VERSION) continue; diff --git a/server/src/client/ConnectedClientTextCommandHandler.cpp b/server/src/client/ConnectedClientTextCommandHandler.cpp index 4bd4264..7c8a1f5 100644 --- a/server/src/client/ConnectedClientTextCommandHandler.cpp +++ b/server/src/client/ConnectedClientTextCommandHandler.cpp @@ -182,7 +182,7 @@ bool ConnectedClient::handle_text_command( else { send_message(music_root, "There are " + to_string(mbots.size()) + " music bots " + locationStr + ":"); for (const auto &mbot : mbots) { - if(mbot->properties()[property::CLIENT_DISABLED].as()) { + if(mbot->properties()[property::CLIENT_DISABLED].as_or(false)) { send_message(music_root, " - [color=red]" + to_string(mbot->getClientDatabaseId()) + " | " + mbot->getDisplayName() + " [DISABLED][/color]"); } else { send_message(music_root, " - [color=green]" + to_string(mbot->getClientDatabaseId()) + " | " + mbot->getDisplayName() + "[/color]"); diff --git a/server/src/client/DataClient.cpp b/server/src/client/DataClient.cpp index d6b7554..45e485b 100644 --- a/server/src/client/DataClient.cpp +++ b/server/src/client/DataClient.cpp @@ -90,12 +90,12 @@ bool DataClient::loadDataForCurrentServer() { } }); - if(this->properties()[property::CLIENT_DATABASE_ID].as() == 0) { + if(this->properties()[property::CLIENT_DATABASE_ID].as_or(0) == 0) { return false; } //Load general properties - std::deque copied; + std::deque copied; for(const auto& prop : this->_properties->list_properties()){ if((prop.type().flags & property::FLAG_GLOBAL) == 0) continue; if(prop.type().default_value == prop.value()) continue; @@ -113,7 +113,7 @@ bool DataClient::loadDataForCurrentServer() { this->_properties->toggleSave(false); for(const auto& e : copied) { - auto p = this->properties()->find(e.type().type_property, e.type().property_index); + auto p = this->properties()->get(e.type().type_property, e.type().property_index); p = e.value(); p.setModified(false); } diff --git a/server/src/client/DataClient.h b/server/src/client/DataClient.h index 75c41ea..9b1d569 100644 --- a/server/src/client/DataClient.h +++ b/server/src/client/DataClient.h @@ -29,45 +29,11 @@ namespace ts { friend class QueryServer; friend class music::MusicBotManager; public: - struct PropertyWrapper { - std::shared_ptr handle; - - Properties* operator->() { - return handle.get(); - } - - const Properties* operator->() const { - return handle.get(); - } - - template - std::result_of_t operator->*(F &&f) { - return std::forward(f)(*handle); - } - - template - std::result_of_t operator->*(F &&f) const { - return std::forward(f)(*handle); - } - - /* - template - ts::PropertyWrapper operator[](T type) { - return (*handle)[type]; - } - */ - - template - ts::PropertyWrapper operator[](const T& type) { - return (*handle)[type]; - } - }; - DataClient(sql::SqlManager*, const std::shared_ptr&); virtual ~DataClient(); - - PropertyWrapper properties(){ return { this->_properties }; } + inline PropertyWrapper properties() { return PropertyWrapper{this->_properties}; } + inline const PropertyWrapper properties() const { return PropertyWrapper{this->_properties}; } [[nodiscard]] inline auto permissions(){ return this->clientPermissions; } /* main permission calculate function */ @@ -137,7 +103,7 @@ namespace ts { std::shared_ptr server; std::shared_ptr clientPermissions = nullptr; - std::shared_ptr _properties; + std::shared_ptr _properties; std::shared_ptr currentChannel = nullptr; }; diff --git a/server/src/client/SpeakingClient.cpp b/server/src/client/SpeakingClient.cpp index af4dfe7..ae5b156 100644 --- a/server/src/client/SpeakingClient.cpp +++ b/server/src/client/SpeakingClient.cpp @@ -38,8 +38,8 @@ SpeakingClient::~SpeakingClient() { bool SpeakingClient::shouldReceiveVoice(const std::shared_ptr &sender) { //if(this->properties()[property::CLIENT_AWAY].as()) return false; - if(!this->properties()[property::CLIENT_OUTPUT_HARDWARE].as()) return false; - if(this->properties()[property::CLIENT_OUTPUT_MUTED].as()) return false; + if(!this->properties()[property::CLIENT_OUTPUT_HARDWARE].as_or(true)) return false; + if(this->properties()[property::CLIENT_OUTPUT_MUTED].as_or(false)) return false; { shared_lock client_lock(this->channel_lock); @@ -241,7 +241,7 @@ command_result SpeakingClient::handleCommandClientInit(Command& cmd) { } if(this->getType() == ClientType::CLIENT_TEAMSPEAK && permission::v2::permission_granted(1, permissions[permission::b_client_enforce_valid_hwid])) { - auto hwid = this->properties()[property::CLIENT_HARDWARE_ID].as(); + auto hwid = this->properties()[property::CLIENT_HARDWARE_ID].value(); if( !std::regex_match(hwid, regex_hwid_windows) && !std::regex_match(hwid, regex_hwid_unix) && @@ -352,8 +352,8 @@ command_result SpeakingClient::handleCommandClientInit(Command& cmd) { count++; } - auto maxClients = this->server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as(); - auto reserved = this->server->properties()[property::VIRTUALSERVER_RESERVED_SLOTS].as(); + auto maxClients = this->server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as_or(0); + auto reserved = this->server->properties()[property::VIRTUALSERVER_RESERVED_SLOTS].as_or(0); bool allowReserved = permission::v2::permission_granted(1, permissions[permission::b_client_use_reserved_slot]); if(reserved > maxClients){ @@ -364,10 +364,10 @@ command_result SpeakingClient::handleCommandClientInit(Command& cmd) { TIMING_STEP(timings, "max clients"); - auto old_last_connected = this->properties()[property::CLIENT_LASTCONNECTED].as(); + auto old_last_connected = this->properties()[property::CLIENT_LASTCONNECTED].as_or(0); this->properties()[property::CONNECTION_CLIENT_IP] = this->getLoggingPeerIp(); this->properties()[property::CLIENT_LASTCONNECTED] = std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count(); - this->properties()[property::CLIENT_TOTALCONNECTIONS]++; + this->properties()[property::CLIENT_TOTALCONNECTIONS].increment_by(1); { auto time_point = system_clock::time_point() + seconds(old_last_connected); if(time_point < build::version()->timestamp) { @@ -453,14 +453,14 @@ void SpeakingClient::processJoin() { } } //this->updateChannelClientProperties(false); /* will be already updated via assignChannel */ - if(ref_server->properties()[property::VIRTUALSERVER_HOSTMESSAGE_MODE].as() == 3 && !ref_server->properties()[property::VIRTUALSERVER_HOSTMESSAGE].as().empty()) { + if(ref_server->properties()[property::VIRTUALSERVER_HOSTMESSAGE_MODE].as_or(0) == 3 && !ref_server->properties()[property::VIRTUALSERVER_HOSTMESSAGE].value().empty()) { auto weak = this->_this; threads::Thread([weak](){ threads::self::sleep_for(milliseconds(2000)); auto client = weak.lock(); if(!client || !client->server) return; - client->disconnect(client->server->properties()[property::VIRTUALSERVER_HOSTMESSAGE].as()); + client->disconnect(client->server->properties()[property::VIRTUALSERVER_HOSTMESSAGE].value()); }).detach(); } @@ -583,13 +583,13 @@ void SpeakingClient::updateSpeak(bool only_update, const std::chrono::system_clo if(this->speak_last_packet + this->speak_accuracy < now) { if(this->speak_last_packet > this->speak_begin) { - if(!this->properties()[property::CLIENT_FLAG_TALKING].as()) { + if(!this->properties()[property::CLIENT_FLAG_TALKING].as_or(false)) { this->properties()[property::CLIENT_FLAG_TALKING] = true; } this->speak_time += duration_cast(this->speak_last_packet - this->speak_begin); } else { - if(this->properties()[property::CLIENT_FLAG_TALKING].as()) { + if(this->properties()[property::CLIENT_FLAG_TALKING].as_or(false)) { this->properties()[property::CLIENT_FLAG_TALKING] = false; } } diff --git a/server/src/client/command_handler/channel.cpp b/server/src/client/command_handler/channel.cpp index 0361f5e..518415c 100644 --- a/server/src/client/command_handler/channel.cpp +++ b/server/src/client/command_handler/channel.cpp @@ -32,9 +32,10 @@ using namespace std; using namespace ts; using namespace ts::server; -//{findError("parameter_invalid"), "could not resolve permission " + (cmd[index].has("permid") ? cmd[index]["permid"].as() : cmd[index]["permsid"].as())}; \ -//TODO: Log missing permissions? - +/* +TODO: Log missing permissions? +{findError("parameter_invalid"), "could not resolve permission " + (cmd[index].has("permid") ? cmd[index]["permid"].as() : cmd[index]["permsid"].as())}; +*/ command_result ConnectedClient::handleCommandChannelGetDescription(Command &cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(0); RESOLVE_CHANNEL_R(cmd["cid"], true); @@ -816,9 +817,9 @@ command_result ConnectedClient::handleCommandChannelCreate(Command &cmd) { for (const auto &channel : target_tree->channels()) { created_total++; if (channel->properties()[property::CHANNEL_CREATED_BY] == own_cldbid) { - if (channel->properties()[property::CHANNEL_FLAG_PERMANENT].as()) { + if (channel->properties()[property::CHANNEL_FLAG_PERMANENT].as_or(false)) { created_perm++; - } else if (channel->properties()[property::CHANNEL_FLAG_SEMI_PERMANENT].as()) { + } else if (channel->properties()[property::CHANNEL_FLAG_SEMI_PERMANENT].as_or(false)) { created_semi++; } else { created_tmp++; @@ -826,7 +827,8 @@ command_result ConnectedClient::handleCommandChannelCreate(Command &cmd) { } } - if (this->server && created_total >= this->server->properties()[property::VIRTUALSERVER_MAX_CHANNELS].as()) + if (this->server && created_total >= + this->server->properties()[property::VIRTUALSERVER_MAX_CHANNELS].as_or(0)) return command_result{error::channel_limit_reached}; auto max_channels = this->calculate_permission(permission::i_client_max_channels, parent_channel_id, false); @@ -1181,7 +1183,6 @@ ts::command_result ConnectedClient::execute_channel_edit(ChannelId& channel_id, bool updating_max_family_clients{false}; bool updating_talk_power{false}; bool updating_type{false}; - bool updating_conversation{false}; bool updating_sort_order{false}; /* Step 1: Parse all values which are possible and validate them without any context. */ @@ -1410,7 +1411,7 @@ ts::command_result ConnectedClient::execute_channel_edit(ChannelId& channel_id, } /* Step 2: Remove all not changed properties and test the updates */ - auto& channel_properties = channel->properties(); + auto channel_properties = channel->properties(); std::map changed_values{}; for(auto& [ key, value ] : values) { @@ -1477,7 +1478,6 @@ ts::command_result ConnectedClient::execute_channel_edit(ChannelId& channel_id, case property::CHANNEL_CONVERSATION_HISTORY_LENGTH: case property::CHANNEL_CONVERSATION_MODE: - updating_conversation = true; break; /* non updatable properties */ @@ -1552,7 +1552,7 @@ ts::command_result ConnectedClient::execute_channel_edit(ChannelId& channel_id, } ChannelType::ChannelType target_channel_type; - { + if(updating_type) { auto flag_permanent = converter::from_string_view(target_channel_property_value(property::CHANNEL_FLAG_PERMANENT)); auto flag_semi_permanent = converter::from_string_view(target_channel_property_value(property::CHANNEL_FLAG_SEMI_PERMANENT)); @@ -2145,11 +2145,11 @@ command_result ConnectedClient::handleCommandChannelAddPerm(Command &cmd) { /* test if we've the default channel */ bool family_contains_default_channel{false}; - if(channel->properties()[property::CHANNEL_FLAG_DEFAULT].as()) { + if(channel->properties()[property::CHANNEL_FLAG_DEFAULT].as_or(false)) { family_contains_default_channel = true; } else { for(const auto& child_channel : channel_tree->channels(channel)) { - if(child_channel->properties()[property::CHANNEL_FLAG_DEFAULT].as()) { + if(child_channel->properties()[property::CHANNEL_FLAG_DEFAULT].as_or(false)) { family_contains_default_channel = true; break; } @@ -2476,7 +2476,7 @@ command_result ConnectedClient::handleCommandChannelInfo(Command &cmd) { Command res(""); - for (const auto &prop : channel->properties().list_properties(property::FLAG_CHANNEL_VIEW | property::FLAG_CHANNEL_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) + for (const auto &prop : channel->properties()->list_properties(property::FLAG_CHANNEL_VIEW | property::FLAG_CHANNEL_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) res[prop.type().name] = prop.value(); res["seconds_empty"] = channel->emptySince(); diff --git a/server/src/client/command_handler/client.cpp b/server/src/client/command_handler/client.cpp index 360058e..84ffc00 100644 --- a/server/src/client/command_handler/client.cpp +++ b/server/src/client/command_handler/client.cpp @@ -237,25 +237,26 @@ command_result ConnectedClient::handleCommandClientMove(Command &cmd) { } /* FIXME: Some kind of invite key frags to prevent limit checking! */ - if (!channel->properties()[property::CHANNEL_FLAG_MAXCLIENTS_UNLIMITED].as() || !channel->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_UNLIMITED].as()) { + if (!channel->properties()[property::CHANNEL_FLAG_MAXCLIENTS_UNLIMITED].as_unchecked() || !channel->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_UNLIMITED].as_unchecked()) { if(!permission::v2::permission_granted(1, this->calculate_permission(permission::b_channel_join_ignore_maxclients, channel->channelId()))) { - if(!channel->properties()[property::CHANNEL_FLAG_MAXCLIENTS_UNLIMITED].as()) { - auto maxClients = channel->properties()[property::CHANNEL_MAXCLIENTS].as(); + if(!channel->properties()[property::CHANNEL_FLAG_MAXCLIENTS_UNLIMITED].as_unchecked()) { + auto maxClients = channel->properties()[property::CHANNEL_MAXCLIENTS].as_unchecked(); if (maxClients >= 0 && maxClients < this->server->getClientsByChannel(channel).size() + clients.size()) { return command_result{error::channel_maxclients_reached}; } } - if(!channel->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_UNLIMITED].as()) { + if(!channel->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_UNLIMITED].as_unchecked()) { shared_ptr family_root; - if(channel->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_INHERITED].as()) { + if(channel->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_INHERITED].as_unchecked()) { family_root = channel; - while(family_root && family_root->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_INHERITED].as()) { + while(family_root && + family_root->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_INHERITED].as_unchecked()) { family_root = family_root->parent(); } } if(family_root && !family_root->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_UNLIMITED]) { //Could not be CHANNEL_FLAG_MAXFAMILYCLIENTS_INHERITED - auto maxClients = family_root->properties()[property::CHANNEL_MAXFAMILYCLIENTS].as(); + auto maxClients = family_root->properties()[property::CHANNEL_MAXFAMILYCLIENTS].as_unchecked(); auto client_count = 0; for(const auto& entry : this->server->getClientsByChannelRoot(channel, false)) { if(entry.get() != this) { @@ -304,7 +305,8 @@ command_result ConnectedClient::handleCommandClientMove(Command &cmd) { server_channel_w_lock.lock(); } - if(oldChannel->channelType() == ChannelType::temporary && oldChannel->properties()[property::CHANNEL_DELETE_DELAY].as() == 0) { + if(oldChannel->channelType() == ChannelType::temporary && + oldChannel->properties()[property::CHANNEL_DELETE_DELAY].as_unchecked() == 0) { if(this->server->getClientsByChannelRoot(oldChannel, false).empty()) { this->server->delete_channel(dynamic_pointer_cast(oldChannel), this->ref(), "temporary auto delete", server_channel_w_lock, true); } @@ -520,7 +522,7 @@ command_result ConnectedClient::handleCommandClientEdit(Command &cmd, const std: logError(this->getServerId(), R"([{}] Tried to change a client property to an invalid value for {}. (Key: "{}", Value: "{}"))", CLIENT_STR_LOG_PREFIX, CLIENT_STR_LOG_PREFIX_(client), key, cmd[key].string()); continue; } - if(client->properties()[&info].as() == cmd[key].as()) continue; + if(client->properties()[&info].as_unchecked() == cmd[key].as()) continue; if (info == property::CLIENT_DESCRIPTION) { if (self) { @@ -815,47 +817,49 @@ command_result ConnectedClient::handleCommandClientList(Command &cmd) { if (cmd.hasParm("uid")) result[index]["client_unique_identifier"] = client->getUid(); if (cmd.hasParm("away")) { - result[index]["client_away"] = client->properties()[property::CLIENT_AWAY].as(); - result[index]["client_away_message"] = client->properties()[property::CLIENT_AWAY_MESSAGE].as(); + result[index]["client_away"] = client->properties()[property::CLIENT_AWAY].as_unchecked(); + result[index]["client_away_message"] = client->properties()[property::CLIENT_AWAY_MESSAGE].as_unchecked(); } if (cmd.hasParm("groups")) { - result[index]["client_channel_group_id"] = client->properties()[property::CLIENT_CHANNEL_GROUP_ID].as(); - result[index]["client_servergroups"] = client->properties()[property::CLIENT_SERVERGROUPS].as(); - result[index]["client_channel_group_inherited_channel_id"] = client->properties()[property::CLIENT_CHANNEL_GROUP_INHERITED_CHANNEL_ID].as(); + result[index]["client_channel_group_id"] = client->properties()[property::CLIENT_CHANNEL_GROUP_ID].as_unchecked(); + result[index]["client_servergroups"] = client->properties()[property::CLIENT_SERVERGROUPS].as_unchecked(); + result[index]["client_channel_group_inherited_channel_id"] = client->properties()[property::CLIENT_CHANNEL_GROUP_INHERITED_CHANNEL_ID].as_unchecked(); } if (cmd.hasParm("times")) { result[index]["client_idle_time"] = duration_cast(system_clock::now() - client->idleTimestamp).count(); - result[index]["client_total_online_time"] = client->properties()[property::CLIENT_TOTAL_ONLINE_TIME].as() + duration_cast(system_clock::now() - client->lastOnlineTimestamp).count(); - result[index]["client_month_online_time"] = client->properties()[property::CLIENT_MONTH_ONLINE_TIME].as() + duration_cast(system_clock::now() - client->lastOnlineTimestamp).count(); + result[index]["client_total_online_time"] = + client->properties()[property::CLIENT_TOTAL_ONLINE_TIME].as_unchecked() + duration_cast(system_clock::now() - client->lastOnlineTimestamp).count(); + result[index]["client_month_online_time"] = + client->properties()[property::CLIENT_MONTH_ONLINE_TIME].as_unchecked() + duration_cast(system_clock::now() - client->lastOnlineTimestamp).count(); result[index]["client_idle_time"] = duration_cast(system_clock::now() - client->idleTimestamp).count(); - result[index]["client_created"] = client->properties()[property::CLIENT_CREATED].as(); - result[index]["client_lastconnected"] = client->properties()[property::CLIENT_LASTCONNECTED].as(); + result[index]["client_created"] = client->properties()[property::CLIENT_CREATED].as_unchecked(); + result[index]["client_lastconnected"] = client->properties()[property::CLIENT_LASTCONNECTED].as_unchecked(); } if (cmd.hasParm("info")) { - result[index]["client_version"] = client->properties()[property::CLIENT_VERSION].as(); - result[index]["client_platform"] = client->properties()[property::CLIENT_PLATFORM].as(); + result[index]["client_version"] = client->properties()[property::CLIENT_VERSION].as_unchecked(); + result[index]["client_platform"] = client->properties()[property::CLIENT_PLATFORM].as_unchecked(); } if (cmd.hasParm("badges")) - result[index]["client_badges"] = client->properties()[property::CLIENT_BADGES].as(); + result[index]["client_badges"] = client->properties()[property::CLIENT_BADGES].as_unchecked(); if (cmd.hasParm("country")) - result[index]["client_country"] = client->properties()[property::CLIENT_COUNTRY].as(); + result[index]["client_country"] = client->properties()[property::CLIENT_COUNTRY].as_unchecked(); if (cmd.hasParm("ip")) - result[index]["connection_client_ip"] = allow_ip ? client->properties()[property::CONNECTION_CLIENT_IP].as() : "hidden"; + result[index]["connection_client_ip"] = allow_ip ? client->properties()[property::CONNECTION_CLIENT_IP].as_unchecked() : "hidden"; if (cmd.hasParm("icon")) - result[index]["client_icon_id"] = client->properties()[property::CLIENT_ICON_ID].as(); + result[index]["client_icon_id"] = client->properties()[property::CLIENT_ICON_ID].as_unchecked(); if (cmd.hasParm("voice")) { - result[index]["client_talk_power"] = client->properties()[property::CLIENT_TALK_POWER].as(); - result[index]["client_flag_talking"] = client->properties()[property::CLIENT_FLAG_TALKING].as(); - result[index]["client_input_muted"] = client->properties()[property::CLIENT_INPUT_MUTED].as(); - result[index]["client_output_muted"] = client->properties()[property::CLIENT_OUTPUT_MUTED].as(); - result[index]["client_input_hardware"] = client->properties()[property::CLIENT_INPUT_HARDWARE].as(); - result[index]["client_output_hardware"] = client->properties()[property::CLIENT_OUTPUT_HARDWARE].as(); - result[index]["client_is_talker"] = client->properties()[property::CLIENT_IS_TALKER].as(); - result[index]["client_is_priority_speaker"] = client->properties()[property::CLIENT_IS_PRIORITY_SPEAKER].as(); - result[index]["client_is_recording"] = client->properties()[property::CLIENT_IS_RECORDING].as(); - result[index]["client_is_channel_commander"] = client->properties()[property::CLIENT_IS_CHANNEL_COMMANDER].as(); + result[index]["client_talk_power"] = client->properties()[property::CLIENT_TALK_POWER].as_unchecked(); + result[index]["client_flag_talking"] = client->properties()[property::CLIENT_FLAG_TALKING].as_unchecked(); + result[index]["client_input_muted"] = client->properties()[property::CLIENT_INPUT_MUTED].as_unchecked(); + result[index]["client_output_muted"] = client->properties()[property::CLIENT_OUTPUT_MUTED].as_unchecked(); + result[index]["client_input_hardware"] = client->properties()[property::CLIENT_INPUT_HARDWARE].as_unchecked(); + result[index]["client_output_hardware"] = client->properties()[property::CLIENT_OUTPUT_HARDWARE].as_unchecked(); + result[index]["client_is_talker"] = client->properties()[property::CLIENT_IS_TALKER].as_unchecked(); + result[index]["client_is_priority_speaker"] = client->properties()[property::CLIENT_IS_PRIORITY_SPEAKER].as_unchecked(); + result[index]["client_is_recording"] = client->properties()[property::CLIENT_IS_RECORDING].as_unchecked(); + result[index]["client_is_channel_commander"] = client->properties()[property::CLIENT_IS_CHANNEL_COMMANDER].as_unchecked(); } index++; @@ -1103,13 +1107,13 @@ command_result ConnectedClient::handleCommandClientDbInfo(Command &cmd) { auto props = serverInstance->databaseHelper()->loadClientProperties(this->server, info->client_database_id, ClientType::CLIENT_TEAMSPEAK); if(allow_ip) { - bulk.put_unchecked("client_lastip", (*props)[property::CONNECTION_CLIENT_IP].as()); + bulk.put_unchecked("client_lastip", (*props)[property::CONNECTION_CLIENT_IP].as_unchecked()); } else { bulk.put_unchecked("client_lastip", "hidden"); } #define ASSIGN_PROPERTY(property) \ - bulk.put_unchecked(property, (*props)[property].as()); + bulk.put_unchecked(property, (*props)[property].value()); ASSIGN_PROPERTY(property::CLIENT_ICON_ID); ASSIGN_PROPERTY(property::CLIENT_BADGES); @@ -1212,10 +1216,13 @@ command_result ConnectedClient::handleCommandClientDBFind(Command &cmd) { auto props = serverInstance->databaseHelper()->loadClientProperties(this->server, client_database_id, ClientType::CLIENT_TEAMSPEAK); if (props) { auto& properties = *props; - bulk.put_unchecked("client_badges", properties[property::CLIENT_BADGES].as()); - bulk.put_unchecked("client_version", properties[property::CLIENT_VERSION].as()); - bulk.put_unchecked("client_platform", properties[property::CLIENT_PLATFORM].as()); - bulk.put_unchecked("client_hwid", properties[property::CLIENT_HARDWARE_ID].as()); + bulk.put_unchecked("client_badges", properties[property::CLIENT_BADGES].as_unchecked()); + bulk.put_unchecked("client_version", + properties[property::CLIENT_VERSION].as_unchecked()); + bulk.put_unchecked("client_platform", + properties[property::CLIENT_PLATFORM].as_unchecked()); + bulk.put_unchecked("client_hwid", + properties[property::CLIENT_HARDWARE_ID].as_unchecked()); } } }); @@ -1249,7 +1256,7 @@ command_result ConnectedClient::handleCommandClientInfo(Command &cmd) { for (const auto &key : client->properties()->list_properties(property::FLAG_CLIENT_VIEW | property::FLAG_CLIENT_VARIABLE | property::FLAG_CLIENT_INFO, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) res[result_index][std::string{key.type().name}] = key.value(); if(view_remote) - res[result_index]["connection_client_ip"] = client->properties()[property::CONNECTION_CLIENT_IP].as(); + res[result_index]["connection_client_ip"] = client->properties()[property::CONNECTION_CLIENT_IP].value(); else res[result_index]["connection_client_ip"] = "hidden"; res[result_index]["client_idle_time"] = duration_cast(system_clock::now() - client->idleTimestamp).count(); diff --git a/server/src/client/command_handler/file.cpp b/server/src/client/command_handler/file.cpp index f01eb39..ed83a05 100644 --- a/server/src/client/command_handler/file.cpp +++ b/server/src/client/command_handler/file.cpp @@ -653,13 +653,13 @@ command_result ConnectedClient::handleCommandFTInitUpload(ts::Command &cmd) { return ts::command_result{error::file_overwrite_excludes_resume}; { - auto server_quota = this->server->properties()[property::VIRTUALSERVER_UPLOAD_QUOTA].as(); - auto server_used_quota = this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED].as(); + auto server_quota = this->server->properties()[property::VIRTUALSERVER_UPLOAD_QUOTA].as_unchecked(); + auto server_used_quota = this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED].as_unchecked(); server_used_quota += cmd["size"].as(); if(server_quota >= 0 && server_quota * 1024 * 1024 < (int64_t) server_used_quota) return command_result{error::file_transfer_server_quota_exceeded}; auto client_quota = this->calculate_permission(permission::i_ft_quota_mb_upload_per_client, 0); - auto client_used_quota = this->properties()[property::CLIENT_MONTH_BYTES_UPLOADED].as(); + auto client_used_quota = this->properties()[property::CLIENT_MONTH_BYTES_UPLOADED].as_unchecked(); client_used_quota += cmd["size"].as(); if(client_quota.has_value && !client_quota.has_infinite_power() && (client_quota.value < 0 || client_quota.value * 1024 * 1024 < (int64_t) client_used_quota)) return command_result{error::file_transfer_client_quota_exceeded}; @@ -772,8 +772,8 @@ command_result ConnectedClient::handleCommandFTInitDownload(ts::Command &cmd) { std::shared_ptr>> transfer_response{}; { - auto server_quota = this->server->properties()[property::VIRTUALSERVER_DOWNLOAD_QUOTA].as(); - auto server_used_quota = this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED].as(); + auto server_quota = this->server->properties()[property::VIRTUALSERVER_DOWNLOAD_QUOTA].as_unchecked(); + auto server_used_quota = this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED].as_unchecked(); if(server_quota >= 0) { if((size_t) server_quota * 1024 * 1024 <= server_used_quota) return command_result{error::file_transfer_server_quota_exceeded}; @@ -782,7 +782,7 @@ command_result ConnectedClient::handleCommandFTInitDownload(ts::Command &cmd) { auto client_quota = this->calculate_permission(permission::i_ft_quota_mb_download_per_client, 0); - auto client_used_quota = this->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED].as(); + auto client_used_quota = this->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED].as_unchecked(); if(client_quota.has_value) { if(client_quota.value > 0) { if((size_t) client_quota.value * 1024 * 1024 <= client_used_quota) diff --git a/server/src/client/command_handler/misc.cpp b/server/src/client/command_handler/misc.cpp index 3d7e25e..add0da0 100644 --- a/server/src/client/command_handler/misc.cpp +++ b/server/src/client/command_handler/misc.cpp @@ -623,7 +623,7 @@ command_result ConnectedClient::handleCommandSendTextMessage(Command &cmd) { channel_tree_read_lock.lock(); } - auto conversation_mode = channel->properties()[property::CHANNEL_CONVERSATION_MODE].as(); + auto conversation_mode = channel->properties()[property::CHANNEL_CONVERSATION_MODE].as_unchecked(); if(conversation_mode == ChannelConversationMode::CHANNELCONVERSATIONMODE_NONE) { return command_result{error::conversation_not_exists}; } else if(channel != this->currentChannel) { @@ -1618,7 +1618,8 @@ command_result ConnectedClient::handleCommandTokenDelete(Command &cmd) { this->server->getTokenManager().delete_token(token->id); - if(token->token == this->server->properties()[property::VIRTUALSERVER_AUTOGENERATED_PRIVILEGEKEY].as()) { + if(token->token == + this->server->properties()[property::VIRTUALSERVER_AUTOGENERATED_PRIVILEGEKEY].as_unchecked()) { this->server->properties()[property::VIRTUALSERVER_AUTOGENERATED_PRIVILEGEKEY] = ""; this->server->properties()[property::VIRTUALSERVER_ASK_FOR_PRIVILEGEKEY] = false; logMessage(this->getServerId(), "{} Deleting the default server token. Don't ask anymore for this a token!", CLIENT_STR_LOG_PREFIX); @@ -1677,10 +1678,10 @@ command_result ConnectedClient::handleCommandWhoAmI(Command &cmd) { if (this->server) { result["virtualserver_status"] = ServerState::string(this->getServer()->state); result["virtualserver_id"] = this->server->getServerId(); - result["virtualserver_unique_identifier"] = this->server->properties()[property::VIRTUALSERVER_UNIQUE_IDENTIFIER].as(); + result["virtualserver_unique_identifier"] = this->server->properties()[property::VIRTUALSERVER_UNIQUE_IDENTIFIER].as_unchecked(); result["virtualserver_port"] = 0; if (this->server->udpVoiceServer) { - result["virtualserver_port"] = this->server->properties()[property::VIRTUALSERVER_PORT].as_save(); + result["virtualserver_port"] = this->server->properties()[property::VIRTUALSERVER_PORT].as_or(0); } } else { result["virtualserver_status"] = "template"; @@ -1693,7 +1694,7 @@ command_result ConnectedClient::handleCommandWhoAmI(Command &cmd) { result["client_channel_id"] = this->currentChannel ? this->currentChannel->channelId() : 0; result["client_nickname"] = this->getDisplayName(); result["client_database_id"] = this->getClientDatabaseId(); - result["client_login_name"] = this->properties()[property::CLIENT_LOGIN_NAME].as(); + result["client_login_name"] = this->properties()[property::CLIENT_LOGIN_NAME].as_unchecked(); result["client_unique_identifier"] = this->getUid(); { @@ -3063,7 +3064,7 @@ command_result ConnectedClient::handleCommandConversationHistory(ts::Command &co if(!channel) return command_result{error::conversation_invalid_id}; - auto conversation_mode = channel->channel()->properties()[property::CHANNEL_CONVERSATION_MODE].as(); + auto conversation_mode = channel->channel()->properties()[property::CHANNEL_CONVERSATION_MODE].as_unchecked(); switch (conversation_mode) { case ChannelConversationMode::CHANNELCONVERSATIONMODE_PRIVATE: return command_result{error::conversation_is_private}; @@ -3193,7 +3194,7 @@ command_result ConnectedClient::handleCommandConversationFetch(ts::Command &cmd) continue; } - auto conversation_mode = channel->channel()->properties()[property::CHANNEL_CONVERSATION_MODE].as(); + auto conversation_mode = channel->channel()->properties()[property::CHANNEL_CONVERSATION_MODE].as_unchecked(); switch (conversation_mode) { case ChannelConversationMode::CHANNELCONVERSATIONMODE_PRIVATE: { auto error = findError("conversation_is_private"); diff --git a/server/src/client/command_handler/server.cpp b/server/src/client/command_handler/server.cpp index 3153f7c..6cda4b0 100644 --- a/server/src/client/command_handler/server.cpp +++ b/server/src/client/command_handler/server.cpp @@ -212,7 +212,7 @@ command_result ConnectedClient::handleCommandServerEdit(Command &cmd) { continue; } - auto property = target_server ? target_server->properties()[info] : (*serverInstance->getDefaultServerProperties())[info]; + auto property = target_server ? target_server->properties()[info] : serverInstance->getDefaultServerProperties()[info]; if(property.value() == elm.second) continue; auto old_value = property.value(); @@ -252,11 +252,15 @@ command_result ConnectedClient::handleCommandServerRequestConnectionInfo(Command first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BANDWIDTH_SENT, minute_report.file_bytes_sent); first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED, minute_report.file_bytes_received); - first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL, this->server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED].as()); - first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL, this->server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_UPLOADED].as()); + first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL, + this->server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED].as_unchecked()); + first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL, + this->server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_UPLOADED].as_unchecked()); - first_bulk.put_unchecked("connection_filetransfer_bytes_sent_month", this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED].as()); - first_bulk.put_unchecked("connection_filetransfer_bytes_received_month", this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED].as()); + first_bulk.put_unchecked("connection_filetransfer_bytes_sent_month", + this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED].as_unchecked()); + first_bulk.put_unchecked("connection_filetransfer_bytes_received_month", + this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED].as_unchecked()); first_bulk.put_unchecked(property::CONNECTION_PACKETS_SENT_TOTAL, std::accumulate(total_stats.connection_packets_sent.begin(), total_stats.connection_packets_sent.end(), (size_t) 0U)); first_bulk.put_unchecked(property::CONNECTION_BYTES_SENT_TOTAL, std::accumulate(total_stats.connection_bytes_sent.begin(), total_stats.connection_bytes_sent.end(), (size_t) 0U)); @@ -268,7 +272,8 @@ command_result ConnectedClient::handleCommandServerRequestConnectionInfo(Command first_bulk.put_unchecked(property::CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL, std::accumulate(second_report.connection_bytes_received.begin(), second_report.connection_bytes_received.end(), (size_t) 0U)); first_bulk.put_unchecked(property::CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL, std::accumulate(minute_report.connection_bytes_received.begin(), minute_report.connection_bytes_received.end(), (size_t) 0U)); - first_bulk.put_unchecked(property::CONNECTION_CONNECTED_TIME, this->server->properties()[property::VIRTUALSERVER_UPTIME].as()); + first_bulk.put_unchecked(property::CONNECTION_CONNECTED_TIME, + this->server->properties()[property::VIRTUALSERVER_UPTIME].as_unchecked()); first_bulk.put_unchecked(property::CONNECTION_PACKETLOSS_TOTAL, network_report.average_loss); first_bulk.put_unchecked(property::CONNECTION_PING, network_report.average_ping); diff --git a/server/src/client/music/MusicClient.cpp b/server/src/client/music/MusicClient.cpp index 444be9b..e5e6d89 100644 --- a/server/src/client/music/MusicClient.cpp +++ b/server/src/client/music/MusicClient.cpp @@ -121,7 +121,7 @@ void MusicClient::initialize_bot() { if(!this->properties()->has(property::CLIENT_COUNTRY) || this->properties()[property::CLIENT_COUNTRY].value().empty()) this->properties()[property::CLIENT_COUNTRY] = config::geo::countryFlag; - if(this->properties()[property::CLIENT_UPTIME_MODE].as() == MusicClient::UptimeMode::TIME_SINCE_SERVER_START) { + if(this->properties()[property::CLIENT_UPTIME_MODE].as_unchecked() == MusicClient::UptimeMode::TIME_SINCE_SERVER_START) { this->properties()[property::CLIENT_LASTCONNECTED] = duration_cast(this->server->start_timestamp().time_since_epoch()).count(); } else { this->properties()[property::CLIENT_LASTCONNECTED] = this->properties()[property::CLIENT_CREATED].value(); diff --git a/server/src/client/music/MusicClientPlayer.cpp b/server/src/client/music/MusicClientPlayer.cpp index 8d13faf..5f586b7 100644 --- a/server/src/client/music/MusicClientPlayer.cpp +++ b/server/src/client/music/MusicClientPlayer.cpp @@ -92,7 +92,7 @@ void MusicClient::replay_song(const shared_ptr &entry, cons }); self->changePlayerState(ReplayState::PAUSED); - if(self->properties()[property::CLIENT_FLAG_NOTIFY_SONG_CHANGE].as()) { + if(self->properties()[property::CLIENT_FLAG_NOTIFY_SONG_CHANGE].as_unchecked()) { string invoker = "unknown"; { auto info_list = serverInstance->databaseHelper()->queryDatabaseInfo(self->getServer(), {entry->getInvoker()}); @@ -185,7 +185,7 @@ void MusicClient::playMusic() { auto self = dynamic_pointer_cast(this->ref()); ts::music::MusicBotManager::tick_music.execute([self]{ auto playlist = self->playlist(); - if(playlist->properties()[property::PLAYLIST_FLAG_FINISHED].as()) { + if(playlist->properties()[property::PLAYLIST_FLAG_FINISHED].as_unchecked()) { playlist->properties()[property::PLAYLIST_FLAG_FINISHED] = false; debugMessage(self->getServerId(), "{} Received play, but playlist had finished. Restarting playlist.", CLIENT_STR_LOG_PREFIX_(self)); } @@ -226,7 +226,7 @@ void MusicClient::forwardSong() { this->handle_event_song_ended(); /* explicitly wanted a "next" song so start over again */ - if(playlist->properties()[property::PLAYLIST_FLAG_FINISHED].as()) { + if(playlist->properties()[property::PLAYLIST_FLAG_FINISHED].as_unchecked()) { playlist->properties()[property::PLAYLIST_FLAG_FINISHED] = false; this->handle_event_song_ended(); } diff --git a/server/src/client/query/QueryClientCommands.cpp b/server/src/client/query/QueryClientCommands.cpp index 23b95e8..00d7a16 100644 --- a/server/src/client/query/QueryClientCommands.cpp +++ b/server/src/client/query/QueryClientCommands.cpp @@ -215,7 +215,8 @@ command_result QueryClient::handleCommandLogin(Command& cmd) { if(!this->whitelisted) { this->handle->client_connect_count[this->getPeerIp()]++; if(this->handle->client_connect_count[this->getPeerIp()] > 3) { - this->handle->client_connect_bans[this->getPeerIp()] = system_clock::now() + seconds(serverInstance->properties()[property::SERVERINSTANCE_SERVERQUERY_BAN_TIME].as()); //TODO configurable | Disconnect all others? + this->handle->client_connect_bans[this->getPeerIp()] = system_clock::now() + seconds( + serverInstance->properties()[property::SERVERINSTANCE_SERVERQUERY_BAN_TIME].as_unchecked()); //TODO configurable | Disconnect all others? this->postCommandHandler.emplace_back([&](){ this->close_connection(system_clock::now() + seconds(1)); }); @@ -227,7 +228,7 @@ command_result QueryClient::handleCommandLogin(Command& cmd) { return command_result{error::client_invalid_password, "username or password dose not match"}; } } - if(!this->properties()[property::CLIENT_LOGIN_NAME].as().empty()) { + if(!this->properties()[property::CLIENT_LOGIN_NAME].as_unchecked().empty()) { Command log("logout"); auto result = this->handleCommandLogout(log); if(result.has_error()) { @@ -296,7 +297,7 @@ command_result QueryClient::handleCommandLogin(Command& cmd) { this->task_update_needed_permissions.enqueue(); } - this->properties()[property::CLIENT_TOTALCONNECTIONS]++; + this->properties()[property::CLIENT_TOTALCONNECTIONS].increment_by(1); this->task_update_channel_client_properties.enqueue(); serverInstance->action_logger()->query_authenticate_logger.log_query_authenticate(this->getServerId(), std::dynamic_pointer_cast(this->ref()), username, log::QueryAuthenticateResult::SUCCESS); @@ -305,7 +306,7 @@ command_result QueryClient::handleCommandLogin(Command& cmd) { command_result QueryClient::handleCommandLogout(Command &) { CMD_RESET_IDLE; - if(this->properties()[property::CLIENT_LOGIN_NAME].as().empty()) return command_result{error::client_not_logged_in}; + if(this->properties()[property::CLIENT_LOGIN_NAME].as_unchecked().empty()) return command_result{error::client_not_logged_in}; this->properties()[property::CLIENT_LOGIN_NAME] = ""; this->query_account = nullptr; @@ -458,10 +459,11 @@ command_result QueryClient::handleCommandServerInfo(Command &) { Command cmd(""); - for(const auto &prop : (this->server ? this->server->properties() : *serverInstance->getDefaultServerProperties()).list_properties(property::FLAG_SERVER_VIEW | property::FLAG_SERVER_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) { - cmd[prop.type().name] = prop.as(); + auto properties = this->server ? this->server->properties() : serverInstance->getDefaultServerProperties(); + for(const auto &prop : properties->list_properties(property::FLAG_SERVER_VIEW | property::FLAG_SERVER_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) { + cmd[prop.type().name] = prop.as_unchecked(); if(prop.type() == property::VIRTUALSERVER_HOST) - cmd["virtualserver_ip"] = prop.as(); + cmd["virtualserver_ip"] = prop.as_unchecked(); } cmd["virtualserver_status"] = this->server ? ServerState::string(this->server->state) : "template"; @@ -551,32 +553,42 @@ command_result QueryClient::handleCommandChannelList(Command& cmd) { const auto channel_clients = this->server ? this->server->getClientsByChannel(channel).size() : 0; result.put_unchecked(index, "cid", channel->channelId()); - result.put_unchecked(index, "pid", channel->properties()[property::CHANNEL_PID].as()); + result.put_unchecked(index, "pid", channel->properties()[property::CHANNEL_PID].as_unchecked()); result.put_unchecked(index, "channel_name", channel->name()); result.put_unchecked(index, "channel_order", channel->channelOrder()); result.put_unchecked(index, "total_clients", channel_clients); /* result.put_unchecked(index, "channel_needed_subscribe_power", channel->permissions()->getPermissionValue(permission::i_channel_needed_subscribe_power, channel, 0)); */ if(cmd.hasParm("flags")){ - result.put_unchecked(index, "channel_flag_default", channel->properties()[property::CHANNEL_FLAG_DEFAULT].as()); - result.put_unchecked(index, "channel_flag_password", channel->properties()[property::CHANNEL_FLAG_PASSWORD].as()); - result.put_unchecked(index, "channel_flag_permanent", channel->properties()[property::CHANNEL_FLAG_PERMANENT].as()); - result.put_unchecked(index, "channel_flag_semi_permanent", channel->properties()[property::CHANNEL_FLAG_SEMI_PERMANENT].as()); + result.put_unchecked(index, "channel_flag_default", + channel->properties()[property::CHANNEL_FLAG_DEFAULT].as_unchecked()); + result.put_unchecked(index, "channel_flag_password", + channel->properties()[property::CHANNEL_FLAG_PASSWORD].as_unchecked()); + result.put_unchecked(index, "channel_flag_permanent", + channel->properties()[property::CHANNEL_FLAG_PERMANENT].as_unchecked()); + result.put_unchecked(index, "channel_flag_semi_permanent", + channel->properties()[property::CHANNEL_FLAG_SEMI_PERMANENT].as_unchecked()); } if(cmd.hasParm("voice")){ - result.put_unchecked(index, "channel_codec", channel->properties()[property::CHANNEL_CODEC].as()); - result.put_unchecked(index, "channel_codec_quality", channel->properties()[property::CHANNEL_CODEC_QUALITY].as()); - result.put_unchecked(index, "channel_needed_talk_power", channel->properties()[property::CHANNEL_NEEDED_TALK_POWER].as()); + result.put_unchecked(index, "channel_codec", + channel->properties()[property::CHANNEL_CODEC].as_unchecked()); + result.put_unchecked(index, "channel_codec_quality", + channel->properties()[property::CHANNEL_CODEC_QUALITY].as_unchecked()); + result.put_unchecked(index, "channel_needed_talk_power", + channel->properties()[property::CHANNEL_NEEDED_TALK_POWER].as_unchecked()); } if(cmd.hasParm("icon")){ - result.put_unchecked(index, "channel_icon_id", channel->properties()[property::CHANNEL_ICON_ID].as()); + result.put_unchecked(index, "channel_icon_id", + channel->properties()[property::CHANNEL_ICON_ID].as_unchecked()); } if(cmd.hasParm("limits")){ result.put_unchecked(index, "total_clients_family", this->server ? this->server->getClientsByChannelRoot(channel, false).size() : 0); result.put_unchecked(index, "total_clients", this->server ? this->server->getClientsByChannel(channel).size() : 0); - result.put_unchecked(index, "channel_maxclients", channel->properties()[property::CHANNEL_MAXCLIENTS].as()); - result.put_unchecked(index, "channel_maxfamilyclients", channel->properties()[property::CHANNEL_MAXFAMILYCLIENTS].as()); + result.put_unchecked(index, "channel_maxclients", + channel->properties()[property::CHANNEL_MAXCLIENTS].as_unchecked()); + result.put_unchecked(index, "channel_maxfamilyclients", + channel->properties()[property::CHANNEL_MAXFAMILYCLIENTS].as_unchecked()); { auto needed_power = channel->permissions()->permission_value_flagged(permission::i_channel_subscribe_power); @@ -584,7 +596,8 @@ command_result QueryClient::handleCommandChannelList(Command& cmd) { } } if(cmd.hasParm("topic")) { - result.put_unchecked(index, "channel_topic", channel->properties()[property::CHANNEL_TOPIC].as()); + result.put_unchecked(index, "channel_topic", + channel->properties()[property::CHANNEL_TOPIC].as_unchecked()); } if(cmd.hasParm("times") || cmd.hasParm("secondsempty")){ result.put_unchecked(index, "seconds_empty", channel_clients == 0 ? channel->emptySince() : 0); @@ -606,23 +619,34 @@ command_result QueryClient::handleCommandServerList(Command& cmd) { size_t index = 0; for(const auto& server : serverInstance->getVoiceServerManager()->serverInstances()) { result.put_unchecked(index, "virtualserver_id", server->getServerId()); - result.put_unchecked(index, "virtualserver_host", server->properties()[property::VIRTUALSERVER_HOST].as()); - result.put_unchecked(index, "virtualserver_port", server->properties()[property::VIRTUALSERVER_PORT].as()); - result.put_unchecked(index, "virtualserver_web_host", server->properties()[property::VIRTUALSERVER_WEB_HOST].as()); - result.put_unchecked(index, "virtualserver_web_port", server->properties()[property::VIRTUALSERVER_WEB_PORT].as()); + result.put_unchecked(index, "virtualserver_host", + server->properties()[property::VIRTUALSERVER_HOST].as_unchecked()); + result.put_unchecked(index, "virtualserver_port", + server->properties()[property::VIRTUALSERVER_PORT].as_unchecked()); + result.put_unchecked(index, "virtualserver_web_host", + server->properties()[property::VIRTUALSERVER_WEB_HOST].as_unchecked()); + result.put_unchecked(index, "virtualserver_web_port", + server->properties()[property::VIRTUALSERVER_WEB_PORT].as_unchecked()); result.put_unchecked(index, "virtualserver_status", ServerState::string(server->state)); - result.put_unchecked(index, "virtualserver_clientsonline", server->properties()[property::VIRTUALSERVER_CLIENTS_ONLINE].as()); - result.put_unchecked(index, "virtualserver_queryclientsonline", server->properties()[property::VIRTUALSERVER_QUERYCLIENTS_ONLINE].as()); - result.put_unchecked(index, "virtualserver_maxclients", server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as()); + result.put_unchecked(index, "virtualserver_clientsonline", + server->properties()[property::VIRTUALSERVER_CLIENTS_ONLINE].as_unchecked()); + result.put_unchecked(index, "virtualserver_queryclientsonline", + server->properties()[property::VIRTUALSERVER_QUERYCLIENTS_ONLINE].as_unchecked()); + result.put_unchecked(index, "virtualserver_maxclients", + server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as_unchecked()); if(server->startTimestamp.time_since_epoch().count() > 0 && server->state == ServerState::ONLINE) result.put_unchecked(index, "virtualserver_uptime", duration_cast(system_clock::now() - server->startTimestamp).count()); else result.put_unchecked(index, "virtualserver_uptime", 0); - result.put_unchecked(index, "virtualserver_name", server->properties()[property::VIRTUALSERVER_NAME].as()); - result.put_unchecked(index, "virtualserver_autostart", server->properties()[property::VIRTUALSERVER_AUTOSTART].as()); - result.put_unchecked(index, "virtualserver_machine_id", server->properties()[property::VIRTUALSERVER_MACHINE_ID].as()); + result.put_unchecked(index, "virtualserver_name", + server->properties()[property::VIRTUALSERVER_NAME].as_unchecked()); + result.put_unchecked(index, "virtualserver_autostart", + server->properties()[property::VIRTUALSERVER_AUTOSTART].as_unchecked()); + result.put_unchecked(index, "virtualserver_machine_id", + server->properties()[property::VIRTUALSERVER_MACHINE_ID].as_unchecked()); if(cmd.hasParm("uid")) - result.put_unchecked(index, "virtualserver_unique_identifier", server->properties()[property::VIRTUALSERVER_UNIQUE_IDENTIFIER].as()); + result.put_unchecked(index, "virtualserver_unique_identifier", + server->properties()[property::VIRTUALSERVER_UNIQUE_IDENTIFIER].as_unchecked()); else result.put_unchecked(index, "virtualserver_unique_identifier", ""); index++; } @@ -702,7 +726,7 @@ command_result QueryClient::handleCommandServerCreate(Command& cmd) { Command res(""); res["sid"] = server->getServerId(); res["error"] = startError; - res["virtualserver_port"] = server->properties()[property::VIRTUALSERVER_PORT].as(); + res["virtualserver_port"] = server->properties()[property::VIRTUALSERVER_PORT].as_unchecked(); res["token"] = tokens.empty() ? "unknown" : tokens[0]->token; res["time_create"] = time_create.count(); res["time_start"] = time_start.count(); @@ -790,8 +814,8 @@ command_result QueryClient::handleCommandInstanceInfo(Command& cmd) { ACTION_REQUIRES_INSTANCE_PERMISSION(permission::b_serverinstance_info_view, 1); Command res(""); - for(const auto& e : serverInstance->properties().list_properties(property::FLAG_INSTANCE_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) - res[e.type().name] = e.as(); + for(const auto& e : serverInstance->properties()->list_properties(property::FLAG_INSTANCE_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) + res[e.type().name] = e.value(); if(!this->properties()[property::CLIENT_LOGIN_NAME].value().empty()) res["serverinstance_teaspeak"] = true; res["serverinstance_serverquery_max_connections_per_ip"] = res["serverinstance_query_max_connections_per_ip"].as(); diff --git a/server/src/client/shared/WhisperHandler.cpp b/server/src/client/shared/WhisperHandler.cpp index 346fcf1..be8e7e2 100644 --- a/server/src/client/shared/WhisperHandler.cpp +++ b/server/src/client/shared/WhisperHandler.cpp @@ -183,7 +183,7 @@ size_t WhisperHandler::max_whisper_targets() { return false; } - auto result = server->properties()[property::VIRTUALSERVER_MIN_CLIENTS_IN_CHANNEL_BEFORE_FORCED_SILENCE].as_save([]{ return kMaxWhisperTargets; }); + auto result = server->properties()[property::VIRTUALSERVER_MIN_CLIENTS_IN_CHANNEL_BEFORE_FORCED_SILENCE].as_or(kMaxWhisperTargets); if(result > kMaxWhisperTargets) { result = kMaxWhisperTargets; } @@ -273,7 +273,7 @@ ts::command_result WhisperHandler::initialize_session_new(uint32_t stream_id, ui target_clients.push_back(speaking_client); } } else if (type == WhisperType::CHANNEL_COMMANDER) { - if (speaking_client->properties()[property::CLIENT_IS_CHANNEL_COMMANDER].as_save([] { return false; })) { + if (speaking_client->properties()[property::CLIENT_IS_CHANNEL_COMMANDER].as_or(false)) { target_clients.push_back(speaking_client); } } else { diff --git a/server/src/client/voice/VoiceClientCommandHandler.cpp b/server/src/client/voice/VoiceClientCommandHandler.cpp index b976a43..69680ba 100644 --- a/server/src/client/voice/VoiceClientCommandHandler.cpp +++ b/server/src/client/voice/VoiceClientCommandHandler.cpp @@ -98,7 +98,7 @@ command_result VoiceClient::handleCommandClientInit(Command &cmd) { return command_result{error::client_could_not_validate_identity}; } - auto requiredLevel = this->getServer()->properties()[property::VIRTUALSERVER_NEEDED_IDENTITY_SECURITY_LEVEL].as(); + auto requiredLevel = this->getServer()->properties()[property::VIRTUALSERVER_NEEDED_IDENTITY_SECURITY_LEVEL].as_unchecked(); if(security_level < requiredLevel) { return command_result{error::client_could_not_validate_identity, to_string(requiredLevel)}; } diff --git a/server/src/manager/ConversationManager.cpp b/server/src/manager/ConversationManager.cpp index 72113e6..6330a59 100644 --- a/server/src/manager/ConversationManager.cpp +++ b/server/src/manager/ConversationManager.cpp @@ -1395,7 +1395,7 @@ void ConversationManager::synchronize_channels() { continue; } - auto history_size = schannel->properties()[property::CHANNEL_CONVERSATION_HISTORY_LENGTH].as(); + auto history_size = schannel->properties()[property::CHANNEL_CONVERSATION_HISTORY_LENGTH].as_unchecked(); channel->set_history_length(history_size); } } diff --git a/server/src/music/MusicBotManager.cpp b/server/src/music/MusicBotManager.cpp index 77f6287..6a9cceb 100644 --- a/server/src/music/MusicBotManager.cpp +++ b/server/src/music/MusicBotManager.cpp @@ -203,7 +203,7 @@ void MusicBotManager::load_bots() { size_t disabled_bots = 0; for(const auto& bot : this->music_bots) { if(bot_limit >= 1) { - if(!bot->properties()[property::CLIENT_DISABLED].as()) + if(!bot->properties()[property::CLIENT_DISABLED].as_unchecked()) bot_limit--; } else { //TODO log message diff --git a/server/src/music/MusicPlaylist.cpp b/server/src/music/MusicPlaylist.cpp index 8199653..ddfab54 100644 --- a/server/src/music/MusicPlaylist.cpp +++ b/server/src/music/MusicPlaylist.cpp @@ -13,7 +13,7 @@ using namespace ts::music; using namespace std; using namespace std::chrono; -Playlist::Playlist(const std::shared_ptr &manager, std::shared_ptr properties, std::shared_ptr permissions) : +Playlist::Playlist(const std::shared_ptr &manager, std::shared_ptr properties, std::shared_ptr permissions) : PlaylistPermissions{std::move(permissions)}, _properties{std::move(properties)}, manager{manager} { } Playlist::~Playlist() { diff --git a/server/src/music/MusicPlaylist.h b/server/src/music/MusicPlaylist.h index 31d0120..1952f34 100644 --- a/server/src/music/MusicPlaylist.h +++ b/server/src/music/MusicPlaylist.h @@ -90,7 +90,7 @@ namespace ts { }; }; - Playlist(const std::shared_ptr& /* manager */, std::shared_ptr /* properties */, std::shared_ptr /* permissions */); + Playlist(const std::shared_ptr& /* manager */, std::shared_ptr /* properties */, std::shared_ptr /* permissions */); virtual ~Playlist(); virtual void load_songs(); @@ -103,14 +103,14 @@ namespace ts { virtual bool delete_song(SongId /* song */); virtual bool reorder_song(SongId /* song */, SongId /* new id */); - inline Properties& properties() const { return *this->_properties; } + inline PropertyManager& properties() const { return *this->_properties; } inline PlaylistId playlist_id() { - return this->properties()[property::PLAYLIST_ID].as(); + return this->properties()[property::PLAYLIST_ID].as_unchecked(); } inline Type::value playlist_type() { - return this->properties()[property::PLAYLIST_TYPE].as(); + return this->properties()[property::PLAYLIST_TYPE].as_unchecked(); } inline int32_t max_songs() { @@ -128,10 +128,11 @@ namespace ts { bool is_subscriber(const std::shared_ptr&); protected: virtual void set_self_ref(const std::shared_ptr& /* playlist */); - [[nodiscard]] bool is_playlist_owner(ClientDbId database_id) const override { return this->properties()[property::PLAYLIST_OWNER_DBID].as_save() == database_id; } + [[nodiscard]] bool is_playlist_owner(ClientDbId database_id) const override { return + this->properties()[property::PLAYLIST_OWNER_DBID].as_or(0) == database_id; } std::atomic current_id; - std::shared_ptr _properties; + std::shared_ptr _properties; std::weak_ptr manager; std::weak_ptr _self; bool _songs_loaded = false; diff --git a/server/src/music/PlayablePlaylist.cpp b/server/src/music/PlayablePlaylist.cpp index 0e55c44..d23e60f 100644 --- a/server/src/music/PlayablePlaylist.cpp +++ b/server/src/music/PlayablePlaylist.cpp @@ -11,7 +11,7 @@ using namespace ts::music; using namespace std; using namespace std::chrono; -PlayablePlaylist::PlayablePlaylist(const std::shared_ptr &handle, const std::shared_ptr &props, const std::shared_ptr& perms) : Playlist(handle, props, perms) { } +PlayablePlaylist::PlayablePlaylist(const std::shared_ptr &handle, const std::shared_ptr &props, const std::shared_ptr& perms) : Playlist(handle, props, perms) { } PlayablePlaylist::~PlayablePlaylist() {} @@ -19,7 +19,7 @@ void PlayablePlaylist::load_songs() { Playlist::load_songs(); unique_lock playlist_lock(this->playlist_mutex); - auto song_id = this->properties()[property::PLAYLIST_CURRENT_SONG_ID].as_save(); + auto song_id = this->properties()[property::PLAYLIST_CURRENT_SONG_ID].as_or(0); auto current_song = this->playlist_find(playlist_lock, song_id); if(!current_song && song_id != 0) { logWarning(this->get_server_id(), "[Playlist] Failed to reinitialize current song index for playlist {}. Song {} is missing.", this->playlist_id(), song_id); @@ -60,7 +60,7 @@ std::shared_ptr PlayablePlaylist::current_song(bool& aw auto entry = this->current_loading_entry.lock(); auto id = entry ? entry->song_id : 0; - if(this->properties()[property::PLAYLIST_CURRENT_SONG_ID].as() != id) /* should not happen */ + if(this->properties()[property::PLAYLIST_CURRENT_SONG_ID].as_unchecked() != id) /* should not happen */ this->properties()[property::PLAYLIST_CURRENT_SONG_ID] = id; if(!entry) @@ -111,7 +111,7 @@ std::shared_ptr PlayablePlaylist::current_song(bool& aw std::shared_ptr PlayablePlaylist::playlist_next_entry() { if(!this->playlist_head) return nullptr; /* fuzzy check if we're not empty */ - auto replay_mode = this->properties()[property::PLAYLIST_REPLAY_MODE].as(); + auto replay_mode = this->properties()[property::PLAYLIST_REPLAY_MODE].as_unchecked(); unique_lock playlist_lock(this->playlist_mutex); auto old_song = this->playlist_find(playlist_lock, this->currently_playing()); @@ -155,7 +155,7 @@ std::shared_ptr PlayablePlaylist::playlist_next_entry() { } } playlist_lock.unlock(); - if(old_song && this->properties()[property::PLAYLIST_FLAG_DELETE_PLAYED].as()) { + if(old_song && this->properties()[property::PLAYLIST_FLAG_DELETE_PLAYED].as_unchecked()) { this->delete_song(old_song->entry->song_id); } return result; @@ -163,7 +163,7 @@ std::shared_ptr PlayablePlaylist::playlist_next_entry() { std::shared_ptr PlayablePlaylist::playlist_previous_entry() { if(!this->playlist_head) return nullptr; /* fuzzy check if we're not empty */ - auto replay_mode = this->properties()[property::PLAYLIST_REPLAY_MODE].as(); + auto replay_mode = this->properties()[property::PLAYLIST_REPLAY_MODE].as_unchecked(); unique_lock playlist_lock(this->playlist_mutex); this->properties()[property::PLAYLIST_FLAG_FINISHED] = false; @@ -200,7 +200,7 @@ bool PlayablePlaylist::set_current_song(SongId song_id) { if(current_song) { this->enqueue_load(current_song->entry); auto id = current_song ? current_song->entry->song_id : 0; - if(this->properties()[property::PLAYLIST_CURRENT_SONG_ID].as() != id) + if(this->properties()[property::PLAYLIST_CURRENT_SONG_ID].as_unchecked() != id) this->properties()[property::PLAYLIST_CURRENT_SONG_ID] = id; } } diff --git a/server/src/music/PlayablePlaylist.h b/server/src/music/PlayablePlaylist.h index a282004..2a85a0e 100644 --- a/server/src/music/PlayablePlaylist.h +++ b/server/src/music/PlayablePlaylist.h @@ -24,12 +24,12 @@ namespace ts { SHUFFLE }; }; - PlayablePlaylist(const std::shared_ptr& /* manager */, const std::shared_ptr& /* properties */, const std::shared_ptr& /* permissions */); + PlayablePlaylist(const std::shared_ptr& /* manager */, const std::shared_ptr& /* properties */, const std::shared_ptr& /* permissions */); virtual ~PlayablePlaylist(); void load_songs() override; - inline ReplayMode::value replay_mode() { return this->properties()[property::PLAYLIST_REPLAY_MODE].as(); } + inline ReplayMode::value replay_mode() { return this->properties()[property::PLAYLIST_REPLAY_MODE].as_unchecked(); } inline void set_replay_mode(ReplayMode::value mode) { this->properties()[property::PLAYLIST_REPLAY_MODE] = mode; } inline SongId currently_playing() { return this->properties()[property::PLAYLIST_CURRENT_SONG_ID]; } diff --git a/server/src/server/QueryServer.cpp b/server/src/server/QueryServer.cpp index 98a8a33..26ff42d 100644 --- a/server/src/server/QueryServer.cpp +++ b/server/src/server/QueryServer.cpp @@ -406,7 +406,7 @@ void QueryServer::on_client_receive(int server_file_descriptor, short, void *) { { unique_lock lock{this->connected_clients_mutex}; - auto max_connections = serverInstance->properties()[property::SERVERINSTANCE_QUERY_MAX_CONNECTIONS].as(); + auto max_connections = serverInstance->properties()[property::SERVERINSTANCE_QUERY_MAX_CONNECTIONS].as_unchecked(); if(max_connections > 0 && max_connections <= this->connected_clients.size()) { lock.unlock(); logMessage(LOG_QUERY, "[{}] Dropping new query connection attempt because of too many connected query clients.", logging_address(remote_address)); @@ -415,7 +415,7 @@ void QueryServer::on_client_receive(int server_file_descriptor, short, void *) { return; } - auto max_ip_connections = serverInstance->properties()[property::SERVERINSTANCE_QUERY_MAX_CONNECTIONS_PER_IP].as(); + auto max_ip_connections = serverInstance->properties()[property::SERVERINSTANCE_QUERY_MAX_CONNECTIONS_PER_IP].as_unchecked(); if(max_ip_connections > 0) { size_t connection_count = 0; for(auto& client : this->connected_clients) { diff --git a/server/src/snapshots/channel.h b/server/src/snapshots/channel.h index c32e837..f67253d 100644 --- a/server/src/snapshots/channel.h +++ b/server/src/snapshots/channel.h @@ -8,7 +8,7 @@ namespace ts::server::snapshots { struct channel_entry { - Properties properties{}; + PropertyManager properties{}; }; class channel_parser : public parser { diff --git a/server/src/snapshots/deploy.cpp b/server/src/snapshots/deploy.cpp index fa71cd2..1c36a9f 100644 --- a/server/src/snapshots/deploy.cpp +++ b/server/src/snapshots/deploy.cpp @@ -35,7 +35,7 @@ VirtualServerManager::SnapshotDeployResult VirtualServerManager::deploy_snapshot } std::string server_host{server ? server->properties()[property::VIRTUALSERVER_HOST].value() : config::binding::DefaultVoiceHost}; - uint16_t server_port{server ? server->properties()[property::VIRTUALSERVER_PORT].as() : this->next_available_port(server_host)}; + uint16_t server_port{server ? server->properties()[property::VIRTUALSERVER_PORT].as_unchecked() : this->next_available_port(server_host)}; this->delete_server_in_db(kSnapshotServerId, false); auto result = sql::command{this->handle->getSql(), "INSERT INTO `servers` (`serverId`, `host`, `port`) VALUES (:sid, :host, :port)"} .value(":sid", kSnapshotServerId) @@ -206,7 +206,7 @@ bool VirtualServerManager::try_deploy_snapshot(std::string &error, ts::ServerId /* Update channel parents and order id */ for(auto& channel : snapshot_data.parsed_channels) { { - auto pid = channel.properties[property::CHANNEL_PID].as(); + auto pid = channel.properties[property::CHANNEL_PID].as_unchecked(); if(pid > 0) { auto new_id = mappings.channel_id.find(pid); if(new_id == mappings.channel_id.end()) { @@ -218,7 +218,7 @@ bool VirtualServerManager::try_deploy_snapshot(std::string &error, ts::ServerId } { - auto oid = channel.properties[property::CHANNEL_ORDER].as(); + auto oid = channel.properties[property::CHANNEL_ORDER].as_unchecked(); if(oid > 0) { auto new_id = mappings.channel_id.find(oid); if(new_id == mappings.channel_id.end()) { @@ -246,11 +246,11 @@ bool VirtualServerManager::try_deploy_snapshot(std::string &error, ts::ServerId }; for(auto& channel : snapshot_data.parsed_channels) { - auto channel_id = channel.properties[property::CHANNEL_ID].as(); + auto channel_id = channel.properties[property::CHANNEL_ID].as_unchecked(); insert_query.add_entry( target_server_id, channel_id, - channel.properties[property::CHANNEL_PID].as() + channel.properties[property::CHANNEL_PID].as_unchecked() ); for(const auto& property : channel.properties.list_properties(property::FLAG_SAVE)) { @@ -585,7 +585,7 @@ bool VirtualServerManager::try_deploy_snapshot(std::string &error, ts::ServerId auto value = property.value(); switch(property.type().property_index) { case property::VIRTUALSERVER_DEFAULT_SERVER_GROUP: { - auto new_id = mappings.server_group_id.find(property.as()); + auto new_id = mappings.server_group_id.find(property.as_unchecked()); if(new_id == mappings.server_group_id.end()) { logWarning(logging_server_id, "Missing server group mapping for group {}. {} will reference an invalid group.", property.value(), property.type().name); break; @@ -597,7 +597,7 @@ bool VirtualServerManager::try_deploy_snapshot(std::string &error, ts::ServerId case property::VIRTUALSERVER_DEFAULT_CHANNEL_ADMIN_GROUP: case property::VIRTUALSERVER_DEFAULT_CHANNEL_GROUP: { - auto new_id = mappings.channel_group_id.find(property.as()); + auto new_id = mappings.channel_group_id.find(property.as_unchecked()); if(new_id == mappings.channel_group_id.end()) { logWarning(logging_server_id, "Missing channel group mapping for group {}. {} will reference an invalid group.", property.value(), property.type().name); break; @@ -796,7 +796,7 @@ bool VirtualServerManager::try_deploy_snapshot(std::string &error, ts::ServerId auto value = property.value(); if(property.type() == property::CLIENT_LAST_CHANNEL) { - auto channel_id = property.as(); + auto channel_id = property.as_unchecked(); auto new_channel_id = mappings.channel_id.find(channel_id); if(new_channel_id == mappings.channel_id.end()) { diff --git a/server/src/snapshots/music.h b/server/src/snapshots/music.h index 380174d..9e8f3a7 100644 --- a/server/src/snapshots/music.h +++ b/server/src/snapshots/music.h @@ -13,12 +13,12 @@ namespace ts::server::snapshots { std::string unique_id{}; ClientDbId bot_owner_id{}; - Properties properties{}; + PropertyManager properties{}; }; struct playlist_entry { PlaylistId playlist_id{0}; - Properties properties{}; + PropertyManager properties{}; }; struct playlist_song_entry { diff --git a/server/src/snapshots/server.h b/server/src/snapshots/server.h index 03aa134..4e7b6e6 100644 --- a/server/src/snapshots/server.h +++ b/server/src/snapshots/server.h @@ -8,7 +8,7 @@ namespace ts::server::snapshots { struct server_entry { - Properties properties{}; + PropertyManager properties{}; }; class server_parser : public parser { diff --git a/shared b/shared index b26132f..26981b9 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit b26132fa5498a1966bb11bbf9d1ee6bb32f39863 +Subproject commit 26981b95f70ed4418be0a0e1720eaa7c7fc0a76a