From 1686ce095f2c103ba398679dcf91af9fd1fa0473 Mon Sep 17 00:00:00 2001 From: WolverinDEV Date: Sun, 4 Oct 2020 15:04:25 +0200 Subject: [PATCH] Updated the property list command and added a channel description only mode --- package.json | 8 ++ server/main.cpp | 76 +++++++++++++++++++ server/src/VirtualServer.cpp | 10 ++- server/src/client/command_handler/channel.cpp | 26 ++++++- server/src/client/command_handler/misc.cpp | 67 ++++++++++++---- server/src/manager/SqlDataManager.cpp | 38 +++++++++- shared | 2 +- 7 files changed, 207 insertions(+), 20 deletions(-) create mode 100644 package.json diff --git a/package.json b/package.json new file mode 100644 index 0000000..0a18a55 --- /dev/null +++ b/package.json @@ -0,0 +1,8 @@ +{ + "name": "TeaSpeak", + "version": "1.0.0", + "dependencies": { + "@types/node": "^14.11.2", + "yaml": "^1.10.0" + } +} diff --git a/server/main.cpp b/server/main.cpp index 81d0c9d..402d7ae 100644 --- a/server/main.cpp +++ b/server/main.cpp @@ -114,6 +114,82 @@ int main(int argc, char** argv) { (void*) malloc_conf; #endif +#if 0 + { + //ts::property::list() + std::cout << "| Name | Type | Flags | Default Value | Description | \n"; + std::cout << "|:-- | -- | -- | -- |:-- | \n"; + for(const auto& property : ts::property::list()) { + std::cout << "| `" << property->name << "` | "; + + switch(property->type_value) { + case ts::property::TYPE_STRING: + std::cout << "String | "; + break; + + case ts::property::TYPE_BOOL: + std::cout << "Boolean | "; + break; + + case ts::property::TYPE_SIGNED_NUMBER: + std::cout << "Signed number | "; + break; + + case ts::property::TYPE_UNSIGNED_NUMBER: + std::cout << "Unsigned number | "; + break; + + case ts::property::TYPE_FLOAT: + std::cout << "Float | "; + break; + + default: + std::cout << "Unknown | "; + break; + } + + std::string flags{}; + if(property->flags & ts::property::FLAG_INTERNAL) { flags += ", internal"; } + if(property->flags & ts::property::FLAG_GLOBAL) { flags += ", global"; } + + if(property->flags & ts::property::FLAG_SNAPSHOT) { flags += ", snapshot"; } + if(property->flags & ts::property::FLAG_SAVE) { flags += ", saved"; } + if(property->flags & ts::property::FLAG_SAVE_MUSIC) { flags += ", saved (music)"; } + + if(property->flags & ts::property::FLAG_NEW) { flags += ", new"; } + if(property->flags & ts::property::FLAG_SERVER_VARIABLE) { flags += ", server variable"; } + if(property->flags & ts::property::FLAG_SERVER_VIEW) { flags += ", server view variable"; } + + if(property->flags & ts::property::FLAG_CLIENT_VARIABLE) { flags += ", client variable"; } + if(property->flags & ts::property::FLAG_CLIENT_VIEW) { flags += ", client view variable"; } + if(property->flags & ts::property::FLAG_CLIENT_INFO) { flags += ", client info variable"; } + + if(property->flags & ts::property::FLAG_CHANNEL_VARIABLE) { flags += ", channel variable"; } + if(property->flags & ts::property::FLAG_CHANNEL_VIEW) { flags += ", channel view variable"; } + + // FLAG_GROUP_VIEW = FLAG_CHANNEL_VIEW << 1UL, + if(property->flags & ts::property::FLAG_INSTANCE_VARIABLE) { flags += ", instance variable"; } + if(property->flags & ts::property::FLAG_PLAYLIST_VARIABLE) { flags += ", playlist variable"; } + if(property->flags & ts::property::FLAG_USER_EDITABLE) { flags += ", editable"; } + + if(!flags.empty()) { + std::cout << flags.substr(2); + } + std::cout << "| "; + if(property->default_value.empty()) { + std::cout << "empty"; + } else { + std::cout << "`" << property->default_value << "` "; + } + std::cout << "| "; + std::cout << "No description "; + std::cout << "| "; + std::cout << " \n"; + } + return 0; + } +#endif + CLIParser arguments(argc, argv); SSL_load_error_strings(); OpenSSL_add_ssl_algorithms(); diff --git a/server/src/VirtualServer.cpp b/server/src/VirtualServer.cpp index 8084382..b0747e5 100644 --- a/server/src/VirtualServer.cpp +++ b/server/src/VirtualServer.cpp @@ -1263,7 +1263,15 @@ void VirtualServer::send_text_message(const std::shared_ptr &chann auto channel_id = channel->channelId(); auto now = chrono::system_clock::now(); - bool conversation_private = channel->properties()[property::CHANNEL_FLAG_CONVERSATION_PRIVATE].as(); + bool conversation_private; + auto conversation_mode = channel->properties()[property::CHANNEL_CONVERSATION_MODE].as(); + if(conversation_mode == ChannelConversationMode::CHANNELCONVERSATIONMODE_NONE) { + /* nothing to do */ + return; + } else { + conversation_private = conversation_mode == ChannelConversationMode::CHANNELCONVERSATIONMODE_PRIVATE; + } + auto flag_password = channel->properties()[property::CHANNEL_FLAG_PASSWORD].as(); for(const auto& client : this->getClients()) { if(client->connectionState() != ConnectionState::CONNECTED) diff --git a/server/src/client/command_handler/channel.cpp b/server/src/client/command_handler/channel.cpp index b360457..2cc5dc2 100644 --- a/server/src/client/command_handler/channel.cpp +++ b/server/src/client/command_handler/channel.cpp @@ -1078,7 +1078,31 @@ command_result ConnectedClient::handleCommandChannelEdit(Command &cmd) { ACTION_REQUIRES_PERMISSION(permission::i_channel_create_modify_conversation_history_length, 1, channel_id); } } else if (key == "channel_flag_conversation_private") { - ACTION_REQUIRES_PERMISSION(permission::b_channel_create_modify_conversation_private, 1, channel_id); + auto value = cmd["channel_flag_conversation_private"].as(); + if(value) { + ACTION_REQUIRES_PERMISSION(permission::b_channel_create_modify_conversation_mode_private, 1, channel_id); + cmd[property::name(property::CHANNEL_CONVERSATION_MODE)] = CHANNELCONVERSATIONMODE_PRIVATE; + } else { + ACTION_REQUIRES_PERMISSION(permission::b_channel_create_modify_conversation_mode_public, 1, channel_id); + cmd[property::name(property::CHANNEL_CONVERSATION_MODE)] = CHANNELCONVERSATIONMODE_PUBLIC; + } + keys.push_back(&property::describe(property::CHANNEL_CONVERSATION_MODE)); + continue; + } else if (key == "channel_conversation_mode") { + auto value = cmd["channel_conversation_mode"].as(); + switch (value) { + case ChannelConversationMode::CHANNELCONVERSATIONMODE_PRIVATE: + ACTION_REQUIRES_PERMISSION(permission::b_channel_create_modify_conversation_mode_private, 1, channel_id); + break; + case ChannelConversationMode::CHANNELCONVERSATIONMODE_PUBLIC: + ACTION_REQUIRES_PERMISSION(permission::b_channel_create_modify_conversation_mode_public, 1, channel_id); + break; + case ChannelConversationMode::CHANNELCONVERSATIONMODE_NONE: + ACTION_REQUIRES_PERMISSION(permission::b_channel_create_modify_conversation_mode_none, 1, channel_id); + break; + default: + return command_result{error::parameter_invalid, "channel_conversation_mode"}; + } } else { logCritical( this->getServerId(), diff --git a/server/src/client/command_handler/misc.cpp b/server/src/client/command_handler/misc.cpp index fc1199a..eb7674e 100644 --- a/server/src/client/command_handler/misc.cpp +++ b/server/src/client/command_handler/misc.cpp @@ -397,6 +397,8 @@ do { \ response[index]["name"] = prop->name; \ response[index]["flags"] = prop->flags; \ response[index]["type"] = property::PropertyType_Names[prop->type_property]; \ + response[index]["value"] = prop->default_value; \ + response[index]["value_type"] = property::ValueType_Names[(int) prop->type_value]; \ index++; \ } \ } while(0) @@ -406,8 +408,11 @@ command_result ConnectedClient::handleCommandPropertyList(ts::Command& cmd) { { string pattern; - for (auto flag_name : property::flag_names) - pattern = flag_name + string("|") + pattern; + for (auto flag_name : property::flag_names) { + if(flag_name) { + pattern = flag_name + string("|") + pattern; + } + } pattern = pattern.substr(0, pattern.length() - 1); response["flag_set"] = pattern; } @@ -425,6 +430,8 @@ command_result ConnectedClient::handleCommandPropertyList(ts::Command& cmd) { M(property::GroupProperties); if(cmd.hasParm("all") || cmd.hasParm("connection")) M(property::ConnectionProperties); + if(cmd.hasParm("all") || cmd.hasParm("playlist")) + M(property::PlaylistProperties); this->sendCommand(response); return command_result{error::ok}; @@ -579,8 +586,10 @@ command_result ConnectedClient::handleCommandSendTextMessage(Command &cmd) { target->notifyTextMessage(ChatMessageMode::TEXTMODE_PRIVATE, _this.lock(), target->getClientId(), 0, timestamp, cmd["msg"].string()); this->notifyTextMessage(ChatMessageMode::TEXTMODE_PRIVATE, _this.lock(), target->getClientId(), 0, timestamp, cmd["msg"].string()); } else if (cmd["targetmode"] == ChatMessageMode::TEXTMODE_CHANNEL) { - if(!cmd[0].has("cid")) + if(!cmd[0].has("cid")) { cmd["cid"] = 0; + } + RESOLVE_CHANNEL_R(cmd["cid"], false); auto channel = l_channel ? dynamic_pointer_cast(l_channel->entry) : nullptr; if(!channel) { @@ -594,18 +603,23 @@ command_result ConnectedClient::handleCommandSendTextMessage(Command &cmd) { if(channel == this->currentChannel) { channel_tree_read_lock.unlock(); //Method may creates a music bot which modifies the channel tree - if(this->handleTextMessage(ChatMessageMode::TEXTMODE_CHANNEL, cmd["msg"], nullptr)) + if(this->handleTextMessage(ChatMessageMode::TEXTMODE_CHANNEL, cmd["msg"], nullptr)) { return command_result{error::ok}; + } channel_tree_read_lock.lock(); } - bool conversation_private = channel->properties()[property::CHANNEL_FLAG_CONVERSATION_PRIVATE].as(); - if(channel != this->currentChannel) { - if(conversation_private) + auto conversation_mode = channel->properties()[property::CHANNEL_CONVERSATION_MODE].as(); + if(conversation_mode == ChannelConversationMode::CHANNELCONVERSATIONMODE_NONE) { + return command_result{error::conversation_not_exists}; + } else if(channel != this->currentChannel) { + if(conversation_mode == ChannelConversationMode::CHANNELCONVERSATIONMODE_PRIVATE) { return command_result{error::conversation_is_private}; + } - if(auto fail_perm{this->calculate_and_get_join_state(channel)}; fail_perm != permission::ok) + if(auto fail_perm{this->calculate_and_get_join_state(channel)}; fail_perm != permission::ok) { return command_result{fail_perm}; /* You're not allowed to send messages :) */ + } } this->server->send_text_message(channel, this->ref(), cmd["msg"].string()); @@ -2547,8 +2561,17 @@ command_result ConnectedClient::handleCommandConversationHistory(ts::Command &co if(!channel) return command_result{error::conversation_invalid_id}; - if(channel->channel()->properties()[property::CHANNEL_FLAG_CONVERSATION_PRIVATE].as()) - return command_result{error::conversation_is_private}; + auto conversation_mode = channel->channel()->properties()[property::CHANNEL_CONVERSATION_MODE].as(); + switch (conversation_mode) { + case ChannelConversationMode::CHANNELCONVERSATIONMODE_PRIVATE: + return command_result{error::conversation_is_private}; + + case ChannelConversationMode::CHANNELCONVERSATIONMODE_NONE: + return command_result{error::conversation_not_exists}; + + case ChannelConversationMode::CHANNELCONVERSATIONMODE_PUBLIC: + break; + } } /* test if there is a channel password or join power which denies that we see the conversation */ @@ -2667,11 +2690,25 @@ command_result ConnectedClient::handleCommandConversationFetch(ts::Command &cmd) result_bulk["error_msg"] = error.message; continue; } - if(channel->channel()->properties()[property::CHANNEL_FLAG_CONVERSATION_PRIVATE].as()) { - auto error = findError("conversation_is_private"); - result_bulk["error_id"] = error.errorId; - result_bulk["error_msg"] = error.message; - continue; + + auto conversation_mode = channel->channel()->properties()[property::CHANNEL_CONVERSATION_MODE].as(); + switch (conversation_mode) { + case ChannelConversationMode::CHANNELCONVERSATIONMODE_PRIVATE: { + auto error = findError("conversation_is_private"); + result_bulk["error_id"] = error.errorId; + result_bulk["error_msg"] = error.message; + continue; + } + + case ChannelConversationMode::CHANNELCONVERSATIONMODE_NONE: { + auto error = findError("conversation_not_exists"); + result_bulk["error_id"] = error.errorId; + result_bulk["error_msg"] = error.message; + continue; + } + + case ChannelConversationMode::CHANNELCONVERSATIONMODE_PUBLIC: + break; } } diff --git a/server/src/manager/SqlDataManager.cpp b/server/src/manager/SqlDataManager.cpp index 7995d8c..482a720 100644 --- a/server/src/manager/SqlDataManager.cpp +++ b/server/src/manager/SqlDataManager.cpp @@ -44,8 +44,8 @@ if(!result && result.msg().find(ignore) == string::npos){ #define RESIZE_COLUMN(tblName, rowName, size) up vote EXECUTE("Could not change column size", "ALTER TABLE " tblName " ALTER COLUMN " rowName " varchar(" size ")"); -#define CURRENT_DATABASE_VERSION 15 -#define CURRENT_PERMISSION_VERSION 4 +#define CURRENT_DATABASE_VERSION 16 +#define CURRENT_PERMISSION_VERSION 5 #define CLIENT_UID_LENGTH "64" #define CLIENT_NAME_LENGTH "128" @@ -556,6 +556,17 @@ bool SqlDataManager::update_database(std::string &error) { db_version(15); } + case 15: { + constexpr static std::array kUpdateCommands{ + "UPDATE `properties` SET `key` = 'channel_conversation_mode' WHERE `key` = 'channel_flag_conversation_private';", + }; + + if(!execute_commands(this->sql(), error, kUpdateCommands)) + return false; + + db_version(16); + } + default: break; } @@ -720,6 +731,29 @@ bool SqlDataManager::update_permissions(std::string &error) { return false; perm_version(4); + + case 4: + if(!auto_update(permission::update::QUERY_ADMIN, "b_channel_create_modify_conversation_mode_private", {1, true}, false, false, {100, true})) + return false; + if(!auto_update(permission::update::QUERY_ADMIN, "b_channel_create_modify_conversation_mode_private", {1, true}, false, false, {75, true})) + return false; + if(!auto_update(permission::update::CHANNEL_ADMIN, "b_channel_create_modify_conversation_mode_private", {1, true}, false, false, {0, false})) + return false; + + if(!auto_update(permission::update::QUERY_ADMIN, "b_channel_create_modify_conversation_mode_public", {1, true}, false, false, {100, true})) + return false; + if(!auto_update(permission::update::QUERY_ADMIN, "b_channel_create_modify_conversation_mode_public", {1, true}, false, false, {75, true})) + return false; + if(!auto_update(permission::update::CHANNEL_ADMIN, "b_channel_create_modify_conversation_mode_public", {1, true}, false, false, {0, false})) + return false; + + if(!auto_update(permission::update::QUERY_ADMIN, "b_channel_create_modify_conversation_mode_none", {1, true}, false, false, {100, true})) + return false; + if(!auto_update(permission::update::QUERY_ADMIN, "b_channel_create_modify_conversation_mode_none", {1, true}, false, false, {75, true})) + return false; + if(!auto_update(permission::update::CHANNEL_ADMIN, "b_channel_create_modify_conversation_mode_none", {1, true}, false, false, {0, false})) + return false; + perm_version(5); default: break; } diff --git a/shared b/shared index 0a960e4..f5c6431 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit 0a960e414811bae5081b45219aad97f6cff5c512 +Subproject commit f5c643129e306132437e8b529c2398e9cfc0545a