Merge branch '1.5.0' into new-groups

# Conflicts:
#	server/src/Group.h
#	server/src/InstanceHandler.cpp
#	server/src/InstanceHandler.h
#	server/src/VirtualServer.cpp
#	server/src/client/DataClient.cpp
#	server/src/client/DataClient.h
This commit is contained in:
WolverinDEV 2021-03-01 19:22:15 +01:00
commit 449df23a4b
44 changed files with 400 additions and 363 deletions

@ -1 +1 @@
Subproject commit 8d025ece01e81d23f965c0284e38b6743bbc6b5a
Subproject commit 883a2f1433576c75d5731d80681886795fb5c41b

View File

@ -558,9 +558,9 @@ void DatabaseHelper::saveChannelPermissions(const std::shared_ptr<ts::server::Vi
}
}
std::shared_ptr<Properties> DatabaseHelper::default_properties_client(std::shared_ptr<Properties> properties, ClientType type){
std::shared_ptr<PropertyManager> DatabaseHelper::default_properties_client(std::shared_ptr<PropertyManager> properties, ClientType type){
if(!properties)
properties = make_shared<Properties>();
properties = make_shared<PropertyManager>();
properties->register_property_type<property::ClientProperties>();
properties->register_property_type<property::ConnectionProperties>();
@ -658,8 +658,8 @@ inline sql::result load_properties(ServerId sid, deque<unique_ptr<FastPropertyEn
return result;
}
std::shared_ptr<Properties> DatabaseHelper::loadServerProperties(const std::shared_ptr<ts::server::VirtualServer>& server) {
auto props = std::make_shared<Properties>();
std::shared_ptr<PropertyManager> DatabaseHelper::loadServerProperties(const std::shared_ptr<ts::server::VirtualServer>& server) {
auto props = std::make_shared<PropertyManager>();
props->register_property_type<property::VirtualServerProperties>();
(*props)[property::VIRTUALSERVER_HOST] = config::binding::DefaultVoiceHost;
@ -732,8 +732,8 @@ std::shared_ptr<Properties> DatabaseHelper::loadServerProperties(const std::shar
return props;
}
std::shared_ptr<Properties> DatabaseHelper::loadPlaylistProperties(const std::shared_ptr<ts::server::VirtualServer>& server, PlaylistId id) {
auto props = std::make_shared<Properties>();
std::shared_ptr<PropertyManager> DatabaseHelper::loadPlaylistProperties(const std::shared_ptr<ts::server::VirtualServer>& server, PlaylistId id) {
auto props = std::make_shared<PropertyManager>();
props->register_property_type<property::PlaylistProperties>();
(*props)[property::PLAYLIST_ID] = id;
@ -805,9 +805,9 @@ std::shared_ptr<Properties> DatabaseHelper::loadPlaylistProperties(const std::sh
return props;
}
std::shared_ptr<Properties> DatabaseHelper::loadChannelProperties(const shared_ptr<VirtualServer>& server, ChannelId channel) {
std::shared_ptr<PropertyManager> DatabaseHelper::loadChannelProperties(const shared_ptr<VirtualServer>& server, ChannelId channel) {
ServerId serverId = server ? server->getServerId() : 0U;
auto props = std::make_shared<Properties>();
auto props = std::make_shared<PropertyManager>();
props->register_property_type<property::ChannelProperties>();
if(server) {
@ -886,7 +886,7 @@ std::shared_ptr<Properties> DatabaseHelper::loadChannelProperties(const shared_p
return props;
}
std::shared_ptr<Properties> DatabaseHelper::loadClientProperties(const std::shared_ptr<VirtualServer>& server, ClientDbId cldbid, ClientType type) {
std::shared_ptr<PropertyManager> DatabaseHelper::loadClientProperties(const std::shared_ptr<VirtualServer>& server, ClientDbId cldbid, ClientType type) {
auto props = DatabaseHelper::default_properties_client(nullptr, type);
if(server) {
props->operator[](property::CLIENT_DESCRIPTION) = server->properties()[property::VIRTUALSERVER_DEFAULT_CLIENT_DESCRIPTION].value();
@ -945,8 +945,11 @@ std::shared_ptr<Properties> DatabaseHelper::loadClientProperties(const std::shar
logTrace(server ? server->getServerId() : 0, "[Property] Not saving property '" + std::string{prop.type().name} + "', changed for " + to_string(cldbid) + " (New value: " + prop.value() + ")");
return;
}
if(!prop.get_handle()) return;
if(!prop.get_handle()->isSaveEnabled()) return;
auto handle = prop.get_handle();
if(!handle || !handle->isSaveEnabled()) {
return;
}
if(!prop.hasDbReference() && (prop.default_value() == prop.value())) return; //No changes to default value
prop.setModified(false);

View File

@ -68,7 +68,7 @@ namespace ts::server {
struct StartupCacheEntry;
class DatabaseHelper {
public:
static std::shared_ptr<Properties> default_properties_client(std::shared_ptr<Properties> /* properties */, ClientType /* type */);
static std::shared_ptr<PropertyManager> default_properties_client(std::shared_ptr<PropertyManager> /* properties */, ClientType /* type */);
static bool assignDatabaseId(sql::SqlManager *, ServerId serverId, std::shared_ptr<DataClient>);
explicit DatabaseHelper(sql::SqlManager*);
@ -104,10 +104,10 @@ namespace ts::server {
std::shared_ptr<permission::v2::PermissionManager> loadPlaylistPermissions(const std::shared_ptr<VirtualServer>&, PlaylistId /* playlist id */);
void savePlaylistPermissions(const std::shared_ptr<VirtualServer>&, PlaylistId, const std::shared_ptr<permission::v2::PermissionManager>& /* permission manager */);
std::shared_ptr<Properties> loadServerProperties(const std::shared_ptr<VirtualServer>&); //Read and write
std::shared_ptr<Properties> loadPlaylistProperties(const std::shared_ptr<VirtualServer>&, PlaylistId); //Read and write
std::shared_ptr<Properties> loadChannelProperties(const std::shared_ptr<VirtualServer>&, ChannelId); //Read and write
std::shared_ptr<Properties> loadClientProperties(const std::shared_ptr<VirtualServer>&, ClientDbId, ClientType);
std::shared_ptr<PropertyManager> loadServerProperties(const std::shared_ptr<VirtualServer>&); //Read and write
std::shared_ptr<PropertyManager> loadPlaylistProperties(const std::shared_ptr<VirtualServer>&, PlaylistId); //Read and write
std::shared_ptr<PropertyManager> loadChannelProperties(const std::shared_ptr<VirtualServer>&, ChannelId); //Read and write
std::shared_ptr<PropertyManager> loadClientProperties(const std::shared_ptr<VirtualServer>&, ClientDbId, ClientType);
void deleteGroupArtifacts(ServerId, GroupId);
bool deleteChannelPermissions(const std::shared_ptr<VirtualServer>&, ChannelId);

View File

@ -14,7 +14,9 @@ using namespace ts::server::file;
FileServerHandler::FileServerHandler(ts::server::InstanceHandler *instance) : instance_{instance} {}
bool FileServerHandler::initialize(std::string &error) {
if(!file::initialize(error, serverInstance->properties()[property::SERVERINSTANCE_FILETRANSFER_HOST].as<std::string>(), serverInstance->properties()[property::SERVERINSTANCE_FILETRANSFER_PORT].as<uint16_t>())) {
if(!file::initialize(error,
serverInstance->properties()[property::SERVERINSTANCE_FILETRANSFER_HOST].value(),
serverInstance->properties()[property::SERVERINSTANCE_FILETRANSFER_PORT].as_or<uint16_t>(30303))) {
return false;
}
@ -46,21 +48,21 @@ void FileServerHandler::callback_transfer_registered(const std::shared_ptr<trans
const auto bytes = transfer->expected_file_size - transfer->file_offset;
if(transfer->direction == transfer::Transfer::DIRECTION_UPLOAD) {
server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_UPLOADED] += (int64_t) bytes;
server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED] += (int64_t) bytes;
server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_UPLOADED].increment_by<int64_t>(bytes);
server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED].increment_by<int64_t>(bytes);
} else {
server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED] += (int64_t) bytes;
server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED] += (int64_t) bytes;
server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED].increment_by<int64_t>(bytes);
server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED].increment_by<int64_t>(bytes);
}
auto client = server->find_client_by_id(transfer->client_id);
if(client && client->getUid() == transfer->client_unique_id) {
if(transfer->direction == transfer::Transfer::DIRECTION_UPLOAD) {
client->properties()[property::CLIENT_TOTAL_BYTES_UPLOADED] += (int64_t) bytes;
client->properties()[property::CLIENT_MONTH_BYTES_UPLOADED] += (int64_t) bytes;
client->properties()[property::CLIENT_TOTAL_BYTES_UPLOADED].increment_by<int64_t>(bytes);
client->properties()[property::CLIENT_MONTH_BYTES_UPLOADED].increment_by<int64_t>(bytes);
} else {
client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED] += (int64_t) bytes;
client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED] += (int64_t) bytes;
client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED].increment_by<int64_t>(bytes);
client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED].increment_by<int64_t>(bytes);
}
}
}
@ -76,21 +78,21 @@ void FileServerHandler::callback_transfer_aborted(const std::shared_ptr<transfer
const int64_t bytes_left = statistics.file_total_size - statistics.file_current_offset;
if(transfer->direction == transfer::Transfer::DIRECTION_UPLOAD) {
server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_UPLOADED] += -bytes_left;
server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED] += -bytes_left;
server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_UPLOADED].increment_by<int64_t>(-bytes_left);
server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED].increment_by<int64_t>(-bytes_left);
} else {
server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED] += -bytes_left;
server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED] += -bytes_left;
server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED].increment_by<int64_t>(-bytes_left);
server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED].increment_by<int64_t>(-bytes_left);
}
auto client = server->find_client_by_id(transfer->client_id);
if(client && client->getUid() == transfer->client_unique_id) {
if(transfer->direction == transfer::Transfer::DIRECTION_UPLOAD) {
client->properties()[property::CLIENT_TOTAL_BYTES_UPLOADED] += -bytes_left;
client->properties()[property::CLIENT_MONTH_BYTES_UPLOADED] += -bytes_left;
client->properties()[property::CLIENT_TOTAL_BYTES_UPLOADED].increment_by<int64_t>(-bytes_left);
client->properties()[property::CLIENT_MONTH_BYTES_UPLOADED].increment_by<int64_t>(-bytes_left);
} else {
client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED] += -bytes_left;
client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED] += -bytes_left;
client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED].increment_by<int64_t>(-bytes_left);
client->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED].increment_by<int64_t>(-bytes_left);
}
ts::command_builder notify{"notifystatusfiletransfer"};

View File

@ -18,7 +18,7 @@ Group::Group(GroupManager* handle, GroupTarget target, GroupType type, GroupId g
memtrack::allocated<Group>(this);
this->handle = handle;
this->_properties = new Properties();
this->_properties = std::make_shared<PropertyManager>();
this->_properties->register_property_type<property::GroupProperties>();
this->setPermissionManager(make_shared<permission::v2::PermissionManager>());
@ -83,7 +83,6 @@ void Group::apply_properties_from_permissions() {
}
Group::~Group() {
delete this->_properties;
memtrack::freed<Group>(this);
}
@ -262,8 +261,9 @@ std::shared_ptr<Group> GroupManager::defaultGroup(GroupTarget type, bool enforce
auto server = this->server.lock();
auto id =
server ?
server->properties()[type == GroupTarget::GROUPTARGET_SERVER ? property::VIRTUALSERVER_DEFAULT_SERVER_GROUP : property::VIRTUALSERVER_DEFAULT_CHANNEL_GROUP].as_save<GroupId>() :
serverInstance->properties()[property::SERVERINSTANCE_GUEST_SERVERQUERY_GROUP].as_save<GroupId>();
server->properties()[type == GroupTarget::GROUPTARGET_SERVER ? property::VIRTUALSERVER_DEFAULT_SERVER_GROUP
: property::VIRTUALSERVER_DEFAULT_CHANNEL_GROUP].as_or<GroupId>(0) :
serverInstance->properties()[property::SERVERINSTANCE_GUEST_SERVERQUERY_GROUP].as_or<GroupId>(0);
auto group = this->findGroupLocal(id);
if(group || enforce_property) return group;
@ -821,8 +821,8 @@ std::vector<std::shared_ptr<GroupAssignment>> GroupManager::defaultServerGroupGr
auto server = this->server.lock();
auto id =
server ?
server->properties()[property::VIRTUALSERVER_DEFAULT_MUSIC_GROUP].as_save<GroupId>() :
serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_MUSICDEFAULT_GROUP].as_save<GroupId>();
server->properties()[property::VIRTUALSERVER_DEFAULT_MUSIC_GROUP].as_or<GroupId>(0) :
serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_MUSICDEFAULT_GROUP].as_or<GroupId>(0);
auto group = this->findGroupLocal(id);
if(group) {
result.push_back(std::make_shared<GroupAssignment>(nullptr, this->getServerId(), 0, group, time_point<system_clock>()));

View File

@ -67,7 +67,7 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql), permission_hel
this->action_logger_->finalize();
}
this->_properties = new Properties();
this->_properties = std::make_shared<PropertyManager>();
this->_properties->register_property_type<property::InstanceProperties>();
this->properties()[property::SERVERINSTANCE_FILETRANSFER_PORT] = ts::config::binding::DefaultFilePort;
this->properties()[property::SERVERINSTANCE_FILETRANSFER_HOST] = ts::config::binding::DefaultFileHost;
@ -205,8 +205,12 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql), permission_hel
this->save_channel_permissions();
}
}
if(!this->default_tree->getDefaultChannel()) this->default_tree->setDefaultChannel(this->default_tree->findChannel("[cspacer04]Default Channel", nullptr));
if(!this->default_tree->getDefaultChannel()) this->default_tree->setDefaultChannel(*this->default_tree->channels().begin());
if(!this->default_tree->getDefaultChannel()) {
this->default_tree->setDefaultChannel(this->default_tree->findChannel("[cspacer04]Default Channel", nullptr));
}
if(!this->default_tree->getDefaultChannel()) {
this->default_tree->setDefaultChannel(*this->default_tree->channels().begin());
}
assert(this->default_tree->getDefaultChannel());
}
@ -215,7 +219,7 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql), permission_hel
}
if(this->properties()[property::SERVERINSTANCE_MONTHLY_TIMESTAMP].as<int64_t>() == 0) {
if(this->properties()[property::SERVERINSTANCE_MONTHLY_TIMESTAMP].as_or<int64_t>(0) == 0) {
debugMessage(LOG_INSTANCE, "Setting up monthly reset timestamp!");
this->properties()[property::SERVERINSTANCE_MONTHLY_TIMESTAMP] = duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
}
@ -225,7 +229,6 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql), permission_hel
}
InstanceHandler::~InstanceHandler() {
delete this->_properties;
delete this->banMgr;
delete this->dbHelper;
@ -330,8 +333,8 @@ bool InstanceHandler::startInstance() {
}
{
auto query_bindings_string = this->properties()[property::SERVERINSTANCE_QUERY_HOST].as<string>();
auto query_port = this->properties()[property::SERVERINSTANCE_QUERY_PORT].as<uint16_t>();
auto query_bindings_string = this->properties()[property::SERVERINSTANCE_QUERY_HOST].value();
auto query_port = this->properties()[property::SERVERINSTANCE_QUERY_PORT].as_or<uint16_t>(0);
auto query_bindings = net::resolve_bindings(query_bindings_string, query_port);
deque<shared_ptr<QueryServer::Binding>> bindings;
@ -503,7 +506,8 @@ void InstanceHandler::tickInstance() {
{
ALARM_TIMER(t, "InstanceHandler::tickInstance -> statistics tick [monthly]", milliseconds(2));
auto month_timestamp = system_clock::time_point() + seconds(this->properties()[property::SERVERINSTANCE_MONTHLY_TIMESTAMP].as<int64_t>());
auto month_timestamp = system_clock::time_point() + seconds(
this->properties()[property::SERVERINSTANCE_MONTHLY_TIMESTAMP].as_or<int64_t>(0));
auto time_t_old = system_clock::to_time_t(month_timestamp);
auto time_t_new = system_clock::to_time_t(system_clock::now());
@ -562,9 +566,9 @@ void InstanceHandler::tickInstance() {
this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_ALIVE] = this->calculateSpokenTime().count();
this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_TOTAL] =
this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_ALIVE].as_save<uint64_t>() +
this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_DELETED].as_save<uint64_t>() +
this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_VARIANZ].as_save<uint64_t>();
this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_ALIVE].as_or<uint64_t>(0) +
this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_DELETED].as_or<uint64_t>(0) +
this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_VARIANZ].as_or<uint64_t>(0);
}
}
@ -647,10 +651,10 @@ std::shared_ptr<ts::server::license::InstanceLicenseInfo> InstanceHandler::gener
request->metrics.web_clients_online = report.clients_web;
request->metrics.bots_online = report.bots;
request->metrics.queries_online = report.queries;
request->metrics.speech_total = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_TOTAL].as<uint64_t>();
request->metrics.speech_varianz = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_VARIANZ].as<uint64_t>();
request->metrics.speech_online = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_ALIVE].as<uint64_t>();
request->metrics.speech_dead = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_DELETED].as<uint64_t>();
request->metrics.speech_total = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_TOTAL].as_or<uint64_t>(0);
request->metrics.speech_varianz = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_VARIANZ].as_or<uint64_t>(0);
request->metrics.speech_online = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_ALIVE].as_or<uint64_t>(0);
request->metrics.speech_dead = this->properties()[property::SERVERINSTANCE_SPOKEN_TIME_DELETED].as_or<uint64_t>(0);
static std::string null_str{"\0\0\0\0\0\0\0\0", 8}; /* we need at least some characters */
request->web_certificate_revision = this->web_cert_revision.empty() ? null_str : this->web_cert_revision;
@ -673,11 +677,11 @@ std::shared_ptr<ts::server::license::InstanceLicenseInfo> InstanceHandler::gener
{ /* unique id */
auto property_unique_id = this->properties()[property::SERVERINSTANCE_UNIQUE_ID];
if(property_unique_id.as<string>().empty())
if(property_unique_id.value().empty())
property_unique_id = rnd_string(64);
auto hash = digest::sha256(request->info.uname);
hash = digest::sha256(hash + property_unique_id.as<string>() + get_mac_address());
hash = digest::sha256(hash + property_unique_id.value() + get_mac_address());
request->info.unique_id = base64::encode(hash);
}
}
@ -896,7 +900,7 @@ bool InstanceHandler::validate_default_groups() {
{
auto property = this->properties()[property::SERVERINSTANCE_ADMIN_SERVERQUERY_GROUP];
auto group_id = property.as_save<GroupId>();
auto group_id = property.as_or<GroupId>(0);
debugMessage(LOG_INSTANCE, "Instance admin query group id {}", group_id);
auto group_instance = this->group_manager_->server_groups()->find_group(GroupCalculateMode::GLOBAL, group_id);
@ -924,7 +928,7 @@ bool InstanceHandler::validate_default_groups() {
{
auto property = this->properties()[property::SERVERINSTANCE_GUEST_SERVERQUERY_GROUP];
auto group_id = property.as_save<GroupId>();
auto group_id = property.as_or<GroupId>(0);
debugMessage(LOG_INSTANCE, "Instance guest query group id {}", group_id);
auto group_instance = this->group_manager_->server_groups()->find_group(GroupCalculateMode::GLOBAL, group_id);

View File

@ -73,9 +73,8 @@ namespace ts {
bool startInstance();
void stopInstance();
ts::Properties& properties(){
return *_properties;
}
inline PropertyWrapper properties() { return PropertyWrapper{this->_properties}; }
inline const PropertyWrapper properties() const { return PropertyWrapper{this->_properties}; }
std::shared_ptr<ts::server::InternalClient> getInitialServerAdmin(){ return globalServerAdmin; }
const auto& group_manager(){ return this->group_manager_; }
@ -106,16 +105,16 @@ namespace ts {
[[nodiscard]] inline const auto& general_task_executor(){ return this->general_task_executor_; }
std::shared_ptr<stats::ConnectionStatistics> getStatistics(){ return statistics; }
std::shared_ptr<license::InstanceLicenseInfo> generateLicenseData();
[[nodiscard]] inline std::shared_ptr<stats::ConnectionStatistics> getStatistics(){ return statistics; }
[[nodiscard]] std::shared_ptr<license::InstanceLicenseInfo> generateLicenseData();
std::shared_ptr<TeamSpeakLicense> getTeamSpeakLicense() { return this->teamspeak_license; }
std::shared_ptr<ts::Properties> getDefaultServerProperties() { return this->default_server_properties; }
std::shared_ptr<webio::LoopManager> getWebIoLoop() { return this->web_event_loop; }
std::shared_ptr<weblist::WebListManager> getWebList() { return this->web_list; }
[[nodiscard]] inline std::shared_ptr<TeamSpeakLicense> getTeamSpeakLicense() { return this->teamspeak_license; }
[[nodiscard]] inline PropertyWrapper getDefaultServerProperties() { return PropertyWrapper{this->default_server_properties}; }
[[nodiscard]] inline std::shared_ptr<webio::LoopManager> getWebIoLoop() { return this->web_event_loop; }
[[nodiscard]] inline std::shared_ptr<weblist::WebListManager> getWebList() { return this->web_list; }
std::shared_ptr<permission::PermissionNameMapper> getPermissionMapper() { return this->permission_mapper; }
std::shared_ptr<ts::event::EventExecutor> getConversationIo() { return this->conversation_io; }
[[nodiscard]] inline std::shared_ptr<permission::PermissionNameMapper> getPermissionMapper() { return this->permission_mapper; }
[[nodiscard]] inline std::shared_ptr<ts::event::EventExecutor> getConversationIo() { return this->conversation_io; }
[[nodiscard]] inline const auto& server_command_executor() { return this->server_command_executor_; }
[[nodiscard]] inline const auto& permission_helper() { return this->permission_helper_; }
@ -146,7 +145,7 @@ namespace ts {
file::FileServerHandler* file_server_handler_{nullptr};
std::unique_ptr<log::ActionLogger> action_logger_{nullptr};
ts::Properties* _properties = nullptr;
std::shared_ptr<ts::PropertyManager> _properties{};
std::shared_ptr<ServerCommandExecutor> server_command_executor_{};
@ -154,7 +153,7 @@ namespace ts {
std::shared_ptr<webio::LoopManager> web_event_loop = nullptr;
std::shared_ptr<weblist::WebListManager> web_list = nullptr;
std::shared_ptr<ts::Properties> default_server_properties = nullptr;
std::shared_ptr<ts::PropertyManager> default_server_properties = nullptr;
std::shared_mutex default_tree_lock;
std::shared_ptr<ts::ServerChannelTree> default_tree = nullptr;

View File

@ -782,14 +782,14 @@ bool VirtualServerManager::createServerSnapshot(Command &cmd, shared_ptr<Virtual
//Server
{
cmd[index]["begin_virtualserver"] = "";
for(const auto& serverProperty : server->properties().list_properties(property::FLAG_SNAPSHOT)) {
for(const auto& serverProperty : server->properties()->list_properties(property::FLAG_SNAPSHOT)) {
if(version == 0) {
switch (serverProperty.type().property_index) {
case property::VIRTUALSERVER_DOWNLOAD_QUOTA:
case property::VIRTUALSERVER_UPLOAD_QUOTA:
case property::VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH:
case property::VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH:
cmd[index][std::string{serverProperty.type().name}] = (uint64_t) serverProperty.as_save<int64_t>();
cmd[index][std::string{serverProperty.type().name}] = (uint64_t) serverProperty.as_or<int64_t>(0);
default:
break;
}
@ -803,13 +803,14 @@ bool VirtualServerManager::createServerSnapshot(Command &cmd, shared_ptr<Virtual
{
cmd[index]["begin_channels"] = "";
for(const auto& channel : server->getChannelTree()->channels()) {
for(const auto& channelProperty : channel->properties().list_properties(property::FLAG_SNAPSHOT)) {
if(channelProperty.type() == property::CHANNEL_ID)
cmd[index]["channel_id"] = channelProperty.as<string>();
else if(channelProperty.type() == property::CHANNEL_PID)
cmd[index]["channel_pid"] = channelProperty.as<string>();
else
cmd[index][std::string{channelProperty.type().name}] = channelProperty.as<string>();
for(const auto& channelProperty : channel->properties()->list_properties(property::FLAG_SNAPSHOT)) {
if(channelProperty.type() == property::CHANNEL_ID) {
cmd[index]["channel_id"] = channelProperty.value();
} else if(channelProperty.type() == property::CHANNEL_PID) {
cmd[index]["channel_pid"] = channelProperty.value();
} else {
cmd[index][std::string{channelProperty.type().name}] = channelProperty.value();
}
}
index++;
}

View File

@ -76,12 +76,12 @@ bool VirtualServer::registerClient(shared_ptr<ConnectedClient> client) {
if(client->getType() == ClientType::CLIENT_TEAMSPEAK || client->getType() == ClientType::CLIENT_WEB) {
this->properties()[property::VIRTUALSERVER_CLIENT_CONNECTIONS] ++; //increase manager connections
this->properties()[property::VIRTUALSERVER_CLIENT_CONNECTIONS].increment_by<uint64_t>(1); //increase manager connections
this->properties()[property::VIRTUALSERVER_LAST_CLIENT_CONNECT] = duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
}
else if(client->getType() == ClientType::CLIENT_QUERY) {
this->properties()[property::VIRTUALSERVER_LAST_QUERY_CONNECT] = duration_cast<seconds>(system_clock::now().time_since_epoch()).count();
this->properties()[property::VIRTUALSERVER_QUERY_CLIENT_CONNECTIONS] ++; //increase manager connections
this->properties()[property::VIRTUALSERVER_QUERY_CLIENT_CONNECTIONS].increment_by<uint64_t>(1); //increase manager connections
}
return true;
@ -567,7 +567,8 @@ void VirtualServer::client_move(
this->groups->setChannelGroup(target->getClientDatabaseId(), nullptr, s_source_channel);
}
auto update = target->properties()[property::CLIENT_IS_TALKER].as<bool>() || target->properties()[property::CLIENT_TALK_REQUEST].as<int64_t>() > 0;
auto update = target->properties()[property::CLIENT_IS_TALKER].as_or<bool>(false) ||
target->properties()[property::CLIENT_TALK_REQUEST].as_or<int64_t>(0) > 0;
if(update) {
target->properties()[property::CLIENT_IS_TALKER] = 0;
target->properties()[property::CLIENT_TALK_REQUEST] = 0;

View File

@ -99,8 +99,8 @@ void VirtualServer::executeServerTick() {
{
BEGIN_TIMINGS();
auto flood_decrease = this->properties()[property::VIRTUALSERVER_ANTIFLOOD_POINTS_TICK_REDUCE].as<FloodPoints>();
auto flood_block = this->properties()[property::VIRTUALSERVER_ANTIFLOOD_POINTS_NEEDED_IP_BLOCK].as<FloodPoints>();
auto flood_decrease = this->properties()[property::VIRTUALSERVER_ANTIFLOOD_POINTS_TICK_REDUCE].as_or<FloodPoints>(0);
auto flood_block = this->properties()[property::VIRTUALSERVER_ANTIFLOOD_POINTS_NEEDED_IP_BLOCK].as_or<FloodPoints>(0);
bool flag_update_spoken = this->spoken_time_timestamp + seconds(30) < system_clock::now();
@ -183,11 +183,10 @@ void VirtualServer::executeServerTick() {
if(server_channel->client_count() > 0 || !this->getClientsByChannelRoot(channel, true).empty())
continue;
seconds deleteTimeout(0);
if(channel->properties().hasProperty(property::CHANNEL_DELETE_DELAY))
deleteTimeout = seconds(channel->properties()[property::CHANNEL_DELETE_DELAY].as<uint64_t>());
seconds deleteTimeout{channel->properties()[property::CHANNEL_DELETE_DELAY].as_or<uint64_t>(0)};
auto last_left = time_point<system_clock>() + milliseconds(channel->properties()[property::CHANNEL_LAST_LEFT].as<int64_t>());
auto last_left = time_point<system_clock>() + milliseconds(
channel->properties()[property::CHANNEL_LAST_LEFT].as_or<int64_t>(0));
auto channel_created = channel->createdTimestamp();
if(system_clock::now() - last_left < deleteTimeout) continue; //One second stay

View File

@ -55,19 +55,19 @@ bool VirtualServer::initialize(bool test_properties) {
this->_properties = serverInstance->databaseHelper()->loadServerProperties(self.lock());
this->_properties->registerNotifyHandler([&](Property& prop){
if(prop.type() == property::VIRTUALSERVER_DISABLE_IP_SAVING) {
this->_disable_ip_saving = prop.as<bool>();
this->_disable_ip_saving = prop.as_or<bool>(false);
return;
} else if(prop.type() == property::VIRTUALSERVER_CODEC_ENCRYPTION_MODE) {
this->_voice_encryption_mode = prop.as<int>();
this->_voice_encryption_mode = prop.as_or<int>(0);
return;
} else if(prop.type() == property::VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH) {
auto file_vs = file::server()->find_virtual_server(this->getServerId());
if(!file_vs) return;
file_vs->max_networking_upload_bandwidth(prop.as_save<int64_t>([]{ return -1; }));
file_vs->max_networking_upload_bandwidth(prop.as_or<int64_t>(-1));
} else if(prop.type() == property::VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH) {
auto file_vs = file::server()->find_virtual_server(this->getServerId());
if(!file_vs) return;
file_vs->max_networking_download_bandwidth(prop.as_save<int64_t>([]{ return -1; }));
file_vs->max_networking_download_bandwidth(prop.as_or<int64_t>(-1));
}
std::string sql{};
if(prop.type() == property::VIRTUALSERVER_HOST)
@ -118,7 +118,8 @@ bool VirtualServer::initialize(bool test_properties) {
return;
}
serverInstance->action_logger()->toggle_logging_group(server_id, action_type, prop.as_save<bool>([]{ return true; }));
serverInstance->action_logger()->toggle_logging_group(server_id, action_type,
prop.as_or<bool>(true));
};
for(const property::VirtualServerProperties& property : {
@ -129,7 +130,7 @@ bool VirtualServer::initialize(bool test_properties) {
property::VIRTUALSERVER_LOG_QUERY,
property::VIRTUALSERVER_LOG_PERMISSIONS
}) {
auto prop = this->_properties->find(property::PROP_TYPE_SERVER, property);
auto prop = this->_properties->get(property::PROP_TYPE_SERVER, property);
sync_property(prop);
}
@ -138,10 +139,10 @@ bool VirtualServer::initialize(bool test_properties) {
});
}
if(!properties()[property::VIRTUALSERVER_KEYPAIR].as<std::string>().empty()){
if(!properties()[property::VIRTUALSERVER_KEYPAIR].value().empty()){
debugMessage(this->serverId, "Importing server keypair");
this->_serverKey = new ecc_key;
auto bytes = base64::decode(properties()[property::VIRTUALSERVER_KEYPAIR].as<std::string>());
auto bytes = base64::decode(properties()[property::VIRTUALSERVER_KEYPAIR].value());
int err;
if((err = ecc_import(reinterpret_cast<const unsigned char *>(bytes.data()), bytes.length(), this->_serverKey)) != CRYPT_OK){
logError(this->getServerId(), "Cant import key. ({} => {})", err, error_to_string(err));
@ -218,7 +219,7 @@ bool VirtualServer::initialize(bool test_properties) {
if(!channelTree->getDefaultChannel()) channelTree->setDefaultChannel(*channelTree->channels().begin());
auto default_channel = channelTree->getDefaultChannel();
assert(default_channel);
if(default_channel->properties()[property::CHANNEL_FLAG_PASSWORD].as<bool>())
if(default_channel->properties()[property::CHANNEL_FLAG_PASSWORD].as_or<bool>(false))
default_channel->properties()[property::CHANNEL_FLAG_PASSWORD] = false;
this->tokenManager = new token::TokenManager(this->sql, this->getServerId());
@ -261,7 +262,7 @@ bool VirtualServer::initialize(bool test_properties) {
}
if (initialize_groups) {
if(!this->properties()[property::VIRTUALSERVER_AUTOGENERATED_PRIVILEGEKEY].as<string>().empty()) {
if(!this->properties()[property::VIRTUALSERVER_AUTOGENERATED_PRIVILEGEKEY].value().empty()) {
logCritical(this->getServerId(), "Missing default groups. Applying permission reset!");
}
@ -285,11 +286,14 @@ bool VirtualServer::initialize(bool test_properties) {
server_statistics_ = make_shared<stats::ConnectionStatistics>(serverInstance->getStatistics());
this->serverRoot = std::make_shared<InternalClient>(this->sql, self.lock(), this->properties()[property::VIRTUALSERVER_NAME].as<string>(), false);
this->serverRoot = std::make_shared<InternalClient>(this->sql, self.lock(),
this->properties()[property::VIRTUALSERVER_NAME].value(), false);
this->serverRoot->initialize_weak_reference(this->serverRoot);
this->properties().registerNotifyHandler([&](Property& property) {
if(property.type() == property::VIRTUALSERVER_NAME) static_pointer_cast<InternalClient>(this->serverRoot)->properties()[property::CLIENT_NICKNAME] = property.as<string>();
this->properties()->registerNotifyHandler([&](Property& property) {
if(property.type() == property::VIRTUALSERVER_NAME) {
static_pointer_cast<InternalClient>(this->serverRoot)->properties()[property::CLIENT_NICKNAME] = property.value();
}
});
this->serverRoot->server = nullptr;
@ -322,8 +326,10 @@ bool VirtualServer::initialize(bool test_properties) {
this->properties()[property::VIRTUALSERVER_FILEBASE] = file::server()->file_base_path();
file_vs->max_networking_download_bandwidth(this->properties()[property::VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH].as_save<int64_t>([]{ return -1; }));
file_vs->max_networking_upload_bandwidth(this->properties()[property::VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH].as_save<int64_t>([]{ return -1; }));
file_vs->max_networking_download_bandwidth(
this->properties()[property::VIRTUALSERVER_MAX_DOWNLOAD_TOTAL_BANDWIDTH].as_or<int64_t>(-1));
file_vs->max_networking_upload_bandwidth(
this->properties()[property::VIRTUALSERVER_MAX_UPLOAD_TOTAL_BANDWIDTH].as_or<int64_t>(-1));
}
this->channelTree->printChannelTree([&](std::string msg){ debugMessage(this->serverId, msg); });
@ -441,7 +447,7 @@ bool VirtualServer::start(std::string& error) {
}
}
auto host = this->properties()[property::VIRTUALSERVER_HOST].as<string>();
auto host = this->properties()[property::VIRTUALSERVER_HOST].value();
if(config::binding::enforce_default_voice_host)
host = config::binding::DefaultVoiceHost;
@ -450,7 +456,7 @@ bool VirtualServer::start(std::string& error) {
this->stop("failed to start", true);
return false;
}
if(this->properties()[property::VIRTUALSERVER_PORT].as<uint16_t>() <= 0){
if(this->properties()[property::VIRTUALSERVER_PORT].as_or<uint16_t>(0) <= 0){
error = "invalid port";
this->stop("failed to start", true);
return false;
@ -463,7 +469,7 @@ bool VirtualServer::start(std::string& error) {
sockaddr_in addr{};
memset(&addr, 0, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(this->properties()[property::VIRTUALSERVER_PORT].as<uint16_t>());
addr.sin_port = htons(this->properties()[property::VIRTUALSERVER_PORT].as_or<uint16_t>(0));
if(!evaluateAddress4(address, addr.sin_addr)) {
logError(this->serverId, "Fail to resolve v4 address info for \"{}\"", address);
continue;
@ -474,7 +480,7 @@ bool VirtualServer::start(std::string& error) {
sockaddr_in6 addr{};
memset(&addr, 0, sizeof(addr));
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(this->properties()[property::VIRTUALSERVER_PORT].as<uint16_t>());
addr.sin6_port = htons(this->properties()[property::VIRTUALSERVER_PORT].as_or<uint16_t>(0));
if(!evaluateAddress6(address, addr.sin6_addr)) {
logError(this->serverId, "Fail to resolve v6 address info for \"{}\"", address);
continue;
@ -504,11 +510,11 @@ bool VirtualServer::start(std::string& error) {
if(ts::config::web::activated && serverInstance->sslManager()->web_ssl_options()) {
string web_host_string = this->properties()[property::VIRTUALSERVER_WEB_HOST];
if(web_host_string.empty())
web_host_string = this->properties()[property::VIRTUALSERVER_HOST].as<string>();
web_host_string = this->properties()[property::VIRTUALSERVER_HOST].as_or<string>(0);
auto web_port = this->properties()[property::VIRTUALSERVER_WEB_PORT].as<uint16_t>();
auto web_port = this->properties()[property::VIRTUALSERVER_WEB_PORT].as_or<uint16_t>(0);
if(web_port == 0)
web_port = this->properties()[property::VIRTUALSERVER_PORT].as<uint16_t>();
web_port = this->properties()[property::VIRTUALSERVER_PORT].as_or<uint16_t>(0);
startTimestamp = std::chrono::system_clock::now();
#ifdef COMPILE_WEB_CLIENT
@ -687,6 +693,7 @@ OnlineClientReport VirtualServer::onlineStats() {
switch (cl->getType()) {
case CLIENT_TEAMSPEAK:
case CLIENT_TEASPEAK:
response.clients_ts++;
break;
case CLIENT_WEB:
@ -698,6 +705,8 @@ OnlineClientReport VirtualServer::onlineStats() {
case CLIENT_MUSIC:
response.bots++;
break;
case CLIENT_INTERNAL:
case MAX:
default:
break;
}
@ -846,7 +855,7 @@ bool VirtualServer::notifyServerEdited(std::shared_ptr<ConnectedClient> invoker,
logError(this->getServerId(), "Tried to broadcast a server update with an unknown info: " + key);
continue;
}
cmd[key] = properties()[info].as<std::string>();
cmd[key] = properties()[info].value();
}
this->forEachClient([&cmd](shared_ptr<ConnectedClient> client){
client->sendCommand(cmd);
@ -1128,7 +1137,7 @@ permission::v2::PermissionFlaggedValue VirtualServer::calculate_permission(
}
bool VirtualServer::verifyServerPassword(std::string password, bool hashed) {
if(!this->properties()[property::VIRTUALSERVER_FLAG_PASSWORD].as<bool>()) return true;
if(!this->properties()[property::VIRTUALSERVER_FLAG_PASSWORD].as_or<bool>(false)) return true;
if(password.empty()) return false;
if(!hashed){
@ -1137,7 +1146,7 @@ bool VirtualServer::verifyServerPassword(std::string password, bool hashed) {
password = base64_encode(string(buffer, SHA_DIGEST_LENGTH));
}
return password == this->properties()[property::VIRTUALSERVER_PASSWORD].as<std::string>();
return password == this->properties()[property::VIRTUALSERVER_PASSWORD].value();
}
VirtualServer::NetworkReport VirtualServer::generate_network_report() {
@ -1184,12 +1193,17 @@ bool VirtualServer::resetPermissions(std::string& new_permission_token) {
}
//Server admin
auto default_server_admin = serverInstance->group_manager()->findGroup(serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_SERVERADMIN_GROUP].as<GroupId>());
auto default_server_music = serverInstance->group_manager()->findGroup(serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_MUSICDEFAULT_GROUP].as<GroupId>());
auto default_server_guest = serverInstance->group_manager()->findGroup(serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_SERVERDEFAULT_GROUP].as<GroupId>());
auto default_server_admin = serverInstance->group_manager()->findGroup(
serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_SERVERADMIN_GROUP].as_or<GroupId>(0));
auto default_server_music = serverInstance->group_manager()->findGroup(
serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_MUSICDEFAULT_GROUP].as_or<GroupId>(0));
auto default_server_guest = serverInstance->group_manager()->findGroup(
serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_SERVERDEFAULT_GROUP].as_or<GroupId>(0));
auto default_channel_admin = serverInstance->group_manager()->findGroup(serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_CHANNELADMIN_GROUP].as<GroupId>());
auto default_channel_guest = serverInstance->group_manager()->findGroup(serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_CHANNELDEFAULT_GROUP].as<GroupId>());
auto default_channel_admin = serverInstance->group_manager()->findGroup(
serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_CHANNELADMIN_GROUP].as_or<GroupId>(0));
auto default_channel_guest = serverInstance->group_manager()->findGroup(
serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_CHANNELDEFAULT_GROUP].as_or<GroupId>(0));
if(!default_server_guest) {
logCritical(0, "Missing default server guest template group!");
@ -1291,7 +1305,8 @@ void VirtualServer::ensureValidDefaultGroups() {
this->properties()[property::VIRTUALSERVER_DEFAULT_CHANNEL_GROUP] = default_channel_group->groupId();
}
auto admin_channel_group = this->group_manager()->findGroupLocal(this->properties()[property::VIRTUALSERVER_DEFAULT_CHANNEL_ADMIN_GROUP].as_save<GroupId>());
auto admin_channel_group = this->group_manager()->findGroupLocal(
this->properties()[property::VIRTUALSERVER_DEFAULT_CHANNEL_ADMIN_GROUP].as_or<GroupId>(0));
if(!admin_channel_group) {
logError(this->serverId, "Missing server's default channel admin group! (Id: {})", this->properties()[property::VIRTUALSERVER_DEFAULT_CHANNEL_ADMIN_GROUP].value());
@ -1310,7 +1325,7 @@ void VirtualServer::send_text_message(const std::shared_ptr<BasicChannel> &chann
auto now = chrono::system_clock::now();
bool conversation_private;
auto conversation_mode = channel->properties()[property::CHANNEL_CONVERSATION_MODE].as<ChannelConversationMode>();
auto conversation_mode = channel->properties()[property::CHANNEL_CONVERSATION_MODE].as_or<ChannelConversationMode>(ChannelConversationMode::CHANNELCONVERSATIONMODE_PRIVATE);
if(conversation_mode == ChannelConversationMode::CHANNELCONVERSATIONMODE_NONE) {
/* nothing to do */
return;
@ -1318,7 +1333,7 @@ void VirtualServer::send_text_message(const std::shared_ptr<BasicChannel> &chann
conversation_private = conversation_mode == ChannelConversationMode::CHANNELCONVERSATIONMODE_PRIVATE;
}
auto flag_password = channel->properties()[property::CHANNEL_FLAG_PASSWORD].as<bool>();
auto flag_password = channel->properties()[property::CHANNEL_FLAG_PASSWORD].as_or<bool>(false);
for(const auto& client : this->getClients()) {
if(client->connectionState() != ConnectionState::CONNECTED)
continue;

View File

@ -185,7 +185,8 @@ namespace ts {
ecc_key* serverKey(){ return _serverKey; }
std::string publicServerKey();
Properties& properties(){ return *this->_properties; }
inline PropertyWrapper properties() { return PropertyWrapper{this->_properties}; }
inline const PropertyWrapper properties() const { return PropertyWrapper{this->_properties}; }
inline sql::SqlManager * getSql(){ return this->sql; }
sql::AsyncSqlPool* getSqlPool(){ return this->sql->pool; }
@ -343,7 +344,7 @@ namespace ts {
//General server properties
ecc_key* _serverKey = nullptr;
std::shared_ptr<Properties> _properties;
std::shared_ptr<PropertyManager> _properties;
int _voice_encryption_mode = 2; /* */
ServerChannelTree* channelTree = nullptr;

View File

@ -131,7 +131,7 @@ bool VirtualServerManager::initialize(bool autostart) {
this->instances.push_back(server);
}
if(autostart && server->properties()[property::VIRTUALSERVER_AUTOSTART].as<bool>()) {
if(autostart && server->properties()[property::VIRTUALSERVER_AUTOSTART].as_or<bool>(false)) {
logMessage(server->getServerId(), "Starting server");
string msg;
try {
@ -201,7 +201,7 @@ uint16_t VirtualServerManager::next_available_port(const std::string& host_strin
unallowed_ports.reserve(instances.size());
for(const auto& instance : instances) {
unallowed_ports.push_back(instance->properties()[property::VIRTUALSERVER_PORT].as<uint16_t>());
unallowed_ports.push_back(instance->properties()[property::VIRTUALSERVER_PORT].as_or<uint16_t>(0));
auto vserver = instance->getVoiceServer();
if(instance->running() && vserver) {
@ -230,12 +230,18 @@ uint16_t VirtualServerManager::next_available_port(const std::string& host_strin
switch (net::address_available(baddress, net::binding_type::TCP)) {
case net::binding_result::ADDRESS_USED:
goto next_port;
case net::binding_result::ADDRESS_FREE:
case net::binding_result::INTERNAL_ERROR:
default:
break; /* if we've an internal error we ignore it */
}
switch (net::address_available(baddress, net::binding_type::UDP)) {
case net::binding_result::ADDRESS_USED:
goto next_port;
case net::binding_result::ADDRESS_FREE:
case net::binding_result::INTERNAL_ERROR:
default:
break; /* if we've an internal error we ignore it */
}
@ -249,7 +255,7 @@ uint16_t VirtualServerManager::next_available_port(const std::string& host_strin
}
ts::ServerId VirtualServerManager::next_available_server_id(bool& success) {
auto server_id_base = this->handle->properties()[property::SERVERINSTANCE_VIRTUAL_SERVER_ID_INDEX].as<ServerId>();
auto server_id_base = this->handle->properties()[property::SERVERINSTANCE_VIRTUAL_SERVER_ID_INDEX].as_or<ServerId>(0);
/* ensure we're not using 0xFFFF (This is the snapshot server) */
if(server_id_base > 65530) {
success = false;
@ -292,7 +298,7 @@ ServerReport VirtualServerManager::report() {
result.avariable++;
if(sr->running()) {
result.online++;
result.slots += sr->properties()[property::VIRTUALSERVER_MAXCLIENTS].as<size_t>();
result.slots += sr->properties()[property::VIRTUALSERVER_MAXCLIENTS].as_or<size_t>(0);
result.onlineClients += sr->onlineClients();
result.onlineChannels += sr->onlineChannels();
}
@ -324,7 +330,7 @@ size_t VirtualServerManager::runningServers() {
size_t VirtualServerManager::usedSlots() {
size_t res = 0;
for(const auto& sr : this->serverInstances())
res += sr->properties()[property::VIRTUALSERVER_MAXCLIENTS].as<size_t>();
res += sr->properties()[property::VIRTUALSERVER_MAXCLIENTS].as_or<size_t>(0);
return res;
}
@ -410,7 +416,7 @@ bool VirtualServerManager::deleteServer(shared_ptr<VirtualServer> server) {
server->state = ServerState::DELETING;
}
this->handle->properties()[property::SERVERINSTANCE_SPOKEN_TIME_DELETED] += server->properties()[property::VIRTUALSERVER_SPOKEN_TIME].as<uint64_t>();
this->handle->properties()[property::SERVERINSTANCE_SPOKEN_TIME_DELETED].increment_by(server->properties()[property::VIRTUALSERVER_SPOKEN_TIME].as_or<uint64_t>(0));
this->delete_server_in_db(server->serverId, false);
this->handle->databaseHelper()->handleServerDelete(server->serverId);
@ -441,7 +447,7 @@ void VirtualServerManager::executeAutostart() {
threads::MutexLock l(this->instanceLock);
auto lastStart = system_clock::time_point();
for(const auto& server : this->instances){
if(!server->running() && server->properties()[property::VIRTUALSERVER_AUTOSTART].as<bool>()){
if(!server->running() && server->properties()[property::VIRTUALSERVER_AUTOSTART].as_or<bool>(false)){
threads::self::sleep_until(lastStart + milliseconds(10)); //Don't start all server at the same point (otherwise all servers would tick at the same moment)
lastStart = system_clock::now();
logMessage(server->getServerId(), "Starting server");

View File

@ -98,7 +98,7 @@ std::shared_ptr<ViewEntry> ClientChannelView::find_channel(const std::shared_ptr
while(heads.front()) {
auto parent = heads.front()->parent();
if(!parent && heads.front()->properties()[property::CHANNEL_PID].as<ChannelId>() != 0) {
if(!parent && heads.front()->properties()[property::CHANNEL_PID].as_or<ChannelId>(0) != 0) {
head = this->find_linked_entry(channel->channelId(), nullptr);//We're searching for a deleted head! So lets iterate over everything
deep_search = true;
break;

View File

@ -54,7 +54,7 @@ size_t ServerChannel::client_count() {
return result;
}
void ServerChannel::setProperties(const std::shared_ptr<Properties> &ptr) {
void ServerChannel::setProperties(const std::shared_ptr<PropertyManager> &ptr) {
BasicChannel::setProperties(ptr);
}
@ -92,7 +92,7 @@ std::shared_ptr<BasicChannel> ServerChannelTree::createChannel(ChannelId parentI
/* TODO: Speed up (skip the database query) */
auto properties = serverInstance->databaseHelper()->loadChannelProperties(this->server_ref.lock(), channel->channelId());
for(const auto& prop : channel->properties().list_properties()) {
for(const auto& prop : channel->properties()->list_properties()) {
if(prop.isModified()) { //Copy the already set properties
(*properties)[prop.type()] = prop.value();
}
@ -135,11 +135,12 @@ bool ServerChannelTree::initializeTempParents() {
auto channel = dynamic_pointer_cast<BasicChannel>(linked_channel->entry);
assert(channel);
if(channel->properties().hasProperty(property::CHANNEL_PID) && channel->properties()[property::CHANNEL_PID].as<ChannelId>() != 0){
if(channel->properties()[property::CHANNEL_PID].as_or<ChannelId>(0) != 0){
if(!channel->parent())
linked_channel->parent = findLinkedChannelByPool(this->tmpChannelList, channel->properties()[property::CHANNEL_PID]);
if(!channel->parent()){
logError(this->getServerId(), "Invalid channel parent (Channel does not exists). Channel id: {} ({}) Missing parent id: {}", channel->channelId(), channel->name(), channel->properties()[property::CHANNEL_PID].as<ChannelId>());
logError(this->getServerId(), "Invalid channel parent (Channel does not exists). Channel id: {} ({}) Missing parent id: {}", channel->channelId(), channel->name(),
channel->properties()[property::CHANNEL_PID].as_or<ChannelId>(0));
logError(this->getServerId(), "Resetting parent");
channel->properties()[property::CHANNEL_PID] = 0;
}
@ -314,7 +315,7 @@ inline std::shared_ptr<TreeView::LinkedTreeEntry> buildChannelTree(ServerId serv
}
auto evaluated_parent_id = channel->parent() ? channel->parent()->channelId() : 0;
if(evaluated_parent_id != channel->properties()[property::CHANNEL_PID].as<ChannelId>()) {
if(evaluated_parent_id != channel->properties()[property::CHANNEL_PID].as_or<ChannelId>(0)) {
debugMessage(serverId, "Fixed parent id for channel {} ({}). New parent channel {}", entry->entry->channelId(), channel->name(), evaluated_parent_id);
channel->properties()[property::CHANNEL_PID] = evaluated_parent_id;
}

View File

@ -22,7 +22,7 @@ namespace ts {
ServerChannel(uint32_t rtc_channel_id, ChannelId parentId, ChannelId channelId);
~ServerChannel() override;
void setProperties(const std::shared_ptr<Properties> &ptr) override;
void setProperties(const std::shared_ptr<PropertyManager> &ptr) override;
uint32_t rtc_channel_id;

View File

@ -146,7 +146,7 @@ void ConnectedClient::updateChannelClientProperties(bool lock_channel_tree, bool
std::deque<property::ClientProperties> updated_client_properties;
{
auto old_talk_power = this->properties()[property::CLIENT_TALK_POWER].as_save<int64_t>();
auto old_talk_power = this->properties()[property::CLIENT_TALK_POWER].as_or<int64_t>(0);
auto new_talk_power = permission_talk_power.has_value ? permission_talk_power.value : 0;
debugMessage(this->getServerId(), "{} Recalculated talk power. New value: {} Old value: {}", CLIENT_STR_LOG_PREFIX, new_talk_power, old_talk_power);
@ -154,7 +154,7 @@ void ConnectedClient::updateChannelClientProperties(bool lock_channel_tree, bool
this->properties()[property::CLIENT_TALK_POWER] = new_talk_power;
updated_client_properties.emplace_back(property::CLIENT_TALK_POWER);
auto retract_request = this->properties()[property::CLIENT_IS_TALKER].as<bool>();
auto retract_request = this->properties()[property::CLIENT_IS_TALKER].as_or<bool>(false);
if(!retract_request && channel) {
retract_request = channel->talk_power_granted(permission_talk_power);
}
@ -176,7 +176,7 @@ void ConnectedClient::updateChannelClientProperties(bool lock_channel_tree, bool
}
{
IconId current_icon_id = this->properties()[property::CLIENT_ICON_ID].as_save<IconId>();
IconId current_icon_id = this->properties()[property::CLIENT_ICON_ID].as_or<IconId>(0);
IconId new_icon_id{ 0};
auto local_permissions = this->clientPermissions;
@ -254,7 +254,7 @@ void ConnectedClient::updateChannelClientProperties(bool lock_channel_tree, bool
void ConnectedClient::updateTalkRights(permission::v2::PermissionFlaggedValue talk_power) {
bool flag = false;
flag |= this->properties()[property::CLIENT_IS_TALKER].as<bool>();
flag |= this->properties()[property::CLIENT_IS_TALKER].as_or<bool>(false);
auto current_channel = this->currentChannel;
if(!flag && current_channel) {
@ -274,7 +274,8 @@ void ConnectedClient::increaseFloodPoints(uint16_t num) {
bool ConnectedClient::shouldFloodBlock() {
if(!this->server) return false;
if(!this->block_flood) return false;
return this->floodPoints > this->server->properties()[property::VIRTUALSERVER_ANTIFLOOD_POINTS_NEEDED_COMMAND_BLOCK].as<uint16_t>();
return this->floodPoints >
this->server->properties()[property::VIRTUALSERVER_ANTIFLOOD_POINTS_NEEDED_COMMAND_BLOCK].as_or<uint16_t>(150);
}
std::deque<std::shared_ptr<BasicChannel>> ConnectedClient::subscribeChannel(const std::deque<std::shared_ptr<BasicChannel>>& targets, bool lock_channel, bool enforce) {
@ -677,11 +678,11 @@ inline void send_channels(ConnectedClient* client, ChannelIT begin, const Channe
continue;
}
for (const auto &elm : channel->properties().list_properties(property::FLAG_CHANNEL_VIEW, client->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) {
for (const auto &elm : channel->properties()->list_properties(property::FLAG_CHANNEL_VIEW, client->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) {
if(elm.type() == property::CHANNEL_ORDER)
builder.put_unchecked(index, elm.type().name, override_orderid ? 0 : (*begin)->previous_channel);
else
builder.put_unchecked(index, elm.type().name, elm.as<string>());
builder.put_unchecked(index, elm.type().name, elm.value());
}
begin++;
@ -758,7 +759,7 @@ void ConnectedClient::sendChannelDescription(const std::shared_ptr<BasicChannel>
auto limit = this->getType() == CLIENT_TEAMSPEAK ? 8192 : 131130;
auto description = channel->properties()[property::CHANNEL_DESCRIPTION].as<std::string>();
auto description = channel->properties()[property::CHANNEL_DESCRIPTION].value();
Command cmd("notifychanneledited");
cmd["cid"] = channel->channelId();
cmd["reasonid"] = 9;
@ -774,20 +775,20 @@ void ConnectedClient::tick_server(const std::chrono::system_clock::time_point &t
if(this->lastOnlineTimestamp.time_since_epoch().count() == 0) {
this->lastOnlineTimestamp = time;
} else if(time - this->lastOnlineTimestamp > seconds(120)) {
this->properties()[property::CLIENT_MONTH_ONLINE_TIME] += duration_cast<seconds>(time - lastOnlineTimestamp).count();
this->properties()[property::CLIENT_TOTAL_ONLINE_TIME] += duration_cast<seconds>(time - lastOnlineTimestamp).count();
this->properties()[property::CLIENT_MONTH_ONLINE_TIME].increment_by<uint64_t>(duration_cast<seconds>(time - lastOnlineTimestamp).count());
this->properties()[property::CLIENT_TOTAL_ONLINE_TIME].increment_by<uint64_t>(duration_cast<seconds>(time - lastOnlineTimestamp).count());
lastOnlineTimestamp = time;
}
if(time - this->lastTransfareTimestamp > seconds(5)) {
lastTransfareTimestamp = time;
auto update = this->connectionStatistics->mark_file_bytes();
if(update.first > 0) {
this->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED] += update.first;
this->properties()[property::CLIENT_TOTAL_BYTES_DOWNLOADED] += update.first;
this->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED].increment_by<uint64_t>(update.first);
this->properties()[property::CLIENT_TOTAL_BYTES_DOWNLOADED].increment_by<uint64_t>(update.first);
}
if(update.second > 0) {
this->properties()[property::CLIENT_MONTH_BYTES_UPLOADED] += update.second;
this->properties()[property::CLIENT_TOTAL_BYTES_UPLOADED] += update.second;
this->properties()[property::CLIENT_MONTH_BYTES_UPLOADED].increment_by<uint64_t>(update.second);
this->properties()[property::CLIENT_TOTAL_BYTES_UPLOADED].increment_by<uint64_t>(update.second);
}
}
}
@ -799,16 +800,16 @@ void ConnectedClient::tick_server(const std::chrono::system_clock::time_point &t
void ConnectedClient::sendServerInit() {
Command command("initserver");
for(const auto& prop : this->server->properties().list_properties(property::FLAG_SERVER_VIEW, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) {
for(const auto& prop : this->server->properties()->list_properties(property::FLAG_SERVER_VIEW, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) {
command[std::string{prop.type().name}] = prop.value();
}
command["virtualserver_maxclients"] = 32;
//Server stuff
command["client_talk_power"] = this->properties()[property::CLIENT_TALK_POWER].as<string>();
command["client_needed_serverquery_view_power"] = this->properties()[property::CLIENT_NEEDED_SERVERQUERY_VIEW_POWER].as<string>();
command["client_myteamspeak_id"] = this->properties()[property::CLIENT_MYTEAMSPEAK_ID].as<string>();
command["client_integrations"] = this->properties()[property::CLIENT_INTEGRATIONS].as<string>();
command["client_talk_power"] = this->properties()[property::CLIENT_TALK_POWER].value();
command["client_needed_serverquery_view_power"] = this->properties()[property::CLIENT_NEEDED_SERVERQUERY_VIEW_POWER].value();
command["client_myteamspeak_id"] = this->properties()[property::CLIENT_MYTEAMSPEAK_ID].value();
command["client_integrations"] = this->properties()[property::CLIENT_INTEGRATIONS].value();
if(ts::config::server::DefaultServerLicense == LicenseType::LICENSE_AUTOMATIC_INSTANCE){
if(serverInstance->getVoiceServerManager()->usedSlots() <= 32)
@ -818,9 +819,9 @@ void ConnectedClient::sendServerInit() {
else
command["lt"] = LicenseType::LICENSE_HOSTING;
} else if(ts::config::server::DefaultServerLicense == LicenseType::LICENSE_AUTOMATIC_SERVER){
if(this->server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as<size_t>() <= 32)
if(this->server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as_or<size_t>(0) <= 32)
command["lt"] = LicenseType::LICENSE_NONE;
else if(this->server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as<size_t>() <= 512)
else if(this->server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as_or<size_t>(0) <= 512)
command["lt"] = LicenseType::LICENSE_NPL;
else
command["lt"] = LicenseType::LICENSE_HOSTING;

View File

@ -422,7 +422,7 @@ bool ConnectedClient::notifyClientUpdated(const std::shared_ptr<ConnectedClient>
response["clid"] = client_id;
for (const auto &prop : props) {
if(lastOnlineTimestamp.time_since_epoch().count() > 0 && (*prop == property::CLIENT_TOTAL_ONLINE_TIME || *prop == property::CLIENT_MONTH_ONLINE_TIME))
response[prop->name] = client->properties()[prop].as<int64_t>() + duration_cast<seconds>(system_clock::now() - client->lastOnlineTimestamp).count();
response[prop->name] = client->properties()[prop].as_or<int64_t>(0) + duration_cast<seconds>(system_clock::now() - client->lastOnlineTimestamp).count();
else
response[prop->name] = client->properties()[prop].value();
}
@ -471,7 +471,7 @@ bool ConnectedClient::notifyChannelMoved(const std::shared_ptr<BasicChannel> &ch
bool ConnectedClient::notifyChannelCreate(const std::shared_ptr<BasicChannel> &channel, ChannelId orderId, const std::shared_ptr<ConnectedClient> &invoker) {
Command notify("notifychannelcreated");
for (auto &prop : channel->properties().list_properties(property::FLAG_CHANNEL_VARIABLE | property::FLAG_CHANNEL_VIEW, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) {
for (auto &prop : channel->properties()->list_properties(property::FLAG_CHANNEL_VARIABLE | property::FLAG_CHANNEL_VIEW, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) {
if(prop.type() == property::CHANNEL_ORDER)
notify[prop.type().name] = orderId;
else if(prop.type() == property::CHANNEL_DESCRIPTION)
@ -536,7 +536,7 @@ bool ConnectedClient::notifyChannelShow(const std::shared_ptr<ts::BasicChannel>
result = this->notifyChannelCreate(channel, orderId, this->server->serverRoot);
} else {
Command notify("notifychannelshow");
for (auto &prop : channel->properties().list_properties(property::FLAG_CHANNEL_VARIABLE | property::FLAG_CHANNEL_VIEW, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) {
for (auto &prop : channel->properties()->list_properties(property::FLAG_CHANNEL_VARIABLE | property::FLAG_CHANNEL_VIEW, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) {
if(prop.type() == property::CHANNEL_ORDER) {
notify[prop.type().name] = orderId;
} else if(prop.type() == property::CHANNEL_DESCRIPTION) {
@ -688,7 +688,7 @@ bool ConnectedClient::notifyChannelEdited(
} else if(prop == property::CHANNEL_DESCRIPTION) {
send_description_change = true;
} else {
notify[prop_info.name] = channel->properties()[prop].as<string>();
notify[prop_info.name] = channel->properties()[prop].value();
property_count++;
}
}
@ -730,7 +730,7 @@ bool ConnectedClient::notifyChannelDeleted(const deque<ChannelId>& channel_ids,
bool ConnectedClient::notifyServerUpdated(std::shared_ptr<ConnectedClient> invoker) {
Command response("notifyserverupdated");
for (const auto& elm : this->server->properties().list_properties(property::FLAG_SERVER_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) {
for (const auto& elm : this->server->properties()->list_properties(property::FLAG_SERVER_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) {
if(elm.type() == property::VIRTUALSERVER_MIN_WINPHONE_VERSION)
continue;

View File

@ -182,7 +182,7 @@ bool ConnectedClient::handle_text_command(
else {
send_message(music_root, "There are " + to_string(mbots.size()) + " music bots " + locationStr + ":");
for (const auto &mbot : mbots) {
if(mbot->properties()[property::CLIENT_DISABLED].as<bool>()) {
if(mbot->properties()[property::CLIENT_DISABLED].as_or<bool>(false)) {
send_message(music_root, " - [color=red]" + to_string(mbot->getClientDatabaseId()) + " | " + mbot->getDisplayName() + " [DISABLED][/color]");
} else {
send_message(music_root, " - [color=green]" + to_string(mbot->getClientDatabaseId()) + " | " + mbot->getDisplayName() + "[/color]");

View File

@ -90,12 +90,12 @@ bool DataClient::loadDataForCurrentServer() {
}
});
if(this->properties()[property::CLIENT_DATABASE_ID].as<ClientDbId>() == 0) {
if(this->properties()[property::CLIENT_DATABASE_ID].as_or<ClientDbId>(0) == 0) {
return false;
}
//Load general properties
std::deque<ts::PropertyWrapper> copied;
std::deque<ts::Property> copied;
for(const auto& prop : this->_properties->list_properties()){
if((prop.type().flags & property::FLAG_GLOBAL) == 0) continue;
if(prop.type().default_value == prop.value()) continue;
@ -113,7 +113,7 @@ bool DataClient::loadDataForCurrentServer() {
this->_properties->toggleSave(false);
for(const auto& e : copied) {
auto p = this->properties()->find(e.type().type_property, e.type().property_index);
auto p = this->properties()->get(e.type().type_property, e.type().property_index);
p = e.value();
p.setModified(false);
}

View File

@ -29,45 +29,11 @@ namespace ts {
friend class QueryServer;
friend class music::MusicBotManager;
public:
struct PropertyWrapper {
std::shared_ptr<Properties> handle;
Properties* operator->() {
return handle.get();
}
const Properties* operator->() const {
return handle.get();
}
template<class F>
std::result_of_t<F(Properties &)> operator->*(F &&f) {
return std::forward<F>(f)(*handle);
}
template<class F>
std::result_of_t<F(Properties const &)> operator->*(F &&f) const {
return std::forward<F>(f)(*handle);
}
/*
template <typename T>
ts::PropertyWrapper operator[](T type) {
return (*handle)[type];
}
*/
template <typename T>
ts::PropertyWrapper operator[](const T& type) {
return (*handle)[type];
}
};
DataClient(sql::SqlManager*, const std::shared_ptr<VirtualServer>&);
virtual ~DataClient();
PropertyWrapper properties(){ return { this->_properties }; }
inline PropertyWrapper properties() { return PropertyWrapper{this->_properties}; }
inline const PropertyWrapper properties() const { return PropertyWrapper{this->_properties}; }
[[nodiscard]] inline auto permissions(){ return this->clientPermissions; }
/* main permission calculate function */
@ -137,7 +103,7 @@ namespace ts {
std::shared_ptr<VirtualServer> server;
std::shared_ptr<permission::v2::PermissionManager> clientPermissions = nullptr;
std::shared_ptr<Properties> _properties;
std::shared_ptr<PropertyManager> _properties;
std::shared_ptr<BasicChannel> currentChannel = nullptr;
};

View File

@ -38,8 +38,8 @@ SpeakingClient::~SpeakingClient() {
bool SpeakingClient::shouldReceiveVoice(const std::shared_ptr<ConnectedClient> &sender) {
//if(this->properties()[property::CLIENT_AWAY].as<bool>()) return false;
if(!this->properties()[property::CLIENT_OUTPUT_HARDWARE].as<bool>()) return false;
if(this->properties()[property::CLIENT_OUTPUT_MUTED].as<bool>()) return false;
if(!this->properties()[property::CLIENT_OUTPUT_HARDWARE].as_or<bool>(true)) return false;
if(this->properties()[property::CLIENT_OUTPUT_MUTED].as_or<bool>(false)) return false;
{
shared_lock client_lock(this->channel_lock);
@ -241,7 +241,7 @@ command_result SpeakingClient::handleCommandClientInit(Command& cmd) {
}
if(this->getType() == ClientType::CLIENT_TEAMSPEAK && permission::v2::permission_granted(1, permissions[permission::b_client_enforce_valid_hwid])) {
auto hwid = this->properties()[property::CLIENT_HARDWARE_ID].as<string>();
auto hwid = this->properties()[property::CLIENT_HARDWARE_ID].value();
if(
!std::regex_match(hwid, regex_hwid_windows) &&
!std::regex_match(hwid, regex_hwid_unix) &&
@ -352,8 +352,8 @@ command_result SpeakingClient::handleCommandClientInit(Command& cmd) {
count++;
}
auto maxClients = this->server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as<size_t>();
auto reserved = this->server->properties()[property::VIRTUALSERVER_RESERVED_SLOTS].as<size_t>();
auto maxClients = this->server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as_or<size_t>(0);
auto reserved = this->server->properties()[property::VIRTUALSERVER_RESERVED_SLOTS].as_or<size_t>(0);
bool allowReserved = permission::v2::permission_granted(1, permissions[permission::b_client_use_reserved_slot]);
if(reserved > maxClients){
@ -364,10 +364,10 @@ command_result SpeakingClient::handleCommandClientInit(Command& cmd) {
TIMING_STEP(timings, "max clients");
auto old_last_connected = this->properties()[property::CLIENT_LASTCONNECTED].as<int64_t>();
auto old_last_connected = this->properties()[property::CLIENT_LASTCONNECTED].as_or<int64_t>(0);
this->properties()[property::CONNECTION_CLIENT_IP] = this->getLoggingPeerIp();
this->properties()[property::CLIENT_LASTCONNECTED] = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
this->properties()[property::CLIENT_TOTALCONNECTIONS]++;
this->properties()[property::CLIENT_TOTALCONNECTIONS].increment_by<uint64_t>(1);
{
auto time_point = system_clock::time_point() + seconds(old_last_connected);
if(time_point < build::version()->timestamp) {
@ -453,14 +453,14 @@ void SpeakingClient::processJoin() {
}
}
//this->updateChannelClientProperties(false); /* will be already updated via assignChannel */
if(ref_server->properties()[property::VIRTUALSERVER_HOSTMESSAGE_MODE].as<int>() == 3 && !ref_server->properties()[property::VIRTUALSERVER_HOSTMESSAGE].as<string>().empty()) {
if(ref_server->properties()[property::VIRTUALSERVER_HOSTMESSAGE_MODE].as_or<int>(0) == 3 && !ref_server->properties()[property::VIRTUALSERVER_HOSTMESSAGE].value().empty()) {
auto weak = this->_this;
threads::Thread([weak](){
threads::self::sleep_for(milliseconds(2000));
auto client = weak.lock();
if(!client || !client->server) return;
client->disconnect(client->server->properties()[property::VIRTUALSERVER_HOSTMESSAGE].as<string>());
client->disconnect(client->server->properties()[property::VIRTUALSERVER_HOSTMESSAGE].value());
}).detach();
}
@ -583,13 +583,13 @@ void SpeakingClient::updateSpeak(bool only_update, const std::chrono::system_clo
if(this->speak_last_packet + this->speak_accuracy < now) {
if(this->speak_last_packet > this->speak_begin) {
if(!this->properties()[property::CLIENT_FLAG_TALKING].as<bool>()) {
if(!this->properties()[property::CLIENT_FLAG_TALKING].as_or<bool>(false)) {
this->properties()[property::CLIENT_FLAG_TALKING] = true;
}
this->speak_time += duration_cast<milliseconds>(this->speak_last_packet - this->speak_begin);
} else {
if(this->properties()[property::CLIENT_FLAG_TALKING].as<bool>()) {
if(this->properties()[property::CLIENT_FLAG_TALKING].as_or<bool>(false)) {
this->properties()[property::CLIENT_FLAG_TALKING] = false;
}
}

View File

@ -32,9 +32,10 @@ using namespace std;
using namespace ts;
using namespace ts::server;
//{findError("parameter_invalid"), "could not resolve permission " + (cmd[index].has("permid") ? cmd[index]["permid"].as<string>() : cmd[index]["permsid"].as<string>())}; \
//TODO: Log missing permissions?
/*
TODO: Log missing permissions?
{findError("parameter_invalid"), "could not resolve permission " + (cmd[index].has("permid") ? cmd[index]["permid"].as<string>() : cmd[index]["permsid"].as<string>())};
*/
command_result ConnectedClient::handleCommandChannelGetDescription(Command &cmd) {
CMD_CHK_AND_INC_FLOOD_POINTS(0);
RESOLVE_CHANNEL_R(cmd["cid"], true);
@ -816,9 +817,9 @@ command_result ConnectedClient::handleCommandChannelCreate(Command &cmd) {
for (const auto &channel : target_tree->channels()) {
created_total++;
if (channel->properties()[property::CHANNEL_CREATED_BY] == own_cldbid) {
if (channel->properties()[property::CHANNEL_FLAG_PERMANENT].as<bool>()) {
if (channel->properties()[property::CHANNEL_FLAG_PERMANENT].as_or<bool>(false)) {
created_perm++;
} else if (channel->properties()[property::CHANNEL_FLAG_SEMI_PERMANENT].as<bool>()) {
} else if (channel->properties()[property::CHANNEL_FLAG_SEMI_PERMANENT].as_or<bool>(false)) {
created_semi++;
} else {
created_tmp++;
@ -826,7 +827,8 @@ command_result ConnectedClient::handleCommandChannelCreate(Command &cmd) {
}
}
if (this->server && created_total >= this->server->properties()[property::VIRTUALSERVER_MAX_CHANNELS].as<uint64_t>())
if (this->server && created_total >=
this->server->properties()[property::VIRTUALSERVER_MAX_CHANNELS].as_or<uint64_t>(0))
return command_result{error::channel_limit_reached};
auto max_channels = this->calculate_permission(permission::i_client_max_channels, parent_channel_id, false);
@ -1181,7 +1183,6 @@ ts::command_result ConnectedClient::execute_channel_edit(ChannelId& channel_id,
bool updating_max_family_clients{false};
bool updating_talk_power{false};
bool updating_type{false};
bool updating_conversation{false};
bool updating_sort_order{false};
/* Step 1: Parse all values which are possible and validate them without any context. */
@ -1410,7 +1411,7 @@ ts::command_result ConnectedClient::execute_channel_edit(ChannelId& channel_id,
}
/* Step 2: Remove all not changed properties and test the updates */
auto& channel_properties = channel->properties();
auto channel_properties = channel->properties();
std::map<property::ChannelProperties, std::string> changed_values{};
for(auto& [ key, value ] : values) {
@ -1477,7 +1478,6 @@ ts::command_result ConnectedClient::execute_channel_edit(ChannelId& channel_id,
case property::CHANNEL_CONVERSATION_HISTORY_LENGTH:
case property::CHANNEL_CONVERSATION_MODE:
updating_conversation = true;
break;
/* non updatable properties */
@ -1552,7 +1552,7 @@ ts::command_result ConnectedClient::execute_channel_edit(ChannelId& channel_id,
}
ChannelType::ChannelType target_channel_type;
{
if(updating_type) {
auto flag_permanent = converter<bool>::from_string_view(target_channel_property_value(property::CHANNEL_FLAG_PERMANENT));
auto flag_semi_permanent = converter<bool>::from_string_view(target_channel_property_value(property::CHANNEL_FLAG_SEMI_PERMANENT));
@ -2145,11 +2145,11 @@ command_result ConnectedClient::handleCommandChannelAddPerm(Command &cmd) {
/* test if we've the default channel */
bool family_contains_default_channel{false};
if(channel->properties()[property::CHANNEL_FLAG_DEFAULT].as<bool>()) {
if(channel->properties()[property::CHANNEL_FLAG_DEFAULT].as_or<bool>(false)) {
family_contains_default_channel = true;
} else {
for(const auto& child_channel : channel_tree->channels(channel)) {
if(child_channel->properties()[property::CHANNEL_FLAG_DEFAULT].as<bool>()) {
if(child_channel->properties()[property::CHANNEL_FLAG_DEFAULT].as_or<bool>(false)) {
family_contains_default_channel = true;
break;
}
@ -2476,7 +2476,7 @@ command_result ConnectedClient::handleCommandChannelInfo(Command &cmd) {
Command res("");
for (const auto &prop : channel->properties().list_properties(property::FLAG_CHANNEL_VIEW | property::FLAG_CHANNEL_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0))
for (const auto &prop : channel->properties()->list_properties(property::FLAG_CHANNEL_VIEW | property::FLAG_CHANNEL_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0))
res[prop.type().name] = prop.value();
res["seconds_empty"] = channel->emptySince();

View File

@ -237,25 +237,26 @@ command_result ConnectedClient::handleCommandClientMove(Command &cmd) {
}
/* FIXME: Some kind of invite key frags to prevent limit checking! */
if (!channel->properties()[property::CHANNEL_FLAG_MAXCLIENTS_UNLIMITED].as<bool>() || !channel->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_UNLIMITED].as<bool>()) {
if (!channel->properties()[property::CHANNEL_FLAG_MAXCLIENTS_UNLIMITED].as_unchecked<bool>() || !channel->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_UNLIMITED].as_unchecked<bool>()) {
if(!permission::v2::permission_granted(1, this->calculate_permission(permission::b_channel_join_ignore_maxclients, channel->channelId()))) {
if(!channel->properties()[property::CHANNEL_FLAG_MAXCLIENTS_UNLIMITED].as<bool>()) {
auto maxClients = channel->properties()[property::CHANNEL_MAXCLIENTS].as<int32_t>();
if(!channel->properties()[property::CHANNEL_FLAG_MAXCLIENTS_UNLIMITED].as_unchecked<bool>()) {
auto maxClients = channel->properties()[property::CHANNEL_MAXCLIENTS].as_unchecked<int32_t>();
if (maxClients >= 0 && maxClients < this->server->getClientsByChannel(channel).size() + clients.size()) {
return command_result{error::channel_maxclients_reached};
}
}
if(!channel->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_UNLIMITED].as<bool>()) {
if(!channel->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_UNLIMITED].as_unchecked<bool>()) {
shared_ptr<BasicChannel> family_root;
if(channel->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_INHERITED].as<bool>()) {
if(channel->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_INHERITED].as_unchecked<bool>()) {
family_root = channel;
while(family_root && family_root->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_INHERITED].as<bool>()) {
while(family_root &&
family_root->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_INHERITED].as_unchecked<bool>()) {
family_root = family_root->parent();
}
}
if(family_root && !family_root->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_UNLIMITED]) { //Could not be CHANNEL_FLAG_MAXFAMILYCLIENTS_INHERITED
auto maxClients = family_root->properties()[property::CHANNEL_MAXFAMILYCLIENTS].as<int32_t>();
auto maxClients = family_root->properties()[property::CHANNEL_MAXFAMILYCLIENTS].as_unchecked<int32_t>();
auto client_count = 0;
for(const auto& entry : this->server->getClientsByChannelRoot(channel, false)) {
if(entry.get() != this) {
@ -304,7 +305,8 @@ command_result ConnectedClient::handleCommandClientMove(Command &cmd) {
server_channel_w_lock.lock();
}
if(oldChannel->channelType() == ChannelType::temporary && oldChannel->properties()[property::CHANNEL_DELETE_DELAY].as<int64_t>() == 0) {
if(oldChannel->channelType() == ChannelType::temporary &&
oldChannel->properties()[property::CHANNEL_DELETE_DELAY].as_unchecked<int64_t>() == 0) {
if(this->server->getClientsByChannelRoot(oldChannel, false).empty()) {
this->server->delete_channel(dynamic_pointer_cast<ServerChannel>(oldChannel), this->ref(), "temporary auto delete", server_channel_w_lock, true);
}
@ -520,7 +522,7 @@ command_result ConnectedClient::handleCommandClientEdit(Command &cmd, const std:
logError(this->getServerId(), R"([{}] Tried to change a client property to an invalid value for {}. (Key: "{}", Value: "{}"))", CLIENT_STR_LOG_PREFIX, CLIENT_STR_LOG_PREFIX_(client), key, cmd[key].string());
continue;
}
if(client->properties()[&info].as<string>() == cmd[key].as<string>()) continue;
if(client->properties()[&info].as_unchecked<string>() == cmd[key].as<string>()) continue;
if (info == property::CLIENT_DESCRIPTION) {
if (self) {
@ -815,47 +817,49 @@ command_result ConnectedClient::handleCommandClientList(Command &cmd) {
if (cmd.hasParm("uid"))
result[index]["client_unique_identifier"] = client->getUid();
if (cmd.hasParm("away")) {
result[index]["client_away"] = client->properties()[property::CLIENT_AWAY].as<string>();
result[index]["client_away_message"] = client->properties()[property::CLIENT_AWAY_MESSAGE].as<string>();
result[index]["client_away"] = client->properties()[property::CLIENT_AWAY].as_unchecked<string>();
result[index]["client_away_message"] = client->properties()[property::CLIENT_AWAY_MESSAGE].as_unchecked<string>();
}
if (cmd.hasParm("groups")) {
result[index]["client_channel_group_id"] = client->properties()[property::CLIENT_CHANNEL_GROUP_ID].as<string>();
result[index]["client_servergroups"] = client->properties()[property::CLIENT_SERVERGROUPS].as<string>();
result[index]["client_channel_group_inherited_channel_id"] = client->properties()[property::CLIENT_CHANNEL_GROUP_INHERITED_CHANNEL_ID].as<string>();
result[index]["client_channel_group_id"] = client->properties()[property::CLIENT_CHANNEL_GROUP_ID].as_unchecked<string>();
result[index]["client_servergroups"] = client->properties()[property::CLIENT_SERVERGROUPS].as_unchecked<string>();
result[index]["client_channel_group_inherited_channel_id"] = client->properties()[property::CLIENT_CHANNEL_GROUP_INHERITED_CHANNEL_ID].as_unchecked<string>();
}
if (cmd.hasParm("times")) {
result[index]["client_idle_time"] = duration_cast<milliseconds>(system_clock::now() - client->idleTimestamp).count();
result[index]["client_total_online_time"] = client->properties()[property::CLIENT_TOTAL_ONLINE_TIME].as<int64_t>() + duration_cast<seconds>(system_clock::now() - client->lastOnlineTimestamp).count();
result[index]["client_month_online_time"] = client->properties()[property::CLIENT_MONTH_ONLINE_TIME].as<int64_t>() + duration_cast<seconds>(system_clock::now() - client->lastOnlineTimestamp).count();
result[index]["client_total_online_time"] =
client->properties()[property::CLIENT_TOTAL_ONLINE_TIME].as_unchecked<int64_t>() + duration_cast<seconds>(system_clock::now() - client->lastOnlineTimestamp).count();
result[index]["client_month_online_time"] =
client->properties()[property::CLIENT_MONTH_ONLINE_TIME].as_unchecked<int64_t>() + duration_cast<seconds>(system_clock::now() - client->lastOnlineTimestamp).count();
result[index]["client_idle_time"] = duration_cast<milliseconds>(system_clock::now() - client->idleTimestamp).count();
result[index]["client_created"] = client->properties()[property::CLIENT_CREATED].as<string>();
result[index]["client_lastconnected"] = client->properties()[property::CLIENT_LASTCONNECTED].as<string>();
result[index]["client_created"] = client->properties()[property::CLIENT_CREATED].as_unchecked<string>();
result[index]["client_lastconnected"] = client->properties()[property::CLIENT_LASTCONNECTED].as_unchecked<string>();
}
if (cmd.hasParm("info")) {
result[index]["client_version"] = client->properties()[property::CLIENT_VERSION].as<string>();
result[index]["client_platform"] = client->properties()[property::CLIENT_PLATFORM].as<string>();
result[index]["client_version"] = client->properties()[property::CLIENT_VERSION].as_unchecked<string>();
result[index]["client_platform"] = client->properties()[property::CLIENT_PLATFORM].as_unchecked<string>();
}
if (cmd.hasParm("badges"))
result[index]["client_badges"] = client->properties()[property::CLIENT_BADGES].as<string>();
result[index]["client_badges"] = client->properties()[property::CLIENT_BADGES].as_unchecked<string>();
if (cmd.hasParm("country"))
result[index]["client_country"] = client->properties()[property::CLIENT_COUNTRY].as<string>();
result[index]["client_country"] = client->properties()[property::CLIENT_COUNTRY].as_unchecked<string>();
if (cmd.hasParm("ip"))
result[index]["connection_client_ip"] = allow_ip ? client->properties()[property::CONNECTION_CLIENT_IP].as<string>() : "hidden";
result[index]["connection_client_ip"] = allow_ip ? client->properties()[property::CONNECTION_CLIENT_IP].as_unchecked<string>() : "hidden";
if (cmd.hasParm("icon"))
result[index]["client_icon_id"] = client->properties()[property::CLIENT_ICON_ID].as<string>();
result[index]["client_icon_id"] = client->properties()[property::CLIENT_ICON_ID].as_unchecked<string>();
if (cmd.hasParm("voice")) {
result[index]["client_talk_power"] = client->properties()[property::CLIENT_TALK_POWER].as<string>();
result[index]["client_flag_talking"] = client->properties()[property::CLIENT_FLAG_TALKING].as<string>();
result[index]["client_input_muted"] = client->properties()[property::CLIENT_INPUT_MUTED].as<string>();
result[index]["client_output_muted"] = client->properties()[property::CLIENT_OUTPUT_MUTED].as<string>();
result[index]["client_input_hardware"] = client->properties()[property::CLIENT_INPUT_HARDWARE].as<string>();
result[index]["client_output_hardware"] = client->properties()[property::CLIENT_OUTPUT_HARDWARE].as<string>();
result[index]["client_is_talker"] = client->properties()[property::CLIENT_IS_TALKER].as<string>();
result[index]["client_is_priority_speaker"] = client->properties()[property::CLIENT_IS_PRIORITY_SPEAKER].as<string>();
result[index]["client_is_recording"] = client->properties()[property::CLIENT_IS_RECORDING].as<string>();
result[index]["client_is_channel_commander"] = client->properties()[property::CLIENT_IS_CHANNEL_COMMANDER].as<string>();
result[index]["client_talk_power"] = client->properties()[property::CLIENT_TALK_POWER].as_unchecked<string>();
result[index]["client_flag_talking"] = client->properties()[property::CLIENT_FLAG_TALKING].as_unchecked<string>();
result[index]["client_input_muted"] = client->properties()[property::CLIENT_INPUT_MUTED].as_unchecked<string>();
result[index]["client_output_muted"] = client->properties()[property::CLIENT_OUTPUT_MUTED].as_unchecked<string>();
result[index]["client_input_hardware"] = client->properties()[property::CLIENT_INPUT_HARDWARE].as_unchecked<string>();
result[index]["client_output_hardware"] = client->properties()[property::CLIENT_OUTPUT_HARDWARE].as_unchecked<string>();
result[index]["client_is_talker"] = client->properties()[property::CLIENT_IS_TALKER].as_unchecked<string>();
result[index]["client_is_priority_speaker"] = client->properties()[property::CLIENT_IS_PRIORITY_SPEAKER].as_unchecked<string>();
result[index]["client_is_recording"] = client->properties()[property::CLIENT_IS_RECORDING].as_unchecked<string>();
result[index]["client_is_channel_commander"] = client->properties()[property::CLIENT_IS_CHANNEL_COMMANDER].as_unchecked<string>();
}
index++;
@ -1103,13 +1107,13 @@ command_result ConnectedClient::handleCommandClientDbInfo(Command &cmd) {
auto props = serverInstance->databaseHelper()->loadClientProperties(this->server, info->client_database_id, ClientType::CLIENT_TEAMSPEAK);
if(allow_ip) {
bulk.put_unchecked("client_lastip", (*props)[property::CONNECTION_CLIENT_IP].as<string>());
bulk.put_unchecked("client_lastip", (*props)[property::CONNECTION_CLIENT_IP].as_unchecked<string>());
} else {
bulk.put_unchecked("client_lastip", "hidden");
}
#define ASSIGN_PROPERTY(property) \
bulk.put_unchecked(property, (*props)[property].as<string>());
bulk.put_unchecked(property, (*props)[property].value());
ASSIGN_PROPERTY(property::CLIENT_ICON_ID);
ASSIGN_PROPERTY(property::CLIENT_BADGES);
@ -1212,10 +1216,13 @@ command_result ConnectedClient::handleCommandClientDBFind(Command &cmd) {
auto props = serverInstance->databaseHelper()->loadClientProperties(this->server, client_database_id, ClientType::CLIENT_TEAMSPEAK);
if (props) {
auto& properties = *props;
bulk.put_unchecked("client_badges", properties[property::CLIENT_BADGES].as<std::string>());
bulk.put_unchecked("client_version", properties[property::CLIENT_VERSION].as<std::string>());
bulk.put_unchecked("client_platform", properties[property::CLIENT_PLATFORM].as<std::string>());
bulk.put_unchecked("client_hwid", properties[property::CLIENT_HARDWARE_ID].as<std::string>());
bulk.put_unchecked("client_badges", properties[property::CLIENT_BADGES].as_unchecked<std::string>());
bulk.put_unchecked("client_version",
properties[property::CLIENT_VERSION].as_unchecked<std::string>());
bulk.put_unchecked("client_platform",
properties[property::CLIENT_PLATFORM].as_unchecked<std::string>());
bulk.put_unchecked("client_hwid",
properties[property::CLIENT_HARDWARE_ID].as_unchecked<std::string>());
}
}
});
@ -1249,7 +1256,7 @@ command_result ConnectedClient::handleCommandClientInfo(Command &cmd) {
for (const auto &key : client->properties()->list_properties(property::FLAG_CLIENT_VIEW | property::FLAG_CLIENT_VARIABLE | property::FLAG_CLIENT_INFO, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0))
res[result_index][std::string{key.type().name}] = key.value();
if(view_remote)
res[result_index]["connection_client_ip"] = client->properties()[property::CONNECTION_CLIENT_IP].as<string>();
res[result_index]["connection_client_ip"] = client->properties()[property::CONNECTION_CLIENT_IP].value();
else
res[result_index]["connection_client_ip"] = "hidden";
res[result_index]["client_idle_time"] = duration_cast<milliseconds>(system_clock::now() - client->idleTimestamp).count();

View File

@ -653,13 +653,13 @@ command_result ConnectedClient::handleCommandFTInitUpload(ts::Command &cmd) {
return ts::command_result{error::file_overwrite_excludes_resume};
{
auto server_quota = this->server->properties()[property::VIRTUALSERVER_UPLOAD_QUOTA].as<ssize_t>();
auto server_used_quota = this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED].as<size_t>();
auto server_quota = this->server->properties()[property::VIRTUALSERVER_UPLOAD_QUOTA].as_unchecked<ssize_t>();
auto server_used_quota = this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED].as_unchecked<size_t>();
server_used_quota += cmd["size"].as<uint64_t>();
if(server_quota >= 0 && server_quota * 1024 * 1024 < (int64_t) server_used_quota) return command_result{error::file_transfer_server_quota_exceeded};
auto client_quota = this->calculate_permission(permission::i_ft_quota_mb_upload_per_client, 0);
auto client_used_quota = this->properties()[property::CLIENT_MONTH_BYTES_UPLOADED].as<size_t>();
auto client_used_quota = this->properties()[property::CLIENT_MONTH_BYTES_UPLOADED].as_unchecked<size_t>();
client_used_quota += cmd["size"].as<uint64_t>();
if(client_quota.has_value && !client_quota.has_infinite_power() && (client_quota.value < 0 || client_quota.value * 1024 * 1024 < (int64_t) client_used_quota))
return command_result{error::file_transfer_client_quota_exceeded};
@ -772,8 +772,8 @@ command_result ConnectedClient::handleCommandFTInitDownload(ts::Command &cmd) {
std::shared_ptr<file::ExecuteResponse<file::transfer::TransferInitError, std::shared_ptr<file::transfer::Transfer>>> transfer_response{};
{
auto server_quota = this->server->properties()[property::VIRTUALSERVER_DOWNLOAD_QUOTA].as<ssize_t>();
auto server_used_quota = this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED].as<size_t>();
auto server_quota = this->server->properties()[property::VIRTUALSERVER_DOWNLOAD_QUOTA].as_unchecked<ssize_t>();
auto server_used_quota = this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED].as_unchecked<size_t>();
if(server_quota >= 0) {
if((size_t) server_quota * 1024 * 1024 <= server_used_quota)
return command_result{error::file_transfer_server_quota_exceeded};
@ -782,7 +782,7 @@ command_result ConnectedClient::handleCommandFTInitDownload(ts::Command &cmd) {
auto client_quota = this->calculate_permission(permission::i_ft_quota_mb_download_per_client, 0);
auto client_used_quota = this->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED].as<size_t>();
auto client_used_quota = this->properties()[property::CLIENT_MONTH_BYTES_DOWNLOADED].as_unchecked<size_t>();
if(client_quota.has_value) {
if(client_quota.value > 0) {
if((size_t) client_quota.value * 1024 * 1024 <= client_used_quota)

View File

@ -623,7 +623,7 @@ command_result ConnectedClient::handleCommandSendTextMessage(Command &cmd) {
channel_tree_read_lock.lock();
}
auto conversation_mode = channel->properties()[property::CHANNEL_CONVERSATION_MODE].as<ChannelConversationMode>();
auto conversation_mode = channel->properties()[property::CHANNEL_CONVERSATION_MODE].as_unchecked<ChannelConversationMode>();
if(conversation_mode == ChannelConversationMode::CHANNELCONVERSATIONMODE_NONE) {
return command_result{error::conversation_not_exists};
} else if(channel != this->currentChannel) {
@ -1618,7 +1618,8 @@ command_result ConnectedClient::handleCommandTokenDelete(Command &cmd) {
this->server->getTokenManager().delete_token(token->id);
if(token->token == this->server->properties()[property::VIRTUALSERVER_AUTOGENERATED_PRIVILEGEKEY].as<string>()) {
if(token->token ==
this->server->properties()[property::VIRTUALSERVER_AUTOGENERATED_PRIVILEGEKEY].as_unchecked<string>()) {
this->server->properties()[property::VIRTUALSERVER_AUTOGENERATED_PRIVILEGEKEY] = "";
this->server->properties()[property::VIRTUALSERVER_ASK_FOR_PRIVILEGEKEY] = false;
logMessage(this->getServerId(), "{} Deleting the default server token. Don't ask anymore for this a token!", CLIENT_STR_LOG_PREFIX);
@ -1677,10 +1678,10 @@ command_result ConnectedClient::handleCommandWhoAmI(Command &cmd) {
if (this->server) {
result["virtualserver_status"] = ServerState::string(this->getServer()->state);
result["virtualserver_id"] = this->server->getServerId();
result["virtualserver_unique_identifier"] = this->server->properties()[property::VIRTUALSERVER_UNIQUE_IDENTIFIER].as<string>();
result["virtualserver_unique_identifier"] = this->server->properties()[property::VIRTUALSERVER_UNIQUE_IDENTIFIER].as_unchecked<string>();
result["virtualserver_port"] = 0;
if (this->server->udpVoiceServer) {
result["virtualserver_port"] = this->server->properties()[property::VIRTUALSERVER_PORT].as_save<uint16_t>();
result["virtualserver_port"] = this->server->properties()[property::VIRTUALSERVER_PORT].as_or<uint16_t>(0);
}
} else {
result["virtualserver_status"] = "template";
@ -1693,7 +1694,7 @@ command_result ConnectedClient::handleCommandWhoAmI(Command &cmd) {
result["client_channel_id"] = this->currentChannel ? this->currentChannel->channelId() : 0;
result["client_nickname"] = this->getDisplayName();
result["client_database_id"] = this->getClientDatabaseId();
result["client_login_name"] = this->properties()[property::CLIENT_LOGIN_NAME].as<string>();
result["client_login_name"] = this->properties()[property::CLIENT_LOGIN_NAME].as_unchecked<string>();
result["client_unique_identifier"] = this->getUid();
{
@ -3063,7 +3064,7 @@ command_result ConnectedClient::handleCommandConversationHistory(ts::Command &co
if(!channel)
return command_result{error::conversation_invalid_id};
auto conversation_mode = channel->channel()->properties()[property::CHANNEL_CONVERSATION_MODE].as<ChannelConversationMode>();
auto conversation_mode = channel->channel()->properties()[property::CHANNEL_CONVERSATION_MODE].as_unchecked<ChannelConversationMode>();
switch (conversation_mode) {
case ChannelConversationMode::CHANNELCONVERSATIONMODE_PRIVATE:
return command_result{error::conversation_is_private};
@ -3193,7 +3194,7 @@ command_result ConnectedClient::handleCommandConversationFetch(ts::Command &cmd)
continue;
}
auto conversation_mode = channel->channel()->properties()[property::CHANNEL_CONVERSATION_MODE].as<ChannelConversationMode>();
auto conversation_mode = channel->channel()->properties()[property::CHANNEL_CONVERSATION_MODE].as_unchecked<ChannelConversationMode>();
switch (conversation_mode) {
case ChannelConversationMode::CHANNELCONVERSATIONMODE_PRIVATE: {
auto error = findError("conversation_is_private");

View File

@ -212,7 +212,7 @@ command_result ConnectedClient::handleCommandServerEdit(Command &cmd) {
continue;
}
auto property = target_server ? target_server->properties()[info] : (*serverInstance->getDefaultServerProperties())[info];
auto property = target_server ? target_server->properties()[info] : serverInstance->getDefaultServerProperties()[info];
if(property.value() == elm.second)
continue;
auto old_value = property.value();
@ -252,11 +252,15 @@ command_result ConnectedClient::handleCommandServerRequestConnectionInfo(Command
first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BANDWIDTH_SENT, minute_report.file_bytes_sent);
first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BANDWIDTH_RECEIVED, minute_report.file_bytes_received);
first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL, this->server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED].as<string>());
first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL, this->server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_UPLOADED].as<string>());
first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BYTES_SENT_TOTAL,
this->server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_DOWNLOADED].as_unchecked<string>());
first_bulk.put_unchecked(property::CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL,
this->server->properties()[property::VIRTUALSERVER_TOTAL_BYTES_UPLOADED].as_unchecked<string>());
first_bulk.put_unchecked("connection_filetransfer_bytes_sent_month", this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED].as<string>());
first_bulk.put_unchecked("connection_filetransfer_bytes_received_month", this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED].as<string>());
first_bulk.put_unchecked("connection_filetransfer_bytes_sent_month",
this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_DOWNLOADED].as_unchecked<string>());
first_bulk.put_unchecked("connection_filetransfer_bytes_received_month",
this->server->properties()[property::VIRTUALSERVER_MONTH_BYTES_UPLOADED].as_unchecked<string>());
first_bulk.put_unchecked(property::CONNECTION_PACKETS_SENT_TOTAL, std::accumulate(total_stats.connection_packets_sent.begin(), total_stats.connection_packets_sent.end(), (size_t) 0U));
first_bulk.put_unchecked(property::CONNECTION_BYTES_SENT_TOTAL, std::accumulate(total_stats.connection_bytes_sent.begin(), total_stats.connection_bytes_sent.end(), (size_t) 0U));
@ -268,7 +272,8 @@ command_result ConnectedClient::handleCommandServerRequestConnectionInfo(Command
first_bulk.put_unchecked(property::CONNECTION_BANDWIDTH_RECEIVED_LAST_SECOND_TOTAL, std::accumulate(second_report.connection_bytes_received.begin(), second_report.connection_bytes_received.end(), (size_t) 0U));
first_bulk.put_unchecked(property::CONNECTION_BANDWIDTH_RECEIVED_LAST_MINUTE_TOTAL, std::accumulate(minute_report.connection_bytes_received.begin(), minute_report.connection_bytes_received.end(), (size_t) 0U));
first_bulk.put_unchecked(property::CONNECTION_CONNECTED_TIME, this->server->properties()[property::VIRTUALSERVER_UPTIME].as<string>());
first_bulk.put_unchecked(property::CONNECTION_CONNECTED_TIME,
this->server->properties()[property::VIRTUALSERVER_UPTIME].as_unchecked<string>());
first_bulk.put_unchecked(property::CONNECTION_PACKETLOSS_TOTAL, network_report.average_loss);
first_bulk.put_unchecked(property::CONNECTION_PING, network_report.average_ping);

View File

@ -121,7 +121,7 @@ void MusicClient::initialize_bot() {
if(!this->properties()->has(property::CLIENT_COUNTRY) || this->properties()[property::CLIENT_COUNTRY].value().empty())
this->properties()[property::CLIENT_COUNTRY] = config::geo::countryFlag;
if(this->properties()[property::CLIENT_UPTIME_MODE].as<MusicClient::UptimeMode::value>() == MusicClient::UptimeMode::TIME_SINCE_SERVER_START) {
if(this->properties()[property::CLIENT_UPTIME_MODE].as_unchecked<MusicClient::UptimeMode::value>() == MusicClient::UptimeMode::TIME_SINCE_SERVER_START) {
this->properties()[property::CLIENT_LASTCONNECTED] = duration_cast<seconds>(this->server->start_timestamp().time_since_epoch()).count();
} else {
this->properties()[property::CLIENT_LASTCONNECTED] = this->properties()[property::CLIENT_CREATED].value();

View File

@ -92,7 +92,7 @@ void MusicClient::replay_song(const shared_ptr<music::PlayableSong> &entry, cons
});
self->changePlayerState(ReplayState::PAUSED);
if(self->properties()[property::CLIENT_FLAG_NOTIFY_SONG_CHANGE].as<bool>()) {
if(self->properties()[property::CLIENT_FLAG_NOTIFY_SONG_CHANGE].as_unchecked<bool>()) {
string invoker = "unknown";
{
auto info_list = serverInstance->databaseHelper()->queryDatabaseInfo(self->getServer(), {entry->getInvoker()});
@ -185,7 +185,7 @@ void MusicClient::playMusic() {
auto self = dynamic_pointer_cast<MusicClient>(this->ref());
ts::music::MusicBotManager::tick_music.execute([self]{
auto playlist = self->playlist();
if(playlist->properties()[property::PLAYLIST_FLAG_FINISHED].as<bool>()) {
if(playlist->properties()[property::PLAYLIST_FLAG_FINISHED].as_unchecked<bool>()) {
playlist->properties()[property::PLAYLIST_FLAG_FINISHED] = false;
debugMessage(self->getServerId(), "{} Received play, but playlist had finished. Restarting playlist.", CLIENT_STR_LOG_PREFIX_(self));
}
@ -226,7 +226,7 @@ void MusicClient::forwardSong() {
this->handle_event_song_ended();
/* explicitly wanted a "next" song so start over again */
if(playlist->properties()[property::PLAYLIST_FLAG_FINISHED].as<bool>()) {
if(playlist->properties()[property::PLAYLIST_FLAG_FINISHED].as_unchecked<bool>()) {
playlist->properties()[property::PLAYLIST_FLAG_FINISHED] = false;
this->handle_event_song_ended();
}

View File

@ -215,7 +215,8 @@ command_result QueryClient::handleCommandLogin(Command& cmd) {
if(!this->whitelisted) {
this->handle->client_connect_count[this->getPeerIp()]++;
if(this->handle->client_connect_count[this->getPeerIp()] > 3) {
this->handle->client_connect_bans[this->getPeerIp()] = system_clock::now() + seconds(serverInstance->properties()[property::SERVERINSTANCE_SERVERQUERY_BAN_TIME].as<uint64_t>()); //TODO configurable | Disconnect all others?
this->handle->client_connect_bans[this->getPeerIp()] = system_clock::now() + seconds(
serverInstance->properties()[property::SERVERINSTANCE_SERVERQUERY_BAN_TIME].as_unchecked<uint64_t>()); //TODO configurable | Disconnect all others?
this->postCommandHandler.emplace_back([&](){
this->close_connection(system_clock::now() + seconds(1));
});
@ -227,7 +228,7 @@ command_result QueryClient::handleCommandLogin(Command& cmd) {
return command_result{error::client_invalid_password, "username or password dose not match"};
}
}
if(!this->properties()[property::CLIENT_LOGIN_NAME].as<string>().empty()) {
if(!this->properties()[property::CLIENT_LOGIN_NAME].as_unchecked<string>().empty()) {
Command log("logout");
auto result = this->handleCommandLogout(log);
if(result.has_error()) {
@ -296,7 +297,7 @@ command_result QueryClient::handleCommandLogin(Command& cmd) {
this->task_update_needed_permissions.enqueue();
}
this->properties()[property::CLIENT_TOTALCONNECTIONS]++;
this->properties()[property::CLIENT_TOTALCONNECTIONS].increment_by<uint64_t>(1);
this->task_update_channel_client_properties.enqueue();
serverInstance->action_logger()->query_authenticate_logger.log_query_authenticate(this->getServerId(), std::dynamic_pointer_cast<QueryClient>(this->ref()), username, log::QueryAuthenticateResult::SUCCESS);
@ -305,7 +306,7 @@ command_result QueryClient::handleCommandLogin(Command& cmd) {
command_result QueryClient::handleCommandLogout(Command &) {
CMD_RESET_IDLE;
if(this->properties()[property::CLIENT_LOGIN_NAME].as<string>().empty()) return command_result{error::client_not_logged_in};
if(this->properties()[property::CLIENT_LOGIN_NAME].as_unchecked<string>().empty()) return command_result{error::client_not_logged_in};
this->properties()[property::CLIENT_LOGIN_NAME] = "";
this->query_account = nullptr;
@ -458,10 +459,11 @@ command_result QueryClient::handleCommandServerInfo(Command &) {
Command cmd("");
for(const auto &prop : (this->server ? this->server->properties() : *serverInstance->getDefaultServerProperties()).list_properties(property::FLAG_SERVER_VIEW | property::FLAG_SERVER_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) {
cmd[prop.type().name] = prop.as<string>();
auto properties = this->server ? this->server->properties() : serverInstance->getDefaultServerProperties();
for(const auto &prop : properties->list_properties(property::FLAG_SERVER_VIEW | property::FLAG_SERVER_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) {
cmd[prop.type().name] = prop.as_unchecked<string>();
if(prop.type() == property::VIRTUALSERVER_HOST)
cmd["virtualserver_ip"] = prop.as<string>();
cmd["virtualserver_ip"] = prop.as_unchecked<string>();
}
cmd["virtualserver_status"] = this->server ? ServerState::string(this->server->state) : "template";
@ -551,32 +553,42 @@ command_result QueryClient::handleCommandChannelList(Command& cmd) {
const auto channel_clients = this->server ? this->server->getClientsByChannel(channel).size() : 0;
result.put_unchecked(index, "cid", channel->channelId());
result.put_unchecked(index, "pid", channel->properties()[property::CHANNEL_PID].as<string>());
result.put_unchecked(index, "pid", channel->properties()[property::CHANNEL_PID].as_unchecked<string>());
result.put_unchecked(index, "channel_name", channel->name());
result.put_unchecked(index, "channel_order", channel->channelOrder());
result.put_unchecked(index, "total_clients", channel_clients);
/* result.put_unchecked(index, "channel_needed_subscribe_power", channel->permissions()->getPermissionValue(permission::i_channel_needed_subscribe_power, channel, 0)); */
if(cmd.hasParm("flags")){
result.put_unchecked(index, "channel_flag_default", channel->properties()[property::CHANNEL_FLAG_DEFAULT].as<string>());
result.put_unchecked(index, "channel_flag_password", channel->properties()[property::CHANNEL_FLAG_PASSWORD].as<string>());
result.put_unchecked(index, "channel_flag_permanent", channel->properties()[property::CHANNEL_FLAG_PERMANENT].as<string>());
result.put_unchecked(index, "channel_flag_semi_permanent", channel->properties()[property::CHANNEL_FLAG_SEMI_PERMANENT].as<string>());
result.put_unchecked(index, "channel_flag_default",
channel->properties()[property::CHANNEL_FLAG_DEFAULT].as_unchecked<string>());
result.put_unchecked(index, "channel_flag_password",
channel->properties()[property::CHANNEL_FLAG_PASSWORD].as_unchecked<string>());
result.put_unchecked(index, "channel_flag_permanent",
channel->properties()[property::CHANNEL_FLAG_PERMANENT].as_unchecked<string>());
result.put_unchecked(index, "channel_flag_semi_permanent",
channel->properties()[property::CHANNEL_FLAG_SEMI_PERMANENT].as_unchecked<string>());
}
if(cmd.hasParm("voice")){
result.put_unchecked(index, "channel_codec", channel->properties()[property::CHANNEL_CODEC].as<string>());
result.put_unchecked(index, "channel_codec_quality", channel->properties()[property::CHANNEL_CODEC_QUALITY].as<string>());
result.put_unchecked(index, "channel_needed_talk_power", channel->properties()[property::CHANNEL_NEEDED_TALK_POWER].as<string>());
result.put_unchecked(index, "channel_codec",
channel->properties()[property::CHANNEL_CODEC].as_unchecked<string>());
result.put_unchecked(index, "channel_codec_quality",
channel->properties()[property::CHANNEL_CODEC_QUALITY].as_unchecked<string>());
result.put_unchecked(index, "channel_needed_talk_power",
channel->properties()[property::CHANNEL_NEEDED_TALK_POWER].as_unchecked<string>());
}
if(cmd.hasParm("icon")){
result.put_unchecked(index, "channel_icon_id", channel->properties()[property::CHANNEL_ICON_ID].as<string>());
result.put_unchecked(index, "channel_icon_id",
channel->properties()[property::CHANNEL_ICON_ID].as_unchecked<string>());
}
if(cmd.hasParm("limits")){
result.put_unchecked(index, "total_clients_family", this->server ? this->server->getClientsByChannelRoot(channel, false).size() : 0);
result.put_unchecked(index, "total_clients", this->server ? this->server->getClientsByChannel(channel).size() : 0);
result.put_unchecked(index, "channel_maxclients", channel->properties()[property::CHANNEL_MAXCLIENTS].as<string>());
result.put_unchecked(index, "channel_maxfamilyclients", channel->properties()[property::CHANNEL_MAXFAMILYCLIENTS].as<string>());
result.put_unchecked(index, "channel_maxclients",
channel->properties()[property::CHANNEL_MAXCLIENTS].as_unchecked<string>());
result.put_unchecked(index, "channel_maxfamilyclients",
channel->properties()[property::CHANNEL_MAXFAMILYCLIENTS].as_unchecked<string>());
{
auto needed_power = channel->permissions()->permission_value_flagged(permission::i_channel_subscribe_power);
@ -584,7 +596,8 @@ command_result QueryClient::handleCommandChannelList(Command& cmd) {
}
}
if(cmd.hasParm("topic")) {
result.put_unchecked(index, "channel_topic", channel->properties()[property::CHANNEL_TOPIC].as<string>());
result.put_unchecked(index, "channel_topic",
channel->properties()[property::CHANNEL_TOPIC].as_unchecked<string>());
}
if(cmd.hasParm("times") || cmd.hasParm("secondsempty")){
result.put_unchecked(index, "seconds_empty", channel_clients == 0 ? channel->emptySince() : 0);
@ -606,23 +619,34 @@ command_result QueryClient::handleCommandServerList(Command& cmd) {
size_t index = 0;
for(const auto& server : serverInstance->getVoiceServerManager()->serverInstances()) {
result.put_unchecked(index, "virtualserver_id", server->getServerId());
result.put_unchecked(index, "virtualserver_host", server->properties()[property::VIRTUALSERVER_HOST].as<string>());
result.put_unchecked(index, "virtualserver_port", server->properties()[property::VIRTUALSERVER_PORT].as<string>());
result.put_unchecked(index, "virtualserver_web_host", server->properties()[property::VIRTUALSERVER_WEB_HOST].as<string>());
result.put_unchecked(index, "virtualserver_web_port", server->properties()[property::VIRTUALSERVER_WEB_PORT].as<string>());
result.put_unchecked(index, "virtualserver_host",
server->properties()[property::VIRTUALSERVER_HOST].as_unchecked<string>());
result.put_unchecked(index, "virtualserver_port",
server->properties()[property::VIRTUALSERVER_PORT].as_unchecked<string>());
result.put_unchecked(index, "virtualserver_web_host",
server->properties()[property::VIRTUALSERVER_WEB_HOST].as_unchecked<string>());
result.put_unchecked(index, "virtualserver_web_port",
server->properties()[property::VIRTUALSERVER_WEB_PORT].as_unchecked<string>());
result.put_unchecked(index, "virtualserver_status", ServerState::string(server->state));
result.put_unchecked(index, "virtualserver_clientsonline", server->properties()[property::VIRTUALSERVER_CLIENTS_ONLINE].as<string>());
result.put_unchecked(index, "virtualserver_queryclientsonline", server->properties()[property::VIRTUALSERVER_QUERYCLIENTS_ONLINE].as<string>());
result.put_unchecked(index, "virtualserver_maxclients", server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as<string>());
result.put_unchecked(index, "virtualserver_clientsonline",
server->properties()[property::VIRTUALSERVER_CLIENTS_ONLINE].as_unchecked<string>());
result.put_unchecked(index, "virtualserver_queryclientsonline",
server->properties()[property::VIRTUALSERVER_QUERYCLIENTS_ONLINE].as_unchecked<string>());
result.put_unchecked(index, "virtualserver_maxclients",
server->properties()[property::VIRTUALSERVER_MAXCLIENTS].as_unchecked<string>());
if(server->startTimestamp.time_since_epoch().count() > 0 && server->state == ServerState::ONLINE)
result.put_unchecked(index, "virtualserver_uptime", duration_cast<seconds>(system_clock::now() - server->startTimestamp).count());
else
result.put_unchecked(index, "virtualserver_uptime", 0);
result.put_unchecked(index, "virtualserver_name", server->properties()[property::VIRTUALSERVER_NAME].as<string>());
result.put_unchecked(index, "virtualserver_autostart", server->properties()[property::VIRTUALSERVER_AUTOSTART].as<string>());
result.put_unchecked(index, "virtualserver_machine_id", server->properties()[property::VIRTUALSERVER_MACHINE_ID].as<string>());
result.put_unchecked(index, "virtualserver_name",
server->properties()[property::VIRTUALSERVER_NAME].as_unchecked<string>());
result.put_unchecked(index, "virtualserver_autostart",
server->properties()[property::VIRTUALSERVER_AUTOSTART].as_unchecked<string>());
result.put_unchecked(index, "virtualserver_machine_id",
server->properties()[property::VIRTUALSERVER_MACHINE_ID].as_unchecked<string>());
if(cmd.hasParm("uid"))
result.put_unchecked(index, "virtualserver_unique_identifier", server->properties()[property::VIRTUALSERVER_UNIQUE_IDENTIFIER].as<string>());
result.put_unchecked(index, "virtualserver_unique_identifier",
server->properties()[property::VIRTUALSERVER_UNIQUE_IDENTIFIER].as_unchecked<string>());
else result.put_unchecked(index, "virtualserver_unique_identifier", "");
index++;
}
@ -702,7 +726,7 @@ command_result QueryClient::handleCommandServerCreate(Command& cmd) {
Command res("");
res["sid"] = server->getServerId();
res["error"] = startError;
res["virtualserver_port"] = server->properties()[property::VIRTUALSERVER_PORT].as<string>();
res["virtualserver_port"] = server->properties()[property::VIRTUALSERVER_PORT].as_unchecked<string>();
res["token"] = tokens.empty() ? "unknown" : tokens[0]->token;
res["time_create"] = time_create.count();
res["time_start"] = time_start.count();
@ -790,8 +814,8 @@ command_result QueryClient::handleCommandInstanceInfo(Command& cmd) {
ACTION_REQUIRES_INSTANCE_PERMISSION(permission::b_serverinstance_info_view, 1);
Command res("");
for(const auto& e : serverInstance->properties().list_properties(property::FLAG_INSTANCE_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0))
res[e.type().name] = e.as<string>();
for(const auto& e : serverInstance->properties()->list_properties(property::FLAG_INSTANCE_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0))
res[e.type().name] = e.value();
if(!this->properties()[property::CLIENT_LOGIN_NAME].value().empty())
res["serverinstance_teaspeak"] = true;
res["serverinstance_serverquery_max_connections_per_ip"] = res["serverinstance_query_max_connections_per_ip"].as<std::string>();

View File

@ -183,7 +183,7 @@ size_t WhisperHandler::max_whisper_targets() {
return false;
}
auto result = server->properties()[property::VIRTUALSERVER_MIN_CLIENTS_IN_CHANNEL_BEFORE_FORCED_SILENCE].as_save<size_t>([]{ return kMaxWhisperTargets; });
auto result = server->properties()[property::VIRTUALSERVER_MIN_CLIENTS_IN_CHANNEL_BEFORE_FORCED_SILENCE].as_or<size_t>(kMaxWhisperTargets);
if(result > kMaxWhisperTargets) {
result = kMaxWhisperTargets;
}
@ -273,7 +273,7 @@ ts::command_result WhisperHandler::initialize_session_new(uint32_t stream_id, ui
target_clients.push_back(speaking_client);
}
} else if (type == WhisperType::CHANNEL_COMMANDER) {
if (speaking_client->properties()[property::CLIENT_IS_CHANNEL_COMMANDER].as_save<bool>([] { return false; })) {
if (speaking_client->properties()[property::CLIENT_IS_CHANNEL_COMMANDER].as_or<bool>(false)) {
target_clients.push_back(speaking_client);
}
} else {

View File

@ -98,7 +98,7 @@ command_result VoiceClient::handleCommandClientInit(Command &cmd) {
return command_result{error::client_could_not_validate_identity};
}
auto requiredLevel = this->getServer()->properties()[property::VIRTUALSERVER_NEEDED_IDENTITY_SECURITY_LEVEL].as<uint8_t>();
auto requiredLevel = this->getServer()->properties()[property::VIRTUALSERVER_NEEDED_IDENTITY_SECURITY_LEVEL].as_unchecked<uint8_t>();
if(security_level < requiredLevel) {
return command_result{error::client_could_not_validate_identity, to_string(requiredLevel)};
}

View File

@ -1395,7 +1395,7 @@ void ConversationManager::synchronize_channels() {
continue;
}
auto history_size = schannel->properties()[property::CHANNEL_CONVERSATION_HISTORY_LENGTH].as<size_t>();
auto history_size = schannel->properties()[property::CHANNEL_CONVERSATION_HISTORY_LENGTH].as_unchecked<size_t>();
channel->set_history_length(history_size);
}
}

View File

@ -203,7 +203,7 @@ void MusicBotManager::load_bots() {
size_t disabled_bots = 0;
for(const auto& bot : this->music_bots) {
if(bot_limit >= 1) {
if(!bot->properties()[property::CLIENT_DISABLED].as<bool>())
if(!bot->properties()[property::CLIENT_DISABLED].as_unchecked<bool>())
bot_limit--;
} else {
//TODO log message

View File

@ -13,7 +13,7 @@ using namespace ts::music;
using namespace std;
using namespace std::chrono;
Playlist::Playlist(const std::shared_ptr<ts::music::MusicBotManager> &manager, std::shared_ptr<ts::Properties> properties, std::shared_ptr<permission::v2::PermissionManager> permissions) :
Playlist::Playlist(const std::shared_ptr<ts::music::MusicBotManager> &manager, std::shared_ptr<ts::PropertyManager> properties, std::shared_ptr<permission::v2::PermissionManager> permissions) :
PlaylistPermissions{std::move(permissions)}, _properties{std::move(properties)}, manager{manager} { }
Playlist::~Playlist() {

View File

@ -90,7 +90,7 @@ namespace ts {
};
};
Playlist(const std::shared_ptr<MusicBotManager>& /* manager */, std::shared_ptr<Properties> /* properties */, std::shared_ptr<permission::v2::PermissionManager> /* permissions */);
Playlist(const std::shared_ptr<MusicBotManager>& /* manager */, std::shared_ptr<PropertyManager> /* properties */, std::shared_ptr<permission::v2::PermissionManager> /* permissions */);
virtual ~Playlist();
virtual void load_songs();
@ -103,14 +103,14 @@ namespace ts {
virtual bool delete_song(SongId /* song */);
virtual bool reorder_song(SongId /* song */, SongId /* new id */);
inline Properties& properties() const { return *this->_properties; }
inline PropertyManager& properties() const { return *this->_properties; }
inline PlaylistId playlist_id() {
return this->properties()[property::PLAYLIST_ID].as<PlaylistId>();
return this->properties()[property::PLAYLIST_ID].as_unchecked<PlaylistId>();
}
inline Type::value playlist_type() {
return this->properties()[property::PLAYLIST_TYPE].as<Type::value>();
return this->properties()[property::PLAYLIST_TYPE].as_unchecked<Type::value>();
}
inline int32_t max_songs() {
@ -128,10 +128,11 @@ namespace ts {
bool is_subscriber(const std::shared_ptr<server::ConnectedClient>&);
protected:
virtual void set_self_ref(const std::shared_ptr<Playlist>& /* playlist */);
[[nodiscard]] bool is_playlist_owner(ClientDbId database_id) const override { return this->properties()[property::PLAYLIST_OWNER_DBID].as_save<ClientDbId>() == database_id; }
[[nodiscard]] bool is_playlist_owner(ClientDbId database_id) const override { return
this->properties()[property::PLAYLIST_OWNER_DBID].as_or<ClientDbId>(0) == database_id; }
std::atomic<SongId> current_id;
std::shared_ptr<Properties> _properties;
std::shared_ptr<PropertyManager> _properties;
std::weak_ptr<MusicBotManager> manager;
std::weak_ptr<Playlist> _self;
bool _songs_loaded = false;

View File

@ -11,7 +11,7 @@ using namespace ts::music;
using namespace std;
using namespace std::chrono;
PlayablePlaylist::PlayablePlaylist(const std::shared_ptr<MusicBotManager> &handle, const std::shared_ptr<Properties> &props, const std::shared_ptr<permission::v2::PermissionManager>& perms) : Playlist(handle, props, perms) { }
PlayablePlaylist::PlayablePlaylist(const std::shared_ptr<MusicBotManager> &handle, const std::shared_ptr<PropertyManager> &props, const std::shared_ptr<permission::v2::PermissionManager>& perms) : Playlist(handle, props, perms) { }
PlayablePlaylist::~PlayablePlaylist() {}
@ -19,7 +19,7 @@ void PlayablePlaylist::load_songs() {
Playlist::load_songs();
unique_lock playlist_lock(this->playlist_mutex);
auto song_id = this->properties()[property::PLAYLIST_CURRENT_SONG_ID].as_save<SongId>();
auto song_id = this->properties()[property::PLAYLIST_CURRENT_SONG_ID].as_or<SongId>(0);
auto current_song = this->playlist_find(playlist_lock, song_id);
if(!current_song && song_id != 0) {
logWarning(this->get_server_id(), "[Playlist] Failed to reinitialize current song index for playlist {}. Song {} is missing.", this->playlist_id(), song_id);
@ -60,7 +60,7 @@ std::shared_ptr<ts::music::PlayableSong> PlayablePlaylist::current_song(bool& aw
auto entry = this->current_loading_entry.lock();
auto id = entry ? entry->song_id : 0;
if(this->properties()[property::PLAYLIST_CURRENT_SONG_ID].as<SongId>() != id) /* should not happen */
if(this->properties()[property::PLAYLIST_CURRENT_SONG_ID].as_unchecked<SongId>() != id) /* should not happen */
this->properties()[property::PLAYLIST_CURRENT_SONG_ID] = id;
if(!entry)
@ -111,7 +111,7 @@ std::shared_ptr<ts::music::PlayableSong> PlayablePlaylist::current_song(bool& aw
std::shared_ptr<PlaylistEntryInfo> PlayablePlaylist::playlist_next_entry() {
if(!this->playlist_head) return nullptr; /* fuzzy check if we're not empty */
auto replay_mode = this->properties()[property::PLAYLIST_REPLAY_MODE].as<ReplayMode::value>();
auto replay_mode = this->properties()[property::PLAYLIST_REPLAY_MODE].as_unchecked<ReplayMode::value>();
unique_lock playlist_lock(this->playlist_mutex);
auto old_song = this->playlist_find(playlist_lock, this->currently_playing());
@ -155,7 +155,7 @@ std::shared_ptr<PlaylistEntryInfo> PlayablePlaylist::playlist_next_entry() {
}
}
playlist_lock.unlock();
if(old_song && this->properties()[property::PLAYLIST_FLAG_DELETE_PLAYED].as<bool>()) {
if(old_song && this->properties()[property::PLAYLIST_FLAG_DELETE_PLAYED].as_unchecked<bool>()) {
this->delete_song(old_song->entry->song_id);
}
return result;
@ -163,7 +163,7 @@ std::shared_ptr<PlaylistEntryInfo> PlayablePlaylist::playlist_next_entry() {
std::shared_ptr<PlaylistEntryInfo> PlayablePlaylist::playlist_previous_entry() {
if(!this->playlist_head) return nullptr; /* fuzzy check if we're not empty */
auto replay_mode = this->properties()[property::PLAYLIST_REPLAY_MODE].as<ReplayMode::value>();
auto replay_mode = this->properties()[property::PLAYLIST_REPLAY_MODE].as_unchecked<ReplayMode::value>();
unique_lock playlist_lock(this->playlist_mutex);
this->properties()[property::PLAYLIST_FLAG_FINISHED] = false;
@ -200,7 +200,7 @@ bool PlayablePlaylist::set_current_song(SongId song_id) {
if(current_song) {
this->enqueue_load(current_song->entry);
auto id = current_song ? current_song->entry->song_id : 0;
if(this->properties()[property::PLAYLIST_CURRENT_SONG_ID].as<SongId>() != id)
if(this->properties()[property::PLAYLIST_CURRENT_SONG_ID].as_unchecked<SongId>() != id)
this->properties()[property::PLAYLIST_CURRENT_SONG_ID] = id;
}
}

View File

@ -24,12 +24,12 @@ namespace ts {
SHUFFLE
};
};
PlayablePlaylist(const std::shared_ptr<MusicBotManager>& /* manager */, const std::shared_ptr<Properties>& /* properties */, const std::shared_ptr<permission::v2::PermissionManager>& /* permissions */);
PlayablePlaylist(const std::shared_ptr<MusicBotManager>& /* manager */, const std::shared_ptr<PropertyManager>& /* properties */, const std::shared_ptr<permission::v2::PermissionManager>& /* permissions */);
virtual ~PlayablePlaylist();
void load_songs() override;
inline ReplayMode::value replay_mode() { return this->properties()[property::PLAYLIST_REPLAY_MODE].as<ReplayMode::value>(); }
inline ReplayMode::value replay_mode() { return this->properties()[property::PLAYLIST_REPLAY_MODE].as_unchecked<ReplayMode::value>(); }
inline void set_replay_mode(ReplayMode::value mode) { this->properties()[property::PLAYLIST_REPLAY_MODE] = mode; }
inline SongId currently_playing() { return this->properties()[property::PLAYLIST_CURRENT_SONG_ID]; }

View File

@ -406,7 +406,7 @@ void QueryServer::on_client_receive(int server_file_descriptor, short, void *) {
{
unique_lock lock{this->connected_clients_mutex};
auto max_connections = serverInstance->properties()[property::SERVERINSTANCE_QUERY_MAX_CONNECTIONS].as<size_t>();
auto max_connections = serverInstance->properties()[property::SERVERINSTANCE_QUERY_MAX_CONNECTIONS].as_unchecked<size_t>();
if(max_connections > 0 && max_connections <= this->connected_clients.size()) {
lock.unlock();
logMessage(LOG_QUERY, "[{}] Dropping new query connection attempt because of too many connected query clients.", logging_address(remote_address));
@ -415,7 +415,7 @@ void QueryServer::on_client_receive(int server_file_descriptor, short, void *) {
return;
}
auto max_ip_connections = serverInstance->properties()[property::SERVERINSTANCE_QUERY_MAX_CONNECTIONS_PER_IP].as<size_t>();
auto max_ip_connections = serverInstance->properties()[property::SERVERINSTANCE_QUERY_MAX_CONNECTIONS_PER_IP].as_unchecked<size_t>();
if(max_ip_connections > 0) {
size_t connection_count = 0;
for(auto& client : this->connected_clients) {

View File

@ -8,7 +8,7 @@
namespace ts::server::snapshots {
struct channel_entry {
Properties properties{};
PropertyManager properties{};
};
class channel_parser : public parser<channel_entry> {

View File

@ -35,7 +35,7 @@ VirtualServerManager::SnapshotDeployResult VirtualServerManager::deploy_snapshot
}
std::string server_host{server ? server->properties()[property::VIRTUALSERVER_HOST].value() : config::binding::DefaultVoiceHost};
uint16_t server_port{server ? server->properties()[property::VIRTUALSERVER_PORT].as<uint16_t>() : this->next_available_port(server_host)};
uint16_t server_port{server ? server->properties()[property::VIRTUALSERVER_PORT].as_unchecked<uint16_t>() : this->next_available_port(server_host)};
this->delete_server_in_db(kSnapshotServerId, false);
auto result = sql::command{this->handle->getSql(), "INSERT INTO `servers` (`serverId`, `host`, `port`) VALUES (:sid, :host, :port)"}
.value(":sid", kSnapshotServerId)
@ -206,7 +206,7 @@ bool VirtualServerManager::try_deploy_snapshot(std::string &error, ts::ServerId
/* Update channel parents and order id */
for(auto& channel : snapshot_data.parsed_channels) {
{
auto pid = channel.properties[property::CHANNEL_PID].as<ChannelId>();
auto pid = channel.properties[property::CHANNEL_PID].as_unchecked<ChannelId>();
if(pid > 0) {
auto new_id = mappings.channel_id.find(pid);
if(new_id == mappings.channel_id.end()) {
@ -218,7 +218,7 @@ bool VirtualServerManager::try_deploy_snapshot(std::string &error, ts::ServerId
}
{
auto oid = channel.properties[property::CHANNEL_ORDER].as<ChannelId>();
auto oid = channel.properties[property::CHANNEL_ORDER].as_unchecked<ChannelId>();
if(oid > 0) {
auto new_id = mappings.channel_id.find(oid);
if(new_id == mappings.channel_id.end()) {
@ -246,11 +246,11 @@ bool VirtualServerManager::try_deploy_snapshot(std::string &error, ts::ServerId
};
for(auto& channel : snapshot_data.parsed_channels) {
auto channel_id = channel.properties[property::CHANNEL_ID].as<ChannelId>();
auto channel_id = channel.properties[property::CHANNEL_ID].as_unchecked<ChannelId>();
insert_query.add_entry(
target_server_id,
channel_id,
channel.properties[property::CHANNEL_PID].as<ChannelId>()
channel.properties[property::CHANNEL_PID].as_unchecked<ChannelId>()
);
for(const auto& property : channel.properties.list_properties(property::FLAG_SAVE)) {
@ -585,7 +585,7 @@ bool VirtualServerManager::try_deploy_snapshot(std::string &error, ts::ServerId
auto value = property.value();
switch(property.type().property_index) {
case property::VIRTUALSERVER_DEFAULT_SERVER_GROUP: {
auto new_id = mappings.server_group_id.find(property.as<GroupId>());
auto new_id = mappings.server_group_id.find(property.as_unchecked<GroupId>());
if(new_id == mappings.server_group_id.end()) {
logWarning(logging_server_id, "Missing server group mapping for group {}. {} will reference an invalid group.", property.value(), property.type().name);
break;
@ -597,7 +597,7 @@ bool VirtualServerManager::try_deploy_snapshot(std::string &error, ts::ServerId
case property::VIRTUALSERVER_DEFAULT_CHANNEL_ADMIN_GROUP:
case property::VIRTUALSERVER_DEFAULT_CHANNEL_GROUP: {
auto new_id = mappings.channel_group_id.find(property.as<GroupId>());
auto new_id = mappings.channel_group_id.find(property.as_unchecked<GroupId>());
if(new_id == mappings.channel_group_id.end()) {
logWarning(logging_server_id, "Missing channel group mapping for group {}. {} will reference an invalid group.", property.value(), property.type().name);
break;
@ -796,7 +796,7 @@ bool VirtualServerManager::try_deploy_snapshot(std::string &error, ts::ServerId
auto value = property.value();
if(property.type() == property::CLIENT_LAST_CHANNEL) {
auto channel_id = property.as<ChannelId>();
auto channel_id = property.as_unchecked<ChannelId>();
auto new_channel_id = mappings.channel_id.find(channel_id);
if(new_channel_id == mappings.channel_id.end()) {

View File

@ -13,12 +13,12 @@ namespace ts::server::snapshots {
std::string unique_id{};
ClientDbId bot_owner_id{};
Properties properties{};
PropertyManager properties{};
};
struct playlist_entry {
PlaylistId playlist_id{0};
Properties properties{};
PropertyManager properties{};
};
struct playlist_song_entry {

View File

@ -8,7 +8,7 @@
namespace ts::server::snapshots {
struct server_entry {
Properties properties{};
PropertyManager properties{};
};
class server_parser : public parser<server_entry> {

2
shared

@ -1 +1 @@
Subproject commit b26132fa5498a1966bb11bbf9d1ee6bb32f39863
Subproject commit 26981b95f70ed4418be0a0e1720eaa7c7fc0a76a