diff --git a/server/src/InstanceHandler.h b/server/src/InstanceHandler.h index b032671..a412e24 100644 --- a/server/src/InstanceHandler.h +++ b/server/src/InstanceHandler.h @@ -42,9 +42,8 @@ namespace ts { bool startInstance(); void stopInstance(); - ts::PropertyManager& 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; } std::shared_ptr getGroupManager(){ return groupManager; } @@ -75,16 +74,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_; } diff --git a/server/src/ServerManagerSnapshotDeploy.cpp b/server/src/ServerManagerSnapshotDeploy.cpp index f99c11a..fdc10d8 100644 --- a/server/src/ServerManagerSnapshotDeploy.cpp +++ b/server/src/ServerManagerSnapshotDeploy.cpp @@ -782,7 +782,7 @@ 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: @@ -803,7 +803,7 @@ bool VirtualServerManager::createServerSnapshot(Command &cmd, shared_ptrgetChannelTree()->channels()) { - for(const auto& channelProperty : channel->properties().list_properties(property::FLAG_SNAPSHOT)) { + 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) { diff --git a/server/src/TS3ServerHeartbeat.cpp b/server/src/TS3ServerHeartbeat.cpp index 4656452..7ea364d 100644 --- a/server/src/TS3ServerHeartbeat.cpp +++ b/server/src/TS3ServerHeartbeat.cpp @@ -183,10 +183,7 @@ 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_or(0)); + seconds deleteTimeout{channel->properties()[property::CHANNEL_DELETE_DELAY].as_or(0)}; auto last_left = time_point() + milliseconds( channel->properties()[property::CHANNEL_LAST_LEFT].as_or(0)); diff --git a/server/src/VirtualServer.cpp b/server/src/VirtualServer.cpp index b2116b2..a3e1a64 100644 --- a/server/src/VirtualServer.cpp +++ b/server/src/VirtualServer.cpp @@ -252,7 +252,7 @@ bool VirtualServer::initialize(bool test_properties) { this->properties()[property::VIRTUALSERVER_NAME].value(), false); this->serverRoot->initialize_weak_reference(this->serverRoot); - this->properties().registerNotifyHandler([&](Property& property) { + this->properties()->registerNotifyHandler([&](Property& property) { if(property.type() == property::VIRTUALSERVER_NAME) { static_pointer_cast(this->serverRoot)->properties()[property::CLIENT_NICKNAME] = property.value(); } @@ -655,6 +655,7 @@ OnlineClientReport VirtualServer::onlineStats() { switch (cl->getType()) { case CLIENT_TEAMSPEAK: + case CLIENT_TEASPEAK: response.clients_ts++; break; case CLIENT_WEB: @@ -666,6 +667,8 @@ OnlineClientReport VirtualServer::onlineStats() { case CLIENT_MUSIC: response.bots++; break; + case CLIENT_INTERNAL: + case MAX: default: break; } diff --git a/server/src/VirtualServer.h b/server/src/VirtualServer.h index 65e6cfa..0dd17c7 100644 --- a/server/src/VirtualServer.h +++ b/server/src/VirtualServer.h @@ -181,7 +181,8 @@ namespace ts { ecc_key* serverKey(){ return _serverKey; } std::string publicServerKey(); - PropertyManager& 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; } diff --git a/server/src/VirtualServerManager.cpp b/server/src/VirtualServerManager.cpp index e72c634..d26856b 100644 --- a/server/src/VirtualServerManager.cpp +++ b/server/src/VirtualServerManager.cpp @@ -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 */ } diff --git a/server/src/channel/ServerChannel.cpp b/server/src/channel/ServerChannel.cpp index 8f174bb..6e4b404 100644 --- a/server/src/channel/ServerChannel.cpp +++ b/server/src/channel/ServerChannel.cpp @@ -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,8 +135,7 @@ 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_or(0) != 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()){ diff --git a/server/src/client/ConnectedClient.cpp b/server/src/client/ConnectedClient.cpp index f253397..0cce013 100644 --- a/server/src/client/ConnectedClient.cpp +++ b/server/src/client/ConnectedClient.cpp @@ -677,7 +677,7 @@ 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 @@ -799,7 +799,7 @@ 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; diff --git a/server/src/client/ConnectedClientNotifyHandler.cpp b/server/src/client/ConnectedClientNotifyHandler.cpp index 2b7f8f8..3f42f4e 100644 --- a/server/src/client/ConnectedClientNotifyHandler.cpp +++ b/server/src/client/ConnectedClientNotifyHandler.cpp @@ -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) { @@ -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/DataClient.h b/server/src/client/DataClient.h index 4c78b11..c9cc76c 100644 --- a/server/src/client/DataClient.h +++ b/server/src/client/DataClient.h @@ -24,45 +24,11 @@ namespace ts { friend class QueryServer; friend class music::MusicBotManager; public: - struct PropertyWrapper { - std::shared_ptr handle; - - PropertyManager* operator->() { - return handle.get(); - } - - const PropertyManager* 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::Property 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}; } /* main permission calculate function */ /** diff --git a/server/src/client/command_handler/channel.cpp b/server/src/client/command_handler/channel.cpp index d8fd54a..1e4ced0 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); @@ -1182,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. */ @@ -1411,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) { @@ -1478,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 */ @@ -1553,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)); @@ -2477,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/server.cpp b/server/src/client/command_handler/server.cpp index fa1a978..a6fd7c3 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(); diff --git a/server/src/client/query/QueryClientCommands.cpp b/server/src/client/query/QueryClientCommands.cpp index 918ded8..19f3ac6 100644 --- a/server/src/client/query/QueryClientCommands.cpp +++ b/server/src/client/query/QueryClientCommands.cpp @@ -459,7 +459,8 @@ 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)) { + 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_unchecked(); @@ -813,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_unchecked(); + 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/shared b/shared index 465975e..206e005 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit 465975e9cadf9a6b6e768dc6551c947a0ff32b3c +Subproject commit 206e0052d1dbe64072e1ce145c380b12114d78d5