Admin System (AMX Mod X Port)
NodeMod includes a complete port of the AMX Mod X admin system, rewritten in TypeScript. This provides familiar functionality for Half-Life server administrators while leveraging modern JavaScript/TypeScript development patterns.
Overview
The admin system provides:
- Player authentication via SteamID, IP address, or name
- Permission-based access control using flag system
- Admin commands (kick, ban, slay, slap, map changes, etc.)
- Voting system for player-initiated votes
- Slot reservation for admin priority
- Admin chat with private and team messaging
- Pluggable storage backends (file-based or SQL)
Quick Start
1. Configure Admin Users
Edit addons/nodemod/configs/users.ini:
; Format: "auth" "password" "access_flags" "account_flags"
; SteamID-based admin (no password required)
"STEAM_0:0:123456" "" "abcdefghij" "ce"
; IP-based admin
"192.168.1.100" "" "bcde" "de"
; Name-based admin with password
"AdminName" "secretpass" "abcdefghij" "a"
2. Load Admin Plugins
Edit addons/nodemod/configs/plugins.ini:
; Admin Base - Always one has to be activated
admin ; admin base (required for any admin-related)
;admin_sql ; admin base - SQL version (comment admin)
; Basic
admincmd ; basic admin console commands
adminhelp ; help command for admin console commands
adminslots ; slot reservation
multilingual ; Multi-Lingual management
; Menus
menufront ; front-end for admin menus
cmdmenu ; command menu (speech, settings)
plmenu ; players menu (kick, ban, client cmds.)
mapsmenu ; maps menu (vote, changelevel)
pluginmenu ; Menus for commands/cvars organized by plugin
; Chat / Messages
adminchat ; console chat commands
antiflood ; prevent clients from chat-flooding the server
scrollmsg ; displays a scrolling message
imessage ; displays information messages
adminvote ; vote commands
; Map related
nextmap ; displays next map in mapcycle
mapchooser ; allows to vote for next map
timeleft ; displays time left on map
; Configuration
pausecfg ; allows to pause and unpause some plugins
statscfg ; allows to manage stats plugins via menu and commands
Understanding Access Flags
AMX Mod X uses two separate flag systems that share the same letters (a-z) but have different meanings:
Access Flags (Column 3) - What Admins Can Do
| Flag | Constant | Permission |
|---|---|---|
| a | ADMIN_IMMUNITY | Cannot be kicked/banned by other admins |
| b | ADMIN_RESERVATION | Reserved slot access |
| c | ADMIN_KICK | Can kick players |
| d | ADMIN_BAN | Can ban players |
| e | ADMIN_SLAY | Can slay/slap players |
| f | ADMIN_MAP | Can change maps |
| g | ADMIN_CVAR | Can change server CVARs |
| h | ADMIN_CFG | Can execute config files |
| i | ADMIN_CHAT | Can use admin chat (@, amx_say) |
| j | ADMIN_VOTE | Can use voting commands |
| k | ADMIN_PASSWORD | Can set server password |
| l | ADMIN_RCON | RCON-level access |
| m-t | ADMIN_LEVEL_A-H | Custom access levels |
| u | ADMIN_MENU | Menu access |
| z | ADMIN_USER | Non-admin user flag |
Account Flags (Column 4) - How Admins Authenticate
| Flag | Constant | Meaning |
|---|---|---|
| a | FLAG_KICK | Kick on invalid password |
| b | FLAG_TAG | Auth is a clan tag (partial match) |
| c | FLAG_AUTHID | Auth is a SteamID |
| d | FLAG_IP | Auth is an IP address |
| e | FLAG_NOPASS | No password required |
| k | FLAG_CASE_SENSITIVE | Name/tag is case sensitive |
Example Configurations
; Full admin via SteamID, no password
"STEAM_0:0:123456" "" "abcdefghijklmnop" "ce"
; Moderator (kick/ban only) via IP
"192.168.1.50" "" "cd" "de"
; VIP with reserved slot via clan tag
"[VIP]" "" "b" "be"
; Admin with password requirement
"SuperAdmin" "mypassword" "abcdefghij" "a"
Available Commands
Admin Commands (admincmd)
| Command | Access | Description |
|---|---|---|
amx_kick <player> [reason] | ADMIN_KICK | Kick a player |
amx_ban <player> <minutes> [reason] | ADMIN_BAN | Ban a player |
amx_banip <player> <minutes> [reason] | ADMIN_BAN | Ban by IP address |
amx_slay <player> | ADMIN_SLAY | Kill a player |
amx_slap <player> [damage] | ADMIN_SLAY | Slap a player |
amx_map <mapname> | ADMIN_MAP | Change map |
amx_cvar <cvar> [value] | ADMIN_CVAR | Get/set CVAR |
amx_rcon <command> | ADMIN_RCON | Execute RCON command |
amx_cfg <filename> | ADMIN_CFG | Execute config file |
Chat Commands (adminchat)
| Command | Access | Description |
|---|---|---|
@ <message> | ADMIN_CHAT | Admin-only chat |
@@ <message> | ADMIN_CHAT | Admin-only anonymous chat |
amx_say <message> | ADMIN_CHAT | Broadcast to all players |
amx_psay <player> <message> | ADMIN_CHAT | Private message to player |
amx_tsay <color> <message> | ADMIN_CHAT | Colored HUD message |
amx_csay <message> | ADMIN_CHAT | Center screen message |
Help Commands (adminhelp)
| Command | Access | Description |
|---|---|---|
amx_help [page] | ADMIN_USER | List available commands |
Voting Commands (adminvote)
| Command | Access | Description |
|---|---|---|
amx_vote <question> <answer1> <answer2> | ADMIN_VOTE | Start a vote |
amx_votemap <map1> [map2] [map3] [map4] | ADMIN_VOTE | Vote for map change |
amx_votekick <player> | ADMIN_VOTE | Vote to kick player |
amx_voteban <player> | ADMIN_VOTE | Vote to ban player |
Storage Backends
The admin system supports pluggable storage for admin accounts.
File Storage (Default)
Uses configs/users.ini. No additional configuration needed.
SQL Storage
Requires the knex npm package. Configure in configs/sql.cfg:
amx_sql_type "mysql"
amx_sql_host "127.0.0.1"
amx_sql_user "root"
amx_sql_pass "password"
amx_sql_db "nodemod"
amx_sql_table "admins"
Switch to SQL storage:
amx_storage_use sql
Custom Storage
Implement the StorageAdapter interface:
import { storage, StorageAdapter, StorageConfig, StorageEntry } from './admin/storage';
class MyCustomAdapter implements StorageAdapter {
name = 'custom';
description = 'My custom storage backend';
isAvailable(): boolean {
return true;
}
async initialize(config: StorageConfig): Promise<void> {
// Setup your storage connection
}
async load(): Promise<StorageEntry[]> {
// Load and return all admin entries
return [];
}
async save(entry: StorageEntry): Promise<boolean> {
// Save an admin entry
return true;
}
async exists(key: string, value: string): Promise<boolean> {
// Check if entry exists
return false;
}
async clear(): Promise<void> {
// Clear all entries
}
async dispose(): Promise<void> {
// Cleanup connections
}
}
// Register your adapter
storage.register(new MyCustomAdapter());
Configuration CVARs
Configure admin behavior in configs/amxx.cfg:
// Authentication mode (0=disabled, 1=normal, 2=strict)
amx_mode 1
// Password field in client info
amx_password_field "_pw"
// Default access for non-admins
amx_default_access ""
// Admin activity display (0=none, 1=admins only, 2=all)
amx_show_activity 2
// Voting settings
amx_vote_ratio 0.02
amx_vote_time 10
amx_vote_delay 60
amx_votekick_ratio 0.40
amx_voteban_ratio 0.40
amx_votemap_ratio 0.40
Creating Admin Plugins
See the Admin Plugin Development Guide for information on creating custom admin plugins.