Skip to content

Filters

Sascha Greuel edited this page Aug 2, 2026 · 1 revision

Filters

Home · Results · Result fields

Filters run after a protocol response has been parsed. They apply to every server in the GameQ instance, in configured order.

Normalize

normalize is enabled by default. It adds consistent gq_* fields and normalizes common player/team properties while retaining protocol-native keys.

$results = $gameQ->process();

echo $results['main']['gq_hostname'];
echo $results['main']['gq_numplayers'];

Removing normalization is rarely useful, but can be done without hard-coding its generated hash:

foreach ($gameQ->listFilters() as $hash => $filter) {
    if ($filter['filter'] === 'normalize') {
        $gameQ->removeFilter($hash);
    }
}

Strip colors

stripcolors recursively removes common Source, Quake, and Unreal formatting sequences:

$gameQ->addFilter('stripcolors');

It operates only on recognized protocol families. The original colorized values are replaced in the result.

Seconds to human-readable time

secondstohuman recursively adds gq_<key>_human values for configured numeric fields:

$gameQ->addFilter('secondstohuman', [
    'timekeys' => ['time', 'uptime'],
]);

For a player value of time => 3723.8, the filter adds gq_time_human => '01:02:03'. The default key list is ['time'].

Multiple instances of a filter

Filter identity is based on the lower-case filter name and a hash of its options. The same filter can therefore be added with different configurations:

$gameQ->addFilter('secondstohuman', ['timekeys' => ['time']]);
$gameQ->addFilter('secondstohuman', ['timekeys' => ['uptime']]);

Adding the same filter with identical options replaces the existing entry rather than running it twice.

Custom filters

Create a class under the GameQ\Filters namespace extending GameQ\Filters\Base:

namespace GameQ\Filters;

use GameQ\Server;

final class Addregion extends Base
{
    public function apply(array $result, Server $server): array
    {
        $result['application_region'] = $this->options['region'] ?? 'unknown';

        return $result;
    }
}
$gameQ->addFilter('addregion', ['region' => 'eu-central']);

The class name is resolved dynamically from the filter name. Custom autoloading must therefore make the class available before process() is called. Keep expensive work out of filters because each filter runs once per server result.

Clone this wiki locally