Starting with 2006-10-30 anticheat release and R1Q2 server b6904+, the anticheat module has the ability to restrict cvars on the client. The file for configuring cvars is anticheat-cvars.txt which belongs in the mod dir and the format is as follows:
var_name operator valuelist default
(Remember, the white space is a TAB character, not spaces!)
Where:
var_name is the variable name, eg gl_modulate or cl_maxfps you wish to evaluate.
operator is one of the following operators:
== (is equal to, numeric)
!= (is not equal to, numeric)
> (greater than)
< (less than)
>= (greater than or equal to)
<= (less than or equal to)
eq (is equal to, case-insensitive string)
ne (is not equal to, case-insensitive string)
~ (contains, case-insensitive string)
valuelist is a list of comma-separated values to test on. Usually you will just want one value here since most of the operators only expect one.
default is the default value to use if the client cvar value matches the expression. The default is only used on connecting, further cvar changes which match the expression will simply be ignored.
You may have multiple lines for the same cvar; they will be evaluated from top to bottom, so the last expression which evaluates successfully will have its default value set.
Now, you're probably quite confused, so here's a ton of examples to get you going:
gl_modulate > 2 1
This will stop gl_modulate from being set higher than 2. If the client connects with an invalid value (eg, gl_modulate 10), they will be reset to gl_modulate 1.
gl_modulate != 2 2
This forces gl_modulate 2 on every client.
rate < 5000 5000
rate > 15000 15000
This will limit rate between 5000 and 15000.
skin ne male/grunt male/grunt
This will prevent clients from changing skin to anything other than male/grunt.
name ~ fark Player
Prevent anyone from changing their name to anything containing "fark". If they connect with an invalid name, reset it to "Player".
fov != 90,110,120 90
This shows the use of multiple values in a single expression. This means the client has to be using fov 90, 110 or 120. If they are not, they will be reset to fov 90 on connecting.
skin ne male/grunt,female/athena,cyborg/terminator male/grunt
Again showing multiple values, the client must be using one of the listed skins. If not, they will be reset to male/grunt.
skin eq female/athena female/brianna
The eq operator and == act differently to the others, since they are inclusive rather than exclusive. The above example means the client will not be allowed to use the female/athena skin. If they connect with it, they will be reset to female/brianna. Any other skin value is permitted.
fov == 121,122 120
A silly example that will allow any fov except 121 and 122.
The anticheat server will disconnect your Q2 server if it has problems understanding an expression. Be careful not to specify a default value that would match any other expressions, including the one just evaluated. Don't do something stupid, like specify a value list with >=, <, etc where it makes no sense to do so. Keep your defaults as safe as possible - remember, default values will only be used if the client connects with something invalid. Once connected, attempting to change a cvar to something that matches an expression will simply be ignored.
Also be aware how Q2 handles cvars internally - there are three ways a cvar is used - either its string value, its float value or its integer value. The anticheat right now only supports string and float matching (an integer op may be added later if the need arises). This means if you try to lock down a discrete integer value using ==, it may be possible to bypass by specifying it as a float. As in the last example above, only fov 121 and 122 are blocked. A client can still use fov 121.001 and likely get the same effect as fov 121. This shouldn't really be a problem since == has limited usefulness anyway.
To make managing cvar enforcements easier, it is possible to split the anticheat-cvars.txt into multiple files by using the \include directive. For example, if you stored your video-related cvars in video-cvars.txt and sound-related cvars in sound-cvars.txt, your anticheat-cvars.txt could look like this:
\include video-cvars.txt
\include sound-cvars.txt
Included files may themselves include other files. There is no recursion checking, so be careful not to get into an include loop! Included files are searched using the standard Quake II path searching, so if the file does not exist in the mod dir, it may be read from baseq2.
Another note, a string interpreted as a float or integer is always 0. Eg, gl_modulate "foo" is the same as gl_modulate 0 when an expression is matched.
Any questions, suggestions or bug reports, please post!