Overview

GameMaster Light is a stripped-down, hacked-up version of the GameMaster software system. It is primarily designed to run Counter-Strike:Source game sessions on a Linux host. It is controlled via a socket interface on which JSON-encoded packets are sent via TCP streams, ona simple request/response- scheme similar to basic HTTP version 1.0.

The software works by listening on the specified socket (default port: 4554) for incoming connections, and simultaneously checking the system time at configurable interval. The current timestamp is compared to timestamps on a number of game sessions and when a game session has expired, it is foribly terminated via the Unix signaling interface.

In order to facilitate maximum flexibility in the system, the command set is extremely simple; being little more than an interface to the system() call in Perl. This is a serious security issue since it can readily allow arbitrary code execution since the interface also allows file creation with specific file contents remotely. To further add insult to injury, no access control whatsoever is implemented in the software.

Control interface

The primary means of control is through the remote socket inteface and JSON-encoded associative arrays. A very simple test can be carried out using only the standard Unix tools echo and netcat.

brax$ echo '{"command":"list"}' | netcat 127.0.0.1 4554

Provided that the software is running and listening at the specified address 127.0.0.1 at port 4554, you will receive a JSON-encoded response back that should look something like this:<(p>

{"sessions":{},"status":"ok","response":"list"}

What you just got back was the standard header, consisting of the keys response, which specifies what kind of response this is (i.e. what command it was that generated this response) and the status key which indicates success or failure with the values "ok" and "error" respectively. Since this is a list-response you also get a list of all running game sessions; which is none at this time. Thus the empty list. An example with a running session is shown below:

{"sessions":{"10903":{"end_time":1237487857,"game":"cs:s",
        "name":"A test session!","executable":"/bin/echo",
        "start_time":1237487557,"config_filename":"/home/gamemaster/test.cfg",
        "working_dir":"/home/gamemaster"}},"status":"ok","response":"list"}

There are a total of four commands available, we list them here.

new command

This command creates a new game session with the specified properties.

terminate command

Terminates or shuts down a specific game session, identified by the PID (Process IDentifier) number available throught the use of the list command.

This command is not implemented yet!

modify command

This command allows you to modify certain properties of a running game session. Right now, this only means the end_time and name properties.

This command is not implemented yet!

list command

This command lists the currently running game sessions.

Example: Creating a new game session from PHP

<?php
error_reporting(E_ALL);

print "Starting script...\n";
$command = array('command' => 'new',
        'length' => 10,
        'name' => 'A test session!',
        'game' => 'cs:s',
        'executable' => '/bin/echo',
        'working_dir' => '/home/gamemaster',
        'config_filename' => '/home/gamemaster/test.cfg',
        'config_contents' => "sv_password kebab\nsome_stuff elite");

$address = '127.0.0.1';
$port = 4554;

$json_command = json_encode($command) . "\n";

print "Creating socket...\n";
if (($socket = socket_create(AF_INET, SOCK_STREAM,
        getprotobyname('tcp'))) === FALSE) {
    die("Unable to create TCP socket.\n");
}

print "Connecting to remote host $address on port $port...\n";
if (!socket_connect($socket, $address, $port)) {
    die("Unable to connect to remote host.\n");
}

print "Writing command to socket...\n";
if (($bytes_written = socket_write($socket, $json_command)) === FALSE) {
    die("Unable to write JSON encoded data to socket.\n");
}

print "Reading response from socket...\n";
if (($response_json = socket_read($socket, 2048, PHP_NORMAL_READ)) === FALSE) {
    die("Unable to read server response from socket.\n");
}
print "Closing socket...\n";
socket_close($socket);

$response = json_decode($response_json, true);

print "Command status: " . $response['status'] . "\n";

if ($response['response'] == 'list') {

    print "'List' command response received.\n";

    foreach ($response['sessions'] as $pid => $session) {
        print "Session \"" . $session['name'] . "\", PID: " . $pid .
                ", Start time: " . $session['start_time'] . ", End time: " .
                $session['end_time'] . "\n";
    }

} elseif ($response['response'] == 'new') {

    print "'New' command response received.\n";

} elseif ($response['response'] == 'terminate') {

    print "'Terminate' command response received.\n";

} elseif ($response['response'] == 'modify') {

    print "'Modify' command response received.\n";

} elseif ($response['response'] == 'error') {
    print "'Error' response was returned.\n";
}

Configuration

The software can be customized by changing a number of constants and variables defined in the top of the main Perl script file, named gamemaster.

ParameterDefault valueDescription
LISTEN_ADDRESS127.0.0.1IPv4 address that the daemon listens to for TCP connections.
LISTEN_PORT4554Port used for listening.
POLLING_INTERVAL5 secondsPolling interval for daemon to check for expired game sessions at.
VERBOSE_MODE1Verbose/debugging mode, provides extended output to syslogd for error diagnosis.
DEFAULT_WORKING_DIRECTORY/home/gamemaster The default working directory for any sessions without a designated session in the command set.
DEFAULT_SESSION_NAME"Unnamed game session" Default name assigned to any session without a designated name
$foreground0Specifies weather the process should run in the foreground or not. Set to 1 for easier debugging.

Download the software

Below are the source files for the software; download, set executable permissions and get going!

gamemaster-0.0.2.tar.gz Latest version, changed the creation of new child processes, included a new test script and changed the PHP script to use this new child script.

gamemaster-0.0.1.tar.gz The main Perl executable, example PHP client interface code.