Protocol Documentation
neomod uses and extends the bancho protocol.
Whenever "convars" or "variables" are mentioned, this means in-game variables, accessible by pressing Shift+F1.
The full list of variables is available here. This should give you a nice idea of how customizable neomod is for server admins.
You do not have to implement any of the features below; neomod will gracefully fallback to "vanilla" behavior.
Detect neomod clients via header on c. endpoint:
x-mcosu-ver: <version>
API endpoints use this user agent:
Mozilla/5.0 (compatible; neomod/<version info>; +https://neomod.net/)
To support the in-browser client, you need to handle CORS by including these headers in EVERY response:
Access-Control-Allow-Origin: *
Access-Control-Allow-Headers: *
Access-Control-Expose-Headers: cho-token, x-mcosu-features
You must also handle preflight requests to each subdomain (e.g. OPTION https://c.neomod.net/), by replying with a 204 No content and the above headers.
Enable score submission with header:
x-mcosu-features: submit=1
PROTECTED variables.PROTECTED. Use the UNPROTECT_VARIABLES packet for allowing individual mods and features.
OAuth authentication is automatically enabled for:
neomod.localneomod.netssl_verify convar to 0 for neomod.local
When clicking the "Log in with osu!" button, neomod will open the browser to:
GEThttps://neomod.net/connect/start?challenge={b64(sha256(verification_bytes))}&client=release-43.00
neomod will poll the server to get the refresh token:
GEThttps://neomod.net/connect/finish?challenge={b64(sha256(verification_bytes))}&proof={b64(verification_bytes)}
If the login is still in process, the server will return an HTTP 204 response.
If the login completed, the server will return the refresh token in an HTTP 200 response.
We use the c. endpoint login packet, with:
$oauthServer returns cho-token like for regular clients.
After logging in, neomod will attempt to connect to wss://c.neomod.net/ws/. If the server returns a different HTTP code than 101, neomod will fall back to HTTP polling, like regular clients.
If you're planning to add support for websockets on your server, remember to treat websocket connections the same as a polling client: CloudFlare tends to close websocket connections after 2 minutes, so a connection closing does not mean the client has actually stopped playing.
Submitted scores have an extra neomod-mods section, containing base64-encoded data representing neomod-specific mods.
Requests: neomod has a "Team" leaderboard filter, which sets the parameter v=5 (as opposed to, say, v=4 for "Country").
Responses: Score lines have an extra section after the "has_replay" flag, containing base64-encoded data representing neomod-specific mods.
In OAuth mode, in requests where the username and password hash are passed as parameters, username will be $token and password hash will be {cho-token}.
This includes score submission, where the username is passed and hashed in the score data.
POSThttps://osu.neomod.net/web/neomod-submit-map.php
Server should verify that the map md5 matches the file data.
128 PROTECT_VARIABLESMarks variables as PROTECTED. Score submission disabled when value differ from defaults.
129 UNPROTECT_VARIABLESRemoves PROTECTED flag. Scores submit regardless of variable value.
130 FORCE_VALUESForces variables to specific values.
131 RESET_VALUESResets variables to client-side value.
132 REQUEST_MAPRequests an .osu file from the client. Used for unranked/unavailable maps.
Client should send the .osu file to the neomod-submit-map endpoint.