The official PHP client for trogdord. This is part of the Trogdor++ project.
- PHP 8.0, 8.1, or 8.2, along with the include files and access to phpize. As of version 0.30.1, the extension will still build against 7.2, 7.3, and 7.4, but those versions of PHP are now EOL, are no longer tested, and should not be relied upon to work in future versions.
- Standalone ASIO library >=1.10
- RapidJSON >= 1.1.0
If you happen to be on an Ubuntu box (and possibly also on Debian), you can install these dependencies with the following command:
sudo apt-get install php8.x-dev libasio-dev rapidjson-dev (where 8.x is your desired php version)
The configure script doesn't currently check for the existence of ASIO or RapidJSON, but if either of these libraries are missing or are not in a place where the configure script can find them, the build will fail.
To compile and install, issue the following commands:
phpize
./configure
make && make install
If trogdord is running on 1040, the default port, you can connect by instantiating the \Trogdord
class with the hostname as the only argument. If an error occurs while attempting to connect, an instance of \Trogdord\NetworkException
will be thrown.
try {
$connection = new \Trogdord("localhost");
}
catch (\Trogdord\NetworkException $e) {
// Handle error
}
If trogdord is running on a non-standard port, you can pass that port number in as an optional second argument:
try {
// Trogdord is running on port 1041 instead of the default 1040
$connection = new \Trogdord("localhost", 1041);
}
catch (\Trogdord\NetworkException $e) {
// Handle error
}
\Trogdord::statistics()
retrieves useful statistical data about the instance of trogdord we're connected to:
try {
$connection = new \Trogdord("localhost");
$statistics = $connection->statistics();
var_dump($statistics);
}
catch (\Trogdord\NetworkException $e) {
// Handle error
}
Result:
array(3) {
["lib_version"]=>
array(3) {
["major"]=>
int(0)
["minor"]=>
int(6)
["patch"]=>
int(0)
}
["players"]=>
int(0)
["version"]=>
array(3) {
["major"]=>
int(0)
["minor"]=>
int(33)
["patch"]=>
int(2)
}
}
Like \Trogdord
's constructor, \Trogdord::statistics()
will throw an instance of \Trogdord\NetworkException
if there are any issues with the connection.
\Trogdord::dump()
dumps the server's state to disk, along with all existing games. It does not return a value.
try {
$connection = new \Trogdord("localhost");
$connection->dump();
}
catch (\Trogdord\NetworkException $e) {
// Handle error
}
Like \Trogdord
's constructor, \Trogdord::dump()
will throw an instance of \Trogdord\NetworkException
if there are any issues with the connection.
\Trogdord::restore()
restores the server's state from disk, along with all previously dumped games. It does not return a value.
try {
$connection = new \Trogdord("localhost");
$connection->restore();
}
catch (\Trogdord\NetworkException $e) {
// Handle error
}
Like \Trogdord
's constructor, \Trogdord::restore()
will throw an instance of \Trogdord\NetworkException
if there are any issues with the connection.
\Trogdord::games()
retrieves a list of games that currently exist on the server:
try {
$connection = new \Trogdord("localhost");
$statistics = $connection->games();
var_dump($games);
}
// A connection-related error occurred
catch (\Trogdord\NetworkException $e) {
// Handle error
}
// The connection is fine, but something went wrong with the request
// ($e->getCode() will provide the trogdord request status and $e->getMessage()
// will explain what went wrong.)
catch (\Trogdord\RequestException $e) {
// Handle error
}
Result:
array(3) {
[0]=>
array(2) {
["id"]=>
int(0)
["name"]=>
string(5) "game1"
["definition"]=>
string(8) "game.xml"
}
[1]=>
array(2) {
["id"]=>
int(1)
["name"]=>
string(5) "game2"
["definition"]=>
string(8) "game.xml"
}
[2]=>
array(2) {
["id"]=>
int(2)
["name"]=>
string(5) "game3"
["definition"]=>
string(8) "game.xml"
}
[3]=>
array(2) {
["id"]=>
int(3)
["name"]=>
string(13) "mystartedgame"
["definition"]=>
string(8) "game.xml"
}
[3]=>
array(2) {
["id"]=>
int(3)
["name"]=>
string(13) "mystoppedgame"
["definition"]=>
string(8) "game.xml"
}
}
You can also pass an optional list of filters to only return games matching certain criteria. For example, the following code returns only games that are currently running:
$startedGames = $connection->games([
'is_running' => true
]);
var_dump($startedGames);
Result:
array(1) {
[0]=>
array(2) {
["id"]=>
int(0)
["name"]=>
string(5) "game1"
["definition"]=>
string(8) "game.xml"
}
[1]=>
array(2) {
["id"]=>
int(3)
["name"]=>
string(13) "mystartedgame"
["definition"]=>
string(8) "game.xml"
}
}
You can AND more filters together like the following example, which only returns games that are running and whose names start with the prefix "my":
$startedGames = $connection->games([
'is_running' => true,
'name_starts' => 'my'
]);
var_dump($startedGames);
Result:
array(1) {
[0]=>
array(2) {
["id"]=>
int(3)
["name"]=>
string(13) "mystartedgame"
["definition"]=>
string(8) "game.xml"
}
}
If you need OR logic, you can pass in an array of filter groups like the following example, which returns all games that are running OR not running and start with the prefix "my":
$games = $connection->games([[
'is_running' => true
], [
'is_running' => false,
'name_starts' => 'my'
]]);
var_dump($games);
Result:
array(3) {
[0]=>
array(2) {
["id"]=>
int(0)
["name"]=>
string(5) "game1"
["definition"]=>
string(8) "game.xml"
}
[1]=>
array(2) {
["id"]=>
int(3)
["name"]=>
string(13) "mystartedgame"
["definition"]=>
string(8) "game.xml"
}
[2]=>
array(2) {
["id"]=>
int(4)
["name"]=>
string(13) "mystoppedgame"
["definition"]=>
string(8) "game.xml"
}
}
Currently supported filters for game lists:
- is_running: Takes a boolean value and returns games that are either running or not running
- name_starts: Takes a string value and returns games whose names start with the given value
If for any reason you need to retrieve one or more meta values associated with the games in the same request (if the value doesn't exist for a particular game, you'll just get an empty string), you can add an array of those meta keys as an optional second argument to \Trogdord::games()
:
// We want to retrieve all games along with the meta values "title" and "author"
$games = $connection->games(null, ['title', 'author']);
var_dump($games);
Result:
array(5) {
[0]=>
array(4) {
["id"]=>
int(0)
["name"]=>
string(5) "game1"
["definition"]=>
string(8) "game.xml"
["title"]=>
string(14) "Game 1's title"
["author"]=>
string(15) "James Colannino"
}
[1]=>
array(4) {
["id"]=>
int(1)
["name"]=>
string(5) "game2"
["definition"]=>
string(8) "game.xml"
["title"]=>
string(14) "Game 2's title"
["author"]=>
string(15) "James Colannino"
}
[2]=>
array(4) {
["id"]=>
int(2)
["name"]=>
string(5) "game3"
["definition"]=>
string(8) "game.xml"
["title"]=>
string(14) "Game 3's title"
["author"]=>
string(15) "James Colannino"
}
[3]=>
array(4) {
["id"]=>
int(3)
["name"]=>
string(10) "mystartedgame"
["definition"]=>
string(8) "game.xml"
["title"]=>
string(23) "My Started Game's title"
["author"]=>
string(15) "James Colannino"
}
[4]=>
array(4) {
["id"]=>
int(4)
["name"]=>
string(13) "mystoppedgame"
["definition"]=>
string(8) "game.xml"
["title"]=>
string(23) "My Stopped Game's Title"
["author"]=>
string(15) "James Colannino"
}
}
\Trogdord::definitions()
returns a list of all game definition files available to the server.
try {
$connection = new \Trogdord("localhost");
$definitions = $connection->definitions();
var_dump($definitions);
}
catch (\Trogdord\NetworkException $e) {
// Handle connection-related error
}
catch (\Trogdord\RequestException $e) {
// Handle request-related error
}
Result:
array(1) {
[0]=>
string(9) "game1.xml"
[1]=>
string(9) "game2.xml"
[2]=>
string(9) "game3.xml"
}
\Trogdord::getGame(id)
retrieves a single game from trogdord if it exists and
throws an instance of \Trogdord\GameNotFound
if not.
try {
$connection = new \Trogdord("localhost");
$game = $connection->getGame(0);
var_dump($game);
}
catch (\Trogdord\NetworkException $e) {
// Handle connection-related error
}
catch (\Trogdord\GameNotFound $e) {
// Game doesn't exist
}
Result:
object(Trogdord\Game)#3 (4) {
["name":"Trogdord\Game":private]=>
string(6) "mygame"
["definition":"Trogdord\Game":private]=>
string(8) "game.xml"
["id":"Trogdord\Game":private]=>
int(0)
["trogdord":"Trogdord\Game":private]=>
object(Trogdord)#1 (0) {
}
}
Note that \Trogdord\Game
contains an instance of the connection that spawned it. The actual property is private, but you can access it through \Trogdord\Game::__get
. Thus, if you need to, you can use it as in the following example:
$game->trogdord->statistics();
The name and id are also available as read-only properties, courtesy of \Trogdord\Game::__get
:
var_dump($game->name);
var_dump($game->id);
Result:
string(6) "mygame"
int(0)
\Trogdord::newGame(name, definition)
creates a new game with the specified name and based
on the passed definition file (must be one of the definitions available to the
connected instance of trogdord) and returns an instance of \Trogdord\Game.
Throws an instance of \Trogdord\NetworkException
if an issue arises with the
connection and an instance of \Trogdord\RequestException
if anything goes
wrong with the request (for example, if the game definition filename passed in
isn't available to the server.)
Example:
try {
$connection = new \Trogdord("localhost");
$game = $connection->newGame('mycoolgame', 'game.xml');
var_dump($game);
}
catch (\Trogdord\NetworkException $e) {
// Handle error
}
catch (\Trogdord\RequestException $e) {
// Handle error
}
Result:
object(Trogdord\Game)#3 (4) {
["name":"Trogdord\Game":private]=>
string(10) "mycoolgame"
["definition":"Trogdord\Game":private]=>
string(8) "game.xml"
["id":"Trogdord\Game":private]=>
int(0)
["trogdord":"Trogdord\Game":private]=>
object(Trogdord)#1 (0) {
}
}
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
Every time a request is made to an instance of trogdord, a status code is
returned as part of the server's response. Whatever this status code is will be
stored in the public read-only property $status
so that you can check it if
necessary, allowing for additional insight.
For example, a call to \Trogdord::restore()
is successful if the underlying
request returns a 200 (\Trogdord\Status\SUCCESS
), indicating success, or a 206
(\Trogdord\\Status\\PARTIAL_CONTENT
), indicating that some but not all dumped
games were restored. To find out if we only had partial success restoring the
state of our trogdord instance, we can check this value after the call like so:
try {
$connection = new \Trogdord("localhost");
$connection->restore();
// A 206 indicates only partial success
if (\Trogdord\\Status\\PARTIAL_CONTENT == $connection->status) {
// do something if we only had partial success
}
}
catch (\Trogdord\NetworkException $e) {
// Handle error
}
catch (\Trogdord\RequestException $e) {
// Handle error
}
The trogdord
extension defines the following classes:
Represents a connection to trogdord and is used to create and retrieve games, as well as to return statistical information about the server.
Below is a complete list of public methods and properties (all methods, including
the constructor, throw an instance of \Trogdord\NetworkException
if anything
goes wrong with the connection):
-
$status
— Gets set after every request to the status code returned in the response. This is a public read-only property and can only be set by internal methods. -
__construct(string hostname, int port = 1040)
— Establish a connection to an instance of trogdord over the network. -
statistics(): array
— Return useful statistics about the instance of trogdord. Throws\Trogdord\RequestException
if anything goes wrong with the request (you shouldn't ever get this exception from this method unless there's a bug in the server or the extension.) -
games(array filters = null, array metaKeys = null): array
— Returns a list of games that exist on the server. Filters can be used to only include games matching certain criteria (see examples above) and metaKeys can be used to include certain meta data values for each game in the list. Throws\Trogdord\RequestException
if anything goes wrong with the request (you shouldn't ever get this exception from this method unless there's a bug in the server or the extension.) -
definitions(): array
— Returns a list of all game definition files available to the server.\Trogdord\RequestException
if anything goes wrong with the request (you shouldn't ever get this exception from this method unless there's a bug in the server or the extension.) -
getGame(int id): \Trogdord\Game
— Returns an instance of\Trogdord\Game
representing the game with the specified id. Throws\Trogdord\GameNotFound
if the game with the specified id doesn't exist. -
newGame(string name, string definition): \Trogdord\Game
— Creates a new game and returns an instance of\Trogdord\Game
that represents it. Throws\Trogdord\RequestException
if anything goes wrong with the request.
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
TODO
The trogdord
extension throws various exceptions, all of which are outlined here:
-
\Trogdord\Exception
— All exceptions inherit from this one. If you want to write a single block that will capture every possible error, this is the type you'd want to catch. -
\Trogdord\FilterException
— If you attempt to pass invalid filters to a method that accepts them (for example,\Trogdord::games
), this exception will be thrown. This inherits from\Trogdord\Exception
. -
\Trogord\NetworkException
— This is thrown whenever an error occurs with the underlying TCP connection. For example, if we attempt to start or stop a game but trogdord has gone down and the extension can't connect to it, you'll see this exception. This inherits from\Trogdord\Exception
. -
\Trogdord\RequestException
— You'll see this whenever a non-connection-related exception occurs while making a request to trogdord. For example, if you attempt to start a game that no longer exists, an instance of\Trogdord\GameNotFound
will be thrown, which inherits from this. Includes both a message and a code (the code in this case is the status code that comes back in trogdord's response.) This inherits from\Trogdord\Exception
. -
\Trogdord\GameNotFound
— If you attempt to call a method on an instance of\Trogdord\Game
representing a game that no longer exists, this exception will be thrown. This inherits from\Trogdord\RequestException
.
TODO: finish listing remaining exceptions
Every response received by trogdord returns a status code indicating success or
the nature of the error that occurred, and after every method that makes a
request, the read-only public property \Trogdord::$status
is set to that value
for inspection if necessary.
The following is a complete list of status codes:
Defined Constant | Value | Meaning |
---|---|---|
\Trogdord\Status\SUCCESS |
200 | Indicates success. |
\Trogdord\Status\PARTIAL_CONTENT |
206 | Indicates only partial success or content returned. |
\Trogdord\Status\INVALID |
400 | Indicates that a request was made with invalid arguments. |
\Trogdord\Status\NOT_FOUND |
404 | Indicates that a request was made for a resource that doesn't exist. |
\Trogdord\Status\CONFLICT |
409 | Indicates that the request was not successful due to a conflict with existing resources. |
\Trogdord\Status\INTERNAL_ERROR |
500 | Indicates that some other error occurred when servicing the request. |
\Trogdord\Status\UNSUPPORTED |
501 | Indicates that the request requires the use of an unsupported operation. |