First implementation for the conversation system (not 100% finished yet)
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "music/MusicClient.h"
|
||||
#include "query/QueryClient.h"
|
||||
#include "../weblist/WebListManager.h"
|
||||
#include "../manager/ConversationManager.h"
|
||||
#include <experimental/filesystem>
|
||||
#include <cstdint>
|
||||
#include <StringVariable.h>
|
||||
@@ -175,7 +176,7 @@ CommandResult ConnectedClient::handleCommand(Command &cmd) {
|
||||
else if (command == "permissionlist") return this->handleCommandPermissionList(cmd);
|
||||
else if (command == "propertylist") return this->handleCommandPropertyList(cmd);
|
||||
|
||||
//Server group
|
||||
//Server group
|
||||
else if (command == "servergrouplist") return this->handleCommandServerGroupList(cmd);
|
||||
else if (command == "servergroupadd") return this->handleCommandServerGroupAdd(cmd);
|
||||
else if (command == "servergroupcopy") return this->handleCommandServerGroupCopy(cmd);
|
||||
@@ -190,19 +191,19 @@ CommandResult ConnectedClient::handleCommand(Command &cmd) {
|
||||
|
||||
else if (command == "setclientchannelgroup") return this->handleCommandSetClientChannelGroup(cmd);
|
||||
|
||||
//Channel basic actions
|
||||
//Channel basic actions
|
||||
else if (command == "channelcreate") return this->handleCommandChannelCreate(cmd);
|
||||
else if (command == "channelmove") return this->handleCommandChannelMove(cmd);
|
||||
else if (command == "channeledit") return this->handleCommandChannelEdit(cmd);
|
||||
else if (command == "channeldelete") return this->handleCommandChannelDelete(cmd);
|
||||
//Find a channel and get informations
|
||||
//Find a channel and get informations
|
||||
else if (command == "channelfind") return this->handleCommandChannelFind(cmd);
|
||||
else if (command == "channelinfo") return this->handleCommandChannelInfo(cmd);
|
||||
//Channel perm actions
|
||||
//Channel perm actions
|
||||
else if (command == "channelpermlist") return this->handleCommandChannelPermList(cmd);
|
||||
else if (command == "channeladdperm") return this->handleCommandChannelAddPerm(cmd);
|
||||
else if (command == "channeldelperm") return this->handleCommandChannelDelPerm(cmd);
|
||||
//Channel group actions
|
||||
//Channel group actions
|
||||
else if (command == "channelgroupadd") return this->handleCommandChannelGroupAdd(cmd);
|
||||
else if (command == "channelgroupcopy") return this->handleCommandChannelGroupCopy(cmd);
|
||||
else if (command == "channelgrouprename") return this->handleCommandChannelGroupRename(cmd);
|
||||
@@ -212,16 +213,16 @@ CommandResult ConnectedClient::handleCommand(Command &cmd) {
|
||||
else if (command == "channelgrouppermlist") return this->handleCommandChannelGroupPermList(cmd);
|
||||
else if (command == "channelgroupaddperm") return this->handleCommandChannelGroupAddPerm(cmd);
|
||||
else if (command == "channelgroupdelperm") return this->handleCommandChannelGroupDelPerm(cmd);
|
||||
//Channel sub/unsubscribe
|
||||
//Channel sub/unsubscribe
|
||||
else if (command == "channelsubscribe") return this->handleCommandChannelSubscribe(cmd);
|
||||
else if (command == "channelsubscribeall") return this->handleCommandChannelSubscribeAll(cmd);
|
||||
else if (command == "channelunsubscribe") return this->handleCommandChannelUnsubscribe(cmd);
|
||||
else if (command == "channelunsubscribeall") return this->handleCommandChannelUnsubscribeAll(cmd);
|
||||
//manager channel permissions
|
||||
//manager channel permissions
|
||||
else if (command == "channelclientpermlist") return this->handleCommandChannelClientPermList(cmd);
|
||||
else if (command == "channelclientaddperm") return this->handleCommandChannelClientAddPerm(cmd);
|
||||
else if (command == "channelclientdelperm") return this->handleCommandChannelClientDelPerm(cmd);
|
||||
//Client actions
|
||||
//Client actions
|
||||
else if (command == "clientupdate") return this->handleCommandClientUpdate(cmd);
|
||||
else if (command == "clientmove") return this->handleCommandClientMove(cmd);
|
||||
else if (command == "clientgetids") return this->handleCommandClientGetIds(cmd);
|
||||
@@ -237,14 +238,14 @@ CommandResult ConnectedClient::handleCommand(Command &cmd) {
|
||||
else if (command == "clientaddperm") return this->handleCommandClientAddPerm(cmd);
|
||||
else if (command == "clientdelperm") return this->handleCommandClientDelPerm(cmd);
|
||||
else if (command == "clientpermlist") return this->handleCommandClientPermList(cmd);
|
||||
//File transfare
|
||||
//File transfare
|
||||
else if (command == "ftgetfilelist") return this->handleCommandFTGetFileList(cmd);
|
||||
else if (command == "ftcreatedir") return this->handleCommandFTCreateDir(cmd);
|
||||
else if (command == "ftdeletefile") return this->handleCommandFTDeleteFile(cmd);
|
||||
else if (command == "ftinitupload") return this->handleCommandFTInitUpload(cmd);
|
||||
else if (command == "ftinitdownload") return this->handleCommandFTInitDownload(cmd);
|
||||
else if (command == "ftgetfileinfo") return this->handleCommandFTGetFileInfo(cmd);
|
||||
//Banlist
|
||||
//Banlist
|
||||
else if (command == "banlist") return this->handleCommandBanList(cmd);
|
||||
else if (command == "banadd") return this->handleCommandBanAdd(cmd);
|
||||
else if (command == "banedit") return this->handleCommandBanEdit(cmd);
|
||||
@@ -252,13 +253,13 @@ CommandResult ConnectedClient::handleCommand(Command &cmd) {
|
||||
else if (command == "bandel") return this->handleCommandBanDel(cmd);
|
||||
else if (command == "bandelall") return this->handleCommandBanDelAll(cmd);
|
||||
else if (command == "bantriggerlist") return this->handleCommandBanTriggerList(cmd);
|
||||
//Tokens
|
||||
//Tokens
|
||||
else if (command == "tokenlist" || command == "privilegekeylist") return this->handleCommandTokenList(cmd);
|
||||
else if (command == "tokenadd" || command == "privilegekeyadd") return this->handleCommandTokenAdd(cmd);
|
||||
else if (command == "tokenuse" || command == "privilegekeyuse") return this->handleCommandTokenUse(cmd);
|
||||
else if (command == "tokendelete" || command == "privilegekeydelete") return this->handleCommandTokenDelete(cmd);
|
||||
|
||||
//DB stuff
|
||||
//DB stuff
|
||||
else if (command == "clientdblist") return this->handleCommandClientDbList(cmd);
|
||||
else if (command == "clientdbinfo") return this->handleCommandClientDbInfo(cmd);
|
||||
else if (command == "clientdbedit") return this->handleCommandClientDBEdit(cmd);
|
||||
@@ -345,6 +346,8 @@ CommandResult ConnectedClient::handleCommand(Command &cmd) {
|
||||
else if (command == "playlistsongremove") return this->handleCommandPlaylistSongRemove(cmd);
|
||||
|
||||
else if (command == "dummy_ipchange") return this->handleCommandDummy_IpChange(cmd);
|
||||
else if (command == "conversationhistory") return this->handleCommandConversationHistory(cmd);
|
||||
else if (command == "conversationfetch") return this->handleCommandConversationFetch(cmd);
|
||||
|
||||
if (this->getType() == ClientType::CLIENT_QUERY) return CommandResult::NotImplemented; //Dont log query invalid commands
|
||||
if (this->getType() == ClientType::CLIENT_TEAMSPEAK)
|
||||
@@ -1162,8 +1165,8 @@ CommandResult ConnectedClient::handleCommandChannelGroupAddPerm(Command &cmd) {
|
||||
permission::v2::PermissionUpdateType::set_value,
|
||||
permission::v2::PermissionUpdateType::do_nothing,
|
||||
|
||||
cmd[index]["permnegated"].as<bool>() ? 1 : 0,
|
||||
cmd[index]["permskip"].as<bool>() ? 1 : 0
|
||||
cmd[index]["permskip"].as<bool>() ? 1 : 0,
|
||||
cmd[index]["permnegated"].as<bool>() ? 1 : 0
|
||||
);
|
||||
updateList |= permission_is_group_property(permType);
|
||||
}
|
||||
@@ -2328,8 +2331,8 @@ CommandResult ConnectedClient::handleCommandChannelAddPerm(Command &cmd) {
|
||||
permission::v2::PermissionUpdateType::set_value,
|
||||
permission::v2::PermissionUpdateType::do_nothing,
|
||||
|
||||
cmd[index]["permnegated"].as<bool>() ? 1 : 0,
|
||||
cmd[index]["permskip"].as<bool>() ? 1 : 0
|
||||
cmd[index]["permskip"].as<bool>() ? 1 : 0,
|
||||
cmd[index]["permnegated"].as<bool>() ? 1 : 0
|
||||
);
|
||||
updateClients |= permission_is_client_property(permType);
|
||||
update_view |= permType == permission::i_channel_needed_view_power;
|
||||
@@ -2813,8 +2816,8 @@ CommandResult ConnectedClient::handleCommandServerGroupAddPerm(Command &cmd) {
|
||||
permission::v2::PermissionUpdateType::set_value,
|
||||
permission::v2::PermissionUpdateType::do_nothing,
|
||||
|
||||
cmd[index]["permnegated"].as<bool>() ? 1 : 0,
|
||||
cmd[index]["permskip"].as<bool>() ? 1 : 0
|
||||
cmd[index]["permskip"].as<bool>() ? 1 : 0,
|
||||
cmd[index]["permnegated"].as<bool>() ? 1 : 0
|
||||
);
|
||||
sgroupUpdate |= permission_is_group_property(permType);
|
||||
checkTp |= permission_is_client_property(permType);
|
||||
@@ -3210,6 +3213,10 @@ CommandResult ConnectedClient::handleCommandSendTextMessage(Command &cmd) {
|
||||
if(this->handleTextMessage(ChatMessageMode::TEXTMODE_CHANNEL, cmd["msg"], nullptr)) return CommandResult::Success;
|
||||
for (auto &cl : this->server->getClientsByChannel(this->currentChannel))
|
||||
cl->notifyTextMessage(ChatMessageMode::TEXTMODE_CHANNEL, _this.lock(), this->getClientId(), cmd["msg"].string());
|
||||
|
||||
auto conversations = this->server->conversation_manager();
|
||||
auto conversation = conversations->get_or_create(this->currentChannel->channelId());
|
||||
conversation->register_message(this->getClientDatabaseId(), this->getUid(), this->getDisplayName(), cmd["msg"].string());
|
||||
} else if (cmd["targetmode"] == ChatMessageMode::TEXTMODE_SERVER) {
|
||||
CACHED_PERM_CHECK(permission::b_client_server_textmessage_send, 1);
|
||||
|
||||
@@ -7200,7 +7207,189 @@ CommandResult ConnectedClient::handleCommandDummy_IpChange(ts::Command &cmd) {
|
||||
return CommandResult::Success;
|
||||
}
|
||||
|
||||
|
||||
//conversationhistory cid=1 [cpw=xxx] [timestamp_begin] [timestamp_end (0 := no end)] [message_count (default 25| max 100)] [-merge]
|
||||
CommandResult ConnectedClient::handleCommandConversationHistory(ts::Command &command) {
|
||||
CMD_REF_SERVER(ref_server);
|
||||
CMD_CHK_AND_INC_FLOOD_POINTS(25);
|
||||
|
||||
if(!command[0].has("cid") || !command[0]["cid"].castable<ChannelId>())
|
||||
return {findError("conversation_invalid_id")};
|
||||
|
||||
auto conversation_id = command[0]["cid"].as<ChannelId>();
|
||||
/* test if we have access to the conversation */
|
||||
{
|
||||
/* test if we're able to see the channel */
|
||||
{
|
||||
shared_lock channel_view_lock(this->channel_lock);
|
||||
auto channel = this->channel_view()->find_channel(conversation_id);
|
||||
if(!channel)
|
||||
return {findError("conversation_invalid_id")};
|
||||
}
|
||||
|
||||
/* test if there is a channel password or join power which denies that we see the conversation */
|
||||
{
|
||||
shared_lock channel_view_lock(ref_server->channel_tree_lock);
|
||||
auto channel = ref_server->getChannelTree()->findChannel(conversation_id);
|
||||
if(!channel) /* should never happen! */
|
||||
return {findError("conversation_invalid_id")};
|
||||
|
||||
if(!command[0].has("cpw"))
|
||||
command[0]["cpw"] = "";
|
||||
|
||||
if (!channel->passwordMatch(command["cpw"], true))
|
||||
if (!this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_channel_join_ignore_password, 1, channel, true))
|
||||
return {findError("channel_invalid_password"), "invalid password"};
|
||||
|
||||
if(!this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_channel_ignore_join_power, 1, channel, true)) {
|
||||
CHANNEL_PERMISSION_TEST(permission::i_channel_join_power, permission::i_channel_needed_join_power, channel, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto conversation_manager = ref_server->conversation_manager();
|
||||
auto conversation = conversation_manager->get(conversation_id);
|
||||
if(!conversation)
|
||||
return {ErrorType::DBEmpty};
|
||||
|
||||
system_clock::time_point timestamp_begin = system_clock::now();
|
||||
system_clock::time_point timestamp_end;
|
||||
size_t message_count = 25;
|
||||
|
||||
if(command[0].has("timestamp_begin"))
|
||||
timestamp_begin = system_clock::time_point{} + milliseconds(command[0]["timestamp_begin"].as<uint64_t>());
|
||||
|
||||
if(command[0].has("timestamp_end"))
|
||||
timestamp_end = system_clock::time_point{} + milliseconds(command[0]["timestamp_end"].as<uint64_t>());
|
||||
|
||||
if(command[0].has("message_count"))
|
||||
message_count = command[0]["message_count"].as<uint64_t>();
|
||||
|
||||
if(timestamp_begin < timestamp_end)
|
||||
return {findError("parameter_invalid")};
|
||||
if(message_count > 100)
|
||||
message_count = 100;
|
||||
|
||||
auto messages = conversation->message_history(timestamp_begin, message_count + 1, timestamp_end); /* query one more to test for more data */
|
||||
if(messages.empty())
|
||||
return {ErrorType::DBEmpty};
|
||||
bool more_data = messages.size() > message_count;
|
||||
if(more_data)
|
||||
messages.pop_back();
|
||||
|
||||
Command notify(this->notify_response_command("notifyconversationhistory"));
|
||||
size_t index = 0;
|
||||
size_t length = 0;
|
||||
bool merge = command.hasParm("merge");
|
||||
for(auto& message : messages) {
|
||||
if(index == 0)
|
||||
notify[index]["cid"] = conversation_id;
|
||||
|
||||
notify[index]["timestamp"] = duration_cast<milliseconds>(message->message_timestamp.time_since_epoch()).count();
|
||||
notify[index]["sender_database_id"] = message->sender_database_id;
|
||||
notify[index]["sender_unique_id"] = message->sender_unique_id;
|
||||
notify[index]["sender_name"] = message->sender_name;
|
||||
|
||||
notify[index]["msg"] = message->message;
|
||||
length += message->message.size();
|
||||
length += message->sender_name.size();
|
||||
length += message->sender_unique_id.size();
|
||||
if(length > 1024 * 8 || !merge) {
|
||||
index = 0;
|
||||
this->sendCommand(notify);
|
||||
notify = Command{this->notify_response_command("notifyconversationhistory")};
|
||||
} else
|
||||
index++;
|
||||
}
|
||||
if(index > 0)
|
||||
this->sendCommand(notify);
|
||||
|
||||
if(more_data)
|
||||
return {findError("conversation_more_data")};
|
||||
|
||||
return CommandResult::Success;
|
||||
}
|
||||
|
||||
CommandResult ConnectedClient::handleCommandConversationFetch(ts::Command &cmd) {
|
||||
CMD_REF_SERVER(ref_server);
|
||||
CMD_CHK_AND_INC_FLOOD_POINTS(25);
|
||||
|
||||
|
||||
Command result(this->notify_response_command("notifyconversationindex"));
|
||||
size_t result_index = 0;
|
||||
|
||||
auto conversation_manager = ref_server->conversation_manager();
|
||||
for(size_t index = 0; index < cmd.bulkCount(); index++) {
|
||||
auto& bulk = cmd[index];
|
||||
|
||||
if(!bulk.has("cid") || !bulk["cid"].castable<ChannelId>())
|
||||
continue;
|
||||
auto conversation_id = bulk["cid"].as<ChannelId>();
|
||||
|
||||
auto& result_bulk = result[result_index++];
|
||||
result_bulk["cid"] = conversation_id;
|
||||
|
||||
/* test if we have access to the conversation */
|
||||
{
|
||||
/* test if we're able to see the channel */
|
||||
{
|
||||
shared_lock channel_view_lock(this->channel_lock);
|
||||
auto channel = this->channel_view()->find_channel(conversation_id);
|
||||
if(!channel) {
|
||||
auto error = findError("conversation_invalid_id");
|
||||
result_bulk["error_id"] = error.errorId;
|
||||
result_bulk["error_msg"] = error.message;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* test if there is a channel password or join power which denies that we see the conversation */
|
||||
{
|
||||
shared_lock channel_view_lock(ref_server->channel_tree_lock);
|
||||
auto channel = ref_server->getChannelTree()->findChannel(conversation_id);
|
||||
if(!channel) { /* should never happen! */
|
||||
auto error = findError("conversation_invalid_id");
|
||||
result_bulk["error_id"] = error.errorId;
|
||||
result_bulk["error_msg"] = error.message;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!bulk.has("cpw"))
|
||||
bulk["cpw"] = "";
|
||||
|
||||
if (!channel->passwordMatch(bulk["cpw"], true))
|
||||
if (!this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_channel_join_ignore_password, 1, channel, true)) {
|
||||
auto error = findError("channel_invalid_password");
|
||||
result_bulk["error_id"] = error.errorId;
|
||||
result_bulk["error_msg"] = error.message;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(!this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_channel_ignore_join_power, 1, channel, true)) {
|
||||
auto permission_granted = this->calculate_permission_value(permission::i_channel_join_power, channel->channelId());
|
||||
if(!channel->permission_granted(permission::i_channel_needed_join_power, permission_granted, false)) {
|
||||
auto error = findError("server_insufficeient_permissions");
|
||||
result_bulk["error_id"] = error.errorId;
|
||||
result_bulk["error_msg"] = error.message;
|
||||
result_bulk["failed_permid"] = permission::i_channel_join_power;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto conversation = conversation_manager->get(conversation_id);
|
||||
if(conversation)
|
||||
result_bulk["timestamp"] = duration_cast<milliseconds>(conversation->last_message().time_since_epoch()).count();
|
||||
else
|
||||
result_bulk["timestamp"] = 0;
|
||||
}
|
||||
if(result_index == 0)
|
||||
return {ErrorType::DBEmpty};
|
||||
this->sendCommand(result);
|
||||
|
||||
|
||||
return CommandResult::Success;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user