Some updates

This commit is contained in:
WolverinDEV 2020-04-28 18:27:49 +02:00
parent 633fe10821
commit ff88705f09
15 changed files with 120 additions and 79 deletions

@ -1 +1 @@
Subproject commit 603ed73a7a706ba831cfca5149ad877d5a6e7dc5
Subproject commit ac7d6a0a1ee75aa6a9e77382c9a010f3827327ba

View File

@ -57,7 +57,7 @@ bool VirtualServer::initialize(bool test_properties) {
this->_voice_encryption_mode = prop.as<int>();
return;
}
std::string sql;
std::string sql{};
if(prop.type() == property::VIRTUALSERVER_HOST)
sql = "UPDATE `servers` SET `host` = :value WHERE `serverId` = :sid";
else if(prop.type() == property::VIRTUALSERVER_PORT)
@ -141,7 +141,7 @@ bool VirtualServer::initialize(bool test_properties) {
channelTree->loadChannelsFromDatabase();
if(channelTree->channel_count() == 0){
logCritical(this->serverId, "Failed to setup channel tree!");
return 0;
return false;
}
if(!channelTree->getDefaultChannel()) {
logError(this->serverId, "Missing default channel! Using first one!");

View File

@ -477,6 +477,7 @@ if(!result) { \
execute_delete("DELETE FROM `channels` WHERE `serverId` = :sid");
execute_delete("DELETE FROM `bannedClients` WHERE `serverId` = :sid");
execute_delete("DELETE FROM `ban_trigger` WHERE `server_id` = :sid");
execute_delete("DELETE FROM `groups` WHERE `serverId` = :sid");
execute_delete("DELETE FROM `assignedGroups` WHERE `serverId` = :sid");
execute_delete("DELETE FROM `servers` WHERE `serverId` = :sid");

View File

@ -571,27 +571,66 @@ bool ConnectedClient::notifyClientNeededPermissions() {
return true;
}
inline void write_command_result_error(ts::command_builder_bulk bulk, const command_result& result) {
bulk.put_unchecked("id", (uint32_t) result.error_code());
bulk.put_unchecked("msg", findError(result.error_code()).message);
if(result.is_permission_error())
bulk.put_unchecked("failed_permid", (uint32_t) result.permission_id());
}
inline void write_command_result_detailed(ts::command_builder_bulk bulk, const command_result& result) {
auto details = result.details();
bulk.put_unchecked("id", (uint32_t) details->error_id);
bulk.put_unchecked("msg", findError(details->error_id).message);
for(const auto& extra : details->extra_properties)
bulk.put(extra.first, extra.second);
}
bool ConnectedClient::notifyError(const command_result& result, const std::string& retCode) {
Command cmd("error");
ts::command_builder command{"error"};
if(result.is_detailed()) {
auto detailed = result.details();
cmd["id"] = (int) detailed->error_id;
cmd["msg"] = findError(detailed->error_id).message;
switch(result.type()) {
case command_result_type::error:
write_command_result_error(command.bulk(0), result);
break;
case command_result_type::detailed:
write_command_result_detailed(command.bulk(0), result);
break;
for(const auto& extra : detailed->extra_properties)
cmd[extra.first] = extra.second;
} else {
cmd["id"] = (int) result.error_code();
cmd["msg"] = findError(result.error_code()).message;
if(result.is_permission_error())
cmd["failed_permid"] = result.permission_id();
case command_result_type::bulked: {
auto bulks = result.bulks();
command.reserve_bulks(bulks->size());
for(size_t index{0}; index < bulks->size(); index++) {
auto entry = bulks->at(index);
switch (entry.type()) {
case command_result_type::error:
write_command_result_error(command.bulk(index), entry);
break;
case command_result_type::detailed:
write_command_result_detailed(command.bulk(index), entry);
break;
case command_result_type::bulked:
assert(false);
break;
}
}
if(bulks->empty()) {
logWarning(this->getServerId(), "{} Trying to send empty error bulk.", CLIENT_STR_LOG_PREFIX_(this));
command.put_unchecked(0, "id", (uint32_t) error::ok);
command.put_unchecked(0, "msg", findError(error::ok).message);
}
break;
}
default:
assert(false);
break;
}
if(retCode.length() > 0)
cmd["return_code"] = retCode;
if(!retCode.empty())
command.put_unchecked(0, "return_code", retCode);
this->sendCommand(cmd);
this->sendCommand(command);
return true;
}
@ -793,7 +832,7 @@ bool ConnectedClient::handleCommandFull(Command& cmd, bool disconnectOnFail) {
this->disconnect("Invalid argument (" + string(ex.what()) + ")");
return false;
} else {
result = command_result{error::parameter_convert};
result = command_result{error::parameter_convert, ex.what()};
}
} catch (exception& ex) {
logWarning(this->getServerId(), "{}[Command] Failed to handle command. Received exception with message: {}", CLIENT_STR_LOG_PREFIX, ex.what());
@ -809,7 +848,7 @@ bool ConnectedClient::handleCommandFull(Command& cmd, bool disconnectOnFail) {
}
bool generateReturnStatus = false;
if(result.error_code() != error::ok || this->getType() == ClientType::CLIENT_QUERY){
if(result.has_error() || this->getType() == ClientType::CLIENT_QUERY){
generateReturnStatus = true;
} else if(cmd["return_code"].size() > 0) {
generateReturnStatus = !cmd["return_code"].string().empty();
@ -818,7 +857,7 @@ bool ConnectedClient::handleCommandFull(Command& cmd, bool disconnectOnFail) {
if(generateReturnStatus)
this->notifyError(result, cmd["return_code"].size() > 0 ? cmd["return_code"].first().as<std::string>() : "");
if(result.error_code() != error::ok && this->state == ConnectionState::INIT_HIGH)
if(result.has_error() && this->state == ConnectionState::INIT_HIGH)
this->close_connection(system_clock::now()); //Disconnect now
for (const auto& handler : postCommandHandler)
@ -832,7 +871,7 @@ bool ConnectedClient::handleCommandFull(Command& cmd, bool disconnectOnFail) {
else
logWarning(this->getServerId(), "Command handling of command {} needs {}ms.", cmd.command(), duration_cast<milliseconds>(end - start).count());
}
result.release_details();
result.release_data();
return true;
}

View File

@ -158,8 +158,8 @@ bool ConnectedClient::handle_text_command(
if (TARG(0, "create")) {
Command cmd("");
auto result = this->handleCommandMusicBotCreate(cmd);
if(result.error_code()) {
result.release_details();
if(result.has_error()) {
result.release_data();
HANDLE_CMD_ERROR("Failed to create music bot");
return true;
}
@ -220,9 +220,9 @@ bool ConnectedClient::handle_text_command(
Command cmd("");
cmd["client_nickname"] = ss.str();
auto result = this->handleCommandClientEdit(cmd, bot);
if(result.error_code()) {
if(result.has_error()) {
HANDLE_CMD_ERROR("Failed to rename bot");
result.release_details();
result.release_data();
return true;
}
send_message(serverInstance->musicRoot(), "Name successfully changed!");
@ -508,9 +508,9 @@ bool ConnectedClient::handle_text_command(
JOIN_ARGS(value, 3);
cmd[arguments[2]] = value;
auto result = this->handleCommandClientEdit(cmd, bot);
if(result.error_code()) {
if(result.has_error()) {
HANDLE_CMD_ERROR("Failed to change bot property");
result.release_details();
result.release_data();
return true;
}
send_message(serverInstance->musicRoot(), "Property successfully changed!");

View File

@ -723,7 +723,7 @@ void SpeakingClient::processJoin() {
if(!ref_server->assignDefaultChannel(this->ref(), false)) {
auto result = command_result{error::vs_critical, "Could not assign default channel!"};
this->notifyError(result);
result.release_details();
result.release_data();
this->close_connection(system_clock::now() + seconds(1));
return;
}
@ -865,7 +865,7 @@ command_result SpeakingClient::handleCommand(Command &command) {
else
result = command_result{error::client_not_logged_in};
if(result.error_code())
if(result.has_error())
this->postCommandHandler.push_back([&]{
this->close_connection(system_clock::now() + seconds(1));
});

View File

@ -1593,7 +1593,7 @@ command_result ConnectedClient::handleCommandChannelDelPerm(Command &cmd) {
for (int index = 0; index < cmd.bulkCount(); index++) {
PARSE_PERMISSION(cmd);
if(!permission::v2::permission_granted(0, this->calculate_permission(permType, channel_id, true))) {
if(!ignore_granted_values && !permission::v2::permission_granted(0, this->calculate_permission(permType, channel_id, true))) {
if(conOnError) continue;
return command_result{permission::i_permission_modify_power};
}

View File

@ -62,11 +62,13 @@ command_result ConnectedClient::handleCommandClientKick(Command &cmd) {
CMD_REQ_SERVER;
CMD_CHK_AND_INC_FLOOD_POINTS(25);
command_result_bulk result{};
result.reserve(cmd.bulkCount());
std::vector<ConnectedLockedClient<ConnectedClient>> clients{};
clients.reserve(cmd.bulkCount());
auto type = cmd["reasonid"].as<ViewReasonId>();
auto single_client = cmd.bulkCount() == 1;
auto target_channel = type == ViewReasonId::VREASON_CHANNEL_KICK ? this->server->channelTree->getDefaultChannel() : nullptr;
auto kick_power = type == ViewReasonId::VREASON_CHANNEL_KICK ?
this->calculate_permission(permission::i_client_kick_from_channel_power, target_channel->channelId()) :
@ -76,31 +78,28 @@ command_result ConnectedClient::handleCommandClientKick(Command &cmd) {
ConnectedLockedClient<ConnectedClient> client{this->server->find_client_by_id(cmd[index]["clid"].as<ClientId>())};
if (!client) {
if(single_client)
return command_result{error::client_invalid_id};
result.emplace_result(error::client_invalid_id);
continue;
}
if (client->getType() == CLIENT_MUSIC) {
if(single_client)
return command_result{error::client_invalid_type};
result.emplace_result(error::client_invalid_type);
continue;
}
if(type == ViewReasonId::VREASON_CHANNEL_KICK) {
if(!permission::v2::permission_granted(client->calculate_permission(permission::i_client_needed_kick_from_channel_power, client->getChannelId()), kick_power)) {
if(single_client)
return command_result{permission::i_client_needed_kick_from_channel_power};
result.emplace_result(permission::i_client_needed_kick_from_channel_power);
continue;
}
} else {
if(!permission::v2::permission_granted(client->calculate_permission(permission::i_client_needed_kick_from_server_power, client->getChannelId()), kick_power)) {
if(single_client)
return command_result{permission::i_client_needed_kick_from_server_power};
result.emplace_result(permission::i_client_needed_kick_from_server_power);
continue;
}
}
clients.emplace_back(std::move(client));
result.emplace_result(error::ok);
}
if (clients.empty())
return command_result{error::database_empty_result};
@ -114,7 +113,7 @@ command_result ConnectedClient::handleCommandClientKick(Command &cmd) {
}
}
return command_result{error::ok};
return command_result{std::forward<command_result_bulk>(result)};
}
command_result ConnectedClient::handleCommandClientGetIds(Command &cmd) {
@ -177,37 +176,35 @@ command_result ConnectedClient::handleCommandClientMove(Command &cmd) {
auto permission_error = this->calculate_and_get_join_state(channel);
if(permission_error != permission::unknown) return command_result{permission_error};
command_result_bulk result{};
result.reserve(cmd.bulkCount());
std::vector<ConnectedLockedClient<ConnectedClient>> clients{};
auto is_single_client = cmd.bulkCount() == 1;
for(size_t index{0}; index < cmd.bulkCount(); index++) {
auto target_client_id = cmd[index]["clid"].as<ClientId>();
ConnectedLockedClient target_client{target_client_id == 0 ? this->ref() : this->server->find_client_by_id(target_client_id)};
if(!target_client) {
if(is_single_client)
return command_result{error::client_invalid_id};
result.emplace_result(error::client_invalid_id);
continue;
}
if(!target_client->getChannel()) {
if(target_client.client != this) {
if(is_single_client)
return command_result{error::client_invalid_id};
result.emplace_result(error::client_invalid_id);
continue;
}
}
if(target_client.client != this) {
if(!permission::v2::permission_granted(target_client->calculate_permission(permission::i_client_needed_move_power, 0), this->calculate_permission(permission::i_client_move_power, 0))) {
if(is_single_client)
return command_result{permission::i_client_move_power};
result.emplace_result(permission::i_client_move_power);
continue;
}
}
clients.emplace_back(std::move(target_client));
result.emplace_result(permission::ok);
}
if(clients.empty())
return command_result{error::database_empty_result};
if (!channel->properties()[property::CHANNEL_FLAG_MAXCLIENTS_UNLIMITED].as<bool>() || !channel->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_UNLIMITED].as<bool>()) {
if(!permission::v2::permission_granted(1, this->calculate_permission(permission::b_channel_join_ignore_maxclients, channel->channelId()))) {
@ -257,7 +254,7 @@ command_result ConnectedClient::handleCommandClientMove(Command &cmd) {
channels.push_back(oldChannel);
}
for(auto oldChannel : channels) {
for(const auto& oldChannel : channels) {
if(!server_channel_w_lock.owns_lock())
server_channel_w_lock.lock();
if(oldChannel->channelType() == ChannelType::temporary && oldChannel->properties()[property::CHANNEL_DELETE_DELAY].as<int64_t>() == 0)
@ -266,7 +263,7 @@ command_result ConnectedClient::handleCommandClientMove(Command &cmd) {
if(server_channel_w_lock.owns_lock())
server_channel_w_lock.unlock();
}
return command_result{error::ok};
return command_result{std::forward<command_result_bulk>(result)};
}
command_result ConnectedClient::handleCommandClientPoke(Command &cmd) {
@ -274,42 +271,45 @@ command_result ConnectedClient::handleCommandClientPoke(Command &cmd) {
CMD_RESET_IDLE;
CMD_CHK_AND_INC_FLOOD_POINTS(25);
command_result_bulk result{};
result.reserve(cmd.bulkCount());
std::vector<ConnectedLockedClient<ConnectedClient>> clients{};
clients.reserve(cmd.bulkCount());
bool is_single_poke = cmd.bulkCount() == 1;
for(size_t index{0}; index < cmd.bulkCount(); index++) {
ConnectedLockedClient client{ this->server->find_client_by_id(cmd["clid"].as<ClientId>())};
ConnectedLockedClient client{ this->server->find_client_by_id(cmd[index]["clid"].as<ClientId>())};
if (!client) {
if(is_single_poke)
return command_result{error::client_invalid_id};
result.emplace_result(error::client_invalid_id);
continue;
}
if (client->getType() == CLIENT_MUSIC) {
if(is_single_poke)
return command_result{error::client_invalid_type};
result.emplace_result(error::client_invalid_type);
continue;
}
auto own_permission = this->calculate_permission(permission::i_client_poke_power, client->getChannelId());
if(!permission::v2::permission_granted(client->calculate_permission(permission::i_client_needed_poke_power, client->getChannelId()), own_permission)) {
if(is_single_poke)
return command_result{permission::i_client_poke_power};
result.emplace_result(permission::i_client_poke_power);
continue;
}
clients.push_back(std::move(client));
result.emplace_result(error::ok);
}
if(clients.empty())
return command_result{error::database_empty_result};
else if(clients.size() > 1) {
/* clients might be empty ;) */
if(clients.size() > 1) {
auto max_clients = this->calculate_permission(permission::i_client_poke_max_clients, 0);
if(!permission::v2::permission_granted(clients.size(), max_clients))
return command_result{permission::i_client_poke_max_clients};
}
for(auto& client : clients)
client->notifyClientPoke(_this.lock(), cmd["msg"]);
return command_result{error::ok};
return command_result{std::forward<command_result_bulk>(result)};
}

View File

@ -150,6 +150,8 @@ inline bool permission_require_granted_value(ts::permission::PermissionType type
case permission::i_max_playlist_size:
case permission::i_max_playlists:
case permission::i_client_poke_max_clients:
case permission::i_client_ban_max_bantime:
case permission::i_client_max_idletime:
case permission::i_group_sort_id:

View File

@ -284,7 +284,6 @@ command_result ConnectedClient::handleCommandServerRequestConnectionInfo(Command
first_bulk.put_unchecked(property::CONNECTION_PACKETS_RECEIVED_TOTAL, std::accumulate(total_stats.connection_packets_received.begin(), total_stats.connection_packets_received.end(), 0U));
first_bulk.put_unchecked(property::CONNECTION_BYTES_RECEIVED_TOTAL, std::accumulate(total_stats.connection_bytes_received.begin(), total_stats.connection_bytes_received.end(), 0U));
first_bulk.put_unchecked(property::CONNECTION_BANDWIDTH_SENT_LAST_SECOND_TOTAL, std::accumulate(second_report.connection_bytes_sent.begin(), second_report.connection_bytes_sent.end(), 0U));
first_bulk.put_unchecked(property::CONNECTION_BANDWIDTH_SENT_LAST_MINUTE_TOTAL, std::accumulate(minute_report.connection_bytes_sent.begin(), minute_report.connection_bytes_sent.end(), 0U));
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(), 0U));
@ -895,7 +894,7 @@ command_result ConnectedClient::handleCommandServerGroupDelPerm(Command &cmd) {
for (int index = 0; index < cmd.bulkCount(); index++) {
PARSE_PERMISSION(cmd);
if(!permission::v2::permission_granted(0, this->calculate_permission(permType, 0, true))) {
if(!ignore_granted_values && !permission::v2::permission_granted(0, this->calculate_permission(permType, 0, true))) {
if(conOnError) continue;
return command_result{permission::i_permission_modify_power};
}

View File

@ -77,7 +77,7 @@ void QueryClient::postInitialize() {
if(ts::config::query::sslMode == 1 && this->connectionType != ConnectionType::SSL_ENCRIPTED) {
command_result error{error::failed_connection_initialisation, "Please use a SSL encryption!"};
this->notifyError(error);
error.release_details();
error.release_data();
this->disconnect("Please us a SSL encryption for more security.\nThe server denies also all other connections!");
return;
}
@ -519,7 +519,7 @@ bool QueryClient::handleMessage(const pipes::buffer_view& message) {
handle_error:
this->notifyError(error);
error.release_details();
error.release_data();
return false;
}

View File

@ -174,8 +174,8 @@ command_result QueryClient::handleCommandLogin(Command& cmd) {
if(!this->properties()[property::CLIENT_LOGIN_NAME].as<string>().empty()) {
Command log("logout");
auto result = this->handleCommandLogout(log);
if(result.error_code()) {
result.release_details();
if(result.has_error()) {
result.release_data();
logError(this->getServerId(), "Query client failed to login from old login.");
return command_result{error::vs_critical};
}
@ -432,10 +432,10 @@ command_result QueryClient::handleCommandServerInfo(Command &) {
cmd["connection_packets_received_control"] = total_stats.connection_packets_received[stats::ConnectionStatistics::category::COMMAND];
cmd["connection_bytes_received_control"] = total_stats.connection_bytes_received[stats::ConnectionStatistics::category::COMMAND];
cmd["connection_packets_sent_total"] = std::accumulate(report_second.connection_packets_sent.begin(), report_second.connection_packets_sent.end(), 0U);
cmd["connection_bytes_sent_total"] = std::accumulate(report_second.connection_bytes_sent.begin(), report_second.connection_bytes_sent.end(), 0U);
cmd["connection_packets_received_total"] = std::accumulate(report_second.connection_packets_received.begin(), report_second.connection_packets_received.end(), 0U);
cmd["connection_bytes_received_total"] = std::accumulate(report_second.connection_bytes_received.begin(), report_second.connection_bytes_received.end(), 0U);
cmd["connection_packets_sent_total"] = std::accumulate(total_stats.connection_packets_sent.begin(), total_stats.connection_packets_sent.end(), 0U);
cmd["connection_bytes_sent_total"] = std::accumulate(total_stats.connection_bytes_sent.begin(), total_stats.connection_bytes_sent.end(), 0U);
cmd["connection_packets_received_total"] = std::accumulate(total_stats.connection_packets_received.begin(), total_stats.connection_packets_received.end(), 0U);
cmd["connection_bytes_received_total"] = std::accumulate(total_stats.connection_bytes_received.begin(), total_stats.connection_bytes_received.end(), 0U);
} else {
cmd["connection_bandwidth_sent_last_second_total"] = "0";
cmd["connection_bandwidth_sent_last_minute_total"] = "0";

View File

@ -30,16 +30,16 @@ void VoiceClient::handlePacketCommand(const pipes::buffer_view& command_string)
if(command->command() == "clientek") {
result = this->handleCommandClientEk(*command);
if(result.error_code()) goto handle_error;
if(result.has_error()) goto handle_error;
} else if(command->command() == "clientinitiv") {
result = this->handleCommandClientInitIv(*command);
if(result.error_code()) goto handle_error;
if(result.has_error()) goto handle_error;
} else this->handleCommandFull(*command, true);
return;
handle_error:
this->notifyError(result);
result.release_details();
result.release_data();
}
void VoiceClient::handlePacketPing(const protocol::ClientPacketParser& packet) {

View File

@ -249,7 +249,7 @@ command_result WebClient::handleCommand(Command &command) {
if(this->connectionState() == ConnectionState::INIT_HIGH && this->handshake.state == HandshakeState::SUCCEEDED){
if(command.command() == "clientinit") {
auto result = this->handleCommandClientInit(command);
if(result.error_code())
if(result.has_error())
this->close_connection(system_clock::now() + seconds(1));
return result;
}

2
shared

@ -1 +1 @@
Subproject commit 56e4ca45a9f716099e6d46c53763f701e0331009
Subproject commit ee4c7540f011d17cdac9c170e02c60296ae2487a