Skip to content

CallowayIsWeird/source-query

Repository files navigation

@callowayisweird/source-query

Modern Source Engine A2S query client for Node.js and Bun. Zero runtime dependencies, fully typed.

Supports A2S_INFO, A2S_PLAYER, and A2S_RULES queries against any Source Engine server (Garry's Mod, CS:GO, CS2, TF2, etc).

Install

npm install @callowayisweird/source-query

Quick Start

import { SourceQuery } from "@callowayisweird/source-query";

// Static one-shot queries
const info = await SourceQuery.info("play.example.com", 27015);
console.log(`${info.name} - ${info.players}/${info.maxPlayers} on ${info.map}`);

const players = await SourceQuery.players("play.example.com", 27015);
for (const p of players) {
  console.log(`${p.name}: ${p.score} pts (${Math.round(p.duration)}s)`);
}

const rules = await SourceQuery.rules("play.example.com", 27015);
console.log(rules);

Instance Usage

import { SourceQuery } from "@callowayisweird/source-query";

const query = new SourceQuery({
  host: "play.example.com",
  port: 27015,
  timeout: 5000,
});

const info = await query.info();
const players = await query.players();
const rules = await query.rules();

query.close();

Batch Querying

Query multiple servers concurrently with a configurable concurrency limit:

import { SourceQuery } from "@callowayisweird/source-query";

const results = await SourceQuery.batch(
  [
    { host: "server1.example.com", port: 27015 },
    { host: "server2.example.com", port: 27015 },
    { host: "server3.example.com", port: 27015 },
  ],
  { timeout: 5000, concurrency: 5 },
);

for (const result of results) {
  if (result.error) {
    console.error(`${result.host}:${result.port} failed: ${result.error.message}`);
  } else {
    console.log(`${result.host}:${result.port} - ${result.info!.name}`);
  }
}

Error Handling

import {
  SourceQuery,
  TimeoutError,
  InvalidResponseError,
  ChallengeError,
} from "@callowayisweird/source-query";

try {
  const info = await SourceQuery.info("play.example.com", 27015);
} catch (err) {
  if (err instanceof TimeoutError) {
    console.error("Server did not respond");
  } else if (err instanceof InvalidResponseError) {
    console.error("Malformed packet:", err.raw);
  } else if (err instanceof ChallengeError) {
    console.error("Challenge handshake failed");
  }
}

TypeScript Types

All types are exported for direct use:

import type {
  QueryOptions,
  ServerInfo,
  Player,
  Rules,
  BatchResult,
  BatchOptions,
} from "@callowayisweird/source-query";

License

MIT

About

Modern Source Engine A2S query client. Typed responses, challenge handling, batch querying.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors