diff --git a/git-teaspeak b/git-teaspeak index 6fa2641..00eff98 160000 --- a/git-teaspeak +++ b/git-teaspeak @@ -1 +1 @@ -Subproject commit 6fa26411e7f38d5697269262bab68c307bd159b1 +Subproject commit 00eff98160e4c367f2d368246b3eb581bb82dd10 diff --git a/server/src/client/ConnectedClient.h b/server/src/client/ConnectedClient.h index e1cf6a0..6f298b1 100644 --- a/server/src/client/ConnectedClient.h +++ b/server/src/client/ConnectedClient.h @@ -198,7 +198,12 @@ namespace ts { virtual bool notifyChannelMoved(const std::shared_ptr &channel, ChannelId order, const std::shared_ptr &invoker); virtual bool notifyChannelDescriptionChanged(std::shared_ptr channel); virtual bool notifyChannelPasswordChanged(std::shared_ptr); - virtual bool notifyChannelEdited(std::shared_ptr, std::vector keys, ConnectedClient* invoker); /* clients channel tree must be at least read locked */ + virtual bool notifyChannelEdited( + const std::shared_ptr& /* channel */, + const std::vector& /* properties */, + const std::shared_ptr& /* invoker */, + bool /* send channel description */ + ); /* clients channel tree must be at least read locked */ virtual bool notifyChannelHide(const std::deque &channels, bool lock_channel_tree); virtual bool notifyChannelShow(const std::shared_ptr &channel, ChannelId orderId); /* client channel tree must be unique locked and server channel tree shared locked */ diff --git a/server/src/client/ConnectedClientCommandHandler.cpp b/server/src/client/ConnectedClientCommandHandler.cpp index b6880f0..4b7c552 100644 --- a/server/src/client/ConnectedClientCommandHandler.cpp +++ b/server/src/client/ConnectedClientCommandHandler.cpp @@ -1672,7 +1672,7 @@ CommandResult ConnectedClient::handleCommandChannelCreate(Command &cmd) { if(old_default_channel) { //TODO: Reminder: client channel tree must be at least read locked here! - client->notifyChannelEdited(old_default_channel, {"channel_flag_default"}, this); + client->notifyChannelEdited(old_default_channel, {property::CHANNEL_FLAG_DEFAULT}, self_lock, false); } }); @@ -2079,6 +2079,7 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { return {findError("channel_name_inuse"), to_string(named_channel->channelId())}; } + auto self_ref = this->ref(); shared_ptr old_default_channel; deque> child_channel_updated; for(const std::shared_ptr& key : keys) { @@ -2110,7 +2111,7 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { cl->notifyChannelMoved(action.second->channel(), action.second->previous_channel, this->ref()); break; case ClientChannelView::REORDER: - cl->notifyChannelEdited(action.second->channel(), {"channel_order"}, this); + cl->notifyChannelEdited(action.second->channel(), {property::CHANNEL_ORDER}, self_ref, false); break; } } @@ -2147,10 +2148,11 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { if(this->server && !updated_channels.empty()) { std::reverse(updated_channels.begin(), updated_channels.end()); + auto this_ref = this->ref(); this->server->forEachClient([&](const shared_ptr& client) { unique_lock client_channel_lock(client->channel_lock); for(const auto& channel : updated_channels) { - client->notifyChannelEdited(channel, {"channel_flag_permanent", "channel_flag_semi_permanent"}, this); + client->notifyChannelEdited(channel, {property::CHANNEL_FLAG_PERMANENT, property::CHANNEL_FLAG_SEMI_PERMANENT}, this_ref, false); } }); } @@ -2192,21 +2194,22 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { channel->properties()[key] = cmd[key->name].string(); } if(this->server) { - vector key_vector; + vector key_vector; key_vector.reserve(keys.size()); for(const auto& key : keys) - key_vector.push_back(key->name); + key_vector.push_back((property::ChannelProperties) key->property_index); + auto self_rev = this->ref(); this->server->forEachClient([&](const shared_ptr& client) { unique_lock client_channel_lock(client->channel_lock); for(const auto& channel : child_channel_updated) - client->notifyChannelEdited(channel, {"channel_flag_permanent", "channel_flag_semi_permanent"}, this); + client->notifyChannelEdited(channel, {property::CHANNEL_FLAG_PERMANENT, property::CHANNEL_FLAG_SEMI_PERMANENT}, self_rev, false); - client->notifyChannelEdited(channel, key_vector, this); + client->notifyChannelEdited(channel, key_vector, self_rev, false); if(old_default_channel) /* clients need to have one or more defualt channels... */ - client->notifyChannelEdited(old_default_channel, {"channel_flag_default"}, this); + client->notifyChannelEdited(old_default_channel, {property::CHANNEL_FLAG_DEFAULT}, self_rev, false); }); } @@ -2305,10 +2308,11 @@ CommandResult ConnectedClient::handleCommandChannelMove(Command &cmd) { } if(this->server) { + auto self_rev = this->ref(); this->server->forEachClient([&](const shared_ptr& client) { unique_lock channel_lock(client->channel_lock); for(const auto& type_update : channel_type_updates) - client->notifyChannelEdited(type_update, {"channel_flag_permanent", "channel_flag_semi_permanent"}, this); + client->notifyChannelEdited(type_update, {property::CHANNEL_FLAG_PERMANENT, property::CHANNEL_FLAG_SEMI_PERMANENT}, self_rev, false); auto actions = client->channels->change_order(l_channel, l_parent, l_order); std::deque deletions; @@ -2326,7 +2330,7 @@ CommandResult ConnectedClient::handleCommandChannelMove(Command &cmd) { client->notifyChannelMoved(action.second->channel(), action.second->previous_channel, _this.lock()); break; case ClientChannelView::REORDER: - client->notifyChannelEdited(action.second->channel(), vector{"channel_order"}, _this.lock().get()); + client->notifyChannelEdited(action.second->channel(), {property::CHANNEL_ORDER}, self_rev, false); break; } } @@ -2462,11 +2466,13 @@ CommandResult ConnectedClient::handleCommandChannelAddPerm(Command &cmd) { update_channel_properties |= channel->permission_require_property_update(permType); if (permType == permission::i_icon_id) { - if(this->server) + if(this->server) { + auto self_ref = this->ref(); this->server->forEachClient([&](std::shared_ptr cl) { shared_lock client_channel_lock(cl->channel_lock); - cl->notifyChannelEdited(channel, {"channel_icon_id"}, this); + cl->notifyChannelEdited(channel, {property::CHANNEL_ICON_ID}, self_ref, false); }); + } continue; } } @@ -2476,15 +2482,10 @@ CommandResult ConnectedClient::handleCommandChannelAddPerm(Command &cmd) { if(update_channel_properties) { auto updates = channel->update_properties_from_permissions(); if(!updates.empty() && this->server){ - vector keys; - keys.reserve(updates.size()); - - for(auto& property : updates) - keys.push_back(property::info(property)->name); - + auto self_ref = this->ref(); this->server->forEachClient([&](std::shared_ptr cl) { shared_lock client_channel_lock(cl->channel_lock); - cl->notifyChannelEdited(channel, keys, this); + cl->notifyChannelEdited(channel, updates, self_ref, false); }); } } @@ -2554,15 +2555,10 @@ CommandResult ConnectedClient::handleCommandChannelDelPerm(Command &cmd) { if(update_channel_properties) { auto updates = channel->update_properties_from_permissions(); if(!updates.empty() && this->server){ - vector keys; - keys.reserve(updates.size()); - - for(auto& property : updates) - keys.push_back(property::info(property)->name); - + auto self_ref = this->ref(); this->server->forEachClient([&](std::shared_ptr cl) { shared_lock client_channel_lock(cl->channel_lock); - cl->notifyChannelEdited(channel, keys, this); + cl->notifyChannelEdited(channel, updates, self_ref, false); }); } } diff --git a/server/src/client/ConnectedClientNotifyHandler.cpp b/server/src/client/ConnectedClientNotifyHandler.cpp index 9b8a9c9..63a5969 100644 --- a/server/src/client/ConnectedClientNotifyHandler.cpp +++ b/server/src/client/ConnectedClientNotifyHandler.cpp @@ -452,6 +452,8 @@ bool ConnectedClient::notifyChannelCreate(const std::shared_ptr &c 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) + continue; else notify[prop.type().name] = prop.value(); } @@ -513,8 +515,11 @@ bool ConnectedClient::notifyChannelShow(const std::shared_ptr } 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)) { - if(prop.type() == property::CHANNEL_ORDER) - notify[prop.type().name] = orderId; + if(prop.type() == property::CHANNEL_ORDER) { + notify[prop.type().name] = orderId; + } else if(prop.type() == property::CHANNEL_DESCRIPTION) { + continue; + } else notify[prop.type().name] = prop.value(); } @@ -640,34 +645,42 @@ bool ConnectedClient::notifyClientEnterView(const std::deque channel, std::vector keys, ConnectedClient *invoker) { +bool ConnectedClient::notifyChannelEdited( + const std::shared_ptr &channel, + const std::vector &properties, + const std::shared_ptr &invoker, + bool send_description) { auto v_channel = this->channels->find_channel(channel->channelId()); if(!v_channel) return false; //Not visible? Important do not remove! + bool send_description_change{false}; + Command notify("notifychanneledited"); + for(auto prop : properties) { + auto prop_info = property::impl::info(prop); - auto counter = 0; - for (const auto& key : keys) { - auto info = property::impl::info(key); - if(*info == property::CHANNEL_UNDEFINED) { - logError(this->getServerId(), "Tried to edit a non existing channel property: " + key); - continue; - } - counter++; - if(*info == property::CHANNEL_ORDER) { - notify[key] = v_channel->previous_channel; - } else { - notify[key] = channel->properties()[info].as(); - } - } - if(counter == 0) return true; + if(prop == property::CHANNEL_ORDER) + notify[prop_info->name] = v_channel->previous_channel; + else if(prop == property::CHANNEL_DESCRIPTION && !send_description) { + send_description_change = true; + } else { + notify[prop_info->name] = channel->properties()[prop].as(); + } + } - notify["cid"] = channel->channelId(); - INVOKER(notify, invoker); - notify["reasonid"] = ViewReasonId::VREASON_EDITED; + notify["cid"] = channel->channelId(); + notify["reasonid"] = ViewReasonId::VREASON_EDITED; - this->sendCommand(notify); - return true; + INVOKER(notify, invoker); + this->sendCommand(notify); + + if(send_description_change) { + Command notify_dchange{"notifychanneldescriptionchanged"}; + notify_dchange["cid"] = channel->channelId(); + this->sendCommand(notify_dchange); + } + + return true; } bool ConnectedClient::notifyChannelDeleted(const deque& channel_ids, const std::shared_ptr& invoker) { diff --git a/server/src/client/music/MusicClientPlayer.cpp b/server/src/client/music/MusicClientPlayer.cpp index 5982e91..06f1e0f 100644 --- a/server/src/client/music/MusicClientPlayer.cpp +++ b/server/src/client/music/MusicClientPlayer.cpp @@ -452,4 +452,5 @@ void MusicClient::execute_music_tick(const shared_ptr& duration_cast(timestamp_end - timestamp_begin_schedule).count() ); } -} \ No newline at end of file +} + diff --git a/server/src/client/query/QueryClient.h b/server/src/client/query/QueryClient.h index 947e8b0..49139ea 100644 --- a/server/src/client/query/QueryClient.h +++ b/server/src/client/query/QueryClient.h @@ -114,7 +114,8 @@ namespace ts { const std::shared_ptr &invoker) override; bool notifyChannelDescriptionChanged(std::shared_ptr channel) override; bool notifyChannelPasswordChanged(std::shared_ptr ) override; - bool notifyChannelEdited(std::shared_ptr channel, std::vector keys, ConnectedClient *invoker) override; + + bool notifyChannelEdited(const std::shared_ptr &ptr, const std::vector &vector, const std::shared_ptr &sharedPtr, bool b) override; bool notifyChannelDeleted(const std::deque &deque, const std::shared_ptr &ptr) override; diff --git a/server/src/client/query/QueryClientCommands.cpp b/server/src/client/query/QueryClientCommands.cpp index a2a4ae6..1858a34 100644 --- a/server/src/client/query/QueryClientCommands.cpp +++ b/server/src/client/query/QueryClientCommands.cpp @@ -1000,5 +1000,4 @@ CommandResult QueryClient::handleCommandServerNotifyUnregister(Command &cmd) { this->toggleEvent(ev.first, ev.second, false); return CommandResult::Success; } - #undef XMACRO_LAGACY_EV \ No newline at end of file diff --git a/server/src/client/query/QueryClientNotify.cpp b/server/src/client/query/QueryClientNotify.cpp index 7852a63..161622d 100644 --- a/server/src/client/query/QueryClientNotify.cpp +++ b/server/src/client/query/QueryClientNotify.cpp @@ -111,9 +111,9 @@ bool QueryClient::notifyChannelPasswordChanged(std::shared_ptr cha return ConnectedClient::notifyChannelPasswordChanged(channel); } -bool QueryClient::notifyChannelEdited(std::shared_ptr channel, std::vector keys, ConnectedClient *invoker) { - CHK_EVENT(QEVENTGROUP_CHANNEL, QEVENTSPECIFIER_CHANNEL_EDIT); - return ConnectedClient::notifyChannelEdited(channel, keys, invoker); +bool QueryClient::notifyChannelEdited(const std::shared_ptr &ptr, const std::vector &vector, const std::shared_ptr &sharedPtr, bool b) { + CHK_EVENT(QEVENTGROUP_CHANNEL, QEVENTSPECIFIER_CHANNEL_EDIT); + return ConnectedClient::notifyChannelEdited(ptr, vector, sharedPtr, b); } bool QueryClient::notifyChannelDeleted(const std::deque &deque, const std::shared_ptr &ptr) {