Improved the db info command performance
This commit is contained in:
		
							parent
							
								
									8ca58056d4
								
							
						
					
					
						commit
						1c99f093c8
					
				@ -328,7 +328,7 @@ namespace ts {
 | 
			
		||||
 | 
			
		||||
                std::deque<std::weak_ptr<ConnectedClient>> visibleClients{}; /* variable locked with channel_lock */
 | 
			
		||||
                std::deque<std::weak_ptr<ConnectedClient>> mutedClients{}; /* variable locked with channel_lock */
 | 
			
		||||
                std::deque<std::weak_ptr<ConnectedClient>> openChats{}; /* variable locked with channel_lock */
 | 
			
		||||
                std::deque<std::weak_ptr<ConnectedClient>> open_private_conversations{}; /* variable locked with channel_lock */
 | 
			
		||||
 | 
			
		||||
                std::chrono::system_clock::time_point lastNeededNotify;
 | 
			
		||||
                std::shared_ptr<BasicChannel> lastNeededPermissionNotifyChannel = nullptr;
 | 
			
		||||
 | 
			
		||||
@ -359,15 +359,15 @@ command_result ConnectedClient::handleCommandClientChatClosed(Command &cmd) {
 | 
			
		||||
    if (!client) return command_result{error::client_invalid_id};
 | 
			
		||||
    {
 | 
			
		||||
        unique_lock channel_lock(this->channel_lock);
 | 
			
		||||
        this->openChats.erase(remove_if(this->openChats.begin(), this->openChats.end(), [&](const weak_ptr<ConnectedClient>& weak) {
 | 
			
		||||
        this->open_private_conversations.erase(remove_if(this->open_private_conversations.begin(), this->open_private_conversations.end(), [&](const weak_ptr<ConnectedClient>& weak) {
 | 
			
		||||
            return weak.lock() == client;
 | 
			
		||||
        }), this->openChats.end());
 | 
			
		||||
        }), this->open_private_conversations.end());
 | 
			
		||||
    }
 | 
			
		||||
    {
 | 
			
		||||
        unique_lock channel_lock(client->get_channel_lock());
 | 
			
		||||
        client->openChats.erase(remove_if(client->openChats.begin(), client->openChats.end(), [&](const weak_ptr<ConnectedClient>& weak) {
 | 
			
		||||
        client->open_private_conversations.erase(remove_if(client->open_private_conversations.begin(), client->open_private_conversations.end(), [&](const weak_ptr<ConnectedClient>& weak) {
 | 
			
		||||
            return weak.lock().get() == this;
 | 
			
		||||
        }), client->openChats.end());
 | 
			
		||||
        }), client->open_private_conversations.end());
 | 
			
		||||
    }
 | 
			
		||||
    client->notifyClientChatClosed(_this.lock());
 | 
			
		||||
    return command_result{error::ok};
 | 
			
		||||
@ -1047,51 +1047,64 @@ command_result ConnectedClient::handleCommandClientDbInfo(Command &cmd) {
 | 
			
		||||
    CMD_CHK_AND_INC_FLOOD_POINTS(5);
 | 
			
		||||
    ACTION_REQUIRES_GLOBAL_PERMISSION(permission::b_virtualserver_client_dbinfo, 1);
 | 
			
		||||
 | 
			
		||||
    deque<ClientDbId> cldbids;
 | 
			
		||||
    for(int index = 0; index < cmd.bulkCount(); index++)
 | 
			
		||||
    std::deque<ClientDbId> cldbids;
 | 
			
		||||
    for(int index = 0; index < cmd.bulkCount(); index++) {
 | 
			
		||||
        cldbids.push_back(cmd[index]["cldbid"]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto basic = serverInstance->databaseHelper()->queryDatabaseInfo(this->server, cldbids);
 | 
			
		||||
    if (basic.empty()) return command_result{error::database_empty_result};
 | 
			
		||||
    if (basic.empty()) {
 | 
			
		||||
        return command_result{error::database_empty_result};
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    auto allow_ip = permission::v2::permission_granted(1, this->calculate_permission(permission::b_client_remoteaddress_view, 0));
 | 
			
		||||
    Command res(this->getExternalType() == ClientType::CLIENT_TEAMSPEAK ? "notifyclientdbinfo" : "");
 | 
			
		||||
    ts::command_builder result{this->getExternalType() == ClientType::CLIENT_TEAMSPEAK ? "notifyclientdbinfo" : ""};
 | 
			
		||||
    result.reserve_bulks(basic.size());
 | 
			
		||||
 | 
			
		||||
    size_t index = 0;
 | 
			
		||||
    for(const auto& info : basic) {
 | 
			
		||||
        res[index]["client_base64HashClientUID"] = hex::hex(base64::validate(info->client_unique_id) ? base64::decode(info->client_unique_id) : info->client_unique_id, 'a', 'q');
 | 
			
		||||
        res[index]["client_unique_identifier"] = info->client_unique_id;
 | 
			
		||||
        res[index]["client_nickname"] = info->client_nickname;
 | 
			
		||||
        res[index]["client_database_id"] = info->client_database_id;
 | 
			
		||||
        res[index]["client_created"] = chrono::duration_cast<chrono::seconds>(info->client_created.time_since_epoch()).count();
 | 
			
		||||
        res[index]["client_lastconnected"] = chrono::duration_cast<chrono::seconds>(info->client_last_connected.time_since_epoch()).count();
 | 
			
		||||
        res[index]["client_totalconnections"] = info->client_total_connections;
 | 
			
		||||
        res[index]["client_database_id"] = info->client_database_id;
 | 
			
		||||
        auto bulk = result.bulk(index++);
 | 
			
		||||
        bulk.reserve(800);
 | 
			
		||||
 | 
			
		||||
        bulk.put_unchecked("client_base64HashClientUID", hex::hex(base64::validate(info->client_unique_id) ? base64::decode(info->client_unique_id) : info->client_unique_id, 'a', 'q'));
 | 
			
		||||
        bulk.put_unchecked(property::CLIENT_UNIQUE_IDENTIFIER, info->client_unique_id);
 | 
			
		||||
        bulk.put_unchecked(property::CLIENT_NICKNAME, info->client_nickname);
 | 
			
		||||
        bulk.put_unchecked(property::CLIENT_DATABASE_ID, info->client_database_id);
 | 
			
		||||
        bulk.put_unchecked(property::CLIENT_CREATED, chrono::duration_cast<chrono::seconds>(info->client_created.time_since_epoch()).count());
 | 
			
		||||
        bulk.put_unchecked(property::CLIENT_LASTCONNECTED, chrono::duration_cast<chrono::seconds>(info->client_last_connected.time_since_epoch()).count());
 | 
			
		||||
        bulk.put_unchecked(property::CLIENT_TOTALCONNECTIONS, info->client_total_connections);
 | 
			
		||||
        bulk.put_unchecked(property::CLIENT_DATABASE_ID, info->client_database_id);
 | 
			
		||||
 | 
			
		||||
        auto props = serverInstance->databaseHelper()->loadClientProperties(this->server, info->client_database_id, ClientType::CLIENT_TEAMSPEAK);
 | 
			
		||||
        if (allow_ip)
 | 
			
		||||
            res[index]["client_lastip"] = (*props)[property::CONNECTION_CLIENT_IP].as<string>();
 | 
			
		||||
        else
 | 
			
		||||
            res[index]["client_lastip"] = "hidden";
 | 
			
		||||
        if(allow_ip) {
 | 
			
		||||
            bulk.put_unchecked("client_lastip", (*props)[property::CONNECTION_CLIENT_IP].as<string>());
 | 
			
		||||
        } else {
 | 
			
		||||
            bulk.put_unchecked("client_lastip", "hidden");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        res[index]["client_icon_id"] = (*props)[property::CLIENT_ICON_ID].as<string>();
 | 
			
		||||
        res[index]["client_badges"] = (*props)[property::CLIENT_BADGES].as<string>();
 | 
			
		||||
        res[index]["client_version"] = (*props)[property::CLIENT_VERSION].as<string>();
 | 
			
		||||
        res[index]["client_platform"] = (*props)[property::CLIENT_PLATFORM].as<string>();
 | 
			
		||||
        res[index]["client_hwid"] = (*props)[property::CLIENT_HARDWARE_ID].as<string>();
 | 
			
		||||
        res[index]["client_total_bytes_downloaded"] = (*props)[property::CLIENT_TOTAL_BYTES_DOWNLOADED].as<string>();
 | 
			
		||||
        res[index]["client_total_bytes_uploaded"] = (*props)[property::CLIENT_TOTAL_BYTES_UPLOADED].as<string>();
 | 
			
		||||
        res[index]["client_month_bytes_downloaded"] = (*props)[property::CLIENT_MONTH_BYTES_DOWNLOADED].as<string>();
 | 
			
		||||
        res[index]["client_month_bytes_uploaded"] = (*props)[property::CLIENT_MONTH_BYTES_DOWNLOADED].as<string>();
 | 
			
		||||
        res[index]["client_description"] = (*props)[property::CLIENT_DESCRIPTION].as<string>();
 | 
			
		||||
        res[index]["client_flag_avatar"] = (*props)[property::CLIENT_FLAG_AVATAR].as<string>();
 | 
			
		||||
#define ASSIGN_PROPERTY(property) \
 | 
			
		||||
        bulk.put_unchecked(property, (*props)[property].as<string>());
 | 
			
		||||
 | 
			
		||||
        ASSIGN_PROPERTY(property::CLIENT_ICON_ID);
 | 
			
		||||
        ASSIGN_PROPERTY(property::CLIENT_BADGES);
 | 
			
		||||
        ASSIGN_PROPERTY(property::CLIENT_VERSION);
 | 
			
		||||
        ASSIGN_PROPERTY(property::CLIENT_PLATFORM);
 | 
			
		||||
        ASSIGN_PROPERTY(property::CLIENT_HARDWARE_ID);
 | 
			
		||||
        ASSIGN_PROPERTY(property::CLIENT_TOTAL_BYTES_DOWNLOADED);
 | 
			
		||||
        ASSIGN_PROPERTY(property::CLIENT_TOTAL_BYTES_UPLOADED);
 | 
			
		||||
        ASSIGN_PROPERTY(property::CLIENT_MONTH_BYTES_DOWNLOADED);
 | 
			
		||||
        ASSIGN_PROPERTY(property::CLIENT_MONTH_BYTES_DOWNLOADED);
 | 
			
		||||
        ASSIGN_PROPERTY(property::CLIENT_DESCRIPTION);
 | 
			
		||||
        ASSIGN_PROPERTY(property::CLIENT_FLAG_AVATAR);
 | 
			
		||||
 | 
			
		||||
        ASSIGN_PROPERTY(property::CLIENT_MONTH_ONLINE_TIME);
 | 
			
		||||
        ASSIGN_PROPERTY(property::CLIENT_TOTAL_ONLINE_TIME);
 | 
			
		||||
#undef ASSIGN_PROPERTY
 | 
			
		||||
 | 
			
		||||
        res[index]["client_month_online_time"] = (*props)[property::CLIENT_MONTH_ONLINE_TIME].as<string>();
 | 
			
		||||
        res[index]["client_total_online_time"] = (*props)[property::CLIENT_TOTAL_ONLINE_TIME].as<string>();
 | 
			
		||||
        index++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this->sendCommand(res);
 | 
			
		||||
    this->sendCommand(result);
 | 
			
		||||
 | 
			
		||||
    return command_result{error::ok};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -551,12 +551,15 @@ command_result ConnectedClient::handleCommandSendTextMessage(Command &cmd) {
 | 
			
		||||
        ConnectedLockedClient target{this->server->find_client_by_id(cmd["target"].as<ClientId>())};
 | 
			
		||||
        if (!target) return command_result{error::client_invalid_id};
 | 
			
		||||
 | 
			
		||||
        bool chat_open = false;
 | 
			
		||||
        bool chat_open{false};
 | 
			
		||||
        {
 | 
			
		||||
 | 
			
		||||
            shared_lock channel_lock(this->channel_lock);
 | 
			
		||||
            this->openChats.erase(remove_if(this->openChats.begin(), this->openChats.end(), [](const weak_ptr<ConnectedClient>& weak) { return !weak.lock(); }), this->openChats.end());
 | 
			
		||||
            for(const auto& entry : this->openChats) {
 | 
			
		||||
            std::unique_lock self_channel_lock{this->channel_lock};
 | 
			
		||||
            this->open_private_conversations.erase(std::remove_if(this->open_private_conversations.begin(), this->open_private_conversations.end(), [](const weak_ptr<ConnectedClient>& weak) {
 | 
			
		||||
                return !weak.lock();
 | 
			
		||||
            }), this->open_private_conversations.end());
 | 
			
		||||
 | 
			
		||||
            for(const auto& entry : this->open_private_conversations) {
 | 
			
		||||
                if(entry.lock() == target) {
 | 
			
		||||
                    chat_open = true;
 | 
			
		||||
                    break;
 | 
			
		||||
@ -565,24 +568,30 @@ command_result ConnectedClient::handleCommandSendTextMessage(Command &cmd) {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(!chat_open) {
 | 
			
		||||
            if (target.client == this)
 | 
			
		||||
            if(target.client == this) {
 | 
			
		||||
                ACTION_REQUIRES_PERMISSION(permission::b_client_even_textmessage_send, 1, this->getChannelId());
 | 
			
		||||
            if(!permission::v2::permission_granted(target->calculate_permission(permission::i_client_needed_private_textmessage_power, target->getClientId()), this->calculate_permission(permission::i_client_private_textmessage_power, this->getClientId()), false))
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(!permission::v2::permission_granted(target->calculate_permission(permission::i_client_needed_private_textmessage_power, target->getClientId()), this->calculate_permission(permission::i_client_private_textmessage_power, this->getClientId()), false)) {
 | 
			
		||||
                return command_result{permission::i_client_private_textmessage_power};
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
            {
 | 
			
		||||
                unique_lock channel_lock(target->get_channel_lock());
 | 
			
		||||
                target->openChats.push_back(_this);
 | 
			
		||||
                std::unique_lock target_channel_lock{target->get_channel_lock()};
 | 
			
		||||
                target->open_private_conversations.push_back(_this);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            {
 | 
			
		||||
                unique_lock channel_lock(this->channel_lock);
 | 
			
		||||
                this->openChats.push_back(target.client);
 | 
			
		||||
                std::unique_lock self_channel_lock{this->channel_lock};
 | 
			
		||||
                this->open_private_conversations.push_back(target.client);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if(this->handleTextMessage(ChatMessageMode::TEXTMODE_PRIVATE, cmd["msg"], target.client)) return command_result{error::ok};
 | 
			
		||||
        if(this->handleTextMessage(ChatMessageMode::TEXTMODE_PRIVATE, cmd["msg"], target.client)) {
 | 
			
		||||
            return command_result{error::ok};
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        target->notifyTextMessage(ChatMessageMode::TEXTMODE_PRIVATE, _this.lock(), target->getClientId(), 0, timestamp, cmd["msg"].string());
 | 
			
		||||
        this->notifyTextMessage(ChatMessageMode::TEXTMODE_PRIVATE, _this.lock(), target->getClientId(), 0, timestamp, cmd["msg"].string());
 | 
			
		||||
    } else if (cmd["targetmode"] == ChatMessageMode::TEXTMODE_CHANNEL) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user