diff --git a/server/src/InstanceHandler.cpp b/server/src/InstanceHandler.cpp index 034ac06..ecb3e38 100644 --- a/server/src/InstanceHandler.cpp +++ b/server/src/InstanceHandler.cpp @@ -111,7 +111,7 @@ InstanceHandler::InstanceHandler(SqlDataManager *sql) : sql(sql) { this->groupManager = std::make_shared(nullptr, this->getSql()); this->groupManager->loadGroupFormDatabase(); - if (this->groupManager->availableServerGroups(false).empty()){ + if (this->groupManager->availableServerGroups(false).empty()) { if(!this->setupDefaultGroups()){ logCritical(LOG_INSTANCE, "Could not setup server instance! Stopping..."); mainThreadActive = false; diff --git a/server/src/InstanceHandlerSetup.cpp b/server/src/InstanceHandlerSetup.cpp index 31cdcc4..ce443ab 100644 --- a/server/src/InstanceHandlerSetup.cpp +++ b/server/src/InstanceHandlerSetup.cpp @@ -141,6 +141,7 @@ bool InstanceHandler::setupDefaultGroups() { } } } + this->save_group_permissions(); this->getSql()->pool->threads()->wait_for(); //Wait for all permissions to flush return true; } diff --git a/server/src/client/ConnectedClient.cpp b/server/src/client/ConnectedClient.cpp index 3936660..fbe4984 100644 --- a/server/src/client/ConnectedClient.cpp +++ b/server/src/client/ConnectedClient.cpp @@ -620,7 +620,12 @@ inline void send_channels(ConnectedClient* client, ChannelIT begin, const Channe if(++index > 6) break; } - client->sendCommand(channellist); + if(dynamic_cast(client)) { + auto vc = dynamic_cast(client); + vc->sendCommand0(channellist, false, true); /* we need to process this command directly so it will be processed before the channellistfinished stuff */ + } else { + client->sendCommand(channellist); + } if(begin != end) send_channels(client, begin, end, override_orderid); } @@ -761,7 +766,11 @@ void ConnectedClient::sendServerInit() { command["pv"] = 6; //Protocol version command["acn"] = this->getDisplayName(); command["aclid"] = this->getClientId(); - this->sendCommand(command); + if(dynamic_cast(this)) { + dynamic_cast(this)->sendCommand0(command, false, true); /* process it directly so the order for the channellist entries is ensured. (First serverinit then everything else) */ + } else { + this->sendCommand(command); + } } bool ConnectedClient::handleCommandFull(Command& cmd, bool disconnectOnFail) { @@ -948,6 +957,13 @@ permission::v2::PermissionFlaggedValue ConnectedClient::calculate_permission_val return {index->second, index->second != permNotGranted}; } + auto ref_server = this->server; + if(ref_server) { + auto result = this->server->calculatePermissions2(this->getClientDatabaseId(), {permission}, this->getType(), channel_id, false); + if(!result.empty()) /* it should never be empty! */ + return result.back().second; + } + auto value = this->permissionValue(permission::PERMTEST_ORDERED, permission, nullptr); return {value, value != permNotGranted}; } \ No newline at end of file diff --git a/server/src/client/ConnectedClient.h b/server/src/client/ConnectedClient.h index a2ad32e..2fc3aac 100644 --- a/server/src/client/ConnectedClient.h +++ b/server/src/client/ConnectedClient.h @@ -121,6 +121,7 @@ namespace ts { bool isAddressV6() { return this->remote_address.ss_family == AF_INET6; } const sockaddr_in6* getAddressV6(){ return (sockaddr_in6*) &this->remote_address; } + /* Note: Order is not guaranteed here! */ virtual void sendCommand(const ts::Command& command, bool low = false) = 0; //General manager stuff diff --git a/server/src/client/ConnectedClientCommandHandler.cpp b/server/src/client/ConnectedClientCommandHandler.cpp index 17ca6f0..53177a0 100644 --- a/server/src/client/ConnectedClientCommandHandler.cpp +++ b/server/src/client/ConnectedClientCommandHandler.cpp @@ -2225,7 +2225,7 @@ CommandResult ConnectedClient::handleCommandClientPoke(Command &cmd) { auto client = this->server->findClient(cmd["clid"].as()); if (!client) return {findError("client_invalid_id"), "invalid client id"}; if (client->getType() == CLIENT_MUSIC) return {findError("client_invalid_type"), "You cant poke a music bot!"}; - CACHED_PERM_CHECK(permission::i_client_poke_power, client->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_needed_poke_power, client->currentChannel)); + CACHED_PERM_CHECK(permission::i_client_poke_power, client->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_needed_poke_power, client->currentChannel), false); client->notifyClientPoke(_this.lock(), cmd["msg"]); return CommandResult::Success; @@ -3320,8 +3320,12 @@ CommandResult ConnectedClient::handleCommandFTGetFileList(Command &cmd) { } if (fileList[0].has("name")) { - this->sendCommand(fileList); - if (this->getExternalType() == CLIENT_TEAMSPEAK) this->sendCommand(fileListFinished); + if(dynamic_cast(this)) { + dynamic_cast(this)->sendCommand0(fileList, false, true); /* We need to process this directly else the order could get shuffeled up! */ + this->sendCommand(fileListFinished); + } else { + this->sendCommand(fileList); + } return CommandResult::Success; } else { return {findError("database_empty_result"), "empty"}; diff --git a/server/src/client/query/QueryClientCommands.cpp b/server/src/client/query/QueryClientCommands.cpp index 69efa71..14019e4 100644 --- a/server/src/client/query/QueryClientCommands.cpp +++ b/server/src/client/query/QueryClientCommands.cpp @@ -318,6 +318,8 @@ CommandResult QueryClient::handleCommandServerSelect(Command &cmd) { //register at current server { + //unique_lock server_lock(this->server_lock); + /* We dont need to lock the server because only one command can be executed at the time. Everything else should copy the server once and test the copy and use that ref then */ this->server = target; } diff --git a/server/src/client/voice/VoiceClient.h b/server/src/client/voice/VoiceClient.h index 8173179..e5283f0 100644 --- a/server/src/client/voice/VoiceClient.h +++ b/server/src/client/voice/VoiceClient.h @@ -55,6 +55,7 @@ namespace ts { bool disconnect(ViewReasonId /* reason type */, const std::string& /* reason */, const std::shared_ptr& /* invoker */, bool /* notify viewer */); virtual void sendCommand(const ts::Command &command, bool low = false) { return this->sendCommand0(command, low); } + /* Note: Order is only guaranteed if progressDirectly is on! */ virtual void sendCommand0(const ts::Command &command, bool low = false, bool progressDirectly = false, std::unique_ptr> listener = nullptr); virtual void sendAcknowledge(uint16_t packetId, bool low = false);