diff --git a/git-teaspeak b/git-teaspeak index 0d28f63..abe8ee2 160000 --- a/git-teaspeak +++ b/git-teaspeak @@ -1 +1 @@ -Subproject commit 0d28f637e11519fbdb5f124fcab126b14a35000f +Subproject commit abe8ee2c32bdee1812d6cb9e2b393b4e9092aa6e diff --git a/server/src/client/command_handler/channel.cpp b/server/src/client/command_handler/channel.cpp index a971cf8..570e33f 100644 --- a/server/src/client/command_handler/channel.cpp +++ b/server/src/client/command_handler/channel.cpp @@ -521,8 +521,9 @@ command_result ConnectedClient::handleCommandChannelGroupAddPerm(Command &cmd) { ACTION_REQUIRES_GROUP_PERMISSION(channelGroup, permission::i_channel_group_needed_modify_power, permission::i_channel_group_modify_power, true); command::bulk_parser::PermissionBulksParser pparser{cmd}; - if (!pparser.validate(this->ref(), 0)) + if (!pparser.validate(this->ref(), 0)) { return pparser.build_command_result(); + } bool updateList{false}; for (const auto &ppermission : pparser.iterate_valid_permissions()) { @@ -538,22 +539,29 @@ command_result ConnectedClient::handleCommandChannelGroupAddPerm(Command &cmd) { updateList |= ppermission.is_group_property(); } - if (updateList) + if (updateList) { channelGroup->apply_properties_from_permissions(); + } if (this->server) { - if (updateList) + if (updateList) { this->server->forEachClient([](shared_ptr cl) { cl->notifyChannelGroupList(); }); + } + this->server->forEachClient([channelGroup](shared_ptr cl) { unique_lock client_channel_lock(cl->channel_lock); /* while we're updating groups we dont want to change anything! */ if (cl->channelGroupAssigned(channelGroup, cl->getChannel())) { - if (cl->update_cached_permissions()) + if (cl->update_cached_permissions()) { cl->sendNeededPermissions(false); /* update the needed permissions */ - cl->updateChannelClientProperties(false, true); + } cl->join_state_id++; /* join permission may changed, all channels need to be recalculate dif needed */ } + client_channel_lock.unlock(); + + /* Must be outside of the lock since updateChannelClientProperties may causes client talk power updates */ + cl->updateChannelClientProperties(true, true); }); } @@ -597,9 +605,12 @@ command_result ConnectedClient::handleCommandChannelGroupDelPerm(Command &cmd) { if (cl->channelGroupAssigned(channelGroup, cl->getChannel())) { if (cl->update_cached_permissions()) /* update cached calculated permissions */ cl->sendNeededPermissions(false); /* cached permissions had changed, notify the client */ - cl->updateChannelClientProperties(false, false); cl->join_state_id++; /* join permission may changed, all channels need to be recalculate dif needed */ } + client_channel_lock.unlock(); + + /* Must be outside of the lock since updateChannelClientProperties may causes client talk power updates */ + cl->updateChannelClientProperties(true, true); }); } @@ -2179,10 +2190,13 @@ command_result ConnectedClient::handleCommandChannelAddPerm(Command &cmd) { if ((updateClients || update_join_permissions) && this->server) { this->server->forEachClient([&](std::shared_ptr cl) { - if (updateClients && cl->currentChannel == channel) + if (updateClients && cl->currentChannel == channel) { cl->updateChannelClientProperties(true, true); - if (update_join_permissions) + } + + if (update_join_permissions) { cl->join_state_id++; + } }); }