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 */);
|
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 */
|
/* 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();
|
void flush_disk_buffer();
|
||||||
|
|
||||||
[[nodiscard]] inline std::string log_prefix() const { return "[" + net::to_string(this->networking.address) + "]"; }
|
[[nodiscard]] inline std::string log_prefix() const { return "[" + net::to_string(this->networking.address) + "]"; }
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
#include <event2/event.h>
|
#include <event2/event.h>
|
||||||
#include <log/LogUtils.h>
|
#include <log/LogUtils.h>
|
||||||
#include "./LocalFileProvider.h"
|
#include "./LocalFileProvider.h"
|
||||||
#include "LocalFileProvider.h"
|
|
||||||
|
|
||||||
using namespace ts::server::file;
|
using namespace ts::server::file;
|
||||||
using namespace ts::server::file::transfer;
|
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) {
|
} else if(client->transfer->direction == Transfer::DIRECTION_DOWNLOAD) {
|
||||||
if(client->state == FileClient::STATE_DISCONNECTING) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,13 +149,14 @@ bool FileClient::enqueue_network_buffer_bytes(const void *snd_buffer, size_t siz
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileClient::flush_network_buffer() {
|
size_t FileClient::flush_network_buffer() {
|
||||||
Buffer* current_head;
|
Buffer* current_head;
|
||||||
|
size_t bytes;
|
||||||
{
|
{
|
||||||
std::lock_guard block{this->network_buffer.mutex};
|
std::lock_guard block{this->network_buffer.mutex};
|
||||||
|
|
||||||
this->network_buffer.write_disconnected = true;
|
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);
|
current_head = std::exchange(this->network_buffer.buffer_head, nullptr);
|
||||||
this->network_buffer.buffer_tail = &this->network_buffer.buffer_head;
|
this->network_buffer.buffer_tail = &this->network_buffer.buffer_head;
|
||||||
}
|
}
|
||||||
@ -165,6 +166,8 @@ void FileClient::flush_network_buffer() {
|
|||||||
free_buffer(current_head);
|
free_buffer(current_head);
|
||||||
current_head = next;
|
current_head = next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
NetworkingStartResult LocalFileTransfer::start_networking() {
|
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};
|
std::unique_lock slock{transfer->state_mutex};
|
||||||
transfer->handle->disconnect_client(transfer->shared_from_this(), slock, true);
|
transfer->handle->disconnect_client(transfer->shared_from_this(), slock, true);
|
||||||
return;
|
return;
|
||||||
@ -773,10 +782,6 @@ void LocalFileTransfer::callback_transfer_network_write(int fd, short events, vo
|
|||||||
callback(transfer->transfer);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
transfer->handle->enqueue_disk_io(transfer->shared_from_this());
|
transfer->handle->enqueue_disk_io(transfer->shared_from_this());
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <array>
|
||||||
|
|
||||||
#include <misc/spin_mutex.h>
|
#include <misc/spin_mutex.h>
|
||||||
#include <numeric>
|
#include <numeric>
|
||||||
@ -11,6 +12,7 @@
|
|||||||
namespace ts::server::file::networking {
|
namespace ts::server::file::networking {
|
||||||
struct NetworkThrottle {
|
struct NetworkThrottle {
|
||||||
constexpr static auto kThrottleTimespanMs{250};
|
constexpr static auto kThrottleTimespanMs{250};
|
||||||
|
|
||||||
typedef uint8_t span_t;
|
typedef uint8_t span_t;
|
||||||
|
|
||||||
static NetworkThrottle kNoThrottle;
|
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"};
|
ts::command_builder notify{"notifystatusfiletransfer"};
|
||||||
|
|
||||||
notify.put_unchecked(0, "clientftfid", transfer->client_transfer_id);
|
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;
|
using ErrorType = ts::server::file::transfer::TransferError::Type;
|
||||||
switch (error.error_type) {
|
switch (error.error_type) {
|
||||||
case ErrorType::TRANSFER_TIMEOUT:
|
case ErrorType::TRANSFER_TIMEOUT:
|
||||||
notify.put_unchecked(0, "status", (int) error::file_transfer_connection_timeout);
|
status.reset(ts::command_result{error::file_transfer_connection_timeout});
|
||||||
notify.put_unchecked(0, "msg", findError(error::file_transfer_connection_timeout).message);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ErrorType::DISK_IO_ERROR:
|
case ErrorType::DISK_IO_ERROR:
|
||||||
case ErrorType::DISK_TIMEOUT:
|
case ErrorType::DISK_TIMEOUT:
|
||||||
case ErrorType::DISK_INITIALIZE_ERROR:
|
case ErrorType::DISK_INITIALIZE_ERROR:
|
||||||
notify.put_unchecked(0, "status", (int) error::file_io_error);
|
status.reset(ts::command_result{error::file_io_error});
|
||||||
notify.put_unchecked(0, "msg", findError(error::file_io_error).message);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ErrorType::UNKNOWN:
|
case ErrorType::UNKNOWN:
|
||||||
case ErrorType::NETWORK_IO_ERROR:
|
case ErrorType::NETWORK_IO_ERROR:
|
||||||
notify.put_unchecked(0, "status", (int) error::file_connection_lost);
|
status.reset(ts::command_result{error::file_connection_lost});
|
||||||
notify.put_unchecked(0, "msg", findError(error::file_connection_lost).message);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ErrorType::UNEXPECTED_CLIENT_DISCONNECT:
|
case ErrorType::UNEXPECTED_CLIENT_DISCONNECT:
|
||||||
case ErrorType::UNEXPECTED_DISK_EOF:
|
case ErrorType::UNEXPECTED_DISK_EOF:
|
||||||
notify.put_unchecked(0, "status", (int) error::file_transfer_interrupted);
|
status.reset(ts::command_result{error::file_transfer_interrupted});
|
||||||
notify.put_unchecked(0, "msg", findError(error::file_transfer_interrupted).message);
|
|
||||||
|
|
||||||
case ErrorType::USER_REQUEST:
|
case ErrorType::USER_REQUEST:
|
||||||
notify.put_unchecked(0, "status", (int) error::file_transfer_canceled);
|
status.reset(ts::command_result{error::file_transfer_canceled});
|
||||||
notify.put_unchecked(0, "msg", findError(error::file_transfer_canceled).message);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
notify.put_unchecked(0, "extra_msg", error.error_message);
|
client->writeCommandResult(notify, status, "status");
|
||||||
|
|
||||||
client->sendCommand(notify);
|
client->sendCommand(notify);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -197,7 +191,7 @@ void FileServerHandler::callback_transfer_finished(const std::shared_ptr<transfe
|
|||||||
ts::command_builder notify{"notifystatusfiletransfer"};
|
ts::command_builder notify{"notifystatusfiletransfer"};
|
||||||
|
|
||||||
notify.put_unchecked(0, "clientftfid", transfer->client_transfer_id);
|
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, "status", (int) error::file_transfer_complete);
|
||||||
notify.put_unchecked(0, "msg", findError(error::file_transfer_complete).message);
|
notify.put_unchecked(0, "msg", findError(error::file_transfer_complete).message);
|
||||||
|
|
||||||
|
@ -15,13 +15,6 @@ namespace ts::server::file {
|
|||||||
private:
|
private:
|
||||||
InstanceHandler* instance_;
|
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_registered(const std::shared_ptr<transfer::Transfer>&);
|
||||||
void callback_transfer_started(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>&);
|
void callback_transfer_finished(const std::shared_ptr<transfer::Transfer>&);
|
||||||
|
@ -138,7 +138,7 @@ bool VirtualServer::initialize(bool test_properties) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
channelTree->deleteSemiPermanentChannels();
|
channelTree->deleteSemiPermanentChannels();
|
||||||
if(channelTree->channel_count() == 0){
|
if(channelTree->channel_count() == 0) {
|
||||||
logMessage(this->serverId, "Creating new channel tree (Copy from server 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 `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",
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void write_command_result_error(ts::command_builder_bulk bulk, const command_result& result) {
|
inline void write_command_result_error(ts::command_builder_bulk bulk, const command_result& result, const std::string& errorCodeKey) {
|
||||||
bulk.put_unchecked("id", (uint32_t) result.error_code());
|
bulk.put_unchecked(errorCodeKey, (uint32_t) result.error_code());
|
||||||
bulk.put_unchecked("msg", findError(result.error_code()).message);
|
bulk.put_unchecked("msg", findError(result.error_code()).message);
|
||||||
if(result.is_permission_error())
|
if(result.is_permission_error())
|
||||||
bulk.put_unchecked("failed_permid", (uint32_t) result.permission_id());
|
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();
|
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);
|
bulk.put_unchecked("msg", findError(details->error_id).message);
|
||||||
|
|
||||||
for(const auto& extra : details->extra_properties)
|
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) {
|
bool ConnectedClient::notifyError(const command_result& result, const std::string& retCode) {
|
||||||
ts::command_builder command{"error"};
|
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()) {
|
switch(result.type()) {
|
||||||
case command_result_type::error:
|
case command_result_type::error:
|
||||||
write_command_result_error(command.bulk(0), result);
|
write_command_result_error(cmd_builder.bulk(0), result, errorCodeKey);
|
||||||
break;
|
break;
|
||||||
case command_result_type::detailed:
|
case command_result_type::detailed:
|
||||||
write_command_result_detailed(command.bulk(0), result);
|
write_command_result_detailed(cmd_builder.bulk(0), result, errorCodeKey);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case command_result_type::bulked: {
|
case command_result_type::bulked: {
|
||||||
auto bulks = result.bulks();
|
auto bulks = result.bulks();
|
||||||
command.reserve_bulks(bulks->size());
|
cmd_builder.reserve_bulks(bulks->size());
|
||||||
for(size_t index{0}; index < bulks->size(); index++) {
|
for(size_t index{0}; index < bulks->size(); index++) {
|
||||||
auto& entry = bulks->at(index);
|
auto& entry = bulks->at(index);
|
||||||
switch (entry.type()) {
|
switch (entry.type()) {
|
||||||
case command_result_type::error:
|
case command_result_type::error:
|
||||||
write_command_result_error(command.bulk(index), entry);
|
write_command_result_error(cmd_builder.bulk(index), entry, errorCodeKey);
|
||||||
break;
|
break;
|
||||||
case command_result_type::detailed:
|
case command_result_type::detailed:
|
||||||
write_command_result_detailed(command.bulk(index), entry);
|
write_command_result_detailed(cmd_builder.bulk(index), entry, errorCodeKey);
|
||||||
break;
|
break;
|
||||||
case command_result_type::bulked:
|
case command_result_type::bulked:
|
||||||
assert(false);
|
assert(false);
|
||||||
@ -621,8 +630,8 @@ bool ConnectedClient::notifyError(const command_result& result, const std::strin
|
|||||||
}
|
}
|
||||||
if(bulks->empty()) {
|
if(bulks->empty()) {
|
||||||
logWarning(this->getServerId(), "{} Trying to send empty error bulk.", CLIENT_STR_LOG_PREFIX_(this));
|
logWarning(this->getServerId(), "{} Trying to send empty error bulk.", CLIENT_STR_LOG_PREFIX_(this));
|
||||||
command.put_unchecked(0, "id", (uint32_t) error::ok);
|
cmd_builder.put_unchecked(0, errorCodeKey, (uint32_t) error::ok);
|
||||||
command.put_unchecked(0, "msg", findError(error::ok).message);
|
cmd_builder.put_unchecked(0, "msg", findError(error::ok).message);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -630,12 +639,6 @@ bool ConnectedClient::notifyError(const command_result& result, const std::strin
|
|||||||
assert(false);
|
assert(false);
|
||||||
break;
|
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) {
|
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 **/
|
/** Notifies general stuff **/
|
||||||
virtual bool notifyError(const command_result&, const std::string& retCode = "");
|
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) */
|
/** Notifies (after request) */
|
||||||
bool sendNeededPermissions(bool /* force an update */); /* invoke this because it dosn't spam the client */
|
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 handleCommandConversationMessageDelete(Command&);
|
||||||
|
|
||||||
command_result handleCommandLogView(Command&);
|
command_result handleCommandLogView(Command&);
|
||||||
//CMD_TODO handleCommandLogAdd
|
|
||||||
command_result handleCommandLogQuery(Command&);
|
command_result handleCommandLogQuery(Command&);
|
||||||
command_result handleCommandLogAdd(Command&);
|
command_result handleCommandLogAdd(Command&);
|
||||||
|
|
||||||
|
@ -4,8 +4,6 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <spdlog/sinks/rotating_file_sink.h>
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -15,7 +13,6 @@
|
|||||||
#include "../InternalClient.h"
|
#include "../InternalClient.h"
|
||||||
#include "../../server/VoiceServer.h"
|
#include "../../server/VoiceServer.h"
|
||||||
#include "../voice/VoiceClient.h"
|
#include "../voice/VoiceClient.h"
|
||||||
#include "PermissionManager.h"
|
|
||||||
#include "../../InstanceHandler.h"
|
#include "../../InstanceHandler.h"
|
||||||
#include "../../server/QueryServer.h"
|
#include "../../server/QueryServer.h"
|
||||||
#include "../music/MusicClient.h"
|
#include "../music/MusicClient.h"
|
||||||
@ -30,16 +27,10 @@
|
|||||||
|
|
||||||
#include "helpers.h"
|
#include "helpers.h"
|
||||||
|
|
||||||
#include <Properties.h>
|
|
||||||
#include <log/LogUtils.h>
|
#include <log/LogUtils.h>
|
||||||
#include <misc/sassert.h>
|
#include <misc/sassert.h>
|
||||||
#include <misc/base64.h>
|
|
||||||
#include <misc/hex.h>
|
|
||||||
#include <misc/digest.h>
|
|
||||||
#include <misc/rnd.h>
|
#include <misc/rnd.h>
|
||||||
#include <misc/timer.h>
|
|
||||||
#include <misc/strobf.h>
|
#include <misc/strobf.h>
|
||||||
#include <misc/scope_guard.h>
|
|
||||||
#include <bbcode/bbcodes.h>
|
#include <bbcode/bbcodes.h>
|
||||||
|
|
||||||
namespace fs = std::experimental::filesystem;
|
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 == "ftgetfilelist") return this->handleCommandFTGetFileList(cmd);
|
||||||
else if (command == "ftcreatedir") return this->handleCommandFTCreateDir(cmd);
|
else if (command == "ftcreatedir") return this->handleCommandFTCreateDir(cmd);
|
||||||
else if (command == "ftdeletefile") return this->handleCommandFTDeleteFile(cmd);
|
else if (command == "ftdeletefile") return this->handleCommandFTDeleteFile(cmd);
|
||||||
else if (command == "ftinitupload") return this->handleCommandFTInitUpload(cmd);
|
else if (command == "ftinitupload") {
|
||||||
else if (command == "ftinitdownload") return this->handleCommandFTInitDownload(cmd);
|
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 == "ftgetfileinfo") return this->handleCommandFTGetFileInfo(cmd);
|
||||||
else if (command == "ftrenamefile") return this->handleCommandFTRenameFile(cmd);
|
else if (command == "ftrenamefile") return this->handleCommandFTRenameFile(cmd);
|
||||||
else if (command == "ftlist") return this->handleCommandFTList(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);
|
auto channel = this->channel_view()->find_channel(conversation_id);
|
||||||
if(!channel)
|
if(!channel)
|
||||||
return command_result{error::conversation_invalid_id};
|
return command_result{error::conversation_invalid_id};
|
||||||
|
|
||||||
if(channel->channel()->properties()[property::CHANNEL_FLAG_CONVERSATION_PRIVATE].as<bool>())
|
if(channel->channel()->properties()[property::CHANNEL_FLAG_CONVERSATION_PRIVATE].as<bool>())
|
||||||
return command_result{error::conversation_is_private};
|
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);
|
auto conversation = conversation_manager->get(conversation_id);
|
||||||
if(conversation)
|
if(conversation) {
|
||||||
result_bulk["timestamp"] = duration_cast<milliseconds>(conversation->last_message().time_since_epoch()).count();
|
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["timestamp"] = 0;
|
||||||
result_bulk["flag_volatile"] = conversation->volatile_only();
|
result_bulk["flag_volatile"] = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(result_index == 0)
|
if(result_index == 0)
|
||||||
return command_result{error::database_empty_result};
|
return command_result{error::database_empty_result};
|
||||||
@ -2737,7 +2757,7 @@ command_result ConnectedClient::handleCommandConversationMessageDelete(ts::Comma
|
|||||||
if (!channel->passwordMatch(bulk["cpw"], true))
|
if (!channel->passwordMatch(bulk["cpw"], true))
|
||||||
ACTION_REQUIRES_PERMISSION(permission::b_channel_join_ignore_password, 1, channel->channelId());
|
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};
|
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)
|
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;
|
auto limit = bulk.has("limit") ? bulk["limit"].as<uint64_t>() : 1;
|
||||||
if(limit > 100)
|
if(limit > 100)
|
||||||
limit = 100;
|
limit = 100;
|
||||||
|
|
||||||
auto delete_count = current_conversation->delete_messages(timestamp_end, limit, timestamp_begin, bulk["cldbid"]);
|
auto delete_count = current_conversation->delete_messages(timestamp_end, limit, timestamp_begin, bulk["cldbid"]);
|
||||||
if(delete_count > 0) {
|
if(delete_count > 0) {
|
||||||
for(const auto& client : ref_server->getClients()) {
|
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
|
permission::i_client_music_create_modify_max_volume
|
||||||
}, this->getChannelId());
|
}, 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];
|
auto max_bots = permissions[permission::i_client_music_limit];
|
||||||
if(max_bots.has_value) {
|
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 */
|
/* test if we have a block or create a new one at the begin of the file */
|
||||||
if(!this->last_message_block) {
|
if(!this->last_message_block) {
|
||||||
//Note: If we reuse blocks we've to reorder them within message_blocks (newest blocks are at the end)
|
//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)
|
while(this->_last_messages.size() > this->_last_messages_limit)
|
||||||
this->_last_messages.pop_front(); /* TODO: Use a iterator for delete to improve performance */
|
this->_last_messages.pop_front(); /* TODO: Use a iterator for delete to improve performance */
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!this->volatile_only()) {
|
if(!this->volatile_only()) {
|
||||||
{
|
{
|
||||||
lock_guard lock(this->_write_queue_lock);
|
lock_guard lock(this->_write_queue_lock);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user