PHP relay for nmrih-crosschat, the cross-server chat plugin for SourceMod servers.
The relay is a single self-contained PHP endpoint that buffers chat messages and serves them to every polling game server. It stores messages in a local JSON file with exclusive locking — no database, no Redis, no dependencies beyond PHP itself.
Data files carry a PHP guard prefix, so direct web access to them returns 404 regardless of web server configuration. The auth token is generated as a UUID v7 on first run and persisted automatically.
- PHP 8.5 or newer (enforced at runtime, older versions are rejected with HTTP 500)
- Download and extract the attached archive.
- Upload
api.phpandconfig.phpto any directory of your PHP host — the site root or any subdirectory both work. - Make sure the directory is writable by PHP (a
data/folder is created automatically next toapi.php). - Open the relay once in a browser, e.g.
https://your.domain/api.php— aninvalid tokenresponse confirms it is alive. - Read the generated token from
data/token.json.php(open the file on the server; a browser only shows 404) and set it assm_crosschat_tokenon every game server.
Optionally deny web access to the data/ directory at the web server level for defense in depth:
location /data/ {
return 404;
}All settings live in config.php:
return [
// Shared secret token. Leave empty to auto-generate a UUID v7 token:
// the relay creates data/token.json.php on first access; copy its value
// into sm_crosschat_token on every game server.
'token' => '',
// Maximum message length in characters (plugin truncates first, relay rejects larger)
'max_message_length' => 128,
// Maximum player name length in characters
'max_name_length' => 64,
// Maximum server id length in characters
'max_server_id_length' => 32,
// Seconds before messages expire from the buffer (must exceed fetch interval)
'message_retention' => 600,
// Hard cap of buffered messages (protects memory under flood)
'max_buffer_size' => 1000,
];You may set your own token instead of using the generated one — any string works, UUID v7 recommended.
The endpoint accepts POST or GET, form-encoded:
| Action | Parameters | Response |
|---|---|---|
send |
token, sid, name, auth, msg |
{"ok":true,"id":N} |
fetch |
token, sid, since |
{"ok":true,"last":N,"msgs":[{"i":N,"s":"S2","a":123,"n":"Name","m":"text"},...]} |
fetch returns only messages newer than since that were not sent by the requesting server itself. auth=0 marks a server console message; positive values are player Steam IDs.
HTTPS is strongly recommended — the token travels with every request. The plugin verifies certificates against the CA bundle shipped with the REST in Pawn extension.
The relay and the plugin share a protocol. Always deploy versions from the same release on both sides.
This project is licensed under the GPL-3.0 License.