diff --git a/git-teaspeak b/git-teaspeak index dc0e490..cf3e1ed 160000 --- a/git-teaspeak +++ b/git-teaspeak @@ -1 +1 @@ -Subproject commit dc0e49097c317f9c04fb9bfc0c8f61156c743ba8 +Subproject commit cf3e1ed1069fca6f8bb657f96f851b5de4c8b033 diff --git a/server/src/TS3ServerClientManager.cpp b/server/src/TS3ServerClientManager.cpp index 4172680..e0ab9e3 100644 --- a/server/src/TS3ServerClientManager.cpp +++ b/server/src/TS3ServerClientManager.cpp @@ -101,7 +101,8 @@ bool VirtualServer::registerClient(shared_ptr client) { } bool VirtualServer::unregisterClient(shared_ptr client, std::string reason, std::unique_lock& chan_tree_lock) { - if(client->getType() == ClientType::CLIENT_TEAMSPEAK || client->getType() == ClientType::CLIENT_TEASPEAK || client->getType() == ClientType::CLIENT_WEB) { + /* FIXME: Reenable this for the web client as soon we've fixed the web client disconnect method */ + if(client->getType() == ClientType::CLIENT_TEAMSPEAK || client->getType() == ClientType::CLIENT_TEASPEAK/* || client->getType() == ClientType::CLIENT_WEB */) { sassert(client->state == ConnectionState::DISCONNECTED); } diff --git a/server/src/client/command_handler/groups.cpp b/server/src/client/command_handler/groups.cpp index ea4947e..461b578 100644 --- a/server/src/client/command_handler/groups.cpp +++ b/server/src/client/command_handler/groups.cpp @@ -51,18 +51,21 @@ command_result ConnectedClient::handleCommandGroupAdd(Command &cmd, GroupTarget return ts::command_result{error::vs_critical, "internal invalid group target"}; } - auto group_manager = this->server ? this->server->group_manager() : serverInstance->group_manager(); + std::shared_ptr group_manager{nullptr}; + log::GroupType log_group_type; auto group_type = cmd[0].has("type") ? cmd["type"].as() : groups::GroupType::GROUP_TYPE_NORMAL; switch (group_type) { case groups::GroupType::GROUP_TYPE_QUERY: ACTION_REQUIRES_GLOBAL_PERMISSION(permission::b_serverinstance_modify_querygroup, 1); log_group_type = log::GroupType::QUERY; + group_manager = serverInstance->group_manager(); break; case groups::GroupType::GROUP_TYPE_TEMPLATE: ACTION_REQUIRES_GLOBAL_PERMISSION(permission::b_serverinstance_modify_templates, 1); log_group_type = log::GroupType::TEMPLATE; + group_manager = serverInstance->group_manager(); break; case groups::GroupType::GROUP_TYPE_NORMAL: @@ -70,6 +73,7 @@ command_result ConnectedClient::handleCommandGroupAdd(Command &cmd, GroupTarget return command_result{error::parameter_invalid, "you cant create normal groups on the template server!"}; } log_group_type = log::GroupType::NORMAL; + group_manager = this->server->group_manager(); break; case groups::GroupType::GROUP_TYPE_UNKNOWN: @@ -148,10 +152,17 @@ command_result ConnectedClient::handleCommandGroupAdd(Command &cmd, GroupTarget } std::deque> server_updates{}; - if(!this->server) { - server_updates = serverInstance->getVoiceServerManager()->serverInstances(); - } else { - server_updates.push_back(this->server); + switch(group_type) { + case groups::GROUP_TYPE_QUERY: + case groups::GROUP_TYPE_TEMPLATE: + server_updates = serverInstance->getVoiceServerManager()->serverInstances(); + break; + + case groups::GROUP_TYPE_NORMAL: + case groups::GROUP_TYPE_UNKNOWN: + default: + server_updates.push_back(this->server); + break; } for(const auto& server : server_updates) { @@ -656,16 +667,19 @@ command_result ConnectedClient::handleCommandGroupDel(Command &cmd, GroupTarget break; } + bool global_update; log::GroupType log_group_type; switch (group->group_type()) { case groups::GroupType::GROUP_TYPE_QUERY: ACTION_REQUIRES_GLOBAL_PERMISSION(permission::b_serverinstance_modify_querygroup, 1); log_group_type = log::GroupType::QUERY; + global_update = true; break; case groups::GroupType::GROUP_TYPE_TEMPLATE: ACTION_REQUIRES_GLOBAL_PERMISSION(permission::b_serverinstance_modify_templates, 1); log_group_type = log::GroupType::TEMPLATE; + global_update = true; break; case groups::GroupType::GROUP_TYPE_NORMAL: @@ -680,6 +694,7 @@ command_result ConnectedClient::handleCommandGroupDel(Command &cmd, GroupTarget } log_group_type = log::GroupType::NORMAL; + global_update = false; break; case groups::GroupType::GROUP_TYPE_UNKNOWN: @@ -730,7 +745,7 @@ command_result ConnectedClient::handleCommandGroupDel(Command &cmd, GroupTarget serverInstance->action_logger()->group_logger.log_group_delete(this->getServerId(), this->ref(), log_group_target, log_group_type, group->group_id(), group->display_name()); std::deque> server_updates{}; - if(!this->server) { + if(global_update) { server_updates = serverInstance->getVoiceServerManager()->serverInstances(); } else { server_updates.push_back(this->server); diff --git a/server/src/client/voice/VoiceClient.cpp b/server/src/client/voice/VoiceClient.cpp index 69c579a..29e4aab 100644 --- a/server/src/client/voice/VoiceClient.cpp +++ b/server/src/client/voice/VoiceClient.cpp @@ -251,6 +251,7 @@ bool VoiceClient::close_connection(const system_clock::time_point &timeout) { return true; } + this->flush_executed = true; this->flush_timeout = timeout; auto weak_client{this->weak_ref()}; @@ -268,7 +269,7 @@ bool VoiceClient::close_connection(const system_clock::time_point &timeout) { std::lock_guard state_lock{client->state_lock}; switch(client->state) { case ConnectionState::DISCONNECTED: - /* somebody else already disconnected the client */ + /* Client has successfully been disconnect. Our task should be removed soon. */ return; case ConnectionState::CONNECTED: @@ -326,7 +327,6 @@ void VoiceClient::finalDisconnect() { { std::lock_guard flush_lock{this->flush_mutex}; - this->flush_executed = true; if(this->flush_task) { serverInstance->general_task_executor()->cancel_task(this->flush_task); this->flush_task = 0; @@ -341,8 +341,10 @@ void VoiceClient::finalDisconnect() { std::lock_guard command_lock{this->command_lock}; this->processLeave(); - if(this->voice_server) { - this->voice_server->unregisterConnection(ownLock); + /* The voice server might be null if it's already gone */ + auto voice_server_{this->voice_server}; + if(voice_server_) { + voice_server_->unregisterConnection(ownLock); } } diff --git a/server/src/client/voice/VoiceClient.h b/server/src/client/voice/VoiceClient.h index c27d562..52d4c74 100644 --- a/server/src/client/voice/VoiceClient.h +++ b/server/src/client/voice/VoiceClient.h @@ -72,7 +72,6 @@ namespace ts { virtual void sendCommand0(const std::string_view& /* data */, bool low, std::unique_ptr> listener); connection::VoiceClientConnection* getConnection(){ return connection; } - std::shared_ptr getVoiceServer(){ return voice_server; } [[nodiscard]] std::chrono::milliseconds current_ping(); [[nodiscard]] float current_ping_deviation(); @@ -87,6 +86,7 @@ namespace ts { connection::VoiceClientConnection* connection; protected: + /* Might be null when the server has been deleted but the client hasn't yet fully disconnected */ std::shared_ptr voice_server; void initialize(); @@ -127,6 +127,7 @@ namespace ts { std::unique_ptr server_command_queue_{}; bool video_unsupported_message_send{false}; + /* This method should only be called from the close connection method! */ void finalDisconnect(); /* Used by close_connection to determine if we've successfully flushed the connection */ diff --git a/server/src/terminal/CommandHandler.cpp b/server/src/terminal/CommandHandler.cpp index 670d0cd..82d569b 100644 --- a/server/src/terminal/CommandHandler.cpp +++ b/server/src/terminal/CommandHandler.cpp @@ -81,6 +81,8 @@ namespace terminal::chandler { return handleCommandStatsReset(command, cmd); else if(cmd.lcommand == "reload") return handleCommandReload(command, cmd); + else if(cmd.lcommand == "taskinfo") + return handleCommandTaskInfo(command, cmd); else { logWarning(LOG_INSTANCE, "Missing terminal command {} ({})", cmd.command, cmd.line); command.response.emplace_back("unknown command"); @@ -530,4 +532,12 @@ namespace terminal::chandler { return true; } + + + extern bool handleCommandTaskInfo(CommandHandle& handle, TerminalCommand& cmd) { + serverInstance->general_task_executor()->print_statistics([&](const std::string& message) { + handle.response.push_back(message); + }, cmd.arguments.size() >= 1 && cmd.larguments[0] == "full"); + return true; + } } \ No newline at end of file diff --git a/server/src/terminal/CommandHandler.h b/server/src/terminal/CommandHandler.h index 7ee9f56..b6ce8fb 100644 --- a/server/src/terminal/CommandHandler.h +++ b/server/src/terminal/CommandHandler.h @@ -40,4 +40,5 @@ namespace terminal::chandler { extern bool handleCommandStatsReset(CommandHandle& /* handle */, TerminalCommand&); extern bool handleCommandReload(CommandHandle& /* handle */, TerminalCommand&); + extern bool handleCommandTaskInfo(CommandHandle& /* handle */, TerminalCommand&); } \ No newline at end of file diff --git a/shared b/shared index c7985c4..616149d 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit c7985c4dd1fc96222cb8e4b170d07dd023d04c74 +Subproject commit 616149d5dddf1fa2545922a1d97c438a9e51da3d