Fixed some bugs

This commit is contained in:
WolverinDEV 2019-10-20 12:09:28 +02:00
parent 0c6fd1f864
commit 0bedf6c42a
21 changed files with 147 additions and 86 deletions

@ -1 +1 @@
Subproject commit ac79fda3b2d409e2fa023a5f38c380121cd7ee93
Subproject commit 965281a51a1f8fbaebbfc9cfeaa51dd25ce49385

View File

@ -17,7 +17,7 @@ using namespace std::chrono;
inline void generate(char* buffer, size_t length){
for(int index = 0; index < length; index++)
buffer[index] = rand();
buffer[index] = (uint8_t) rand();
}
namespace license {
@ -124,7 +124,7 @@ namespace license::v2 {
result->_version = 2;
result->crypt_seed = std::mt19937_64{std::random_device{}()}();
result->_hierarchy = hierarchy;
result->private_data = LicensePrivate::create(result, hierarchy.size() - 1, prv_key.data());
result->private_data = LicensePrivate::create(result, (int) hierarchy.size() - 1, prv_key.data());
return result;
}

View File

@ -89,11 +89,11 @@ namespace license {
bool private_data_editable() const;
bool write_private_data(const LicensePrivateWriteOptions& /* write options */);
inline uint8_t version() const { return this->_version; }
[[nodiscard]] inline uint16_t version() const { return this->_version; }
private:
License() = default;
uint8_t _version = 0;
uint16_t _version = 0;
std::array<uint8_t, 64> private_buffer_sign{};
uint8_t* private_buffer = nullptr;

View File

@ -425,7 +425,7 @@ void TSServer::client_move(
auto chan_source = client->channels->find_channel(s_source_channel);
if(chan_source) {
if (chan_target->subscribed || client == target) {
if (client->isClientVisible(target, false) || client == target) {
if (client == target || client->isClientVisible(target, false)) {
client->notifyClientMoved(target, s_target_channel, reason_id, reason_message, invoker, false);
} else {
client->notifyClientEnterView(target, invoker, reason_message, s_target_channel, reason_id, s_source_channel, false);

View File

@ -454,10 +454,12 @@ void TSServer::preStop(const std::string& reason) {
for(const auto& cl : this->getClients()) {
unique_lock channel_lock(cl->channel_lock);
if (cl->currentChannel) {
if(cl->getType() == CLIENT_TEAMSPEAK)
((VoiceClient*) cl.get())->disconnect(VREASON_SERVER_SHUTDOWN, reason, nullptr, false);
else
auto vc = dynamic_pointer_cast<VoiceClient>(cl);
if(vc) {
vc->disconnect(VREASON_SERVER_SHUTDOWN, reason, nullptr, false);
} else {
cl->notifyClientLeftView(cl, nullptr, ViewReasonId::VREASON_SERVER_SHUTDOWN, reason, nullptr, false);
}
}
cl->visibleClients.clear();
cl->mutedClients.clear();
@ -486,7 +488,7 @@ void TSServer::stop(const std::string& reason) {
cl->server = nullptr;
cl->loadDataForCurrentServer();
} else if(cl->getType() == CLIENT_MUSIC) {
cl->properties()[property::CLIENT_LAST_CHANNEL] = cl->currentChannel ? cl->currentChannel->channelId() : 0;
cl->disconnect("");
cl->currentChannel = nullptr;
} else if(cl->getType() == CLIENT_INTERNAL) {

View File

@ -769,8 +769,9 @@ void ConnectedClient::sendServerInit() {
command["lt"] = LicenseType::LICENSE_NPL;
else
command["lt"] = LicenseType::LICENSE_HOSTING;
} else
command["lt"] = ts::config::server::DefaultServerLicense;
} else {
command["lt"] = ts::config::server::DefaultServerLicense;
}
command["pv"] = 6; //Protocol version
command["acn"] = this->getDisplayName();
command["aclid"] = this->getClientId();

View File

@ -3451,9 +3451,12 @@ CommandResult ConnectedClient::handleCommandSendTextMessage(Command &cmd) {
CMD_REQ_CHANNEL;
channel = this->currentChannel;
channel_id = this->currentChannel->channelId();
}
if(channel == this->currentChannel) {
channel_tree_read_lock.unlock(); //Method may creates a music bot which modifies the channel tree
if(this->handleTextMessage(ChatMessageMode::TEXTMODE_CHANNEL, cmd["msg"], nullptr))
return CommandResult::Success;
channel_tree_read_lock.lock();
}
if(!this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_channel_textmessage_send, 1, channel, false))
@ -3565,17 +3568,20 @@ CommandResult ConnectedClient::handleCommandClientChatClosed(Command &cmd) {
//1 .. n
// notifyfilelist cid=1 path=\/ return_code=1:x name=testFile size=35256 datetime=1509459767 type=1|name=testDir size=0 datetime=1509459741 type=0|name=testDir_2 size=0 datetime=1509459763 type=0
//notifyfilelistfinished cid=1 path=\/
inline void appendFileList(Command &fileList, vector<std::shared_ptr<file::FileEntry>> files) {
inline void cmd_filelist_append_files(ServerId sid, Command &command, vector<std::shared_ptr<file::FileEntry>> files) {
int index = 0;
logTrace(sid, "Sending file list for path {}", command["path"].string());
for (const auto& fileEntry : files) {
debugMessage(lstream << "Having file " << fileEntry->path << "/" << fileEntry->name << " (Name: " << fileEntry->name << ")" << endl);
fileList[index]["name"] = fileEntry->name;
fileList[index]["datetime"] = std::chrono::duration_cast<std::chrono::seconds>(fileEntry->lastChanged.time_since_epoch()).count();
fileList[index]["type"] = fileEntry->type;
logTrace(sid, " - {} ({})", fileEntry->name, fileEntry->type == file::FileType::FILE ? "file" : "directory");
command[index]["name"] = fileEntry->name;
command[index]["datetime"] = std::chrono::duration_cast<std::chrono::seconds>(fileEntry->lastChanged.time_since_epoch()).count();
command[index]["type"] = fileEntry->type;
if (fileEntry->type == file::FileType::FILE)
fileList[index]["size"] = static_pointer_cast<file::File>(fileEntry)->fileSize;
command[index]["size"] = static_pointer_cast<file::File>(fileEntry)->fileSize;
else
fileList[index]["size"] = 0;
command[index]["size"] = 0;
index++;
}
}
@ -3592,10 +3598,10 @@ CommandResult ConnectedClient::handleCommandFTGetFileList(Command &cmd) {
Command fileListFinished("notifyfilelistfinished");
fileList["path"] = cmd["path"].as<std::string>();
fileList["return_code"] = code;
if(!code.empty()) fileList["return_code"] = code;
fileListFinished["path"] = cmd["path"].as<std::string>();
fileList["cid"] = cmd["cid"].as<size_t>();
fileListFinished["cid"] = cmd["cid"].as<size_t>();
fileListFinished["cid"] = cmd["cid"].as<ChannelId>();
if (cmd[0].has("cid") && cmd["cid"] != 0) { //Channel
auto channel = this->server->channelTree->findChannel(cmd["cid"].as<ChannelId>());
@ -3603,27 +3609,32 @@ CommandResult ConnectedClient::handleCommandFTGetFileList(Command &cmd) {
if (!channel->passwordMatch(cmd["cpw"]) && !this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_ft_ignore_password, 1, channel, true))
return cmd["cpw"].string().empty() ? CommandResultPermissionError{permission::b_ft_ignore_password} : CommandResult{findError("channel_invalid_password")};
CHANNEL_PERMISSION_TEST(permission::i_ft_file_browse_power, permission::i_ft_needed_file_browse_power, channel, true);
appendFileList(fileList, serverInstance->getFileServer()->listFiles(serverInstance->getFileServer()->resolveDirectory(this->server, channel, cmd["path"].as<std::string>())));
cmd_filelist_append_files(
this->getServerId(),
fileList,
serverInstance->getFileServer()->listFiles(serverInstance->getFileServer()->resolveDirectory(this->server, channel, cmd["path"].as<std::string>()))
);
} else {
if (cmd["path"].as<string>() == "/icons" || cmd["path"].as<string>() == "/icons/") {
appendFileList(fileList, serverInstance->getFileServer()->listFiles(serverInstance->getFileServer()->iconDirectory(this->server)));
cmd_filelist_append_files(this->getServerId(), fileList, serverInstance->getFileServer()->listFiles(serverInstance->getFileServer()->iconDirectory(this->server)));
PERM_CHECKR(permission::b_icon_manage, 1, true);
} else if (cmd["path"].as<string>() == "/") {
appendFileList(fileList, serverInstance->getFileServer()->listFiles(serverInstance->getFileServer()->avatarDirectory(this->server)));
cmd_filelist_append_files(this->getServerId(), fileList, serverInstance->getFileServer()->listFiles(serverInstance->getFileServer()->avatarDirectory(this->server)));
PERM_CHECKR(permission::b_icon_manage, 1, true);
} else {
cerr << "Unknown requested directory: '" << cmd["path"].as<std::string>() << "'" << endl;
logMessage(this->getServerId(), "{} Requested file list for unknown path/name: path: {} name: {}", cmd["path"].string(), cmd["name"].string());
return CommandResult::NotImplemented;
}
}
if (fileList[0].has("name")) {
if(dynamic_cast<VoiceClient*>(this)) {
dynamic_cast<VoiceClient*>(this)->sendCommand0(fileList, false, true); /* We need to process this directly else the order could get shuffeled up! */
dynamic_cast<VoiceClient*>(this)->sendCommand0(fileList, false, true); /* We need to process this directly else the order could get shuffled up! */
this->sendCommand(fileListFinished);
} else {
this->sendCommand(fileList);
this->sendCommand(fileListFinished);
if(this->getType() != CLIENT_QUERY)
this->sendCommand(fileListFinished);
}
return CommandResult::Success;
} else {
@ -3690,7 +3701,7 @@ CommandResult ConnectedClient::handleCommandFTDeleteFile(Command &cmd) {
}
files.push_back(serverInstance->getFileServer()->findFile(cmd["name"].string(), serverInstance->getFileServer()->avatarDirectory(this->server)));
} else {
cerr << "Unknown requested file to delete: " << cmd["path"].as<std::string>() << endl;
logError(this->getServerId(), "Unknown requested file to delete: {}", cmd["path"].as<std::string>());
return CommandResult::NotImplemented;
}
}

View File

@ -657,6 +657,10 @@ bool ConnectedClient::handle_text_command(
this->increaseFloodPoints(0xFF8F);
send_message(_this.lock(), "Done :)");
return true;
} else if(TARG(0, "binary")) {
send_message(_this.lock(), "Send binary message");
this->sendCommand(Command{"\02\03\04 \22"});
return true;
}
send_message(_this.lock(), "Invalid protocol command!");
send_message(_this.lock(), "- generation");

View File

@ -130,24 +130,38 @@ bool DataClient::loadDataForCurrentServer() { //TODO for query
return true;
}
permission::PermissionValue DataClient::permissionValue(permission::PermissionTestType test, permission::PermissionType type, const std::shared_ptr<BasicChannel>& target, std::shared_ptr<CalculateCache> cache, std::shared_ptr<TSServer> server, bool server_defined) {
permission::PermissionValue result = permNotGranted;
if(!server_defined && !server) server = this->server;
permission::v2::PermissionFlaggedValue DataClient::permissionValueFlagged(permission::PermissionType type, const std::shared_ptr<BasicChannel>& target, std::shared_ptr<CalculateCache> cache, std::shared_ptr<TSServer> server, bool server_defined) {
if(!server_defined && !server)
server = this->server;
if(server) {
return server->calculatePermission(test, this->getClientDatabaseId(), type, this->getType(), target, cache);
auto result = server->calculatePermissions2(this->getClientDatabaseId(), {type}, this->getType(), target ? target->channelId() : 0, false, cache);
if(result.empty() || result[0].first != type)
return permission::v2::empty_permission_flagged_value;
return result[0].second;
} else {
/* if you're not bound to a channel then you cant be bound to a server as well. */
//TODO: Implement negate flag!
bool permission_set = false;
permission::PermissionValue result = permNotGranted;
for(const auto &gr : serverInstance->getGroupManager()->getServerGroups(this->getClientDatabaseId(), this->getType())){
auto group_permissions = gr->group->permissions();
auto flagged_permissions = group_permissions->permission_value_flagged(type);
if(flagged_permissions.has_value)
if(flagged_permissions.value > result || flagged_permissions.value == -1) result = flagged_permissions.value;
if(flagged_permissions.has_value) {
if(flagged_permissions.value > result || flagged_permissions.value == -1) {
result = flagged_permissions.value;
permission_set = true;
}
}
}
return {result, permission_set};
}
}
return result;
permission::PermissionValue DataClient::permissionValue(permission::PermissionTestType test, permission::PermissionType type, const std::shared_ptr<BasicChannel>& target, std::shared_ptr<CalculateCache> cache, std::shared_ptr<TSServer> server, bool server_defined) {
auto result = this->permissionValueFlagged(type, target, cache, server, server_defined);
if(result.has_value)
return result.value;
return permNotGranted;
}
std::deque<std::pair<permission::PermissionType, permission::PermissionValue>> DataClient::permissionValues(permission::PermissionTestType test, const std::deque<permission::PermissionType>& permissions, const std::shared_ptr<BasicChannel> &channel, std::shared_ptr<CalculateCache> cache, std::shared_ptr<TSServer> server, bool server_defined) {

View File

@ -74,6 +74,14 @@ namespace ts {
std::shared_ptr<TSServer> server = nullptr,
bool server_defined = false);
virtual permission::v2::PermissionFlaggedValue permissionValueFlagged(
permission::PermissionType,
const std::shared_ptr<BasicChannel>& channel = nullptr,
std::shared_ptr<CalculateCache> cache = nullptr,
std::shared_ptr<TSServer> server = nullptr,
bool server_defined = false
);
virtual bool permissionGranted(permission::PermissionTestType test,
permission::PermissionType,
permission::PermissionValue,

View File

@ -760,17 +760,20 @@ void SpeakingClient::tick(const std::chrono::system_clock::time_point &time) {
this->updateSpeak(true, time);
if(this->state == ConnectionState::CONNECTED) {
if(this->max_idle_time != permNotGranted)
if(this->idleTimestamp.time_since_epoch().count() > 0 && this->max_idle_time > 0 && duration_cast<seconds>(time - this->idleTimestamp).count() > this->max_idle_time) {
if(this->max_idle_time.has_value) {
auto max_idle = this->max_idle_time.value;
if(max_idle > 0 && this->idleTimestamp.time_since_epoch().count() > 0 && duration_cast<seconds>(time - this->idleTimestamp).count() > max_idle) {
this->server->notify_client_kick(this->ref(), this->server->getServerRoot(), ts::config::messages::idle_time_exceeded, nullptr);
this->closeConnection(system_clock::now() + seconds(1));
}
}
}
}
void SpeakingClient::updateChannelClientProperties(bool channel_lock, bool notify) {
ConnectedClient::updateChannelClientProperties(channel_lock, notify);
this->max_idle_time = this->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_max_idletime, this->currentChannel);
this->max_idle_time = this->permissionValueFlagged(permission::i_client_max_idletime, this->currentChannel);
}
CommandResult SpeakingClient::handleCommand(Command &command) {

View File

@ -15,9 +15,7 @@ namespace ts {
bool new_protocol : 1;
char _unused : 4;
VoicePacketFlags() {
*(uint8_t*) this = 0;
}
VoicePacketFlags() : encrypted{false}, head{false}, fragmented{false}, new_protocol{false}, _unused{0} { }
};
static_assert(sizeof(VoicePacketFlags) == 1);
@ -26,17 +24,19 @@ namespace ts {
IDENTITY_PROOF,
SUCCEEDED
};
enum IdentityType {
enum IdentityType : uint8_t {
TEASPEAK_FORUM,
TEAMSPEAK,
NICKNAME
NICKNAME,
UNSET = 0xff
};
SpeakingClient(sql::SqlManager* a, const std::shared_ptr<TSServer>& b) : ConnectedClient(a, b) {
speak_begin = std::chrono::system_clock::now();
speak_last_packet = std::chrono::system_clock::now();
};
virtual ~SpeakingClient() = default;
~SpeakingClient() override = default;
//Voice
virtual void send_voice_packet(const pipes::buffer_view& /* voice packet data */, const VoicePacketFlags& /* flags */) = 0;
@ -74,18 +74,18 @@ namespace ts {
void triggerVoiceEnd();
inline void updateSpeak(bool onlyUpdate, const std::chrono::system_clock::time_point &time);
std::chrono::milliseconds speak_accuracy = std::chrono::seconds(1);
std::chrono::milliseconds speak_accuracy = std::chrono::seconds{1};
threads::Mutex speak_lock;
std::chrono::milliseconds speak_time = std::chrono::milliseconds(0);
std::chrono::milliseconds speak_time = std::chrono::milliseconds{0};
std::chrono::system_clock::time_point speak_begin;
std::chrono::system_clock::time_point speak_last_packet;
permission::PermissionValue max_idle_time = permNotGranted;
permission::v2::PermissionFlaggedValue max_idle_time{permission::v2::empty_permission_flagged_value};
struct {
HandshakeState state = HandshakeState::BEGIN;
HandshakeState state{HandshakeState::BEGIN};
IdentityType identityType;
IdentityType identityType{IdentityType::UNSET};
std::string proof_message;
//TeamSpeak
std::shared_ptr<ecc_key> identityKey;

View File

@ -107,17 +107,26 @@ bool MusicClient::closeConnection(const std::chrono::system_clock::time_point&)
return true;
}
/*
bool MusicClient::joinChannel(std::shared_ptr<BasicChannel> channel, ViewReasonId reason, bool notifySelf, const std::shared_ptr<ConnectedClient> &ptr, const std::string &reasonMsg) {
if(reason != ViewReasonId::VREASON_SERVER_LEFT && reason != ViewReasonId::VREASON_SERVER_SHUTDOWN)
this->properties()[property::CLIENT_LAST_CHANNEL] = channel ? channel->channelId() : 0;
else {
this->player_reset(false);
}
return ConnectedClient::joinChannel(channel, reason, notifySelf, ptr, reasonMsg);
bool MusicClient::disconnect(const std::string &reason) {
this->player_reset(false);
if(this->currentChannel)
this->properties()[property::CLIENT_LAST_CHANNEL] = this->currentChannel->channelId();
return true;
}
bool server::MusicClient::notifyClientMoved(
const std::shared_ptr<ConnectedClient> &client,
const std::shared_ptr<BasicChannel> &target_channel,
ViewReasonId reason,
std::string msg,
std::shared_ptr<ConnectedClient> invoker,
bool lock_channel_tree) {
if(&*client == this) {
this->properties()[property::CLIENT_LAST_CHANNEL] = target_channel ? target_channel->channelId() : 0;
}
return true;
}
FIXME: Last channel!
*/
void MusicClient::initialize_bot() {
this->_player_state = this->properties()[property::CLIENT_PLAYER_STATE];
@ -165,10 +174,6 @@ void MusicClient::apply_volume(const std::shared_ptr<::music::SampleSegment> &se
}
}
bool MusicClient::disconnect(const std::string &reason) {
return false;
}
void MusicClient::add_subscriber(const std::shared_ptr<ts::server::ConnectedClient> &client) {
lock_guard lock(this->subscriber_lock);
this->subscribers.erase(remove_if(this->subscribers.begin(), this->subscribers.end(), [&](const std::tuple<std::weak_ptr<ConnectedClient>, system_clock::time_point>& entry) {

View File

@ -86,7 +86,19 @@ namespace ts {
bool is_subscriber(const std::shared_ptr<ConnectedClient>&);
protected:
void broadcast_text_message(const std::string &message);
public:
bool notifyClientMoved(
const std::shared_ptr<ConnectedClient> &client,
const std::shared_ptr<BasicChannel> &target_channel,
ViewReasonId reason,
std::string msg,
std::shared_ptr<ConnectedClient> invoker,
bool lock_channel_tree
) override;
protected:
void broadcast_text_message(const std::string &message);
void tick(const std::chrono::system_clock::time_point &time) override;
std::chrono::system_clock::time_point next_music_tick;

View File

@ -54,14 +54,18 @@ void VoiceClient::sendCommand0(const ts::Command &command, bool low, bool direct
return;
}
auto command_str = command.build();
auto packet = make_shared<protocol::ServerPacket>(low ? protocol::PacketTypeInfo::CommandLow : protocol::PacketTypeInfo::Command, pipes::buffer_view{(void*) command_str.data(), command_str.length()});
if(low) packet->enable_flag(protocol::PacketFlag::NewProtocol);
auto packet = make_shared<protocol::ServerPacket>(
low ? protocol::PacketTypeInfo::CommandLow : protocol::PacketTypeInfo::Command,
pipes::buffer_view{(void*) cmd.data(), cmd.length()}
);
if(low) {
packet->enable_flag(protocol::PacketFlag::NewProtocol);
}
packet->setListener(std::move(listener));
this->connection->sendPacket(packet, false, direct);
#ifdef PKT_LOG_CMD
logTrace(this->getServerId(), "{}[Command][Server -> Client] Sending command {}. Command low: {}. Full command: {}", CLIENT_STR_LOG_PREFIX, command.command(), low, command_str);
logTrace(this->getServerId(), "{}[Command][Server -> Client] Sending command {}. Command low: {}. Full command: {}", CLIENT_STR_LOG_PREFIX, command.command(), low, cmd);
#endif
}
void VoiceClient::sendAcknowledge(uint16_t packetId, bool low) {

View File

@ -76,10 +76,8 @@ void VoiceClientConnection::handleDatagramReceived(const pipes::buffer_view& buf
#endif
#endif
auto packet = std::make_unique<ClientPacket>(buffer);
//packet
auto packet = ClientPacket::from_buffer(buffer);
//packet->type().type()
auto packet_type = packet->type();
auto packet_id = packet->packetId();
auto ordered = packet_type.type() == protocol::COMMAND || packet_type.type() == protocol::COMMAND_LOW;
@ -427,7 +425,7 @@ unique_ptr<protocol::ClientPacket> VoiceClientConnection::next_reassembled_packe
);
}
final_packet = make_unique<ClientPacket>(packet_buffer);
final_packet = ClientPacket::from_buffer(packet_buffer);
final_packet->setCompressed(final_packet->has_flag(PacketFlag::Compressed));
} else {
final_packet = buffer->pop_front();
@ -455,12 +453,13 @@ void VoiceClientConnection::sendPacket(const shared_ptr<protocol::ServerPacket>&
shared_ptr<protocol::ServerPacket> packet;
if(copy) {
packet.reset(new protocol::ServerPacket(original_packet->buffer().dup(buffer::allocate_buffer(original_packet->buffer().length()))));
packet = protocol::ServerPacket::from_buffer(original_packet->buffer().dup(buffer::allocate_buffer(original_packet->buffer().length())));
if(original_packet->getListener())
packet->setListener(std::move(original_packet->getListener()));
packet->memory_state.flags = original_packet->memory_state.flags;
} else
} else {
packet = original_packet;
}
if(prepare_directly) {
vector<pipes::buffer> buffers;

View File

@ -59,7 +59,7 @@ namespace ts {
std::chrono::system_clock::time_point last_request;
std::chrono::system_clock::time_point last_response;
std::chrono::nanoseconds value;
std::chrono::nanoseconds value{};
std::chrono::nanoseconds timeout{2000};
} ping;
@ -68,7 +68,7 @@ namespace ts {
std::chrono::system_clock::time_point last_request;
std::chrono::system_clock::time_point last_response;
std::chrono::nanoseconds value;
std::chrono::nanoseconds value{};
std::chrono::nanoseconds timeout{2000};
} js_ping;

View File

@ -22,7 +22,6 @@ namespace fs = std::experimental::filesystem;
/* Using const O3 to improve unreadability */
#if 0
/*
/* Debug */
0x555555c542a2 push rbp
0x555555c542a3 mov rbp,rsp
@ -192,7 +191,6 @@ namespace fs = std::experimental::filesystem;
0x555555c41ed4 pop r14
0x555555c41ed6 pop rbp
0x555555c41ed7 ret
*/
#endif
__attribute__((optimize("-O3"), always_inline)) void apply_crypt(void* source, void* target, size_t length, uint64_t base_key) {
uint64_t crypt_key = base_key;

View File

@ -118,9 +118,9 @@ namespace ts {
std::weak_ptr<Playlist> _self;
bool _songs_loaded = false;
inline sql::SqlManager* get_sql();
inline std::shared_ptr<server::TSServer> get_server();
inline ServerId get_server_id();
sql::SqlManager* get_sql();
std::shared_ptr<server::TSServer> get_server();
ServerId get_server_id();
std::shared_mutex playlist_lock;
std::shared_ptr<PlaylistEntry> playlist_head;

View File

@ -147,7 +147,7 @@ std::shared_ptr<file::FileTransfereKey> FileServer::generateDownloadTransferKey(
result->owner = client;
result->server = client->getServerId();
result->key_id = rand() % 65535;
result->key_id = (uint16_t) (rand() & 0xFFFF);
result->createTimestamp = std::chrono::system_clock::now();
result->key = randomString(16);
result->offset = offset;
@ -183,7 +183,7 @@ std::shared_ptr<file::FileTransfereKey> FileServer::generateUploadTransferKey(st
result->owner = client;
result->server = client->getServerId();
result->key_id = rand() % 65535;
result->key_id = (uint16_t) (rand() & 0xFFFF);
result->createTimestamp = std::chrono::system_clock::now();
result->key = randomString(16);
result->offset = offset;

2
shared

@ -1 +1 @@
Subproject commit 6b667b8d73e263facafb72b16d8f0b788f8eeb32
Subproject commit a3c5bcb9f2f36598675da74dfb118b76eeff99fa