Some minor bugfixes
This commit is contained in:
		
							parent
							
								
									e01811e20e
								
							
						
					
					
						commit
						9c7223d016
					
				| @ -258,7 +258,7 @@ namespace ts::server::file { | ||||
|             bool enqueue_disk_buffer_bytes(const void* /* buffer */, size_t /* length */); | ||||
| 
 | ||||
|             /* these function clear the buffers and set the write disconnected flags to true so no new buffers will be enqueued */ | ||||
|             void flush_network_buffer(); | ||||
|             size_t flush_network_buffer(); | ||||
|             void flush_disk_buffer(); | ||||
| 
 | ||||
|             [[nodiscard]] inline std::string log_prefix() const { return "[" + net::to_string(this->networking.address) + "]"; } | ||||
|  | ||||
| @ -6,7 +6,6 @@ | ||||
| #include <event2/event.h> | ||||
| #include <log/LogUtils.h> | ||||
| #include "./LocalFileProvider.h" | ||||
| #include "LocalFileProvider.h" | ||||
| 
 | ||||
| using namespace ts::server::file; | ||||
| using namespace ts::server::file::transfer; | ||||
|  | ||||
| @ -478,7 +478,7 @@ void LocalFileTransfer::execute_disk_io(const std::shared_ptr<FileClient> &clien | ||||
|         } | ||||
|     } else if(client->transfer->direction == Transfer::DIRECTION_DOWNLOAD) { | ||||
|         if(client->state == FileClient::STATE_DISCONNECTING) { | ||||
|             client->flush_disk_buffer(); /* just in case */ | ||||
|             client->flush_disk_buffer(); /* just in case, file download usually don't write to the disk */ | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -149,13 +149,14 @@ bool FileClient::enqueue_network_buffer_bytes(const void *snd_buffer, size_t siz | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| void FileClient::flush_network_buffer() { | ||||
| size_t FileClient::flush_network_buffer() { | ||||
|     Buffer* current_head; | ||||
|     size_t bytes; | ||||
|     { | ||||
|         std::lock_guard block{this->network_buffer.mutex}; | ||||
| 
 | ||||
|         this->network_buffer.write_disconnected = true; | ||||
|         this->network_buffer.bytes = 0; | ||||
|         bytes = std::exchange(this->network_buffer.bytes, 0); | ||||
|         current_head = std::exchange(this->network_buffer.buffer_head, nullptr); | ||||
|         this->network_buffer.buffer_tail = &this->network_buffer.buffer_head; | ||||
|     } | ||||
| @ -165,6 +166,8 @@ void FileClient::flush_network_buffer() { | ||||
|         free_buffer(current_head); | ||||
|         current_head = next; | ||||
|     } | ||||
| 
 | ||||
|     return bytes; | ||||
| } | ||||
| 
 | ||||
| NetworkingStartResult LocalFileTransfer::start_networking() { | ||||
| @ -726,7 +729,13 @@ void LocalFileTransfer::callback_transfer_network_write(int fd, short events, vo | ||||
|                     } | ||||
|                 } | ||||
| 
 | ||||
|                 transfer->flush_network_buffer(); /* invalidate all network write operations */ | ||||
|                 /* invalidate all network write operations, but still flush the disk IO buffer */ | ||||
|                 if(size_t bytes_dropped{transfer->flush_network_buffer()}; bytes_dropped > 0) { | ||||
|                     if(transfer->state != FileClient::STATE_TRANSFERRING) { | ||||
|                         logWarning(LOG_FT, "{} Dropped {} bytes due to a write error ({}/{})", | ||||
|                                 transfer->log_prefix(), bytes_dropped, errno, strerror(errno)); | ||||
|                     } | ||||
|                 } | ||||
|                 std::unique_lock slock{transfer->state_mutex}; | ||||
|                 transfer->handle->disconnect_client(transfer->shared_from_this(), slock, true); | ||||
|                 return; | ||||
| @ -773,10 +782,6 @@ void LocalFileTransfer::callback_transfer_network_write(int fd, short events, vo | ||||
|                         callback(transfer->transfer); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             std::unique_lock slock{transfer->state_mutex}; | ||||
|             /* no need to flush here, since we read only from the disk and all bytes which sould be send have been written already */ | ||||
|             transfer->handle->disconnect_client(transfer->shared_from_this(), slock, false); | ||||
|             return; | ||||
|         } | ||||
|         transfer->handle->enqueue_disk_io(transfer->shared_from_this()); | ||||
|  | ||||
| @ -4,6 +4,7 @@ | ||||
| #include <chrono> | ||||
| #include <mutex> | ||||
| #include <cassert> | ||||
| #include <array> | ||||
| 
 | ||||
| #include <misc/spin_mutex.h> | ||||
| #include <numeric> | ||||
| @ -11,6 +12,7 @@ | ||||
| namespace ts::server::file::networking { | ||||
|     struct NetworkThrottle { | ||||
|         constexpr static auto kThrottleTimespanMs{250}; | ||||
| 
 | ||||
|         typedef uint8_t span_t; | ||||
| 
 | ||||
|         static NetworkThrottle kNoThrottle; | ||||
|  | ||||
| @ -93,44 +93,38 @@ void FileServerHandler::callback_transfer_aborted(const std::shared_ptr<transfer | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         //notifystatusfiletransfer clientftfid=4096 status=2568 failed_permid=234 msg=insufficient\sclient\spermissions\s(failed\son\si_ft_needed_file_upload_power) size=0
 | ||||
|         ts::command_builder notify{"notifystatusfiletransfer"}; | ||||
| 
 | ||||
|         notify.put_unchecked(0, "clientftfid", transfer->client_transfer_id); | ||||
|         notify.put(0, "size", 0); /* not sure where TeamSpeak counts from */ | ||||
|         notify.put(0, "size", 0); | ||||
| 
 | ||||
|         ts::command_result status{}; | ||||
|         using ErrorType = ts::server::file::transfer::TransferError::Type; | ||||
|         switch (error.error_type) { | ||||
|             case ErrorType::TRANSFER_TIMEOUT: | ||||
|                 notify.put_unchecked(0, "status", (int) error::file_transfer_connection_timeout); | ||||
|                 notify.put_unchecked(0, "msg", findError(error::file_transfer_connection_timeout).message); | ||||
|                 status.reset(ts::command_result{error::file_transfer_connection_timeout}); | ||||
|                 break; | ||||
| 
 | ||||
|             case ErrorType::DISK_IO_ERROR: | ||||
|             case ErrorType::DISK_TIMEOUT: | ||||
|             case ErrorType::DISK_INITIALIZE_ERROR: | ||||
|                 notify.put_unchecked(0, "status", (int) error::file_io_error); | ||||
|                 notify.put_unchecked(0, "msg", findError(error::file_io_error).message); | ||||
|                 status.reset(ts::command_result{error::file_io_error}); | ||||
|                 break; | ||||
| 
 | ||||
|             case ErrorType::UNKNOWN: | ||||
|             case ErrorType::NETWORK_IO_ERROR: | ||||
|                 notify.put_unchecked(0, "status", (int) error::file_connection_lost); | ||||
|                 notify.put_unchecked(0, "msg", findError(error::file_connection_lost).message); | ||||
|                 status.reset(ts::command_result{error::file_connection_lost}); | ||||
|                 break; | ||||
| 
 | ||||
|             case ErrorType::UNEXPECTED_CLIENT_DISCONNECT: | ||||
|             case ErrorType::UNEXPECTED_DISK_EOF: | ||||
|                 notify.put_unchecked(0, "status", (int) error::file_transfer_interrupted); | ||||
|                 notify.put_unchecked(0, "msg", findError(error::file_transfer_interrupted).message); | ||||
|                 status.reset(ts::command_result{error::file_transfer_interrupted}); | ||||
| 
 | ||||
|             case ErrorType::USER_REQUEST: | ||||
|                 notify.put_unchecked(0, "status", (int) error::file_transfer_canceled); | ||||
|                 notify.put_unchecked(0, "msg", findError(error::file_transfer_canceled).message); | ||||
|                 status.reset(ts::command_result{error::file_transfer_canceled}); | ||||
|                 break; | ||||
|         } | ||||
|         notify.put_unchecked(0, "extra_msg", error.error_message); | ||||
| 
 | ||||
|         client->writeCommandResult(notify, status, "status"); | ||||
|         client->sendCommand(notify); | ||||
|     } | ||||
| } | ||||
| @ -197,7 +191,7 @@ void FileServerHandler::callback_transfer_finished(const std::shared_ptr<transfe | ||||
|     ts::command_builder notify{"notifystatusfiletransfer"}; | ||||
| 
 | ||||
|     notify.put_unchecked(0, "clientftfid", transfer->client_transfer_id); | ||||
|     notify.put(0, "size", 0); /* not sure where TeamSpeak counts from */ | ||||
|     notify.put(0, "size", transfer->expected_file_size); /* not sure where TeamSpeak counts from */ | ||||
|     notify.put_unchecked(0, "status", (int) error::file_transfer_complete); | ||||
|     notify.put_unchecked(0, "msg", findError(error::file_transfer_complete).message); | ||||
| 
 | ||||
|  | ||||
| @ -15,13 +15,6 @@ namespace ts::server::file { | ||||
|         private: | ||||
|             InstanceHandler* instance_; | ||||
| 
 | ||||
| #if 0 | ||||
|             std::function<void(const std::shared_ptr<Transfer>&)> callback_transfer_registered{}; /* transfer has been registered */ | ||||
|             std::function<void(const std::shared_ptr<Transfer>&)> callback_transfer_started{}; /* transfer has been started */ | ||||
|             std::function<void(const std::shared_ptr<Transfer>&)> callback_transfer_finished{}; /* transfer has been finished */ | ||||
|             std::function<void(const std::shared_ptr<Transfer>&, const TransferError&)> callback_transfer_aborted{}; /* an error happened while transferring the data  */ | ||||
|             std::function<void(const std::shared_ptr<Transfer>&, const TransferStatistics&)> callback_transfer_statistics{}; | ||||
| #endif | ||||
|             void callback_transfer_registered(const std::shared_ptr<transfer::Transfer>&); | ||||
|             void callback_transfer_started(const std::shared_ptr<transfer::Transfer>&); | ||||
|             void callback_transfer_finished(const std::shared_ptr<transfer::Transfer>&); | ||||
|  | ||||
| @ -138,7 +138,7 @@ bool VirtualServer::initialize(bool test_properties) { | ||||
|     } | ||||
| 
 | ||||
|     channelTree->deleteSemiPermanentChannels(); | ||||
|     if(channelTree->channel_count() == 0){ | ||||
|     if(channelTree->channel_count() == 0) { | ||||
|         logMessage(this->serverId, "Creating new channel tree (Copy from server 0)"); | ||||
|         LOG_SQL_CMD(sql::command(this->getSql(), "INSERT INTO `channels` (`serverId`, `channelId`, `type`, `parentId`) SELECT :serverId AS `serverId`, `channelId`, `type`, `parentId` FROM `channels` WHERE `serverId` = 0", variable{":serverId", this->serverId}).execute()); | ||||
|         LOG_SQL_CMD(sql::command(this->getSql(), "INSERT INTO `properties` (`serverId`, `type`, `id`, `key`, `value`) SELECT :serverId AS `serverId`, `type`, `id`, `key`, `value` FROM `properties` WHERE `serverId` = 0 AND `type` = :type", | ||||
|  | ||||
| @ -575,16 +575,16 @@ bool ConnectedClient::notifyClientNeededPermissions() { | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| inline void write_command_result_error(ts::command_builder_bulk bulk, const command_result& result) { | ||||
|     bulk.put_unchecked("id", (uint32_t) result.error_code()); | ||||
| inline void write_command_result_error(ts::command_builder_bulk bulk, const command_result& result, const std::string& errorCodeKey) { | ||||
|     bulk.put_unchecked(errorCodeKey, (uint32_t) result.error_code()); | ||||
|     bulk.put_unchecked("msg", findError(result.error_code()).message); | ||||
|     if(result.is_permission_error()) | ||||
|         bulk.put_unchecked("failed_permid", (uint32_t) result.permission_id()); | ||||
| } | ||||
| 
 | ||||
| inline void write_command_result_detailed(ts::command_builder_bulk bulk, const command_result& result) { | ||||
| inline void write_command_result_detailed(ts::command_builder_bulk bulk, const command_result& result, const std::string& errorCodeKey) { | ||||
|     auto details = result.details(); | ||||
|     bulk.put_unchecked("id", (uint32_t) details->error_id); | ||||
|     bulk.put_unchecked(errorCodeKey, (uint32_t) details->error_id); | ||||
|     bulk.put_unchecked("msg", findError(details->error_id).message); | ||||
| 
 | ||||
|     for(const auto& extra : details->extra_properties) | ||||
| @ -594,25 +594,34 @@ inline void write_command_result_detailed(ts::command_builder_bulk bulk, const c | ||||
| bool ConnectedClient::notifyError(const command_result& result, const std::string& retCode) { | ||||
|     ts::command_builder command{"error"}; | ||||
| 
 | ||||
|     this->writeCommandResult(command, result); | ||||
|     if(!retCode.empty()) | ||||
|         command.put_unchecked(0, "return_code", retCode); | ||||
| 
 | ||||
|     this->sendCommand(command); | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| void ConnectedClient::writeCommandResult(ts::command_builder &cmd_builder, const command_result &result, const std::string& errorCodeKey) { | ||||
|     switch(result.type()) { | ||||
|         case command_result_type::error: | ||||
|             write_command_result_error(command.bulk(0), result); | ||||
|             write_command_result_error(cmd_builder.bulk(0), result, errorCodeKey); | ||||
|             break; | ||||
|         case command_result_type::detailed: | ||||
|             write_command_result_detailed(command.bulk(0), result); | ||||
|             write_command_result_detailed(cmd_builder.bulk(0), result, errorCodeKey); | ||||
|             break; | ||||
| 
 | ||||
|         case command_result_type::bulked: { | ||||
|             auto bulks = result.bulks(); | ||||
|             command.reserve_bulks(bulks->size()); | ||||
|             cmd_builder.reserve_bulks(bulks->size()); | ||||
|             for(size_t index{0}; index < bulks->size(); index++) { | ||||
|                 auto& entry = bulks->at(index); | ||||
|                 switch (entry.type()) { | ||||
|                     case command_result_type::error: | ||||
|                         write_command_result_error(command.bulk(index), entry); | ||||
|                         write_command_result_error(cmd_builder.bulk(index), entry, errorCodeKey); | ||||
|                         break; | ||||
|                     case command_result_type::detailed: | ||||
|                         write_command_result_detailed(command.bulk(index), entry); | ||||
|                         write_command_result_detailed(cmd_builder.bulk(index), entry, errorCodeKey); | ||||
|                         break; | ||||
|                     case command_result_type::bulked: | ||||
|                         assert(false); | ||||
| @ -621,8 +630,8 @@ bool ConnectedClient::notifyError(const command_result& result, const std::strin | ||||
|             } | ||||
|             if(bulks->empty()) { | ||||
|                 logWarning(this->getServerId(), "{} Trying to send empty error bulk.", CLIENT_STR_LOG_PREFIX_(this)); | ||||
|                 command.put_unchecked(0, "id", (uint32_t) error::ok); | ||||
|                 command.put_unchecked(0, "msg", findError(error::ok).message); | ||||
|                 cmd_builder.put_unchecked(0, errorCodeKey, (uint32_t) error::ok); | ||||
|                 cmd_builder.put_unchecked(0, "msg", findError(error::ok).message); | ||||
|             } | ||||
|             break; | ||||
|         } | ||||
| @ -630,12 +639,6 @@ bool ConnectedClient::notifyError(const command_result& result, const std::strin | ||||
|             assert(false); | ||||
|             break; | ||||
|     } | ||||
| 
 | ||||
|     if(!retCode.empty()) | ||||
|         command.put_unchecked(0, "return_code", retCode); | ||||
| 
 | ||||
|     this->sendCommand(command); | ||||
|     return true; | ||||
| } | ||||
| 
 | ||||
| inline std::shared_ptr<ViewEntry> pop_view_entry(std::deque<std::shared_ptr<ViewEntry>>& pool, ChannelId id) { | ||||
|  | ||||
| @ -122,6 +122,7 @@ namespace ts { | ||||
| 
 | ||||
|                 /** Notifies general stuff **/ | ||||
|                 virtual bool notifyError(const command_result&, const std::string& retCode = ""); | ||||
|                 virtual void writeCommandResult(ts::command_builder&, const command_result&, const std::string& errorCodeKey = "id"); | ||||
| 
 | ||||
|                 /** Notifies (after request) */ | ||||
|                 bool sendNeededPermissions(bool /* force an update */); /* invoke this because it dosn't spam the client */ | ||||
| @ -597,7 +598,6 @@ namespace ts { | ||||
|                 command_result handleCommandConversationMessageDelete(Command&); | ||||
| 
 | ||||
|                 command_result handleCommandLogView(Command&); | ||||
|                 //CMD_TODO handleCommandLogAdd
 | ||||
|                 command_result handleCommandLogQuery(Command&); | ||||
|                 command_result handleCommandLogAdd(Command&); | ||||
| 
 | ||||
|  | ||||
| @ -4,8 +4,6 @@ | ||||
| 
 | ||||
| #include <memory> | ||||
| 
 | ||||
| #include <spdlog/sinks/rotating_file_sink.h> | ||||
| 
 | ||||
| #include <iostream> | ||||
| #include <bitset> | ||||
| #include <algorithm> | ||||
| @ -15,7 +13,6 @@ | ||||
| #include "../InternalClient.h" | ||||
| #include "../../server/VoiceServer.h" | ||||
| #include "../voice/VoiceClient.h" | ||||
| #include "PermissionManager.h" | ||||
| #include "../../InstanceHandler.h" | ||||
| #include "../../server/QueryServer.h" | ||||
| #include "../music/MusicClient.h" | ||||
| @ -30,16 +27,10 @@ | ||||
| 
 | ||||
| #include "helpers.h" | ||||
| 
 | ||||
| #include <Properties.h> | ||||
| #include <log/LogUtils.h> | ||||
| #include <misc/sassert.h> | ||||
| #include <misc/base64.h> | ||||
| #include <misc/hex.h> | ||||
| #include <misc/digest.h> | ||||
| #include <misc/rnd.h> | ||||
| #include <misc/timer.h> | ||||
| #include <misc/strobf.h> | ||||
| #include <misc/scope_guard.h> | ||||
| #include <bbcode/bbcodes.h> | ||||
| 
 | ||||
| namespace fs = std::experimental::filesystem; | ||||
| @ -132,8 +123,34 @@ command_result ConnectedClient::handleCommand(Command &cmd) { | ||||
|     else if (command == "ftgetfilelist") return this->handleCommandFTGetFileList(cmd); | ||||
|     else if (command == "ftcreatedir") return this->handleCommandFTCreateDir(cmd); | ||||
|     else if (command == "ftdeletefile") return this->handleCommandFTDeleteFile(cmd); | ||||
|     else if (command == "ftinitupload") return this->handleCommandFTInitUpload(cmd); | ||||
|     else if (command == "ftinitdownload") return this->handleCommandFTInitDownload(cmd); | ||||
|     else if (command == "ftinitupload") { | ||||
|         auto result = this->handleCommandFTInitUpload(cmd); | ||||
|         if(result.has_error() && this->getType() == ClientType::CLIENT_TEAMSPEAK) { | ||||
|             ts::command_builder notify{"notifystatusfiletransfer"}; | ||||
|             notify.put_unchecked(0, "clientftfid", cmd["clientftfid"].string()); | ||||
|             notify.put(0, "size", 0); | ||||
|             this->writeCommandResult(notify, result, "status"); | ||||
|             this->sendCommand(notify); | ||||
|             result.release_data(); | ||||
| 
 | ||||
|             return command_result{error::ok}; | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|     else if (command == "ftinitdownload") { | ||||
|         auto result = this->handleCommandFTInitDownload(cmd); | ||||
|         if(result.has_error() && this->getType() == ClientType::CLIENT_TEAMSPEAK) { | ||||
|             ts::command_builder notify{"notifystatusfiletransfer"}; | ||||
|             notify.put_unchecked(0, "clientftfid", cmd["clientftfid"].string()); | ||||
|             notify.put(0, "size", 0); | ||||
|             this->writeCommandResult(notify, result, "status"); | ||||
|             this->sendCommand(notify); | ||||
|             result.release_data(); | ||||
| 
 | ||||
|             return command_result{error::ok}; | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|     else if (command == "ftgetfileinfo") return this->handleCommandFTGetFileInfo(cmd); | ||||
|     else if (command == "ftrenamefile") return this->handleCommandFTRenameFile(cmd); | ||||
|     else if (command == "ftlist") return this->handleCommandFTList(cmd); | ||||
| @ -2523,6 +2540,7 @@ command_result ConnectedClient::handleCommandConversationHistory(ts::Command &co | ||||
|             auto channel = this->channel_view()->find_channel(conversation_id); | ||||
|             if(!channel) | ||||
|                 return command_result{error::conversation_invalid_id}; | ||||
| 
 | ||||
|             if(channel->channel()->properties()[property::CHANNEL_FLAG_CONVERSATION_PRIVATE].as<bool>()) | ||||
|                 return command_result{error::conversation_is_private}; | ||||
|         } | ||||
| @ -2684,11 +2702,13 @@ command_result ConnectedClient::handleCommandConversationFetch(ts::Command &cmd) | ||||
|         } | ||||
| 
 | ||||
|         auto conversation = conversation_manager->get(conversation_id); | ||||
|         if(conversation) | ||||
|         if(conversation) { | ||||
|             result_bulk["timestamp"] = duration_cast<milliseconds>(conversation->last_message().time_since_epoch()).count(); | ||||
|         else | ||||
|             result_bulk["flag_volatile"] = conversation->volatile_only(); | ||||
|         } else { | ||||
|             result_bulk["timestamp"] = 0; | ||||
|         result_bulk["flag_volatile"] = conversation->volatile_only(); | ||||
|             result_bulk["flag_volatile"] = false; | ||||
|         } | ||||
|     } | ||||
|     if(result_index == 0) | ||||
|         return command_result{error::database_empty_result}; | ||||
| @ -2737,7 +2757,7 @@ command_result ConnectedClient::handleCommandConversationMessageDelete(ts::Comma | ||||
|                 if (!channel->passwordMatch(bulk["cpw"], true)) | ||||
|                     ACTION_REQUIRES_PERMISSION(permission::b_channel_join_ignore_password, 1, channel->channelId()); | ||||
| 
 | ||||
|                 if (!permission::v2::permission_granted(1, this->calculate_permission(permission::b_channel_conversation_message_delete, 1, channel->channelId()))) | ||||
|                 if (!permission::v2::permission_granted(1, this->calculate_permission(permission::b_channel_conversation_message_delete, channel->channelId()))) | ||||
|                     return command_result{permission::b_channel_conversation_message_delete}; | ||||
| 
 | ||||
|                 if(auto error_perm = this->calculate_and_get_join_state(channel); error_perm != permission::ok && error_perm != permission::b_client_is_sticky) | ||||
| @ -2753,6 +2773,7 @@ command_result ConnectedClient::handleCommandConversationMessageDelete(ts::Comma | ||||
|         auto limit = bulk.has("limit") ? bulk["limit"].as<uint64_t>() : 1; | ||||
|         if(limit > 100) | ||||
|             limit = 100; | ||||
| 
 | ||||
|         auto delete_count = current_conversation->delete_messages(timestamp_end, limit, timestamp_begin, bulk["cldbid"]); | ||||
|         if(delete_count > 0) { | ||||
|             for(const auto& client : ref_server->getClients()) { | ||||
|  | ||||
| @ -75,7 +75,7 @@ command_result ConnectedClient::handleCommandMusicBotCreate(Command& cmd) { | ||||
|                                                     permission::i_client_music_create_modify_max_volume | ||||
|                                             }, this->getChannelId()); | ||||
| 
 | ||||
|     auto permissions = map<permission::PermissionType, permission::v2::PermissionFlaggedValue>(permissions_list.begin(), permissions_list.end()); | ||||
|     auto permissions = std::map<permission::PermissionType, permission::v2::PermissionFlaggedValue>(permissions_list.begin(), permissions_list.end()); | ||||
| 
 | ||||
|     auto max_bots = permissions[permission::i_client_music_limit]; | ||||
|     if(max_bots.has_value) { | ||||
|  | ||||
| @ -806,6 +806,7 @@ void Conversation::process_write_queue(const std::chrono::system_clock::time_poi | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /* test if we have a block or create a new one at the begin of the file */ | ||||
|         if(!this->last_message_block) { | ||||
|             //Note: If we reuse blocks we've to reorder them within message_blocks (newest blocks are at the end)
 | ||||
| @ -1003,6 +1004,7 @@ void Conversation::register_message(ts::ClientDbId sender_database_id, const std | ||||
|         while(this->_last_messages.size() > this->_last_messages_limit) | ||||
|             this->_last_messages.pop_front(); /* TODO: Use a iterator for delete to improve performance */ | ||||
|     } | ||||
| 
 | ||||
|     if(!this->volatile_only()) { | ||||
|         { | ||||
|             lock_guard lock(this->_write_queue_lock); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user