Skip to content
 
 

Repository files navigation

GameQ

CI Latest Stable Version Supported protocols PHP Version License

GameQ is a PHP library for querying many kinds of multiplayer game and voice servers. A single GameQ instance can query mixed UDP, TCP, TLS, HTTP, and master-list protocols and return a consistent result structure.

This repository is the maintained SoftCreatR Media fork of Austinb/GameQ. Version 5 targets PHP 8.1 and newer, provides a documented migration path from 4.x, and deliberately modernizes the extension API while adding current protocol support, stricter parsing, bounded batching, and modern quality checks.

Highlights

  • 186 game, voice-server, and generic protocol identifiers.
  • Concurrent mixed-protocol queries with configurable batch and response limits.
  • Normalized gq_* fields plus protocol-native data, players, teams, and join links.
  • Broad coverage through established families such as Source and GoldSource, GameSpy, Quake, Unreal, Doom 3, Frostbite, RakNet, and dedicated voice-server protocols.
  • Direct UDP, TCP, TLS, and SSL queries alongside protocols that use HTTP APIs, plugins, or public master lists.
  • PHPStan at maximum level, PHPUnit coverage for captured protocol responses, and automated compatibility checks within the GameQ 5 release line.

Installation

Composer is recommended:

composer require softcreatr/gameq:^5.2

GameQ requires PHP 8.1 or newer and the curl, libxml, simplexml, and xml extensions. The optional bz2 extension is only needed to decode compressed Source/A2S split responses. See the installation guide for standalone loading and platform details.

Quick start

<?php

require __DIR__ . '/vendor/autoload.php';

use GameQ\GameQ;

$gameQ = new GameQ();
$gameQ->addServers([
    [
        'id' => 'source-server',
        'type' => 'css',
        'host' => '192.0.2.10:27015',
    ],
    [
        'id' => 'unreal-server',
        'type' => 'ut2004',
        'host' => '192.0.2.20:7777',
    ],
]);

$gameQ
    ->setOption('timeout', 5)
    ->setOption('max_servers_per_batch', 50);

$results = $gameQ->process();

if ($results['source-server']['gq_online']) {
    printf(
        "%s: %d/%d players\n",
        $results['source-server']['gq_hostname'],
        $results['source-server']['gq_numplayers'],
        $results['source-server']['gq_maxplayers'],
    );
}

The port in host is always the client/connect port. GameQ calculates the query port where a protocol has a known offset; use the per-server query_port option when the server uses a custom query port.

Custom HTTP clients (5.2+)

All HTTP requests, including EOS/Dragonwilds, WARDOGS, official directories, authenticated APIs, and legacy HTTP packet protocols, use the configured transport. UDP and non-HTTP TCP queries continue to use GameQ's query transport.

The default GameQ\Http\CurlClient works without additional dependencies. Use any PSR-18 client with PSR-17 request and stream factories through the optional GameQ\Http\Psr18Client adapter. Configure its proxy, TLS verification, redirect refusal, and timeout on the underlying client: PSR-18 has no per-request options. The adapter bounds response reads, but an underlying client may buffer the response before returning it.

For Guzzle, the optional GameQ\Http\GuzzleClient adapter applies each protocol's timeout and decoded response size limit during transfer, verifies TLS, and refuses redirects. Install Guzzle separately (composer require guzzlehttp/guzzle:^7.9):

use GameQ\GameQ;
use GameQ\Http\GuzzleClient;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\HttpFactory;

$factory = new HttpFactory();
$gameQ = (new GameQ())->setHttpClient(new GuzzleClient(
    new Client(['proxy' => 'http://proxy.example:8080']),
    $factory,
    $factory,
));

For another PSR-18 implementation, replace GuzzleClient with Psr18Client and provide your client and factories. For transports without PSR support, implement GameQ\Http\ClientInterface::send(Request $request): Response. Honor the request's timeout and size limit, verify TLS, refuse redirects, and throw HttpException for transfer failures. HTTP error statuses are returned as responses; protocols decide whether they mean offline. Windrose login cookies are scoped to the current server and query, and directory caches are scoped to the configured transport.

setHttpClient() updates existing servers and servers added later. Independently created Server/Protocol instances can use protocolInstance()->setHttpClient(). The standalone autoloader remains supported without installing PSR or Guzzle packages when using the default cURL transport.

In WoltLab Suite, use new wcf\system\gameq\ScGameQ() from the developer package. It injects a client from the Suite's HttpFactory and honors PROXY_SERVER_HTTP.

Documentation

Project documentation is maintained in the separate GameQ Wiki, updated from the useful parts of the upstream wiki for this fork and version 5.

Start here Operate GameQ Extend GameQ
Installation Global options Architecture
Quick start and examples Results and normalized fields Adding a protocol
Server definitions and ports Performance and batching Tests and fixtures
Supported identifiers and protocol families Troubleshooting Upgrading from 4.x

Protocol-specific credentials and HTTP endpoints need additional care. Read protocol options and security guidance before exposing queries through a public application.

Support and contributing

License

GameQ is licensed under the GNU Lesser General Public License 3.0 or later.

Releases

Sponsor this project

Contributors

Languages