From e2034a51ef9fba57e5e26dc44c929035fb1caeb2 Mon Sep 17 00:00:00 2001 From: terencehill Date: Sun, 30 Jul 2023 10:47:24 +0200 Subject: [PATCH] Minigames: apply flood control only to common minigame commands since individual minigame commands shouldn't be limited for gameplay reasons --- qcsrc/common/minigames/sv_minigames.qc | 15 ++++++++------- qcsrc/common/minigames/sv_minigames.qh | 14 ++++++++++++++ qcsrc/server/command/cmd.qc | 14 ++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/qcsrc/common/minigames/sv_minigames.qc b/qcsrc/common/minigames/sv_minigames.qc index cb2beaa48..e1e6eec9e 100644 --- a/qcsrc/common/minigames/sv_minigames.qc +++ b/qcsrc/common/minigames/sv_minigames.qc @@ -304,7 +304,8 @@ bool MinigameImpulse(entity this, int imp) return false; } - +// this macro exists only to shorten code lines +#define MINIGAME_CMD(cmd_id) MINIGAME_COMMON_CMD[MINIGAME_COMMON_CMD_ID_##cmd_id] void ClientCommand_minigame(entity caller, int request, int argc, string command) { @@ -324,7 +325,7 @@ void ClientCommand_minigame(entity caller, int request, int argc, string command if (request == CMD_REQUEST_COMMAND ) { string minig_cmd = argv(1); - if ( minig_cmd == "create" && argc > 2 ) + if ( minig_cmd == MINIGAME_CMD(CREATE) && argc > 2 ) { entity minig = start_minigame(caller, argv(2)); if ( minig ) @@ -333,7 +334,7 @@ void ClientCommand_minigame(entity caller, int request, int argc, string command sprint(caller,"Cannot start minigame session!\n"); return; } - else if ( minig_cmd == "join" && argc > 2 ) + else if ( minig_cmd == MINIGAME_CMD(JOIN) && argc > 2 ) { entity minig = join_minigame(caller, argv(2)); if ( minig ) @@ -345,19 +346,19 @@ void ClientCommand_minigame(entity caller, int request, int argc, string command } return; } - else if ( minig_cmd == "list" ) + else if ( minig_cmd == MINIGAME_CMD(LIST) ) { FOREACH(Minigames, true, sprint(caller, it.netname, " (", it.message, ") ", "\n")); return; } - else if ( minig_cmd == "list-sessions" ) + else if ( minig_cmd == MINIGAME_CMD(LIST_SESSIONS) ) { entity e; for ( e = minigame_sessions; e != NULL; e = e.list_next ) sprint(caller,e.netname,"\n"); return; } - else if ( minig_cmd == "end" || minig_cmd == "part" ) + else if ( minig_cmd == MINIGAME_CMD(END) || minig_cmd == MINIGAME_CMD(PART) ) { if ( CS(caller).active_minigame ) { @@ -368,7 +369,7 @@ void ClientCommand_minigame(entity caller, int request, int argc, string command sprint(caller,"You aren't playing any minigame...\n"); return; } - else if ( minig_cmd == "invite" && argc > 2 ) + else if ( minig_cmd == MINIGAME_CMD(INVITE) && argc > 2 ) { if ( CS(caller).active_minigame ) { diff --git a/qcsrc/common/minigames/sv_minigames.qh b/qcsrc/common/minigames/sv_minigames.qh index 06f16a9dc..a6c774e6b 100644 --- a/qcsrc/common/minigames/sv_minigames.qh +++ b/qcsrc/common/minigames/sv_minigames.qh @@ -1,5 +1,19 @@ #pragma once +enum +{ + MINIGAME_COMMON_CMD_ID_CREATE, + MINIGAME_COMMON_CMD_ID_JOIN, + MINIGAME_COMMON_CMD_ID_LIST, + MINIGAME_COMMON_CMD_ID_LIST_SESSIONS, + MINIGAME_COMMON_CMD_ID_END, + MINIGAME_COMMON_CMD_ID_PART, + MINIGAME_COMMON_CMD_ID_INVITE, + MINIGAME_COMMON_CMD_COUNT +}; +string MINIGAME_COMMON_CMD[MINIGAME_COMMON_CMD_COUNT] = + {"create", "join", "list", "list-sessions", "end", "part", "invite"}; + bool autocvar_sv_minigames; bool autocvar_sv_minigames_observer; diff --git a/qcsrc/server/command/cmd.qc b/qcsrc/server/command/cmd.qc index f93880a68..057b45307 100644 --- a/qcsrc/server/command/cmd.qc +++ b/qcsrc/server/command/cmd.qc @@ -1025,6 +1025,19 @@ void SV_ParseClientCommand(entity this, string command) case "sentcvar": break; // handled by server in this file case "spawn": break; // handled by engine in host_cmd.c case "say": case "say_team": case "tell": break; // chat has its own flood control in chat.qc + case "minigame": // flood control only for common commands + string arg = argv(1); + if (arg == "") + goto flood_control; + for (int i = 0; i < MINIGAME_COMMON_CMD_COUNT; ++i) + { + if (MINIGAME_COMMON_CMD[i] == arg) + goto flood_control; + } + // if we get here we haven't found any common command, so no flood control for other commands + // individual minigame commands shouldn't be limited for gameplay reasons + // FIXME unknown/wrong minigame commands have no flood control + break; case "color": case "topcolor": case "bottomcolor": // handled by engine in host_cmd.c if(!IS_CLIENT(this)) // on connection { @@ -1041,6 +1054,7 @@ void SV_ParseClientCommand(entity this, string command) if(!IS_CLIENT(this)) break; // else fall through to default: flood control default: + LABEL(flood_control) if (!timeout_status) // not while paused { entity store = IS_CLIENT(this) ? CS(this) : this; // unfortunately, we need to store these on the client initially -- 2.39.2