diff --git a/server/src/client/ConnectedClient.cpp b/server/src/client/ConnectedClient.cpp index 14a043f..46c0c1b 100644 --- a/server/src/client/ConnectedClient.cpp +++ b/server/src/client/ConnectedClient.cpp @@ -578,18 +578,24 @@ bool ConnectedClient::notifyClientNeededPermissions() { return true; } -bool ConnectedClient::notifyError(const CommandResult& result, const std::string& retCode) { +bool ConnectedClient::notifyError(const command_result& result, const std::string& retCode) { Command cmd("error"); - cmd["id"] = result.error.errorId; - cmd["msg"] = result.error.message; + if(result.is_detailed()) { + auto detailed = result.details(); + cmd["id"] = (int) detailed->error_id; + cmd["msg"] = findError(detailed->error_id).message; + + for(const auto& extra : detailed->extra_properties) + cmd[extra.first] = extra.second; + } else { + cmd["id"] = (int) result.error_code(); + cmd["msg"] = findError(result.error_code()).message; + } if(retCode.length() > 0) cmd["return_code"] = retCode; - for(const auto& extra : result.extraProperties) - cmd[extra.first] = extra.second; - this->sendCommand(cmd); return true; } @@ -792,60 +798,46 @@ bool ConnectedClient::handleCommandFull(Command& cmd, bool disconnectOnFail) { logTrace(this->getServerId() == 0 ? LOG_QUERY : this->getServerId(), "{}[Command][Client -> Server] Processing command: {}", CLIENT_STR_LOG_PREFIX, cmd.build(false)); #endif - CommandResult result; + command_result result; try { result = this->handleCommand(cmd); } catch(invalid_argument& ex){ - debugMessage(this->getServerId(), "{}[Command] Execution throws invalid_argument exception ({}).", CLIENT_STR_LOG_PREFIX, ex.what()); + logWarning(this->getServerId(), "{}[Command] Failed to handle command. Received invalid argument exception: {}", CLIENT_STR_LOG_PREFIX, ex.what()); if(disconnectOnFail) { this->disconnect("Invalid argument (" + string(ex.what()) + ")"); return false; } else { - result = {findError("parameter_convert"), "Invalid argument (" + string(ex.what()) + ")"}; + result = command_result{error::parameter_convert}; } } catch (exception& ex) { + logWarning(this->getServerId(), "{}[Command] Failed to handle command. Received exception with message: {}", CLIENT_STR_LOG_PREFIX, ex.what()); if(disconnectOnFail) { this->disconnect("Error while command handling (" + string(ex.what()) + ")!"); return false; } else { - result = {findError("vs_critical"), "error while command handling (" + string(ex.what()) + ")"}; + result = command_result{error::vs_critical}; } } catch (...) { this->disconnect("Error while command handling! (unknown)"); return false; } + bool generateReturnStatus = false; - if(result.type() == PERM_ERROR){ + if(result.error_code() != error::ok || this->getType() == ClientType::CLIENT_QUERY){ generateReturnStatus = true; } else if(cmd["return_code"].size() > 0) { generateReturnStatus = !cmd["return_code"].string().empty(); } - if(this->getType() == ClientType::CLIENT_QUERY) - generateReturnStatus = true; - - if (!result) { - generateReturnStatus = true; - - stringstream ss; - ss << "{"; - for(auto it = result.extraProperties.begin(); it != result.extraProperties.end();){ - ss << it->first << " = " << it->second; - if(++it != result.extraProperties.end()) - ss << ", "; - } - ss << "}" << endl; - logTrace(this->getServerId(), "{}[Command] Command {} with return code {} fails and returns error code {:#06x}. Properties: {}", CLIENT_STR_LOG_PREFIX, cmd.command(), cmd["return_code"].size() ? "\"" + cmd["return_code"].first().as() + "\"" : "", result.error.errorId, ss.str()); - } if(generateReturnStatus) this->notifyError(result, cmd["return_code"].size() > 0 ? cmd["return_code"].first().as() : ""); - if(!result && this->state == ConnectionState::INIT_HIGH) { + if(result.error_code() != error::ok && this->state == ConnectionState::INIT_HIGH) this->closeConnection(system_clock::now()); //Disconnect now - } for (const auto& handler : postCommandHandler) handler(); + postCommandHandler.clear(); end = system_clock::now(); if(end - start > milliseconds(10)) { @@ -854,6 +846,7 @@ bool ConnectedClient::handleCommandFull(Command& cmd, bool disconnectOnFail) { else logWarning(this->getServerId(), "Command handling of command {} needs {}ms.", cmd.command(), duration_cast(end - start).count()); } + result.release_details(); return true; } diff --git a/server/src/client/ConnectedClient.h b/server/src/client/ConnectedClient.h index 87d7eaf..cb7e369 100644 --- a/server/src/client/ConnectedClient.h +++ b/server/src/client/ConnectedClient.h @@ -7,22 +7,19 @@ #include "../channel/ClientChannelView.h" #include "DataClient.h" -#define CLIENT_LOG_PREFIX_(this) "[" << this->getLoggingPeerIp() << ":" << this->getPeerPort() << "/" << this->getDisplayName() << "]" -#define CLIENT_LOG_PREFIX CLIENT_LOG_PREFIX_(this) - #define CLIENT_STR_LOG_PREFIX_(this) (std::string("[") + this->getLoggingPeerIp() + ":" + std::to_string(this->getPeerPort()) + "/" + this->getDisplayName() + " | " + std::to_string(this->getClientId()) + "]") #define CLIENT_STR_LOG_PREFIX CLIENT_STR_LOG_PREFIX_(this) #define CMD_REQ_SERVER \ -if(!this->server) return {findError("server_invalid_id"), "invalid bound server"} +if(!this->server) return command_result{error::server_invalid_id}; /* TODO: Play lock the server here with read? So the client dosn't get kicked within that moment */ #define CMD_REF_SERVER(variable_name) \ std::shared_ptr variable_name = this->getServer(); \ -if(!variable_name) return {findError("server_invalid_id"), "invalid bound server"} +if(!variable_name) return command_result{error::server_invalid_id}; #define CMD_REQ_CHANNEL \ -if(!this->currentChannel) return {findError("channel_invalid_id"), "invalid bound channel"} +if(!this->currentChannel) return command_result{error::channel_invalid_id}; #define CMD_RESET_IDLE \ do { \ @@ -30,22 +27,22 @@ do { \ } while(false) #define CMD_REQ_PARM(parm) \ -if(!cmd[0].has(parm)) return {findError("parameter_not_found"), parm} +if(!cmd[0].has(parm)) return command_result{error::parameter_not_found}; //the message here is show to the manager! #define CMD_CHK_AND_INC_FLOOD_POINTS(num) \ this->increaseFloodPoints(num); \ -if(this->shouldFloodBlock()) return {findError("ban_flooding"), "You reached the flood limit"}; +if(this->shouldFloodBlock()) return command_result{error::ban_flooding}; #define CMD_CHK_PARM_COUNT(count) \ -if(cmd.bulkCount() != count) return {findError("parameter_invalid_count"), ""}; +if(cmd.bulkCount() != count) return command_result{error::parameter_invalid_count}; #define PERM_CHECK_CHANNEL_CR(pr, required, channel, req, cache) \ do { \ if(!this->permissionGranted(permission::PERMTEST_ORDERED, pr, required, channel, req, cache)) {\ - return ts::CommandResultPermissionError(pr); \ + return command_result{pr}; \ }\ } while(false) @@ -62,7 +59,7 @@ do { \ #define CACHED_PERM_CHECK(permission_type, required, ...) \ do { \ if(!this->permission_granted(this->cached_permission_value(permission_type), required, #__VA_ARGS__)) \ - return CommandResultPermissionError{permission_type}; \ + return command_result{permission_type}; \ } while(0) //p = permission | target_permission = channel permission | channel = target channel | requires a power @@ -148,7 +145,7 @@ namespace ts { } /** Notifies general stuff **/ - virtual bool notifyError(const CommandResult&, const std::string& retCode = ""); + virtual bool notifyError(const command_result&, const std::string& retCode = ""); /** Notifies (after request) */ bool sendNeededPermissions(bool /* force an update */); /* invoke this because it dosn't spam the client */ @@ -387,189 +384,189 @@ namespace ts { threads::Mutex command_lock; /* Note: This mutex must be recursive! */ std::vector> postCommandHandler; virtual bool handleCommandFull(Command&, bool disconnectOnFail = false); - virtual CommandResult handleCommand(Command&); + virtual command_result handleCommand(Command&); - CommandResult handleCommandServerGetVariables(Command&); - CommandResult handleCommandServerEdit(Command&); + command_result handleCommandServerGetVariables(Command&); + command_result handleCommandServerEdit(Command&); - CommandResult handleCommandGetConnectionInfo(Command&); - CommandResult handleCommandSetConnectionInfo(Command&); - CommandResult handleCommandServerRequestConnectionInfo(Command&); - CommandResult handleCommandConnectionInfoAutoUpdate(Command&); - CommandResult handleCommandPermissionList(Command&); - CommandResult handleCommandPropertyList(Command&); + command_result handleCommandGetConnectionInfo(Command&); + command_result handleCommandSetConnectionInfo(Command&); + command_result handleCommandServerRequestConnectionInfo(Command&); + command_result handleCommandConnectionInfoAutoUpdate(Command&); + command_result handleCommandPermissionList(Command&); + command_result handleCommandPropertyList(Command&); - CommandResult handleCommandServerGroupList(Command&); + command_result handleCommandServerGroupList(Command&); - CommandResult handleCommandClientGetIds(Command&); - CommandResult handleCommandClientUpdate(Command&); - CommandResult handleCommandClientEdit(Command&); - CommandResult handleCommandClientEdit(Command&, const std::shared_ptr& /* target */); - CommandResult handleCommandClientMove(Command&); - CommandResult handleCommandClientGetVariables(Command&); - CommandResult handleCommandClientKick(Command&); - CommandResult handleCommandClientPoke(Command&); + command_result handleCommandClientGetIds(Command&); + command_result handleCommandClientUpdate(Command&); + command_result handleCommandClientEdit(Command&); + command_result handleCommandClientEdit(Command&, const std::shared_ptr& /* target */); + command_result handleCommandClientMove(Command&); + command_result handleCommandClientGetVariables(Command&); + command_result handleCommandClientKick(Command&); + command_result handleCommandClientPoke(Command&); - CommandResult handleCommandChannelSubscribe(Command&); - CommandResult handleCommandChannelSubscribeAll(Command&); - CommandResult handleCommandChannelUnsubscribe(Command&); - CommandResult handleCommandChannelUnsubscribeAll(Command&); - CommandResult handleCommandChannelCreate(Command&); - CommandResult handleCommandChannelDelete(Command&); - CommandResult handleCommandChannelEdit(Command&); - CommandResult handleCommandChannelGetDescription(Command&); - CommandResult handleCommandChannelMove(Command&); - CommandResult handleCommandChannelPermList(Command&); - CommandResult handleCommandChannelAddPerm(Command&); - CommandResult handleCommandChannelDelPerm(Command&); + command_result handleCommandChannelSubscribe(Command&); + command_result handleCommandChannelSubscribeAll(Command&); + command_result handleCommandChannelUnsubscribe(Command&); + command_result handleCommandChannelUnsubscribeAll(Command&); + command_result handleCommandChannelCreate(Command&); + command_result handleCommandChannelDelete(Command&); + command_result handleCommandChannelEdit(Command&); + command_result handleCommandChannelGetDescription(Command&); + command_result handleCommandChannelMove(Command&); + command_result handleCommandChannelPermList(Command&); + command_result handleCommandChannelAddPerm(Command&); + command_result handleCommandChannelDelPerm(Command&); //Server group manager management - CommandResult handleCommandServerGroupCopy(Command&); - CommandResult handleCommandServerGroupAdd(Command&); - CommandResult handleCommandServerGroupRename(Command&); - CommandResult handleCommandServerGroupDel(Command&); - CommandResult handleCommandServerGroupClientList(Command&); - CommandResult handleCommandServerGroupDelClient(Command&); - CommandResult handleCommandServerGroupAddClient(Command&); - CommandResult handleCommandServerGroupPermList(Command&); - CommandResult handleCommandServerGroupAddPerm(Command&); - CommandResult handleCommandServerGroupDelPerm(Command&); + command_result handleCommandServerGroupCopy(Command&); + command_result handleCommandServerGroupAdd(Command&); + command_result handleCommandServerGroupRename(Command&); + command_result handleCommandServerGroupDel(Command&); + command_result handleCommandServerGroupClientList(Command&); + command_result handleCommandServerGroupDelClient(Command&); + command_result handleCommandServerGroupAddClient(Command&); + command_result handleCommandServerGroupPermList(Command&); + command_result handleCommandServerGroupAddPerm(Command&); + command_result handleCommandServerGroupDelPerm(Command&); - CommandResult handleCommandServerGroupAutoAddPerm(Command&); - CommandResult handleCommandServerGroupAutoDelPerm(Command&); + command_result handleCommandServerGroupAutoAddPerm(Command&); + command_result handleCommandServerGroupAutoDelPerm(Command&); - CommandResult handleCommandClientAddPerm(Command&); //TODO: Use cached permission values - CommandResult handleCommandClientDelPerm(Command&); //TODO: Use cached permission values - CommandResult handleCommandClientPermList(Command&); //TODO: Use cached permission values + command_result handleCommandClientAddPerm(Command&); //TODO: Use cached permission values + command_result handleCommandClientDelPerm(Command&); //TODO: Use cached permission values + command_result handleCommandClientPermList(Command&); //TODO: Use cached permission values - CommandResult handleCommandChannelClientAddPerm(Command&); //TODO: Use cached permission values - CommandResult handleCommandChannelClientDelPerm(Command&); //TODO: Use cached permission values - CommandResult handleCommandChannelClientPermList(Command&); //TODO: Use cached permission values + command_result handleCommandChannelClientAddPerm(Command&); //TODO: Use cached permission values + command_result handleCommandChannelClientDelPerm(Command&); //TODO: Use cached permission values + command_result handleCommandChannelClientPermList(Command&); //TODO: Use cached permission values - CommandResult handleCommandChannelGroupAdd(Command&); - CommandResult handleCommandChannelGroupCopy(Command&); - CommandResult handleCommandChannelGroupRename(Command&); - CommandResult handleCommandChannelGroupDel(Command&); - CommandResult handleCommandChannelGroupList(Command&); - CommandResult handleCommandChannelGroupClientList(Command&); - CommandResult handleCommandChannelGroupPermList(Command&); - CommandResult handleCommandChannelGroupAddPerm(Command&); - CommandResult handleCommandChannelGroupDelPerm(Command&); - CommandResult handleCommandSetClientChannelGroup(Command&); + command_result handleCommandChannelGroupAdd(Command&); + command_result handleCommandChannelGroupCopy(Command&); + command_result handleCommandChannelGroupRename(Command&); + command_result handleCommandChannelGroupDel(Command&); + command_result handleCommandChannelGroupList(Command&); + command_result handleCommandChannelGroupClientList(Command&); + command_result handleCommandChannelGroupPermList(Command&); + command_result handleCommandChannelGroupAddPerm(Command&); + command_result handleCommandChannelGroupDelPerm(Command&); + command_result handleCommandSetClientChannelGroup(Command&); - CommandResult handleCommandSendTextMessage(Command&); - CommandResult handleCommandClientChatComposing(Command&); - CommandResult handleCommandClientChatClosed(Command&); + command_result handleCommandSendTextMessage(Command&); + command_result handleCommandClientChatComposing(Command&); + command_result handleCommandClientChatClosed(Command&); //File transfare commands - CommandResult handleCommandFTGetFileList(Command&); //TODO: Use cached permission values - CommandResult handleCommandFTCreateDir(Command&); //TODO: Use cached permission values - CommandResult handleCommandFTDeleteFile(Command&); //TODO: Use cached permission values - CommandResult handleCommandFTInitUpload(Command&); //TODO: Use cached permission values - CommandResult handleCommandFTInitDownload(Command&); //TODO: Use cached permission values - CommandResult handleCommandFTGetFileInfo(Command&); //TODO: Use cached permission values + command_result handleCommandFTGetFileList(Command&); //TODO: Use cached permission values + command_result handleCommandFTCreateDir(Command&); //TODO: Use cached permission values + command_result handleCommandFTDeleteFile(Command&); //TODO: Use cached permission values + command_result handleCommandFTInitUpload(Command&); //TODO: Use cached permission values + command_result handleCommandFTInitDownload(Command&); //TODO: Use cached permission values + command_result handleCommandFTGetFileInfo(Command&); //TODO: Use cached permission values //CMD_TODO handleCommandFTGetFileInfo -> 5 points //CMD_TODO handleCommandFTStop -> 5 points //CMD_TODO handleCommandFTRenameFile -> 5 points //CMD_TODO handleCommandFTList -> 5 points - CommandResult handleCommandBanList(Command&); - CommandResult handleCommandBanAdd(Command&); - CommandResult handleCommandBanEdit(Command&); - CommandResult handleCommandBanClient(Command&); - CommandResult handleCommandBanDel(Command&); - CommandResult handleCommandBanDelAll(Command&); - CommandResult handleCommandBanTriggerList(Command&); + command_result handleCommandBanList(Command&); + command_result handleCommandBanAdd(Command&); + command_result handleCommandBanEdit(Command&); + command_result handleCommandBanClient(Command&); + command_result handleCommandBanDel(Command&); + command_result handleCommandBanDelAll(Command&); + command_result handleCommandBanTriggerList(Command&); - CommandResult handleCommandTokenList(Command&); - CommandResult handleCommandTokenAdd(Command&); - CommandResult handleCommandTokenUse(Command&); - CommandResult handleCommandTokenDelete(Command&); + command_result handleCommandTokenList(Command&); + command_result handleCommandTokenAdd(Command&); + command_result handleCommandTokenUse(Command&); + command_result handleCommandTokenDelete(Command&); - CommandResult handleCommandClientDbList(Command&); - CommandResult handleCommandClientDBEdit(Command&); - CommandResult handleCommandClientDbInfo(Command&); - CommandResult handleCommandClientDBDelete(Command&); - CommandResult handleCommandClientDBFind(Command&); + command_result handleCommandClientDbList(Command&); + command_result handleCommandClientDBEdit(Command&); + command_result handleCommandClientDbInfo(Command&); + command_result handleCommandClientDBDelete(Command&); + command_result handleCommandClientDBFind(Command&); - CommandResult handleCommandPluginCmd(Command&); + command_result handleCommandPluginCmd(Command&); - CommandResult handleCommandClientMute(Command&); - CommandResult handleCommandClientUnmute(Command&); + command_result handleCommandClientMute(Command&); + command_result handleCommandClientUnmute(Command&); - CommandResult handleCommandComplainAdd(Command&); - CommandResult handleCommandComplainList(Command&); - CommandResult handleCommandComplainDel(Command&); - CommandResult handleCommandComplainDelAll(Command&); + command_result handleCommandComplainAdd(Command&); + command_result handleCommandComplainList(Command&); + command_result handleCommandComplainDel(Command&); + command_result handleCommandComplainDelAll(Command&); - CommandResult handleCommandClientGetDBIDfromUID(Command&); - CommandResult handleCommandClientGetNameFromDBID(Command&); - CommandResult handleCommandClientGetNameFromUid(Command&); - CommandResult handleCommandClientGetUidFromClid(Command&); + command_result handleCommandClientGetDBIDfromUID(Command&); + command_result handleCommandClientGetNameFromDBID(Command&); + command_result handleCommandClientGetNameFromUid(Command&); + command_result handleCommandClientGetUidFromClid(Command&); //Original from query but still reachable for all - CommandResult handleCommandClientList(Command&); - CommandResult handleCommandWhoAmI(Command&); - CommandResult handleCommandServerGroupsByClientId(Command &); //Maybe not query? + command_result handleCommandClientList(Command&); + command_result handleCommandWhoAmI(Command&); + command_result handleCommandServerGroupsByClientId(Command &); //Maybe not query? - CommandResult handleCommandClientFind(Command&); - CommandResult handleCommandClientInfo(Command&); - CommandResult handleCommandVersion(Command&); + command_result handleCommandClientFind(Command&); + command_result handleCommandClientInfo(Command&); + command_result handleCommandVersion(Command&); - CommandResult handleCommandVerifyChannelPassword(Command&); - CommandResult handleCommandVerifyServerPassword(Command&); + command_result handleCommandVerifyChannelPassword(Command&); + command_result handleCommandVerifyServerPassword(Command&); - CommandResult handleCommandMessageList(Command&); - CommandResult handleCommandMessageAdd(Command&); - CommandResult handleCommandMessageGet(Command&); - CommandResult handleCommandMessageUpdateFlag(Command&); - CommandResult handleCommandMessageDel(Command&); + command_result handleCommandMessageList(Command&); + command_result handleCommandMessageAdd(Command&); + command_result handleCommandMessageGet(Command&); + command_result handleCommandMessageUpdateFlag(Command&); + command_result handleCommandMessageDel(Command&); - CommandResult handleCommandPermGet(Command&); - CommandResult handleCommandPermIdGetByName(Command&); - CommandResult handleCommandPermFind(Command&); - CommandResult handleCommandPermOverview(Command&); + command_result handleCommandPermGet(Command&); + command_result handleCommandPermIdGetByName(Command&); + command_result handleCommandPermFind(Command&); + command_result handleCommandPermOverview(Command&); - CommandResult handleCommandChannelFind(Command&); //TODO: Use cached permission values - CommandResult handleCommandChannelInfo(Command&); //TODO: Use cached permission values + command_result handleCommandChannelFind(Command&); //TODO: Use cached permission values + command_result handleCommandChannelInfo(Command&); //TODO: Use cached permission values - CommandResult handleCommandMusicBotCreate(Command&); //TODO: Use cached permission values - CommandResult handleCommandMusicBotDelete(Command&); //TODO: Use cached permission values - CommandResult handleCommandMusicBotSetSubscription(Command&); //TODO: Use cached permission values + command_result handleCommandMusicBotCreate(Command&); //TODO: Use cached permission values + command_result handleCommandMusicBotDelete(Command&); //TODO: Use cached permission values + command_result handleCommandMusicBotSetSubscription(Command&); //TODO: Use cached permission values - CommandResult handleCommandMusicBotPlayerInfo(Command&); //TODO: Use cached permission values - CommandResult handleCommandMusicBotPlayerAction(Command&); //TODO: Use cached permission values + command_result handleCommandMusicBotPlayerInfo(Command&); //TODO: Use cached permission values + command_result handleCommandMusicBotPlayerAction(Command&); //TODO: Use cached permission values command_result handleCommandMusicBotQueueList(Command&); //TODO: Use cached permission values command_result handleCommandMusicBotQueueAdd(Command&); //TODO: Use cached permission values command_result handleCommandMusicBotQueueRemove(Command&); //TODO: Use cached permission values command_result handleCommandMusicBotQueueReorder(Command&); //TODO: Use cached permission values - CommandResult handleCommandMusicBotPlaylistAssign(Command&); + command_result handleCommandMusicBotPlaylistAssign(Command&); /* playlist management */ - CommandResult handleCommandPlaylistList(Command&); - CommandResult handleCommandPlaylistCreate(Command&); - CommandResult handleCommandPlaylistDelete(Command&); - CommandResult handleCommandPlaylistPermList(Command&); - CommandResult handleCommandPlaylistAddPerm(Command&); - CommandResult handleCommandPlaylistDelPerm(Command&); + command_result handleCommandPlaylistList(Command&); + command_result handleCommandPlaylistCreate(Command&); + command_result handleCommandPlaylistDelete(Command&); + command_result handleCommandPlaylistPermList(Command&); + command_result handleCommandPlaylistAddPerm(Command&); + command_result handleCommandPlaylistDelPerm(Command&); /* playlist properties */ - CommandResult handleCommandPlaylistInfo(Command&); - CommandResult handleCommandPlaylistEdit(Command&); + command_result handleCommandPlaylistInfo(Command&); + command_result handleCommandPlaylistEdit(Command&); - CommandResult handleCommandPlaylistSongList(Command&); - CommandResult handleCommandPlaylistSongAdd(Command&); - CommandResult handleCommandPlaylistSongReorder(Command&); - CommandResult handleCommandPlaylistSongRemove(Command&); + command_result handleCommandPlaylistSongList(Command&); + command_result handleCommandPlaylistSongAdd(Command&); + command_result handleCommandPlaylistSongReorder(Command&); + command_result handleCommandPlaylistSongRemove(Command&); - CommandResult handleCommandPermReset(Command&); //TODO: Use cached permission values + command_result handleCommandPermReset(Command&); //TODO: Use cached permission values - CommandResult handleCommandHelp(Command&); //TODO: Use cached permission values + command_result handleCommandHelp(Command&); //TODO: Use cached permission values - CommandResult handleCommandUpdateMyTsId(Command&); - CommandResult handleCommandUpdateMyTsData(Command&); + command_result handleCommandUpdateMyTsId(Command&); + command_result handleCommandUpdateMyTsData(Command&); /// /// With a whisper list set a client can talk to the specified clients and channels bypassing the standard rule that voice is only transmitted to the current channel. Whisper lists can be defined for individual clients. /// @@ -585,26 +582,26 @@ namespace ts { //CMD_TODO handleCommandServerTempPasswordAdd -> servertemppasswordadd pw=PWD desc=DES duration=1200 (20 min) tcid=4 tcpw=asdasd (channel password) //Legacy, for TeamSpeak 3 - CommandResult handleCommandClientSetServerQueryLogin(Command&); + command_result handleCommandClientSetServerQueryLogin(Command&); - CommandResult handleCommandQueryList(Command&); - CommandResult handleCommandQueryRename(Command&); - CommandResult handleCommandQueryCreate(Command&); - CommandResult handleCommandQueryDelete(Command&); - CommandResult handleCommandQueryChangePassword(Command&); + command_result handleCommandQueryList(Command&); + command_result handleCommandQueryRename(Command&); + command_result handleCommandQueryCreate(Command&); + command_result handleCommandQueryDelete(Command&); + command_result handleCommandQueryChangePassword(Command&); - CommandResult handleCommandConversationHistory(Command&); - CommandResult handleCommandConversationFetch(Command&); - CommandResult handleCommandConversationMessageDelete(Command&); + command_result handleCommandConversationHistory(Command&); + command_result handleCommandConversationFetch(Command&); + command_result handleCommandConversationMessageDelete(Command&); - CommandResult handleCommandLogView(Command&); + command_result handleCommandLogView(Command&); //CMD_TODO handleCommandLogAdd //handleCommandClientSiteReport() -> return findError(0x00) //handleCommandChannelCreatePrivate() -> return findError(0x02) //handleCommandCustome_Unknown_Command() -> return findError(0x100) - CommandResult handleCommandDummy_IpChange(Command&); + command_result handleCommandDummy_IpChange(Command&); //handleCommandDummy_NewIp //handleCommandDummy_ConnectFailed //handleCommandDummy_ConnectionLost diff --git a/server/src/client/ConnectedClientCommandHandler.cpp b/server/src/client/ConnectedClientCommandHandler.cpp index c7b97e5..143a6d8 100644 --- a/server/src/client/ConnectedClientCommandHandler.cpp +++ b/server/src/client/ConnectedClientCommandHandler.cpp @@ -63,8 +63,10 @@ if (cmd[index].has("permid")) { } \ if (permission::resolvePermissionData(permType)->type == permission::PermissionType::unknown) { \ if (conOnError) continue; \ - return {findError("parameter_invalid"), "could not resolve permission " + (cmd[index].has("permid") ? cmd[index]["permid"].as() : cmd[index]["permsid"].as())}; \ + return ts::command_result{error::parameter_invalid}; \ } +//{findError("parameter_invalid"), "could not resolve permission " + (cmd[index].has("permid") ? cmd[index]["permid"].as() : cmd[index]["permsid"].as())}; \ +//TODO: Log missing permissions? #define CHANNEL_PERM_TEST_INIT \ auto current_channel = channel == this->getChannel() @@ -82,21 +84,21 @@ auto channel_tree = this->server ? this->server->channelTree : serverInstance->g shared_lock channel_tree_read_lock(this->server ? this->server->channel_tree_lock : serverInstance->getChannelTreeLock());\ auto channel_id = command.as(); \ auto l_channel = channel_id ? channel_tree->findLinkedChannel(command.as()) : nullptr; \ -if (!l_channel && (channel_id != 0 || force)) return {findError("channel_invalid_id"), "Cant resolve channel"}; \ +if (!l_channel && (channel_id != 0 || force)) return command_result{error::channel_invalid_id, "Cant resolve channel"}; \ #define RESOLVE_CHANNEL_W(command, force) \ auto channel_tree = this->server ? this->server->channelTree : serverInstance->getChannelTree().get();\ unique_lock channel_tree_write_lock(this->server ? this->server->channel_tree_lock : serverInstance->getChannelTreeLock());\ auto channel_id = command.as(); \ auto l_channel = channel_id ? channel_tree->findLinkedChannel(command.as()) : nullptr; \ -if (!l_channel && (channel_id != 0 || force)) return {findError("channel_invalid_id"), "Cant resolve channel"}; \ +if (!l_channel && (channel_id != 0 || force)) return command_result{error::channel_invalid_id, "Cant resolve channel"}; \ /* the "newest" channel permission access test */ #define CHANNEL_PERMISSION_TEST(permission_type, permission_needed_type, _channel, permission_required) \ do { \ auto permission_granted = this->calculate_permission_value(permission_type, _channel->channelId()); \ if(!channel->permission_granted(permission_needed_type, permission_granted, permission_required)) \ - return CommandResultPermissionError{permission_type}; \ + return command_result{permission_type}; \ } while(0) /* the "newest" group permission access test */ @@ -104,7 +106,7 @@ do { \ do { \ auto permission_granted = this->calculate_permission_value(permission_type, 0); \ if(!_group->permission_granted(permission_needed_type, permission_granted, permission_required)) \ - return CommandResultPermissionError{permission_type}; \ + return command_result{permission_type}; \ } while(0) inline bool permission_require_granted_value(permission::PermissionType type) { @@ -181,7 +183,7 @@ inline bool permission_is_client_property(permission::PermissionType type) { } } -CommandResult ConnectedClient::handleCommand(Command &cmd) { +command_result ConnectedClient::handleCommand(Command &cmd) { threads::MutexLock l2(this->command_lock); auto command = cmd.command(); if (command == "servergetvariables") return this->handleCommandServerGetVariables(cmd); @@ -330,10 +332,10 @@ CommandResult ConnectedClient::handleCommand(Command &cmd) { else if (command == "musicbotsetsubscription") return this->handleCommandMusicBotSetSubscription(cmd); else if (command == "musicbotplayerinfo") return this->handleCommandMusicBotPlayerInfo(cmd); else if (command == "musicbotplayeraction") return this->handleCommandMusicBotPlayerAction(cmd); - else if (command == "musicbotqueuelist") return this->handleCommandMusicBotQueueList(cmd).as_command_result(); - else if (command == "musicbotqueueadd") return this->handleCommandMusicBotQueueAdd(cmd).as_command_result(); - else if (command == "musicbotqueueremove") return this->handleCommandMusicBotQueueRemove(cmd).as_command_result(); - else if (command == "musicbotqueuereorder") return this->handleCommandMusicBotQueueReorder(cmd).as_command_result(); + else if (command == "musicbotqueuelist") return this->handleCommandMusicBotQueueList(cmd); + else if (command == "musicbotqueueadd") return this->handleCommandMusicBotQueueAdd(cmd); + else if (command == "musicbotqueueremove") return this->handleCommandMusicBotQueueRemove(cmd); + else if (command == "musicbotqueuereorder") return this->handleCommandMusicBotQueueReorder(cmd); else if (command == "musicbotplaylistassign") return this->handleCommandMusicBotPlaylistAssign(cmd); else if (command == "help") return this->handleCommandHelp(cmd); @@ -370,7 +372,7 @@ CommandResult ConnectedClient::handleCommand(Command &cmd) { else if (command == "conversationfetch") return this->handleCommandConversationFetch(cmd); else if (command == "conversationmessagedelete") return this->handleCommandConversationMessageDelete(cmd); - if (this->getType() == ClientType::CLIENT_QUERY) return CommandResult::NotImplemented; //Dont log query invalid commands + if (this->getType() == ClientType::CLIENT_QUERY) return command_result{error::command_not_found}; //Dont log query invalid commands if (this->getType() == ClientType::CLIENT_TEAMSPEAK) if (command.empty() || command.find_first_not_of(' ') == -1) { if (!this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_allow_invalid_packet, 1, this->currentChannel)) @@ -378,43 +380,43 @@ CommandResult ConnectedClient::handleCommand(Command &cmd) { } logError(this->getServerId(), "Missing command '{}'", command); - return CommandResult::NotImplemented; -} + return command_result{error::command_not_found}; +}; -CommandResult ConnectedClient::handleCommandServerGetVariables(Command &cmd) { +command_result ConnectedClient::handleCommandServerGetVariables(Command &cmd) { CMD_REQ_SERVER; this->notifyServerUpdated(_this.lock()); - return CommandResult::Success; + return command_result{error::ok}; } #define SERVEREDIT_CHK_PROP(name, perm, type)\ else if(key == name) { \ - if(!permissionGranted(permission::PERMTEST_HIGHEST, perm, 1, nullptr, true, cache, target_server, true)) return CommandResultPermissionError(perm); \ + if(!permissionGranted(permission::PERMTEST_HIGHEST, perm, 1, nullptr, true, cache, target_server, true)) return command_result{perm}; \ if(toApplay.count(key) == 0) toApplay[key] = cmd[key].as(); \ - if(!cmd[0][key].castable()) return {findError("parameter_invalid"), "Invalid type for " + key}; + if(!cmd[0][key].castable()) return command_result{error::parameter_invalid}; #define SERVEREDIT_CHK_PROP_CACHED(name, perm, type)\ else if(key == name) { \ - if(!this->permission_granted(this->cached_permission_value(perm), 1)) return CommandResultPermissionError(perm); \ + if(!this->permission_granted(this->cached_permission_value(perm), 1)) return command_result{perm}; \ if(toApplay.count(key) == 0) toApplay[key] = cmd[key].as(); \ - if(!cmd[0][key].castable()) return {findError("parameter_invalid"), "Invalid type for " + key}; + if(!cmd[0][key].castable()) return command_result{error::parameter_invalid}; #define SERVEREDIT_CHK_PROP2(name, perm, type_a, type_b)\ else if(key == name) { \ - if(!permissionGranted(permission::PERMTEST_HIGHEST, perm, 1, nullptr, true, cache, target_server, true)) return CommandResultPermissionError(perm); \ + if(!permissionGranted(permission::PERMTEST_HIGHEST, perm, 1, nullptr, true, cache, target_server, true)) return command_result{perm}; \ if(toApplay.count(key) == 0) toApplay[key] = cmd[key].as(); \ - if(!cmd[0][key].castable() && !!cmd[0][key].castable()) return {findError("parameter_invalid"), "Invalid type for " + key}; + if(!cmd[0][key].castable() && !!cmd[0][key].castable()) return command_result{error::parameter_invalid}; -CommandResult ConnectedClient::handleCommandServerEdit(Command &cmd) { +command_result ConnectedClient::handleCommandServerEdit(Command &cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(5); if (cmd[0].has("sid") && this->getServerId() != cmd["sid"].as()) - return {findError("server_invalid_id"), "Invalid server id! You can just edit the server where your're bound on"}; + return command_result{error::server_invalid_id}; auto target_server = this->server; if(cmd[0].has("sid")) { target_server = serverInstance->getVoiceServerManager()->findServerById(cmd["sid"]); - if(!target_server && cmd["sid"].as() != 0) return {findError("server_invalid_id")}; + if(!target_server && cmd["sid"].as() != 0) return command_result{error::server_invalid_id}; } auto cache = make_shared(); @@ -425,7 +427,7 @@ CommandResult ConnectedClient::handleCommandServerEdit(Command &cmd) { SERVEREDIT_CHK_PROP_CACHED("virtualserver_name_phonetic", permission::b_virtualserver_modify_name, string) } SERVEREDIT_CHK_PROP_CACHED("virtualserver_maxclients", permission::b_virtualserver_modify_maxclients, size_t) if (cmd["virtualserver_maxclients"].as() > 1024) - return {findError("accounting_slot_limit_reached"), "Do you really need more that 1024 slots?"}; + return command_result{error::accounting_slot_limit_reached, "Do you really need more that 1024 slots?"}; } SERVEREDIT_CHK_PROP_CACHED("virtualserver_reserved_slots", permission::b_virtualserver_modify_reserved_slots, size_t) } SERVEREDIT_CHK_PROP_CACHED("virtualserver_icon_id", permission::b_virtualserver_modify_icon_id, int64_t) } SERVEREDIT_CHK_PROP_CACHED("virtualserver_channel_temp_delete_delay_default", permission::b_virtualserver_modify_channel_temp_delete_delay_default, ChannelId) } @@ -433,22 +435,22 @@ CommandResult ConnectedClient::handleCommandServerEdit(Command &cmd) { SERVEREDIT_CHK_PROP_CACHED("virtualserver_default_server_group", permission::b_virtualserver_modify_default_servergroup, GroupId) if(target_server) { auto group = target_server->groups->findGroup(cmd["virtualserver_default_server_group"].as()); - if (!group || group->target() != GROUPTARGET_SERVER) return {findError("parameter_invalid"), "Invalid default server group!"}; + if (!group || group->target() != GROUPTARGET_SERVER) return command_result{error::parameter_invalid}; } } SERVEREDIT_CHK_PROP_CACHED("virtualserver_default_channel_group", permission::b_virtualserver_modify_default_channelgroup, GroupId) if(target_server) { auto group = target_server->groups->findGroup(cmd["virtualserver_default_channel_group"].as()); - if (!group || group->target() != GROUPTARGET_CHANNEL) return {findError("parameter_invalid"), "Invalid default channel group!"}; + if (!group || group->target() != GROUPTARGET_CHANNEL) return command_result{error::parameter_invalid}; } } SERVEREDIT_CHK_PROP_CACHED("virtualserver_default_channel_admin_group", permission::b_virtualserver_modify_default_channeladmingroup, GroupId) if(target_server) { auto group = target_server->groups->findGroup(cmd["virtualserver_default_channel_admin_group"].as()); - if (!group || group->target() != GROUPTARGET_CHANNEL) return {findError("parameter_invalid"), "Invalid default channel admin group!"}; + if (!group || group->target() != GROUPTARGET_CHANNEL) return command_result{error::parameter_invalid}; } } SERVEREDIT_CHK_PROP_CACHED("virtualserver_default_music_group", permission::b_virtualserver_modify_default_musicgroup, GroupId) if(target_server) { auto group = target_server->groups->findGroup(cmd["virtualserver_default_music_group"].as()); - if (!group || group->target() != GROUPTARGET_SERVER) return {findError("parameter_invalid"), "Invalid default music group!"}; + if (!group || group->target() != GROUPTARGET_SERVER) return command_result{error::parameter_invalid}; } } SERVEREDIT_CHK_PROP_CACHED("virtualserver_priority_speaker_dimm_modificator", permission::b_virtualserver_modify_priority_speaker_dimm_modificator, float) } @@ -508,7 +510,7 @@ CommandResult ConnectedClient::handleCommandServerEdit(Command &cmd) { SERVEREDIT_CHK_PROP_CACHED("virtualserver_music_bot_limit", permission::b_virtualserver_modify_music_bot_limit, int) } SERVEREDIT_CHK_PROP_CACHED("virtualserver_flag_password", permission::b_virtualserver_modify_password, bool) if (cmd["virtualserver_flag_password"].as() && !cmd[0].has("virtualserver_password")) - return {findError("parameter_invalid"), "Invalid password flag"}; + return command_result{error::parameter_invalid}; } SERVEREDIT_CHK_PROP_CACHED("virtualserver_password", permission::b_virtualserver_modify_password, string) if(cmd["virtualserver_password"].string().empty()) { toApplay["virtualserver_flag_password"] = "0"; @@ -548,7 +550,7 @@ CommandResult ConnectedClient::handleCommandServerEdit(Command &cmd) { } else { logError(target_server ? target_server->getServerId() : 0, "Client " + this->getDisplayName() + " tried to change a not existing server properties. (" + key + ")"); - //return CommandResult::NotImplemented; + //return command_result{error::not_implemented}; } } @@ -586,16 +588,16 @@ CommandResult ConnectedClient::handleCommandServerEdit(Command &cmd) { if (!keys.empty()) target_server->notifyServerEdited(_this.lock(), keys); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientGetVariables(Command &cmd) { +command_result ConnectedClient::handleCommandClientGetVariables(Command &cmd) { CMD_REQ_SERVER; auto client = this->server->findClient(cmd["clid"].as()); shared_lock tree_lock(this->channel_lock); if (!client || (client != this && !this->isClientVisible(client, false))) - return {findError("client_invalid_id"), ""}; + return command_result{error::client_invalid_id, ""}; deque> props; for (auto &prop : client->properties()->list_properties(property::FLAG_CLIENT_VARIABLE, this->getType() == CLIENT_TEAMSPEAK ? property::FLAG_NEW : (uint16_t) 0)) { @@ -603,16 +605,16 @@ CommandResult ConnectedClient::handleCommandClientGetVariables(Command &cmd) { } this->notifyClientUpdated(client, props, false); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientKick(Command &cmd) { +command_result ConnectedClient::handleCommandClientKick(Command &cmd) { CMD_REQ_SERVER; CMD_CHK_AND_INC_FLOOD_POINTS(25); 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 kick a music bot!"}; + if (!client) return command_result{error::client_invalid_id}; + if (client->getType() == CLIENT_MUSIC) return command_result{error::client_invalid_type, "You cant kick a music bot!"}; std::shared_ptr targetChannel = nullptr; auto type = cmd["reasonid"].as(); if (type == ViewReasonId::VREASON_CHANNEL_KICK) { @@ -623,7 +625,7 @@ CommandResult ConnectedClient::handleCommandClientKick(Command &cmd) { auto channel = client->currentChannel; PERM_CHECK_CHANNELR(permission::i_client_kick_from_server_power, client->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_needed_kick_from_server_power, channel), channel, true); targetChannel = nullptr; - } else return CommandResult::NotImplemented; + } else return command_result{error::not_implemented}; if (targetChannel) { this->server->notify_client_kick(client, this->ref(), cmd["reasonmsg"].as(), targetChannel); @@ -632,10 +634,10 @@ CommandResult ConnectedClient::handleCommandClientKick(Command &cmd) { client->closeConnection(system_clock::now() + seconds(1)); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelGetDescription(Command &cmd) { +command_result ConnectedClient::handleCommandChannelGetDescription(Command &cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(0); RESOLVE_CHANNEL_R(cmd["cid"], true); auto channel = dynamic_pointer_cast(l_channel->entry); @@ -646,15 +648,15 @@ CommandResult ConnectedClient::handleCommandChannelGetDescription(Command &cmd) } this->sendChannelDescription(channel, true); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandGetConnectionInfo(Command &cmd) { +command_result ConnectedClient::handleCommandGetConnectionInfo(Command &cmd) { CMD_REQ_SERVER; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto client = this->server->findClient(cmd["clid"].as()); - if (!client) return {findError("client_invalid_id"), "invalid client id"}; + if (!client) return command_result{error::client_invalid_id}; bool send_temp; auto info = client->request_connection_info(_this.lock(), send_temp); @@ -664,10 +666,10 @@ CommandResult ConnectedClient::handleCommandGetConnectionInfo(Command &cmd) { this->notifyConnectionInfo(client, nullptr); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandSetConnectionInfo(Command &cmd) { +command_result ConnectedClient::handleCommandSetConnectionInfo(Command &cmd) { auto info = std::make_shared(); info->timestamp = chrono::system_clock::now(); for (const auto &key : cmd[0].keys()) @@ -695,10 +697,10 @@ CommandResult ConnectedClient::handleCommandSetConnectionInfo(Command &cmd) { } for(const auto& receiver : receivers) receiver->notifyConnectionInfo(_this.lock(), info); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandServerRequestConnectionInfo(Command &) { +command_result ConnectedClient::handleCommandServerRequestConnectionInfo(Command &) { CMD_REQ_SERVER; CACHED_PERM_CHECK(permission::b_virtualserver_connectioninfo_view, 1, true); @@ -731,19 +733,19 @@ CommandResult ConnectedClient::handleCommandServerRequestConnectionInfo(Command notify[0]["connection_ping"] = this->server->averagePing(); this->sendCommand(notify); - return CommandResult::Success; + return command_result{error::ok}; } //connectioninfoautoupdate connection_server2client_packetloss_speech=0.0000 connection_server2client_packetloss_keepalive=0.0010 connection_server2client_packetloss_control=0.0000 connection_server2client_packetloss_total=0.0009 -CommandResult ConnectedClient::handleCommandConnectionInfoAutoUpdate(Command &cmd) { +command_result ConnectedClient::handleCommandConnectionInfoAutoUpdate(Command &cmd) { this->properties()[property::CONNECTION_SERVER2CLIENT_PACKETLOSS_KEEPALIVE] = cmd["connection_server2client_packetloss_keepalive"].as(); this->properties()[property::CONNECTION_SERVER2CLIENT_PACKETLOSS_CONTROL] = cmd["connection_server2client_packetloss_control"].as(); this->properties()[property::CONNECTION_SERVER2CLIENT_PACKETLOSS_SPEECH] = cmd["connection_server2client_packetloss_speech"].as(); this->properties()[property::CONNECTION_SERVER2CLIENT_PACKETLOSS_TOTAL] = cmd["connection_server2client_packetloss_total"].as(); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientGetIds(Command &cmd) { +command_result ConnectedClient::handleCommandClientGetIds(Command &cmd) { CMD_REQ_SERVER; bool error = false; @@ -776,12 +778,12 @@ CommandResult ConnectedClient::handleCommandClientGetIds(Command &cmd) { this->sendCommand(notify); } if(error) { - return {findError("database_empty_result"), "empty!"}; + return command_result{error::database_empty_result}; } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelSubscribe(Command &cmd) { +command_result ConnectedClient::handleCommandChannelSubscribe(Command &cmd) { CMD_REF_SERVER(ref_server); CMD_RESET_IDLE; @@ -795,11 +797,11 @@ CommandResult ConnectedClient::handleCommandChannelSubscribe(Command &cmd) { for (int index = 0; index < cmd.bulkCount(); index++) { auto local_channel = this->channel_view()->find_channel(cmd[index]["cid"].as()); if(!local_channel) - return {findError("channel_invalid_id"), "Cant resolve channel"}; + return command_result{error::channel_invalid_id, "Cant resolve channel"}; auto channel = this->server->channelTree->findChannel(cmd[index]["cid"].as()); if (!channel) - return {findError("channel_invalid_id"), "Cant resolve channel"}; + return command_result{error::channel_invalid_id, "Cant resolve channel"}; channels.push_back(channel); if(!flood_points && system_clock::now() - local_channel->view_timestamp > seconds(5)) { @@ -812,10 +814,10 @@ CommandResult ConnectedClient::handleCommandChannelSubscribe(Command &cmd) { this->subscribeChannel(channels, false, false); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelSubscribeAll(Command &cmd) { +command_result ConnectedClient::handleCommandChannelSubscribeAll(Command &cmd) { CMD_REQ_SERVER; CMD_CHK_AND_INC_FLOOD_POINTS(20); @@ -825,10 +827,10 @@ CommandResult ConnectedClient::handleCommandChannelSubscribeAll(Command &cmd) { this->subscribeChannel(this->server->channelTree->channels(), false, false); this->subscribeToAll = true; } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelUnsubscribe(Command &cmd) { +command_result ConnectedClient::handleCommandChannelUnsubscribe(Command &cmd) { CMD_REQ_SERVER; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -845,10 +847,10 @@ CommandResult ConnectedClient::handleCommandChannelUnsubscribe(Command &cmd) { this->unsubscribeChannel(channels, false); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelUnsubscribeAll(Command &cmd) { +command_result ConnectedClient::handleCommandChannelUnsubscribeAll(Command &cmd) { CMD_REQ_SERVER; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -858,10 +860,10 @@ CommandResult ConnectedClient::handleCommandChannelUnsubscribeAll(Command &cmd) this->unsubscribeChannel(this->server->channelTree->channels(), false); this->subscribeToAll = false; } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPermissionList(Command &cmd) { +command_result ConnectedClient::handleCommandPermissionList(Command &cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(5); static std::string permission_list_string[ClientType::MAX]; @@ -905,7 +907,7 @@ CommandResult ConnectedClient::handleCommandPermissionList(Command &cmd) { } else { this->sendCommand(build_permission_list(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifypermissionlist" : "", type)); } - return CommandResult::Success; + return command_result{error::ok}; } @@ -920,7 +922,7 @@ do { \ } \ } while(0) -CommandResult ConnectedClient::handleCommandPropertyList(ts::Command& cmd) { +command_result ConnectedClient::handleCommandPropertyList(ts::Command& cmd) { Command response(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifypropertylist" : ""); { @@ -946,29 +948,29 @@ CommandResult ConnectedClient::handleCommandPropertyList(ts::Command& cmd) { M(property::ConnectionProperties); this->sendCommand(response); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandServerGroupList(Command &) { +command_result ConnectedClient::handleCommandServerGroupList(Command &) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); CACHED_PERM_CHECK(permission::b_virtualserver_servergroup_list, 1, true); this->notifyServerGroupList(); this->command_times.servergrouplist = system_clock::now(); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelGroupAdd(Command &cmd) { +command_result ConnectedClient::handleCommandChannelGroupAdd(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); CACHED_PERM_CHECK(permission::b_virtualserver_channelgroup_create, 1, true); auto group_manager = this->server ? this->server->getGroupManager() : serverInstance->getGroupManager().get(); - if(cmd["type"].as() == GroupType::GROUP_TYPE_NORMAL && !this->server) return {findError("parameter_invalid"), "You cant create normal channel groups on the template server"}; - if(cmd["name"].string().empty()) return {findError("parameter_invalid"), "invalid group name"}; + if(cmd["type"].as() == GroupType::GROUP_TYPE_NORMAL && !this->server) return command_result{error::parameter_invalid, "You cant create normal channel groups on the template server"}; + if(cmd["name"].string().empty()) return command_result{error::parameter_invalid, "invalid group name"}; for(const auto& gr : group_manager->availableServerGroups(true)) - if(gr->name() == cmd["name"].string() && gr->target() == GroupTarget::GROUPTARGET_CHANNEL) return {findError("parameter_invalid"), "Group already exists"}; + if(gr->name() == cmd["name"].string() && gr->target() == GroupTarget::GROUPTARGET_CHANNEL) return command_result{error::parameter_invalid, "Group already exists"}; auto group = group_manager->createGroup(GroupTarget::GROUPTARGET_CHANNEL, cmd["type"].as(), cmd["name"].string()); if (group) { group->permissions()->set_permission(permission::b_group_is_permanent, {1, 0}, permission::v2::set_value, permission::v2::do_nothing); @@ -976,12 +978,12 @@ CommandResult ConnectedClient::handleCommandChannelGroupAdd(Command &cmd) { this->server->forEachClient([](shared_ptr cl) { cl->notifyChannelGroupList(); }); - } else return {findError("parameter_invalid"), "invalid server group id"}; - return CommandResult::Success; + } else return command_result{error::group_invalid_id}; + return command_result{error::ok}; } //name=Channel\sAdmin scgid=5 tcgid=4 type=1 -CommandResult ConnectedClient::handleCommandChannelGroupCopy(Command &cmd) { +command_result ConnectedClient::handleCommandChannelGroupCopy(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -994,7 +996,7 @@ CommandResult ConnectedClient::handleCommandChannelGroupCopy(Command &cmd) { auto source_group = group_manager->findGroup(source_group_id); if(!source_group || source_group->target() != GROUPTARGET_CHANNEL) - return {findError("group_invalid_id"), "invalid source group"}; + return command_result{error::group_invalid_id, "invalid source group"}; const auto group_type_modificable = [&](GroupType type) { switch(type) { @@ -1016,7 +1018,7 @@ CommandResult ConnectedClient::handleCommandChannelGroupCopy(Command &cmd) { { auto result = group_type_modificable(source_group->type()); if(result != permission::undefined) - return CommandResultPermissionError{result}; + return command_result{result}; } auto global_update = false; @@ -1024,19 +1026,19 @@ CommandResult ConnectedClient::handleCommandChannelGroupCopy(Command &cmd) { //Copy an existing group auto target_group = group_manager->findGroup(cmd["tcgid"]); if(!target_group || target_group->target() != GROUPTARGET_CHANNEL) - return {findError("group_invalid_id"), "invalid target group"}; + return command_result{error::group_invalid_id, "invalid target group"}; { auto result = group_type_modificable(target_group->type()); if(result != permission::undefined) - return CommandResultPermissionError{result}; + return command_result{result}; } if(!target_group->permission_granted(permission::i_channel_group_needed_modify_power, this->calculate_permission_value(permission::i_channel_group_modify_power, 0), true)) - return CommandResultPermissionError{permission::i_channel_group_modify_power}; + return command_result{permission::i_channel_group_modify_power}; if(!group_manager->copyGroupPermissions(source_group, target_group)) - return {findError("vs_critical"), "failed to copy group permissions"}; + return command_result{error::vs_critical, "failed to copy group permissions"}; global_update = !this->server || !group_manager->isLocalGroup(target_group); } else { @@ -1046,18 +1048,18 @@ CommandResult ConnectedClient::handleCommandChannelGroupCopy(Command &cmd) { { auto result = group_type_modificable(target_type); if(result != permission::undefined) - return CommandResultPermissionError{result}; + return command_result{result}; } if(!ref_server && target_type == GroupType::GROUP_TYPE_NORMAL) - return {findError("parameter_invalid"), "You cant create normal groups on the template server!"}; + return command_result{error::parameter_invalid, "You cant create normal groups on the template server!"}; if(!group_manager->findGroup(GroupTarget::GROUPTARGET_CHANNEL, cmd["name"].string()).empty()) - return {findError("group_name_used"), "You cant create normal groups on the template server!"}; + return command_result{error::group_name_inuse, "You cant create normal groups on the template server!"}; auto target_group_id = group_manager->copyGroup(source_group, target_type, cmd["name"], target_type != GroupType::GROUP_TYPE_NORMAL ? 0 : this->getServerId()); if(target_group_id == 0) - return {findError("vs_critical"), "failed to copy group"}; + return command_result{error::vs_critical, "failed to copy group"}; if(this->getType() == ClientType::CLIENT_QUERY) { Command notify(""); @@ -1073,16 +1075,16 @@ CommandResult ConnectedClient::handleCommandChannelGroupCopy(Command &cmd) { server->forEachClient([](shared_ptr cl) { cl->notifyChannelGroupList(); }); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelGroupRename(Command &cmd) { +command_result ConnectedClient::handleCommandChannelGroupRename(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto group_manager = this->server ? this->server->getGroupManager() : serverInstance->getGroupManager().get(); auto serverGroup = group_manager->findGroup(cmd["cgid"].as()); - if (!serverGroup || serverGroup->target() != GROUPTARGET_CHANNEL) return {findError("parameter_invalid"), "invalid channel group id"}; + if (!serverGroup || serverGroup->target() != GROUPTARGET_CHANNEL) return command_result{error::parameter_invalid, "invalid channel group id"}; GROUP_PERMISSION_TEST(permission::i_channel_group_modify_power, permission::i_channel_group_needed_modify_power, serverGroup, true); group_manager->renameGroup(serverGroup, cmd["name"].string()); @@ -1091,32 +1093,32 @@ CommandResult ConnectedClient::handleCommandChannelGroupRename(Command &cmd) { cl->notifyChannelGroupList(); }); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelGroupDel(Command &cmd) { +command_result ConnectedClient::handleCommandChannelGroupDel(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto group_manager = this->server ? this->server->getGroupManager() : serverInstance->getGroupManager().get(); auto channel_group = group_manager->findGroup(cmd["cgid"].as()); - if (!channel_group || channel_group->target() != GROUPTARGET_CHANNEL) return {findError("parameter_invalid"), "invalid channel group id"}; + if (!channel_group || channel_group->target() != GROUPTARGET_CHANNEL) return command_result{error::parameter_invalid, "invalid channel group id"}; CACHED_PERM_CHECK(permission::b_virtualserver_channelgroup_delete, 1, true); if(this->server) { if(this->server->properties()[property::VIRTUALSERVER_DEFAULT_CHANNEL_GROUP] == channel_group->groupId()) - return {findError("parameter_invalid"), "Could not delete default channel group!"}; + return command_result{error::parameter_invalid, "Could not delete default channel group!"}; if(this->server->properties()[property::VIRTUALSERVER_DEFAULT_CHANNEL_ADMIN_GROUP] == channel_group->groupId()) - return {findError("parameter_invalid"), "Could not delete default channel admin group!"}; + return command_result{error::parameter_invalid, "Could not delete default channel admin group!"}; } if(serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_CHANNELDEFAULT_GROUP] == channel_group->groupId()) - return {findError("parameter_invalid"), "Could not delete instance default channel group!"}; + return command_result{error::parameter_invalid, "Could not delete instance default channel group!"}; if(serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_CHANNELADMIN_GROUP] == channel_group->groupId()) - return {findError("parameter_invalid"), "Could not delete instance default channel admin group!"}; + return command_result{error::parameter_invalid, "Could not delete instance default channel admin group!"}; if (!cmd["force"].as()) if (!group_manager->listGroupMembers(channel_group, false).empty()) - return {findError("database_empty_result"), "group not empty!"}; + return command_result{error::database_empty_result, "group not empty!"}; if (group_manager->deleteGroup(channel_group) && this->server) { this->server->forEachClient([&](shared_ptr cl) { @@ -1128,20 +1130,20 @@ CommandResult ConnectedClient::handleCommandChannelGroupDel(Command &cmd) { }); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelGroupList(Command &) { +command_result ConnectedClient::handleCommandChannelGroupList(Command &) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); CACHED_PERM_CHECK(permission::b_virtualserver_channelgroup_list, 1, true); this->notifyChannelGroupList(); this->command_times.servergrouplist = system_clock::now(); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelGroupClientList(Command &cmd) { +command_result ConnectedClient::handleCommandChannelGroupClientList(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -1154,7 +1156,7 @@ CommandResult ConnectedClient::handleCommandChannelGroupClientList(Command &cmd) if(cmd[0].has("cgid") && cmd["cgid"].as() > 0) { auto group = this->server->getGroupManager()->findGroup(cmd["cgid"]); if(!group || group->target() != GroupTarget::GROUPTARGET_CHANNEL) - return {findError("parameter_invalid"), "invalid channel group id"}; + return command_result{error::parameter_invalid, "invalid channel group id"}; query += " AND `groupId` = :groupId"; variables.push_back({":groupId", cmd["cgid"].as()}); } else { @@ -1168,7 +1170,7 @@ CommandResult ConnectedClient::handleCommandChannelGroupClientList(Command &cmd) if(cmd[0].has("cid") && cmd["cid"].as() > 0) { auto channel = this->server->getChannelTree()->findChannel(cmd["cid"]); if(!channel) - return {findError("parameter_invalid"), "invalid channel id"}; + return command_result{error::parameter_invalid, "invalid channel id"}; query += " AND `channelId` = :cid"; variables.push_back({":cid", cmd["cid"].as()}); } @@ -1200,32 +1202,32 @@ CommandResult ConnectedClient::handleCommandChannelGroupClientList(Command &cmd) result[index]["cldbid"] = cldbid; index++; }, result, index); - if (index == 0) return {findError("database_empty_result"), "empty"}; + if (index == 0) return command_result{error::database_empty_result}; this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelGroupPermList(Command &cmd) { +command_result ConnectedClient::handleCommandChannelGroupPermList(Command &cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(5); CACHED_PERM_CHECK(permission::b_virtualserver_channelgroup_permission_list, 1, true); auto channelGroup = (this->server ? this->server->groups : serverInstance->getGroupManager().get())->findGroup(cmd["cgid"].as()); - if (!channelGroup || channelGroup->target() != GROUPTARGET_CHANNEL) return {findError("parameter_invalid"), "invalid channel group id"}; - if (!this->notifyGroupPermList(channelGroup, cmd.hasParm("permsid"))) return {findError("database_empty_result"), "empty"}; + if (!channelGroup || channelGroup->target() != GROUPTARGET_CHANNEL) return command_result{error::parameter_invalid, "invalid channel group id"}; + if (!this->notifyGroupPermList(channelGroup, cmd.hasParm("permsid"))) return command_result{error::database_empty_result}; if(this->getType() == ClientType::CLIENT_TEAMSPEAK && this->command_times.last_notify + this->command_times.notify_timeout < system_clock::now()) { this->sendTSPermEditorWarning(); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelGroupAddPerm(Command &cmd) { +command_result ConnectedClient::handleCommandChannelGroupAddPerm(Command &cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(5); auto group_manager = this->server ? this->server->getGroupManager() : serverInstance->getGroupManager().get(); auto channelGroup = group_manager->findGroup(cmd["cgid"].as()); - if (!channelGroup || channelGroup->target() != GROUPTARGET_CHANNEL) return {findError("parameter_invalid"), "invalid channel group id"}; + if (!channelGroup || channelGroup->target() != GROUPTARGET_CHANNEL) return command_result{error::parameter_invalid, "invalid channel group id"}; GROUP_PERMISSION_TEST(permission::i_channel_group_modify_power, permission::i_channel_group_needed_modify_power, channelGroup, true); auto maxValue = this->getPermissionGrantValue(permission::PERMTEST_ORDERED, permission::i_permission_modify_power, this->currentChannel); @@ -1239,10 +1241,10 @@ CommandResult ConnectedClient::handleCommandChannelGroupAddPerm(Command &cmd) { auto val = cmd[index]["permvalue"].as(); if(permission_require_granted_value(permType) && val > maxValue) - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; if(!ignoreGrant && !this->permissionGrantGranted(permission::PERMTEST_ORDERED, permType, 1, this->currentChannel)) - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; if (grant) { permission_manager->set_permission(permType, {0, cmd[index]["permvalue"]}, permission::v2::PermissionUpdateType::do_nothing, permission::v2::PermissionUpdateType::set_value); @@ -1279,14 +1281,14 @@ CommandResult ConnectedClient::handleCommandChannelGroupAddPerm(Command &cmd) { } }); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelGroupDelPerm(Command &cmd) { +command_result ConnectedClient::handleCommandChannelGroupDelPerm(Command &cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(5); auto group_manager = this->server ? this->server->getGroupManager() : serverInstance->getGroupManager().get(); auto channelGroup = group_manager->findGroup(cmd["cgid"].as()); - if (!channelGroup || channelGroup->target() != GROUPTARGET_CHANNEL) return {findError("parameter_invalid"), "invalid channel group id"}; + if (!channelGroup || channelGroup->target() != GROUPTARGET_CHANNEL) return command_result{error::parameter_invalid, "invalid channel group id"}; GROUP_PERMISSION_TEST(permission::i_channel_group_modify_power, permission::i_channel_group_needed_modify_power, channelGroup, true); bool ignoreGrant = this->permission_granted(this->cached_permission_value(permission::b_permission_modify_power_ignore), 1); @@ -1298,7 +1300,7 @@ CommandResult ConnectedClient::handleCommandChannelGroupDelPerm(Command &cmd) { PARSE_PERMISSION(cmd) if(!ignoreGrant && !this->permissionGrantGranted(permission::PERMTEST_ORDERED, permType, 1, this->currentChannel)) - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; if (grant) { permission_manager->set_permission(permType, permission::v2::empty_permission_values, permission::v2::PermissionUpdateType::do_nothing, permission::v2::PermissionUpdateType::delete_value); } else { @@ -1330,12 +1332,12 @@ CommandResult ConnectedClient::handleCommandChannelGroupDelPerm(Command &cmd) { } }); } - return CommandResult::Success; + return command_result{error::ok}; } using namespace std::chrono; -CommandResult ConnectedClient::handleCommandClientMove(Command &cmd) { +command_result ConnectedClient::handleCommandClientMove(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(10); @@ -1344,16 +1346,16 @@ CommandResult ConnectedClient::handleCommandClientMove(Command &cmd) { auto target_client_id = cmd["clid"].as(); auto target_client = target_client_id == 0 ? this->ref() : this->server->findClient(target_client_id); if(!target_client) { - return {findError("client_invalid_id"), "Invalid target clid"}; + return command_result{error::client_invalid_id, "Invalid target clid"}; } if(!target_client->currentChannel) { if(target_client != this) - return {findError("client_invalid_id"), "Invalid target clid"}; + return command_result{error::client_invalid_id, "Invalid target clid"}; } auto channel = this->server->channelTree->findChannel(cmd["cid"].as()); if (!channel) { - return {findError("channel_invalid_id")}; + return command_result{error::channel_invalid_id}; } auto permission_cache = make_shared(); @@ -1361,7 +1363,7 @@ CommandResult ConnectedClient::handleCommandClientMove(Command &cmd) { cmd["cpw"] = ""; if (!channel->passwordMatch(cmd["cpw"], true)) if (!this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_channel_join_ignore_password, 1, channel, true, permission_cache)) - return {findError("channel_invalid_password"), "invalid password"}; + return command_result{error::channel_invalid_password}; switch(channel->channelType()) { case ChannelType::permanent: @@ -1379,7 +1381,7 @@ CommandResult ConnectedClient::handleCommandClientMove(Command &cmd) { if(!channel->properties()[property::CHANNEL_FLAG_MAXCLIENTS_UNLIMITED].as()) { auto maxClients = channel->properties()[property::CHANNEL_MAXCLIENTS].as(); if (maxClients >= 0 && maxClients <= this->server->getClientsByChannel(channel).size()) - return {findError("channel_maxclients_reached"), ""}; + return command_result{error::channel_maxclients_reached}; } if(!channel->properties()[property::CHANNEL_FLAG_MAXFAMILYCLIENTS_UNLIMITED].as()) { shared_ptr family_root; @@ -1393,7 +1395,7 @@ CommandResult ConnectedClient::handleCommandClientMove(Command &cmd) { auto clients = 0; for(const auto& entry : this->server->getClientsByChannelRoot(channel, false)) if(entry.get() != this) clients++; //Dont count the client itself if (maxClients >= 0 && maxClients <= clients) - return {findError("channel_maxfamily_reached"), ""}; + return command_result{error::channel_maxfamily_reached}; } } } @@ -1409,7 +1411,7 @@ CommandResult ConnectedClient::handleCommandClientMove(Command &cmd) { if (val != permNotGranted && val > 0) { auto st = this->permissionValue(permission::PERMTEST_ORDERED, permission::b_client_ignore_sticky, this->currentChannel, permission_cache_current); if (st != 1) - return CommandResultPermissionError{permission::b_client_is_sticky}; + return command_result{permission::b_client_is_sticky}; } } @@ -1440,11 +1442,11 @@ CommandResult ConnectedClient::handleCommandClientMove(Command &cmd) { if(server_channel_w_lock.owns_lock()) server_channel_w_lock.unlock(); } - return CommandResult::Success; + return command_result{error::ok}; } //TODO: Test if parent or previous is deleted! -CommandResult ConnectedClient::handleCommandChannelCreate(Command &cmd) { +command_result ConnectedClient::handleCommandChannelCreate(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); CMD_CHK_PARM_COUNT(1); @@ -1462,11 +1464,11 @@ CommandResult ConnectedClient::handleCommandChannelCreate(Command &cmd) { else if (cmd[0]["channel_flag_semi_permanent"].as()) CACHED_PERM_CHECK(permission::b_channel_create_semi_permanent, 1); else CACHED_PERM_CHECK(permission::b_channel_create_temporary, 1); - if (!cmd[0]["channel_flag_permanent"].as() && !this->server) return {findError("parameter_invalid"), "You can only create a permanent channel"}; + if (!cmd[0]["channel_flag_permanent"].as() && !this->server) return command_result{error::parameter_invalid, "You can only create a permanent channel"}; if (cmd[0]["channel_flag_default"].as()) CACHED_PERM_CHECK(permission::b_channel_create_with_default, 1); if (cmd[0]["channel_flag_password"].as()) CACHED_PERM_CHECK(permission::b_channel_create_with_password, 1); - else if(this->permission_granted(this->cached_permission_value(permission::b_channel_create_modify_with_force_password), 1)) return CommandResultPermissionError{permission::b_channel_create_modify_with_force_password}; + else if(this->permission_granted(this->cached_permission_value(permission::b_channel_create_modify_with_force_password), 1)) return command_result{permission::b_channel_create_modify_with_force_password}; if(cmd[0].has("channel_password") && this->getType() == ClientType::CLIENT_QUERY) cmd["channel_password"] = base64::decode(digest::sha1(cmd["channel_password"].string())); @@ -1526,28 +1528,28 @@ CommandResult ConnectedClient::handleCommandChannelCreate(Command &cmd) { if(max_channels >= 0) { if(max_channels <= created_perm + created_semi + created_tmp) - return CommandResultPermissionError{permission::i_client_max_channels}; + return command_result{permission::i_client_max_channels}; } if (cmd[0]["channel_flag_permanent"].as()) { max_channels = this->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_max_permanent_channels, nullptr, permission_cache); if(max_channels >= 0) { if(max_channels <= created_perm) - return CommandResultPermissionError{permission::i_client_max_permanent_channels}; + return command_result{permission::i_client_max_permanent_channels}; } } else if (cmd[0]["channel_flag_semi_permanent"].as()) { max_channels = this->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_max_semi_channels, nullptr, permission_cache); if(max_channels >= 0) { if(max_channels <= created_semi) - return CommandResultPermissionError{permission::i_client_max_semi_channels}; + return command_result{permission::i_client_max_semi_channels}; } } else { max_channels = this->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_max_temporary_channels, nullptr, permission_cache); if(max_channels >= 0) { if(max_channels <= created_tmp) - return CommandResultPermissionError{permission::i_client_max_temporary_channels}; + return command_result{permission::i_client_max_temporary_channels}; } } } @@ -1560,7 +1562,7 @@ CommandResult ConnectedClient::handleCommandChannelCreate(Command &cmd) { { //Checkout the parent(s) if (cmd[0].has("cpid") && cmd["cpid"].as() != 0 && cmd["cpid"].as() != -1) { parent = target_tree->findLinkedChannel(cmd["cpid"].as()); - if (!parent) return {findError("channel_invalid_id"), "Cant resolve parent channel"}; + if (!parent) return command_result{error::channel_invalid_id, "Cant resolve parent channel"}; } { @@ -1575,13 +1577,13 @@ CommandResult ConnectedClient::handleCommandChannelCreate(Command &cmd) { channel_deep++; { const auto typed_parent = dynamic_pointer_cast(local_parent->entry); - if(typed_parent->deleted) return {findError("channel_is_deleted"), "Oneof parent is deleted"}; + if(typed_parent->deleted) return command_result{error::channel_is_deleted, "Oneof parent is deleted"}; } local_parent = local_parent->parent.lock(); } - if(min_channel_deep >= 0 && channel_deep < min_channel_deep) return CommandResultPermissionError{permission::i_channel_min_depth}; - if(max_channel_deep >= 0 && channel_deep > max_channel_deep) return CommandResultPermissionError{permission::i_channel_max_depth}; + if(min_channel_deep >= 0 && channel_deep < min_channel_deep) return command_result{permission::i_channel_min_depth}; + if(max_channel_deep >= 0 && channel_deep > max_channel_deep) return command_result{permission::i_channel_max_depth}; } } } @@ -1596,15 +1598,15 @@ CommandResult ConnectedClient::handleCommandChannelCreate(Command &cmd) { } - if (cmd["channel_name"].string().length() < 1) return {findError("channel_name_inuse"), "Invalid channel name"}; + if (cmd["channel_name"].string().length() < 1) return command_result{error::channel_name_inuse, "Invalid channel name"}; { - if (target_tree->findChannel(cmd["channel_name"].as(), parent ? dynamic_pointer_cast(parent->entry) : nullptr)) return {findError("channel_name_inuse"), "Name already in use"}; + if (target_tree->findChannel(cmd["channel_name"].as(), parent ? dynamic_pointer_cast(parent->entry) : nullptr)) return command_result{error::channel_name_inuse, "Name already in use"}; created_channel = target_tree->createChannel(parent ? parent->entry->channelId() : (ChannelId) 0, cmd[0].has("channel_order") ? cmd["channel_order"].as() : (ChannelId) 0, cmd["channel_name"].as()); } - if (!created_channel) return {findError("channel_invalid_flags"), "Could not create channel"}; + if (!created_channel) return command_result{error::channel_invalid_flags, "Could not create channel"}; auto created_linked_channel = target_tree->findLinkedChannel(created_channel->channelId()); sassert(created_linked_channel); @@ -1699,10 +1701,10 @@ CommandResult ConnectedClient::handleCommandChannelCreate(Command &cmd) { ); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelDelete(Command &cmd) { +command_result ConnectedClient::handleCommandChannelDelete(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -1710,12 +1712,12 @@ CommandResult ConnectedClient::handleCommandChannelDelete(Command &cmd) { auto channel = dynamic_pointer_cast(l_channel->entry); assert(channel); if(channel->deleted) /* channel gets already removed */ - return CommandResult::Success; + return command_result{error::ok}; CHANNEL_PERMISSION_TEST(permission::i_channel_delete_power, permission::i_channel_needed_delete_power, channel, true); for(const auto& ch : channel_tree->channels(channel)) { if(ch->defaultChannel()) - return {findError("channel_can_not_delete_default"), "The channel tree you're going to delete contains the default channel!"}; + return command_result{error::channel_can_not_delete_default}; } if(this->server) { @@ -1728,7 +1730,7 @@ CommandResult ConnectedClient::handleCommandChannelDelete(Command &cmd) { auto channel_ids = channel_tree->deleteChannelRoot(channel); this->notifyChannelDeleted(channel_ids, this->ref()); } - return CommandResult::Success; + return command_result{error::ok}; } inline ssize_t count_characters(const std::string& in) { @@ -1771,7 +1773,7 @@ inline ssize_t count_characters(const std::string& in) { * 3. Apply changed, test for advanced requirements like channel name etc * 4. notify everyone */ -CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { +command_result ConnectedClient::handleCommandChannelEdit(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -1780,7 +1782,7 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { assert(channel); if(channel->deleted) { /* channel gets already removed */ - return CommandResult::Success; + return command_result{error::ok}; } std::deque> keys; @@ -1829,16 +1831,16 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { require_write_lock = true; } else if (key == "channel_flag_default") { if(!cmd["channel_flag_default"].as()) - return {findError("channel_invalid_flags")}; + return command_result{error::channel_invalid_flags}; CHANNEL_PERM_TEST(permission::b_channel_modify_make_default, 1, true); require_write_lock = true; } else if (key == "channel_name") { CHANNEL_PERM_TEST(permission::b_channel_modify_name, 1, true); if (count_characters(cmd["channel_name"]) < 1) - return {findError("channel_name_inuse"), "Invalid channel name (too short)"}; + return command_result{error::channel_name_invalid}; if (count_characters(cmd["channel_name"]) > 40) - return {findError("channel_name_inuse"), "Invalid channel name (too long)"}; + return command_result{error::channel_name_invalid}; require_write_lock = true; update_name = true; } else if (key == "channel_name_phonetic") { @@ -1852,9 +1854,9 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { auto bbcode_url = bbcode::sloppy::has_url(cmd[key]); debugMessage(this->getServerId(), "Channel description contains bb codes: Image: {} URL: {}", bbcode_image, bbcode_url); if(bbcode_image && !this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_use_bbcode_image, 1, this->currentChannel)) - return CommandResultPermissionError{permission::b_client_use_bbcode_image}; + return command_result{permission::b_client_use_bbcode_image}; if(bbcode_url && !this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_use_bbcode_url, 1, this->currentChannel)) - return CommandResultPermissionError{permission::b_client_use_bbcode_url}; + return command_result{permission::b_client_use_bbcode_url}; } } else if (key == "channel_codec") { CHANNEL_PERM_TEST(permission::b_channel_modify_codec, 1, true); @@ -1919,14 +1921,14 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { /* not that while we're waiting to edit the server the channel got deleted... fuck my english */ if(channel->deleted) - return CommandResult::Success; + return command_result{error::ok}; } /* test the password parameters */ if(update_password) { if(!cmd[0].has("channel_password")) { if(cmd[0].has("channel_flag_password") && cmd["channel_flag_password"].as()) - return {findError("parameter_missing"), ""}; + return command_result{error::parameter_missing}; else cmd["channel_password"] = ""; /* no password set */ keys.push_back(property::info(property::CHANNEL_PASSWORD)); @@ -1938,7 +1940,7 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { if(cmd["channel_flag_password"].as()) { if(cmd["channel_password"].string().empty()) - return {findError("channel_invalid_flags")}; /* we cant enable a password without a given password */ + return command_result{error::channel_invalid_flags}; /* we cant enable a password without a given password */ /* we've to "encode" the password */ if(this->getType() == ClientType ::CLIENT_QUERY) @@ -1951,7 +1953,7 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { /* test the default channel update */ if(cmd[0].has("channel_flag_default") || channel->defaultChannel()) { if(target_channel_type != ChannelType::permanent) - return {findError("channel_default_require_permanent")}; /* default channel is not allowed to be non permanent */ + return command_result{error::channel_default_require_permanent}; /* default channel is not allowed to be non permanent */ if((cmd[0].has("channel_flag_password") && cmd["channel_flag_password"].as()) || channel->properties()[property::CHANNEL_FLAG_PASSWORD]) { cmd["channel_flag_password"] = false; @@ -1997,11 +1999,11 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { /* test if any child is the default channel */ for(const auto& child : channel_tree->channels(channel)) if(child->defaultChannel()) - return {findError("channel_default_require_permanent")}; /* default channel is not allowed to be non permanent */ + return command_result{error::channel_default_require_permanent}; /* default channel is not allowed to be non permanent */ } auto parent = channel->parent(); if(parent && parent->channelType() > target_channel_type) - return {findError("channel_parent_not_permanent")}; + return command_result{error::channel_parent_not_permanent}; } /* test the max clients parameters */ @@ -2010,7 +2012,7 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { if(cmd[0].has("channel_flag_maxclients_unlimited") && cmd["channel_flag_maxclients_unlimited"].as()) cmd["channel_maxclients"] = -1; else - return {findError("parameter_missing"), "channel_maxclients"}; /* max clients must be specified */ + return command_result{error::parameter_missing, "channel_maxclients"}; /* max clients must be specified */ keys.push_back(property::info(property::CHANNEL_MAXCLIENTS)); } @@ -2020,10 +2022,10 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { } if(cmd["channel_flag_maxclients_unlimited"].as() && cmd["channel_maxclients"].as() != -1) - return {findError("channel_invalid_flags")}; /* channel cant have a max client settings AND be unlimited as well */ + return command_result{error::channel_invalid_flags}; /* channel cant have a max client settings AND be unlimited as well */ if(!cmd["channel_flag_maxclients_unlimited"].as() && target_channel_type == ChannelType::temporary) - return {findError("channel_invalid_flags")}; /* temporary channels cant have a limited user count */ + return command_result{error::channel_invalid_flags}; /* temporary channels cant have a limited user count */ } /* test the max family clients parameters */ @@ -2042,7 +2044,7 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { cmd["channel_flag_maxfamilyclients_unlimited"] = true; keys.push_back(property::info(property::CHANNEL_FLAG_MAXFAMILYCLIENTS_UNLIMITED)); } else /* not really possible */ - return {findError("parameter_missing"), "channel_maxfamilyclients"}; /* family max clients must be */ + return command_result{error::parameter_missing, "channel_maxfamilyclients"}; /* family max clients must be */ cmd["channel_maxfamilyclients"] = -1; keys.push_back(property::info(property::CHANNEL_MAXFAMILYCLIENTS)); } @@ -2063,23 +2065,23 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { } if(cmd["channel_flag_maxfamilyclients_inherited"].as() && cmd["channel_flag_maxfamilyclients_unlimited"].as()) - return {findError("channel_invalid_flags")}; /* both at the same time are not possible */ + return command_result{error::channel_invalid_flags}; /* both at the same time are not possible */ if(cmd["channel_flag_maxfamilyclients_inherited"].as() && cmd["channel_maxfamilyclients"].as() != -1) - return {findError("channel_invalid_flags")}; /* flag inherited required max users to be -1 */ + return command_result{error::channel_invalid_flags}; /* flag inherited required max users to be -1 */ if(cmd["channel_flag_maxfamilyclients_unlimited"].as() && cmd["channel_maxfamilyclients"].as() != -1) - return {findError("channel_invalid_flags")}; /* flag unlimited required max users to be -1 */ + return command_result{error::channel_invalid_flags}; /* flag unlimited required max users to be -1 */ if(cmd["channel_maxfamilyclients"].as() != -1 && target_channel_type == ChannelType::temporary) - return {findError("channel_invalid_flags")}; /* temporary channels cant have a limited user count */ + return command_result{error::channel_invalid_flags}; /* temporary channels cant have a limited user count */ } /* test the channel name */ if(update_name) { auto named_channel = channel_tree->findChannel(cmd["channel_name"].string(), channel->parent()); if (named_channel) - return {findError("channel_name_inuse"), to_string(named_channel->channelId())}; + return command_result{error::channel_name_inuse}; } auto self_ref = this->ref(); @@ -2089,7 +2091,7 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { if(*key == property::CHANNEL_ORDER) { /* TODO: May move that up because if it fails may some other props have already be applied */ if (!channel_tree->change_order(channel, cmd[key->name])) - return {findError("channel_invalid_order"), "Can't change order id"}; + return command_result{error::channel_invalid_order, "Can't change order id"}; if(this->server) { auto parent = channel->hasParent() ? channel_tree->findLinkedChannel(channel->parent()->channelId()) : nullptr; @@ -2226,17 +2228,17 @@ CommandResult ConnectedClient::handleCommandChannelEdit(Command &cmd) { for(const auto& client : this->server->getClientsByChannel(channel)) client->updateChannelClientProperties(true, true); //TODO: May only update the talk power and not all? } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelMove(Command &cmd) { +command_result ConnectedClient::handleCommandChannelMove(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); RESOLVE_CHANNEL_W(cmd["cid"], true); auto channel = dynamic_pointer_cast(l_channel->entry); assert(channel); if(channel->deleted) - return {findError("channel_is_deleted"), "target channel has been deleted"}; + return command_result{error::channel_is_deleted}; if(!cmd[0].has("order")) cmd["order"] = 0; @@ -2245,7 +2247,7 @@ CommandResult ConnectedClient::handleCommandChannelMove(Command &cmd) { shared_ptr l_order; if(cmd[0].has("order")) { l_order = channel_tree->findLinkedChannel(cmd["order"]); - if (!l_order && cmd["order"].as() != 0) return {findError("channel_invalid_id"), "Cant resolve order channel"}; + if (!l_order && cmd["order"].as() != 0) return command_result{error::channel_invalid_id}; } else { l_order = l_parent ? l_parent->child_head : (this->server ? this->server->getChannelTree() : serverInstance->getChannelTree().get())->tree_head(); while(l_order && l_order->next) @@ -2256,10 +2258,10 @@ CommandResult ConnectedClient::handleCommandChannelMove(Command &cmd) { auto order = l_order ? dynamic_pointer_cast(l_order->entry) : nullptr; if((parent && parent->deleted) || (order && order->deleted)) - return {findError("channel_is_deleted"), "parent channel order previous channel has been deleted"}; + return command_result{error::channel_is_deleted, "parent channel order previous channel has been deleted"}; if(channel->parent() == parent && channel->channelOrder() == (order ? order->channelId() : 0)) - return CommandResult::Success; + return command_result{error::ok}; if (channel->parent() != parent) PERM_CHECK_CHANNELR(permission::b_channel_modify_parent, 1, channel, true); @@ -2279,17 +2281,17 @@ CommandResult ConnectedClient::handleCommandChannelMove(Command &cmd) { local_parent = local_parent->parent.lock(); } - if(min_channel_deep >= 0 && channel_deep < min_channel_deep) return CommandResultPermissionError{permission::i_channel_min_depth}; - if(max_channel_deep >= 0 && channel_deep > max_channel_deep) return CommandResultPermissionError{permission::i_channel_max_depth}; + if(min_channel_deep >= 0 && channel_deep < min_channel_deep) return command_result{permission::i_channel_min_depth}; + if(max_channel_deep >= 0 && channel_deep > max_channel_deep) return command_result{permission::i_channel_max_depth}; } } { auto name = channel_tree->findChannel(channel->name(), parent); - if(name && name != channel) return {findError("channel_invalid_name"), "Channel with this name already exists"}; + if(name && name != channel) return command_result{error::channel_name_inuse}; } debugMessage(this->getServerId(), "Moving channel {} from old [{} | {}] to [{} | {}]", channel->name(), channel->channelOrder(), channel->parent() ? channel->parent()->channelId() : 0, order ? order->channelId() : 0, parent ? parent->channelId() : 0); - if (!channel_tree->move_channel(channel, parent, order)) return {findError("channel_invalid_order"), "Cant change order id"}; + if (!channel_tree->move_channel(channel, parent, order)) return command_result{error::channel_invalid_order, "Cant change order id"}; deque> channel_type_updates; { @@ -2342,24 +2344,24 @@ CommandResult ConnectedClient::handleCommandChannelMove(Command &cmd) { }); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientPoke(Command &cmd) { +command_result ConnectedClient::handleCommandClientPoke(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); 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!"}; + if (!client) return command_result{error::client_invalid_id}; + if (client->getType() == CLIENT_MUSIC) return command_result{error::client_invalid_type}; 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; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelPermList(Command &cmd) { +command_result ConnectedClient::handleCommandChannelPermList(Command &cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(5); RESOLVE_CHANNEL_R(cmd["cid"], true); @@ -2409,10 +2411,10 @@ CommandResult ConnectedClient::handleCommandChannelPermList(Command &cmd) { } } if(index == 0) - return {ErrorType::DBEmpty}; + return command_result{error::database_empty_result}; this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } // @@ -2420,7 +2422,7 @@ CommandResult ConnectedClient::handleCommandChannelPermList(Command &cmd) { //channel_name //channel_topic //Desctiption has no extra parm -CommandResult ConnectedClient::handleCommandChannelAddPerm(Command &cmd) { +command_result ConnectedClient::handleCommandChannelAddPerm(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -2434,7 +2436,6 @@ CommandResult ConnectedClient::handleCommandChannelAddPerm(Command &cmd) { bool ignoreGrant = this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_permission_modify_power_ignore, 1, channel); auto updateClients = false, update_view = false, update_channel_properties = false; - CommandResult command_result = CommandResult::Success; bool conOnError = cmd[0].has("continueonerror"); auto permission_manager = channel->permissions(); @@ -2443,13 +2444,15 @@ CommandResult ConnectedClient::handleCommandChannelAddPerm(Command &cmd) { auto val = cmd[index]["permvalue"].as(); if(permission_require_granted_value(permType) && val > maxValue) { - command_result = CommandResultPermissionError{permission::i_permission_modify_power}; - break; + if(conOnError) continue; + + return command_result{permission::i_permission_modify_power}; } if(!ignoreGrant && !this->permissionGrantGranted(permission::PERMTEST_ORDERED, permType, 1, channel)) { - command_result = CommandResultPermissionError{permission::i_permission_modify_power}; - break; + if(conOnError) continue; + + return command_result{permission::i_permission_modify_power}; } if (grant) { @@ -2522,10 +2525,10 @@ CommandResult ConnectedClient::handleCommandChannelAddPerm(Command &cmd) { } }); } - return command_result; + return command_result{error::ok};; } -CommandResult ConnectedClient::handleCommandChannelDelPerm(Command &cmd) { +command_result ConnectedClient::handleCommandChannelDelPerm(Command &cmd) { CMD_RESET_IDLE; RESOLVE_CHANNEL_R(cmd["cid"], true) @@ -2542,7 +2545,7 @@ CommandResult ConnectedClient::handleCommandChannelDelPerm(Command &cmd) { PARSE_PERMISSION(cmd); if(!ignoreGrant && !this->permissionGrantGranted(permission::PERMTEST_ORDERED, permType, 1, channel)) - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; if (grant) { permission_manager->set_permission(permType, permission::v2::empty_permission_values, permission::v2::PermissionUpdateType::do_nothing, permission::v2::PermissionUpdateType::delete_value); @@ -2595,27 +2598,27 @@ CommandResult ConnectedClient::handleCommandChannelDelPerm(Command &cmd) { } }); } - return CommandResult::Success; + return command_result{error::ok}; } //servergroupadd name=TestGroup type=1 -CommandResult ConnectedClient::handleCommandServerGroupAdd(Command &cmd) { +command_result ConnectedClient::handleCommandServerGroupAdd(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); CACHED_PERM_CHECK(permission::b_virtualserver_servergroup_create, 1, true); - if(cmd["name"].string().empty()) return {findError("parameter_invalid"), "invalid group name"}; + if(cmd["name"].string().empty()) return command_result{error::parameter_invalid}; if(cmd["type"].as() == GroupType::GROUP_TYPE_QUERY) { if(!this->permission_granted(this->cached_permission_value(permission::b_serverinstance_modify_querygroup), 1, true)) - return CommandResultPermissionError{permission::b_serverinstance_modify_querygroup}; + return command_result{permission::b_serverinstance_modify_querygroup}; } else if(cmd["type"].as() == GroupType::GROUP_TYPE_TEMPLATE) { if(!this->permission_granted(this->cached_permission_value(permission::b_serverinstance_modify_templates), 1, true)) - return CommandResultPermissionError{permission::b_serverinstance_modify_templates}; - } else if(!this->server) return {findError("parameter_invalid"), "you cant create normal groups on the template server!"}; + return command_result{permission::b_serverinstance_modify_templates}; + } else if(!this->server) return command_result{error::parameter_invalid, "you cant create normal groups on the template server!"}; auto group_manager = this->server ? this->server->getGroupManager() : serverInstance->getGroupManager().get(); for(const auto& gr : group_manager->availableServerGroups(true)) - if(gr->name() == cmd["name"].string() && gr->target() == GroupTarget::GROUPTARGET_SERVER) return {findError("parameter_invalid"), "Group already exists"}; + if(gr->name() == cmd["name"].string() && gr->target() == GroupTarget::GROUPTARGET_SERVER) return command_result{error::parameter_invalid, "Group already exists"}; auto group = group_manager->createGroup(GroupTarget::GROUPTARGET_SERVER, cmd["type"].as(), cmd["name"].string()); if (group) { group->permissions()->set_permission(permission::b_group_is_permanent, {1,0}, permission::v2::set_value, permission::v2::do_nothing); @@ -2623,11 +2626,11 @@ CommandResult ConnectedClient::handleCommandServerGroupAdd(Command &cmd) { this->server->forEachClient([](shared_ptr cl) { cl->notifyServerGroupList(); }); - } else return {ErrorType::VSError, "Could not create group"}; - return CommandResult::Success; + } else return command_result{error::vs_critical}; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandServerGroupCopy(Command &cmd) { +command_result ConnectedClient::handleCommandServerGroupCopy(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -2640,7 +2643,7 @@ CommandResult ConnectedClient::handleCommandServerGroupCopy(Command &cmd) { auto source_group = group_manager->findGroup(source_group_id); if(!source_group || source_group->target() != GROUPTARGET_SERVER) - return {findError("group_invalid_id"), "invalid source group"}; + return command_result{error::group_invalid_id}; const auto group_type_modificable = [&](GroupType type) { switch(type) { @@ -2662,7 +2665,7 @@ CommandResult ConnectedClient::handleCommandServerGroupCopy(Command &cmd) { { auto result = group_type_modificable(source_group->type()); if(result != permission::undefined) - return CommandResultPermissionError{result}; + return command_result{result}; } auto global_update = false; @@ -2670,19 +2673,19 @@ CommandResult ConnectedClient::handleCommandServerGroupCopy(Command &cmd) { //Copy an existing group auto target_group = group_manager->findGroup(cmd["tsgid"]); if(!target_group || target_group->target() != GROUPTARGET_SERVER) - return {findError("group_invalid_id"), "invalid target group"}; + return command_result{error::group_invalid_id}; { auto result = group_type_modificable(target_group->type()); if(result != permission::undefined) - return CommandResultPermissionError{result}; + return command_result{result}; } if(!target_group->permission_granted(permission::i_server_group_needed_modify_power, this->calculate_permission_value(permission::i_server_group_modify_power, 0), true)) - return CommandResultPermissionError{permission::i_server_group_modify_power}; + return command_result{permission::i_server_group_modify_power}; if(!group_manager->copyGroupPermissions(source_group, target_group)) - return {findError("vs_critical"), "failed to copy group permissions"}; + return command_result{error::vs_critical, "failed to copy group permissions"}; global_update = !this->server || !group_manager->isLocalGroup(target_group); } else { @@ -2692,18 +2695,18 @@ CommandResult ConnectedClient::handleCommandServerGroupCopy(Command &cmd) { { auto result = group_type_modificable(target_type); if(result != permission::undefined) - return CommandResultPermissionError{result}; + return command_result{result}; } if(!ref_server && target_type == GroupType::GROUP_TYPE_NORMAL) - return {findError("parameter_invalid"), "You cant create normal groups on the template server!"}; + return command_result{error::parameter_invalid, "You cant create normal groups on the template server!"}; if(!group_manager->findGroup(GroupTarget::GROUPTARGET_SERVER, cmd["name"].string()).empty()) - return {findError("group_name_used"), "You cant create normal groups on the template server!"}; + return command_result{error::group_name_inuse, "You cant create normal groups on the template server!"}; auto target_group_id = group_manager->copyGroup(source_group, target_type, cmd["name"], target_type != GroupType::GROUP_TYPE_NORMAL ? 0 : this->getServerId()); if(target_group_id == 0) - return {findError("vs_critical"), "failed to copy group"}; + return command_result{error::vs_critical, "failed to copy group"}; if(this->getType() == ClientType::CLIENT_QUERY) { Command notify(""); @@ -2719,26 +2722,26 @@ CommandResult ConnectedClient::handleCommandServerGroupCopy(Command &cmd) { server->forEachClient([](shared_ptr cl) { cl->notifyServerGroupList(); }); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandServerGroupRename(Command &cmd) { +command_result ConnectedClient::handleCommandServerGroupRename(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto group_manager = this->server ? this->server->getGroupManager() : serverInstance->getGroupManager().get(); auto serverGroup = group_manager->findGroup(cmd["sgid"].as()); - if (!serverGroup || serverGroup->target() != GROUPTARGET_SERVER) return {findError("parameter_invalid"), "invalid server group id"}; + if (!serverGroup || serverGroup->target() != GROUPTARGET_SERVER) return command_result{error::group_invalid_id}; GROUP_PERMISSION_TEST(permission::i_server_group_modify_power, permission::i_server_group_needed_modify_power, serverGroup, true); auto type = serverGroup->type(); if(type == GroupType::GROUP_TYPE_QUERY) { if(!this->permission_granted(this->cached_permission_value(permission::b_serverinstance_modify_querygroup), 1, true)) - return CommandResultPermissionError{permission::b_serverinstance_modify_querygroup}; + return command_result{permission::b_serverinstance_modify_querygroup}; } else if(type == GroupType::GROUP_TYPE_TEMPLATE) { if(!this->permission_granted(this->cached_permission_value(permission::b_serverinstance_modify_templates), 1, true)) - return CommandResultPermissionError{permission::b_serverinstance_modify_templates}; + return command_result{permission::b_serverinstance_modify_templates}; } group_manager->renameGroup(serverGroup, cmd["name"].string()); @@ -2747,40 +2750,40 @@ CommandResult ConnectedClient::handleCommandServerGroupRename(Command &cmd) { cl->notifyServerGroupList(); }); - return CommandResult::Success; + return command_result{error::ok}; } //servergroupdel sgid=2 force=0 -CommandResult ConnectedClient::handleCommandServerGroupDel(Command &cmd) { +command_result ConnectedClient::handleCommandServerGroupDel(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); CACHED_PERM_CHECK(permission::b_virtualserver_servergroup_delete, 1, true); auto group_manager = this->server ? this->server->getGroupManager() : serverInstance->getGroupManager().get(); auto serverGroup = group_manager->findGroup(cmd["sgid"].as()); - if (!serverGroup || serverGroup->target() != GROUPTARGET_SERVER) return {findError("parameter_invalid"), "invalid server group id"}; + if (!serverGroup || serverGroup->target() != GROUPTARGET_SERVER) return command_result{error::group_invalid_id}; if(this->server && this->server->properties()[property::VIRTUALSERVER_DEFAULT_SERVER_GROUP] == serverGroup->groupId()) - return {findError("parameter_invalid"), "Could not delete default server group!"}; + return command_result{error::parameter_invalid, "Could not delete default server group!"}; if(serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_SERVERADMIN_GROUP] == serverGroup->groupId()) - return {findError("parameter_invalid"), "Could not delete instance default server admin group!"}; + return command_result{error::parameter_invalid, "Could not delete instance default server admin group!"}; if(serverInstance->properties()[property::SERVERINSTANCE_TEMPLATE_SERVERDEFAULT_GROUP] == serverGroup->groupId()) - return {findError("parameter_invalid"), "Could not delete instance default server group!"}; + return command_result{error::parameter_invalid, "Could not delete instance default server group!"}; if(serverInstance->properties()[property::SERVERINSTANCE_GUEST_SERVERQUERY_GROUP] == serverGroup->groupId()) - return {findError("parameter_invalid"), "Could not delete instance default guest server query group!"}; + return command_result{error::parameter_invalid, "Could not delete instance default guest server query group!"}; auto type = serverGroup->type(); if(type == GroupType::GROUP_TYPE_QUERY) { if(!this->permission_granted(this->cached_permission_value(permission::b_serverinstance_modify_querygroup), 1, true)) - return CommandResultPermissionError{permission::b_serverinstance_modify_querygroup}; + return command_result{permission::b_serverinstance_modify_querygroup}; } else if(type == GroupType::GROUP_TYPE_TEMPLATE) { if(!this->permission_granted(this->cached_permission_value(permission::b_serverinstance_modify_templates), 1, true)) - return CommandResultPermissionError{permission::b_serverinstance_modify_templates}; + return command_result{permission::b_serverinstance_modify_templates}; } if (!cmd["force"].as()) if (!group_manager->listGroupMembers(serverGroup, false).empty()) - return {findError("database_empty_result"), "group not empty!"}; + return command_result{error::database_empty_result, "group not empty!"}; if (group_manager->deleteGroup(serverGroup)) { if(this->server) @@ -2793,12 +2796,12 @@ CommandResult ConnectedClient::handleCommandServerGroupDel(Command &cmd) { }); } - return CommandResult::Success; + return command_result{error::ok}; } //servergroupclientlist sgid=2 //notifyservergroupclientlist sgid=6 cldbid=2 client_nickname=WolverinDEV client_unique_identifier=xxjnc14LmvTk+Lyrm8OOeo4tOqw= -CommandResult ConnectedClient::handleCommandServerGroupClientList(Command &cmd) { +command_result ConnectedClient::handleCommandServerGroupClientList(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -2808,7 +2811,7 @@ CommandResult ConnectedClient::handleCommandServerGroupClientList(Command &cmd) auto groupManager = server ? this->server->groups : serverInstance->getGroupManager().get(); auto serverGroup = groupManager->findGroup(cmd["sgid"].as()); - if (!serverGroup || serverGroup->target() != GROUPTARGET_SERVER) return {findError("parameter_invalid"), "invalid server group id"}; + if (!serverGroup || serverGroup->target() != GROUPTARGET_SERVER) return command_result{error::group_invalid_id}; Command notify(this->getExternalType() == ClientType::CLIENT_TEAMSPEAK ? "notifyservergroupclientlist" : ""); notify["sgid"] = cmd["sgid"].as(); @@ -2820,10 +2823,10 @@ CommandResult ConnectedClient::handleCommandServerGroupClientList(Command &cmd) index++; } this->sendCommand(notify); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandServerGroupAddClient(Command &cmd) { +command_result ConnectedClient::handleCommandServerGroupAddClient(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -2831,12 +2834,12 @@ CommandResult ConnectedClient::handleCommandServerGroupAddClient(Command &cmd) { auto group_manager = target_server ? this->server->groups : serverInstance->getGroupManager().get(); auto target_cldbid = cmd["cldbid"].as(); - if (!serverInstance->databaseHelper()->validClientDatabaseId(target_server, cmd["cldbid"])) return {findError("client_invalid_id"), "invalid cldbid"}; + if (!serverInstance->databaseHelper()->validClientDatabaseId(target_server, cmd["cldbid"])) return command_result{error::client_invalid_id, "invalid cldbid"}; auto needed_client_permission = this->server->calculatePermission(permission::PERMTEST_ORDERED, target_cldbid, permission::i_client_needed_permission_modify_power, ClientType::CLIENT_TEAMSPEAK, nullptr); if(needed_client_permission != permNotGranted) { if(!this->permission_granted(this->permissionValue(permission::i_client_permission_modify_power), needed_client_permission)) - return CommandResultPermissionError{permission::i_client_needed_permission_modify_power}; + return command_result{permission::i_client_needed_permission_modify_power}; } vector> target_groups; @@ -2859,17 +2862,17 @@ CommandResult ConnectedClient::handleCommandServerGroupAddClient(Command &cmd) { if(continue_on_error) continue; - return {findError("parameter_invalid"), "missing server group for id " + to_string(gid)}; + return command_result{error::group_invalid_id}; } if(!target_server && group->target() != GroupTarget::GROUPTARGET_SERVER && group->type() != GroupType::GROUP_TYPE_QUERY) - return {findError("parameter_invalid"), "invalid server group type for id " + to_string(gid)}; + return command_result{error::parameter_invalid}; if(find(target_groups.begin(), target_groups.end(), group) != target_groups.end()) { if(continue_on_error) continue; - return {findError("parameter_invalid"), "duplicate server group for id " + to_string(gid)}; + return command_result{error::client_is_already_member_of_group}; } /* permission tests */ @@ -2878,14 +2881,14 @@ CommandResult ConnectedClient::handleCommandServerGroupAddClient(Command &cmd) { if(continue_on_error) continue; - return CommandResultPermissionError{permission::i_server_group_member_add_power}; + return command_result{permission::i_server_group_member_add_power}; } if(!group->permission_granted(permission::i_server_group_needed_member_add_power, permission_self_add_power, true)) { if(continue_on_error) continue; - return CommandResultPermissionError{permission::i_server_group_self_add_power}; + return command_result{permission::i_server_group_self_add_power}; } } @@ -2894,12 +2897,12 @@ CommandResult ConnectedClient::handleCommandServerGroupAddClient(Command &cmd) { } applied_groups.reserve(target_groups.size()); - if(target_groups.empty()) return CommandResult::Success; + if(target_groups.empty()) return command_result{error::ok}; else if(target_groups.size() == 1) { /* speed up thing, don't try to load any cache */ auto group = target_groups[0]; if(group_manager->hasServerGroupAssigned(target_cldbid, group)) - return {findError("parameter_invalid"), "Client is already member of server group " + to_string(group->groupId())}; + return command_result{error::client_is_already_member_of_group}; group_manager->addServerGroup(target_cldbid, group); applied_groups.push_back(group); @@ -2913,7 +2916,7 @@ CommandResult ConnectedClient::handleCommandServerGroupAddClient(Command &cmd) { if(group_manager->hasServerGroupAssigned(target_cldbid, group)) { if(continue_on_error) continue; - return {findError("parameter_invalid"), "Client is already member of server group " + to_string(group->groupId())}; + return command_result{error::client_is_already_member_of_group}; } group_manager->addServerGroup(target_cldbid, group); @@ -2936,10 +2939,10 @@ CommandResult ConnectedClient::handleCommandServerGroupAddClient(Command &cmd) { } } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandServerGroupDelClient(Command &cmd) { +command_result ConnectedClient::handleCommandServerGroupDelClient(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -2947,12 +2950,12 @@ CommandResult ConnectedClient::handleCommandServerGroupDelClient(Command &cmd) { auto group_manager = target_server ? this->server->groups : serverInstance->getGroupManager().get(); auto target_cldbid = cmd["cldbid"].as(); - if (!serverInstance->databaseHelper()->validClientDatabaseId(target_server, cmd["cldbid"])) return {findError("client_invalid_id"), "invalid cldbid"}; + if (!serverInstance->databaseHelper()->validClientDatabaseId(target_server, cmd["cldbid"])) return command_result{error::client_invalid_id, "invalid cldbid"}; auto needed_client_permission = this->server->calculatePermission(permission::PERMTEST_ORDERED, target_cldbid, permission::i_client_needed_permission_modify_power, ClientType::CLIENT_TEAMSPEAK, nullptr); if(needed_client_permission != permNotGranted) { if(!this->permission_granted(this->permissionValue(permission::i_client_permission_modify_power), needed_client_permission)) - return CommandResultPermissionError{permission::i_client_needed_permission_modify_power}; + return command_result{permission::i_client_needed_permission_modify_power}; } vector> target_groups; @@ -2975,17 +2978,17 @@ CommandResult ConnectedClient::handleCommandServerGroupDelClient(Command &cmd) { if(continue_on_error) continue; - return {findError("parameter_invalid"), "missing server group for id " + to_string(gid)}; + return command_result{error::group_invalid_id}; } if(!target_server && group->target() != GroupTarget::GROUPTARGET_SERVER && group->type() != GroupType::GROUP_TYPE_QUERY) - return {findError("parameter_invalid"), "invalid server group type for id " + to_string(gid)}; + return command_result{error::group_invalid_id}; if(find(target_groups.begin(), target_groups.end(), group) != target_groups.end()) { if(continue_on_error) continue; - return {findError("parameter_invalid"), "duplicate server group for id " + to_string(gid)}; + return command_result{error::parameter_invalid, "duplicate server group for id " + to_string(gid)}; } /* permission tests */ @@ -2994,14 +2997,14 @@ CommandResult ConnectedClient::handleCommandServerGroupDelClient(Command &cmd) { if(continue_on_error) continue; - return CommandResultPermissionError{permission::i_server_group_member_remove_power}; + return command_result{permission::i_server_group_member_remove_power}; } if(!group->permission_granted(permission::i_server_group_needed_member_remove_power, permission_self_remove_power, true)) { if(continue_on_error) continue; - return CommandResultPermissionError{permission::i_server_group_self_remove_power}; + return command_result{permission::i_server_group_self_remove_power}; } } @@ -3010,16 +3013,16 @@ CommandResult ConnectedClient::handleCommandServerGroupDelClient(Command &cmd) { } applied_groups.reserve(target_groups.size()); - if(target_groups.empty()) return CommandResult::Success; + if(target_groups.empty()) return command_result{error::ok}; else if(target_groups.size() == 1) { /* speed up thing, don't try to load any cache */ auto group = target_groups[0]; auto assignment = group_manager->get_group_assignment(target_cldbid, group); if(!assignment) { - return {findError("parameter_invalid"), "Client is not member of server group " + to_string(group->groupId())}; + return command_result{error::client_is_not_member_of_group}; } if(assignment->server != (target_server ? target_server->getServerId() : 0)) { - return {findError("parameter_invalid"), "Group assignment for group " + to_string(assignment->group->groupId()) + " hasn't been made over the target server. Assignment origin server id " + to_string(assignment->server)}; + return command_result{error::group_not_assigned_over_this_server}; } group_manager->removeServerGroup(target_cldbid, group); @@ -3035,12 +3038,12 @@ CommandResult ConnectedClient::handleCommandServerGroupDelClient(Command &cmd) { if(!assignment) { if(continue_on_error) continue; - return {findError("parameter_invalid"), "Client is not member of server group " + to_string(group->groupId())}; + return command_result{error::client_is_not_member_of_group}; } if(assignment->server != (target_server ? target_server->getServerId() : 0)) { if(continue_on_error) continue; - return {findError("parameter_invalid"), "Group assignment for group " + to_string(assignment->group->groupId()) + " hasn't been made over the target server. Assignment origin server id " + to_string(assignment->server)}; + return command_result{error::group_not_assigned_over_this_server}; } applied_groups.push_back(group); @@ -3063,42 +3066,42 @@ CommandResult ConnectedClient::handleCommandServerGroupDelClient(Command &cmd) { } } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandServerGroupPermList(Command &cmd) { +command_result ConnectedClient::handleCommandServerGroupPermList(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); CACHED_PERM_CHECK(permission::b_virtualserver_servergroup_permission_list, 1, true); auto serverGroup = (this->server ? this->server->groups : serverInstance->getGroupManager().get())->findGroup(cmd["sgid"].as()); - if (!serverGroup) return {findError("parameter_invalid"), "invalid server group id"}; + if (!serverGroup) return command_result{error::group_invalid_id}; if(this->getType() == ClientType::CLIENT_TEAMSPEAK && this->command_times.last_notify + this->command_times.notify_timeout < system_clock::now()) { this->sendTSPermEditorWarning(); } - if (!this->notifyGroupPermList(serverGroup, cmd.hasParm("permsid"))) return {findError("database_empty_result"), "empty"}; + if (!this->notifyGroupPermList(serverGroup, cmd.hasParm("permsid"))) return command_result{error::database_empty_result}; - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandServerGroupAddPerm(Command &cmd) { +command_result ConnectedClient::handleCommandServerGroupAddPerm(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto serverGroup = (this->server ? this->server->groups : serverInstance->getGroupManager().get())->findGroup(cmd["sgid"].as()); - if (!serverGroup) return {findError("parameter_invalid"), "invalid server group id"}; - if (serverGroup->target() != GROUPTARGET_SERVER) return {findError("parameter_invalid"), "invalid group type"}; + if (!serverGroup) return command_result{error::group_invalid_id}; + if (serverGroup->target() != GROUPTARGET_SERVER) return command_result{error::parameter_invalid}; GROUP_PERMISSION_TEST(permission::i_server_group_modify_power, permission::i_server_group_needed_modify_power, serverGroup, true); auto type = serverGroup->type(); if(type == GroupType::GROUP_TYPE_QUERY) { if(!this->permission_granted(this->cached_permission_value(permission::b_serverinstance_modify_querygroup), 1, true)) - return CommandResultPermissionError{permission::b_serverinstance_modify_querygroup}; + return command_result{permission::b_serverinstance_modify_querygroup}; } else if(type == GroupType::GROUP_TYPE_TEMPLATE) { if(!this->permission_granted(this->cached_permission_value(permission::b_serverinstance_modify_templates), 1, true)) - return CommandResultPermissionError{permission::b_serverinstance_modify_templates}; + return command_result{permission::b_serverinstance_modify_templates}; } auto maxValue = this->getPermissionGrantValue(permission::PERMTEST_ORDERED, permission::i_permission_modify_power, this->currentChannel); @@ -3115,12 +3118,12 @@ CommandResult ConnectedClient::handleCommandServerGroupAddPerm(Command &cmd) { auto val = cmd[index]["permvalue"].as(); if(permission_require_granted_value(permType) && val > maxValue) { if(conOnError) continue; - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; } if(!ignoreGrant && !this->permissionGrantGranted(permission::PERMTEST_ORDERED, permType, 1, this->currentChannel)) { if(conOnError) continue; - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; } if (grant) { @@ -3163,25 +3166,25 @@ CommandResult ConnectedClient::handleCommandServerGroupAddPerm(Command &cmd) { }); }).detach(); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandServerGroupDelPerm(Command &cmd) { +command_result ConnectedClient::handleCommandServerGroupDelPerm(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto serverGroup = (this->server ? this->server->groups : serverInstance->getGroupManager().get())->findGroup(cmd["sgid"].as()); - if (!serverGroup) return {findError("parameter_invalid"), "invalid server group id"}; - if (serverGroup->target() != GROUPTARGET_SERVER) return {findError("parameter_invalid"), "invalid group type"}; + if (!serverGroup) return command_result{error::group_invalid_id}; + if (serverGroup->target() != GROUPTARGET_SERVER) return command_result{error::parameter_invalid}; GROUP_PERMISSION_TEST(permission::i_server_group_modify_power, permission::i_server_group_needed_modify_power, serverGroup, true); auto type = serverGroup->type(); if(type == GroupType::GROUP_TYPE_QUERY) { if(!this->permission_granted(this->cached_permission_value(permission::b_serverinstance_modify_querygroup), 1, true)) - return CommandResultPermissionError{permission::b_serverinstance_modify_querygroup}; + return command_result{permission::b_serverinstance_modify_querygroup}; } else if(type == GroupType::GROUP_TYPE_TEMPLATE) { if(!this->permission_granted(this->cached_permission_value(permission::b_serverinstance_modify_templates), 1, true)) - return CommandResultPermissionError{permission::b_serverinstance_modify_templates}; + return command_result{permission::b_serverinstance_modify_templates}; } bool ignoreGrant = this->permission_granted(this->cached_permission_value(permission::b_permission_modify_power_ignore), 1); @@ -3193,7 +3196,7 @@ CommandResult ConnectedClient::handleCommandServerGroupDelPerm(Command &cmd) { if(!ignoreGrant && !this->permissionGrantGranted(permission::PERMTEST_ORDERED, permType, 1, this->currentChannel)) { if(conOnError) continue; - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; } if (grant) { @@ -3234,10 +3237,10 @@ CommandResult ConnectedClient::handleCommandServerGroupDelPerm(Command &cmd) { }).detach(); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandServerGroupAutoAddPerm(ts::Command& cmd) { +command_result ConnectedClient::handleCommandServerGroupAutoAddPerm(ts::Command& cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -3262,7 +3265,7 @@ CommandResult ConnectedClient::handleCommandServerGroupAutoAddPerm(ts::Command& } if(groups.empty()) - return CommandResult::Success; + return command_result{error::ok}; auto maxValue = this->getPermissionGrantValue(permission::PERMTEST_ORDERED, permission::i_permission_modify_power, this->currentChannel); @@ -3278,12 +3281,12 @@ CommandResult ConnectedClient::handleCommandServerGroupAutoAddPerm(ts::Command& auto val = cmd[index]["permvalue"].as(); if(permission_require_granted_value(permType) && val > maxValue) { if(conOnError) continue; - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; } if(!ignoreGrant && !this->permissionGrantGranted(permission::PERMTEST_ORDERED, permType, 1, this->currentChannel)) { if(conOnError) continue; - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; } for(const auto& serverGroup : groups) { if (grant) { @@ -3331,10 +3334,10 @@ CommandResult ConnectedClient::handleCommandServerGroupAutoAddPerm(ts::Command& }); }).detach(); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandServerGroupAutoDelPerm(ts::Command& cmd) { +command_result ConnectedClient::handleCommandServerGroupAutoDelPerm(ts::Command& cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -3358,7 +3361,7 @@ CommandResult ConnectedClient::handleCommandServerGroupAutoDelPerm(ts::Command& } } - if(groups.empty()) return CommandResult::Success; + if(groups.empty()) return command_result{error::ok}; bool ignoreGrant = this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_permission_modify_power_ignore, 1); bool conOnError = cmd[0].has("continueonerror"); @@ -3369,7 +3372,7 @@ CommandResult ConnectedClient::handleCommandServerGroupAutoDelPerm(ts::Command& if(!ignoreGrant && !this->permissionGrantGranted(permission::PERMTEST_ORDERED, permType, 1, this->currentChannel)) { if(conOnError) continue; - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; } for(const auto& serverGroup : groups) { @@ -3416,10 +3419,10 @@ CommandResult ConnectedClient::handleCommandServerGroupAutoDelPerm(ts::Command& }).detach(); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandSetClientChannelGroup(Command &cmd) { +command_result ConnectedClient::handleCommandSetClientChannelGroup(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -3429,23 +3432,23 @@ CommandResult ConnectedClient::handleCommandSetClientChannelGroup(Command &cmd) serverGroup = this->server->groups->defaultGroup(GroupTarget::GROUPTARGET_CHANNEL); if (!serverGroup || serverGroup->target() != GROUPTARGET_CHANNEL) - return {findError("parameter_invalid"), "invalid channel group id"}; + return command_result{error::group_invalid_id}; shared_lock server_channel_lock(this->server->channel_tree_lock); /* ensure we dont get moved or somebody could move us */ auto channel_id = cmd["cid"].as(); auto channel = this->server->channelTree->findChannel(channel_id); - if (!channel) return {findError("channel_invalid_id"), "Cant resolve channel"}; + if (!channel) return command_result{error::channel_invalid_id}; auto target_cldbid = cmd["cldbid"].as(); { auto channel_group_member_add_power = this->calculate_permission_value(permission::i_channel_group_member_add_power, channel_id); if(!serverGroup->permission_granted(permission::i_channel_group_needed_member_add_power, channel_group_member_add_power, true)) { if(target_cldbid != this->getClientDatabaseId()) - return CommandResultPermissionError{permission::i_channel_group_member_add_power}; + return command_result{permission::i_channel_group_member_add_power}; auto channel_group_self_add_power = this->calculate_permission_value(permission::i_channel_group_self_add_power, channel_id); if(!serverGroup->permission_granted(permission::i_channel_group_needed_member_add_power, channel_group_self_add_power, true)) - return CommandResultPermissionError{permission::i_channel_group_self_add_power}; + return command_result{permission::i_channel_group_self_add_power}; } @@ -3456,7 +3459,7 @@ CommandResult ConnectedClient::handleCommandSetClientChannelGroup(Command &cmd) if(client_needed_permission_modify_power.has_value) { if(!this->permission_granted(client_permission_modify_power, client_needed_permission_modify_power.value, true)) - return CommandResultPermissionError{permission::i_client_permission_modify_power}; + return command_result{permission::i_client_permission_modify_power}; } } @@ -3466,11 +3469,11 @@ CommandResult ConnectedClient::handleCommandSetClientChannelGroup(Command &cmd) auto channel_group_member_remove_power = this->calculate_permission_value(permission::i_channel_group_member_remove_power, channel_id); if(!serverGroup->permission_granted(permission::i_channel_group_needed_member_remove_power, channel_group_member_remove_power, true)) { if(target_cldbid != this->getClientDatabaseId()) - return CommandResultPermissionError{permission::i_channel_group_member_remove_power}; + return command_result{permission::i_channel_group_member_remove_power}; auto channel_group_self_remove_power = this->calculate_permission_value(permission::i_channel_group_self_remove_power, channel_id); if(!serverGroup->permission_granted(permission::i_channel_group_needed_member_remove_power, channel_group_self_remove_power, true)) - return CommandResultPermissionError{permission::i_channel_group_self_remove_power}; + return command_result{permission::i_channel_group_self_remove_power}; } } } @@ -3499,11 +3502,11 @@ CommandResult ConnectedClient::handleCommandSetClientChannelGroup(Command &cmd) targetClient->updateChannelClientProperties(false, true); } - return CommandResult::Success; + return command_result{error::ok}; } //sendtextmessage targetmode=1 <1 = direct | 2 = channel | 3 = server> msg=asd target=1 -CommandResult ConnectedClient::handleCommandSendTextMessage(Command &cmd) { +command_result ConnectedClient::handleCommandSendTextMessage(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -3511,7 +3514,7 @@ CommandResult ConnectedClient::handleCommandSendTextMessage(Command &cmd) { auto timestamp = system_clock::now(); if (cmd["targetmode"].as() == ChatMessageMode::TEXTMODE_PRIVATE) { auto target = this->server->findClient(cmd["target"].as()); - if (!target) return {findError("client_invalid_id"), "invalid target clid"}; + if (!target) return command_result{error::client_invalid_id}; bool chat_open = false; { @@ -3545,7 +3548,7 @@ CommandResult ConnectedClient::handleCommandSendTextMessage(Command &cmd) { } } - if(this->handleTextMessage(ChatMessageMode::TEXTMODE_PRIVATE, cmd["msg"], target)) return CommandResult::Success; + if(this->handleTextMessage(ChatMessageMode::TEXTMODE_PRIVATE, cmd["msg"], target)) return command_result{error::ok}; 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) { @@ -3561,20 +3564,20 @@ CommandResult 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)) - return CommandResult::Success; + return command_result{error::ok}; channel_tree_read_lock.lock(); } if(!this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_channel_textmessage_send, 1, channel, false)) - return CommandResultPermissionError{permission::b_client_channel_textmessage_send}; + return command_result{permission::b_client_channel_textmessage_send}; bool conversation_private = channel->properties()[property::CHANNEL_FLAG_CONVERSATION_PRIVATE].as(); if(channel != this->currentChannel) { if(conversation_private) - return {findError("conversation_is_private")}; + return command_result{error::conversation_is_private}; if(!this->calculate_and_get_join_state(channel)) - return CommandResultPermissionError{permission::unknown}; /* You're not allowed to send messages :) */ + return command_result{permission::unknown}; /* You're not allowed to send messages :) */ } auto message = cmd["msg"].string(); @@ -3614,7 +3617,7 @@ CommandResult ConnectedClient::handleCommandSendTextMessage(Command &cmd) { } else if (cmd["targetmode"] == ChatMessageMode::TEXTMODE_SERVER) { CACHED_PERM_CHECK(permission::b_client_server_textmessage_send, 1); - if(this->handleTextMessage(ChatMessageMode::TEXTMODE_SERVER, cmd["msg"], nullptr)) return CommandResult::Success; + if(this->handleTextMessage(ChatMessageMode::TEXTMODE_SERVER, cmd["msg"], nullptr)) return command_result{error::ok}; for(const auto& client : this->server->getClients()) { if (client->connectionState() != ConnectionState::CONNECTED) continue; @@ -3631,28 +3634,28 @@ CommandResult ConnectedClient::handleCommandSendTextMessage(Command &cmd) { auto conversation = conversations->get_or_create(0); conversation->register_message(this->getClientDatabaseId(), this->getUid(), this->getDisplayName(), timestamp, cmd["msg"].string()); } - } else return {findError("parameter_invalid"), "invalid target mode"}; + } else return command_result{error::parameter_invalid, "invalid target mode"}; - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientChatComposing(Command &cmd) { +command_result ConnectedClient::handleCommandClientChatComposing(Command &cmd) { CMD_REQ_SERVER; CMD_CHK_AND_INC_FLOOD_POINTS(0); auto client = this->server->findClient(cmd["clid"].as()); - if (!client) return {findError("client_invalid_id"), "invalid client id"}; + if (!client) return command_result{error::client_invalid_id}; client->notifyClientChatComposing(_this.lock()); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientChatClosed(Command &cmd) { +command_result ConnectedClient::handleCommandClientChatClosed(Command &cmd) { CMD_REQ_SERVER; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto client = this->server->findClient(cmd["clid"].as()); - if (!client) return {findError("client_invalid_id"), "invalid client id"}; + if (!client) return command_result{error::client_invalid_id}; { unique_lock channel_lock(this->channel_lock); this->openChats.erase(remove_if(this->openChats.begin(), this->openChats.end(), [client](const weak_ptr& weak) { @@ -3666,7 +3669,7 @@ CommandResult ConnectedClient::handleCommandClientChatClosed(Command &cmd) { }), client->openChats.end()); } client->notifyClientChatClosed(_this.lock()); - return CommandResult::Success; + return command_result{error::ok}; } //ftgetfilelist cid=1 cpw path=\/ return_code=1:x @@ -3692,9 +3695,9 @@ inline void cmd_filelist_append_files(ServerId sid, Command &command, vectorgetFileServer()) return {findError("vs_critical"), "file server not started yet!"} +#define CMD_REQ_FSERVER if(!serverInstance->getFileServer()) return command_result{error::vs_critical, "file server not started yet!"} -CommandResult ConnectedClient::handleCommandFTGetFileList(Command &cmd) { +command_result ConnectedClient::handleCommandFTGetFileList(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_REQ_FSERVER; @@ -3711,9 +3714,9 @@ CommandResult ConnectedClient::handleCommandFTGetFileList(Command &cmd) { if (cmd[0].has("cid") && cmd["cid"] != 0) { //Channel auto channel = this->server->channelTree->findChannel(cmd["cid"].as()); - if (!channel) return {findError("channel_invalid_id"), "Cant resolve channel"}; + if (!channel) return command_result{error::channel_invalid_id, "Cant resolve channel"}; if (!channel->passwordMatch(cmd["cpw"]) && !this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_ft_ignore_password, 1, channel, true)) - return cmd["cpw"].string().empty() ? CommandResultPermissionError{permission::b_ft_ignore_password} : CommandResult{findError("channel_invalid_password")}; + return cmd["cpw"].string().empty() ? command_result{permission::b_ft_ignore_password} : command_result{error::channel_invalid_password}; CHANNEL_PERMISSION_TEST(permission::i_ft_file_browse_power, permission::i_ft_needed_file_browse_power, channel, true); cmd_filelist_append_files( this->getServerId(), @@ -3729,7 +3732,7 @@ CommandResult ConnectedClient::handleCommandFTGetFileList(Command &cmd) { PERM_CHECKR(permission::b_icon_manage, 1, true); } else { logMessage(this->getServerId(), "{} Requested file list for unknown path/name: path: {} name: {}", cmd["path"].string(), cmd["name"].string()); - return CommandResult::NotImplemented; + return command_result{error::not_implemented}; } } @@ -3742,32 +3745,32 @@ CommandResult ConnectedClient::handleCommandFTGetFileList(Command &cmd) { if(this->getType() != CLIENT_QUERY) this->sendCommand(fileListFinished); } - return CommandResult::Success; + return command_result{error::ok}; } else { - return {findError("database_empty_result"), "empty"}; + return command_result{error::database_empty_result}; } } //ftcreatedir cid=4 cpw dirname=\/TestDir return_code=1:17 -CommandResult ConnectedClient::handleCommandFTCreateDir(Command &cmd) { +command_result ConnectedClient::handleCommandFTCreateDir(Command &cmd) { CMD_REQ_SERVER; CMD_CHK_AND_INC_FLOOD_POINTS(5); CMD_REQ_FSERVER; auto channel = this->server->channelTree->findChannel(cmd["cid"].as()); - if (!channel) return {findError("channel_invalid_id"), "Cant resolve channel"}; + if (!channel) return command_result{error::channel_invalid_id, "Cant resolve channel"}; if (!channel->passwordMatch(cmd["cpw"]) && !this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_ft_ignore_password, 1, channel, true)) - return cmd["cpw"].string().empty() ? CommandResultPermissionError{permission::b_ft_ignore_password} : CommandResult{findError("channel_invalid_password")}; + return cmd["cpw"].string().empty() ? command_result{permission::b_ft_ignore_password} : command_result{error::channel_invalid_password}; CHANNEL_PERMISSION_TEST(permission::i_ft_directory_create_power, permission::i_ft_needed_directory_create_power, channel, true); auto dir = serverInstance->getFileServer()->createDirectory(cmd["dirname"], serverInstance->getFileServer()->resolveDirectory(this->server, channel, cmd["path"].as())); - if (!dir) return {findError("file_invalid_path"), "could not create dir"}; + if (!dir) return command_result{error::file_invalid_path, "could not create dir"}; - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandFTDeleteFile(Command &cmd) { +command_result ConnectedClient::handleCommandFTDeleteFile(Command &cmd) { CMD_REQ_SERVER; CMD_CHK_AND_INC_FLOOD_POINTS(5); CMD_REQ_FSERVER; @@ -3776,9 +3779,9 @@ CommandResult ConnectedClient::handleCommandFTDeleteFile(Command &cmd) { if (cmd[0].has("cid") && cmd["cid"] != 0) { //Channel auto channel = this->server->channelTree->findChannel(cmd["cid"].as()); - if (!channel) return {findError("channel_invalid_id"), "Cant resolve channel"}; + if (!channel) return command_result{error::channel_invalid_id, "Cant resolve channel"}; if (!channel->passwordMatch(cmd["cpw"]) && !this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_ft_ignore_password, 1, channel, true)) - return cmd["cpw"].string().empty() ? CommandResultPermissionError{permission::b_ft_ignore_password} : CommandResult{findError("channel_invalid_password")}; + return cmd["cpw"].string().empty() ? command_result{permission::b_ft_ignore_password} : command_result{error::channel_invalid_password}; CHANNEL_PERMISSION_TEST(permission::i_ft_file_delete_power, permission::i_ft_needed_file_delete_power, channel, true); for (int index = 0; index < cmd.bulkCount(); index++) files.push_back(serverInstance->getFileServer()->findFile(cmd[index]["name"].as(), serverInstance->getFileServer()->resolveDirectory(this->server, channel))); @@ -3808,7 +3811,7 @@ CommandResult ConnectedClient::handleCommandFTDeleteFile(Command &cmd) { files.push_back(serverInstance->getFileServer()->findFile(cmd["name"].string(), serverInstance->getFileServer()->avatarDirectory(this->server))); } else { logError(this->getServerId(), "Unknown requested file to delete: {}", cmd["path"].as()); - return CommandResult::NotImplemented; + return command_result{error::not_implemented}; } } @@ -3819,10 +3822,10 @@ CommandResult ConnectedClient::handleCommandFTDeleteFile(Command &cmd) { } } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandFTInitUpload(Command &cmd) { +command_result ConnectedClient::handleCommandFTInitUpload(Command &cmd) { CMD_REQ_SERVER; CMD_REQ_FSERVER; @@ -3830,31 +3833,31 @@ CommandResult ConnectedClient::handleCommandFTInitUpload(Command &cmd) { if (cmd[0].has("cid") && cmd["cid"] != 0) { //Channel auto channel = this->server->channelTree->findChannel(cmd["cid"].as()); - if (!channel) return {findError("channel_invalid_id"), "Cant resolve channel"}; + if (!channel) return command_result{error::channel_invalid_id, "Cant resolve channel"}; if (!channel->passwordMatch(cmd["cpw"]) && !this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_ft_ignore_password, 1, channel, true)) - return cmd["cpw"].string().empty() ? CommandResultPermissionError{permission::b_ft_ignore_password} : CommandResult{findError("channel_invalid_password")}; + return cmd["cpw"].string().empty() ? command_result{permission::b_ft_ignore_password} : command_result{error::channel_invalid_password}; CHANNEL_PERMISSION_TEST(permission::i_ft_file_upload_power, permission::i_ft_needed_file_upload_power, channel, true); directory = serverInstance->getFileServer()->resolveDirectory(this->server, channel); } else { if (cmd["path"].as().empty() && cmd["name"].as().find("/icon_") == 0) { auto max_size = this->permissionValue(permission::PERMTEST_ORDERED, permission::i_max_icon_filesize, this->currentChannel); - if(max_size != -1 && max_size < (ssize_t) cmd["size"].as()) return CommandResultPermissionError{permission::i_max_icon_filesize}; + if(max_size != -1 && max_size < (ssize_t) cmd["size"].as()) return command_result{permission::i_max_icon_filesize}; directory = serverInstance->getFileServer()->iconDirectory(this->server); } else if (cmd["path"].as().empty() && cmd["name"].string() == "/avatar") { auto max_size = this->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_max_avatar_filesize, this->currentChannel); - if(max_size != -1 && max_size < (ssize_t) cmd["size"].as()) return CommandResultPermissionError{permission::i_client_max_avatar_filesize}; + if(max_size != -1 && max_size < (ssize_t) cmd["size"].as()) return command_result{permission::i_client_max_avatar_filesize}; directory = serverInstance->getFileServer()->avatarDirectory(this->server); cmd["name"] = "/avatar_" + this->getAvatarId(); } else { cerr << "Unknown requested directory: " << cmd["path"].as() << endl; - return CommandResult::NotImplemented; + return command_result{error::not_implemented}; } } if (!directory || directory->type != file::FileType::DIRECTORY) { //Should not happen cerr << "Invalid upload file path!" << endl; - return {findError("file_invalid_path"), "could not resolve directory"}; + return command_result{error::file_invalid_path, "could not resolve directory"}; } { @@ -3865,7 +3868,7 @@ CommandResult ConnectedClient::handleCommandFTInitUpload(Command &cmd) { server_used_quota += trans->size; for(const auto& trans : serverInstance->getFileServer()->running_file_transfers()) server_used_quota += trans->remaining_bytes(); - if(server_quota >= 0 && server_quota * 1024 * 1024 < (int64_t) server_used_quota) return {findError("file_transfer_server_quota_exceeded")}; + if(server_quota >= 0 && server_quota * 1024 * 1024 < (int64_t) server_used_quota) return command_result{error::file_transfer_server_quota_exceeded}; auto client_quota = this->permissionValue(permission::PERMTEST_ORDERED, permission::i_ft_quota_mb_upload_per_client, this->currentChannel); auto client_used_quota = this->properties()[property::CLIENT_MONTH_BYTES_UPLOADED].as(); @@ -3875,18 +3878,18 @@ CommandResult ConnectedClient::handleCommandFTInitUpload(Command &cmd) { for(const auto& trans : serverInstance->getFileServer()->running_file_transfers(_this.lock())) client_used_quota += trans->remaining_bytes(); - if(client_quota >= 0 && client_quota * 1024 * 1024 < (int64_t) client_used_quota) return {findError("file_transfer_client_quota_exceeded")}; + if(client_quota >= 0 && client_quota * 1024 * 1024 < (int64_t) client_used_quota) return command_result{error::file_transfer_client_quota_exceeded}; } - if (cmd["overwrite"].as() && cmd["resume"].as()) return {findError("file_overwrite_excludes_resume"), "funny"}; + if (cmd["overwrite"].as() && cmd["resume"].as()) return command_result{error::file_overwrite_excludes_resume}; if (serverInstance->getFileServer()->findFile(cmd["name"].as(), directory) && !(cmd["overwrite"].as() || cmd["resume"].as())) - return {findError("file_already_exists"), "file already exists"}; + return command_result{error::file_already_exists, "file already exists"}; //Request: clientftfid=1 serverftfid=6 ftkey=itRNdsIOvcBiBg\/Xj4Ge51ZSrsShHuid port=30033 seekpos=0 //Reqpose: notifystartupload clientftfid=4079 serverftfid=1 ftkey=aX9CFQbfaddHpOYxhQiSLu\/BumfVtPyP port=30033 seekpos=0 proto=1 string error = "success"; auto key = serverInstance->getFileServer()->generateUploadTransferKey(error, directory->path + "/" + directory->name + cmd["name"].string(), cmd["size"].as(), 0, _this.lock()); //TODO implement resume! - if (!key) return {findError(""), "cant generate key"}; //TODO insert error! + if (!key) return command_result{error::vs_critical}; Command result(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifystartupload" : ""); result["clientftfid"] = cmd["clientftfid"].as(); @@ -3906,17 +3909,17 @@ CommandResult ConnectedClient::handleCommandFTInitUpload(Command &cmd) { if(!ip.empty()) result["ip"] = ip; } else { - return {findError("server_is_not_running"), "file server is not bound to any address"}; + return command_result{error::server_is_not_running, "file server is not bound to any address"}; } result["seekpos"] = 0; result["proto"] = 1; result["serverftfid"] = key->key_id; //TODO generate! this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandFTInitDownload(Command &cmd) { +command_result ConnectedClient::handleCommandFTInitDownload(Command &cmd) { CMD_REQ_SERVER; CMD_REQ_FSERVER; @@ -3926,11 +3929,11 @@ CommandResult ConnectedClient::handleCommandFTInitDownload(Command &cmd) { if (cmd[0].has("cid") && cmd["cid"] != (ChannelId) 0) { //Channel auto channel = this->server->channelTree->findChannel(cmd["cid"].as()); - if (!channel) return {findError("channel_invalid_id"), "Cant resolve channel"}; + if (!channel) return command_result{error::channel_invalid_id, "Cant resolve channel"}; CHANNEL_PERMISSION_TEST(permission::i_ft_file_download_power, permission::i_ft_needed_file_download_power, channel, true); if (!channel->passwordMatch(cmd["cpw"]) && !this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_ft_ignore_password, 1, channel, true)) - return cmd["cpw"].string().empty() ? CommandResultPermissionError{permission::b_ft_ignore_password} : CommandResult{findError("channel_invalid_password")}; + return cmd["cpw"].string().empty() ? command_result{permission::b_ft_ignore_password} : command_result{error::channel_invalid_password}; directory = serverInstance->getFileServer()->resolveDirectory(this->server, channel); } else { @@ -3940,21 +3943,21 @@ CommandResult ConnectedClient::handleCommandFTInitDownload(Command &cmd) { directory = serverInstance->getFileServer()->avatarDirectory(this->server); } else { cerr << "Unknown requested directory: " << cmd["path"].as() << endl; - return CommandResult::NotImplemented; + return command_result{error::not_implemented}; } } if (!directory || directory->type != file::FileType::DIRECTORY) { //Should not happen cerr << "Invalid download file path!" << endl; - return {findError("file_invalid_path"), "could not resolve directory"}; + return command_result{error::file_invalid_path, "could not resolve directory"}; } if (!serverInstance->getFileServer()->findFile(cmd["name"].as(), directory)) - return {findError("file_not_found"), "file not exists"}; + return command_result{error::file_not_found, "file not exists"}; string error = "success"; auto key = serverInstance->getFileServer()->generateDownloadTransferKey(error, directory->path + "/" + directory->name + cmd["name"].as(), 0, _this.lock()); //TODO implement resume! - if (!key) return {findError("vs_critical"), "cant generate key (" + error + ")"}; + if (!key) return command_result{error::vs_critical, "cant generate key (" + error + ")"}; { auto server_quota = this->server->properties()[property::VIRTUALSERVER_DOWNLOAD_QUOTA].as(); @@ -3964,7 +3967,7 @@ CommandResult ConnectedClient::handleCommandFTInitDownload(Command &cmd) { server_used_quota += trans->size; for(const auto& trans : serverInstance->getFileServer()->running_file_transfers()) server_used_quota += trans->remaining_bytes(); - if(server_quota >= 0 && server_quota * 1024 * 1024 < (int64_t) server_used_quota) return {findError("file_transfer_server_quota_exceeded")}; + if(server_quota >= 0 && server_quota * 1024 * 1024 < (int64_t) server_used_quota) return command_result{error::file_transfer_server_quota_exceeded}; auto client_quota = this->permissionValue(permission::PERMTEST_ORDERED, permission::i_ft_quota_mb_download_per_client, this->currentChannel); @@ -3975,7 +3978,7 @@ CommandResult ConnectedClient::handleCommandFTInitDownload(Command &cmd) { for(const auto& trans : serverInstance->getFileServer()->running_file_transfers(_this.lock())) client_used_quota += trans->remaining_bytes(); - if(client_quota >= 0 && client_quota * 1024 * 1024 < (int64_t) client_used_quota) return {findError("file_transfer_client_quota_exceeded")}; + if(client_quota >= 0 && client_quota * 1024 * 1024 < (int64_t) client_used_quota) return command_result{error::file_transfer_client_quota_exceeded}; } Command result(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifystartdownload" : ""); @@ -3998,13 +4001,13 @@ CommandResult ConnectedClient::handleCommandFTInitDownload(Command &cmd) { if(!ip.empty()) result["ip"] = ip; } else { - return {findError("server_is_not_running"), "file server is not bound to any address"}; + return command_result{error::server_is_not_running, "file server is not bound to any address"}; } result["size"] = key->size; this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } /* @@ -4025,7 +4028,7 @@ Example: */ -CommandResult ConnectedClient::handleCommandFTGetFileInfo(ts::Command &cmd) { +command_result ConnectedClient::handleCommandFTGetFileInfo(ts::Command &cmd) { CMD_REQ_SERVER; CMD_REQ_FSERVER; CMD_RESET_IDLE; @@ -4038,9 +4041,9 @@ CommandResult ConnectedClient::handleCommandFTGetFileInfo(ts::Command &cmd) { std::shared_ptr file; if (request.has("cid") && request["cid"].as() != 0) { //Channel auto channel = this->server->channelTree->findChannel(request["cid"].as()); - if (!channel) return {findError("channel_invalid_id"), "Cant resolve channel"}; + if (!channel) return command_result{error::channel_invalid_id, "Cant resolve channel"}; if (!channel->passwordMatch(cmd["cpw"]) && !this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_ft_ignore_password, 1, channel, true)) - return cmd["cpw"].string().empty() ? CommandResultPermissionError{permission::b_ft_ignore_password} : CommandResult{findError("channel_invalid_password"), ""}; + return cmd["cpw"].string().empty() ? command_result{permission::b_ft_ignore_password} : command_result{error::channel_invalid_password}; CHANNEL_PERMISSION_TEST(permission::i_ft_file_browse_power, permission::i_ft_needed_file_browse_power, channel, true); file = serverInstance->getFileServer()->findFile(request["name"],serverInstance->getFileServer()->resolveDirectory(this->server, channel, request["path"])); @@ -4052,7 +4055,7 @@ CommandResult ConnectedClient::handleCommandFTGetFileInfo(ts::Command &cmd) { directory = serverInstance->getFileServer()->iconDirectory(this->server); } else { cerr << "Unknown requested directory: '" << request["path"].as() << "'" << endl; - return CommandResult::NotImplemented; + return command_result{error::not_implemented}; } if(!directory) continue; @@ -4073,13 +4076,13 @@ CommandResult ConnectedClient::handleCommandFTGetFileInfo(ts::Command &cmd) { } if(result_index == 0) - return {findError("database_empty_result")}; + return command_result{error::database_empty_result}; this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } //notifybanlist banid=3 ip name uid=zbex8X3bFRTIKLI7mzeyJGZsh64= lastnickname=Wolf\sC++\sXXXX created=1510357269 duration=3600 invokername=WolverinDEV invokercldbid=5 invokeruid=xxjnc14LmvTk+Lyrm8OOeo4tOqw= reason=Prefix\sFake\s\p\sName enforcements=3 -CommandResult ConnectedClient::handleCommandBanList(Command &cmd) { +command_result ConnectedClient::handleCommandBanList(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -4089,18 +4092,18 @@ CommandResult ConnectedClient::handleCommandBanList(Command &cmd) { if (sid == 0) { if(!this->permission_granted(this->cached_permission_value(permission::b_client_ban_list_global), 1)) - return CommandResultPermissionError{permission::b_client_ban_list_global}; + return command_result{permission::b_client_ban_list_global}; } else { auto server = serverInstance->getVoiceServerManager()->findServerById(sid); - if (!server) return {findError("parameter_invalid"), ""}; + if (!server) return command_result{error::parameter_invalid}; if (server->calculatePermission(permission::PERMTEST_ORDERED, this->getClientDatabaseId(), permission::b_client_ban_list, this->getType(), nullptr) != 1) - return CommandResultPermissionError{permission::b_client_ban_list}; + return command_result{permission::b_client_ban_list}; } - //When empty: return {findError("database_empty_result"), "empty"}; + //When empty: return command_result{error::database_empty_result}; auto banList = serverInstance->banManager()->listBans(sid); - if (banList.empty()) return {findError("database_empty_result")}; + if (banList.empty()) return command_result{error::database_empty_result}; auto allow_ip = this->permission_granted(this->cached_permission_value(permission::b_client_remoteaddress_view), 1); Command notify(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifybanlist" : ""); @@ -4132,10 +4135,10 @@ CommandResult ConnectedClient::handleCommandBanList(Command &cmd) { index++; } this->sendCommand(notify); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandBanAdd(Command &cmd) { +command_result ConnectedClient::handleCommandBanAdd(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -4152,18 +4155,18 @@ CommandResult ConnectedClient::handleCommandBanAdd(Command &cmd) { if (sid == 0) { if(!this->permission_granted(this->cached_permission_value(permission::b_client_ban_create_global), 1)) - return CommandResultPermissionError{permission::b_client_ban_create_global}; + return command_result{permission::b_client_ban_create_global}; } else { auto server = serverInstance->getVoiceServerManager()->findServerById(sid); - if (!server) return {findError("parameter_invalid"), ""}; + if (!server) return command_result{error::parameter_invalid}; if (server->calculatePermission(permission::PERMTEST_ORDERED, this->getClientDatabaseId(), permission::b_client_ban_create, this->getType(), nullptr) != 1) - return CommandResultPermissionError{permission::b_client_ban_create_global}; + return command_result{permission::b_client_ban_create_global}; } auto max_ban_time = this->cached_permission_value(permission::i_client_ban_max_bantime); if (max_ban_time != permNotGranted) { if (max_ban_time != -1 && max_ban_time < time) - return CommandResultPermissionError(permission::i_client_ban_max_bantime); + return command_result{permission::i_client_ban_max_bantime}; } chrono::time_point until = time > 0 ? chrono::system_clock::now() + chrono::seconds(time) : chrono::time_point(); @@ -4172,7 +4175,7 @@ CommandResult ConnectedClient::handleCommandBanAdd(Command &cmd) { bool banned = false; if(existing) { if(existing->invokerDbId == this->getClientDatabaseId()) { - if(existing->until == until) return {findError("database_duplicate_entry")}; + if(existing->until == until) return command_result{error::database_duplicate_entry}; else { existing->until = until; serverInstance->banManager()->updateBan(existing); @@ -4186,10 +4189,10 @@ CommandResult ConnectedClient::handleCommandBanAdd(Command &cmd) { for(auto server : (this->server ? std::deque>{this->server} : serverInstance->getVoiceServerManager()->serverInstances())) server->testBanStateChange(_this.lock()); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandBanEdit(Command &cmd) { +command_result ConnectedClient::handleCommandBanEdit(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -4198,16 +4201,16 @@ CommandResult ConnectedClient::handleCommandBanEdit(Command &cmd) { sid = cmd["sid"]; auto ban = serverInstance->banManager()->findBanById(sid, cmd["banid"].as()); - if (!ban) return {findError("database_empty_result"), "empty"}; + if (!ban) return command_result{error::database_empty_result}; if (sid == 0) { if(!this->permission_granted(this->cached_permission_value(permission::b_client_ban_edit_global), 1)) - return CommandResultPermissionError{permission::b_client_ban_edit_global}; + return command_result{permission::b_client_ban_edit_global}; } else { auto server = serverInstance->getVoiceServerManager()->findServerById(sid); - if (!server) return {findError("parameter_invalid"), ""}; + if (!server) return command_result{error::parameter_invalid}; - if (server->calculatePermission(permission::PERMTEST_ORDERED, this->getClientDatabaseId(), permission::b_client_ban_edit, this->getType(), nullptr) != 1) return CommandResultPermissionError{permission::b_client_ban_edit}; + if (server->calculatePermission(permission::PERMTEST_ORDERED, this->getClientDatabaseId(), permission::b_client_ban_edit, this->getType(), nullptr) != 1) return command_result{permission::b_client_ban_edit}; } /* ip name uid reason time hwid */ @@ -4248,12 +4251,12 @@ CommandResult ConnectedClient::handleCommandBanEdit(Command &cmd) { if (changed) serverInstance->banManager()->updateBan(ban); - else return {findError("parameter_invalid"), ""}; + else return command_result{error::parameter_invalid}; - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandBanClient(Command &cmd) { +command_result ConnectedClient::handleCommandBanClient(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -4273,14 +4276,14 @@ CommandResult ConnectedClient::handleCommandBanClient(Command &cmd) { target_clients = this->server->findClientsByUid(uid = cmd["uid"].string()); for(const auto& client : target_clients) if(client->getType() == ClientType::CLIENT_MUSIC) - return {findError("client_invalid_id"), "You cant ban a music bot!"}; + return command_result{error::client_invalid_id, "You cant ban a music bot!"}; } else { target_clients = {this->server->findClient(cmd["clid"].as())}; if(!target_clients[0]) { - return {findError("client_invalid_id"), "Could not find target client"}; + return command_result{error::client_invalid_id, "Could not find target client"}; } if(target_clients[0]->getType() == ClientType::CLIENT_MUSIC) { - return {findError("client_invalid_id"), "You cant ban a music bot!"}; + return command_result{error::client_invalid_id, "You cant ban a music bot!"}; } uid = target_clients[0]->getUid(); } @@ -4292,12 +4295,12 @@ CommandResult ConnectedClient::handleCommandBanClient(Command &cmd) { if (!info.empty()) target_dbid = info[0]->cldbid; else - return {findError("client_unknown")}; + return command_result{error::client_unknown}; } if (target_dbid != 0) { if (this->server->calculatePermission(permission::PERMTEST_ORDERED, target_dbid, permission::i_client_needed_ban_power, ClientType::CLIENT_TEAMSPEAK, nullptr) > this->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_ban_power)) - return CommandResultPermissionError(permission::i_client_ban_power); - if (this->server->calculatePermission(permission::PERMTEST_ORDERED, target_dbid, permission::b_client_ignore_bans, ClientType::CLIENT_TEAMSPEAK, nullptr) >= 1) return CommandResultPermissionError(permission::b_client_ignore_bans); + return command_result{permission::i_client_ban_power}; + if (this->server->calculatePermission(permission::PERMTEST_ORDERED, target_dbid, permission::b_client_ignore_bans, ClientType::CLIENT_TEAMSPEAK, nullptr) >= 1) return command_result{permission::b_client_ignore_bans}; } deque ban_ids; auto _id = serverInstance->banManager()->registerBan(this->getServer()->getServerId(), this->getClientDatabaseId(), reason, uid, "", "", "", until); @@ -4309,8 +4312,8 @@ CommandResult ConnectedClient::handleCommandBanClient(Command &cmd) { auto max_value = this->cached_permission_value(permission::i_client_ban_max_bantime); if(max_value != permNotGranted && max_value != -1) { - if(time > max_value) return CommandResultPermissionError{permission::i_client_ban_max_bantime}; - if(time == 0) return CommandResultPermissionError{permission::i_client_ban_max_bantime}; + if(time > max_value) return command_result{permission::i_client_ban_max_bantime}; + if(time == 0) return command_result{permission::i_client_ban_max_bantime}; } for (const auto &client : target_clients) { @@ -4350,10 +4353,10 @@ CommandResult ConnectedClient::handleCommandBanClient(Command &cmd) { this->sendCommand(notify); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandBanDel(Command &cmd) { +command_result ConnectedClient::handleCommandBanDel(Command &cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -4362,34 +4365,34 @@ CommandResult ConnectedClient::handleCommandBanDel(Command &cmd) { sid = cmd["sid"]; auto ban = serverInstance->banManager()->findBanById(sid, cmd["banid"].as()); - if (!ban) return {findError("database_empty_result"), "empty"}; + if (!ban) return command_result{error::database_empty_result}; if (sid == 0) { const auto permission = ban->invokerDbId == this->getClientDatabaseId() ? permission::b_client_ban_delete_own_global : permission::b_client_ban_delete_global; if(!this->permission_granted(this->cached_permission_value(permission), 1)) - return CommandResultPermissionError{permission}; + return command_result{permission}; } else { auto server = serverInstance->getVoiceServerManager()->findServerById(sid); - if (!server) return {findError("parameter_invalid"), ""}; + if (!server) return command_result{error::parameter_invalid}; auto perm = ban->invokerDbId == this->getClientDatabaseId() ? permission::b_client_ban_delete_own : permission::b_client_ban_delete; - if (server->calculatePermission(permission::PERMTEST_ORDERED, this->getClientDatabaseId(), perm, this->getType(), nullptr) != 1) return CommandResultPermissionError{perm}; + if (server->calculatePermission(permission::PERMTEST_ORDERED, this->getClientDatabaseId(), perm, this->getType(), nullptr) != 1) return command_result{perm}; } serverInstance->banManager()->unban(ban); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandBanDelAll(Command &cmd) { +command_result ConnectedClient::handleCommandBanDelAll(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); CACHED_PERM_CHECK(permission::b_client_ban_delete, 1, true); serverInstance->banManager()->deleteAllBans(server->getServerId()); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandBanTriggerList(ts::Command &cmd) { +command_result ConnectedClient::handleCommandBanTriggerList(ts::Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -4398,7 +4401,7 @@ CommandResult ConnectedClient::handleCommandBanTriggerList(ts::Command &cmd) { CMD_REQ_PARM("banid"); auto record = serverInstance->banManager()->findBanById(this->getServerId(), cmd["banid"]); - if(!record) return {findError("parameter_invalid"), "Invalid ban id"}; + if(!record) return command_result{error::parameter_invalid, "Invalid ban id"}; Command notify(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifybantriggerlist" : ""); notify["banid"] = record->banId; @@ -4417,13 +4420,13 @@ CommandResult ConnectedClient::handleCommandBanTriggerList(ts::Command &cmd) { notify[index]["timestamp"] = duration_cast(entry->timestamp.time_since_epoch()).count(); index++; } - if (index == 0) return {findError("database_empty_result")}; + if (index == 0) return command_result{error::database_empty_result}; this->sendCommand(notify); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandTokenList(Command &cmd) { +command_result ConnectedClient::handleCommandTokenList(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -4440,13 +4443,13 @@ CommandResult ConnectedClient::handleCommandTokenList(Command &cmd) { notify[index]["token_description"] = token->description; index++; } - if (index == 0) return {findError("database_empty_result"), "empty!"}; + if (index == 0) return command_result{error::database_empty_result}; this->sendCommand(notify); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandTokenAdd(Command &cmd) { +command_result ConnectedClient::handleCommandTokenAdd(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -4459,8 +4462,8 @@ CommandResult ConnectedClient::handleCommandTokenAdd(Command &cmd) { { auto group = this->server->groups->findGroup(gId); - if(!group) return {findError("parameter_invalid"), "invalid server group id"}; - if(group->type() == GroupType::GROUP_TYPE_TEMPLATE) return {findError("parameter_invalid"), "invalid server group type"}; + if(!group) return command_result{error::group_invalid_id}; + if(group->type() == GroupType::GROUP_TYPE_TEMPLATE) return command_result{error::parameter_invalid, "invalid server group type"}; if(group->target() == GroupTarget::GROUPTARGET_SERVER) GROUP_PERMISSION_TEST(permission::i_server_group_member_add_power, permission::i_server_group_needed_member_add_power, group, true); @@ -4468,22 +4471,22 @@ CommandResult ConnectedClient::handleCommandTokenAdd(Command &cmd) { GROUP_PERMISSION_TEST(permission::i_channel_group_member_add_power, permission::i_channel_group_needed_member_add_power, group, true); } if (ttype == TokenType::TOKEN_CHANNEL) { - if (!this->server->channelTree->findChannel(cId)) return {findError("channel_invalid_id"), "Cant resolve channel"}; + if (!this->server->channelTree->findChannel(cId)) return command_result{error::channel_invalid_id, "Cant resolve channel"}; } else if (ttype == TokenType::TOKEN_SERVER); - else return {findError("parameter_invalid"), "invalid token target type"}; + else return command_result{error::parameter_invalid, "invalid token target type"}; auto result = this->server->tokenManager->createToken(ttype, gId, description, cId, cmd["token"]); - if (!result) return {ErrorType::Success, "internal error"}; + if (!result) return command_result{error::vs_critical}; Command notify(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifytokenadd" : ""); notify["token"] = result->token; this->sendCommand(notify); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandTokenUse(Command &cmd) { +command_result ConnectedClient::handleCommandTokenUse(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -4491,24 +4494,24 @@ CommandResult ConnectedClient::handleCommandTokenUse(Command &cmd) { auto strToken = cmd["token"].string(); auto token = this->server->tokenManager->findToken(strToken); - if (!token) return {findError("token_invalid_id"), "Invalid token. (Token not registered)"}; + if (!token) return command_result{error::token_invalid_id, "Invalid token. (Token not registered)"}; this->server->tokenManager->deleteToke(token->token); auto serverGroup = this->server->groups->findGroup(token->groupId); - if (!serverGroup) return {findError("token_invalid_id"), "Token invalid groupId"}; + if (!serverGroup) return command_result{error::token_invalid_id, "Token invalid groupId"}; this->server->properties()[property::VIRTUALSERVER_ASK_FOR_PRIVILEGEKEY] = false; //TODO test if its the default token std::shared_ptr channel = nullptr; if (token->channelId != 0) { channel = this->server->channelTree->findChannel(token->channelId); - if (!channel) return {findError("token_invalid_id"), "Token invalid channelId"}; + if (!channel) return command_result{error::token_invalid_id, "Token invalid channelId"}; this->server->groups->setChannelGroup(this->getClientDatabaseId(), serverGroup, channel); } else { if(!this->server->groups->hasServerGroupAssigned(this->getClientDatabaseId(), serverGroup)) this->server->groups->addServerGroup(this->getClientDatabaseId(), serverGroup); else { - return CommandResult::Success; + return command_result{error::ok}; } } @@ -4525,10 +4528,10 @@ CommandResult ConnectedClient::handleCommandTokenUse(Command &cmd) { this->notifyServerGroupClientAdd(this->server->serverRoot, _this.lock(), serverGroup); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandTokenDelete(Command &cmd) { +command_result ConnectedClient::handleCommandTokenDelete(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -4536,14 +4539,14 @@ CommandResult ConnectedClient::handleCommandTokenDelete(Command &cmd) { auto strToken = cmd["token"].string(); auto token = this->server->tokenManager->findToken(strToken); - if (!token) return {findError("token_invalid_id"), "Invalid token. (Token not registered)"}; + if (!token) return command_result{error::token_invalid_id, "Invalid token. (Token not registered)"}; this->server->tokenManager->deleteToke(token->token); if(token->token == this->server->properties()[property::VIRTUALSERVER_AUTOGENERATED_PRIVILEGEKEY].as()) { this->server->properties()[property::VIRTUALSERVER_AUTOGENERATED_PRIVILEGEKEY] = ""; this->server->properties()[property::VIRTUALSERVER_ASK_FOR_PRIVILEGEKEY] = false; logMessage(this->getServerId(), "{} Deleting the default server token. Don't ask anymore for this a token!", CLIENT_STR_LOG_PREFIX); } - return CommandResult::Success; + return command_result{error::ok}; } //start=0 duration=10 @@ -4559,7 +4562,7 @@ struct ClientDbArgs { Command *result = nullptr; }; -CommandResult ConnectedClient::handleCommandClientDbList(Command &cmd) { +command_result ConnectedClient::handleCommandClientDbList(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -4634,7 +4637,7 @@ CommandResult ConnectedClient::handleCommandClientDbList(Command &cmd) { return 0; }, &args)); - if (args.resultIndex == 0) return {findError("database_empty_result"), "empty!"}; + if (args.resultIndex == 0) return command_result{error::database_empty_result}; if (cmd.hasParm("count")) { size_t result = 0; sql::command(this->server->getSql(), "SELECT COUNT(*) AS `count` FROM `clients` WHERE `serverId` = :sid", variable{":sid", this->server->getServerId()}).query([](size_t *ptr, int, char **v, char **) { @@ -4645,16 +4648,16 @@ CommandResult ConnectedClient::handleCommandClientDbList(Command &cmd) { } this->sendCommand(notify); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientDBEdit(Command &cmd) { +command_result ConnectedClient::handleCommandClientDBEdit(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); PERM_CHECKR(permission::b_client_modify_dbproperties, 1, true); - if (!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cmd["cldbid"])) return {findError("database_empty_result"), "invalid cldbid"}; + if (!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cmd["cldbid"])) return command_result{error::database_empty_result, "invalid cldbid"}; auto props = serverInstance->databaseHelper()->loadClientProperties(this->server, cmd["cldbid"], ClientType::CLIENT_TEAMSPEAK); for (auto &elm : cmd[0].keys()) { @@ -4672,10 +4675,10 @@ CommandResult ConnectedClient::handleCommandClientDBEdit(Command &cmd) { (*props)[info] = cmd[elm].string(); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPluginCmd(Command &cmd) { +command_result ConnectedClient::handleCommandPluginCmd(Command &cmd) { CMD_REQ_SERVER; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -4696,7 +4699,7 @@ CommandResult ConnectedClient::handleCommandPluginCmd(Command &cmd) { for (int index = 0; index < cmd.bulkCount(); index++) { auto target = cmd[index]["target"].as(); auto cl = this->server->findClient(target); - if (!cl) return {findError("client_invalid_id"), "invalid target id"}; + if (!cl) return command_result{error::client_invalid_id, "invalid target id"}; cl->notifyPluginCmd(cmd["name"], cmd["data"], _this.lock()); } } @@ -4706,25 +4709,25 @@ CommandResult ConnectedClient::handleCommandPluginCmd(Command &cmd) { auto target = _this.lock(); if(cmd[0].has("target")) target = this->server->findClient(cmd["target"].as()); - if(!target) return {findError("client_invalid_id"), "invalid target id"}; + if(!target) return command_result{error::client_invalid_id, "invalid target id"}; target->sendCommand(Command(cmd["command"].string()), cmd[0].has("low") ? cmd["low"] : false); } */ - else return CommandResult::NotImplemented; - return CommandResult::Success; + else return command_result{error::not_implemented}; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientEdit(ts::Command &cmd) { +command_result ConnectedClient::handleCommandClientEdit(ts::Command &cmd) { CMD_REQ_SERVER; auto client = this->server->findClient(cmd["clid"].as()); - if (!client) return {findError("client_invalid_id"), "invalid client id"}; + if (!client) return command_result{error::client_invalid_id}; return this->handleCommandClientEdit(cmd, client); } -CommandResult ConnectedClient::handleCommandClientEdit(Command &cmd, const std::shared_ptr& client) { +command_result ConnectedClient::handleCommandClientEdit(Command &cmd, const std::shared_ptr& client) { assert(client); auto self = client == this; CMD_CHK_AND_INC_FLOOD_POINTS(self ? 15 : 25); @@ -4767,7 +4770,7 @@ CommandResult ConnectedClient::handleCommandClientEdit(Command &cmd, const std:: } string value = cmd["client_description"].string(); - if (count_characters(value) > 200) return {findError("parameter_invalid"), "Invalid description length. A maximum of 200 characters is allowed!"}; + if (count_characters(value) > 200) return command_result{error::parameter_invalid, "Invalid description length. A maximum of 200 characters is allowed!"}; } else if (*info == property::CLIENT_IS_TALKER) { PERM_CHECK_CHANNELR(permission::b_client_set_flag_talker, 1, client->getChannel(), true); cmd["client_is_talker"] = cmd["client_is_talker"].as(); @@ -4779,20 +4782,21 @@ CommandResult ConnectedClient::handleCommandClientEdit(Command &cmd, const std:: continue; } else if(*info == property::CLIENT_NICKNAME) { if(!self) { - if(client->getType() != ClientType::CLIENT_MUSIC) return {findError("client_invalid_type")}; + if(client->getType() != ClientType::CLIENT_MUSIC) return command_result{error::client_invalid_type}; if(client->properties()[property::CLIENT_OWNER] != this->getClientDatabaseId()) { CACHED_PERM_CHECK(permission::i_client_music_rename_power, client->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_rename_power, client->currentChannel), true); } } string name = cmd["client_nickname"].string(); - if (count_characters(name) < 3) return {findError("parameter_invalid"), "Invalid name length. A minimum of 3 characters is required!"}; - if (count_characters(name) > 30) return {findError("parameter_invalid"), "Invalid name length. A maximum of 30 characters is allowed!"}; + if (count_characters(name) < 3) return command_result{error::parameter_invalid, "Invalid name length. A minimum of 3 characters is required!"}; + if (count_characters(name) > 30) return command_result{error::parameter_invalid, "Invalid name length. A maximum of 30 characters is allowed!"}; auto banIgnore = this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_ignore_bans, 1, this->currentChannel); if (!banIgnore) { auto banRecord = serverInstance->banManager()->findBanByName(this->getServerId(), name); - if (banRecord) return {findError("client_nickname_inuse"), string() + "This nickname is " + (banRecord->serverId == 0 ? "globally " : "") + "banned for the reason: " + banRecord->reason}; + if (banRecord) + return command_result{error::client_nickname_inuse, string() + "This nickname is " + (banRecord->serverId == 0 ? "globally " : "") + "banned for the reason: " + banRecord->reason}; } if (this->server) { nickname_lock = std::make_unique>(this->server->client_nickname_lock); @@ -4802,7 +4806,7 @@ CommandResult ConnectedClient::handleCommandClientEdit(Command &cmd, const std:: if(cl == this) self = true; else - return {findError("client_nickname_inuse"), "This nickname is already in use"}; + return command_result{error::client_nickname_inuse, "This nickname is already in use"}; } } if(self) { @@ -4811,7 +4815,7 @@ CommandResult ConnectedClient::handleCommandClientEdit(Command &cmd, const std:: } } } else if(*info == property::CLIENT_PLAYER_VOLUME) { - if(client->getType() != ClientType::CLIENT_MUSIC) return {findError("client_invalid_type")}; + if(client->getType() != ClientType::CLIENT_MUSIC) return command_result{error::client_invalid_type}; if(client->properties()[property::CLIENT_OWNER] != this->getClientDatabaseId()) { CACHED_PERM_CHECK(permission::i_client_music_modify_power, client->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_modify_power, client->currentChannel), true); } @@ -4820,12 +4824,12 @@ CommandResult ConnectedClient::handleCommandClientEdit(Command &cmd, const std:: auto volume = cmd["player_volume"].as(); auto max_volume = this->cached_permission_value(permission::i_client_music_create_modify_max_volume); - if(max_volume != permNotGranted && !this->permission_granted(max_volume, volume * 100)) return CommandResultPermissionError{permission::i_client_music_create_modify_max_volume}; + if(max_volume != permNotGranted && !this->permission_granted(max_volume, volume * 100)) return command_result{permission::i_client_music_create_modify_max_volume}; bot->volume_modifier(cmd["player_volume"]); } else if(*info == property::CLIENT_IS_CHANNEL_COMMANDER) { if(!self) { - if(client->getType() != ClientType::CLIENT_MUSIC) return {findError("client_invalid_type")}; + if(client->getType() != ClientType::CLIENT_MUSIC) return command_result{error::client_invalid_type}; if(client->properties()[property::CLIENT_OWNER] != this->getClientDatabaseId()) { CACHED_PERM_CHECK(permission::i_client_music_modify_power, client->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_modify_power, client->currentChannel), true); } @@ -4838,7 +4842,7 @@ CommandResult ConnectedClient::handleCommandClientEdit(Command &cmd, const std:: //FIXME allow other to remove this thing if(!self) { if(client->getType() != ClientType::CLIENT_MUSIC) - return {findError("client_invalid_type")}; + return command_result{error::client_invalid_type}; if(client->properties()[property::CLIENT_OWNER] != this->getClientDatabaseId()) { CACHED_PERM_CHECK(permission::i_client_music_modify_power, client->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_modify_power, client->currentChannel), true); } @@ -4869,31 +4873,31 @@ CommandResult ConnectedClient::handleCommandClientEdit(Command &cmd, const std:: if (badgesTags >= 2) { if (!this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_allow_invalid_badges, 1, this->currentChannel)) ((VoiceClient *) this)->disconnect(VREASON_SERVER_KICK, config::messages::kick_invalid_badges, this->server ? this->server->serverAdmin : dynamic_pointer_cast(serverInstance->getInitialServerAdmin()), true); - return {findError("parameter_invalid"), "Invalid badges"}; + return command_result{error::parameter_invalid, "Invalid badges"}; } //FIXME stuff here } else if(!self && key == "client_version") { - if(client->getType() != ClientType::CLIENT_MUSIC) return {findError("client_invalid_type")}; + if(client->getType() != ClientType::CLIENT_MUSIC) return command_result{error::client_invalid_type}; if(client->properties()[property::CLIENT_OWNER] != this->getClientDatabaseId()) { CACHED_PERM_CHECK(permission::i_client_music_modify_power, client->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_modify_power, client->currentChannel), true); } } else if(!self && key == "client_platform") { - if(client->getType() != ClientType::CLIENT_MUSIC) return {findError("client_invalid_type")}; + if(client->getType() != ClientType::CLIENT_MUSIC) return command_result{error::client_invalid_type}; if(client->properties()[property::CLIENT_OWNER] != this->getClientDatabaseId()) { CACHED_PERM_CHECK(permission::i_client_music_modify_power, client->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_modify_power, client->currentChannel), true); } } else if(!self && key == "client_country") { - if(client->getType() != ClientType::CLIENT_MUSIC) return {findError("client_invalid_type")}; + if(client->getType() != ClientType::CLIENT_MUSIC) return command_result{error::client_invalid_type}; if(client->properties()[property::CLIENT_OWNER] != this->getClientDatabaseId()) { CACHED_PERM_CHECK(permission::i_client_music_modify_power, client->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_modify_power, client->currentChannel), true); } } else if(!self && (*info == property::CLIENT_FLAG_NOTIFY_SONG_CHANGE/* || *info == property::CLIENT_NOTIFY_SONG_MESSAGE*/)) { - if(client->getType() != ClientType::CLIENT_MUSIC) return {findError("client_invalid_type")}; + if(client->getType() != ClientType::CLIENT_MUSIC) return command_result{error::client_invalid_type}; if(client->properties()[property::CLIENT_OWNER] != this->getClientDatabaseId()) { CACHED_PERM_CHECK(permission::i_client_music_modify_power, client->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_modify_power, client->currentChannel), true); } } else if(!self && key == "client_uptime_mode") { - if(client->getType() != ClientType::CLIENT_MUSIC) return {findError("client_invalid_type")}; + if(client->getType() != ClientType::CLIENT_MUSIC) return command_result{error::client_invalid_type}; if(client->properties()[property::CLIENT_OWNER] != this->getClientDatabaseId()) { CACHED_PERM_CHECK(permission::i_client_music_modify_power, client->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_modify_power, client->currentChannel), true); } @@ -4917,12 +4921,12 @@ CommandResult ConnectedClient::handleCommandClientEdit(Command &cmd, const std:: } else if(type == MusicClient::Type::PERMANENT) { CACHED_PERM_CHECK(permission::b_client_music_modify_permanent, 1, true); } else - return {findError("parameter_invalid")}; + return command_result{error::parameter_invalid}; } else if(*info == property::CLIENT_AWAY_MESSAGE) { if(!self) continue; if(cmd["client_away_message"].string().length() > 256) - return {findError("parameter_invalid")}; + return command_result{error::parameter_invalid}; } else if(!self) { /* dont edit random properties of other clients. For us self its allowed to edit the rest without permissions */ continue; } @@ -4944,39 +4948,39 @@ CommandResult ConnectedClient::handleCommandClientEdit(Command &cmd, const std:: if(this->server) this->server->notifyClientPropertyUpdates(client, updates); nickname_lock.reset(); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientUpdate(Command &cmd) { +command_result ConnectedClient::handleCommandClientUpdate(Command &cmd) { return this->handleCommandClientEdit(cmd, _this.lock()); } -CommandResult ConnectedClient::handleCommandClientMute(Command &cmd) { +command_result ConnectedClient::handleCommandClientMute(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; auto client = this->server->findClient(cmd["clid"].as()); - if (!client || client->getClientId() == this->getClientId()) return {findError("client_invalid_id"), "invalid client id"}; + if (!client || client->getClientId() == this->getClientId()) return command_result{error::client_invalid_id}; { unique_lock channel_lock(this->channel_lock); for(const auto& weak : this->mutedClients) - if(weak.lock() == client) return CommandResult::Success; + if(weak.lock() == client) return command_result{error::ok}; this->mutedClients.push_back(client); } if (config::voice::notifyMuted) client->notifyTextMessage(ChatMessageMode::TEXTMODE_PRIVATE, _this.lock(), client->getClientId(), 0, system_clock::now(), config::messages::mute_notify_message); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientUnmute(Command &cmd) { +command_result ConnectedClient::handleCommandClientUnmute(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; auto client = this->server->findClient(cmd["clid"].as()); - if (!client || client->getClientId() == this->getClientId()) return {findError("client_invalid_id"), "invalid client id"}; + if (!client || client->getClientId() == this->getClientId()) return command_result{error::client_invalid_id}; { unique_lock channel_lock(this->channel_lock); @@ -4989,10 +4993,10 @@ CommandResult ConnectedClient::handleCommandClientUnmute(Command &cmd) { if (config::voice::notifyMuted) client->notifyTextMessage(ChatMessageMode::TEXTMODE_PRIVATE, _this.lock(), client->getClientId(), 0, system_clock::now(), config::messages::unmute_notify_message); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientList(Command &cmd) { +command_result ConnectedClient::handleCommandClientList(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; @@ -5062,10 +5066,10 @@ CommandResult ConnectedClient::handleCommandClientList(Command &cmd) { index++; }); this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandWhoAmI(Command &cmd) { +command_result ConnectedClient::handleCommandWhoAmI(Command &cmd) { CMD_RESET_IDLE; Command result(""); @@ -5102,14 +5106,14 @@ CommandResult ConnectedClient::handleCommandWhoAmI(Command &cmd) { } this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandServerGroupsByClientId(Command &cmd) { +command_result ConnectedClient::handleCommandServerGroupsByClientId(Command &cmd) { CMD_RESET_IDLE; ClientDbId cldbid = cmd["cldbid"]; - if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cldbid)) return {findError("client_invalid_id"), "invalid client id"}; + if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cldbid)) return command_result{error::client_invalid_id}; Command result(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifyservergroupsbyclientid" : ""); @@ -5130,12 +5134,12 @@ CommandResult ConnectedClient::handleCommandServerGroupsByClientId(Command &cmd) } } - if (index == 0) return {findError("database_empty_result"), "empty!"}; + if (index == 0) return command_result{error::database_empty_result}; this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientGetDBIDfromUID(Command &cmd) { +command_result ConnectedClient::handleCommandClientGetDBIDfromUID(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; @@ -5144,7 +5148,7 @@ CommandResult ConnectedClient::handleCommandClientGetDBIDfromUID(Command &cmd) { unique_ids.push_back(cmd[index]["cluid"].as()); auto res = serverInstance->databaseHelper()->queryDatabaseInfoByUid(this->server, unique_ids); - if (res.empty()) return {findError("database_empty_result"), "empty!"}; + if (res.empty()) return command_result{error::database_empty_result}; Command result(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifyclientdbidfromuid" : ""); int result_index = 0; @@ -5154,10 +5158,10 @@ CommandResult ConnectedClient::handleCommandClientGetDBIDfromUID(Command &cmd) { result_index++; } this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientGetNameFromDBID(Command &cmd) { +command_result ConnectedClient::handleCommandClientGetNameFromDBID(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; @@ -5166,7 +5170,7 @@ CommandResult ConnectedClient::handleCommandClientGetNameFromDBID(Command &cmd) dbids.push_back(cmd[index]["cldbid"].as()); auto res = serverInstance->databaseHelper()->queryDatabaseInfo(this->server, dbids); - if (res.empty()) return {findError("database_empty_result"), "empty!"}; + if (res.empty()) return command_result{error::database_empty_result}; Command result(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifyclientgetnamefromdbid" : ""); int result_index = 0; @@ -5178,10 +5182,10 @@ CommandResult ConnectedClient::handleCommandClientGetNameFromDBID(Command &cmd) result_index++; } this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientGetNameFromUid(Command &cmd) { +command_result ConnectedClient::handleCommandClientGetNameFromUid(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; @@ -5190,7 +5194,7 @@ CommandResult ConnectedClient::handleCommandClientGetNameFromUid(Command &cmd) { unique_ids.push_back(cmd[index]["cluid"].as()); auto res = serverInstance->databaseHelper()->queryDatabaseInfoByUid(this->server, unique_ids); - if (res.empty()) return {findError("database_empty_result"), "empty!"}; + if (res.empty()) return command_result{error::database_empty_result}; Command result(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifyclientnamefromuid" : ""); int result_index = 0; @@ -5202,10 +5206,10 @@ CommandResult ConnectedClient::handleCommandClientGetNameFromUid(Command &cmd) { result_index++; } this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientGetUidFromClid(Command &cmd) { +command_result ConnectedClient::handleCommandClientGetUidFromClid(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; @@ -5235,18 +5239,18 @@ CommandResult ConnectedClient::handleCommandClientGetUidFromClid(Command &cmd) { if(result_index > 0) this->sendCommand(notify); if(error) - return {findError("database_empty_result"), "empty!"}; - return CommandResult::Success; + return command_result{error::database_empty_result}; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientAddPerm(Command &cmd) { +command_result ConnectedClient::handleCommandClientAddPerm(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto cldbid = cmd["cldbid"].as(); if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cldbid)) - return {findError("client_invalid_id"), "invalid client id"}; + return command_result{error::client_invalid_id}; auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cldbid); PERM_CHECKR(permission::i_client_permission_modify_power, this->server->calculatePermission(permission::PERMTEST_ORDERED, cldbid, permission::i_client_needed_permission_modify_power, ClientType::CLIENT_TEAMSPEAK, nullptr), true); @@ -5260,10 +5264,10 @@ CommandResult ConnectedClient::handleCommandClientAddPerm(Command &cmd) { auto val = cmd[index]["permvalue"].as(); if(permission_require_granted_value(permType) && val > maxValue) - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; if(!ignoreGrant && !this->permissionGrantGranted(permission::PERMTEST_ORDERED, permType, 1, this->currentChannel)) - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; if (grant) { mgr->set_permission(permType, {0, cmd[index]["permvalue"]}, permission::v2::do_nothing, permission::v2::set_value); @@ -5283,17 +5287,17 @@ CommandResult ConnectedClient::handleCommandClientAddPerm(Command &cmd) { elm->join_state_id++; /* join permission may changed, all channels need to be recalculate dif needed */ } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientDelPerm(Command &cmd) { +command_result ConnectedClient::handleCommandClientDelPerm(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto cldbid = cmd["cldbid"].as(); if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cldbid)) - return {findError("client_invalid_id"), "invalid client id"}; + return command_result{error::client_invalid_id}; auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cldbid); PERM_CHECKR(permission::i_client_permission_modify_power, this->server->calculatePermission(permission::PERMTEST_ORDERED, cldbid, permission::i_client_needed_permission_modify_power, ClientType::CLIENT_TEAMSPEAK, nullptr), true); @@ -5305,7 +5309,7 @@ CommandResult ConnectedClient::handleCommandClientDelPerm(Command &cmd) { PARSE_PERMISSION(cmd) if(!ignoreGrant && !this->permissionGrantGranted(permission::PERMTEST_ORDERED, permType, 1, this->currentChannel)) - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; if (grant) { @@ -5325,38 +5329,38 @@ CommandResult ConnectedClient::handleCommandClientDelPerm(Command &cmd) { elm->updateChannelClientProperties(true, true); elm->join_state_id++; /* join permission may changed, all channels need to be recalculate dif needed */ } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientPermList(Command &cmd) { +command_result ConnectedClient::handleCommandClientPermList(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); PERM_CHECKR(permission::b_virtualserver_client_permission_list, 1, true); - if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cmd["cldbid"])) return {findError("client_invalid_id"), "invalid client id"}; + if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cmd["cldbid"])) return command_result{error::client_invalid_id}; auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cmd["cldbid"]); - if (!this->notifyClientPermList(cmd["cldbid"], mgr, cmd.hasParm("permsid"))) return {findError("database_empty_result"), "empty!"}; - return CommandResult::Success; + if (!this->notifyClientPermList(cmd["cldbid"], mgr, cmd.hasParm("permsid"))) return command_result{error::database_empty_result}; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelClientPermList(Command &cmd) { +command_result ConnectedClient::handleCommandChannelClientPermList(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); PERM_CHECKR(permission::b_virtualserver_channelclient_permission_list, 1, true); RESOLVE_CHANNEL_R(cmd["cid"], true); auto channel = dynamic_pointer_cast(l_channel->entry); - if(!channel) return {ErrorType::VSError}; + if(!channel) return command_result{error::vs_critical}; - if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cmd["cldbid"])) return {findError("client_invalid_id"), "invalid client id"}; + if(!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cmd["cldbid"])) return command_result{error::client_invalid_id}; auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cmd["cldbid"].as()); Command res(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifychannelclientpermlist" : ""); auto permissions = mgr->channel_permissions(channel->channelId()); if(permissions.empty()) - return {ErrorType::DBEmpty}; + return command_result{error::database_empty_result}; int index = 0; res[index]["cid"] = channel->channelId(); @@ -5394,24 +5398,24 @@ CommandResult ConnectedClient::handleCommandChannelClientPermList(Command &cmd) } this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelClientDelPerm(Command &cmd) { +command_result ConnectedClient::handleCommandChannelClientDelPerm(Command &cmd) { CMD_REF_SERVER(server_ref); CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto cldbid = cmd["cldbid"].as(); if (!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cldbid)) - return {findError("parameter_invalid"), "Invalid manager db id"}; + return command_result{error::parameter_invalid, "Invalid manager db id"}; auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cldbid); PERM_CHECKR(permission::i_client_permission_modify_power, this->server->calculatePermission(permission::PERMTEST_ORDERED, cmd["cldbid"], permission::i_client_needed_permission_modify_power, ClientType::CLIENT_TEAMSPEAK, nullptr), true); RESOLVE_CHANNEL_R(cmd["cid"], true); auto channel = dynamic_pointer_cast(l_channel->entry); - if(!channel) return {ErrorType::VSError}; + if(!channel) return command_result{error::vs_critical}; bool ignoreGrant = this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_permission_modify_power_ignore, 1, this->currentChannel); bool conOnError = cmd[0].has("continueonerror"), update_view = false; @@ -5420,7 +5424,7 @@ CommandResult ConnectedClient::handleCommandChannelClientDelPerm(Command &cmd) { PARSE_PERMISSION(cmd); if(!ignoreGrant && !this->permissionGrantGranted(permission::PERMTEST_ORDERED, permType, 1, this->currentChannel)) - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; if (grant) { mgr->set_channel_permission(permType, channel->channelId(), permission::v2::empty_permission_values, permission::v2::do_nothing, permission::v2::delete_value); @@ -5458,21 +5462,21 @@ CommandResult ConnectedClient::handleCommandChannelClientDelPerm(Command &cmd) { } } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelClientAddPerm(Command &cmd) { +command_result ConnectedClient::handleCommandChannelClientAddPerm(Command &cmd) { CMD_REF_SERVER(server_ref); CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto cldbid = cmd["cldbid"].as(); if (!serverInstance->databaseHelper()->validClientDatabaseId(this->server, cldbid)) - return {findError("parameter_invalid"), "Invalid client db id"}; + return command_result{error::parameter_invalid, "Invalid client db id"}; RESOLVE_CHANNEL_R(cmd["cid"], true); auto channel = dynamic_pointer_cast(l_channel->entry); - if(!channel) return {ErrorType::VSError}; + if(!channel) return command_result{error::vs_critical}; auto mgr = serverInstance->databaseHelper()->loadClientPermissionManager(this->server, cldbid); PERM_CHECK_CHANNELR(permission::i_client_permission_modify_power, this->server->calculatePermission(permission::PERMTEST_ORDERED, cmd["cldbid"], permission::i_client_needed_permission_modify_power, ClientType::CLIENT_TEAMSPEAK, channel), channel, true); @@ -5488,10 +5492,10 @@ CommandResult ConnectedClient::handleCommandChannelClientAddPerm(Command &cmd) { auto val = cmd[index]["permvalue"].as(); if(permission_require_granted_value(permType) && val > maxValue) - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; if(!ignoreGrant && !this->permissionGrantGranted(permission::PERMTEST_ORDERED, permType, 1, this->currentChannel)) - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; if (grant) { @@ -5528,10 +5532,10 @@ CommandResult ConnectedClient::handleCommandChannelClientAddPerm(Command &cmd) { elm->join_state_id++; /* join permission may changed, all channels need to be recalculate dif needed */ } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientDbInfo(Command &cmd) { +command_result ConnectedClient::handleCommandClientDbInfo(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -5542,7 +5546,7 @@ CommandResult ConnectedClient::handleCommandClientDbInfo(Command &cmd) { cldbids.push_back(cmd[index]["cldbid"]); auto basic = serverInstance->databaseHelper()->queryDatabaseInfo(this->server, cldbids); - if (basic.empty()) return {findError("database_empty_result"), "empty!"}; + if (basic.empty()) return command_result{error::database_empty_result}; auto allow_ip = this->permission_granted(this->cached_permission_value(permission::b_client_remoteaddress_view), 1); Command res(this->getExternalType() == ClientType::CLIENT_TEAMSPEAK ? "notifyclientdbinfo" : ""); @@ -5583,20 +5587,20 @@ CommandResult ConnectedClient::handleCommandClientDbInfo(Command &cmd) { this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientDBDelete(Command &cmd) { +command_result ConnectedClient::handleCommandClientDBDelete(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); PERM_CHECKR(permission::b_client_delete_dbproperties, 1, true); ClientDbId id = cmd["cldbid"]; - if (!serverInstance->databaseHelper()->validClientDatabaseId(this->server, id)) return {findError("database_empty_result"), ""}; + if (!serverInstance->databaseHelper()->validClientDatabaseId(this->server, id)) return command_result{error::database_empty_result}; serverInstance->databaseHelper()->deleteClient(this->server, id); - return CommandResult::Success; + return command_result{error::ok}; } struct DBFindArgs { @@ -5606,7 +5610,7 @@ struct DBFindArgs { Command cmd{""}; }; -CommandResult ConnectedClient::handleCommandClientDBFind(Command &cmd) { +command_result ConnectedClient::handleCommandClientDBFind(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -5651,14 +5655,14 @@ CommandResult ConnectedClient::handleCommandClientDBFind(Command &cmd) { }, &args); auto pf = LOG_SQL_CMD; pf(res); - if (args.index == 0) return {findError("database_empty_result"), ""}; + if (args.index == 0) return command_result{error::database_empty_result}; this->sendCommand(args.cmd); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientInfo(Command &cmd) { +command_result ConnectedClient::handleCommandClientInfo(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; @@ -5702,12 +5706,12 @@ CommandResult ConnectedClient::handleCommandClientInfo(Command &cmd) { } if(trigger_error || result_index == 0) - return {findError("client_invalid_id"), "invalid client id"}; + return command_result{error::client_invalid_id}; else - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientFind(Command &cmd) { +command_result ConnectedClient::handleCommandClientFind(Command &cmd) { CMD_REQ_SERVER; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -5725,13 +5729,13 @@ CommandResult ConnectedClient::handleCommandClientFind(Command &cmd) { index++; } } - if (index == 0) return {findError("database_empty_result"), ""}; + if (index == 0) return command_result{error::database_empty_result}; this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandVersion(Command &) { +command_result ConnectedClient::handleCommandVersion(Command &) { CMD_RESET_IDLE; Command res(""); @@ -5744,42 +5748,42 @@ CommandResult ConnectedClient::handleCommandVersion(Command &) { res["platform"] = "Linux"; #endif this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } //cid=%d password=%s -CommandResult ConnectedClient::handleCommandVerifyChannelPassword(Command &cmd) { +command_result ConnectedClient::handleCommandVerifyChannelPassword(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); std::shared_ptr channel = (this->server ? this->server->channelTree : serverInstance->getChannelTree().get())->findChannel(cmd["cid"].as()); - if (!channel) return {findError("channel_invalid_id"), "Cant resolve channel"}; + if (!channel) return command_result{error::channel_invalid_id, "Cant resolve channel"}; std::string password = cmd["password"]; - if (!channel->passwordMatch(password, false)) return {findError("server_invalid_password"), ""}; - return CommandResult::Success; + if (!channel->passwordMatch(password, false)) return command_result{error::server_invalid_password}; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandVerifyServerPassword(Command &cmd) { +command_result ConnectedClient::handleCommandVerifyServerPassword(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); std::string password = cmd["password"]; - if (!this->server->verifyServerPassword(password, false)) return {findError("server_invalid_password"), ""}; - return CommandResult::Success; + if (!this->server->verifyServerPassword(password, false)) return command_result{error::server_invalid_password}; + return command_result{error::ok}; } //msgid=2 cluid=IkBXingb46\/z1Q3hhMvJEweb3lw= subject=The\sSubject timestamp=1512224138 flag_read=0 //notifymessagelist msgid=2 cluid=IkBXingb46\/z1Q3hhMvJEweb3lw= subject=The\sSubject timestamp=1512224138 flag_read=0 -CommandResult ConnectedClient::handleCommandMessageList(Command &cmd) { +command_result ConnectedClient::handleCommandMessageList(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto msgList = this->server->letters->avariableLetters(this->getUid()); - if (msgList.empty()) return {findError("database_empty_result"), "no letters available"}; + if (msgList.empty()) return command_result{error::database_empty_result, "no letters available"}; Command notify(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifymessagelist" : ""); @@ -5794,21 +5798,21 @@ CommandResult ConnectedClient::handleCommandMessageList(Command &cmd) { } this->sendCommand(notify); - return CommandResult::Success; + return command_result{error::ok}; } //messageadd cluid=ePHuXhcai9nk\/4Fd\/xkxrokvnNk= subject=Test message=Message -CommandResult ConnectedClient::handleCommandMessageAdd(Command &cmd) { +command_result ConnectedClient::handleCommandMessageAdd(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); CACHED_PERM_CHECK(permission::b_client_offline_textmessage_send, 1, true); this->server->letters->createLetter(this->getUid(), cmd["cluid"], cmd["subject"], cmd["message"]); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandMessageGet(Command &cmd) { +command_result ConnectedClient::handleCommandMessageGet(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(10); @@ -5824,30 +5828,30 @@ CommandResult ConnectedClient::handleCommandMessageGet(Command &cmd) { notify["timestamp"] = duration_cast(letter->created.time_since_epoch()).count(); this->sendCommand(notify); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandMessageUpdateFlag(Command &cmd) { +command_result ConnectedClient::handleCommandMessageUpdateFlag(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); this->server->letters->updateReadFlag(cmd["msgid"], cmd["flag"]); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandMessageDel(Command &cmd) { +command_result ConnectedClient::handleCommandMessageDel(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); this->server->letters->deleteLetter(cmd["msgid"]); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPermGet(Command &cmd) { +command_result ConnectedClient::handleCommandPermGet(Command &cmd) { CMD_RESET_IDLE; CACHED_PERM_CHECK(permission::b_client_permissionoverview_own, 1, true); @@ -5862,7 +5866,7 @@ CommandResult ConnectedClient::handleCommandPermGet(Command &cmd) { permType = cmd[index]["permid"].as(); else if (cmd[index].has("permsid")) permType = permission::resolvePermissionData(cmd[index]["permsid"].as())->type; //TODO: Map the other way around! - if (permission::resolvePermissionData(permType)->type == permission::PermissionType::unknown) return {findError("parameter_invalid"), "could not resolve permission"}; + if (permission::resolvePermissionData(permType)->type == permission::PermissionType::unknown) return command_result{error::parameter_invalid, "could not resolve permission"}; requrested.push_back(permType); } @@ -5875,18 +5879,18 @@ CommandResult ConnectedClient::handleCommandPermGet(Command &cmd) { } this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPermIdGetByName(Command &cmd) { +command_result ConnectedClient::handleCommandPermIdGetByName(Command &cmd) { auto found = permission::resolvePermissionData(cmd["permsid"].as()); //TODO: Map the other way around Command res(""); res["permid"] = found->type; this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPermFind(Command &cmd) { +command_result ConnectedClient::handleCommandPermFind(Command &cmd) { struct PermissionEntry { permission::PermissionType permission_type; permission::PermissionValue permission_value; @@ -5914,13 +5918,13 @@ CommandResult ConnectedClient::handleCommandPermFind(Command &cmd) { granted = (cmd[index]["permid"].as() & PERM_ID_GRANT) > 0; if(permission->type == permission::PermissionType::unknown) - return {findError("parameter_invalid"), "could not resolve permission (id=" + cmd[index]["permid"].string() + ")"}; + return command_result{error::parameter_invalid, "could not resolve permission (id=" + cmd[index]["permid"].string() + ")"}; } else if (cmd[index].has("permsid")) { permission = permission::resolvePermissionData(cmd[index]["permsid"].as()); //TODO: Map the other way around granted = permission->grant_name == cmd[index]["permsid"].as(); if(permission->type == permission::PermissionType::unknown) - return {findError("parameter_invalid"), "could not resolve permission (id=" + cmd[index]["permid"].string() + ")"}; + return command_result{error::parameter_invalid, "could not resolve permission (id=" + cmd[index]["permid"].string() + ")"}; } else { continue; } @@ -5929,7 +5933,7 @@ CommandResult ConnectedClient::handleCommandPermFind(Command &cmd) { } if(permissions.empty()) - return {findError("database_empty_result")}; + return command_result{error::database_empty_result}; map flags; map quick_mapping; @@ -6105,9 +6109,9 @@ CommandResult ConnectedClient::handleCommandPermFind(Command &cmd) { index++; } - if(index == 0) return {findError("database_empty_result")}; + if(index == 0) return command_result{error::database_empty_result}; this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } /* @@ -6115,13 +6119,13 @@ CommandResult ConnectedClient::handleCommandPermFind(Command &cmd) { * - Alle client rechte | channel cleint rechte * - Alle rechte des channels */ -CommandResult ConnectedClient::handleCommandPermOverview(Command &cmd) { +command_result ConnectedClient::handleCommandPermOverview(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto client_dbid = cmd["cldbid"].as(); - if(!serverInstance->databaseHelper()->validClientDatabaseId(this->getServer(), client_dbid)) return {findError("client_invalid_id")}; + if(!serverInstance->databaseHelper()->validClientDatabaseId(this->getServer(), client_dbid)) return command_result{error::client_invalid_id}; if(client_dbid == this->getClientDatabaseId()) { CACHED_PERM_CHECK(permission::b_client_permissionoverview_own, 1, true); @@ -6132,7 +6136,7 @@ CommandResult ConnectedClient::handleCommandPermOverview(Command &cmd) { string channel_query, perm_query; auto channel = this->server ? this->server->channelTree->findChannel(cmd["cid"]) : serverInstance->getChannelTree()->findChannel(cmd["cid"]); - if(!channel) return {findError("channel_invalid_id")}; + if(!channel) return command_result{error::channel_invalid_id}; auto server_groups = this->server->getGroupManager()->getServerGroups(client_dbid, ClientType::CLIENT_TEAMSPEAK); auto channel_group = this->server->getGroupManager()->getChannelGroup(client_dbid, channel, true); @@ -6288,13 +6292,13 @@ CommandResult ConnectedClient::handleCommandPermOverview(Command &cmd) { } } - if (index == 0) return {findError("database_empty_result"), ""}; + if (index == 0) return command_result{error::database_empty_result}; this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelFind(Command &cmd) { +command_result ConnectedClient::handleCommandChannelFind(Command &cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(5); string pattern = cmd["pattern"]; @@ -6311,15 +6315,15 @@ CommandResult ConnectedClient::handleCommandChannelFind(Command &cmd) { index++; } } - if (index == 0) return {findError("database_empty_result"), ""}; + if (index == 0) return command_result{error::database_empty_result}; this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandChannelInfo(Command &cmd) { +command_result ConnectedClient::handleCommandChannelInfo(Command &cmd) { std::shared_ptr channel = (this->server ? this->server->channelTree : serverInstance->getChannelTree().get())->findChannel(cmd["cid"].as()); - if (!channel) return {findError("channel_invalid_id"), "Cant resolve channel"}; + if (!channel) return command_result{error::channel_invalid_id, "Cant resolve channel"}; Command res(""); @@ -6330,10 +6334,10 @@ CommandResult ConnectedClient::handleCommandChannelInfo(Command &cmd) { res["pid"] = res["cpid"].string(); this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandClientSetServerQueryLogin(Command &cmd) { +command_result ConnectedClient::handleCommandClientSetServerQueryLogin(Command &cmd) { PERM_CHECKR(permission::b_client_create_modify_serverquery_login, 1, true); if(!cmd[0].has("client_login_password")) cmd["client_login_password"] = ""; @@ -6347,7 +6351,7 @@ CommandResult ConnectedClient::handleCommandClientSetServerQueryLogin(Command &c if(old->unique_id == this->getUid()) { serverInstance->getQueryServer()->change_query_password(old, password); } else { - return {findError("client_not_logged_in")}; + return command_result{error::client_not_logged_in}; } } else { serverInstance->getQueryServer()->create_query_account(cmd["client_login_name"], this->getServerId(), this->getUid(), password); @@ -6357,10 +6361,10 @@ CommandResult ConnectedClient::handleCommandClientSetServerQueryLogin(Command &c res["client_login_password"] = password; this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandComplainAdd(Command &cmd) { +command_result ConnectedClient::handleCommandComplainAdd(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -6369,23 +6373,23 @@ CommandResult ConnectedClient::handleCommandComplainAdd(Command &cmd) { std::string msg = cmd["message"]; auto cl = this->server->findClientsByCldbId(target); - if (cl.empty()) return {findError("client_invalid_id"), "invalid client id"}; + if (cl.empty()) return command_result{error::client_invalid_id}; PERM_CHECKR(permission::i_client_complain_power, cl[0]->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_needed_complain_power), true); /* if(!serverInstance->databaseHelper()->validClientDatabaseId(target)) - return {findError("client_invalid_id"), "invalid database id"}; + return command_result{error::client_invalid_id, "invalid database id"}; */ for (const auto &elm : this->server->complains->findComplainsFromTarget(target)) if (elm->invoker == this->getClientDatabaseId()) - return {findError("database_duplicate_entry"), "you already send a complain"}; + return command_result{error::database_duplicate_entry, "you already send a complain"}; - if (!this->server->complains->createComplain(target, this->getClientDatabaseId(), msg)) return {findError("vs_critical"), "could not create complains"}; - return CommandResult::Success; + if (!this->server->complains->createComplain(target, this->getClientDatabaseId(), msg)) return command_result{error::vs_critical, "could not create complains"}; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandComplainList(Command &cmd) { +command_result ConnectedClient::handleCommandComplainList(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -6394,7 +6398,7 @@ CommandResult ConnectedClient::handleCommandComplainList(Command &cmd) { ClientDbId id = cmd[0].has("tcldbid") ? cmd["tcldbid"].as() : 0; auto list = id == 0 ? this->server->complains->complains() : this->server->complains->findComplainsFromTarget(id); - if (list.empty()) return {findError("database_empty_result"), "empty!"}; + if (list.empty()) return command_result{error::database_empty_result}; deque nameQuery; for (const auto &elm : list) { @@ -6428,10 +6432,10 @@ CommandResult ConnectedClient::handleCommandComplainList(Command &cmd) { } this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandComplainDel(Command &cmd) { +command_result ConnectedClient::handleCommandComplainDel(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); @@ -6445,7 +6449,7 @@ CommandResult ConnectedClient::handleCommandComplainDel(Command &cmd) { entry = elm; break; } - if (!entry) return {findError("database_empty_result"), "empty!"}; + if (!entry) return command_result{error::database_empty_result}; if (entry->invoker == this->getClientDatabaseId()) CACHED_PERM_CHECK(permission::b_client_complain_delete_own, 1, true); @@ -6454,23 +6458,23 @@ CommandResult ConnectedClient::handleCommandComplainDel(Command &cmd) { this->server->complains->deleteComplain(entry); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandComplainDelAll(Command &cmd) { +command_result ConnectedClient::handleCommandComplainDelAll(Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); CACHED_PERM_CHECK(permission::b_client_complain_delete, 1, true); ClientDbId tid = cmd["tcldbid"]; - if (!this->server->complains->deleteComplainsFromTarget(tid)) return {findError("database_empty_result"), "empty!"}; - return CommandResult::Success; + if (!this->server->complains->deleteComplainsFromTarget(tid)) return command_result{error::database_empty_result}; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandMusicBotCreate(Command& cmd) { - if(!config::music::enabled) return {findError("music_disabled")}; +command_result ConnectedClient::handleCommandMusicBotCreate(Command& cmd) { + if(!config::music::enabled) return command_result{error::music_disabled}; CMD_REQ_SERVER; CMD_RESET_IDLE; @@ -6478,9 +6482,9 @@ CommandResult ConnectedClient::handleCommandMusicBotCreate(Command& cmd) { if(this->server->musicManager->max_bots() != -1 && this->server->musicManager->max_bots() <= this->server->musicManager->current_bot_count()){ if(config::license->isPremium()) - return {findError("music_limit_reached"), ""}; + return command_result{error::music_limit_reached}; else - return {findError("music_limit_reached"), strobf("You reached the server music bot limit. You could increase this limit by extend your server with a premium license.").string()}; + return command_result{error::music_limit_reached, strobf("You reached the server music bot limit. You could increase this limit by extend your server with a premium license.").string()}; } @@ -6500,7 +6504,7 @@ CommandResult ConnectedClient::handleCommandMusicBotCreate(Command& cmd) { if(max_bots >= 0) { auto ownBots = this->server->musicManager->listBots(this->getClientDatabaseId()); if(ownBots.size() > max_bots) - return {findError("music_client_limit_reached"), ""}; + return command_result{error::music_client_limit_reached}; } MusicClient::Type::value create_type; @@ -6509,18 +6513,18 @@ CommandResult ConnectedClient::handleCommandMusicBotCreate(Command& cmd) { switch(create_type) { case MusicClient::Type::PERMANENT: if(permissions[permission::b_client_music_create_permanent] != 1) - return CommandResultPermissionError{permission::b_client_music_create_permanent}; + return command_result{permission::b_client_music_create_permanent}; break; case MusicClient::Type::SEMI_PERMANENT: if(permissions[permission::b_client_music_create_semi_permanent] != 1) - return CommandResultPermissionError{permission::b_client_music_create_semi_permanent}; + return command_result{permission::b_client_music_create_semi_permanent}; break; case MusicClient::Type::TEMPORARY: if(permissions[permission::b_client_music_create_temporary] != 1) - return CommandResultPermissionError{permission::b_client_music_create_temporary}; + return command_result{permission::b_client_music_create_temporary}; break; default: - return {ErrorType::VSError}; + return command_result{error::vs_critical}; } } else { if(permissions[permission::b_client_music_create_permanent] == 1) @@ -6530,13 +6534,13 @@ CommandResult ConnectedClient::handleCommandMusicBotCreate(Command& cmd) { else if(permissions[permission::b_client_music_create_temporary] == 1) create_type = MusicClient::Type::TEMPORARY; else - return CommandResultPermissionError{permission::b_client_music_create_temporary}; + return command_result{permission::b_client_music_create_temporary}; } shared_lock server_channel_lock(this->server->channel_tree_lock); auto channel = cmd[0].has("cid") ? this->server->channelTree->findChannel(cmd["cid"]) : this->currentChannel; if(!channel) { - if(cmd[0].has("cid")) return {findError("channel_invalid_id")}; + if(cmd[0].has("cid")) return command_result{error::channel_invalid_id}; } else { CHANNEL_PERMISSION_TEST(permission::i_channel_description_view_power, permission::i_channel_needed_description_view_power, channel, false); auto permission_granted = this->calculate_permission_value(permission::i_channel_join_power, channel->channelId()); @@ -6548,7 +6552,7 @@ CommandResult ConnectedClient::handleCommandMusicBotCreate(Command& cmd) { } auto bot = this->server->musicManager->createBot(this->getClientDatabaseId()); - if(!bot) return {ErrorType::VSError, ""}; + if(!bot) return command_result{error::vs_critical}; bot->set_bot_type(create_type); { if(permissions[permission::i_client_music_create_modify_max_volume] > 0) { @@ -6583,33 +6587,33 @@ CommandResult ConnectedClient::handleCommandMusicBotCreate(Command& cmd) { notify["bot_id"] = bot->getClientDatabaseId(); this->sendCommand(notify); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandMusicBotDelete(Command& cmd) { - if(!config::music::enabled) return {findError("music_disabled")}; +command_result ConnectedClient::handleCommandMusicBotDelete(Command& cmd) { + if(!config::music::enabled) return command_result{error::music_disabled}; CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); auto bot = this->server->musicManager->findBotById(cmd["bot_id"]); - if(!bot) return {findError("music_invalid_id")}; + if(!bot) return command_result{error::music_invalid_id}; bool permPower = this->permissionGranted(permission::PERMTEST_ORDERED, permission::i_client_music_delete_power, bot->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_delete_power)); if(bot->getOwner() != this->getClientDatabaseId()) { - if(!permPower) return CommandResultPermissionError{permission::i_client_music_delete_power}; + if(!permPower) return command_result{permission::i_client_music_delete_power}; } this->server->musicManager->deleteBot(bot); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandMusicBotSetSubscription(ts::Command &cmd) { - if(!config::music::enabled) return {findError("music_disabled")}; +command_result ConnectedClient::handleCommandMusicBotSetSubscription(ts::Command &cmd) { + if(!config::music::enabled) return command_result{error::music_disabled}; auto bot = this->server->musicManager->findBotById(cmd["bot_id"]); - if(!bot && cmd["bot_id"].as() != 0) return {findError("music_invalid_id")}; + if(!bot && cmd["bot_id"].as() != 0) return command_result{error::music_invalid_id}; { auto old_bot = this->subscribed_bot.lock(); @@ -6622,7 +6626,7 @@ CommandResult ConnectedClient::handleCommandMusicBotSetSubscription(ts::Command this->subscribed_bot = bot; } - return CommandResult::Success; + return command_result{error::ok}; } void apply_song(Command& command, const std::shared_ptr& element, int index = 0) { @@ -6647,15 +6651,15 @@ void apply_song(Command& command, const std::shared_ptr& el } } -CommandResult ConnectedClient::handleCommandMusicBotPlayerInfo(Command& cmd) { - if(!config::music::enabled) return {findError("music_disabled")}; +command_result ConnectedClient::handleCommandMusicBotPlayerInfo(Command& cmd) { + if(!config::music::enabled) return command_result{error::music_disabled}; CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto bot = this->server->musicManager->findBotById(cmd["bot_id"]); - if(!bot) return {findError("music_invalid_id")}; + if(!bot) return command_result{error::music_invalid_id}; Command result(this->getExternalType() == CLIENT_TEAMSPEAK ? "notifymusicplayerinfo" : ""); result["bot_id"] = bot->getClientDatabaseId(); @@ -6681,18 +6685,18 @@ CommandResult ConnectedClient::handleCommandMusicBotPlayerInfo(Command& cmd) { apply_song(result, bot->current_song()); this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandMusicBotPlayerAction(Command& cmd) { - if(!config::music::enabled) return {findError("music_disabled")}; +command_result ConnectedClient::handleCommandMusicBotPlayerAction(Command& cmd) { + if(!config::music::enabled) return command_result{error::music_disabled}; CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); auto bot = this->server->musicManager->findBotById(cmd["bot_id"]); - if(!bot) return {findError("music_invalid_id")}; + if(!bot) return command_result{error::music_invalid_id}; PERM_CHECK_CHANNELR(permission::i_client_music_play_power, bot->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_play_power, bot->currentChannel), this->currentChannel, true); if(cmd["action"] == 0) { @@ -6706,17 +6710,17 @@ CommandResult ConnectedClient::handleCommandMusicBotPlayerAction(Command& cmd) { } else if(cmd["action"] == 4) { bot->rewindSong(); } else if(cmd["action"] == 5) { - if(!bot->current_player()) return {findError("music_no_player")}; + if(!bot->current_player()) return command_result{error::music_no_player}; bot->current_player()->forward(::music::PlayerUnits(cmd["units"].as())); } else if(cmd["action"] == 6) { - if(!bot->current_player()) return {findError("music_no_player")}; + if(!bot->current_player()) return command_result{error::music_no_player}; bot->current_player()->rewind(::music::PlayerUnits(cmd["units"].as())); - } else return {findError("music_invalid_action")}; + } else return command_result{error::music_invalid_action}; - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPlaylistList(ts::Command &cmd) { +command_result ConnectedClient::handleCommandPlaylistList(ts::Command &cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -6734,7 +6738,7 @@ CommandResult ConnectedClient::handleCommandPlaylistList(ts::Command &cmd) { }), playlists.end()); if(playlists.empty()) - return {ErrorType::DBEmpty}; + return command_result{error::database_empty_result}; Command notify(this->notify_response_command("notifyplaylistlist")); @@ -6757,10 +6761,10 @@ CommandResult ConnectedClient::handleCommandPlaylistList(ts::Command &cmd) { } this->sendCommand(notify); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPlaylistCreate(ts::Command &cmd) { +command_result ConnectedClient::handleCommandPlaylistCreate(ts::Command &cmd) { CMD_REF_SERVER(ref_server); CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -6771,12 +6775,12 @@ CommandResult ConnectedClient::handleCommandPlaylistCreate(ts::Command &cmd) { if(max_playlists != permNotGranted) { auto playlists = ref_server->musicManager->find_playlists_by_client(this->getClientDatabaseId()); if(!this->permission_granted(this->cached_permission_value(permission::i_max_playlists), playlists.size(), false)) - return CommandResultPermissionError{permission::i_max_playlists}; + return command_result{permission::i_max_playlists}; } } auto playlist = ref_server->musicManager->create_playlist(this->getClientDatabaseId(), this->getDisplayName()); - if(!playlist) return {ErrorType::VSError}; + if(!playlist) return command_result{error::vs_critical}; playlist->properties()[property::PLAYLIST_TYPE] = music::Playlist::Type::GENERAL; @@ -6795,16 +6799,16 @@ CommandResult ConnectedClient::handleCommandPlaylistCreate(ts::Command &cmd) { notify["playlist_id"] = playlist->playlist_id(); this->sendCommand(notify); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPlaylistDelete(ts::Command &cmd) { +command_result ConnectedClient::handleCommandPlaylistDelete(ts::Command &cmd) { CMD_REF_SERVER(ref_server); CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); auto playlist = ref_server->musicManager->find_playlist(cmd["playlist_id"]); - if(!playlist) return {findError("playlist_invalid_id")}; + if(!playlist) return command_result{error::playlist_invalid_id}; if(playlist->properties()[property::PLAYLIST_OWNER_DBID] != this->getClientDatabaseId()) CACHED_PERM_CHECK(permission::i_playlist_delete_power, playlist->permissions()->getPermissionValue(permission::i_playlist_needed_delete_power)); @@ -6812,19 +6816,19 @@ CommandResult ConnectedClient::handleCommandPlaylistDelete(ts::Command &cmd) { string error; if(!ref_server->musicManager->delete_playlist(playlist->playlist_id(), error)) { logError(this->getServerId(), "Failed to delete playlist with id {}. Error: {}", playlist->playlist_id(), error); - return {ErrorType::VSError, error}; + return command_result{error::vs_critical}; } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPlaylistInfo(ts::Command &cmd) { +command_result ConnectedClient::handleCommandPlaylistInfo(ts::Command &cmd) { CMD_REF_SERVER(ref_server); CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); auto playlist = ref_server->musicManager->find_playlist(cmd["playlist_id"]); - if(!playlist) return {findError("playlist_invalid_id")}; + if(!playlist) return command_result{error::playlist_invalid_id}; if(playlist->properties()[property::PLAYLIST_OWNER_DBID] != this->getClientDatabaseId()) CACHED_PERM_CHECK(permission::i_playlist_view_power, playlist->permissions()->getPermissionValue(permission::i_playlist_needed_view_power)); @@ -6836,16 +6840,16 @@ CommandResult ConnectedClient::handleCommandPlaylistInfo(ts::Command &cmd) { } this->sendCommand(notify); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPlaylistEdit(ts::Command &cmd) { +command_result ConnectedClient::handleCommandPlaylistEdit(ts::Command &cmd) { CMD_REF_SERVER(ref_server); CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); auto playlist = ref_server->musicManager->find_playlist(cmd["playlist_id"]); - if(!playlist) return {findError("playlist_invalid_id")}; + if(!playlist) return command_result{error::playlist_invalid_id}; if(playlist->properties()[property::PLAYLIST_OWNER_DBID] != this->getClientDatabaseId()) CACHED_PERM_CHECK(permission::i_playlist_modify_power, playlist->permissions()->getPermissionValue(permission::i_playlist_needed_modify_power)); @@ -6876,12 +6880,12 @@ CommandResult ConnectedClient::handleCommandPlaylistEdit(ts::Command &cmd) { auto song_id = cmd[key].as(); auto song = song_id > 0 ? playlist->find_song(song_id) : nullptr; if(song_id != 0 && !song) - return {findError("playlist_invalid_song_id")}; + return command_result{error::playlist_invalid_song_id}; } else if(*property == property::PLAYLIST_MAX_SONGS) { auto value = cmd[key].as(); auto max_value = this->cached_permission_value(permission::i_max_playlist_size); if(!this->permission_granted(max_value, value, false)) - return CommandResultPermissionError{permission::i_max_playlist_size}; + return command_result{permission::i_max_playlist_size}; } properties.emplace_back(property, key); @@ -6894,23 +6898,23 @@ CommandResult ConnectedClient::handleCommandPlaylistEdit(ts::Command &cmd) { playlist->properties()[property.first] = cmd[property.second].string(); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPlaylistPermList(ts::Command &cmd) { +command_result ConnectedClient::handleCommandPlaylistPermList(ts::Command &cmd) { CMD_REF_SERVER(ref_server); CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); auto playlist = ref_server->musicManager->find_playlist(cmd["playlist_id"]); - if(!playlist) return {findError("playlist_invalid_id")}; + if(!playlist) return command_result{error::playlist_invalid_id}; if(playlist->properties()[property::PLAYLIST_OWNER_DBID] != this->getClientDatabaseId()) CACHED_PERM_CHECK(permission::b_virtualserver_playlist_permission_list, 1, true); auto permissions = playlist->permissions()->listPermissions(PERM_FLAG_PUBLIC); if(permissions.empty()) - return {ErrorType::VSError}; + return command_result{error::vs_critical}; Command result(this->notify_response_command("notifyplaylistpermlist")); int index = 0; @@ -6934,16 +6938,16 @@ CommandResult ConnectedClient::handleCommandPlaylistPermList(ts::Command &cmd) { } this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPlaylistAddPerm(ts::Command &cmd) { +command_result ConnectedClient::handleCommandPlaylistAddPerm(ts::Command &cmd) { CMD_REF_SERVER(ref_server); CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto playlist = ref_server->musicManager->find_playlist(cmd["playlist_id"]); - if(!playlist) return {findError("playlist_invalid_id")}; + if(!playlist) return command_result{error::playlist_invalid_id}; if(playlist->properties()[property::PLAYLIST_OWNER_DBID] != this->getClientDatabaseId()) CACHED_PERM_CHECK(permission::i_playlist_permission_modify_power, playlist->permissions()->getPermissionValue(permission::i_playlist_needed_permission_modify_power), true); @@ -6957,10 +6961,10 @@ CommandResult ConnectedClient::handleCommandPlaylistAddPerm(ts::Command &cmd) { auto val = cmd[index]["permvalue"].as(); if(permission_require_granted_value(permType) && val > maxValue) - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; if(!ignoreGrant && !this->permissionGrantGranted(permission::PERMTEST_ORDERED, permType, 1, this->currentChannel)) - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; if (grant) { playlist->permissions()->setPermissionGranted(permType, cmd[index]["permvalue"], nullptr); @@ -6970,16 +6974,16 @@ CommandResult ConnectedClient::handleCommandPlaylistAddPerm(ts::Command &cmd) { } } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPlaylistDelPerm(ts::Command &cmd) { +command_result ConnectedClient::handleCommandPlaylistDelPerm(ts::Command &cmd) { CMD_REF_SERVER(ref_server); CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); auto playlist = ref_server->musicManager->find_playlist(cmd["playlist_id"]); - if(!playlist) return {findError("playlist_invalid_id")}; + if(!playlist) return command_result{error::playlist_invalid_id}; if(playlist->properties()[property::PLAYLIST_OWNER_DBID] != this->getClientDatabaseId()) CACHED_PERM_CHECK(permission::i_playlist_permission_modify_power, playlist->permissions()->getPermissionValue(permission::i_playlist_needed_permission_modify_power), true); @@ -6991,7 +6995,7 @@ CommandResult ConnectedClient::handleCommandPlaylistDelPerm(ts::Command &cmd) { PARSE_PERMISSION(cmd); if(!ignoreGrant && !this->permissionGrantGranted(permission::PERMTEST_ORDERED, permType, 1, this->currentChannel)) - return CommandResultPermissionError{permission::i_permission_modify_power}; + return command_result{permission::i_permission_modify_power}; if (grant) { playlist->permissions()->setPermissionGranted(permType, permNotGranted, nullptr); @@ -7000,23 +7004,23 @@ CommandResult ConnectedClient::handleCommandPlaylistDelPerm(ts::Command &cmd) { } } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPlaylistSongList(ts::Command &cmd) { +command_result ConnectedClient::handleCommandPlaylistSongList(ts::Command &cmd) { CMD_REF_SERVER(ref_server); CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); auto playlist = ref_server->musicManager->find_playlist(cmd["playlist_id"]); - if(!playlist) return {findError("playlist_invalid_id")}; + if(!playlist) return command_result{error::playlist_invalid_id}; if(playlist->properties()[property::PLAYLIST_OWNER_DBID] != this->getClientDatabaseId()) CACHED_PERM_CHECK(permission::i_playlist_view_power, playlist->permissions()->getPermissionValue(permission::i_playlist_needed_view_power)); auto songs = playlist->list_songs(); if(songs.empty()) - return {ErrorType::DBEmpty}; + return command_result{error::database_empty_result}; Command notify(this->notify_response_command("notifyplaylistsonglist")); notify["playlist_id"] = playlist->playlist_id(); @@ -7034,16 +7038,16 @@ CommandResult ConnectedClient::handleCommandPlaylistSongList(ts::Command &cmd) { } this->sendCommand(notify); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPlaylistSongAdd(ts::Command &cmd) { +command_result ConnectedClient::handleCommandPlaylistSongAdd(ts::Command &cmd) { CMD_REF_SERVER(ref_server); CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); auto playlist = ref_server->musicManager->find_playlist(cmd["playlist_id"]); - if(!playlist) return {findError("playlist_invalid_id")}; + if(!playlist) return command_result{error::playlist_invalid_id}; if(playlist->properties()[property::PLAYLIST_OWNER_DBID] != this->getClientDatabaseId()) CACHED_PERM_CHECK(permission::i_playlist_song_add_power, playlist->permissions()->getPermissionValue(permission::i_playlist_song_needed_add_power)); @@ -7060,22 +7064,22 @@ CommandResult ConnectedClient::handleCommandPlaylistSongAdd(ts::Command &cmd) { auto song = playlist->add_song(_this.lock(), cmd["url"], cmd["invoker"], cmd["previous"]); - if(!song) return {ErrorType::VSError}; + if(!song) return command_result{error::vs_critical}; Command notify(this->notify_response_command("notifyplaylistsongadd")); notify["song_id"] = song->id; this->sendCommand(notify); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPlaylistSongReorder(ts::Command &cmd) { +command_result ConnectedClient::handleCommandPlaylistSongReorder(ts::Command &cmd) { CMD_REF_SERVER(ref_server); CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); auto playlist = ref_server->musicManager->find_playlist(cmd["playlist_id"]); - if(!playlist) return {findError("playlist_invalid_id")}; + if(!playlist) return command_result{error::playlist_invalid_id}; if(playlist->properties()[property::PLAYLIST_OWNER_DBID] != this->getClientDatabaseId()) CACHED_PERM_CHECK(permission::i_playlist_song_move_power, playlist->permissions()->getPermissionValue(permission::i_playlist_song_needed_move_power)); @@ -7084,21 +7088,21 @@ CommandResult ConnectedClient::handleCommandPlaylistSongReorder(ts::Command &cmd SongId previous_id = cmd["song_previous_song_id"]; auto song = playlist->find_song(song_id); - if(!song) return {findError("playlist_invalid_song_id")}; + if(!song) return command_result{error::playlist_invalid_song_id}; if(!playlist->reorder_song(song_id, previous_id)) - return {ErrorType::VSError}; + return command_result{error::vs_critical}; - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPlaylistSongRemove(ts::Command &cmd) { +command_result ConnectedClient::handleCommandPlaylistSongRemove(ts::Command &cmd) { CMD_REF_SERVER(ref_server); CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); auto playlist = ref_server->musicManager->find_playlist(cmd["playlist_id"]); - if(!playlist) return {findError("playlist_invalid_id")}; + if(!playlist) return command_result{error::playlist_invalid_id}; if(playlist->properties()[property::PLAYLIST_OWNER_DBID] != this->getClientDatabaseId()) CACHED_PERM_CHECK(permission::i_playlist_song_remove_power, playlist->permissions()->getPermissionValue(permission::i_playlist_song_needed_remove_power)); @@ -7106,12 +7110,12 @@ CommandResult ConnectedClient::handleCommandPlaylistSongRemove(ts::Command &cmd) SongId song_id = cmd["song_id"]; auto song = playlist->find_song(song_id); - if(!song) return {findError("playlist_invalid_song_id")}; + if(!song) return command_result{error::playlist_invalid_song_id}; if(!playlist->delete_song(song_id)) - return {ErrorType::VSError}; + return command_result{error::vs_critical}; - return CommandResult::Success; + return command_result{error::ok}; } command_result ConnectedClient::handleCommandMusicBotQueueList(Command& cmd) { @@ -7123,7 +7127,7 @@ command_result ConnectedClient::handleCommandMusicBotQueueList(Command& cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(25); auto bot = this->server->musicManager->findBotById(cmd["bot_id"]); - if(!bot) return {findError("music_invalid_id")}; + if(!bot) return command_result{error::music_invalid_id}; PERM_CHECK_CHANNELR(permission::i_client_music_info, bot->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_info, bot->currentChannel), this->currentChannel, true); @@ -7191,7 +7195,7 @@ command_result ConnectedClient::handleCommandMusicBotQueueList(Command& cmd) { this->sendCommand(notify); } - return CommandResult::Success; + return command_result{error::ok}; */ } @@ -7204,7 +7208,7 @@ command_result ConnectedClient::handleCommandMusicBotQueueAdd(Command& cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(25); auto bot = this->server->musicManager->findBotById(cmd["bot_id"]); - if(!bot) return {findError("music_invalid_id")}; + if(!bot) return command_result{error::music_invalid_id}; PERM_CHECK_CHANNELR(permission::i_client_music_play_power, bot->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_play_power, bot->currentChannel), this->currentChannel, true); MusicClient::loader_t loader; @@ -7218,16 +7222,16 @@ command_result ConnectedClient::handleCommandMusicBotQueueAdd(Command& cmd) { } else if((type.castable() && type.as() == -1) || type.as() == "any") { loader = bot->providerLoader(this->getServer(), ""); } - if(!loader) return {findError("music_invalid_action")}; + if(!loader) return command_result{error::music_invalid_action}; auto entry = bot->queue()->insertEntry(cmd["url"], _this.lock(), loader); - if(!entry) return {ErrorType::VSError}; + if(!entry) return command_result{error::vs_critical}; this->server->forEachClient([&](shared_ptr client) { client->notifyMusicQueueAdd(bot, entry, bot->queue()->queueEntries().size() - 1, _this.lock()); }); - return CommandResult::Success; + return command_result{error::ok}; */ } @@ -7240,7 +7244,7 @@ command_result ConnectedClient::handleCommandMusicBotQueueRemove(Command& cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(25); auto bot = this->server->musicManager->findBotById(cmd["bot_id"]); - if(!bot) return {findError("music_invalid_id")}; + if(!bot) return command_result{error::music_invalid_id}; PERM_CHECK_CHANNELR(permission::i_client_music_play_power, bot->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_play_power, bot->currentChannel), this->currentChannel, true); std::deque> songs; @@ -7248,7 +7252,7 @@ command_result ConnectedClient::handleCommandMusicBotQueueRemove(Command& cmd) { auto entry = bot->queue()->find_queue(cmd["song_id"]); if(!entry) { if(cmd.hasParm("skip_error")) continue; - return {ErrorType::DBEmpty}; + return command_result{error::database_empty_result}; } songs.push_back(move(entry)); @@ -7259,7 +7263,7 @@ command_result ConnectedClient::handleCommandMusicBotQueueRemove(Command& cmd) { this->server->forEachClient([&](shared_ptr client) { client->notifyMusicQueueRemove(bot, songs, _this.lock()); }); - return CommandResult::Success; + return command_result{error::ok}; */ } @@ -7272,47 +7276,47 @@ command_result ConnectedClient::handleCommandMusicBotQueueReorder(Command& cmd) CMD_CHK_AND_INC_FLOOD_POINTS(25); auto bot = this->server->musicManager->findBotById(cmd["bot_id"]); - if(!bot) return {findError("music_invalid_id")}; + if(!bot) return command_result{error::music_invalid_id}; PERM_CHECK_CHANNELR(permission::i_client_music_play_power, bot->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_play_power, bot->currentChannel), this->currentChannel, true); auto entry = bot->queue()->find_queue(cmd["song_id"]); - if(!entry) return {ErrorType::DBEmpty}; + if(!entry) return command_result{error::database_empty_result}; auto order = bot->queue()->changeOrder(entry, cmd["index"]); - if(order < 0) return {ErrorType::VSError}; + if(order < 0) return command_result{error::vs_critical}; this->server->forEachClient([&](shared_ptr client) { client->notifyMusicQueueOrderChange(bot, entry, order, _this.lock()); }); - return CommandResult::Success; + return command_result{error::ok}; */ } -CommandResult ConnectedClient::handleCommandMusicBotPlaylistAssign(ts::Command &cmd) { +command_result ConnectedClient::handleCommandMusicBotPlaylistAssign(ts::Command &cmd) { CMD_REF_SERVER(ref_server); CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(25); auto bot = ref_server->musicManager->findBotById(cmd["bot_id"]); - if(!bot) return {findError("music_invalid_id")}; + if(!bot) return command_result{error::music_invalid_id}; if(bot->getOwner() != this->getClientDatabaseId()) PERM_CHECK_CHANNELR(permission::i_client_music_play_power, bot->permissionValue(permission::PERMTEST_ORDERED, permission::i_client_music_needed_play_power, bot->currentChannel), this->currentChannel, true); auto playlist = ref_server->musicManager->find_playlist(cmd["playlist_id"]); - if(!playlist && cmd["playlist_id"] != 0) return {findError("playlist_invalid_id")}; + if(!playlist && cmd["playlist_id"] != 0) return command_result{error::playlist_invalid_id}; if(ref_server->musicManager->find_bot_by_playlist(playlist)) - return {findError("playlist_already_in_use")}; + return command_result{error::playlist_already_in_use}; if(playlist && playlist->properties()[property::PLAYLIST_OWNER_DBID] != this->getClientDatabaseId()) CACHED_PERM_CHECK(permission::i_playlist_view_power, playlist->permissions()->getPermissionValue(permission::i_playlist_needed_view_power)); if(!ref_server->musicManager->assign_playlist(bot, playlist)) - return {ErrorType::VSError}; + return command_result{error::vs_critical}; - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandHelp(Command& cmd) { +command_result ConnectedClient::handleCommandHelp(Command& cmd) { CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(5); PERM_CHECKR(permission::b_serverinstance_help_view, 1, false); @@ -7328,18 +7332,18 @@ CommandResult ConnectedClient::handleCommandHelp(Command& cmd) { std::transform(command.begin(), command.end(), command.begin(), ::tolower); auto file = fs::u8path("commanddocs/" + command + ".txt"); - if(!fs::exists(file)) return {findError("file_not_found"), "Could not resolve file " + file.string()}; + if(!fs::exists(file)) return command_result{error::file_not_found}; string line; ifstream stream(file); - if(!stream) return {findError("file_io_error"), "Could not read documentation file " + file.string()}; + if(!stream) return command_result{error::file_io_error}; while(getline(stream, line)) this->sendCommand(Command{line}); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandPermReset(ts::Command& cmd) { +command_result ConnectedClient::handleCommandPermReset(ts::Command& cmd) { CMD_REQ_FSERVER; CMD_RESET_IDLE; CMD_CHK_AND_INC_FLOOD_POINTS(50); @@ -7347,16 +7351,16 @@ CommandResult ConnectedClient::handleCommandPermReset(ts::Command& cmd) { string token; if(!this->server->resetPermissions(token)) - return {ErrorType::VSError, "Could not reset permissions!"}; + return command_result{error::vs_critical}; Command result(""); result["token"] = token; this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandLogView(ts::Command& cmd) { +command_result ConnectedClient::handleCommandLogView(ts::Command& cmd) { CMD_CHK_AND_INC_FLOOD_POINTS(50); auto lagacy = this->getType() == CLIENT_TEAMSPEAK || cmd.hasParm("lagacy") || cmd.hasParm("legacy"); @@ -7382,7 +7386,7 @@ CommandResult ConnectedClient::handleCommandLogView(ts::Command& cmd) { } } if(log_path.empty()) - return {findError("file_not_found"), "Cant find log file (May log disabled?)"}; + return command_result{error::file_not_found, "Cant find log file (May log disabled?)"}; { //Replace " within the log path size_t index = 0; @@ -7406,7 +7410,7 @@ CommandResult ConnectedClient::handleCommandLogView(ts::Command& cmd) { string line_buffer; std::shared_ptr pipe(popen(command.c_str(), "r"), pclose); - if (!pipe) return {findError("file_io_error"), "Could not execute command"}; + if (!pipe) return command_result{error::file_io_error, "Could not execute command"}; while (!feof(pipe.get())) { auto read = fread(buffer.data(), 1, buffer.size(), pipe.get()); if(read > 0) { @@ -7451,7 +7455,7 @@ CommandResult ConnectedClient::handleCommandLogView(ts::Command& cmd) { } } file_index += read; - } else if(read < 0) return {findError("file_io_error"), "fread(...) returned " + to_string(read) + " (" + to_string(errno) + ")"}; + } else if(read < 0) return command_result{error::file_io_error, "fread(...) returned " + to_string(read) + " (" + to_string(errno) + ")"}; } if(!line_buffer.empty()) { @@ -7460,7 +7464,7 @@ CommandResult ConnectedClient::handleCommandLogView(ts::Command& cmd) { } } //last_pos=1558 file_size=1764 l - if(lines.empty()) return {ErrorType::DBEmpty}; + if(lines.empty()) return command_result{error::database_empty_result}; Command result(this->getExternalType() == ClientType::CLIENT_TEAMSPEAK ? "notifyserverlog" : ""); result["last_pos"] = lines.front().first; result["file_size"] = file_index; @@ -7498,21 +7502,21 @@ CommandResult ConnectedClient::handleCommandLogView(ts::Command& cmd) { } this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandUpdateMyTsId(ts::Command &) { - if(config::voice::suppress_myts_warnings) return CommandResult::Success; - return CommandResult::NotImplemented; +command_result ConnectedClient::handleCommandUpdateMyTsId(ts::Command &) { + if(config::voice::suppress_myts_warnings) return command_result{error::ok}; + return command_result{error::not_implemented}; } -CommandResult ConnectedClient::handleCommandUpdateMyTsData(ts::Command &) { - if(config::voice::suppress_myts_warnings) return CommandResult::Success; - return CommandResult::NotImplemented; +command_result ConnectedClient::handleCommandUpdateMyTsData(ts::Command &) { + if(config::voice::suppress_myts_warnings) return command_result{error::ok}; + return command_result{error::not_implemented}; } -CommandResult ConnectedClient::handleCommandQueryList(ts::Command &cmd) { +command_result ConnectedClient::handleCommandQueryList(ts::Command &cmd) { OptionalServerId server_id = EmptyServerId; if(this->getExternalType() == ClientType::CLIENT_TEAMSPEAK) server_id = this->getServerId(); @@ -7524,13 +7528,13 @@ CommandResult ConnectedClient::handleCommandQueryList(ts::Command &cmd) { auto server = server_id == EmptyServerId ? nullptr : serverInstance->getVoiceServerManager()->findServerById(server_id); if(!server && server_id != EmptyServerId && server_id != 0) - return {findError("server_invalid_id")}; + return command_result{error::server_invalid_id}; auto global_list = this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_query_list, 1, nullptr, true, nullptr, server, true); auto own_list = global_list || this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_query_list_own, 1, nullptr, true, nullptr, server, true); if(!own_list && !global_list) - return CommandResultPermissionError{permission::b_client_query_list}; + return command_result{permission::b_client_query_list}; auto accounts = serverInstance->getQueryServer()->list_query_accounts(server_id); if(!global_list) { @@ -7540,7 +7544,7 @@ CommandResult ConnectedClient::handleCommandQueryList(ts::Command &cmd) { } if(accounts.empty()) - return {ErrorType::DBEmpty}; + return command_result{error::database_empty_result}; Command result(this->getExternalType() == ClientType::CLIENT_TEAMSPEAK ? "notifyquerylist" : ""); result["server_id"] = server_id; @@ -7557,10 +7561,10 @@ CommandResult ConnectedClient::handleCommandQueryList(ts::Command &cmd) { this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandQueryCreate(ts::Command &cmd) { +command_result ConnectedClient::handleCommandQueryCreate(ts::Command &cmd) { OptionalServerId server_id = this->getServerId(); if(cmd[0].has("server_id")) server_id = cmd["server_id"]; @@ -7569,10 +7573,10 @@ CommandResult ConnectedClient::handleCommandQueryCreate(ts::Command &cmd) { auto server = server_id == EmptyServerId ? nullptr : serverInstance->getVoiceServerManager()->findServerById(server_id); if(!server && server_id != EmptyServerId && server_id != 0) - return {findError("server_invalid_id")}; + return command_result{error::server_invalid_id}; if(!this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_query_create, 1, nullptr, true, nullptr, server, true)) - return CommandResultPermissionError{permission::b_client_query_create}; + return command_result{permission::b_client_query_create}; auto username = cmd["client_login_name"].as(); auto password = cmd[0].has("client_login_password") ? cmd["client_login_password"].as() : ""; @@ -7581,11 +7585,11 @@ CommandResult ConnectedClient::handleCommandQueryCreate(ts::Command &cmd) { password = rnd_string(QUERY_PASSWORD_LENGTH); auto account = serverInstance->getQueryServer()->find_query_account_by_name(username); - if(account) return {findError("query_already_exists")}; + if(account) return command_result{error::query_already_exists}; account = serverInstance->getQueryServer()->create_query_account(username, server_id, this->getUid(), password); if(!account) - return {ErrorType::VSError}; + return command_result{error::vs_critical}; Command result(this->getExternalType() == ClientType::CLIENT_TEAMSPEAK ? "notifyquerycreated" : ""); result["client_unique_identifier"] = account->unique_id; @@ -7594,19 +7598,19 @@ CommandResult ConnectedClient::handleCommandQueryCreate(ts::Command &cmd) { result["client_bound_server"] = account->bound_server; this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandQueryDelete(ts::Command &cmd) { +command_result ConnectedClient::handleCommandQueryDelete(ts::Command &cmd) { auto username = cmd["client_login_name"].as(); auto account = serverInstance->getQueryServer()->find_query_account_by_name(username); if(!account) - return {findError("query_not_exists")}; + return command_result{error::query_not_exists}; auto server = serverInstance->getVoiceServerManager()->findServerById(account->bound_server); /* If the server is not existing anymore, we're asking for global permissions if(!server && account->bounded_server != 0) - return {findError("server_invalid_id")}; + return command_result{error::server_invalid_id}; */ auto delete_all = this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_query_delete, 1, nullptr, true, nullptr, server, true); @@ -7614,63 +7618,63 @@ CommandResult ConnectedClient::handleCommandQueryDelete(ts::Command &cmd) { if(account->unique_id == this->getUid()) { if(!delete_own) - return CommandResultPermissionError{permission::b_client_query_delete_own}; + return command_result{permission::b_client_query_delete_own}; } else { if(!delete_all) - return CommandResultPermissionError{permission::b_client_query_delete}; + return command_result{permission::b_client_query_delete}; } if(account->unique_id == "serveradmin" && account->username == "serveradmin") - return ErrorType::VSError; + return command_result{error::vs_critical}; serverInstance->getQueryServer()->delete_query_account(account); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandQueryRename(ts::Command &cmd) { +command_result ConnectedClient::handleCommandQueryRename(ts::Command &cmd) { auto username = cmd["client_login_name"].as(); auto new_username = cmd["client_new_login_name"].as(); auto account = serverInstance->getQueryServer()->find_query_account_by_name(username); if(!account) - return {findError("query_not_exists")}; + return command_result{error::query_not_exists}; auto server = serverInstance->getVoiceServerManager()->findServerById(account->bound_server); if(!server && account->bound_server != 0) - return {findError("server_invalid_id")}; + return command_result{error::server_invalid_id}; auto rename_all = this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_query_rename, 1, nullptr, true, nullptr, server, true); auto rename_own = rename_all || this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_query_rename_own, 1, nullptr, true, nullptr, server, true); if(account->unique_id == this->getUid()) { if(!rename_own) - return CommandResultPermissionError{permission::b_client_query_rename_own}; + return command_result{permission::b_client_query_rename_own}; } else { if(!rename_all) - return CommandResultPermissionError{permission::b_client_query_rename}; + return command_result{permission::b_client_query_rename}; } auto target_account = serverInstance->getQueryServer()->find_query_account_by_name(new_username); - if(target_account) return {findError("query_already_exists")}; + if(target_account) return command_result{error::query_already_exists}; if(account->unique_id == "serveradmin" && account->username == "serveradmin") - return ErrorType::VSError; + return command_result{error::parameter_invalid}; if(!serverInstance->getQueryServer()->rename_query_account(account, new_username)) - return {ErrorType::VSError}; + return command_result{error::vs_critical}; - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandQueryChangePassword(ts::Command &cmd) { +command_result ConnectedClient::handleCommandQueryChangePassword(ts::Command &cmd) { auto username = cmd["client_login_name"].as(); auto account = serverInstance->getQueryServer()->find_query_account_by_name(username); if(!account) - return {findError("query_not_exists")}; + return command_result{error::query_not_exists}; auto server = serverInstance->getVoiceServerManager()->findServerById(account->bound_server); if(!server && account->bound_server != 0) - return {findError("server_invalid_id")}; + return command_result{error::server_invalid_id}; auto change_all = this->permissionGranted(permission::PERMTEST_ORDERED, server ? permission::b_client_query_change_password : permission::b_client_query_change_password_global, 1, nullptr, true, nullptr, server, true); auto change_own = change_all || this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_client_query_change_own_password, 1, nullptr, true, nullptr, server, true); @@ -7682,24 +7686,24 @@ CommandResult ConnectedClient::handleCommandQueryChangePassword(ts::Command &cmd if(account->unique_id == this->getUid()) { if(!change_own) - return CommandResultPermissionError{permission::b_client_query_change_own_password}; + return command_result{permission::b_client_query_change_own_password}; } else { if(!change_all) - return CommandResultPermissionError{server ? permission::b_client_query_change_password : permission::b_client_query_change_password_global}; + return command_result{server ? permission::b_client_query_change_password : permission::b_client_query_change_password_global}; } if(!serverInstance->getQueryServer()->change_query_password(account, password)) - return {ErrorType::VSError}; + return command_result{error::vs_critical}; Command result(this->getExternalType() == ClientType::CLIENT_TEAMSPEAK ? "notifyquerypasswordchanges" : ""); result["client_login_name"] = account->username; result["client_login_password"] = password; this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandDummy_IpChange(ts::Command &cmd) { +command_result ConnectedClient::handleCommandDummy_IpChange(ts::Command &cmd) { CMD_REF_SERVER(server); logMessage(this->getServerId(), "[{}] Address changed from {} to {}", CLIENT_STR_LOG_PREFIX, cmd["old_ip"].string(), cmd["new_ip"].string()); @@ -7707,7 +7711,7 @@ CommandResult ConnectedClient::handleCommandDummy_IpChange(ts::Command &cmd) { auto provider = this->isAddressV4() ? geoloc::provider_vpn->resolveInfoV4(this->getPeerIp(), true) : geoloc::provider_vpn->resolveInfoV6(this->getPeerIp(), true); if(provider) { this->disconnect(strvar::transform(ts::config::messages::kick_vpn, strvar::StringValue{"provider.name", provider->name}, strvar::StringValue{"provider.website", provider->side})); - return CommandResult::Success; + return command_result{error::ok}; } } @@ -7725,16 +7729,16 @@ CommandResult ConnectedClient::handleCommandDummy_IpChange(ts::Command &cmd) { } this->properties()[property::CONNECTION_CLIENT_IP] = this->getLoggingPeerIp(); - return CommandResult::Success; + return command_result{error::ok}; } //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) { +command_result 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()) - return {findError("conversation_invalid_id")}; + return command_result{error::conversation_invalid_id}; auto conversation_id = command[0]["cid"].as(); /* test if we have access to the conversation */ @@ -7744,9 +7748,9 @@ CommandResult ConnectedClient::handleCommandConversationHistory(ts::Command &com shared_lock channel_view_lock(this->channel_lock); auto channel = this->channel_view()->find_channel(conversation_id); if(!channel) - return {findError("conversation_invalid_id")}; + return command_result{error::conversation_invalid_id}; if(channel->channel()->properties()[property::CHANNEL_FLAG_CONVERSATION_PRIVATE].as()) - return {findError("conversation_is_private")}; + return command_result{error::conversation_is_private}; } /* test if there is a channel password or join power which denies that we see the conversation */ @@ -7754,14 +7758,14 @@ CommandResult ConnectedClient::handleCommandConversationHistory(ts::Command &com 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")}; + return command_result{error::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"}; + return command_result{error::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); @@ -7772,7 +7776,7 @@ CommandResult ConnectedClient::handleCommandConversationHistory(ts::Command &com auto conversation_manager = ref_server->conversation_manager(); auto conversation = conversation_manager->get(conversation_id); if(!conversation) - return {ErrorType::DBEmpty}; + return command_result{error::database_empty_result}; system_clock::time_point timestamp_begin = system_clock::now(); system_clock::time_point timestamp_end; @@ -7788,13 +7792,13 @@ CommandResult ConnectedClient::handleCommandConversationHistory(ts::Command &com message_count = command[0]["message_count"].as(); if(timestamp_begin < timestamp_end) - return {findError("parameter_invalid")}; + return command_result{error::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}; + return command_result{error::database_empty_result}; bool more_data = messages.size() > message_count; if(more_data) messages.pop_back(); @@ -7831,12 +7835,12 @@ CommandResult ConnectedClient::handleCommandConversationHistory(ts::Command &com this->sendCommand(notify); if(more_data) - return {findError("conversation_more_data")}; + return command_result{error::conversation_more_data}; - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandConversationFetch(ts::Command &cmd) { +command_result ConnectedClient::handleCommandConversationFetch(ts::Command &cmd) { CMD_REF_SERVER(ref_server); CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -7918,14 +7922,14 @@ CommandResult ConnectedClient::handleCommandConversationFetch(ts::Command &cmd) result_bulk["flag_volatile"] = conversation->volatile_only(); } if(result_index == 0) - return {ErrorType::DBEmpty}; + return command_result{error::database_empty_result}; this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult ConnectedClient::handleCommandConversationMessageDelete(ts::Command &cmd) { +command_result ConnectedClient::handleCommandConversationMessageDelete(ts::Command &cmd) { CMD_REF_SERVER(ref_server); CMD_CHK_AND_INC_FLOOD_POINTS(25); @@ -7948,7 +7952,7 @@ CommandResult ConnectedClient::handleCommandConversationMessageDelete(ts::Comman shared_lock channel_view_lock(this->channel_lock); auto channel = this->channel_view()->find_channel(current_conversation_id); if(!channel) - return findError("conversation_invalid_id"); + return command_result{error::conversation_invalid_id}; } /* test if there is a channel password or join power which denies that we see the conversation */ @@ -7956,22 +7960,22 @@ CommandResult ConnectedClient::handleCommandConversationMessageDelete(ts::Comman shared_lock channel_view_lock(ref_server->channel_tree_lock); auto channel = ref_server->getChannelTree()->findChannel(current_conversation_id); if(!channel) - return findError("conversation_invalid_id"); + return command_result{error::conversation_invalid_id}; 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)) - return findError("channel_invalid_password"); + return command_result{error::channel_invalid_password}; if (!this->permissionGranted(permission::PERMTEST_ORDERED, permission::b_channel_conversation_message_delete, 1, channel)) - return CommandResultPermissionError{permission::b_channel_conversation_message_delete}; + return command_result{permission::b_channel_conversation_message_delete}; 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)) - return CommandResultPermissionError{permission::i_channel_needed_join_power}; + return command_result{permission::i_channel_needed_join_power}; } } } @@ -7999,7 +8003,7 @@ CommandResult ConnectedClient::handleCommandConversationMessageDelete(ts::Comman } } - return CommandResult::Success; + return command_result{error::ok}; } diff --git a/server/src/client/ConnectedClientTextCommandHandler.cpp b/server/src/client/ConnectedClientTextCommandHandler.cpp index 458a19b..b8cc42a 100644 --- a/server/src/client/ConnectedClientTextCommandHandler.cpp +++ b/server/src/client/ConnectedClientTextCommandHandler.cpp @@ -103,13 +103,17 @@ bool ConnectedClient::handleTextMessage(ChatMessageMode mode, std::string text, return true; \ } +//TODO: Correct error message print! #define HANDLE_CMD_ERROR(_message) \ + send_message(serverInstance->musicRoot(), string(_message) + ": action failed"); +/* if(result.extraProperties.count("extra_msg") > 0) \ send_message(serverInstance->musicRoot(), string(_message) + ": " + result.extraProperties["extra_msg"]); \ else if(result.extraProperties.count("failed_permid") > 0) \ send_message(serverInstance->musicRoot(), string(_message) + ". (Missing permission " + permission::resolvePermissionData((permission::PermissionType) stoull(result.extraProperties["failed_permid"]))->name + ")"); \ else \ send_message(serverInstance->musicRoot(), string(_message) + ": " + result.error.message); +*/ #define JOIN_ARGS(variable, index) \ string variable; \ @@ -153,7 +157,8 @@ bool ConnectedClient::handle_text_command( if (TARG(0, "create")) { Command cmd(""); auto result = this->handleCommandMusicBotCreate(cmd); - if(!result) { + if(result.error_code()) { + result.release_details(); HANDLE_CMD_ERROR("Failed to create music bot"); return true; } @@ -212,8 +217,9 @@ bool ConnectedClient::handle_text_command( Command cmd(""); cmd["client_nickname"] = ss.str(); auto result = this->handleCommandClientEdit(cmd, bot); - if(!result) { + if(result.error_code()) { HANDLE_CMD_ERROR("Failed to rename bot"); + result.release_details(); return true; } send_message(serverInstance->musicRoot(), "Name successfully changed!"); @@ -499,8 +505,9 @@ bool ConnectedClient::handle_text_command( JOIN_ARGS(value, 3); cmd[arguments[2]] = value; auto result = this->handleCommandClientEdit(cmd, bot); - if(!result) { + if(result.error_code()) { HANDLE_CMD_ERROR("Failed to change bot property"); + result.release_details(); return true; } send_message(serverInstance->musicRoot(), "Property successfully changed!"); diff --git a/server/src/client/SpeakingClient.cpp b/server/src/client/SpeakingClient.cpp index 580c6f7..3570fd8 100644 --- a/server/src/client/SpeakingClient.cpp +++ b/server/src/client/SpeakingClient.cpp @@ -343,22 +343,24 @@ HWID_REGEX(unix, "^[a-z0-9]{32}$"); HWID_REGEX(android, "^[a-z0-9]{16}$"); HWID_REGEX(ios, "^[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}$"); -CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) { +command_result SpeakingClient::handleCommandClientInit(Command& cmd) { TIMING_START(timings); { lock_guard lock(this->server->join_attempts_lock); auto inetAddr = this->getPeerIp(); if(config::voice::clientConnectLimit > 0 && this->server->join_attempts[inetAddr] + 1 > config::voice::clientConnectLimit) - return {findError("client_is_flooding"), "To many joins per second per ip"}; + return command_result{error::client_join_rate_limit_reached}; if(config::voice::connectLimit > 0 && this->server->join_attempts["_"] + 1 > config::voice::connectLimit) - return {findError("client_is_flooding"), "To many joins per second"}; + return command_result{error::server_join_rate_limit_reached}; this->server->join_attempts[inetAddr]++; this->server->join_attempts["_"]++; } TIMING_STEP(timings, "join atmp c"); - if(!DatabaseHelper::assignDatabaseId(this->server->getSql(), this->server->getServerId(), _this.lock())) return {findError("vs_critical"), "Could not assign database id!"}; + if(!DatabaseHelper::assignDatabaseId(this->server->getSql(), this->server->getServerId(), _this.lock())) + return command_result{error::vs_critical, "Could not assign database id!"}; + TIMING_STEP(timings, "db assign "); this->server->getGroupManager()->enableCache(this->getClientDatabaseId()); TIMING_STEP(timings, "gr cache "); @@ -423,8 +425,10 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) { else if(key == "pubSignCert") continue; else if(key == "client_version" || key == "client_platform") { for(auto& character : cmd[key].string()) - if(!isascii(character)) - return {findError("parameter_invalid"), "invalid version or platform"}; + if(!isascii(character)) { + logWarning(this->getServerId(), "{} Tried to join within an invalid supplied '{}' ({})", CLIENT_STR_LOG_PREFIX, key,cmd[key].string()); + return command_result{error::client_hacked}; + } } const auto &info = property::info(key); @@ -433,7 +437,8 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) { continue; //return {findError("parameter_invalid"), "Unknown property " + key}; } - if(!info->validate_input(cmd[key].as())) return {findError("parameter_invalid"), "Unknown value type for " + key}; + if(!info->validate_input(cmd[key].as())) + return command_result{error::parameter_invalid}; this->properties()[info] = cmd[key].as(); } @@ -459,7 +464,7 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) { if(geoloc::provider_vpn && permissions[permission::b_client_ignore_vpn] == permNotGranted) { auto provider = this->isAddressV4() ? geoloc::provider_vpn->resolveInfoV4(this->getPeerIp(), true) : geoloc::provider_vpn->resolveInfoV6(this->getPeerIp(), true); if(provider) - return {findError(0xD01), strvar::transform(ts::config::messages::kick_vpn, strvar::StringValue{"provider.name", provider->name}, strvar::StringValue{"provider.website", provider->side})}; + return command_result{error::server_connect_banned, strvar::transform(ts::config::messages::kick_vpn, strvar::StringValue{"provider.name", provider->name}, strvar::StringValue{"provider.website", provider->side})}; } if(this->getType() == ClientType::CLIENT_TEAMSPEAK && (permissions[permission::b_client_enforce_valid_hwid] == permNotGranted && permissions[permission::b_client_enforce_valid_hwid] == 0)) { @@ -470,14 +475,15 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) { !std::regex_match(hwid, regex_hwid_android) && !std::regex_match(hwid, regex_hwid_ios) ) { - return {findError("parameter_invalid"), config::messages::kick_invalid_hardware_id}; + return command_result{error::parameter_invalid, config::messages::kick_invalid_hardware_id}; } } TIMING_STEP(timings, "valid hw ip"); auto ignorePassword = permissions[permission::b_virtualserver_join_ignore_password] > 0 && permissions[permission::b_virtualserver_join_ignore_password] != permNotGranted; if(!ignorePassword) - if(!this->server->verifyServerPassword(cmd["client_server_password"].string(), true)) return {findError("server_invalid_password"), "invalid server password"}; + if(!this->server->verifyServerPassword(cmd["client_server_password"].string(), true)) + return command_result{error::server_invalid_password}; size_t clones_uid = 0; size_t clones_ip = 0; @@ -496,17 +502,17 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) { if(permissions[permission::i_client_max_clones_uid] > 0 && clones_uid >= permissions[permission::i_client_max_clones_uid]) { logMessage(this->getServerId(), "{} Disconnecting because there are already {} uid clones connected. (Allowed: {})", CLIENT_STR_LOG_PREFIX, clones_uid, permissions[permission::i_client_max_clones_uid]); - return {findError("client_too_many_clones_connected"), "too many clones connected (uid)"}; + return command_result{error:: client_too_many_clones_connected, "too many clones connected (uid)"}; } if(permissions[permission::i_client_max_clones_ip] > 0 && clones_ip >= permissions[permission::i_client_max_clones_ip]) { logMessage(this->getServerId(), "{} Disconnecting because there are already {} ip clones connected. (Allowed: {})", CLIENT_STR_LOG_PREFIX, clones_ip, permissions[permission::i_client_max_clones_ip]); - return {findError("client_too_many_clones_connected"), "too many clones connected (ip)"}; + return command_result{error:: client_too_many_clones_connected, "too many clones connected (ip)"}; } if(permissions[permission::i_client_max_clones_hwid] > 0 && clones_hwid >= permissions[permission::i_client_max_clones_hwid] && !_own_hwid.empty()) { logMessage(this->getServerId(), "{} Disconnecting because there are already {} hwid clones connected. (Allowed: {})", CLIENT_STR_LOG_PREFIX, clones_hwid, permissions[permission::i_client_max_clones_hwid]); - return {findError("client_too_many_clones_connected"), "too many clones connected (hwid)"}; + return command_result{error:: client_too_many_clones_connected, "too many clones connected (hwid)"}; } TIMING_STEP(timings, "max clones "); @@ -560,7 +566,7 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) { } else time = "never"; fullReason += time + "!"; - return {findError(0xD01), fullReason}; + return command_result{error::server_connect_banned, fullReason}; } TIMING_STEP(timings, "ban resolve"); @@ -577,9 +583,10 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) { bool allowReserved = permissions[permission::b_client_use_reserved_slot] != permNotGranted && permissions[permission::b_client_use_reserved_slot] != 0; if(reserved > maxClients){ - if(!allowReserved) return {findError("server_maxclients_reached"), "server max clients reached"}; + if(!allowReserved) + return command_result{error::server_maxclients_reached}; } else if(maxClients - (allowReserved ? 0 : reserved) <= count) - return {findError("server_maxclients_reached"), "server max clients reached"}; + return command_result{error::server_maxclients_reached}; TIMING_STEP(timings, "max clients"); @@ -613,7 +620,7 @@ CommandResult SpeakingClient::handleCommandClientInit(Command& cmd) { }); debugMessage(this->getServerId(), "{} Client init timings: {}", CLIENT_STR_LOG_PREFIX, TIMING_FINISH(timings)); - return CommandResult::Success; + return command_result{error::ok}; } /* must be triggered while helding an execute lock */ @@ -666,7 +673,9 @@ void SpeakingClient::processJoin() { TIMING_STEP(timings, "notify sini"); if(!ref_server->assignDefaultChannel(this->ref(), false)) { - this->notifyError({findError("vs_critical"), "Could not assign default channel!"}); + auto result = command_result{error::vs_critical, "Could not assign default channel!"}; + this->notifyError(result); + result.release_details(); this->closeConnection(system_clock::now() + seconds(1)); return; } @@ -776,19 +785,21 @@ void SpeakingClient::updateChannelClientProperties(bool channel_lock, bool notif this->max_idle_time = this->permissionValueFlagged(permission::i_client_max_idletime, this->currentChannel); } -CommandResult SpeakingClient::handleCommand(Command &command) { +command_result SpeakingClient::handleCommand(Command &command) { if(this->connectionState() == ConnectionState::INIT_HIGH) { if(this->handshake.state == HandshakeState::BEGIN || this->handshake.state == HandshakeState::IDENTITY_PROOF) { - CommandResult result; + command_result result; if(command.command() == "handshakebegin") result = this->handleCommandHandshakeBegin(command); else if(command.command() == "handshakeindentityproof") result = this->handleCommandHandshakeIdentityProof(command); else - result = {findError("client_not_logged_in")}; + result = command_result{error::client_not_logged_in}; - if(!result) - this->closeConnection(system_clock::now() + seconds(1)); + if(result.error_code()) + this->postCommandHandler.push_back([&]{ + this->closeConnection(system_clock::now() + seconds(1)); + }); return result; } } diff --git a/server/src/client/SpeakingClient.h b/server/src/client/SpeakingClient.h index e9701d0..c27c4bf 100644 --- a/server/src/client/SpeakingClient.h +++ b/server/src/client/SpeakingClient.h @@ -59,7 +59,7 @@ namespace ts { void updateChannelClientProperties(bool channel_lock, bool notify) override; protected: - CommandResult handleCommand(Command &command) override; + command_result handleCommand(Command &command) override; public: void handlePacketVoice(const pipes::buffer_view&, bool head, bool fragmented); @@ -68,9 +68,9 @@ namespace ts { void processJoin(); void processLeave(); - virtual CommandResult handleCommandHandshakeBegin(Command&); - virtual CommandResult handleCommandHandshakeIdentityProof(Command &); - virtual CommandResult handleCommandClientInit(Command&); + virtual command_result handleCommandHandshakeBegin(Command&); + virtual command_result handleCommandHandshakeIdentityProof(Command &); + virtual command_result handleCommandClientInit(Command&); void triggerVoiceEnd(); inline void updateSpeak(bool onlyUpdate, const std::chrono::system_clock::time_point &time); diff --git a/server/src/client/SpeakingClientHandshake.cpp b/server/src/client/SpeakingClientHandshake.cpp index 5c633dd..2889c8c 100644 --- a/server/src/client/SpeakingClientHandshake.cpp +++ b/server/src/client/SpeakingClientHandshake.cpp @@ -23,13 +23,13 @@ void free_ecc(ecc_key* key) { delete key; } -CommandResult SpeakingClient::handleCommandHandshakeBegin(Command& cmd) { //If !result than the connection will be closed! +command_result SpeakingClient::handleCommandHandshakeBegin(Command& cmd) { //If !result than the connection will be closed! if(this->handshake.state != HandshakeState::BEGIN) - return {findError("web_handshake_invalid"), "invalid connection state!"}; + return command_result{error::web_handshake_invalid}; auto intention = cmd["intention"].as(); if(intention != 0) - return {findError("web_handshake_unsupported"), ""}; + return command_result{error::web_handshake_unsupported}; auto authenticationMethod = cmd["authentication_method"].as(); if(authenticationMethod == IdentityType::TEAMSPEAK) { @@ -41,7 +41,8 @@ CommandResult SpeakingClient::handleCommandHandshakeBegin(Command& cmd) { //If ! this->handshake.identityKey = shared_ptr(new ecc_key{}, free_ecc); if(ecc_import((u_char*) identity.data(), identity.length(), this->handshake.identityKey.get()) != CRYPT_OK) { this->handshake.identityKey = nullptr; - return {findError("web_handshake_invalid"), "invalid ecc key state!"}; + logWarning(this->getServerId(), "{} Failed to import remote public key.", CLIENT_STR_LOG_PREFIX); + return command_result{error::web_handshake_invalid}; } auto message = "TeaSpeak, made with love and coffee by WolverinDEV (#" + base64::encode(rnd_string(32)) + ")"; @@ -65,26 +66,26 @@ CommandResult SpeakingClient::handleCommandHandshakeBegin(Command& cmd) { //If ! auto& json_str = this->handshake.proof_message; if(!reader->parse(json_str.data(), json_str.data() + json_str.size(), &*this->handshake.identityData, &error)) { debugMessage(this->getServerId(), "[{}] Failed to parse forum account data: {}", error); - return {findError("web_handshake_invalid"), "invalid json!"}; + return command_result{error::web_handshake_invalid}; } auto& json_data = *this->handshake.identityData; if(json_data["user_id"].isNull()) - return {findError("web_handshake_invalid"), "Missing json data (user_id)!"}; + return command_result{error::web_handshake_invalid}; //{findError("web_handshake_invalid"), "Missing json data (user_id)!"}; if(json_data["user_name"].isNull()) - return {findError("web_handshake_invalid"), "Missing json data (user_name)!"}; + return command_result{error::web_handshake_invalid}; //{findError("web_handshake_invalid"), "Missing json data (user_name)!"}; if(json_data["user_group"].isNull()) - return {findError("web_handshake_invalid"), "Missing json data (user_group)!"}; + return command_result{error::web_handshake_invalid}; //{findError("web_handshake_invalid"), "Missing json data (user_group)!"}; if(json_data["user_groups"].isNull()) - return {findError("web_handshake_invalid"), "Missing json data (user_groups)!"}; + return command_result{error::web_handshake_invalid}; //{findError("web_handshake_invalid"), "Missing json data (user_groups)!"}; if(json_data["data_age"].isNull()) - return {findError("web_handshake_invalid"), "Missing json data (data_age)!"}; + return command_result{error::web_handshake_invalid}; //{findError("web_handshake_invalid"), "Missing json data (data_age)!"}; //Type test json_data["user_id"].asInt64(); if(json_data["data_age"].asUInt64() < duration_cast((system_clock::now() - hours(72)).time_since_epoch()).count()) - return {findError("web_handshake_invalid"), "Provided data is too old!"}; + return command_result{error::web_handshake_identity_outdated}; // {findError("web_handshake_invalid"), "Provided data is too old!"}; this->properties()[property::CLIENT_UNIQUE_IDENTIFIER] = base64::encode(digest::sha1("TeaSpeak-Forum#" + json_data["user_id"].asString())); @@ -107,34 +108,37 @@ CommandResult SpeakingClient::handleCommandHandshakeBegin(Command& cmd) { //If ! this->properties()[property::CLIENT_TEAFORO_FLAGS] = flags; } } catch (Json::Exception& exception) { - return {findError("web_handshake_invalid"), "invalid json!"}; + debugMessage(this->getServerId(), "{} Failed to parse supplied json: {}", CLIENT_STR_LOG_PREFIX, exception.what()); + return command_result{error::web_handshake_invalid}; } this->sendCommand(Command("handshakeidentityproof")); this->handshake.state = HandshakeState::IDENTITY_PROOF; } else if(authenticationMethod == IdentityType::NICKNAME) { if(!config::server::authentication::name) - return {findError("web_handshake_identity_unsupported"), "Name authentication has been disabled"}; + return command_result{error::web_handshake_unsupported}; this->handshake.state = HandshakeState::SUCCEEDED; this->handshake.identityType = IdentityType::NICKNAME; this->properties()[property::CLIENT_UNIQUE_IDENTIFIER] = base64::encode(digest::sha1("UserName#" + cmd["client_nickname"].string())); } else { - return {findError("web_handshake_identity_unsupported"), ""}; + return command_result{error::web_handshake_unsupported}; } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult SpeakingClient::handleCommandHandshakeIdentityProof(Command& cmd) { +command_result SpeakingClient::handleCommandHandshakeIdentityProof(Command& cmd) { if(this->handshake.state != HandshakeState::IDENTITY_PROOF) - return {findError("web_handshake_invalid"), "invalid connection state!"}; + return command_result{error::web_handshake_invalid}; if(this->handshake.identityType == IdentityType::TEASPEAK_FORUM) { auto encodedProof = cmd["proof"].string(); auto proof = base64::decode(encodedProof); auto key = serverInstance->sslManager()->getRsaKey("teaforo_sign"); - if(!key) return {findError("web_handshake_identity_unsupported"), "Missing server public key!"}; - if(!serverInstance->sslManager()->verifySign(key, this->handshake.proof_message, proof)) return {findError("web_handshake_identity_proof_failed"), ""}; + if(!key) + return command_result{error::web_handshake_identity_unsupported}; + if(!serverInstance->sslManager()->verifySign(key, this->handshake.proof_message, proof)) + return command_result{error::web_handshake_identity_proof_failed}; this->properties()[property::CLIENT_TEAFORO_ID] = (int64_t) (*this->handshake.identityData)["user_id"].asInt64(); this->properties()[property::CLIENT_TEAFORO_NAME] = (*this->handshake.identityData)["user_name"].asString(); @@ -143,11 +147,13 @@ CommandResult SpeakingClient::handleCommandHandshakeIdentityProof(Command& cmd) auto proof = base64::decode(cmd["proof"]); int result; - if(ecc_verify_hash((u_char*) proof.data(), proof.length(), (u_char*) this->handshake.proof_message.data(), this->handshake.proof_message.length(), &result, this->handshake.identityKey.get()) != CRYPT_OK) return {findError("web_handshake_identity_proof_failed"), ""}; - if(!result) return {findError("web_handshake_identity_proof_failed"), ""}; + if(ecc_verify_hash((u_char*) proof.data(), proof.length(), (u_char*) this->handshake.proof_message.data(), this->handshake.proof_message.length(), &result, this->handshake.identityKey.get()) != CRYPT_OK) + return command_result{error::web_handshake_identity_proof_failed}; + if(!result) + return command_result{error::web_handshake_identity_proof_failed}; this->handshake.state = HandshakeState::SUCCEEDED; } else - return {findError("web_handshake_invalid"), "identity isn't required to proof authentication"}; + return command_result{error::web_handshake_invalid}; - return CommandResult::Success; + return command_result{error::ok}; } \ No newline at end of file diff --git a/server/src/client/query/QueryClient.cpp b/server/src/client/query/QueryClient.cpp index 1ceef9a..2c34c04 100644 --- a/server/src/client/query/QueryClient.cpp +++ b/server/src/client/query/QueryClient.cpp @@ -7,7 +7,6 @@ #include #include "src/InstanceHandler.h" #include -#include #include using namespace std; @@ -76,7 +75,9 @@ void QueryClient::postInitialize() { this->properties()[property::CLIENT_LASTCONNECTED] = duration_cast(this->connectTimestamp.time_since_epoch()).count(); if(ts::config::query::sslMode == 1 && this->connectionType != ConnectionType::SSL_ENCRIPTED) { - this->notifyError({findError("failed_connection_initialisation"), "Please use a SSL encryption!"}); + command_result error{error::failed_connection_initialisation, "Please use a SSL encryption!"}; + this->notifyError(error); + error.release_details(); this->disconnect("Please us a SSL encryption for more security.\nThe server denies also all other connections!"); return; } @@ -495,28 +496,31 @@ bool QueryClient::handleMessage(const pipes::buffer_view& message) { } unique_ptr cmd; + command_result error{}; try { cmd = make_unique(Command::parse(pipes::buffer_view{(void*) command.data(), command.length()}, true, !ts::config::server::strict_ut8_mode)); } catch(std::invalid_argument& ex) { logTrace(LOG_QUERY, "[{}:{}] Failed to parse command (invalid argument): {}", this->getLoggingPeerIp(), this->getPeerPort(), command); - this->notifyError(CommandResult{findError("parameter_convert"), ex.what()}); - return false; - } catch(command_malformed_exception& ex) { - logTrace(LOG_QUERY, "[{}:{}] Failed to parse command (malformed command at {}): {}", this->getLoggingPeerIp(), this->getPeerPort(), ex.index(), command); - this->notifyError(CommandResult{findError("parameter_convert"), "invalid character @" + to_string(ex.index())}); - return false; + error = command_result{error::parameter_convert}; + goto handle_error; } catch(std::exception& ex) { logTrace(LOG_QUERY, "[{}:{}] Failed to parse command (exception: {}): {}", this->getLoggingPeerIp(), this->getPeerPort(), ex.what(), command); - this->notifyError(CommandResult{ErrorType::VSError, ex.what()}); - return false; + error = command_result{error::vs_critical, std::string{ex.what()}}; + goto handle_error; } try { this->handleCommandFull(*cmd); } catch(std::exception& ex) { - this->notifyError(CommandResult{ErrorType::VSError, ex.what()}); + error = command_result{error::vs_critical, std::string{ex.what()}}; + goto handle_error; } return true; + + handle_error: + this->notifyError(error); + error.release_details(); + return false; } void QueryClient::sendCommand(const ts::Command &command, bool) { diff --git a/server/src/client/query/QueryClient.h b/server/src/client/query/QueryClient.h index afa381d..ebb1f91 100644 --- a/server/src/client/query/QueryClient.h +++ b/server/src/client/query/QueryClient.h @@ -86,7 +86,7 @@ namespace ts { std::shared_ptr query_account; protected: - CommandResult handleCommand(Command &command) override; + command_result handleCommand(Command &command) override; public: //Silent events @@ -144,41 +144,41 @@ namespace ts { bool notifyClientLeftViewBanned(const std::shared_ptr &client, const std::string &message, std::shared_ptr invoker, size_t length, bool lock_channel_tree) override; private: - CommandResult handleCommandExit(Command&); - CommandResult handleCommandLogin(Command&); - CommandResult handleCommandLogout(Command&); - CommandResult handleCommandServerSelect(Command &); - CommandResult handleCommandServerInfo(Command&); - CommandResult handleCommandChannelList(Command&); - CommandResult handleCommandJoin(Command&); - CommandResult handleCommandLeft(Command&); + command_result handleCommandExit(Command&); + command_result handleCommandLogin(Command&); + command_result handleCommandLogout(Command&); + command_result handleCommandServerSelect(Command &); + command_result handleCommandServerInfo(Command&); + command_result handleCommandChannelList(Command&); + command_result handleCommandJoin(Command&); + command_result handleCommandLeft(Command&); - CommandResult handleCommandServerList(Command&); - CommandResult handleCommandServerCreate(Command&); - CommandResult handleCommandServerDelete(Command&); - CommandResult handleCommandServerStart(Command&); - CommandResult handleCommandServerStop(Command&); + command_result handleCommandServerList(Command&); + command_result handleCommandServerCreate(Command&); + command_result handleCommandServerDelete(Command&); + command_result handleCommandServerStart(Command&); + command_result handleCommandServerStop(Command&); - CommandResult handleCommandInstanceInfo(Command&); - CommandResult handleCommandInstanceEdit(Command&); + command_result handleCommandInstanceInfo(Command&); + command_result handleCommandInstanceEdit(Command&); - CommandResult handleCommandBindingList(Command&); + command_result handleCommandBindingList(Command&); - CommandResult handleCommandHostInfo(Command&); + command_result handleCommandHostInfo(Command&); - CommandResult handleCommandGlobalMessage(Command&); + command_result handleCommandGlobalMessage(Command&); - CommandResult handleCommandServerIdGetByPort(Command&); + command_result handleCommandServerIdGetByPort(Command&); - CommandResult handleCommandServerSnapshotDeploy(Command&); - CommandResult handleCommandServerSnapshotCreate(Command&); - CommandResult handleCommandServerProcessStop(Command&); + command_result handleCommandServerSnapshotDeploy(Command&); + command_result handleCommandServerSnapshotCreate(Command&); + command_result handleCommandServerProcessStop(Command&); - CommandResult handleCommandServerNotifyRegister(Command&); - CommandResult handleCommandServerNotifyList(Command&); - CommandResult handleCommandServerNotifyUnregister(Command&); + command_result handleCommandServerNotifyRegister(Command&); + command_result handleCommandServerNotifyList(Command&); + command_result handleCommandServerNotifyUnregister(Command&); - CommandResult handleCommandSetCompressionMode(Command&); + command_result handleCommandSetCompressionMode(Command&); }; } } \ No newline at end of file diff --git a/server/src/client/query/QueryClientCommands.cpp b/server/src/client/query/QueryClientCommands.cpp index d53430c..55748ea 100644 --- a/server/src/client/query/QueryClientCommands.cpp +++ b/server/src/client/query/QueryClientCommands.cpp @@ -20,7 +20,7 @@ constexpr unsigned int string_hash(const char* str, int h = 0) { return !str[h] ? 5381 : (string_hash(str, h + 1U) * 33U) ^ str[h]; } -CommandResult QueryClient::handleCommand(Command& cmd) { +command_result QueryClient::handleCommand(Command& cmd) { /* if (cmd.command() == "exit" || cmd.command() == "quit") return this->handleCommandExit(cmd); else if (cmd.command() == "use" || cmd.command() == "serverselect") return this->handleCommandServerSelect(cmd); @@ -117,14 +117,14 @@ CommandResult QueryClient::handleCommand(Command& cmd) { return ConnectedClient::handleCommand(cmd); } -CommandResult QueryClient::handleCommandExit(Command &) { +command_result QueryClient::handleCommandExit(Command &) { logMessage(LOG_QUERY, "[Query] {}:{} disconnected. (Requested by client)", this->getLoggingPeerIp(), this->getPeerPort()); this->closeConnection(system_clock::now() + seconds(1)); - return CommandResult::Success; + return command_result{error::ok}; } //login client_login_name=andreas client_login_password=meinPW -CommandResult QueryClient::handleCommandLogin(Command& cmd) { +command_result QueryClient::handleCommandLogin(Command& cmd) { CMD_RESET_IDLE; std::string username, password; @@ -144,7 +144,7 @@ CommandResult QueryClient::handleCommandLogin(Command& cmd) { threads::MutexLock lock(this->handle->loginLock); if(!account) - return {findError("client_invalid_password"), "username or password dose not match"}; + return command_result{error::client_invalid_password, "username or password dose not match"}; if (account->password != password) { if(!this->whitelisted) { @@ -154,15 +154,20 @@ CommandResult QueryClient::handleCommandLogin(Command& cmd) { this->postCommandHandler.emplace_back([&](){ this->closeConnection(system_clock::now() + seconds(1)); }); - return {findError("ban_flooding"), ""}; + return command_result{error::ban_flooding}; } } - return {findError("client_invalid_password"), "username or password dose not match"}; + return command_result{error::client_invalid_password, "username or password dose not match"}; } } if(!this->properties()[property::CLIENT_LOGIN_NAME].as().empty()) { Command log("logout"); - if(!this->handleCommandLogout(log)) return {ErrorType::VSError, "Failed to logout!"}; + auto result = this->handleCommandLogout(log); + if(result.error_code()) { + result.release_details(); + logError(this->getServerId(), "Query client failed to login from old login."); + return command_result{error::vs_critical}; + } } this->query_account = account; @@ -190,7 +195,7 @@ CommandResult QueryClient::handleCommandLogin(Command& cmd) { if(target_server != this->server) joined_channel = nullptr; if(!target_server) - return {findError("server_invalid_id"), "server does not exists anymore"}; + return command_result{error::server_invalid_id, "server does not exists anymore"}; } this->server = target_server; @@ -226,12 +231,12 @@ CommandResult QueryClient::handleCommandLogin(Command& cmd) { this->properties()[property::CLIENT_TOTALCONNECTIONS]++; this->updateChannelClientProperties(true, true); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandLogout(Command &) { +command_result QueryClient::handleCommandLogout(Command &) { CMD_RESET_IDLE; - if(this->properties()[property::CLIENT_LOGIN_NAME].as().empty()) return {findError("client_not_logged_in"), "not logged in"}; + if(this->properties()[property::CLIENT_LOGIN_NAME].as().empty()) return command_result{error::client_not_logged_in, "not logged in"}; this->properties()[property::CLIENT_LOGIN_NAME] = ""; this->query_account = nullptr; @@ -278,10 +283,10 @@ CommandResult QueryClient::handleCommandLogout(Command &) { this->updateChannelClientProperties(true, true); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandServerSelect(Command &cmd) { +command_result QueryClient::handleCommandServerSelect(Command &cmd) { CMD_RESET_IDLE; shared_ptr target; @@ -295,18 +300,18 @@ CommandResult QueryClient::handleCommandServerSelect(Command &cmd) { if(parm.find_first_not_of("0123456789") == string::npos) target = serverInstance->getVoiceServerManager()->findServerById(static_cast(stol(parm))); - if(!target && (!cmd[0].has("0") && (!cmd[0].has("sid") || !cmd["sid"] == 0))) return {findError("server_invalid_id"), "Invalid server id"}; + if(!target && (!cmd[0].has("0") && (!cmd[0].has("sid") || !cmd["sid"] == 0))) return command_result{error::server_invalid_id, "Invalid server id"}; - if(target == this->server) return CommandResult::Success; + if(target == this->server) return command_result{error::ok}; if(target) { if(this->query_account && this->query_account->bound_server > 0) { if(target->getServerId() != this->query_account->bound_server) - return {findError("server_invalid_id"), "You're a server bound query, and the target server isn't your origin."}; + return command_result{error::server_invalid_id, "You're a server bound query, and the target server isn't your origin."}; } else { auto allowed = target->calculatePermission(permission::PERMTEST_ORDERED, this->getClientDatabaseId(), permission::b_virtualserver_select, this->getType(), nullptr); - if(allowed != -1 && allowed <= 0) return CommandResultPermissionError{permission::b_virtualserver_select}; + if(allowed != -1 && allowed <= 0) return command_result{permission::b_virtualserver_select}; } } @@ -362,23 +367,23 @@ CommandResult QueryClient::handleCommandServerSelect(Command &cmd) { } this->updateChannelClientProperties(true, true); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandJoin(Command &) { +command_result QueryClient::handleCommandJoin(Command &) { CMD_REQ_SERVER; CMD_RESET_IDLE; if(!this->server->running()) - return {findError("server_is_not_running"), "server isnt started yet"}; + return command_result{error::server_is_not_running, "server isnt started yet"}; if(this->currentChannel) - return {findError("server_already_joined"), "already joined!"}; + return command_result{error::server_already_joined, "already joined!"}; this->server->assignDefaultChannel(this->ref(), true); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandLeft(Command&) { +command_result QueryClient::handleCommandLeft(Command&) { CMD_REQ_SERVER; CMD_REQ_CHANNEL; CMD_RESET_IDLE; @@ -386,10 +391,10 @@ CommandResult QueryClient::handleCommandLeft(Command&) { PERM_CHECK_CHANNELR(permission::b_virtualserver_select_godmode, 1, nullptr, 1); unique_lock server_channel_lock(this->server->channel_tree_lock); this->server->client_move(this->ref(), nullptr, nullptr, "leaving", ViewReasonId::VREASON_SERVER_LEFT, true, server_channel_lock); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandServerInfo(Command &) { +command_result QueryClient::handleCommandServerInfo(Command &) { CMD_RESET_IDLE; PERM_CHECKR(permission::b_virtualserver_info_view, 1, true); @@ -469,10 +474,10 @@ CommandResult QueryClient::handleCommandServerInfo(Command &) { } this->sendCommand(cmd); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandChannelList(Command& cmd) { +command_result QueryClient::handleCommandChannelList(Command& cmd) { PERM_CHECKR(permission::b_virtualserver_channel_list, 1, true); CMD_RESET_IDLE; @@ -530,10 +535,10 @@ CommandResult QueryClient::handleCommandChannelList(Command& cmd) { } this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandServerList(Command& cmd) { +command_result QueryClient::handleCommandServerList(Command& cmd) { CMD_RESET_IDLE; PERM_CHECKR(permission::b_serverinstance_virtualserver_list, 1, true); Command res(""); @@ -563,15 +568,15 @@ CommandResult QueryClient::handleCommandServerList(Command& cmd) { } this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandServerCreate(Command& cmd) { +command_result QueryClient::handleCommandServerCreate(Command& cmd) { CMD_RESET_IDLE; PERM_CHECKR(permission::b_virtualserver_create, 1, true); if(serverInstance->getVoiceServerManager()->getState() != ServerManager::STARTED) { - return {findError("vs_critical"), "Server manager isn't started yet or not finished starting"}; + return command_result{error::vs_critical, "Server manager isn't started yet or not finished starting"}; } string startError; @@ -583,9 +588,9 @@ CommandResult QueryClient::handleCommandServerCreate(Command& cmd) { threads::MutexLock lock(serverInstance->getVoiceServerManager()->server_create_lock); auto instances = serverInstance->getVoiceServerManager()->serverInstances(); if(config::server::max_virtual_server != -1 && instances.size() > config::server::max_virtual_server) - return {findError("server_max_vs_reached"), "You reached the via config.yml enabled virtual server limit."}; + return command_result{error::server_max_vs_reached, "You reached the via config.yml enabled virtual server limit."}; if(instances.size() >= 65535) - return {findError("server_max_vs_reached"), "You cant create anymore virtual servers. (Software limit reached)"}; + return command_result{error::server_max_vs_reached, "You cant create anymore virtual servers. (Software limit reached)"}; { auto end = system_clock::now(); time_wait = duration_cast(end - start); @@ -601,7 +606,7 @@ CommandResult QueryClient::handleCommandServerCreate(Command& cmd) { auto _end = system_clock::now(); time_create = duration_cast(_end - _start); } - if(!server) return {findError("vs_critical"), "could not create new server"}; + if(!server) return command_result{error::vs_critical, "could not create new server"}; for(const auto& key : cmd[0].keys()){ if(key == "virtualserver_port") continue; @@ -640,64 +645,64 @@ CommandResult QueryClient::handleCommandServerCreate(Command& cmd) { res["time_global"] = time_global.count(); res["time_wait"] = time_wait.count(); this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandServerDelete(Command& cmd) { +command_result QueryClient::handleCommandServerDelete(Command& cmd) { CMD_RESET_IDLE; PERM_CHECKR(permission::b_virtualserver_delete, 1, true); if(serverInstance->getVoiceServerManager()->getState() != ServerManager::STARTED) - return {findError("vs_critical"), "Server manager isn't started yet or not finished starting"}; + return command_result{error::vs_critical, "Server manager isn't started yet or not finished starting"}; auto server = serverInstance->getVoiceServerManager()->findServerById(cmd["sid"]); - if(!server) return {findError("server_invalid_id"), "invalid bounded server"}; - if(!serverInstance->getVoiceServerManager()->deleteServer(server)) return {ErrorType::VSError}; - return CommandResult::Success; + if(!server) return command_result{error::server_invalid_id, "invalid bounded server"}; + if(!serverInstance->getVoiceServerManager()->deleteServer(server)) return command_result{error::vs_critical}; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandServerStart(Command& cmd) { +command_result QueryClient::handleCommandServerStart(Command& cmd) { CMD_RESET_IDLE; PERM_CHECKR(permission::b_virtualserver_start_any, 1, true); if(serverInstance->getVoiceServerManager()->getState() != ServerManager::STARTED) - return {findError("vs_critical"), "Server manager isn't started yet or not finished starting"}; + return command_result{error::vs_critical, "Server manager isn't started yet or not finished starting"}; auto server = serverInstance->getVoiceServerManager()->findServerById(cmd["sid"]); - if(!server) return {findError("server_invalid_id"), "invalid bounded server"}; - if(server->running()) return {findError("server_running"), "server already running"}; + if(!server) return command_result{error::server_invalid_id, "invalid bounded server"}; + if(server->running()) return command_result{error::server_running, "server already running"}; if(server->calculatePermission(permission::PERMTEST_ORDERED, this->getClientDatabaseId(), permission::b_virtualserver_start, ClientType::CLIENT_QUERY, nullptr) != 1) { if(!this->permissionGranted(permission::PERMTEST_HIGHEST, permission::b_virtualserver_start_any, 1)) - return CommandResultPermissionError{permission::b_virtualserver_start}; + return command_result{permission::b_virtualserver_start}; } string err; - if(!server->start(err)) return {findError("vs_critical"), err}; - return CommandResult::Success; + if(!server->start(err)) return command_result{error::vs_critical, err}; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandServerStop(Command& cmd) { +command_result QueryClient::handleCommandServerStop(Command& cmd) { CMD_RESET_IDLE; PERM_CHECKR(permission::b_virtualserver_stop, 1, true); if(serverInstance->getVoiceServerManager()->getState() != ServerManager::STARTED) - return {findError("vs_critical"), "Server manager isn't started yet or not finished starting"}; + return command_result{error::vs_critical, "Server manager isn't started yet or not finished starting"}; auto server = serverInstance->getVoiceServerManager()->findServerById(cmd["sid"]); - if(!server) return {findError("server_invalid_id"), "invalid bounded server"}; - if(!server->running()) return {findError("server_is_not_running"), "server is not running"}; + if(!server) return command_result{error::server_invalid_id, "invalid bounded server"}; + if(!server->running()) return command_result{error::server_is_not_running, "server is not running"}; if(server->calculatePermission(permission::PERMTEST_ORDERED, this->getClientDatabaseId(), permission::b_virtualserver_stop, ClientType::CLIENT_QUERY, nullptr) != 1) { if(!this->permissionGranted(permission::PERMTEST_HIGHEST, permission::b_virtualserver_stop_any, 1)) - return CommandResultPermissionError{permission::b_virtualserver_stop}; + return command_result{permission::b_virtualserver_stop}; } server->stop("server stopped"); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandInstanceInfo(Command& cmd) { +command_result QueryClient::handleCommandInstanceInfo(Command& cmd) { PERM_CHECKR(permission::b_serverinstance_info_view, 1, true); Command res(""); @@ -707,10 +712,10 @@ CommandResult QueryClient::handleCommandInstanceInfo(Command& cmd) { res["serverinstance_teaspeak"] = true; this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandInstanceEdit(Command& cmd) { +command_result QueryClient::handleCommandInstanceEdit(Command& cmd) { PERM_CHECKR(permission::b_serverinstance_modify_settings, 1, true); for(const auto &key : cmd[0].keys()){ @@ -730,10 +735,10 @@ CommandResult QueryClient::handleCommandInstanceEdit(Command& cmd) { } serverInstance->properties()[info] = cmd[key].string(); } - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandHostInfo(Command &) { +command_result QueryClient::handleCommandHostInfo(Command &) { PERM_CHECKR(permission::b_serverinstance_info_view, 1, true); Command res(""); @@ -765,37 +770,37 @@ CommandResult QueryClient::handleCommandHostInfo(Command &) { res["connection_filetransfer_bytes_received_total"] = (*stats)[property::CONNECTION_FILETRANSFER_BYTES_RECEIVED_TOTAL].as(); this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandGlobalMessage(Command& cmd) { +command_result QueryClient::handleCommandGlobalMessage(Command& cmd) { PERM_CHECKR(permission::b_serverinstance_textmessage_send, 1, true); for(const auto &server : serverInstance->getVoiceServerManager()->serverInstances()) if(server->running()) server->broadcastMessage(server->getServerRoot(), cmd["msg"]); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandServerIdGetByPort(Command& cmd) { +command_result QueryClient::handleCommandServerIdGetByPort(Command& cmd) { uint16_t port = cmd["virtualserver_port"]; auto server = serverInstance->getVoiceServerManager()->findServerByPort(port); - if(!server) return {findError("databse_empty_result"), "Invalid port"}; + if(!server) return command_result{error::server_invalid_id}; Command res(""); res["server_id"] = server->getServerId(); this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandBindingList(Command& cmd) { +command_result QueryClient::handleCommandBindingList(Command& cmd) { Command res(""); res["ip"] = "0.0.0.0 "; this->sendCommand(res); //TODO maybe list here all bindings from voice & file and query server? - return CommandResult::Success; + return command_result{error::ok}; } //TODO with mapping! -CommandResult QueryClient::handleCommandServerSnapshotDeploy(Command& cmd) { +command_result QueryClient::handleCommandServerSnapshotDeploy(Command& cmd) { PERM_CHECKR(permission::b_virtualserver_snapshot_deploy, 1, true); CMD_RESET_IDLE; @@ -809,7 +814,7 @@ CommandResult QueryClient::handleCommandServerSnapshotDeploy(Command& cmd) { } auto hash = cmd["hash"].string(); - if(hash.empty()) return {findError("parameter_invalid"), "Invalid hash (not present)"}; + if(hash.empty()) return command_result{error::parameter_invalid, "Invalid hash (not present)"}; debugMessage(this->getServerId(), "Serversnapshot calculated hash: {}", hash); bool mapping = cmd.hasParm("mapping"); cmd.disableParm("mapping"); @@ -821,7 +826,7 @@ CommandResult QueryClient::handleCommandServerSnapshotDeploy(Command& cmd) { auto str = cmd.build().substr(strlen("serversnapshotdeploy ")); if(!ignore_hash) { auto buildHash = base64::encode(digest::sha1(str)); - if(buildHash != hash) return {findError("parameter_invalid"), "Invalid hash (Expected: \"" + hash + "\", Got: \"" + buildHash + "\")"}; + if(buildHash != hash) return command_result{error::parameter_invalid, "Invalid hash (Expected: \"" + hash + "\", Got: \"" + buildHash + "\")"}; } unique_lock server_create_lock(serverInstance->getVoiceServerManager()->server_create_lock); @@ -853,10 +858,10 @@ CommandResult QueryClient::handleCommandServerSnapshotDeploy(Command& cmd) { res["time"] = duration_cast(end - start).count(); this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } -CommandResult QueryClient::handleCommandServerSnapshotCreate(Command& cmd) { +command_result QueryClient::handleCommandServerSnapshotCreate(Command& cmd) { PERM_CHECKR(permission::b_virtualserver_snapshot_create, 1, true); CMD_RESET_IDLE; CMD_REQ_SERVER; @@ -868,7 +873,7 @@ CommandResult QueryClient::handleCommandServerSnapshotCreate(Command& cmd) { if(version == -1 && (cmd.hasParm("lagacy") || cmd.hasParm("legacy"))) version = 0; if(!serverInstance->getVoiceServerManager()->createServerSnapshot(result, this->server, version, error)) - return {ErrorType::VSError, error}; + return command_result{error::vs_critical, error}; string data = result.build(); auto buildHash = base64::encode(digest::sha1(data)); @@ -877,23 +882,23 @@ CommandResult QueryClient::handleCommandServerSnapshotCreate(Command& cmd) { result[0]["hash"] = buildHash; this->sendCommand(result); - return CommandResult::Success; + return command_result{error::ok}; } extern bool mainThreadActive; -CommandResult QueryClient::handleCommandServerProcessStop(Command& cmd) { +command_result QueryClient::handleCommandServerProcessStop(Command& cmd) { PERM_CHECKR(permission::b_serverinstance_stop, 1, true); if(cmd[0].has("type")) { if(cmd["type"] == "cancel") { auto task = ts::server::scheduledShutdown(); - if(!task) return {findError("server_is_not_shutting_down"), "There isn't a shutdown scheduled"}; + if(!task) return command_result{error::server_is_not_shutting_down, "There isn't a shutdown scheduled"}; ts::server::cancelShutdown(true); - return CommandResult::Success; + return command_result{error::ok}; } else if(cmd["type"] == "schedule") { - if(!cmd[0].has("time")) return {findError("parameter_missing"), "Missing time"}; + if(!cmd[0].has("time")) return command_result{error::parameter_missing, "Missing time"}; ts::server::scheduleShutdown(system_clock::now() + seconds(cmd["time"].as()), cmd[0].has("msg") ? cmd["msg"].string() : ts::config::messages::applicationStopped); - return CommandResult::Success; + return command_result{error::ok}; } } @@ -904,18 +909,18 @@ CommandResult QueryClient::handleCommandServerProcessStop(Command& cmd) { reason = cmd["reasonmsg"].string(); serverInstance->getVoiceServerManager()->shutdownAll(reason); mainThreadActive = false; - return CommandResult::Success; + return command_result{error::ok}; } #define XMACRO_EV(evName0, evSpec0, evName1, evSpec1) \ if(cmd["event"].value() == "all" || (cmd["event"].value() == (evName0) && (cmd["specifier"].value() == "all" || cmd["specifier"].value() == (evSpec0)))) \ events.push_back({QueryEventGroup::evName1, QueryEventSpecifier::evSpec1}); -inline CommandResult parseEvent(ParameterBulk& cmd, vector>& events){ +inline bool parseEvent(ParameterBulk& cmd, vector>& events){ auto start = events.size(); #include "XMacroEventTypes.h" - if(start == events.size()) return {findError("parameter_invalid"), "invalid group/specifier"}; - return CommandResult::Success; + if(start == events.size()) return false; + return true; } #undef XMACRO_EV @@ -923,7 +928,7 @@ inline CommandResult parseEvent(ParameterBulk& cmd, vectortoggleEvent(QueryEventGroup::gr, QueryEventSpecifier::spec, true); -CommandResult QueryClient::handleCommandServerNotifyRegister(Command &cmd) { +command_result QueryClient::handleCommandServerNotifyRegister(Command &cmd) { CMD_REQ_SERVER; CMD_REQ_PARM("event"); CMD_RESET_IDLE; @@ -932,17 +937,17 @@ CommandResult QueryClient::handleCommandServerNotifyRegister(Command &cmd) { string event = cmd["event"]; std::transform(event.begin(), event.end(), event.begin(), ::tolower); #include "XMacroEventTypes.h" - return CommandResult::Success; + return command_result{error::ok}; } //TODO implement bulk vector> events; //parameter_invalid auto result = parseEvent(cmd[0], events); - if(!result) return result; + if(!result) return command_result{error::parameter_invalid}; for(const auto& ev : events) this->toggleEvent(ev.first, ev.second, true); - return CommandResult::Success; + return command_result{error::ok}; } #undef XMACRO_LAGACY_EV @@ -953,7 +958,7 @@ else if((evName1) == group && (evSpec1) == spec){ \ index++; \ } -CommandResult QueryClient::handleCommandServerNotifyList(Command& cmd) { +command_result QueryClient::handleCommandServerNotifyList(Command& cmd) { CMD_REQ_SERVER; CMD_RESET_IDLE; @@ -970,16 +975,16 @@ CommandResult QueryClient::handleCommandServerNotifyList(Command& cmd) { } } - if(index == 0) return {findError("database_empty_result"), ""}; + if(index == 0) return command_result{error::database_empty_result}; this->sendCommand(res); - return CommandResult::Success; + return command_result{error::ok}; } #undef XMACRO_EV #define XMACRO_LAGACY_EV(lagacyName, gr, spec) \ if(event == lagacyName) this->toggleEvent(QueryEventGroup::gr, QueryEventSpecifier::spec, false); -CommandResult QueryClient::handleCommandServerNotifyUnregister(Command &cmd) { +command_result QueryClient::handleCommandServerNotifyUnregister(Command &cmd) { CMD_REQ_SERVER; CMD_REQ_PARM("event"); CMD_RESET_IDLE; @@ -988,15 +993,15 @@ CommandResult QueryClient::handleCommandServerNotifyUnregister(Command &cmd) { string event = cmd["event"]; std::transform(event.begin(), event.end(), event.begin(), ::tolower); #include "XMacroEventTypes.h" - return CommandResult::Success; + return command_result{error::ok}; } //TODO implemt bulk vector> events; auto result = parseEvent(cmd[0], events); - if(!result) return result; + if(!result) return command_result{error::parameter_invalid}; for(const auto& ev : events) this->toggleEvent(ev.first, ev.second, false); - return CommandResult::Success; + return command_result{error::ok}; } #undef XMACRO_LAGACY_EV \ No newline at end of file diff --git a/server/src/client/query/XMacroEventTypes.h b/server/src/client/query/XMacroEventTypes.h index 8da6d5f..4c5eea0 100644 --- a/server/src/client/query/XMacroEventTypes.h +++ b/server/src/client/query/XMacroEventTypes.h @@ -1,6 +1,6 @@ -#ifndef XMACRO_EV #define XMACRO_EV_UNDEF - #define XMACRO_EV(a, b, c, d) +#ifndef XMACRO_EV +#define XMACRO_EV(a, b, c, d) #endif #ifndef XMACRO_LAGACY_EV #define XMACRO_LAGACY_EV_UNDEF diff --git a/server/src/client/voice/VoiceClient.h b/server/src/client/voice/VoiceClient.h index 5acde66..61154ab 100644 --- a/server/src/client/voice/VoiceClient.h +++ b/server/src/client/voice/VoiceClient.h @@ -85,7 +85,7 @@ namespace ts { void send_voice_whisper_packet(const pipes::buffer_view &packet, const VoicePacketFlags &flags) override; protected: - virtual CommandResult handleCommand(Command &command) override; + virtual command_result handleCommand(Command &command) override; //Some helper method void sendPingRequest(); @@ -106,10 +106,10 @@ namespace ts { bool final_disconnected = false; //General TS3 manager commands - CommandResult handleCommandClientInitIv(Command&); - CommandResult handleCommandClientEk(const std::unique_ptr&, Command&); - CommandResult handleCommandClientInit(Command&) override; - CommandResult handleCommandClientDisconnect(Command&); + command_result handleCommandClientInitIv(Command&); + command_result handleCommandClientEk(const std::unique_ptr&, Command&); + command_result handleCommandClientInit(Command&) override; + command_result handleCommandClientDisconnect(Command&); //Locked by finalDisconnect, disconnect and close connection std::shared_ptr flushing_thread; diff --git a/server/src/client/voice/VoiceClientCommandHandler.cpp b/server/src/client/voice/VoiceClientCommandHandler.cpp index 5313809..78671e6 100644 --- a/server/src/client/voice/VoiceClientCommandHandler.cpp +++ b/server/src/client/voice/VoiceClientCommandHandler.cpp @@ -16,10 +16,10 @@ using namespace ts::protocol; using namespace ts; -CommandResult VoiceClient::handleCommand(ts::Command &command) { +command_result VoiceClient::handleCommand(ts::Command &command) { threads::MutexLock l2(this->command_lock); - if(this->state == ConnectionState::DISCONNECTED) return CommandResult::NotImplemented; - if(!this->voice_server) return CommandResult::NotImplemented; + if(this->state == ConnectionState::DISCONNECTED) return command_result{error::client_not_logged_in}; + if(!this->voice_server) return command_result{error::server_unbound}; if(this->state == ConnectionState::INIT_HIGH && this->handshake.state == HandshakeState::SUCCEEDED) { if(command.command() == "clientinit") @@ -55,7 +55,7 @@ inline bool calculate_security_level(int& result, ecc_key* pubKey, size_t offset return true; } -CommandResult VoiceClient::handleCommandClientInit(Command &cmd) { +command_result VoiceClient::handleCommandClientInit(Command &cmd) { this->crypto.client_init = true; this->connection->acknowledge_handler.reset(); @@ -63,22 +63,22 @@ CommandResult VoiceClient::handleCommandClientInit(Command &cmd) { int securityLevel; if(!calculate_security_level(securityLevel, this->crypto.remote_key.get(), cmd["client_key_offset"])) { logError(this->getServerId(), "[{}] Failed to calculate security level. Error code: {}", CLIENT_STR_LOG_PREFIX, securityLevel); - return {ErrorType::VSError}; + return command_result{error::vs_critical}; } if(securityLevel < 8) - return {findError("channel_invalid_security_hash"), "cant calculate security level"}; + return command_result{error::client_could_not_validate_identity}; auto requiredLevel = this->getServer()->properties()[property::VIRTUALSERVER_NEEDED_IDENTITY_SECURITY_LEVEL].as(); - if(securityLevel < requiredLevel) return {findError("client_could_not_validate_identity"), to_string(requiredLevel)}; + if(securityLevel < requiredLevel) return command_result{error::client_could_not_validate_identity, to_string(requiredLevel)}; } this->lastPingResponse = std::chrono::system_clock::now(); return SpeakingClient::handleCommandClientInit(cmd); } -CommandResult VoiceClient::handleCommandClientDisconnect(Command& cmd) { +command_result VoiceClient::handleCommandClientDisconnect(Command& cmd) { auto reason = cmd["reasonmsg"].size() > 0 ? cmd["reasonmsg"].as() : ""; this->disconnect(VREASON_SERVER_LEFT, reason, nullptr, true); logMessage(this->getServerId(), "{} Got remote disconnect with the reason '{}'", CLIENT_STR_LOG_PREFIX, reason); - return CommandResult::Success; + return command_result{error::ok}; } \ No newline at end of file diff --git a/server/src/client/voice/VoiceClientHandschake.cpp b/server/src/client/voice/VoiceClientHandschake.cpp index 07f0562..3d14763 100644 --- a/server/src/client/voice/VoiceClientHandschake.cpp +++ b/server/src/client/voice/VoiceClientHandschake.cpp @@ -22,7 +22,7 @@ inline void generate_random(uint8_t *destination, size_t length) { *(destination++) = (uint8_t) rand(); } -ts::CommandResult VoiceClient::handleCommandClientInitIv(Command& command) { +ts::command_result VoiceClient::handleCommandClientInitIv(Command& command) { this->last_packet_handshake = system_clock::now(); if(this->state == ConnectionState::CONNECTED) { /* we've a reconnect */ @@ -31,13 +31,13 @@ ts::CommandResult VoiceClient::handleCommandClientInitIv(Command& command) { CLIENT_STR_LOG_PREFIX, duration_cast(system_clock::now() - this->lastPingResponse).count() ); - return CommandResult::Success; + return ts::command_result{error::ok}; } else if(!config::voice::allow_session_reinitialize) { logMessage(this->getServerId(), "{} Client initialized session reconnect and last ping response is older then 5 seconds ({}). Dropping attempt because its not allowed due to config settings", CLIENT_STR_LOG_PREFIX, duration_cast(system_clock::now() - this->lastPingResponse).count() ); - return CommandResult::Success; + return ts::command_result{error::ok}; } logMessage(this->getServerId(), "{} Client initialized reconnect and last ping response is older then 5 seconds ({}). Allowing attempt", CLIENT_STR_LOG_PREFIX, @@ -70,7 +70,7 @@ ts::CommandResult VoiceClient::handleCommandClientInitIv(Command& command) { /* normal TeamSpeak handling */ string clientAlpha = base64::decode(command["alpha"]); //random - if(clientAlpha.length() != 10) return {findError("parameter_invalid"), "Invalid alpha"}; + if(clientAlpha.length() != 10) return ts::command_result{error::parameter_invalid}; string clientOmega = base64::decode(command["omega"]); //The identity public key string ip = command["ip"]; @@ -85,7 +85,7 @@ ts::CommandResult VoiceClient::handleCommandClientInitIv(Command& command) { auto state = ecc_import((const unsigned char *) clientOmega.data(), clientOmega.length(), this->crypto.remote_key.get()); if(state != CRYPT_OK) { this->crypto.remote_key.reset(); - return {ts::findError("client_could_not_validate_identity"), error_to_string(state)}; + return ts::command_result{error::client_could_not_validate_identity}; } this->properties()[property::CLIENT_UNIQUE_IDENTIFIER] = base64::encode(digest::sha1(command["omega"].string())); @@ -115,7 +115,10 @@ ts::CommandResult VoiceClient::handleCommandClientInitIv(Command& command) { char signBuffer[signBufferLength]; prng_state prngState{}; memset(&prngState, 0, sizeof(prngState)); - if(ecc_sign_hash((u_char*) licenseHash.data(), licenseHash.length(), (u_char*) signBuffer, &signBufferLength, &prngState, find_prng("sprng"), this->getServer()->serverKey()) != CRYPT_OK) return {findError("vs_critical"), "Could not sign license!"}; + if(ecc_sign_hash((u_char*) licenseHash.data(), licenseHash.length(), (u_char*) signBuffer, &signBufferLength, &prngState, find_prng("sprng"), this->getServer()->serverKey()) != CRYPT_OK) { + logError(this->getServerId(), "Failed to sign crypto chain!"); + return ts::command_result{error::vs_critical}; + } auto proof = base64::encode(signBuffer, signBufferLength); Command initivexpand2("initivexpand2"); @@ -134,7 +137,10 @@ ts::CommandResult VoiceClient::handleCommandClientInitIv(Command& command) { debugMessage(this->getServerId(), "{} Got non client 3.1 protocol with build timestamp {}", CLIENT_STR_LOG_PREFIX, this->crypto.client_time); auto serverOmega = this->getServer()->publicServerKey(); - if(serverOmega.empty()) return {findError("vs_critical"), "Could not export public key!"}; + if(serverOmega.empty()) { + logError(this->getServerId(), "Failed to export server public key!"); + return ts::command_result{error::vs_critical};; + } { Command initivexpand("initivexpand"); @@ -155,17 +161,17 @@ ts::CommandResult VoiceClient::handleCommandClientInitIv(Command& command) { string error; if(!this->connection->getCryptHandler()->setupSharedSecret(this->crypto.alpha, this->crypto.beta, this->crypto.remote_key.get(), this->server->serverKey(), error)){ this->connection->getCryptHandler()->unblock(); - debugMessage(this->server->getServerId(), "Could not setup shared secret! (" + error + ")"); - return {findError("vs_critical"), "Could not setup shared secret"}; + logError(this->server->getServerId(), "Could not setup shared secret! (" + error + ")"); + return ts::command_result{error::vs_critical}; } this->connection->getCryptHandler()->unblock(); this->crypto.protocol_encrypted = true; } } - return CommandResult::Success; + return ts::command_result{error::ok}; } -ts::CommandResult VoiceClient::handleCommandClientEk(const std::unique_ptr& packet, Command& cmd) { +ts::command_result VoiceClient::handleCommandClientEk(const std::unique_ptr& packet, Command& cmd) { this->last_packet_handshake = system_clock::now(); debugMessage(this->getServerId(), "{} Got client ek!", CLIENT_STR_LOG_PREFIX); @@ -176,5 +182,5 @@ ts::CommandResult VoiceClient::handleCommandClientEk(const std::unique_ptrconnection->acknowledge_handler.reset(); this->crypto.protocol_encrypted = true; this->sendAcknowledge(packet->packetId()); //Send the encrypted acknowledge - return CommandResult::Success; + return ts::command_result{error::ok}; } \ No newline at end of file diff --git a/server/src/client/voice/VoiceClientPacketHandler.cpp b/server/src/client/voice/VoiceClientPacketHandler.cpp index d932567..c9e3470 100644 --- a/server/src/client/voice/VoiceClientPacketHandler.cpp +++ b/server/src/client/voice/VoiceClientPacketHandler.cpp @@ -3,7 +3,6 @@ #include #include #include "../web/WebClient.h" -#include "query/command2.h" #include "VoiceClient.h" using namespace std; @@ -18,28 +17,29 @@ void VoiceClient::handlePacketInit(const unique_ptr //TODO Packet handlers -> move back to voice manager? void VoiceClient::handlePacketCommand(const std::unique_ptr& packet) { std::unique_ptr command; + command_result result{}; try { command = make_unique(Command::parse(packet->data(), true, !ts::config::server::strict_ut8_mode)); } catch(std::invalid_argument& ex) { - this->notifyError({findError("parameter_convert"), ex.what()}); - return; - } catch(command_malformed_exception& ex) { - this->notifyError({findError("parameter_convert"), ex.what()}); - return; + result = command_result{error::parameter_convert, std::string{ex.what()}}; + goto handle_error; } catch(std::exception& ex) { - this->notifyError({findError("parameter_convert"), ex.what()}); - return; + result = command_result{error::parameter_convert, std::string{ex.what()}}; + goto handle_error; } if(command->command() == "clientek") { - auto result = this->handleCommandClientEk(packet, *command); - if(!result) - this->notifyError(result); + result = this->handleCommandClientEk(packet, *command); + if(result.error_code()) goto handle_error; } else if(command->command() == "clientinitiv") { - auto result = this->handleCommandClientInitIv(*command); - if(!result) - this->notifyError(result); + result = this->handleCommandClientInitIv(*command); + if(result.error_code()) goto handle_error; } else this->handleCommandFull(*command, true); + + return; + handle_error: + this->notifyError(result); + result.release_details(); } void VoiceClient::handlePacketPing(const std::unique_ptr& packet) { diff --git a/server/src/client/web/WebClient.cpp b/server/src/client/web/WebClient.cpp index 41ca675..06dcb6a 100644 --- a/server/src/client/web/WebClient.cpp +++ b/server/src/client/web/WebClient.cpp @@ -232,11 +232,11 @@ bool WebClient::closeConnection(const std::chrono::system_clock::time_point& tim return true; } -CommandResult WebClient::handleCommand(Command &command) { +command_result WebClient::handleCommand(Command &command) { if(this->connectionState() == ConnectionState::INIT_HIGH && this->handshake.state == HandshakeState::SUCCEEDED){ if(command.command() == "clientinit") { auto result = this->handleCommandClientInit(command); - if(!result) + if(result.error_code()) this->closeConnection(system_clock::now() + seconds(1)); return result; } @@ -624,7 +624,7 @@ bool WebClient::disconnect(const std::string &reason) { return this->closeConnection(system_clock::now() + seconds(1)); } -CommandResult WebClient::handleCommandClientInit(Command &command) { +command_result WebClient::handleCommandClientInit(Command &command) { return SpeakingClient::handleCommandClientInit(command); } diff --git a/server/src/client/web/WebClient.h b/server/src/client/web/WebClient.h index 40cb61c..0442082 100644 --- a/server/src/client/web/WebClient.h +++ b/server/src/client/web/WebClient.h @@ -109,8 +109,8 @@ namespace ts { protected: - CommandResult handleCommand(Command &command) override; - CommandResult handleCommandClientInit(Command &command) override; + command_result handleCommand(Command &command) override; + command_result handleCommandClientInit(Command &command) override; }; } } diff --git a/shared b/shared index 664b739..d42ec40 160000 --- a/shared +++ b/shared @@ -1 +1 @@ -Subproject commit 664b73910c99558f9ba14dd2f06dabe67b5f2f2a +Subproject commit d42ec40a58892f4c7ff1da6dd4e69df94e2aa848