node-gamedig/protocols/mindustry.js
Sam Schumacher ec4860cffc
feat(games): add ATS, The Cenozoic Era, VEIN and Mindustry support (#768)
* feat(games): add American Truck Simulator (ats) support

Mirrors the Euro Truck Simulator 2 configuration (valve protocol,
port 27015 with query port offset +1).

* Update .gitignore

* feat(games): add The Cenozoic Era, VEIN and Mindustry support

- The Cenozoic Era and VEIN use the Valve A2S protocol with a query
  port offset of +1 (verified live against running servers).
- Mindustry is queried via a new protocol module implementing the
  arc-net discovery ping: a two-byte UDP request (0xFE 0x01) returns
  the serialized Host struct (name, map, players, wave, version,
  vertype, gamemode, player limit, description, modeName).

* fix(games): rename thecenozoicera to tce

Satisfies the MoreThanTwoWordsMakeAcronym naming rule enforced by
the id-tests CI check: game names with more than two words require
an acronym-style id.

* Update .gitignore

* meta: restore .gitignore endline

---------

Co-authored-by: CosminPerRam <cosmin.p@live.com>
2026-05-26 22:14:06 +03:00

44 lines
1.3 KiB
JavaScript

import Core from './core.js'
const GAMEMODES = ['survival', 'sandbox', 'attack', 'pvp', 'editor']
export default class mindustry extends Core {
constructor () {
super()
this.encoding = 'utf8'
this.byteorder = 'be'
}
async run (state) {
if (!this.options.port) this.options.port = 6567
// arc-net discovery request: triggers the Mindustry server to reply
// with a serialized Host struct (see Mindustry NetworkIO.writeServerData).
const request = Buffer.from([0xfe, 0x01])
const buffer = await this.udpSend(request, b => b)
const reader = this.reader(buffer)
const name = reader.pascalString(1)
const map = reader.pascalString(1)
const players = reader.int(4)
const wave = reader.int(4)
const version = reader.int(4)
const vertype = reader.pascalString(1)
const gamemodeId = reader.uint(1)
const playerLimit = reader.int(4)
const description = reader.pascalString(1)
const modeName = reader.pascalString(1)
state.name = name
state.map = map
state.password = false
state.numplayers = players
state.maxplayers = playerLimit
state.version = String(version)
state.raw.wave = wave
state.raw.vertype = vertype
state.raw.gamemode = GAMEMODES[gamemodeId] ?? String(gamemodeId)
state.raw.description = description
state.raw.modeName = modeName
}
}