if(strstrofs(l, strcat(" ", vote_command, " "), 0) >= 0)
return TRUE;
- // if gotomap is allowed, chmap is too, and vice versa
- if(vote_command == "gotomap")
- if(strstrofs(l, " chmap ", 0) >= 0)
- return TRUE;
-
- if(vote_command == "chmap")
- if(strstrofs(l, " gotomap ", 0) >= 0)
- return TRUE;
-
return FALSE;
}
return validated_map;
}
-float VoteCommand_parse(entity caller, string vote_command, string vote_list, float startpos, float argc)
+float VoteCommand_checkargs(float startpos, float argc)
{
- string first_command;
-
- first_command = argv(startpos);
+ float p, q, check, minargs;
+ string cvarname = strcat("sv_vote_command_restriction_", argv(startpos));
+ string cmdrestriction = cvar_string(cvarname); // note: this warns on undefined cvar. We want that.
+ string charlist, arg;
+ float checkmate;
- if not(VoteCommand_checkinlist(first_command, vote_list))
+ if(cmdrestriction == "")
+ return TRUE;
+
+ ++startpos; // skip command name
+
+ // check minimum arg count
+
+ // 0 args: argc == startpos
+ // 1 args: argc == startpos + 1
+ // ...
+
+ minargs = stof(cmdrestriction);
+ if(argc - startpos < minargs)
return FALSE;
- if(argc < startpos) // These commands won't work without arguments
+ p = strstrofs(cmdrestriction, ";", 0); // find first semicolon
+
+ for(;;)
{
- switch(first_command)
+ // we know that at any time, startpos <= argc - minargs
+ // so this means: argc-minargs >= startpos >= argc, thus
+ // argc-minargs >= argc, thus minargs <= 0, thus all minargs
+ // have been seen already
+
+ if(startpos >= argc) // all args checked? GOOD
+ break;
+
+ if(p < 0) // no more args? FAIL
{
- case "map":
- case "chmap":
- case "gotomap":
- case "kick":
- case "kickban":
- return FALSE;
-
- default: { break; }
+ // exception: exactly minargs left, this one included
+ if(argc - startpos == minargs)
+ break;
+
+ // otherwise fail
+ return FALSE;
+ }
+
+ // cut to next semicolon
+ q = strstrofs(cmdrestriction, ";", p+1); // find next semicolon
+ if(q < 0)
+ charlist = substring(cmdrestriction, p+1, -1);
+ else
+ charlist = substring(cmdrestriction, p+1, q - (p+1));
+
+ // in case we ever want to allow semicolons in VoteCommand_checknasty
+ // charlist = strreplace("^^", ";", charlist);
+
+ if(charlist != "")
+ {
+ // verify the arg only contains allowed chars
+ arg = argv(startpos);
+ checkmate = strlen(arg);
+ for(check = 0; check < checkmate; ++check)
+ if(strstrofs(charlist, substring(arg, check, 1), 0) < 0)
+ return FALSE; // not allowed character
+ // all characters are allowed. FINE.
}
+
+ ++startpos;
+ --minargs;
+ p = q;
}
+
+ return TRUE;
+}
+
+float VoteCommand_parse(entity caller, string vote_command, string vote_list, float startpos, float argc)
+{
+ string first_command;
+ first_command = argv(startpos);
+
+ if not(VoteCommand_checkinlist(first_command, vote_list))
+ return FALSE;
+
+ if not(VoteCommand_checkargs(startpos, argc))
+ return FALSE;
+
switch(first_command) // now go through and parse the proper commands to adjust as needed.
{
case "kick":