The master list at mafiam.com/servers collects the servers that are online right now. It stores nothing beyond what a server itself answers to the launcher’s query: name, player count, game edition, season, tags and protocol version.
How a server gets on the list
- By itself. m2o_server sends
POST /api/announcewith its port every minute. This is on by default, see[master]below. - By address. Anyone can enter IP:port in the form on the Servers page.
Either way the master list sends that address the same UDP query the launcher uses (M2OQ + a token) and waits up to two seconds for M2OI. If the server answers, it is listed. From then on the master list polls it every 30 seconds.
- A server is online if it answered within the last 150 seconds.
- A server that has not answered for 7 days is removed.
- It needs a public IPv4 address and an open UDP port. LAN addresses (192.168.x.x, 10.x.x.x) are not accepted.
Settings in m2o_server.ini
[master] enabled=on ; off: not on the public list (LAN, testing) ;host=my.domain.com ; when players reach the server by another address (playit.gg, a domain)
On the command line: --master on|off. The console shows [master] on the public server list as … once the server is listed, otherwise the reason it is not.
POST/api/announce
Registration and heartbeat. The body is JSON (Content-Type: application/json) or a regular form.
| Field | Type | Description |
|---|---|---|
port | number | The server’s game port, the same as in m2o_server.ini. |
host | string | Optional. IPv4 or domain players use to reach the server. Without it, the IP the request came from is used. Needed for tunnels like playit.gg and for machines on IPv6. |
Send it to master.mafiam.com: that host has only an IPv4 address, so the request always arrives from the IPv4 address players will use, even on a machine with IPv6. mafiam.com answers too, but over IPv6 it needs host.
curl -X POST https://master.mafiam.com/api/announce \
-H "Content-Type: application/json" \
-d '{"port": 27015}'
Responses
| Code | error | Meaning |
|---|---|---|
200 | The server answered and is listed. The response carries server and interval: seconds until the next announce. | |
202 | Accepted, but the server did not answer right away (pending: true). The master list checks it again within 30 seconds. | |
400 | bad_port, bad_host, private_ip, ipv6 | Bad port, a domain without IPv4, a LAN address, or the request came over IPv6 without host. |
422 | no_answer | host was given, but the server did not answer there. Check that the UDP port is open. |
429 | rate_limit | More than 20 requests a minute from one IP. |
{
"ok": true,
"server": {
"address": "203.0.113.7:27015",
"name": "MafiaM server",
"players": 3,
"maxPlayers": 128,
"edition": "de",
"season": "summer",
"tags": ["RP", "Cars", "Mafia"],
"protocol": 26,
"online": true
},
"interval": 60
}
If you write your own announcer: the master list queries the server during the request, so do not block the thread that runs enet_host_service while waiting for the answer. m2o_server announces from a separate thread.
GET/api/servers
Servers online, most players first. Served with Access-Control-Allow-Origin: * and cached for 10 seconds. The launcher’s Internet tab takes its addresses from here and measures ping to each server itself with the same M2OQ.
| Parameter | Description |
|---|---|
all=1 | Also return servers seen in the last 7 days (online: false). |
edition=de | Definitive Edition only, classic for Classic only. |
{
"ok": true,
"updated": 1792351200,
"online": 1,
"players": 3,
"protocol": 26,
"servers": [
{
"address": "203.0.113.7:27015",
"host": "203.0.113.7",
"ip": "203.0.113.7",
"port": 27015,
"name": "MafiaM server",
"players": 3,
"maxPlayers": 128,
"edition": "de",
"season": "summer",
"tags": ["RP", "Cars", "Mafia"],
"protocol": 26,
"online": true,
"lastSeen": 1792351190,
"firstSeen": 1792340000
}
]
}
| Field | Description |
|---|---|
address | What to enter in the launcher: host:port. If the server registered with a domain, the domain is here. |
edition | de or classic. |
season | summer (1950s) or winter (1940s). |
tags | From [server] tags in m2o_server.ini, up to 8. |
protocol | The server’s protocol version. A launcher with another version cannot join it. The top-level protocol is the newest one among online servers. |
lastSeen | Unix time of the last answer. |
GET/api/servers/{host:port}
One server by address, for example /api/servers/203.0.113.7:27015. Unknown servers return 404 with error: not_found.
GET/api/downloads
The files on the Download page: link, size, date and sha256.
{
"ok": true,
"files": {
"client": {
"name": "m2o-client.zip",
"available": true,
"url": "https://mafiam.com/files/m2o-client.zip",
"size": 199229440,
"updated": 1792351200,
"sha256": "…"
},
"server": { "name": "m2o-server.zip", "available": false }
}
}