Difference between revisions of "Security Levels"
Shadlington (Talk | contribs) (→Features) |
|||
(13 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
{{Build | {{Build | ||
− | |Version = | + | |Version = 1865 |
}} | }} | ||
<onlyinclude> | <onlyinclude> | ||
Line 9: | Line 9: | ||
=Basics= | =Basics= | ||
− | <p>The contents of the file <code> | + | <p>The contents of the file <code>autoconfig.cfg</code> in <code>kagServer</code> (where kagServer is the path to the kagServer's directory) should look something like this:</p> |
− | < | + | <syntaxhighlight lang="ini" enclose="div"> |
− | # Security | + | security_whitelist_active = 0 # Set to 1 to allow only the names in the whitelist or 0 to disallow the names in the blacklist |
+ | security_whitelist = ../Security/whitelist.cfg # The file with the whitelist config | ||
+ | security_blacklist = ../Security/blacklist.cfg # The file with the blacklist config | ||
+ | security_ignorelist = ../Security/ignorelist.cfg # The file with the ignorelist config | ||
+ | security_seclevs = ../Security/seclevs.cfg # The file with the seclev config | ||
+ | </syntaxhighlight> | ||
− | + | <p>The contents of the file defined by <code>seclevs.cfg</code> in <code>kagServer/Security</code> should look something like this (with additional commenting):</p> | |
− | + | ||
− | + | ||
− | + | ||
− | + | <syntaxhighlight lang="ini" enclose="div"> | |
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
− | + | ||
# If 0, defers to hardcoded settings | # If 0, defers to hardcoded settings | ||
levels_active = 1 | levels_active = 1 | ||
− | # | + | # The default level (that users will be assigned if they do not match any of the other levels) is the last one in this list. |
− | levels_files = Security/superadmin.cfg; Security/admin.cfg; Security/guard.cfg; Security/vip.cfg; Security/premium.cfg; Security/normal.cfg; | + | levels_files = ../Security/superadmin.cfg; ../Security/admin.cfg; ../Security/guard.cfg; ../Security/vip.cfg; ../Security/premium.cfg; ../Security/normal.cfg; |
− | </ | + | </syntaxhighlight> |
<p>If you set levels_active to 0 or the file is otherwise missing/unreadable, then [[#Default Levels|default, hardcoded seclevs]] will be loaded for you.</p> | <p>If you set levels_active to 0 or the file is otherwise missing/unreadable, then [[#Default Levels|default, hardcoded seclevs]] will be loaded for you.</p> | ||
Line 39: | Line 35: | ||
<p>The contents of one of the files defined by levels_files should look something like this (all lists are semi-colon-delimited):</p> | <p>The contents of one of the files defined by levels_files should look something like this (all lists are semi-colon-delimited):</p> | ||
− | < | + | <syntaxhighlight lang="ini" enclose="div"> |
name = Name of the seclev | name = Name of the seclev | ||
users = usernames; go; here; | users = usernames; go; here; | ||
Line 46: | Line 42: | ||
features = features; go; here; | features = features; go; here; | ||
assign = seclevs; go; here; | assign = seclevs; go; here; | ||
− | </ | + | </syntaxhighlight> |
− | <p>The name variable simply provides the human-readable name of the seclev.</p> | + | <p>The <code>name</code> variable simply provides the human-readable name of the seclev.</p> |
− | <p>The users list defines usernames that will match to this seclev (if they haven't already matched to a seclev higher up the list).</p> | + | <p>The <code>users</code> list defines usernames that will match to this seclev (if they haven't already matched to a seclev higher up the list).</p> |
− | <p>The [[#Roles|roles | + | <p>The [[#Roles|roles]] list defines roles that will match to this seclev (if they haven't already matched to a seclev higher up the list).</p> |
− | <p>The [[#Commands|commands | + | <p>The [[#Commands|commands]] list defines the rcon commands that players matching this seclev have access to.</p> |
− | <p>The [[#Features|features | + | <p>The [[#Features|features]] list defines the seclev-controlled features that players matching this seclev have access to.</p> |
− | <p>The [[#Assign|assign | + | <p>The [[#Assign|assign]] list defines the seclevs that players matching this seclev are able to assign other players to/from.</p> |
Line 73: | Line 69: | ||
<p>The commands list defines the rcon commands that players matching this seclev have access to.</p> | <p>The commands list defines the rcon commands that players matching this seclev have access to.</p> | ||
<p>For example, to enable the rcon command /kick, used for kicking players from the game, you would add 'kick' to the commands list</p> | <p>For example, to enable the rcon command /kick, used for kicking players from the game, you would add 'kick' to the commands list</p> | ||
− | <p>There is one special keyword used for enabling all rcon commands at once - 'ALL'. So in this case your commands list would look like: < | + | <p>There is one special keyword used for enabling all rcon commands at once - 'ALL'. So in this case your commands list would look like: <syntaxhighlight lang="ini" enclose="div">commands = ALL;</syntaxhighlight></p> |
<p>Scripting commands (like waterLevel()) are not compatible with this system - if you want to use them you must have a seclev with the ALL keyword in its commands list</p> | <p>Scripting commands (like waterLevel()) are not compatible with this system - if you want to use them you must have a seclev with the ALL keyword in its commands list</p> | ||
<p>A full list of available rcon commands can be found [[Commands|here]].</p> | <p>A full list of available rcon commands can be found [[Commands|here]].</p> | ||
Line 99: | Line 95: | ||
|- | |- | ||
| deny_join | | deny_join | ||
− | | Player is banned on the server. Works well as a replacement for whitelists (see advanced usage). | + | | Player is banned on the server. Works well as a replacement for whitelists (see [[#Advanced Usage|advanced usage]]). |
|- | |- | ||
| editor | | editor | ||
Line 106: | Line 102: | ||
| freeze_immunity | | freeze_immunity | ||
| Freeze immunity. | | Freeze immunity. | ||
+ | |- | ||
+ | | ignore_immunity | ||
+ | | Ignore immunity. | ||
|- | |- | ||
| invincible | | invincible | ||
Line 128: | Line 127: | ||
| Able to mark players to be kicked. | | Able to mark players to be kicked. | ||
|- | |- | ||
− | | | + | | mute_immunity |
− | | | + | | Mute immunity. |
|- | |- | ||
| name_mouseover | | name_mouseover | ||
| Can see player names when hovering cursor above them. | | Can see player names when hovering cursor above them. | ||
|- | |- | ||
− | | | + | | name_mouseover_spectator |
− | | | + | | Can see player names when hovering cursor above them when in spectator. |
− | + | ||
− | + | ||
− | + | ||
|- | |- | ||
| pingkick_immunity | | pingkick_immunity | ||
Line 151: | Line 147: | ||
| spectator | | spectator | ||
| Use of spectator mode. | | Use of spectator mode. | ||
+ | |- | ||
+ | | speedkick_immunity | ||
+ | | Speedhack kick immunity (this is a temporary fix to work around modded servers that have speeded-up their classes in such a way that the speedhack detection gets false positives) | ||
|- | |- | ||
| view_collapses | | view_collapses | ||
Line 160: | Line 159: | ||
| view_rcon | | view_rcon | ||
| Can view non-silent rcon activity. | | Can view non-silent rcon activity. | ||
+ | |- | ||
+ | | vote_cancel | ||
+ | | Enables the ability to cancel vote-kicks. | ||
|- | |- | ||
|} | |} | ||
Line 167: | Line 169: | ||
<p>The assign list defines the seclevs that players matching this seclev are able to assign other players to/from.</p> | <p>The assign list defines the seclevs that players matching this seclev are able to assign other players to/from.</p> | ||
<p>A player is able to assign another player a seclev via /rcon /assignseclev [playername] [seclev ID] if they have the name of both that other user's current seclev and the seclev they wish to assign them in their own seclev's assign list. Seclev ID is a number that (should) correspond to the seclev's position in the seclev list, where the first is 0, the second is 1, etc. Use /rcon /printseclevs to see the seclev's with their IDs.</p> | <p>A player is able to assign another player a seclev via /rcon /assignseclev [playername] [seclev ID] if they have the name of both that other user's current seclev and the seclev they wish to assign them in their own seclev's assign list. Seclev ID is a number that (should) correspond to the seclev's position in the seclev list, where the first is 0, the second is 1, etc. Use /rcon /printseclevs to see the seclev's with their IDs.</p> | ||
− | + | <p>You are also able to use /assignseclevid [player ID] [seclev ID], and you should grant access to this command if you want to make use of the admin menu for seclev assignment, as the menus use this command.</p> | |
=Advanced Usage= | =Advanced Usage= | ||
Line 174: | Line 176: | ||
<p>To do this, first ensure that none of your non-admin levels have 'login' in their commands list. Then add 'login' (or 'ALL') to your lower-level admin seclev and make sure that it is assigned to your administrators by adding their names to the users list. Also ensure that your higher-level admin seclev is not assigned to your administrators by name but is assigned to the 'rcon' role and that it has 'logout' (or 'ALL') in its commands list.</p> | <p>To do this, first ensure that none of your non-admin levels have 'login' in their commands list. Then add 'login' (or 'ALL') to your lower-level admin seclev and make sure that it is assigned to your administrators by adding their names to the users list. Also ensure that your higher-level admin seclev is not assigned to your administrators by name but is assigned to the 'rcon' role and that it has 'logout' (or 'ALL') in its commands list.</p> | ||
<p>Now when your administrators join your server they will have access to all their normal admin powers by default, but will be able to go up a level by logging into rcon (and back down again by using /rcon /logout). As they are the only ones with access to /login you can safely keep the password very easy to remember, too. You may find it useful to include features that you would only want to have active temporarily in this higher admin level - like invincibility.</p> | <p>Now when your administrators join your server they will have access to all their normal admin powers by default, but will be able to go up a level by logging into rcon (and back down again by using /rcon /logout). As they are the only ones with access to /login you can safely keep the password very easy to remember, too. You may find it useful to include features that you would only want to have active temporarily in this higher admin level - like invincibility.</p> | ||
− | + | ||
+ | |||
<p>You are able to use seclevs in place of the whitelist by making use of the deny_join feature. By making your default seclev deny_join you have to explicitly add people to other seclevs without deny_join in order to grant access - essentially performing the same function as the whitelist. This is actually advised in preference to a whitelist as it has several benefits, including: allowing easy removal of people from the whitelist using in-game seclev assignment, not having to spread lists of players between the whitelist and seclevs and allowing the blacklist to be used at the same time so that temporary bans can be issued to your 'whitelisted' players if they break rules, without having to outright remove them from the list.</p> | <p>You are able to use seclevs in place of the whitelist by making use of the deny_join feature. By making your default seclev deny_join you have to explicitly add people to other seclevs without deny_join in order to grant access - essentially performing the same function as the whitelist. This is actually advised in preference to a whitelist as it has several benefits, including: allowing easy removal of people from the whitelist using in-game seclev assignment, not having to spread lists of players between the whitelist and seclevs and allowing the blacklist to be used at the same time so that temporary bans can be issued to your 'whitelisted' players if they break rules, without having to outright remove them from the list.</p> | ||
+ | |||
=Default Levels= | =Default Levels= | ||
The default, hardcoded levels are equivalent to the following security level files: | The default, hardcoded levels are equivalent to the following security level files: | ||
− | + | ==superadmin.cfg== | |
− | < | + | <syntaxhighlight lang="ini" enclose="div"> |
− | name = | + | name = Super Admin |
users = | users = | ||
roles = rcon; | roles = rcon; | ||
commands = ALL; | commands = ALL; | ||
− | features = admin_color; always_change_team; ban_immunity; editor; join_full; kick_immunity; map_vote; mark_any_team; mark_player; name_mouseover; pingkick_immunity; silent_rcon; skip_votewait; spectator; view_collapses; view_console; view_rcon; | + | features = admin_color; always_change_team; ban_immunity; editor; freeze_immunity; ignore_immunity; join_full; kick_immunity; map_vote; mark_any_team; mark_player; mute_immunity; name_mouseover; pingkick_immunity; silent_rcon; skip_votewait; spectator; view_collapses; view_console; view_rcon; |
− | </ | + | assign = admin; vip; normal; premium; |
− | + | </syntaxhighlight> | |
− | < | + | ==admin.cfg== |
− | name = | + | <syntaxhighlight lang="ini" enclose="div"> |
+ | name = Admin | ||
users = | users = | ||
roles = kagstaff; | roles = kagstaff; | ||
− | commands = ban; banhost; banid; freezeid; help; kick; kickhid; kickhost; kickid; listbans; login; msg; nextmap; players; restartmap; swapid; unban; unbanhost; unfreezeid; | + | commands = assignseclev; assignseclevid; ban; banhost; banid; freezeid; help; kick; kickhid; kickhost; kickid; list; listbans; login; msg; mute; muteid; nextmap; players; printseclevs; restartmap; swapid; unban; unbanhost; unfreezeid; unmute; unmuteid; |
− | features = always_change_team; ban_immunity; join_full; kick_immunity; map_vote; mark_any_team; mark_player; name_mouseover; pingkick_immunity; skip_votewait; spectator; view_collapses; view_rcon; | + | features = always_change_team; ban_immunity; freeze_immunity; ignore_immunity; join_full; kick_immunity; map_vote; mark_any_team; mark_player; mute_immunity; name_mouseover; pingkick_immunity; skip_votewait; spectator; view_collapses; view_rcon; |
− | </ | + | assign = vip; normal; premium; |
− | + | </syntaxhighlight> | |
− | < | + | ==guard.cfg== |
+ | <syntaxhighlight lang="ini" enclose="div"> | ||
name = Guard | name = Guard | ||
users = | users = | ||
roles = guard; | roles = guard; | ||
− | commands = ban; banhost; banid; freezeid; help; kick | + | commands = ban; banhost; banid; freezeid; help; kick; kickhost; kickid; list; listbans; login; mute; muteid; players; swapid; unban; unbanhost; unfreezeid; unmute; unmuteid; |
− | features = always_change_team; join_full; map_vote; mark_any_team; mark_player; name_mouseover; pingkick_immunity; skip_votewait; spectator; view_collapses; | + | features = always_change_team; freeze_immunity; ignore_immunity; join_full; map_vote; mark_any_team; mark_player; mute_immunity; name_mouseover; pingkick_immunity; skip_votewait; spectator; view_collapses; |
− | </ | + | assign = |
− | + | </syntaxhighlight> | |
− | < | + | ==vip.cfg== |
+ | <syntaxhighlight lang="ini" enclose="div"> | ||
+ | name = VIP | ||
+ | users = | ||
+ | roles = | ||
+ | commands = help; login; | ||
+ | features = freeze_immunity; join_reserved; map_vote; mark_any_team; mark_player; pingkick_immunity; skip_votewait; spectator; | ||
+ | assign = | ||
+ | </syntaxhighlight> | ||
+ | ==premium.cfg== | ||
+ | <syntaxhighlight lang="ini" enclose="div"> | ||
+ | name = Premium | ||
+ | users = | ||
+ | roles = premium; | ||
+ | commands = help; login; | ||
+ | features = map_vote; mark_player; spectator; | ||
+ | assign = | ||
+ | </syntaxhighlight> | ||
+ | ==normal.cfg== | ||
+ | <syntaxhighlight lang="ini" enclose="div"> | ||
name = Normal | name = Normal | ||
users = | users = | ||
Line 211: | Line 236: | ||
commands = help; login; | commands = help; login; | ||
features = map_vote; mark_player; spectator; | features = map_vote; mark_player; spectator; | ||
− | </ | + | assign = |
+ | </syntaxhighlight> |
Latest revision as of 21:27, 8 December 2017
King Arthur's Gold uses a system called 'Security Levels' (or 'seclevs' for short) to manage player access to various features on its servers. There are default, hardcoded levels setup but it is strongly advised that server owners take the time to setup their own specific seclev definitions.
Contents
Basics
The contents of the file autoconfig.cfg
in kagServer
(where kagServer is the path to the kagServer's directory) should look something like this:
security_whitelist = ../Security/whitelist.cfg # The file with the whitelist config
security_blacklist = ../Security/blacklist.cfg # The file with the blacklist config
security_ignorelist = ../Security/ignorelist.cfg # The file with the ignorelist config
security_seclevs = ../Security/seclevs.cfg # The file with the seclev config
The contents of the file defined by seclevs.cfg
in kagServer/Security
should look something like this (with additional commenting):
levels_active = 1
# The default level (that users will be assigned if they do not match any of the other levels) is the last one in this list.
levels_files = ../Security/superadmin.cfg; ../Security/admin.cfg; ../Security/guard.cfg; ../Security/vip.cfg; ../Security/premium.cfg; ../Security/normal.cfg;
If you set levels_active to 0 or the file is otherwise missing/unreadable, then default, hardcoded seclevs will be loaded for you.
levels_files should be a semi-colon-delimited list of files that define individual security levels. The ordering of this list matters for 2 reasons: 1) When users are being matched to a security level in order to determine their level of access, they will be matched to the first seclev in the list that matches either their username or their role. 2) When users do not match any security level they will be assigned to the last seclev in the list - this last level is essentially the default.
The contents of one of the files defined by levels_files should look something like this (all lists are semi-colon-delimited):
users = usernames; go; here;
roles = roles; go; here;
commands = rcon; commands; go; here;
features = features; go; here;
assign = seclevs; go; here;
The name
variable simply provides the human-readable name of the seclev.
The users
list defines usernames that will match to this seclev (if they haven't already matched to a seclev higher up the list).
The roles list defines roles that will match to this seclev (if they haven't already matched to a seclev higher up the list).
The commands list defines the rcon commands that players matching this seclev have access to.
The features list defines the seclev-controlled features that players matching this seclev have access to.
The assign list defines the seclevs that players matching this seclev are able to assign other players to/from.
If you make a change to your seclevs and want to reload the new configuration you can do so without restarting your server - just use /rcon /reloadseclevs (or /reloadsecurity) in the console (make sure you have access to that command in your seclev!
You can see all the currently loaded seclevs and who of the currently active players has been assigned to what seclev by using /rcon /printseclevs (you will need access to the command to use this, and access to the feature view_console to view the list)
A set of example seclev definition files has been included in your kagServer/Base/Security
directory, with the extension .cfg.example. If you make a copy of these files and remove the .example extensions you will be left with a good start point for building up your own definitions.
Roles
The roles list defines roles that will match to this seclev (if they haven't already matched to a seclev higher up the list).
Roles are special flags that define what kind of user a player is.
There are 4 available: premium (premium players), guard (KAG guards), kagstaff (KAG staff) and rcon (people logged into rcon).
So if you were to have 'roles = guard; kagstaff' in a seclev, then all KAG Guards and members of the KAG Team would be matched to that seclev, if they hadn't already matched a seclev higher up the list.
The only one that can change mid-game is rcon, which will be active when a player logs into rcon (/rcon /login [password]) and become inactive again when they logout (/rcon /logout).
Commands
The commands list defines the rcon commands that players matching this seclev have access to.
For example, to enable the rcon command /kick, used for kicking players from the game, you would add 'kick' to the commands list
There is one special keyword used for enabling all rcon commands at once - 'ALL'. So in this case your commands list would look like:
Scripting commands (like waterLevel()) are not compatible with this system - if you want to use them you must have a seclev with the ALL keyword in its commands list
A full list of available rcon commands can be found here.
Features
The features list defines the seclev-controlled features that players matching this seclev have access to.
Features are any game feature that has its access defined by seclevs - for example, the ability to join a server when it is full, or to use the map editor.
They are currently all positive buffs, but in the future some will be added that enforce restrictions (blocking access to a given class, for example).
Feature | Description |
---|---|
admin_color | Show admin names in the red/orange admin color. |
always_change_team | Able to change team regardless of (im)balance. |
ban_immunity | Ban immunity. |
deny_join | Player is banned on the server. Works well as a replacement for whitelists (see advanced usage). |
editor | Use of map editor. |
freeze_immunity | Freeze immunity. |
ignore_immunity | Ignore immunity. |
invincible | Player will be invincible. |
join_full | Join full server. |
join_reserved | Join if reserved slots free. [Not currently available] |
kick_immunity | Kick immunity. |
map_vote | Able to vote to go to next map. |
mark_any_team | Able to mark players on any team - still need mark_player. |
mark_player | Able to mark players to be kicked. |
mute_immunity | Mute immunity. |
name_mouseover | Can see player names when hovering cursor above them. |
name_mouseover_spectator | Can see player names when hovering cursor above them when in spectator. |
pingkick_immunity | Ping kick immunity. |
silent_rcon | Your rcon activity is not posted to the console of those that can view it. |
skip_votewait | Skip the wait required to vote/mark players. |
spectator | Use of spectator mode. |
speedkick_immunity | Speedhack kick immunity (this is a temporary fix to work around modded servers that have speeded-up their classes in such a way that the speedhack detection gets false positives) |
view_collapses | View who caused collapses. |
view_console | Can view server console messages in your own console. |
view_rcon | Can view non-silent rcon activity. |
vote_cancel | Enables the ability to cancel vote-kicks. |
Assign
The assign list defines the seclevs that players matching this seclev are able to assign other players to/from.
A player is able to assign another player a seclev via /rcon /assignseclev [playername] [seclev ID] if they have the name of both that other user's current seclev and the seclev they wish to assign them in their own seclev's assign list. Seclev ID is a number that (should) correspond to the seclev's position in the seclev list, where the first is 0, the second is 1, etc. Use /rcon /printseclevs to see the seclev's with their IDs.
You are also able to use /assignseclevid [player ID] [seclev ID], and you should grant access to this command if you want to make use of the admin menu for seclev assignment, as the menus use this command.
Advanced Usage
Because you can restrict access to every /rcon command, including /login itself, its possible to create two levels for your administrators that they can swap in and out of according to need.
To do this, first ensure that none of your non-admin levels have 'login' in their commands list. Then add 'login' (or 'ALL') to your lower-level admin seclev and make sure that it is assigned to your administrators by adding their names to the users list. Also ensure that your higher-level admin seclev is not assigned to your administrators by name but is assigned to the 'rcon' role and that it has 'logout' (or 'ALL') in its commands list.
Now when your administrators join your server they will have access to all their normal admin powers by default, but will be able to go up a level by logging into rcon (and back down again by using /rcon /logout). As they are the only ones with access to /login you can safely keep the password very easy to remember, too. You may find it useful to include features that you would only want to have active temporarily in this higher admin level - like invincibility.
You are able to use seclevs in place of the whitelist by making use of the deny_join feature. By making your default seclev deny_join you have to explicitly add people to other seclevs without deny_join in order to grant access - essentially performing the same function as the whitelist. This is actually advised in preference to a whitelist as it has several benefits, including: allowing easy removal of people from the whitelist using in-game seclev assignment, not having to spread lists of players between the whitelist and seclevs and allowing the blacklist to be used at the same time so that temporary bans can be issued to your 'whitelisted' players if they break rules, without having to outright remove them from the list.
Default Levels
The default, hardcoded levels are equivalent to the following security level files:
superadmin.cfg
users =
roles = rcon;
commands = ALL;
features = admin_color; always_change_team; ban_immunity; editor; freeze_immunity; ignore_immunity; join_full; kick_immunity; map_vote; mark_any_team; mark_player; mute_immunity; name_mouseover; pingkick_immunity; silent_rcon; skip_votewait; spectator; view_collapses; view_console; view_rcon;
assign = admin; vip; normal; premium;
admin.cfg
users =
roles = kagstaff;
commands = assignseclev; assignseclevid; ban; banhost; banid; freezeid; help; kick; kickhid; kickhost; kickid; list; listbans; login; msg; mute; muteid; nextmap; players; printseclevs; restartmap; swapid; unban; unbanhost; unfreezeid; unmute; unmuteid;
features = always_change_team; ban_immunity; freeze_immunity; ignore_immunity; join_full; kick_immunity; map_vote; mark_any_team; mark_player; mute_immunity; name_mouseover; pingkick_immunity; skip_votewait; spectator; view_collapses; view_rcon;
assign = vip; normal; premium;
guard.cfg
users =
roles = guard;
commands = ban; banhost; banid; freezeid; help; kick; kickhost; kickid; list; listbans; login; mute; muteid; players; swapid; unban; unbanhost; unfreezeid; unmute; unmuteid;
features = always_change_team; freeze_immunity; ignore_immunity; join_full; map_vote; mark_any_team; mark_player; mute_immunity; name_mouseover; pingkick_immunity; skip_votewait; spectator; view_collapses;
assign =
vip.cfg
users =
roles =
commands = help; login;
features = freeze_immunity; join_reserved; map_vote; mark_any_team; mark_player; pingkick_immunity; skip_votewait; spectator;
assign =
users =
roles = premium;
commands = help; login;
features = map_vote; mark_player; spectator;
assign =
normal.cfg
users =
roles =
commands = help; login;
features = map_vote; mark_player; spectator;
assign =