Created
October 10, 2013 22:48
-
-
Save DavidGannon/6926820 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/BufferUnderflowException.php'; | |
| /** | |
| * This class represents a byte buffer which helps reading byte-wise data from | |
| * a string which acts as a raw byte array. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| */ | |
| class ByteBuffer { | |
| /** | |
| * @var string The string holding the buffer's bytes | |
| */ | |
| private $byteArray; | |
| /** | |
| * @var int The size of the buffer | |
| */ | |
| private $capacity; | |
| /** | |
| * @var int The limit to which the buffer may be filled | |
| */ | |
| private $limit; | |
| /** | |
| * @var int The current position of the read pointer | |
| */ | |
| private $position; | |
| /** | |
| * Allocates a string with the specified amount of bytes wrapped into a | |
| * byte buffer object | |
| * | |
| * @param int $length The size of the byte buffer | |
| * @return ByteBuffer The new byte buffer object | |
| */ | |
| public static function allocate($length) { | |
| return new ByteBuffer(str_repeat("\0", $length)); | |
| } | |
| /** | |
| * Wraps an existing string into a byte buffer object | |
| * | |
| * @param string $byteArray The string to encapsulate into the byte buffer | |
| * @return ByteBuffer The new ByteBuffer object | |
| */ | |
| public static function wrap($byteArray) { | |
| return new ByteBuffer($byteArray); | |
| } | |
| /** | |
| * Creates a new byte buffer instance | |
| * | |
| * @param string $byteArray The string to encapsulate into the | |
| * byte buffer | |
| */ | |
| public function __construct($byteArray) { | |
| $this->byteArray = $byteArray; | |
| $this->capacity = strlen($byteArray); | |
| $this->limit = $this->capacity; | |
| $this->position = 0; | |
| } | |
| /** | |
| * Returns the string wrapped into this byte buffer object | |
| * | |
| * @return string The string encapsulated in this byte buffer | |
| */ | |
| public function _array() { | |
| return $this->byteArray; | |
| } | |
| /** | |
| * Clears the state of this byte buffer object | |
| * | |
| * Sets the <var>limit</var> to the <var>capacity</var> of the buffer and | |
| * resets the <var>position</var>. | |
| */ | |
| public function clear() { | |
| $this->limit = $this->capacity; | |
| $this->position = 0; | |
| } | |
| /** | |
| * Sets the <var>limit</var> to the current <var>position</var> before | |
| * resetting the <var>position</var>. | |
| * | |
| * @return ByteBuffer This byte buffer | |
| */ | |
| public function flip() { | |
| $this->limit = $this->position; | |
| $this->position = 0; | |
| return $this; | |
| } | |
| /** | |
| * Reads the specified amount of bytes from the current <var>position</var> | |
| * of the byte buffer | |
| * | |
| * @param int $length The amount of bytes to read from the buffer or | |
| * <var>null</var> if everything up to <var>limit</var> should be | |
| * read | |
| * @return string The data read from the buffer | |
| * @throws BufferUnderflowException if the buffer does not contain $length | |
| * or more bytes after the current position | |
| */ | |
| public function get($length = null) { | |
| if($length === null) { | |
| $length = $this->limit - $this->position; | |
| } elseif($length > $this->remaining()) { | |
| throw new BufferUnderFlowException(); | |
| } | |
| $data = substr($this->byteArray, $this->position, $length); | |
| $this->position += $length; | |
| return $data; | |
| } | |
| /** | |
| * Reads a single byte from the buffer | |
| * | |
| * @return int The byte at the current position | |
| */ | |
| public function getByte() { | |
| return ord($this->get(1)); | |
| } | |
| /** | |
| * Reads a floating point number from the buffer | |
| * | |
| * @return float The floating point number, i.e. four bytes converted to a | |
| * <var>float</var> read at the current position | |
| */ | |
| public function getFloat() { | |
| $data = unpack('f', $this->get(4)); | |
| return $data[1]; | |
| } | |
| /** | |
| * Reads a long integer from the buffer | |
| * | |
| * @return int The long integer, i.e. four bytes converted to an | |
| * <var>int</var> read at the current position | |
| */ | |
| public function getLong() { | |
| $data = unpack('l', $this->get(4)); | |
| return $data[1]; | |
| } | |
| /** | |
| * Reads a short integer from the buffer | |
| * | |
| * @return int The short integer, i.e. two bytes converted to an | |
| * <var>int</var> read at the current position | |
| */ | |
| public function getShort() { | |
| $data = unpack('v', $this->get(2)); | |
| return $data[1]; | |
| } | |
| /** | |
| * Reads a zero-byte terminated string from the current position of the | |
| * byte buffer | |
| * | |
| * This reads the buffer up until the first occurance of a zero-byte or the | |
| * end of the buffer. The zero-byte is not included in the returned string. | |
| * | |
| * @return string The zero-byte terminated string read from the byte stream | |
| */ | |
| public function getString() { | |
| $zeroByteIndex = strpos($this->byteArray, "\0", $this->position); | |
| if($zeroByteIndex === false) { | |
| return ''; | |
| } else { | |
| $dataString = $this->get($zeroByteIndex - $this->position); | |
| $this->position ++; | |
| return $dataString; | |
| } | |
| } | |
| /** | |
| * Reads an unsigned long integer from the buffer | |
| * | |
| * @return int The long integer, i.e. four bytes converted to an unsigned | |
| * <var>float</var> read at the current position | |
| */ | |
| public function getUnsignedLong() { | |
| $data = unpack('V', $this->get(4)); | |
| return $data[1]; | |
| } | |
| /** | |
| * Sets or returns the <var>limit</var> of the buffer | |
| * | |
| * @param int $newLimit Sets the buffer's <var>limit</var> to this value | |
| * @return int If no new <var>limit</var> value is given, the current value | |
| */ | |
| public function limit($newLimit = null) { | |
| if($newLimit == null) { | |
| return $this->limit; | |
| } else { | |
| $this->limit = $newLimit; | |
| return null; | |
| } | |
| } | |
| /** | |
| * Returns the current <var>position</var> of the buffer | |
| * | |
| * @return int The current <var>position</var> of the buffer | |
| */ | |
| public function position() { | |
| return $this->position; | |
| } | |
| /** | |
| * Replaces the contents of the byte buffer with the bytes from the source | |
| * string beginning at the current <var>position</var> | |
| * | |
| * @param string $sourceByteArray The string to take bytes from | |
| * @return ByteBuffer This byte buffer | |
| */ | |
| public function put($sourceByteArray) { | |
| $newPosition = min($this->remaining(), strlen($sourceByteArray)); | |
| $this->byteArray = substr_replace($this->byteArray, $sourceByteArray, $this->position, $newPosition); | |
| $this->position = $newPosition; | |
| return $this; | |
| } | |
| /** | |
| * Returns the remaining number of byte from the current | |
| * <var>position</var> to the <var>limit</var> of the buffer | |
| * | |
| * @return int The number of bytes remaining in the buffer | |
| */ | |
| public function remaining() { | |
| return $this->limit - $this->position; | |
| } | |
| /** | |
| * Resets the <var>position</var> of this buffer | |
| * | |
| * @return ByteBuffer This byte buffer | |
| */ | |
| public function rewind() { | |
| $this->position = 0; | |
| return $this; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| /** | |
| * This exception class indicates a problem while reading from a | |
| * <var>ByteBuffer</var> instance, i.e. reading more data than the buffer | |
| * contains. This may hint at a protocol related problem. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage exceptions | |
| * @see ByteBuffer | |
| */ | |
| class BufferUnderflowException extends Exception {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/SteamCondenserException.php'; | |
| /** | |
| * This exception class indicates a problem when parsing packet data from the | |
| * responses received from a game or master server | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage exceptions | |
| */ | |
| class PacketFormatException extends SteamCondenserException { | |
| /** | |
| * Creates a new <var>PacketFormatException</var> instance | |
| * | |
| * @param string $message The message to attach to the exception | |
| */ | |
| public function __construct($message = "The packet data received doesn't match the packet format.") { | |
| parent::__construct($message); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/SteamCondenserException.php'; | |
| /** | |
| * This exception class indicates that the IP address your accessing the game | |
| * server from has been banned by the server | |
| * | |
| * You or the server operator will have to unban your IP address on the server. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage exceptions | |
| * @see GameServer::rconAuth() | |
| */ | |
| class RCONBanException extends SteamCondenserException { | |
| /** | |
| * Creates a new <var>RCONBanException</var> instance | |
| */ | |
| public function __construct() { | |
| parent::__construct('You have been banned from this server.'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/SteamCondenserException.php'; | |
| /** | |
| * This exception class indicates that you have not authenticated yet with the | |
| * game server you're trying to send commands via RCON | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage exceptions | |
| * @see GameServer::rconAuth() | |
| * @see GameServer::rconExec() | |
| */ | |
| class RCONNoAuthException extends SteamCondenserException { | |
| /** | |
| * Creates a new <var>RCONNoAuthException</var> instance | |
| */ | |
| public function __construct() { | |
| parent::__construct('Not authenticated yet.'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/SteamCondenserException.php'; | |
| /** | |
| * This exception class is used to indicate errors while commmunicating through | |
| * UDP or TCP sockets | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage exceptions | |
| */ | |
| class SocketException extends SteamCondenserException { | |
| /** | |
| * @var int | |
| */ | |
| protected $errorCode; | |
| /** | |
| * Create a new instance with an error code provided by the sockets | |
| * extension or with the given message. | |
| * | |
| * @param int|string $errorCode The error code or message | |
| * @see socket_lasterror() | |
| * @see socket_strerror() | |
| */ | |
| public function __construct($errorCode) { | |
| if (is_string($errorCode)) { | |
| $errorMessage = $errorCode; | |
| $errorCode = null; | |
| } else { | |
| $this->errorCode = $errorCode; | |
| $errorMessage = socket_strerror($errorCode) . " (Code: $errorCode)"; | |
| } | |
| parent::__construct($errorMessage, $errorCode); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| /** | |
| * This exception class is used as a base class for all exceptions related to | |
| * Steam Condenser's operation | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage exceptions | |
| */ | |
| class SteamCondenserException extends Exception {} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| /** | |
| * This exception class indicates that an operation could not be finished | |
| * within a reasonable amount of time | |
| * | |
| * This usually indicates that a server could not be contacted because of | |
| * network problems. | |
| * | |
| * <b>Note:</b> {@link SteamSocket::setTimeout()} allows to set a custom | |
| * timeout for socket operations | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage exceptions | |
| */ | |
| class TimeoutException extends Exception { | |
| /** | |
| * Creates a new <var>TimeoutException</var> instance | |
| */ | |
| public function __construct() { | |
| parent::__construct('The operation timed out.'); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2010-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/SteamCondenserException.php'; | |
| /** | |
| * This exception is raised when a Steam Web API request or a related action | |
| * fails. This can have various reasons like an invalid Web API key or a broken | |
| * request. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage exceptions | |
| * @see WebApi | |
| */ | |
| class WebApiException extends SteamCondenserException { | |
| const HTTP_ERROR = 0; | |
| const INVALID_KEY = 1; | |
| const STATUS_BAD = 2; | |
| const UNAUTHORIZED = 3; | |
| /** | |
| * Creates a new WebApiException with an error message according to the | |
| * given <var>$cause</var>. If this cause is <var>STATUS_BAD</var> (which | |
| * will origin from the Web API itself) or <var>HTTP_ERROR</var> the | |
| * details about this failed request will be taken from | |
| * <var>$statusCode</var> and <var>$statusMessage</var>. | |
| * | |
| * @param int $cause An integer indicating the problem which caused this | |
| * exception: | |
| * | |
| * <ul> | |
| * <li><var>HTTP_ERROR</var>: An error during the HTTP request | |
| * itself will result in an exception with this reason.</li> | |
| * <li><var>INVALID_KEY</var>: This occurs when trying to set a Web | |
| * API key that isn't valid, i.e. a 128 bit integer in a | |
| * hexadecimal string. | |
| * <li><var>STATUS_BAD</var>: This is caused by a successful request | |
| * that fails for some Web API internal reason (e.g. an invalid | |
| * argument). Details about this failed request will be taken | |
| * from <var>$statusCode</var> and <var>$statusMessage</var>. | |
| * <li><var>UNAUTHORIZED</var>: This happens when a Steam Web API | |
| * request is rejected as unauthorized. This most likely means | |
| * that you did not specify a valid Web API key using | |
| * {@link WebApi::setApiKey()}. A Web API key can be obtained | |
| * from http://steamcommunity.com/dev/apikey. | |
| * </ul> | |
| * | |
| * Other undefined reasons will cause a generic error message. | |
| * @param int $statusCode The HTTP status code returned by the Web API | |
| * @param string $statusMessage The status message returned in the response | |
| */ | |
| public function __construct($cause, $statusCode = null, $statusMessage = '') { | |
| switch($cause) { | |
| case self::HTTP_ERROR: | |
| $message = "The Web API request has failed due to an HTTP error: $statusMessage (status code: $statusCode)."; | |
| break; | |
| case self::INVALID_KEY: | |
| $message = 'This is not a valid Steam Web API key.'; | |
| break; | |
| case self::STATUS_BAD: | |
| $message = "The Web API request failed with the following error: $statusMessage (status code: $statusCode)."; | |
| break; | |
| case self::UNAUTHORIZED: | |
| $message = 'Your Web API request has been rejected. You most likely did not specify a valid Web API key.'; | |
| break; | |
| default: | |
| $message = 'An unexpected error occurred while executing a Web API request.'; | |
| } | |
| parent::__construct($message); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/SocketException.php'; | |
| /** | |
| * This class represents an IP socket | |
| * | |
| * It can connect to a remote host, send and receive packets | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| */ | |
| abstract class Socket { | |
| /** | |
| * The IP address the socket is connected to | |
| * | |
| * @var string | |
| */ | |
| protected $ipAddress; | |
| /** | |
| * The port number the socket is connected to | |
| * | |
| * @var int | |
| */ | |
| protected $portNumber; | |
| /** | |
| * @var string | |
| */ | |
| protected $readBuffer = ''; | |
| /** | |
| * The socket itself | |
| * @var resource | |
| */ | |
| protected $socket; | |
| /** | |
| * Stores if the sockets extension is loaded | |
| * @var bool | |
| */ | |
| protected $socketsEnabled; | |
| /** | |
| * Constructs the Socket object | |
| * | |
| * This will check if PHP's sockets extension is loaded which might be used | |
| * for socket communication. | |
| */ | |
| public function __construct() { | |
| $this->socketsEnabled = extension_loaded('sockets'); | |
| } | |
| /** | |
| * Destructor of this socket | |
| * | |
| * Automatically calls close() | |
| */ | |
| public function __destruct() { | |
| $this->close(); | |
| } | |
| /** | |
| * Connects the socket to the host with the given IP address and port | |
| * number | |
| * | |
| * @param string $ipAddress The IP address to connect to | |
| * @param int $portNumber The TCP port to connect to | |
| * @param int $timeout The timeout in milliseconds | |
| */ | |
| abstract public function connect($ipAddress, $portNumber, $timeout); | |
| /** | |
| * Closes the socket | |
| */ | |
| public function close() { | |
| if(!empty($this->socket)) { | |
| if($this->socketsEnabled) { | |
| @socket_close($this->socket); | |
| } else { | |
| @fclose($this->socket); | |
| } | |
| $this->socket = null; | |
| } | |
| } | |
| /** | |
| * Returns whether this socket has an open connection | |
| * | |
| * @return bool <var>true</var> if this socket is open | |
| */ | |
| public function isOpen() { | |
| return !empty($this->socket); | |
| } | |
| /** | |
| * Receives the specified amount of data from the socket | |
| * | |
| * @param int $length The number of bytes to read from the socket | |
| * @return string The data read from the socket | |
| * @throws SocketException if reading from the socket fails | |
| */ | |
| public function recv($length = 128) { | |
| if($this->socketsEnabled) { | |
| $data = @socket_read($this->socket, $length, PHP_BINARY_READ); | |
| if ($data === false) { | |
| throw new SocketException(socket_last_error($this->socket)); | |
| } | |
| } else { | |
| $data = fread($this->socket, $length); | |
| if ($data === false) { | |
| throw new SocketException('Could not read from socket.'); | |
| } | |
| } | |
| return $data; | |
| } | |
| /** | |
| * Waits for data to be read from this socket before the specified timeout | |
| * occurs | |
| * | |
| * @param int $timeout The number of milliseconds to wait for data arriving | |
| * on this socket before timing out | |
| * @return bool whether data arrived on this socket before the timeout | |
| */ | |
| public function select($timeout = 0) { | |
| $read = array($this->socket); | |
| $write = null; | |
| $except = null; | |
| $sec = floor($timeout / 1000); | |
| $usec = $timeout % 1000; | |
| if($this->socketsEnabled) { | |
| $select = socket_select($read, $write, $except, $sec, $usec); | |
| } else { | |
| $select = stream_select($read, $write, $except, $sec, $usec); | |
| } | |
| return $select > 0; | |
| } | |
| /** | |
| * Sends the specified data to the peer this socket is connected to | |
| * | |
| * @param string $data The data to send to the connected peer | |
| * @throws SocketException if sending fails | |
| */ | |
| public function send($data) { | |
| if($this->socketsEnabled) { | |
| $sendResult = socket_send($this->socket, $data, strlen($data), 0); | |
| if ($sendResult === false) { | |
| throw new SocketException(socket_last_error($this->socket)); | |
| } | |
| } else { | |
| $sendResult = fwrite($this->socket, $data, strlen($data)); | |
| if ($sendResult === false) { | |
| throw new SocketException('Could not send data.'); | |
| } | |
| } | |
| } | |
| /** | |
| * Returns the file descriptor of the underlying socket | |
| * | |
| * @return resource The underlying socket descriptor | |
| */ | |
| public function resource() { | |
| return $this->socket; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2010-2013, Sebastian Staudt | |
| * | |
| * @author Sebastian Staudt | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| * @package steam-condenser | |
| */ | |
| define('STEAM_CONDENSER_PATH', dirname(__FILE__) . '/'); | |
| define('STEAM_CONDENSER_VERSION', '1.3.6'); | |
| require_once STEAM_CONDENSER_PATH . 'steam/servers/GoldSrcServer.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/servers/MasterServer.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/servers/SourceServer.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/SteamId.php'; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2010-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| /** | |
| * This class holds statistical information about missions played by a player | |
| * in Alien Swarm | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class AlienSwarmMission { | |
| /** | |
| * @var float | |
| */ | |
| private $avgDamageTaken; | |
| /** | |
| * @var float | |
| */ | |
| private $avgFriendlyFire; | |
| /** | |
| * @var float | |
| */ | |
| private $avgKills; | |
| /** | |
| * @var string | |
| */ | |
| private $bestDifficulty; | |
| /** | |
| * @var int | |
| */ | |
| private $damageTaken; | |
| /** | |
| * @var int | |
| */ | |
| private $friendlyFire; | |
| /** | |
| * @var int | |
| */ | |
| private $gamesSuccessful; | |
| /** | |
| * @var string | |
| */ | |
| private $img; | |
| /** | |
| * @var int | |
| */ | |
| private $kills; | |
| /** | |
| * @var string | |
| */ | |
| private $mapName; | |
| /** | |
| * @var string | |
| */ | |
| private $name; | |
| /** | |
| * @var int | |
| */ | |
| private $time; | |
| /** | |
| * @var string | |
| */ | |
| private $totalGames; | |
| /** | |
| * @var float | |
| */ | |
| private $totalGamesPercentage; | |
| /** | |
| * Creates a new mission instance of based on the given XML data | |
| * | |
| * @param SimpleXMLElement $missionData The data representing this mission | |
| */ | |
| public function __construct(SimpleXMLElement $missionData) { | |
| $this->avgDamageTaken = (float) $missionData->damagetakenavg; | |
| $this->avgFriendlyFire = (float) $missionData->friendlyfireavg; | |
| $this->avgKills = (float) $missionData->killsavg; | |
| $this->bestDifficulty = (string) $missionData->bestdifficulty; | |
| $this->damageTaken = (int) $missionData->damagetaken; | |
| $this->friendlyFire = (int) $missionData->friendlyfire; | |
| $this->gamesSuccessful = (int) $missionData->gamessuccess; | |
| $this->img = AlienSwarmStats::BASE_URL . (string) $missionData->image; | |
| $this->kills = (int) $missionData->kills; | |
| $this->mapName = $missionData->getName(); | |
| $this->name = (string) $missionData->name; | |
| $this->totalGames = (int) $missionData->gamestotal; | |
| $this->totalGamesPercentage = (float) $missionData->gamestotalpct; | |
| $this->time = array(); | |
| $this->time['average'] = (string) $missionData->avgtime; | |
| $this->time['brutal'] = (string) $missionData->brutaltime; | |
| $this->time['easy'] = (string) $missionData->easytime; | |
| $this->time['hard'] = (string) $missionData->hardtime; | |
| $this->time['insane'] = (string) $missionData->insanetime; | |
| $this->time['normal'] = (string) $missionData->normaltime; | |
| $this->time['total'] = (string) $missionData->totaltime; | |
| } | |
| /** | |
| * Returns the avarage damage taken by the player while playing a round in | |
| * this mission | |
| * | |
| * @return float The average damage taken by the player | |
| */ | |
| public function getAvgDamageTaken() { | |
| return $this->avgDamageTaken; | |
| } | |
| /** | |
| * Returns the avarage damage dealt by the player to team mates while | |
| * playing a round in this mission | |
| * | |
| * @return float The average damage dealt by the player to team mates | |
| */ | |
| public function getAvgFriendlyFire() { | |
| return $this->avgFriendlyFire; | |
| } | |
| /** | |
| * Returns the avarage number of aliens killed by the player while playing | |
| * a round in this mission | |
| * | |
| * @return float The avarage number of aliens killed by the player | |
| */ | |
| public function getAvgKills() { | |
| return $this->avgKills; | |
| } | |
| /** | |
| * Returns the highest difficulty the player has beat this mission in | |
| * | |
| * @return string The highest difficulty the player has beat this mission | |
| * in | |
| */ | |
| public function getBestDifficulty() { | |
| return $this->bestDifficulty; | |
| } | |
| /** | |
| * Returns the total damage taken by the player in this mission | |
| * | |
| * @return int The total damage taken by the player | |
| */ | |
| public function getDamageTaken() { | |
| return $this->damageTaken; | |
| } | |
| /** | |
| * Returns the total damage dealt by the player to team mates in this | |
| * mission | |
| * | |
| * @return int The total damage dealt by the player to team mates | |
| */ | |
| public function getFriendlyFire() { | |
| return $this->friendlyFire; | |
| } | |
| /** | |
| * Returns the number of successful rounds the player played in this | |
| * mission | |
| * | |
| * @return int The number of successful rounds of this mission | |
| */ | |
| public function getGamesSuccessful() { | |
| return $this->gamesSuccessful; | |
| } | |
| /** | |
| * Returns the URL to a image displaying the mission | |
| * | |
| * @return string The URL of the mission's image | |
| */ | |
| public function getImg() { | |
| return $this->img; | |
| } | |
| /** | |
| * Returns the total number of aliens killed by the player in this mission | |
| * | |
| * @return int The total number of aliens killed by the player | |
| */ | |
| public function getKills() { | |
| return $this->kills; | |
| } | |
| /** | |
| * Returns the file name of the mission's map | |
| * | |
| * @return string The file name of the mission's map | |
| */ | |
| public function getMapName() { | |
| return $this->mapName; | |
| } | |
| /** | |
| * Returns the name of the mission | |
| * | |
| * @return string The name of the mission | |
| */ | |
| public function getName() { | |
| return $this->name; | |
| } | |
| /** | |
| * Returns various statistics about the times needed to accomplish this | |
| * mission | |
| * | |
| * This includes the best times for each difficulty, the average time and | |
| * the total time spent in this mission. | |
| * | |
| * @return array Various time statistics about this mission | |
| */ | |
| public function getTime() { | |
| return $this->time; | |
| } | |
| /** | |
| * Returns the number of games played in this mission | |
| * | |
| * @return int The number of games played in this mission | |
| */ | |
| public function getTotalGames() { | |
| return $this->totalGames; | |
| } | |
| /** | |
| * Returns the percentage of successful games played in this mission | |
| * | |
| * @return float The percentage of successful games played in this mission | |
| */ | |
| public function getTotalGamesPercentage() { | |
| return $this->totalGamesPercentage; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2010-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/alien_swarm/AlienSwarmMission.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/alien_swarm/AlienSwarmWeapon.php'; | |
| /** | |
| * This class represents the game statistics for a single user in Alien Swarm | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class AlienSwarmStats extends GameStats { | |
| /** | |
| * @var string The base URL for all images referenced in the stats | |
| */ | |
| const BASE_URL = 'http://steamcommunity.com/public/images/gamestats/swarm/'; | |
| /** | |
| * @var string The names of all weapons in Alien Swarm | |
| */ | |
| private static $WEAPONS = array('Autogun', 'Cannon_Sentry', 'Chainsaw', | |
| 'Flamer', 'Grenade_Launcher', 'Hand_Grenades', 'Hornet_Barrage', | |
| 'Incendiary_Sentry', 'Laser_Mines', 'Marskman_Rifle', 'Minigun', | |
| 'Mining_Laser', 'PDW', 'Pistol', 'Prototype_Rifle', 'Rail_Rifle', | |
| 'Rifle', 'Rifle_Grenade', 'Sentry_Gun', 'Shotgun', 'Tesla_Cannon', | |
| 'Vindicator', 'Vindicator_Grenade'); | |
| /** | |
| * @var array | |
| */ | |
| private $favorites; | |
| /** | |
| * @var array | |
| */ | |
| private $itemStats; | |
| /** | |
| * @var array | |
| */ | |
| private $lifetimeStats; | |
| /** | |
| * @var array | |
| */ | |
| private $missionStats; | |
| /** | |
| * @var array | |
| */ | |
| private $weaponStats; | |
| /** | |
| * Creates a new <var>AlienSwarmStats</var> instance by calling the super | |
| * constructor with the game name <var>"alienswarm"</var> | |
| * | |
| * @param mixed $steamId The custom URL or the 64bit Steam ID of the user | |
| */ | |
| public function __construct($steamId) { | |
| parent::__construct($steamId, 'alienswarm'); | |
| if($this->isPublic()) { | |
| $lifetimeStats = $this->xmlData->stats->lifetime; | |
| $this->hoursPlayed = (string) $lifetimeStats->timePlayed; | |
| $this->lifetimeStats = array(); | |
| $this->lifetimeStats['accuracy'] = (float) $lifetimeStats->accuracy; | |
| $this->lifetimeStats['aliensBurned'] = (int) $lifetimeStats->aliensburned; | |
| $this->lifetimeStats['aliensKilled'] = (int) $lifetimeStats->alienskilled; | |
| $this->lifetimeStats['campaigns'] = (int) $lifetimeStats->campaigns; | |
| $this->lifetimeStats['damageTaken'] = (int) $lifetimeStats->damagetaken; | |
| $this->lifetimeStats['experience'] = (int) $lifetimeStats->experience; | |
| $this->lifetimeStats['experienceRequired'] = (int) $lifetimeStats->xprequired; | |
| $this->lifetimeStats['fastHacks'] = (int) $lifetimeStats->fasthacks; | |
| $this->lifetimeStats['friendlyFire'] = (int) $lifetimeStats->friendlyfire; | |
| $this->lifetimeStats['gamesSuccessful'] = (int) $lifetimeStats->gamessuccess; | |
| $this->lifetimeStats['healing'] = (int) $lifetimeStats->healing; | |
| $this->lifetimeStats['killsPerHour'] = (float) $lifetimeStats->killsperhour; | |
| $this->lifetimeStats['level'] = (int) $lifetimeStats->level; | |
| $this->lifetimeStats['promotion'] = (int) $lifetimeStats->promotion; | |
| $this->lifetimeStats['nextUnlock'] = (string) $lifetimeStats->nextunlock; | |
| $this->lifetimeStats['nextUnlockImg'] = self::BASE_URL . (string) $lifetimeStats->nextunlockimg; | |
| $this->lifetimeStats['shotsFired'] = (int) $lifetimeStats->shotsfired; | |
| $this->lifetimeStats['totalGames'] = (int) $lifetimeStats->totalgames; | |
| if($this->lifetimeStats['promotion'] > 0) { | |
| $this->lifetimeStats['promotionImg'] = self::BASE_URL . (string) $lifetimeStats->promotionpic; | |
| } | |
| $this->lifetimeStats['games_successful_percentage'] = ($this->lifetimeStats['totalGames'] > 0) ? $this->lifetimeStats['gamesSuccessful'] / $this->lifetimeStats['totalGames'] : 0; | |
| } | |
| } | |
| /** | |
| * Returns the favorites of this user like weapons and marine | |
| * | |
| * If the favorites haven't been parsed already, parsing is done now. | |
| * | |
| * @return array The favorites of this player | |
| */ | |
| public function getFavorites() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->favorites)) { | |
| $favoritesData = $this->xmlData->stats->favorites; | |
| $this->favorites = array(); | |
| $this->favorites['class'] = (string) $favoritesData->class; | |
| $this->favorites['classImg'] = (string) $favoritesData->classimg; | |
| $this->favorites['classPercentage'] = (float) $favoritesData->classpct; | |
| $this->favorites['difficulty'] = (string) $favoritesData->difficulty; | |
| $this->favorites['difficultyPercentage'] = (float) $favoritesData->difficultypct; | |
| $this->favorites['extra'] = (string) $favoritesData->extra; | |
| $this->favorites['extraImg'] = (string) $favoritesData->extraimg; | |
| $this->favorites['extraPercentage'] = (float) $favoritesData->extrapct; | |
| $this->favorites['marine'] = (string) $favoritesData->marine; | |
| $this->favorites['marineImg'] = (string) $favoritesData->marineimg; | |
| $this->favorites['marinePercentage'] = (float) $favoritesData->marinepct; | |
| $this->favorites['mission'] = (string) $favoritesData->mission; | |
| $this->favorites['missionImg'] = (string) $favoritesData->missionimg; | |
| $this->favorites['missionPercentage'] = (float) $favoritesData->missionpct; | |
| $this->favorites['primaryWeapon'] = (string) $favoritesData->primary; | |
| $this->favorites['primaryWeaponImg'] = (string) $favoritesData->primaryimg; | |
| $this->favorites['primaryWeaponPercentage'] = (float) $favoritesData->primarypct; | |
| $this->favorites['secondaryWeapon'] = (string) $favoritesData->secondary; | |
| $this->favorites['secondaryWeaponImg'] = (string) $favoritesData->secondaryimg; | |
| $this->favorites['secondaryWeapon_Percentage'] = (float) $favoritesData->secondarypct; | |
| } | |
| return $this->favorites; | |
| } | |
| /** | |
| * Returns the item stats for this user like ammo deployed and medkits | |
| * used | |
| * | |
| * If the items haven't been parsed already, parsing is done now. | |
| * | |
| * @return array The item stats of this player | |
| */ | |
| public function getItemStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->itemStats)) { | |
| $itemStatsData = $this->xmlData->stats->weapons; | |
| $this->itemStats = array(); | |
| $this->itemStats['ammoDeployed'] = (int) $itemStatsData->ammo_deployed; | |
| $this->itemStats['sentrygunsDeployed'] = (int) $itemStatsData->sentryguns_deployed; | |
| $this->itemStats['sentryFlamersDeployed'] = (int) $itemStatsData->sentry_flamers_deployed; | |
| $this->itemStats['sentryFreezeDeployed'] = (int) $itemStatsData->sentry_freeze_deployed; | |
| $this->itemStats['sentryCannonDeployed'] = (int) $itemStatsData->sentry_cannon_deployed; | |
| $this->itemStats['medkitsUsed'] = (int) $itemStatsData->medkits_used; | |
| $this->itemStats['flaresUsed'] = (int) $itemStatsData->flares_used; | |
| $this->itemStats['adrenalineUsed'] = (int) $itemStatsData->adrenaline_used; | |
| $this->itemStats['teslaTrapsDeployed'] = (int) $itemStatsData->tesla_traps_deployed; | |
| $this->itemStats['freezeGrenadesThrown'] = (int) $itemStatsData->freeze_grenades_thrown; | |
| $this->itemStats['electricArmorUsed'] = (int) $itemStatsData->electric_armor_used; | |
| $this->itemStats['healgunHeals'] = (int) $itemStatsData->healgun_heals; | |
| $this->itemStats['healgunHealsSelf'] = (int) $itemStatsData->healgun_heals_self; | |
| $this->itemStats['healbeaconHeals'] = (int) $itemStatsData->healbeacon_heals; | |
| $this->itemStats['healbeaconHealsSelf'] = (int) $itemStatsData->healbeacon_heals_self; | |
| $this->itemStats['damageAmpsUsed'] = (int) $itemStatsData->damage_amps_used; | |
| $this->itemStats['healbeaconsDeployed'] = (int) $itemStatsData->healbeacons_deployed; | |
| $this->itemStats['healbeaconHealsPct'] = (float) $itemStatsData->healbeacon_heals_pct; | |
| $this->itemStats['healgunHealsPct'] = (float) $itemStatsData->healgun_heals_pct; | |
| $this->itemStats['healbeaconHealsPctSelf'] = (float) $itemStatsData->healbeacon_heals_pct_self; | |
| $this->itemStats['healgunHealsPctSelf'] = (float) $itemStatsData->healgun_heals_pct_self; | |
| } | |
| return $this->itemStats; | |
| } | |
| /** | |
| * Returns general stats for the players | |
| * | |
| * @return array The stats for the player | |
| */ | |
| public function getLifetimeStats() { | |
| return $this->lifetimeStats; | |
| } | |
| /** | |
| * Returns the stats for individual missions for this user containing all | |
| * Alien Swarm missions | |
| * | |
| * If the mission stats haven't been parsed already, parsing is done now. | |
| * | |
| * @return array The mission stats for this player | |
| */ | |
| public function getMissionStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->missionStats)) { | |
| $this->missionStats = array(); | |
| foreach($this->xmlData->stats->missions->children() as $missionData) { | |
| $this->missionStats[$missionData->getName()] = new AlienSwarmMission($missionData); | |
| } | |
| } | |
| return $this->missionStats; | |
| } | |
| /** | |
| * Returns the stats for individual weapons for this user containing all | |
| * Alien Swarm weapons | |
| * | |
| * If the weapon stats haven't been parsed already, parsing is done now. | |
| * | |
| * @return array The weapon stats for this player | |
| */ | |
| public function getWeaponStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->weaponStats)) { | |
| $this->weaponStats = array(); | |
| foreach(self::$WEAPONS as $weaponNode) { | |
| $weaponData = $this->xmlData->stats->weapons->$weaponNode; | |
| $weapon = new AlienSwarmWeapon($weaponData); | |
| $this->weaponStats[$weapon->getName()] = $weapon; | |
| } | |
| } | |
| return $this->weaponStats; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2010-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameWeapon.php'; | |
| /** | |
| * This class holds statistical information about weapons used by a player | |
| * in Alien Swarm | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class AlienSwarmWeapon extends GameWeapon { | |
| private $accuracy; | |
| private $damage; | |
| private $friendlyFire; | |
| private $name; | |
| /** | |
| * Creates a new weapon instance based on the assigned weapon XML data | |
| * | |
| * @param SimpleXMLElement $weaponData The data representing this weapon | |
| */ | |
| public function __construct(SimpleXMLElement $weaponData) { | |
| parent::__construct($weaponData); | |
| $this->accuracy = (float) $weaponData->accuracy; | |
| $this->damage = (int) $weaponData->damage; | |
| $this->friendlyFire = (int) $weaponData->friendlyfire; | |
| $this->name = (string) $weaponData->name; | |
| $this->shots = (int) $weaponData->shotsfired; | |
| } | |
| /** | |
| * Returns the accuracy of the player with this weapon | |
| * | |
| * @return The accuracy of the player with this weapon | |
| */ | |
| public function getAccuracy() { | |
| return $this->accuracy; | |
| } | |
| /** | |
| * Returns the damage achieved with this weapon | |
| * | |
| * @return The damage achieved with this weapon | |
| */ | |
| public function getDamage() { | |
| return $this->damage; | |
| } | |
| /** | |
| * Returns the damage dealt to team mates with this weapon | |
| * | |
| * @return The damage dealt to team mates with this weapon | |
| */ | |
| public function getFriendlyFire() { | |
| return $this->friendlyFire; | |
| } | |
| /** | |
| * Returns the name of this weapon | |
| * | |
| * @return The name of this weapon | |
| */ | |
| public function getName() { | |
| return $this->name; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2010-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/WebApi.php'; | |
| /** | |
| * This class represents Steam news and can be used to load a list of current | |
| * news about specific games | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class AppNews { | |
| /** | |
| * @var int | |
| */ | |
| private $appId; | |
| /** | |
| * @var string | |
| */ | |
| private $author; | |
| /** | |
| * @var string | |
| */ | |
| private $contents; | |
| /** | |
| * @var int | |
| */ | |
| private $date; | |
| /** | |
| * @var bool | |
| */ | |
| private $external; | |
| /** | |
| * @var string | |
| */ | |
| private $feedLabel; | |
| /** | |
| * @var string | |
| */ | |
| private $feedName; | |
| /** | |
| * @var string | |
| */ | |
| private $gid; | |
| /** | |
| * @var string | |
| */ | |
| private $title; | |
| /** | |
| * @var string | |
| */ | |
| private $url; | |
| /** | |
| * Loads the news for the given game with the given restrictions | |
| * | |
| * @param int $appId The unique Steam Application ID of the game (e.g. 440 | |
| * for Team Fortress 2). See | |
| * http://developer.valvesoftware.com/wiki/Steam_Application_IDs for | |
| * all application IDs | |
| * @param int $count The maximum number of news to load (default: 5). | |
| * There's no reliable way to load all news. Use really a really | |
| * great number instead | |
| * @param int $maxLength The maximum content length of the news (default: | |
| * null). If a maximum length is defined, the content of the news | |
| * will only be at most <var>maxLength</var> characters long plus an | |
| * ellipsis | |
| * @return array An array of news items for the specified game with the | |
| * given options | |
| */ | |
| public static function getNewsForApp($appId, $count = 5, $maxLength = null) { | |
| $params = array('appid' => $appId, 'count' => $count, | |
| 'maxlength' => $maxLength); | |
| $data = json_decode(WebApi::getJSON('ISteamNews', 'GetNewsForApp', 2, $params)); | |
| $newsItems = array(); | |
| foreach($data->appnews->newsitems as $newsData) { | |
| $newsItems[] = new AppNews($appId, $newsData); | |
| } | |
| return $newsItems; | |
| } | |
| /** | |
| * Creates a new instance of an AppNews news item with the given data | |
| * | |
| * @param int $appId The unique Steam Application ID of the game (e.g. 440 | |
| * for Team Fortress 2). See | |
| * http://developer.valvesoftware.com/wiki/Steam_Application_IDs for | |
| * all application IDs | |
| * @param stdClass $newsData The news data extracted from JSON | |
| */ | |
| private function __construct($appId, $newsData) { | |
| $this->appId = $appId; | |
| $this->author = $newsData->author; | |
| $this->contents = trim($newsData->contents); | |
| $this->date = (int) $newsData->date; | |
| $this->external = (bool) $newsData->is_external_url; | |
| $this->feedLabel = $newsData->feedlabel; | |
| $this->feedName = $newsData->feedname; | |
| $this->gid = $newsData->gid; | |
| $this->title = $newsData->title; | |
| $this->url = $newsData->url; | |
| } | |
| /** | |
| * Returns the Steam Application ID of the game this news belongs to | |
| * | |
| * @return int The application ID of the game this news belongs to | |
| */ | |
| public function getAppId() { | |
| return $this->appId; | |
| } | |
| /** | |
| * Returns the author of this news item | |
| * | |
| * @return string The author of this news | |
| */ | |
| public function getAuthor() { | |
| return $this->author; | |
| } | |
| /** | |
| * Returns the content of this news item | |
| * | |
| * This might contain HTML code. | |
| * | |
| * <strong>Note:</strong> Depending on the setting for the maximum length | |
| * of a news (see {@link #getNewsForApp}, the contents might be truncated. | |
| * | |
| * @return string The content of this news | |
| */ | |
| public function getContents() { | |
| return $this->contents; | |
| } | |
| /** | |
| * Returns the date this news item has been published | |
| * | |
| * @return int The date this news has been published | |
| */ | |
| public function getDate() { | |
| return $this->date; | |
| } | |
| /** | |
| * Returns the name of the feed this news item belongs to | |
| * | |
| * @return string The name of the feed this news belongs to | |
| */ | |
| public function getFeedLabel() { | |
| return $this->feedLabel; | |
| } | |
| /** | |
| * Returns the symbolic name of the feed this news item belongs to | |
| * | |
| * @return string The symbolic name of the feed this news belongs to | |
| */ | |
| public function getFeedName() { | |
| return $this->feedName; | |
| } | |
| /** | |
| * Returns a unique identifier for this news | |
| * | |
| * @return string A unique identifier for this news | |
| */ | |
| public function getGid() { | |
| return $this->gid; | |
| } | |
| /** | |
| * Returns the title of this news item | |
| * | |
| * @return string The title of this news | |
| */ | |
| public function getTitle() { | |
| return $this->title; | |
| } | |
| /** | |
| * Returns the URL of the original news | |
| * | |
| * This is a direct link to the news on the Steam website or a redirecting | |
| * link to the external post. | |
| * | |
| * @return string The URL of the original news | |
| */ | |
| public function getUrl() { | |
| return $this->url; | |
| } | |
| /** | |
| * Returns whether this news item originates from a source other than Steam | |
| * itself (e.g. an external blog) | |
| * | |
| * @return boolean <var>true</var> if this news item is from an external | |
| * source | |
| */ | |
| public function isExternal() { | |
| return $this->external; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2010-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| /** | |
| * Represents the stats for a Counter-Strike: Source map for a specific user | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class CSSMap { | |
| /** | |
| * @var bool | |
| */ | |
| private $favorite; | |
| /** | |
| * @var string | |
| */ | |
| private $name; | |
| /** | |
| * @var int | |
| */ | |
| private $roundsPlayed; | |
| /** | |
| * @var int | |
| */ | |
| private $roundsLost; | |
| /** | |
| * @var int | |
| */ | |
| private $roundsWon; | |
| /** | |
| * Creates a new instance of a Counter-Strike: Source class based on the | |
| * given XML data | |
| * | |
| * @param string $mapName The name of the map | |
| * @param SimpleXMLElement $mapsData The XML data of all maps | |
| */ | |
| public function __construct($mapName, SimpleXMLElement $mapsData) { | |
| $this->name = $mapName; | |
| $this->favorite = ((string) $mapsData->favorite) == $this->name; | |
| $this->roundsPlayed = (int) $mapsData->{"{$this->name}_rounds"}; | |
| $this->roundsWon = (int) $mapsData->{"{$this->name}_wins"}; | |
| $this->roundsLost = $this->roundsPlayed - $this->roundsWon; | |
| } | |
| /** | |
| * Returns whether this map is the favorite map of this player | |
| * | |
| * @return bool <var>true</var> if this is the favorite map | |
| */ | |
| public function isFavorite() { | |
| return $this->favorite; | |
| } | |
| /** | |
| * Returns the name of this map | |
| * | |
| * @return string The name of this map | |
| */ | |
| public function getName() { | |
| return $this->name; | |
| } | |
| /** | |
| * Returns the number of rounds the player has lost on this map | |
| * | |
| * @return int The number of rounds lost | |
| */ | |
| public function getRoundsLost() { | |
| return $this->roundsLost; | |
| } | |
| /** | |
| * Returns the number of rounds the player has played on this map | |
| * | |
| * @return int The number of rounds played | |
| */ | |
| public function getRoundsPlayed() { | |
| return $this->roundsPlayed; | |
| } | |
| /** | |
| * Returns the number of rounds the player has won on this map | |
| * | |
| * @return int The number of rounds won | |
| */ | |
| public function getRoundsWon() { | |
| return $this->roundsWon; | |
| } | |
| /** | |
| * Returns the percentage of rounds the player has won on this map | |
| * | |
| * @return float The percentage of rounds won | |
| */ | |
| public function getRoundsWonPercentage() { | |
| return ($this->roundsPlayed > 0) ? ($this->roundsWon / $this->roundsPlayed) : 0; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2010-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/css/CSSMap.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/css/CSSWeapon.php'; | |
| /** | |
| * The is class represents the game statistics for a single user in | |
| * Counter-Strike: Source | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class CSSStats extends GameStats { | |
| /** | |
| * @var array The names of the maps in Counter-Strike: Source | |
| */ | |
| protected static $MAPS = array( 'cs_assault', 'cs_compound', | |
| 'cs_havana', 'cs_italy', 'cs_militia', 'cs_office', 'de_aztec', | |
| 'de_cbble', 'de_chateau', 'de_dust', 'de_dust2', 'de_inferno', | |
| 'de_nuke', 'de_piranesi', 'de_port', 'de_prodigy', 'de_tides', | |
| 'de_train' ); | |
| /** | |
| * @var array The names of the weapons in Counter-Strike: Source | |
| */ | |
| protected static $WEAPONS = array( 'deagle', 'usp', 'glock', 'p228', | |
| 'elite', 'fiveseven', 'awp', 'ak47', 'm4a1', 'aug', 'sg552', | |
| 'sg550', 'galil', 'famas', 'scout', 'g3sg1', 'p90', 'mp5navy', | |
| 'tmp', 'mac10', 'ump45', 'm3', 'xm1014', 'm249', 'knife', | |
| 'grenade' ); | |
| private $lastMatchStats; | |
| private $totalStats; | |
| /** | |
| * Creates a <var>CSSStats</var> instance by calling the super constructor | |
| * with the game name <var>"cs:s"</var> | |
| * | |
| * @param string $steamId The custom URL or 64bit Steam ID of the user | |
| */ | |
| public function __construct($steamId) { | |
| parent::__construct($steamId, 'cs:s'); | |
| if($this->isPublic()) { | |
| $statsData = $this->xmlData->stats; | |
| $this->lastMatchStats = array(); | |
| $this->totalStats = array(); | |
| $this->lastMatchStats['costPerKill'] = (float) $statsData->lastmatch->costkill; | |
| $this->lastMatchStats['ctWins'] = (int) $statsData->lastmatch->ct_wins; | |
| $this->lastMatchStats['damage'] = (int) $statsData->lastmatch->dmg; | |
| $this->lastMatchStats['deaths'] = (int) $statsData->lastmatch->deaths; | |
| $this->lastMatchStats['dominations'] = (int) $statsData->lastmatch->dominations; | |
| $this->lastMatchStats['favoriteWeaponId'] = (int) $statsData->lastmatch->favwpnid; | |
| $this->lastMatchStats['kills'] = (int) $statsData->lastmatch->kills; | |
| $this->lastMatchStats['maxPlayers'] = (int) $statsData->lastmatch->max_players; | |
| $this->lastMatchStats['money'] = (int) $statsData->lastmatch->money; | |
| $this->lastMatchStats['revenges'] = (int) $statsData->lastmatch->revenges; | |
| $this->lastMatchStats['stars'] = (int) $statsData->lastmatch->stars; | |
| $this->lastMatchStats['tWins'] = (int) $statsData->lastmatch->t_wins; | |
| $this->lastMatchStats['wins'] = (int) $statsData->lastmatch->wins; | |
| $this->totalStats['blindKills'] = (int) $statsData->lifetime->blindkills; | |
| $this->totalStats['bombsDefused'] = (int) $statsData->lifetime->bombsdefused; | |
| $this->totalStats['bombsPlanted'] = (int) $statsData->lifetime->bombsplanted; | |
| $this->totalStats['damage'] = (int) $statsData->lifetime->dmg; | |
| $this->totalStats['deaths'] = (int) $statsData->summary->deaths; | |
| $this->totalStats['dominationOverkills'] = (int) $statsData->lifetime->dominationoverkills; | |
| $this->totalStats['dominations'] = (int) $statsData->lifetime->dominations; | |
| $this->totalStats['earnedMoney'] = (int) $statsData->lifetime->money; | |
| $this->totalStats['enemyWeaponKills'] = (int) $statsData->lifetime->enemywpnkills; | |
| $this->totalStats['headshots'] = (int) $statsData->lifetime->headshots; | |
| $this->totalStats['hits'] = (int) $statsData->summary->shotshit; | |
| $this->totalStats['hostagesRescued'] = (int) $statsData->lifetime->hostagesrescued; | |
| $this->totalStats['kills'] = (int) $statsData->summary->kills; | |
| $this->totalStats['knifeKills'] = (int) $statsData->lifetime->knifekills; | |
| $this->totalStats['logosSprayed'] = (int) $statsData->lifetime->decals; | |
| $this->totalStats['nightvisionDamage'] = (int) $statsData->lifetime->nvgdmg; | |
| $this->totalStats['pistolRoundsWon'] = (int) $statsData->lifetime->pistolrounds; | |
| $this->totalStats['revenges'] = (int) $statsData->lifetime->revenges; | |
| $this->totalStats['roundsPlayed'] = (int) $statsData->summary->rounds; | |
| $this->totalStats['roundsWon'] = (int) $statsData->summary->wins; | |
| $this->totalStats['secondsPlayed'] = (int) $statsData->summary->timeplayed; | |
| $this->totalStats['shots'] = (int) $statsData->summary->shots; | |
| $this->totalStats['stars'] = (int) $statsData->summary->stars; | |
| $this->totalStats['weaponsDonated'] = (int) $statsData->lifetime->wpndonated; | |
| $this->totalStats['windowsBroken'] = (int) $statsData->lifetime->winbroken; | |
| $this->totalStats['zoomedSniperKills'] = (int) $statsData->lifetime->zsniperkills; | |
| $this->lastMatchStats['kdratio'] = ($this->totalStats['deaths'] > 0) ? $this->lastMatchStats['kills'] / $this->lastMatchStats['deaths'] : 0; | |
| $this->totalStats['accuracy'] = ($this->totalStats['shots'] > 0) ? $this->totalStats['hits'] / $this->totalStats['shots'] : 0; | |
| $this->totalStats['kdratio'] = ($this->totalStats['deaths'] > 0) ? $this->totalStats['kills'] / $this->totalStats['deaths'] : 0; | |
| $this->totalStats['roundsLost'] = $this->totalStats['roundsPlayed'] - $this->totalStats['roundsWon']; | |
| } | |
| } | |
| /** | |
| * Returns statistics about the last match the player played | |
| * | |
| * @return array The stats of the last match | |
| */ | |
| public function getLastMatchStats() { | |
| return $this->lastMatchStats; | |
| } | |
| /** | |
| * Returns a map of <var>CSSMap</var> for this user containing all CS:S | |
| * maps. | |
| * | |
| * If the maps haven't been parsed already, parsing is done now. | |
| * | |
| * @return array The map statistics for this user | |
| */ | |
| public function getMapStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if($this->mapStats == null) { | |
| $this->mapStats = array(); | |
| $mapsData = $this->xmlData->stats->maps; | |
| foreach(self::$MAPS as $mapName) { | |
| $this->mapStats[$mapName] = new CSSMap($mapName, $mapsData); | |
| } | |
| } | |
| return $this->mapStats; | |
| } | |
| /** | |
| * Returns overall statistics of this player | |
| * | |
| * @return array The overall statistics | |
| */ | |
| public function getTotalStats() { | |
| return $this->totalStats; | |
| } | |
| /** | |
| * Returns a map of <var>CSSWeapon</var> for this user containing all CS:S | |
| * weapons. | |
| * | |
| * If the weapons haven't been parsed already, parsing is done now. | |
| * | |
| * @return array The weapon statistics for this user | |
| */ | |
| public function getWeaponStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if($this->weaponStats == null) { | |
| $this->weaponStats = array(); | |
| $weaponData = $this->xmlData->stats->weapons; | |
| foreach(self::$WEAPONS as $weaponName) { | |
| $this->weaponStats[$weaponName] = new CSSWeapon($weaponName, $weaponData); | |
| } | |
| } | |
| return $this->weaponStats; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2010-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| /** | |
| * Represents the stats for a Counter-Strike: Source weapon for a specific user | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class CSSWeapon { | |
| /** | |
| * @var bool | |
| */ | |
| private $favorite; | |
| /** | |
| * @var int | |
| */ | |
| private $hits; | |
| /** | |
| * @var int | |
| */ | |
| private $kills; | |
| /** | |
| * @var string | |
| */ | |
| private $name; | |
| /** | |
| * @var int | |
| */ | |
| private $shots; | |
| /** | |
| * Creates a new instance of a Counter-Strike: Source weapon based on the | |
| * given XML data | |
| * | |
| * @param string $weaponName The name of the weapon | |
| * @param SimpleXMLElement $weaponsData The XML data of all weapons | |
| */ | |
| public function __construct($weaponName, SimpleXMLElement $weaponsData) { | |
| $this->name = $weaponName; | |
| $this->favorite = ((string) $weaponsData->favorite) == $this->name; | |
| $this->kills = (int) $weaponsData->{"{$this->name}_kills"}; | |
| if($this->name != 'grenade' && $this->name != 'knife') { | |
| $this->hits = (int) $weaponsData->{"{$this->name}_hits"}; | |
| $this->shots = (int) $weaponsData->{"{$this->name}_shots"}; | |
| } | |
| } | |
| /** | |
| * Returns whether this weapon is the favorite weapon of this player | |
| * | |
| * @return bool <var>true</var> if this is the favorite weapon | |
| */ | |
| public function isFavorite() { | |
| return $this->favorite; | |
| } | |
| /** | |
| * Returns the accuracy of this player with this weapon | |
| * | |
| * @return float The accuracy with this weapon | |
| */ | |
| public function getAccuracy() { | |
| return ($this->shots > 0) ? $this->hits / $this->shots : 0; | |
| } | |
| /** | |
| * Returns the number of hits achieved with this weapon | |
| * | |
| * @return int The number of hits achieved | |
| */ | |
| public function getHits() { | |
| return $this->hits; | |
| } | |
| /** | |
| * Returns the number of kills achieved with this weapon | |
| * | |
| * @return int The number of kills achieved | |
| */ | |
| public function getKills() { | |
| return $this->kills; | |
| } | |
| /** | |
| * Returns the kill-shot-ratio of this player with this weapon | |
| * | |
| * @return float The kill-shot-ratio | |
| */ | |
| public function getKsRatio() { | |
| return ($this->shots > 0) ? $this->kills / $this->shots : 0; | |
| } | |
| /** | |
| * Returns the name of this weapon | |
| * | |
| * @return string The name of this weapon | |
| */ | |
| public function getName() { | |
| return $this->name; | |
| } | |
| /** | |
| * Returns the number of shots fired with this weapon | |
| * | |
| * @return int The number of shots fired | |
| */ | |
| public function getShots() { | |
| return $this->shots; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameStats.php'; | |
| /** | |
| * This class represents the game statistics for a single user in Defense Grid: | |
| * The Awakening | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class DefenseGridStats extends GameStats { | |
| /** | |
| * @var array | |
| */ | |
| private $alienStats; | |
| /** | |
| * @var int | |
| */ | |
| private $bronzeMedals; | |
| /** | |
| * @var float | |
| */ | |
| private $damage; | |
| /** | |
| * @var float | |
| */ | |
| private $damageCampaign; | |
| /** | |
| * @var float | |
| */ | |
| private $damageChallenge; | |
| /** | |
| * @var int | |
| */ | |
| private $encountered; | |
| /** | |
| * @var int | |
| */ | |
| private $goldMedals; | |
| /** | |
| * @var float | |
| */ | |
| private $heatDamage; | |
| /** | |
| * @var int | |
| */ | |
| private $interest; | |
| /** | |
| * @var int | |
| */ | |
| private $killed; | |
| /** | |
| * @var int | |
| */ | |
| private $killedCampaign; | |
| /** | |
| * @var int | |
| */ | |
| private $killedChallenge; | |
| /** | |
| * @var int | |
| */ | |
| private $levelsPlayed; | |
| /** | |
| * @var int | |
| */ | |
| private $levelsPlayedCampaign; | |
| /** | |
| * @var int | |
| */ | |
| private $levelsPlayedChallenge; | |
| /** | |
| * @var int | |
| */ | |
| private $levelsWon; | |
| /** | |
| * @var int | |
| */ | |
| private $levelsWonCampaign; | |
| /** | |
| * @var int | |
| */ | |
| private $levelsWonChallenge; | |
| /** | |
| * @var int | |
| */ | |
| private $silverMedals; | |
| /** | |
| * @var float | |
| */ | |
| private $orbitalLaserDamage; | |
| /** | |
| * @var int | |
| */ | |
| private $orbitalLaserFired; | |
| /** | |
| * @var int | |
| */ | |
| private $resources; | |
| /** | |
| * @var float | |
| */ | |
| private $timePlayed; | |
| /** | |
| * @var array | |
| */ | |
| private $towerStats; | |
| /** | |
| * Creates a <var>DefenseGridStats</var> object by calling the super | |
| * constructor with the game name <var>"defensegrid:awakening"</var> | |
| * | |
| * @param string $steamId The custom URL or the 64bit Steam ID of the user | |
| */ | |
| public function __construct($steamId) { | |
| parent::__construct($steamId, 'defensegrid:awakening'); | |
| if($this->isPublic()) { | |
| $generalData = $this->xmlData->stats->general; | |
| $this->bronzeMedals = (int) $generalData->bronze_medals_won->value; | |
| $this->silverMedals = (int) $generalData->silver_medals_won->value; | |
| $this->goldMedals = (int) $generalData->gold_medals_won->value; | |
| $this->levelsPlayed = (int) $generalData->levels_played_total->value; | |
| $this->levelsPlayedCampaign = (int) $generalData->levels_played_campaign->value; | |
| $this->levelsPlayedChallenge = (int) $generalData->levels_played_challenge->value; | |
| $this->levelsWon = (int) $generalData->levels_won_total->value; | |
| $this->levelsWonCampaign = (int) $generalData->levels_won_campaign->value; | |
| $this->levelsWonChallenge = (int) $generalData->levels_won_challenge->value; | |
| $this->encountered = (int) $generalData->total_aliens_encountered->value; | |
| $this->killed = (int) $generalData->total_aliens_killed->value; | |
| $this->killedCampaign = (int) $generalData->total_aliens_killed_campaign->value; | |
| $this->killedChallenge = (int) $generalData->total_aliens_killed_challenge->value; | |
| $this->resources = (int) $generalData->resources_recovered->value; | |
| $this->heatDamage = (float) $generalData->heatdamage->value; | |
| $this->timePlayed = (float) $generalData->time_played->value; | |
| $this->interest = (float) $generalData->interest_gained->value; | |
| $this->damage = (float) $generalData->tower_damage_total->value; | |
| $this->damageCampaign = (float) $generalData->tower_damage_total_campaign->value; | |
| $this->damageChallenge = (float) $generalData->tower_damage_total_challenge->value; | |
| $this->orbitalLaserFired = (int) $this->xmlData->stats->orbitallaser->fired->value; | |
| $this->orbitalLaserDamage = (float) $this->xmlData->stats->orbitallaser->damage->value; | |
| } | |
| } | |
| /** | |
| * Returns stats about the aliens encountered by the player | |
| * | |
| * The array returned uses the names of the aliens as keys. Every value of | |
| * the array is an array containing the number of aliens encountered as the | |
| * first element and the number of aliens killed as the second element. | |
| * | |
| * @return array Stats about the aliens encountered | |
| */ | |
| public function getAlienStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->alienStats)) { | |
| $alienData = $this->xmlData->stats->aliens; | |
| $this->alienStats = array(); | |
| $aliens = array('bulwark', 'crasher', 'dart', 'decoy', 'drone', | |
| 'grunt', 'juggernaut', 'manta', 'racer', 'rumbler', 'seeker', | |
| 'spire', 'stealth', 'swarmer', 'turtle', 'walker'); | |
| foreach($aliens as $alien) { | |
| $this->alienStats[$alien] = array( | |
| (int) $alienData->$alien->encountered->value, | |
| (int) $alienData->$alien->killed->value | |
| ); | |
| } | |
| } | |
| return $this->alienStats; | |
| } | |
| /** | |
| * Returns the bronze medals won by this player | |
| * | |
| * @return int Bronze medals won | |
| */ | |
| public function getBronzeMedals() { | |
| return $this->bronzeMedals; | |
| } | |
| /** | |
| * Returns the damage done by this player | |
| * | |
| * @return float Damage done | |
| */ | |
| public function getDamage() { | |
| return $this->damage; | |
| } | |
| /** | |
| * Returns the damage done during the campaign by this player | |
| * | |
| * @return float Damage done during the campaign | |
| */ | |
| public function getDamageCampaign() { | |
| return $this->damageCampaign; | |
| } | |
| /** | |
| * Returns the damage done during challenges by this player | |
| * | |
| * @return float Damage done during challenges | |
| */ | |
| public function getDamageChallenge() { | |
| return $this->damageChallenge; | |
| } | |
| /** | |
| * Returns the aliens encountered by this player | |
| * | |
| * @return int Aliens encountered | |
| */ | |
| public function getEncountered() { | |
| return $this->encountered; | |
| } | |
| /** | |
| * Returns the gold medals won by this player | |
| * | |
| * @return int Gold medals won | |
| */ | |
| public function getGoldMedals() { | |
| return $this->goldMedals; | |
| } | |
| /** | |
| * Returns the heat damage done by this player | |
| * | |
| * @return float Heat damage done | |
| */ | |
| public function getHeatDamage() { | |
| return $this->heatDamage; | |
| } | |
| /** | |
| * Returns the interest gained by the player | |
| * | |
| * @return int Interest gained | |
| */ | |
| public function getInterest() { | |
| return $this->interest; | |
| } | |
| /** | |
| * Returns the aliens killed by the player | |
| * | |
| * @return int Aliens killed | |
| */ | |
| public function getKilled() { | |
| return $this->killed; | |
| } | |
| /** | |
| * Returns the aliens killed during the campaign by the player | |
| * | |
| * @return int Aliens killed during the campaign | |
| */ | |
| public function getKilledCampaign() { | |
| return $this->killedCampaign; | |
| } | |
| /** | |
| * Returns the aliens killed during challenges by the player | |
| * | |
| * @return int Aliens killed during challenges | |
| */ | |
| public function getKilledChallenge() { | |
| return $this->killedChallenge; | |
| } | |
| /** | |
| * Returns the number of levels played by the player | |
| * | |
| * @return int Number of levels played | |
| */ | |
| public function getLevelsPlayed() { | |
| return $this->levelsPlayed; | |
| } | |
| /** | |
| * Returns the number of levels played during the campaign by the player | |
| * | |
| * @return int Number of levels played during the campaign | |
| */ | |
| public function getLevelsPlayedCampaign() { | |
| return $this->levelsPlayedCampaign; | |
| } | |
| /** | |
| * Returns the number of levels played during challenges by the player | |
| * | |
| * @return int Number of levels played during challenges | |
| */ | |
| public function getLevelsPlayedChallenge() { | |
| return $this->levelsPlayedChallenge; | |
| } | |
| /** | |
| * Returns the number of levels won by the player | |
| * | |
| * @return int Number of levels won | |
| */ | |
| public function getLevelsWon() { | |
| return $this->levelsWon; | |
| } | |
| /** | |
| * Returns the number of levels won during the campaign by the player | |
| * | |
| * @return int Number of levels during the campaign won | |
| */ | |
| public function getLevelsWonCampaign() { | |
| return $this->levelsWonCampaign; | |
| } | |
| /** | |
| * Returns the number of levels won during challenges by the player | |
| * | |
| * @return int Number of levels during challenges won | |
| */ | |
| public function getLevelsWonChallenge() { | |
| return $this->levelsWonChallenge; | |
| } | |
| /** | |
| * Returns the damage dealt by the orbital laser | |
| * | |
| * @return float Damage dealt by the orbital laser | |
| */ | |
| public function getOrbitalLaserDamage() { | |
| return $this->orbitalLaserDamage; | |
| } | |
| /** | |
| * Returns the number of times the orbital lasers has been fired by the | |
| * player | |
| * | |
| * @return int Number of times the orbital laser has been fired | |
| */ | |
| public function getOrbitalLaserFired() { | |
| return $this->orbitalLaserFired; | |
| } | |
| /** | |
| * Returns the amount of resources harvested by the player | |
| * | |
| * @return int Resources harvested by the player | |
| */ | |
| public function getResources() { | |
| return $this->resources; | |
| } | |
| /** | |
| * Returns the silver medals won by this player | |
| * | |
| * @return int Silver medals won | |
| */ | |
| public function getSilverMedals() { | |
| return $this->silverMedals; | |
| } | |
| /** | |
| * Returns the time played in seconds by the player | |
| * | |
| * @return float Time played | |
| */ | |
| public function getTimePlayed() { | |
| return $this->timePlayed; | |
| } | |
| /** | |
| * Returns stats about the towers built by the player | |
| * | |
| * The array returned uses the names of the towers as keys. Every value of | |
| * the array is another array using the keys 1 to 3 for different tower | |
| * levels. | |
| * The values of these arrays is an array containing the number of towers | |
| * built as the first element and the damage dealt by this specific tower | |
| * type as the second element. | |
| * | |
| * The Command tower uses the resources gained as second element. | |
| * The Temporal tower doesn't have a second element. | |
| * | |
| * @return array Stats about the towers built | |
| */ | |
| public function getTowerStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->towerStats)) { | |
| $towerData = $this->xmlData->stats->towers; | |
| $this->towerStats = array(); | |
| $towers = array('cannon', 'flak', 'gun', 'inferno', 'laser', | |
| 'meteor', 'missile', 'tesla'); | |
| foreach($towers as $tower) { | |
| $this->towerStats[$tower] = array(); | |
| for($i = 1; $i <= 3; $i++) { | |
| $built = $towerData->xpath("{$tower}[@level=$i]/built/value"); | |
| $damage = $towerData->xpath("{$tower}[@level=$i]/damage/value"); | |
| $this->towerStats[$tower][$i] = array( | |
| (int) $built[0], | |
| (float) $damage[0] | |
| ); | |
| } | |
| } | |
| $this->towerStats['command'] = array(); | |
| for($i = 1; $i <= 3; $i++) { | |
| $built = $towerData->xpath("command[@level=$i]/built/value"); | |
| $resources = $towerData->xpath("command[@level=$i]/resource/value"); | |
| $this->towerStats['command'][$i] = array( | |
| (int) $built[0], | |
| (float) $resources[0] | |
| ); | |
| } | |
| $this->towerStats['temporal'] = array(); | |
| for($i = 1; $i <= 3; $i++) { | |
| $built = $towerData->xpath("temporal[@level=$i]/built/value"); | |
| $this->towerStats['temporal'][$i] = array( | |
| (int) $built[0] | |
| ); | |
| } | |
| } | |
| return $this->towerStats; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameClass.php'; | |
| /** | |
| * Represents the stats for a Day of Defeat: Source class for a specific user | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class DoDSClass extends GameClass { | |
| /** | |
| * @var int | |
| */ | |
| private $blocks; | |
| /** | |
| * @var int | |
| */ | |
| private $bombsDefused; | |
| /** | |
| * @var int | |
| */ | |
| private $bombsPlanted; | |
| /** | |
| * @var int | |
| */ | |
| private $captures; | |
| /** | |
| * @var int | |
| */ | |
| private $deaths; | |
| /** | |
| * @var int | |
| */ | |
| private $dominations; | |
| /** | |
| * @var string | |
| */ | |
| private $key; | |
| /** | |
| * @var int | |
| */ | |
| private $kills; | |
| /** | |
| * @var int | |
| */ | |
| private $roundsLost; | |
| /** | |
| * @var int | |
| */ | |
| private $roundsWon; | |
| /** | |
| * @var int | |
| */ | |
| private $revenges; | |
| /** | |
| * Creates a new instance of a Day of Defeat: Source class based on the | |
| * given XML data | |
| * | |
| * @param SimpleXMLElement $classData The XML data of the class | |
| */ | |
| public function __construct(SimpleXMLElement $classData) { | |
| $this->blocks = (int) $classData->blocks; | |
| $this->bombsDefused = (int) $classData->bombsdefused; | |
| $this->bombsPlanted = (int) $classData->bombsplanted; | |
| $this->captures = (int) $classData->captures; | |
| $this->deaths = (int) $classData->deaths; | |
| $this->dominations = (int) $classData->dominations; | |
| $this->key = (string) $classData['key']; | |
| $this->kills = (int) $classData->kills; | |
| $this->name = (string) $classData->name; | |
| $this->playTime = (int) $classData->playtime; | |
| $this->roundsLost = (int) $classData->roundslost; | |
| $this->roundsWon = (int) $classData->roundswon; | |
| $this->revenges = (int) $classData->revenges; | |
| } | |
| /** | |
| * Returns the blocks achieved by the player with this class | |
| * | |
| * @return int The blocks achieved by the player | |
| */ | |
| public function getBlocks() { | |
| return $this->blocks; | |
| } | |
| /** | |
| * Returns the bombs defused by the player with this class | |
| * | |
| * @return int The bombs defused by the player | |
| */ | |
| public function getBombsDefuse() { | |
| return $this->bombsDefused; | |
| } | |
| /** | |
| * Returns the bombs planted by the player with this class | |
| * | |
| * @return int the bombs planted by the player | |
| */ | |
| public function getBombsPlanted() { | |
| return $this->bombsPlanted; | |
| } | |
| /** | |
| * Returns the number of points captured by the player with this class | |
| * | |
| * @return int The number of points captured by the player | |
| */ | |
| public function getCaptures() { | |
| return $this->captures; | |
| } | |
| /** | |
| * Returns the number of times the player died with this class | |
| * | |
| * @return int The number of deaths by the player | |
| */ | |
| public function getDeaths() { | |
| return $this->deaths; | |
| } | |
| /** | |
| * Returns the dominations achieved by the player with this class | |
| * | |
| * @return int The dominations achieved by the player | |
| */ | |
| public function getDominations() { | |
| return $this->dominations; | |
| } | |
| /** | |
| * Returns the ID of this class | |
| * | |
| * @return string The ID of this class | |
| */ | |
| public function getKey() { | |
| return $this->key; | |
| } | |
| /** | |
| * Returns the number of enemies killed by the player with this class | |
| * | |
| * @return int The number of enemies killed by the player | |
| */ | |
| public function getKills() { | |
| return $this->kills; | |
| } | |
| /** | |
| * Returns the revenges achieved by the player with this class | |
| * | |
| * @return int The revenges achieved by the player | |
| */ | |
| public function getRevenges() { | |
| return $this->revenges; | |
| } | |
| /** | |
| * Returns the number of rounds lost with this class | |
| * | |
| * @return int The number of rounds lost with this class | |
| */ | |
| public function getRoundsLost() { | |
| return $this->roundsLost; | |
| } | |
| /** | |
| * Returns the number of rounds won with this class | |
| * | |
| * @return int The number of rounds won with this class | |
| */ | |
| public function getRoundsWon() { | |
| return $this->roundsWon; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameStats.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/dods/DoDSClass.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/dods/DoDSWeapon.php'; | |
| /** | |
| * The is class represents the game statistics for a single user in Day of | |
| * Defeat: Source | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class DoDSStats extends GameStats { | |
| private $classStats; | |
| private $weaponStats; | |
| /** | |
| * Creates a <var>DoDSStats</var> instance by calling the super constructor | |
| * with the game name <var>"DoD:S"</var> | |
| * | |
| * @param string $steamId The custom URL or 64bit Steam ID of the user | |
| */ | |
| public function __construct($steamId) { | |
| parent::__construct($steamId, 'DoD:S'); | |
| } | |
| /** | |
| * Returns an array of <var>DoDSClass</var> for this user containing all | |
| * DoD:S classes. | |
| * | |
| * If the classes haven't been parsed already, parsing is done now. | |
| * | |
| * @return array The class statistics for this user | |
| */ | |
| public function getClassStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->classStats)) { | |
| $this->classStats = array(); | |
| foreach($this->xmlData->stats->classes->children() as $classData) { | |
| $this->classStats[(string) $classData['key']] = new DoDSClass($classData); | |
| } | |
| } | |
| return $this->classStats; | |
| } | |
| /** | |
| * Returns an array of <var>DoDSWeapon</var> for this user containing all | |
| * DoD:S weapons. | |
| * | |
| * If the weapons haven't been parsed already, parsing is done now. | |
| * | |
| * @return array The weapon statistics for this user | |
| */ | |
| public function getWeaponStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->weaponStats)) { | |
| foreach($this->xmlData->stats->weapons->children() as $classData) { | |
| $this->weaponStats[(string) $classData['key']] = new DoDSWeapon($classData); | |
| } | |
| } | |
| return $this->weaponStats; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameWeapon.php'; | |
| /** | |
| * Represents the stats for a Day of Defeat: Source weapon for a specific user | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class DoDSWeapon extends GameWeapon { | |
| /** | |
| * @var int | |
| */ | |
| private $headshots; | |
| /** | |
| * @var int | |
| */ | |
| private $hits; | |
| /** | |
| * @var string | |
| */ | |
| private $name; | |
| /** | |
| * Creates a new instance of a Day of Defeat: Source weapon based on the | |
| * given XML data | |
| * | |
| * @param SimpleXMLElement $weaponData The XML data of the class | |
| */ | |
| public function __construct(SimpleXMLElement $weaponData) { | |
| parent::__construct($weaponData); | |
| $this->headshots = (int) $weaponData->headshots; | |
| $this->id = (string) $weaponData['key']; | |
| $this->name = (string) $weaponData->name; | |
| $this->shots = (int) $weaponData->shotsfired; | |
| $this->hits = (int) $weaponData->shotshit; | |
| } | |
| /** | |
| * Returns the average number of hits needed for a kill with this weapon | |
| * | |
| * @return float The average number of hits needed for a kill | |
| */ | |
| public function getAvgHitsPerKill() { | |
| return $this->hits / $this->kills; | |
| } | |
| /** | |
| * Returns the percentage of headshots relative to the shots hit with this | |
| * weapon | |
| * | |
| * @return float The percentage of headshots | |
| */ | |
| public function getHeadshotPercentage() { | |
| return $this->headshots / $this->hits; | |
| } | |
| /** | |
| * Returns the number of headshots achieved with this weapon | |
| * | |
| * @return int The number of headshots achieved | |
| */ | |
| public function getHeadshots() { | |
| return $this->headshots; | |
| } | |
| /** | |
| * Returns the percentage of hits relative to the shots fired with this | |
| * weapon | |
| * | |
| * @return float The percentage of hits | |
| */ | |
| public function getHitPercentage() { | |
| return$this->hits / $this->shots; | |
| } | |
| /** | |
| * Returns the number of hits achieved with this weapon | |
| * | |
| * @return int The number of hits achieved | |
| */ | |
| public function getHits() { | |
| return $this->hits; | |
| } | |
| /** | |
| * Returns the name of this weapon | |
| * | |
| * @return string The name of this weapon | |
| */ | |
| public function getName() { | |
| return $this->name; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameInventory.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/dota2/DotA2Item.php'; | |
| /** | |
| * Represents the inventory of a player of the DotA 2 beta | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class DotA2BetaInventory extends GameInventory { | |
| const APP_ID = 205790; | |
| const ITEM_CLASS = 'DotA2Item'; | |
| /** | |
| * This checks the cache for an existing inventory. If it exists it is | |
| * returned. Otherwise a new inventory is created. | |
| * | |
| * @param string $steamId The 64bit Steam ID or vanity URL of the user | |
| * @param bool $fetchNow Whether the data should be fetched now | |
| * @param bool $bypassCache Whether the cache should be bypassed | |
| * @return DotA2BetaInventory The inventory created from the given options | |
| */ | |
| public static function createInventory($steamId, $fetchNow = true, $bypassCache = false) { | |
| return parent::create(self::APP_ID, $steamId, $fetchNow, $bypassCache); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameInventory.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/dota2/DotA2Item.php'; | |
| /** | |
| * Represents the inventory of a DotA 2 player | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class DotA2Inventory extends GameInventory { | |
| const APP_ID = 570; | |
| const ITEM_CLASS = 'DotA2Item'; | |
| /** | |
| * This checks the cache for an existing inventory. If it exists it is | |
| * returned. Otherwise a new inventory is created. | |
| * | |
| * @param string $steamId The 64bit Steam ID or vanity URL of the user | |
| * @param bool $fetchNow Whether the data should be fetched now | |
| * @param bool $bypassCache Whether the cache should be bypassed | |
| * @return DotA2Inventory The inventory created from the given options | |
| */ | |
| public static function createInventory($steamId, $fetchNow = true, $bypassCache = false) { | |
| return parent::create(self::APP_ID, $steamId, $fetchNow, $bypassCache); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2012-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameItem.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/dota2/DotA2Inventory.php'; | |
| /** | |
| * Represents a DotA 2 item | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class DotA2Item extends GameItem { | |
| /** | |
| * @var bool | |
| */ | |
| private $equipped; | |
| /** | |
| * Creates a new instance of a DotA2Item with the given data | |
| * | |
| * @param DotA2Inventory $inventory The inventory this item is contained | |
| * in | |
| * @param array $itemData The data specifying this item | |
| * @throws WebApiException on Web API errors | |
| */ | |
| public function __construct(DotA2Inventory $inventory, $itemData) { | |
| parent::__construct($inventory, $itemData); | |
| $this->equipped = property_exists($itemData, 'equipped') && sizeof($itemData->equipped) > 0; | |
| } | |
| /** | |
| * Returns whether this item is equipped by this player at all | |
| * | |
| * @return bool Whether this item is equipped by this player at all | |
| */ | |
| public function isEquipped() { | |
| return $this->equipped; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/WebApi.php'; | |
| /** | |
| * The GameAchievement class represents a specific achievement for a single | |
| * game and for a single user | |
| * | |
| * It also provides the ability to load the global unlock percentages of all | |
| * achievements of a specific game. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class GameAchievement { | |
| /** | |
| * @var string | |
| */ | |
| private $apiName; | |
| /** | |
| * @var SteamGame | |
| */ | |
| private $game; | |
| /** | |
| * @var string | |
| */ | |
| private $iconClosedUrl; | |
| /** | |
| * @var string | |
| */ | |
| private $iconOpenUrl; | |
| /** | |
| * @var string | |
| */ | |
| private $name; | |
| /** | |
| * @var int | |
| */ | |
| private $timestamp; | |
| /** | |
| * @var SteamId | |
| */ | |
| private $user; | |
| /** | |
| * @var bool | |
| */ | |
| private $unlocked; | |
| /** | |
| * Loads the global unlock percentages of all achievements for the given | |
| * game | |
| * | |
| * @param int $appId The unique Steam Application ID of the game (e.g. | |
| * <var>440</var> for Team Fortress 2). See | |
| * http://developer.valvesoftware.com/wiki/Steam_Application_IDs for | |
| * all application IDs | |
| * @return array The symbolic achievement names with the corresponding | |
| * global unlock percentages | |
| * @throws WebApiException if a request to Steam's Web API fails | |
| */ | |
| public static function getGlobalPercentages($appId) { | |
| $params = array('gameid' => $appId); | |
| $data = json_decode(WebApi::getJSON('ISteamUserStats', 'GetGlobalAchievementPercentagesForApp', 2, $params)); | |
| $percentages = array(); | |
| foreach($data->achievementpercentages->achievements as $achievementData) { | |
| $percentages[$achievementData->name] = (float) $achievementData->percent; | |
| } | |
| return $percentages; | |
| } | |
| /** | |
| * Creates the achievement with the given name for the given user and game | |
| * and achievement data | |
| * | |
| * @param SteamId $user The Steam ID of the player this achievement belongs | |
| * to | |
| * @param SteamGame $game The game this achievement belongs to | |
| * @param SimpleXMLElement $achievementData The achievement data extracted | |
| * from XML | |
| */ | |
| public function __construct(SteamId $user, SteamGame $game, SimpleXMLElement $achievementData) { | |
| $this->apiName = (string) $achievementData->apiname; | |
| $this->description = (string) $achievementData->description; | |
| $this->game = $game; | |
| $this->iconClosedUrl = (string) $achievementData->iconClosed; | |
| $this->iconOpenUrl = (string) $achievementData->iconOpen; | |
| $this->name = (string) $achievementData->name; | |
| $this->unlocked = (bool)(int) $achievementData->attributes()->closed; | |
| $this->user = $user; | |
| if($this->unlocked && $achievementData->unlockTimestamp != null) { | |
| $this->timestamp = (int) $achievementData->unlockTimestamp; | |
| } | |
| } | |
| /** | |
| * Returns the symbolic API name of this achievement | |
| * | |
| * @return string The API name of this achievement | |
| */ | |
| public function getApiName() { | |
| return $this->apiName; | |
| } | |
| /** | |
| * Returns the description of this achievement | |
| * | |
| * @return string The description of this achievement | |
| */ | |
| public function getDescription() { | |
| return $this->description; | |
| } | |
| /** | |
| * Returns the game this achievement belongs to | |
| * | |
| * @return SteamGame The game this achievement belongs to | |
| */ | |
| public function getGame() { | |
| return $this->game; | |
| } | |
| /** | |
| * Returns the url for the closed icon of this achievement | |
| * | |
| * @return string The url of the closed achievement icon | |
| */ | |
| public function getIconClosedUrl() { | |
| return $this->iconClosedUrl; | |
| } | |
| /** | |
| * Returns the url for the open icon of this achievement | |
| * | |
| * @return string The url of the open achievement icon | |
| */ | |
| public function getIconOpenUrl() { | |
| return $this->iconOpenUrl; | |
| } | |
| /** | |
| * Returns the name of this achievement | |
| * | |
| * @return string The name of this achievement | |
| */ | |
| public function getName() { | |
| return $this->name; | |
| } | |
| /** | |
| * Returns the time this achievement has been unlocked by its owner | |
| * | |
| * @return int The time this achievement has been unlocked | |
| */ | |
| public function getTimestamp() { | |
| return $this->timestamp; | |
| } | |
| /** | |
| * Returns the SteamID of the user who owns this achievement | |
| * | |
| * @return SteamId The SteamID of this achievement's owner | |
| */ | |
| public function getUser() { | |
| return $this->user; | |
| } | |
| /** | |
| * Returns whether this achievement has been unlocked by its owner | |
| * | |
| * @return bool <var>true</var> if the achievement has been unlocked by the | |
| * user | |
| */ | |
| public function isUnlocked() { | |
| return $this->unlocked; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| /** | |
| * An abstract class implementing basic functionality for classes representing | |
| * player classes | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| abstract class GameClass { | |
| /** | |
| * @var String | |
| */ | |
| protected $name; | |
| /** | |
| * @var float | |
| */ | |
| protected $playtime; | |
| /** | |
| * Returns the name of this class | |
| * | |
| * @return string The name of this class | |
| */ | |
| public function getName() { | |
| return $this->name; | |
| } | |
| /** | |
| * Returns the time in minutes the player has played with this class | |
| * | |
| * @return int The time this class has been played | |
| */ | |
| public function getPlayTime() { | |
| return $this->playtime; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2011-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameItem.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameItemSchema.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/SteamId.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/WebApi.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/dota2/DotA2BetaInventory.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/dota2/DotA2Inventory.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/portal2/Portal2Inventory.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2BetaInventory.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Inventory.php'; | |
| /** | |
| * Provides basic functionality to represent an inventory of player in a game | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class GameInventory { | |
| const ITEM_CLASS = 'GameItem'; | |
| /** | |
| * @var array | |
| */ | |
| public static $cache = array(); | |
| /** | |
| * @var string | |
| */ | |
| public static $schemaLanguage = 'en'; | |
| /** | |
| * @var int | |
| */ | |
| protected $appId; | |
| /** | |
| * @var int | |
| */ | |
| protected $fetchDate; | |
| /** | |
| * @var GameItemSchema | |
| */ | |
| protected $itemSchema; | |
| /** | |
| * @var array | |
| */ | |
| protected $items; | |
| /** | |
| * @var array | |
| */ | |
| protected $preliminaryItems; | |
| /** | |
| * @var string | |
| */ | |
| protected $steamId64; | |
| /** | |
| * @var SteamId | |
| */ | |
| protected $user; | |
| /** | |
| * Clears the inventory cache | |
| */ | |
| public static function clearCache() { | |
| self::$cache = array(); | |
| } | |
| /** | |
| * This checks the cache for an existing inventory. If it exists it is | |
| * returned. Otherwise a new inventory is created. | |
| * | |
| * @param int $appId The application ID of the game | |
| * @param string $steamId The 64bit Steam ID or the vanity URL of the user | |
| * @param bool $fetchNow Whether the data should be fetched now | |
| * @param bool $bypassCache Whether the cache should be bypassed | |
| * @return GameInventory | |
| */ | |
| public static function create($appId, $steamId, $fetchNow = true, $bypassCache = false) { | |
| if (is_numeric($steamId)) { | |
| $steamId64 = $steamId; | |
| } else { | |
| $steamId64 = SteamId::resolveVanityUrl($steamId); | |
| } | |
| if (self::isCached($appId, $steamId64) && !$bypassCache) { | |
| $inventory = self::$cache[$appId][$steamId64]; | |
| if ($fetchNow && !$inventory->isFetched()) { | |
| $inventory->fetch(); | |
| } | |
| return $inventory; | |
| } else { | |
| switch ($appId) { | |
| case Dota2BetaInventory::APP_ID: | |
| $inventoryClass = 'Dota2BetaInventory'; | |
| break; | |
| case Dota2Inventory::APP_ID: | |
| $inventoryClass = 'Dota2Inventory'; | |
| break; | |
| case Portal2Inventory::APP_ID: | |
| $inventoryClass = 'Portal2Inventory'; | |
| break; | |
| case TF2BetaInventory::APP_ID: | |
| $inventoryClass = 'TF2BetaInventory'; | |
| break; | |
| case TF2Inventory::APP_ID: | |
| $inventoryClass = 'TF2Inventory'; | |
| break; | |
| default: | |
| $inventoryClass = 'GameInventory'; | |
| } | |
| return new $inventoryClass($appId, $steamId64, $fetchNow); | |
| } | |
| } | |
| /** | |
| * Returns whether the requested inventory is already cached | |
| * | |
| * @param int $appId The application ID of the game | |
| * @param string $steamId64 The 64bit Steam ID of the user | |
| * @return bool <var>true</var> if the inventory of the given user for the | |
| * given game is already cached | |
| */ | |
| public static function isCached($appId, $steamId64) { | |
| return array_key_exists($appId, self::$cache) && | |
| array_key_exists($steamId64, self::$cache[$appId]); | |
| } | |
| /** | |
| * Sets the language the schema should be fetched in (default is: | |
| * <var>'en'</var>) | |
| * | |
| * @param string $language The language code for the language item | |
| * descriptions should be fetched in | |
| */ | |
| public static function setSchemaLanguage($language) { | |
| self::$schemaLanguage = $language; | |
| } | |
| /** | |
| * Creates a new inventory object for the given user. This calls | |
| * <var>fetch()</var> to update the data and create the GameItem instances | |
| * contained in this player's inventory | |
| * | |
| * @param int $appId The application ID of the game | |
| * @param string $steamId64 The 64bit Steam ID of the user | |
| * @param bool $fetchNow Whether the data should be fetched now | |
| * @throws WebApiException on Web API errors | |
| */ | |
| protected function __construct($appId, $steamId64, $fetchNow = true) { | |
| $this->appId = $appId; | |
| $this->steamId64 = $steamId64; | |
| $this->user = SteamId::create($steamId64, false); | |
| if ($fetchNow) { | |
| $this->fetch(); | |
| } | |
| $this->cache(); | |
| array_keys(self::$cache); | |
| array_keys(self::$cache[$appId]); | |
| } | |
| /** | |
| * Saves this inventory in the cache | |
| */ | |
| public function cache() { | |
| self::$cache[$this->appId][$this->steamId64] = $this; | |
| } | |
| /** | |
| * Updates the contents of the backpack using Steam Web API | |
| */ | |
| public function fetch() { | |
| $params = array('SteamID' => $this->steamId64); | |
| $result = WebApi::getJSONData("IEconItems_{$this->getAppId()}", 'GetPlayerItems', 1, $params); | |
| $this->items = array(); | |
| $this->preliminaryItems = array(); | |
| foreach ($result->items as $itemData) { | |
| if ($itemData != null) { | |
| $inventoryClass = new ReflectionClass(get_class($this)); | |
| $itemClass = $inventoryClass->getConstant('ITEM_CLASS'); | |
| $item = new $itemClass($this, $itemData); | |
| if ($item->isPreliminary()) { | |
| $this->preliminaryItems[] = $item; | |
| } else { | |
| $this->items[$item->getBackpackPosition() - 1] = $item; | |
| } | |
| } | |
| } | |
| $this->fetchDate = time(); | |
| } | |
| /** | |
| * Returns the application ID of the game this inventory belongs to | |
| * | |
| * @return int The application ID of the game this inventory belongs to | |
| */ | |
| public function getAppId() { | |
| return $this->appId; | |
| } | |
| /** | |
| * Returns the item at the given position in the backpack. The positions | |
| * range from 1 to 100 instead of the usual array indices (0 to 99). | |
| * | |
| * @param int $index The position of the item in the backpack | |
| * @return GameItem The item at the given position | |
| */ | |
| public function getItem($index) { | |
| return $this->items[$index - 1]; | |
| } | |
| /** | |
| * Returns the item schema | |
| * | |
| * The item schema is fetched first if not done already | |
| * | |
| * @return GameItemSchema The item schema for the game this inventory belongs to | |
| * @throws WebApiException on Web API errors | |
| */ | |
| public function getItemSchema() { | |
| if ($this->itemSchema == null) { | |
| $this->itemSchema = GameItemSchema::create($this->appId, self::$schemaLanguage); | |
| } | |
| return $this->itemSchema; | |
| } | |
| /** | |
| * Returns an array of all items in this players inventory. | |
| * | |
| * @return array All items in the backpack | |
| */ | |
| public function getItems() { | |
| return $this->items; | |
| } | |
| /** | |
| * Returns an array of all items that this player just found or traded | |
| * | |
| * @return array All preliminary items of the inventory | |
| */ | |
| public function getPreliminaryItems() { | |
| return $this->preliminaryItems; | |
| } | |
| /** | |
| * Returns the Steam ID of the player owning this inventory | |
| * | |
| * @return SteamId The Steam ID of the owner of this inventory | |
| */ | |
| public function getUser() { | |
| return $this->user; | |
| } | |
| /** | |
| * Returns the 64bit SteamID of the player owning this inventory | |
| * | |
| * @return string The 64bit SteamID | |
| */ | |
| public function getSteamId64() { | |
| return $this->steamId64; | |
| } | |
| /** | |
| * Returns whether the items contained in this inventory have been already | |
| * fetched | |
| * | |
| * @return bool Whether the contents backpack have been fetched | |
| */ | |
| public function isFetched() { | |
| return !empty($this->fetchDate); | |
| } | |
| /** | |
| * Returns the number of items in the user's backpack | |
| * | |
| * @return int The number of items in the backpack | |
| */ | |
| public function size() { | |
| return sizeof($this->items); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2011-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameItem.php'; | |
| /** | |
| * Provides basic functionality to represent an item in a game | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class GameItem { | |
| /** | |
| * @var array | |
| */ | |
| private $attributes; | |
| /** | |
| * @var int | |
| */ | |
| private $backpackPosition; | |
| /** | |
| * @var int | |
| */ | |
| private $count; | |
| /** | |
| * @var bool | |
| */ | |
| private $craftable; | |
| /** | |
| * @var int | |
| */ | |
| private $defindex; | |
| /** | |
| * @var int | |
| */ | |
| private $id; | |
| /** | |
| * @var string | |
| */ | |
| private $itemClass; | |
| /** | |
| * @var int | |
| */ | |
| private $level; | |
| /** | |
| * @var string | |
| */ | |
| private $name; | |
| /** | |
| * @var string | |
| */ | |
| private $origin; | |
| /** | |
| * @var int | |
| */ | |
| private $originalId; | |
| /** | |
| * @var bool | |
| */ | |
| private $preliminary; | |
| /** | |
| * @var string | |
| */ | |
| private $quality; | |
| /** | |
| * @var bool | |
| */ | |
| private $tradeable; | |
| /** | |
| * @var string | |
| */ | |
| private $type; | |
| /** | |
| * Creates a new instance of a GameItem with the given data | |
| * | |
| * @param GameInventory $inventory The inventory this item is contained in | |
| * @param stdClass $itemData The data specifying this item | |
| * @throws WebApiException on Web API errors | |
| */ | |
| public function __construct(GameInventory $inventory, $itemData) { | |
| $this->inventory = $inventory; | |
| $this->defindex = $itemData->defindex; | |
| $this->backpackPosition = $itemData->inventory & 0xffff; | |
| $this->count = $itemData->quantity; | |
| $this->id = $itemData->id; | |
| $this->itemClass = $this->getSchemaData()->item_class; | |
| $this->level = $itemData->level; | |
| $this->name = $this->getSchemaData()->item_name; | |
| $origins = $this->inventory->getItemSchema()->getOrigins(); | |
| $this->originalId = $itemData->original_id; | |
| $this->preliminary = ($itemData->inventory & 0x40000000) != 0; | |
| $qualities = $this->inventory->getItemSchema()->getQualities(); | |
| $this->quality = $qualities[$itemData->quality]; | |
| $this->type = $this->getSchemaData()->item_type_name; | |
| if (property_exists($itemData, 'flag_cannot_craft')) { | |
| $this->craftable = !!$itemData->flag_cannot_craft; | |
| } | |
| if (!empty($this->getSchemaData()->item_set)) { | |
| $itemSets = $this->inventory->getItemSchema()->getItemSets(); | |
| $this->itemSet = $itemSets[$this->getSchemaData()->item_set]; | |
| } | |
| if (property_exists($itemData, 'origin')) { | |
| $this->origin = $origins[$itemData->origin]; | |
| } | |
| if (property_exists($itemData, 'flag_cannot_trade')) { | |
| $this->tradeable = !!$itemData->flag_cannot_trade; | |
| } | |
| $attributesData = array(); | |
| if (property_exists($this->getSchemaData(), 'attributes')) { | |
| $attributesData = (array) $this->getSchemaData()->attributes; | |
| } | |
| if (!empty($itemData->attributes)) { | |
| $attributesData = array_merge_recursive($attributesData, (array) $itemData->attributes); | |
| } | |
| $this->attributes = array(); | |
| foreach ($attributesData as $attributeData) { | |
| $attributeKey = property_exists($attributeData, 'defindex') ? | |
| $attributeData->defindex : $attributeData->name; | |
| if ($attributeKey != null) { | |
| $schemaAttributesData = $inventory->getItemSchema()->getAttributes(); | |
| $schemaAttributeData = $schemaAttributesData[$attributeKey]; | |
| $this->attributes[] = (object) array_merge_recursive((array) $attributeData, (array) $schemaAttributeData); | |
| } | |
| } | |
| } | |
| /** | |
| * Return the attributes of this item | |
| * | |
| * @return array The attributes of this item | |
| */ | |
| public function getAttributes() { | |
| return $this->attributes; | |
| } | |
| /** | |
| * Returns the position of this item in the player's inventory | |
| * | |
| * @return int The position of this item in the player's inventory | |
| */ | |
| public function getBackpackPosition() { | |
| return $this->backpackPosition; | |
| } | |
| /** | |
| * Returns the number of items the player owns of this item | |
| * | |
| * @return int The quanitity of this item | |
| */ | |
| public function getCount() { | |
| return $this->count; | |
| } | |
| /** | |
| * Returns the index where the item is defined in the schema | |
| * | |
| * @return int The schema index of this item | |
| */ | |
| public function getDefIndex() { | |
| return $this->defindex; | |
| } | |
| /** | |
| * Returns the ID of this item | |
| * | |
| * @return int The ID of this item | |
| */ | |
| public function getId() { | |
| return $this->id; | |
| } | |
| /** | |
| * Returns the class of this item | |
| * | |
| * @return string The class of this item | |
| */ | |
| public function getItemClass() { | |
| return $this->itemClass; | |
| } | |
| /** | |
| * Returns the level of this item | |
| * | |
| * @return int The level of this item | |
| */ | |
| public function getLevel() { | |
| return $this->level; | |
| } | |
| /** | |
| * Returns the level of this item | |
| * | |
| * @return string The level of this item | |
| */ | |
| public function getName() { | |
| return $this->name; | |
| } | |
| /** | |
| * Returns the original ID of this item | |
| * | |
| * @return int The original ID of this item | |
| */ | |
| public function getOriginalId() { | |
| return $this->originalId; | |
| } | |
| /** | |
| * Returns the quality of this item | |
| * | |
| * @return string The quality of this item | |
| */ | |
| public function getQuality() { | |
| return $this->quality; | |
| } | |
| /** | |
| * Returns the data for this item that's defined in the item schema | |
| * | |
| * @return array The schema data for this item | |
| * @throws SteamCondenserException if the item schema cannot be loaded | |
| */ | |
| public function getSchemaData() { | |
| $schemaItems = $this->inventory->getItemSchema()->getItems(); | |
| return $schemaItems[$this->defindex]; | |
| } | |
| /** | |
| * Returns the type of this item | |
| * | |
| * @return string The type of this item | |
| */ | |
| public function getType() { | |
| return $this->type; | |
| } | |
| /** | |
| * Returns whether this item is craftable | |
| * | |
| * @return bool <var>true</var> if this item is craftable | |
| */ | |
| public function isCraftable() { | |
| return $this->craftable; | |
| } | |
| /** | |
| * Returns whether this item is preliminary | |
| * | |
| * Preliminary means that this item was just found or traded and has not | |
| * yet been added to the inventory | |
| * | |
| * @return bool <var>true</var> if this item is preliminary | |
| */ | |
| public function isPreliminary() { | |
| return $this->preliminary; | |
| } | |
| /** | |
| * Returns whether this item is tradeable | |
| * | |
| * @return bool <var>true</var> if this item is tradeable | |
| */ | |
| public function isTradeable() { | |
| return $this->tradeable; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/WebApi.php'; | |
| /** | |
| * Provides item definitions and related data that specify the items of a game | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class GameItemSchema { | |
| /** | |
| * @var array | |
| */ | |
| public static $cache = array(); | |
| /** | |
| * @var int | |
| */ | |
| private $appId; | |
| /** | |
| * @var array | |
| */ | |
| private $attributes; | |
| /** | |
| * @var array | |
| */ | |
| private $effects; | |
| /** | |
| * @var int | |
| */ | |
| private $fetchDate; | |
| /** | |
| * @var array | |
| */ | |
| private $itemLevels; | |
| /** | |
| * @var array | |
| */ | |
| private $itemNames; | |
| /** | |
| * @var array | |
| */ | |
| private $itemSets; | |
| /** | |
| * @var array | |
| */ | |
| private $items; | |
| /** | |
| * @var string | |
| */ | |
| private $language; | |
| /** | |
| * @var array | |
| */ | |
| private $origins; | |
| /** | |
| * @var array | |
| */ | |
| private $qualities; | |
| /** | |
| * Clears the item schema cache | |
| */ | |
| public static function clearCache() { | |
| self::$cache = array(); | |
| } | |
| /** | |
| * Creates a new item schema for the game with the given application ID and | |
| * with descriptions in the given language | |
| * | |
| * @param int $appId The application ID of the game | |
| * @param string $language The language of description strings | |
| * @param bool $fetch if <var>true</var> the schemas's data is fetched | |
| * after creation | |
| * @param bool $bypassCache if <var>true</var> the schemas's data is | |
| * fetched again even if it has been cached already | |
| * @return GameInventory The item schema for the given game and language | |
| */ | |
| public static function create($appId, $language, $fetch = true, $bypassCache = false) { | |
| if (GameItemSchema::isCached($appId, $language) && !$bypassCache) { | |
| $itemSchema = self::$cache[$appId][$language]; | |
| if ($fetch && !$itemSchema->isFetched()) { | |
| $itemSchema->fetch(); | |
| } | |
| return $itemSchema; | |
| } else { | |
| return new GameItemSchema($appId, $language, $fetch); | |
| } | |
| } | |
| /** | |
| * Returns whether the item schema for the given application ID and | |
| * language is already cached | |
| * | |
| * @param int $appId The application ID of the game | |
| * @param string $language The language of the item schema | |
| * @return bool <var>true</var> if the object with the given ID is already | |
| * cached | |
| */ | |
| public static function isCached($appId, $language) { | |
| return array_key_exists($appId, self::$cache) && | |
| array_key_exists($language, self::$cache[$appId]); | |
| } | |
| /** | |
| * Creates a new item schema for the game with the given application ID and | |
| * with descriptions in the given language | |
| * | |
| * @param int $appId The application ID of the game | |
| * @param string $language The language of description strings | |
| * @param bool $fetch if <var>true</var> the schemas's data is fetched | |
| * after creation | |
| */ | |
| protected function __construct($appId, $language, $fetch) { | |
| $this->appId = $appId; | |
| $this->language = $language; | |
| if ($fetch) { | |
| $this->fetch(); | |
| } | |
| } | |
| /** | |
| * Updates the item definitions of this schema using the Steam Web API | |
| * | |
| * @throws WebApiException if the item schema cannot be fetched | |
| */ | |
| public function fetch() { | |
| $params = array('language' => $this->language); | |
| $data = WebApi::getJSONData("IEconItems_{$this->appId}", 'GetSchema', 1, $params); | |
| $this->attributes = array(); | |
| foreach ($data->attributes as $attribute) { | |
| $this->attributes[$attribute->defindex] = $attribute; | |
| $this->attributes[$attribute->name] = $attribute; | |
| } | |
| $this->effects = array(); | |
| foreach ($data->attribute_controlled_attached_particles as $effect) { | |
| $this->effects[$effect->id] = $effect; | |
| } | |
| $this->items = array(); | |
| $this->itemNames = array(); | |
| foreach ($data->items as $item) { | |
| $this->items[$item->defindex] = $item; | |
| $this->itemNames[$item->name] = $item->defindex; | |
| } | |
| if (!empty($data->levels)) { | |
| $this->itemLevels = array(); | |
| foreach ($data->item_levels as $itemLevelType) { | |
| $itemLevels = array(); | |
| foreach ($itemLevelType->levels as $itemLevel) { | |
| $itemLevels[$itemLevel->level] = $itemLevel->name; | |
| } | |
| $this->itemLevels[$itemLevelType->name] = $itemLevels; | |
| } | |
| } | |
| $this->itemSets = array(); | |
| foreach ($data->item_sets as $itemSet) { | |
| $this->itemSets[$itemSet->item_set] = $itemSet; | |
| } | |
| $this->origins = array(); | |
| foreach ($data->originNames as $origin) { | |
| $this->origins[$origin->origin] = $origin->name; | |
| } | |
| $this->qualities = array(); | |
| $index = -1; | |
| foreach ($data->qualities as $key => $value) { | |
| $index ++; | |
| if (property_exists($data->qualityNames, $key)) { | |
| $qualityName = $data->qualityNames->$key; | |
| } | |
| if (empty($qualityName)) { | |
| $qualityName = ucwords($key); | |
| } | |
| $this->qualities[$index] = $qualityName; | |
| } | |
| $this->cache(); | |
| $this->fetchDate = time(); | |
| } | |
| /** | |
| * Returns whether the data for this item schema has already been fetched | |
| * | |
| * @return bool <var>true</var> if this item schema's data is available | |
| */ | |
| public function isFetched() { | |
| return $this->fetchDate != null; | |
| } | |
| /** | |
| * Returns the application ID of the game this item schema belongs to | |
| * | |
| * @return int The application ID of the game | |
| */ | |
| public function getAppId() { | |
| return $this->appId; | |
| } | |
| /** | |
| * The attributes defined for this game's items | |
| * | |
| * @return array This item schema's attributes | |
| */ | |
| public function getAttributes() { | |
| return $this->attributes; | |
| } | |
| /** | |
| * The effects defined for this game's items | |
| * | |
| * @return array This item schema's effects | |
| */ | |
| public function getEffects() { | |
| return $this->effects; | |
| } | |
| /** | |
| * The levels defined for this game's items | |
| * | |
| * @return array This item schema's item levels | |
| */ | |
| public function getItemLevels() { | |
| return $this->itemLevels; | |
| } | |
| /** | |
| * A mapping from the item name to the item's defindex | |
| * | |
| * @return array The item name mapping | |
| */ | |
| public function getItemNames() { | |
| return $this->itemNames; | |
| } | |
| /** | |
| * The item sets defined for this game's items | |
| * | |
| * @return array This item schema's item sets | |
| */ | |
| public function getItemSets() { | |
| return $this->itemSets; | |
| } | |
| /** | |
| * The items defined for this game | |
| * | |
| * @return array The items in this schema | |
| */ | |
| public function getItems() { | |
| return $this->items; | |
| } | |
| /** | |
| * The language of this item schema | |
| * | |
| * @return string The language of this item schema | |
| */ | |
| public function getLanguage() { | |
| return $this->language; | |
| } | |
| /** | |
| * The item origins defined for this mµµ game's items | |
| * | |
| * @return array This item schema's origins | |
| */ | |
| public function getOrigins() { | |
| return $this->origins; | |
| } | |
| /** | |
| * The item qualities defined for this game's items | |
| * | |
| * @return array This item schema's qualities | |
| */ | |
| public function getQualities() { | |
| return $this->qualities; | |
| } | |
| /** | |
| * Saves this item schema in the cache | |
| */ | |
| private function cache() { | |
| self::$cache[$this->appId][$this->language] = $this; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2011, Nicholas Hastings | |
| * 2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameLeaderboardEntry.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/SteamId.php'; | |
| /** | |
| * The GameLeaderboard class represents a single leaderboard for a specific | |
| * game | |
| * | |
| * @author Nicholas Hastings | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class GameLeaderboard { | |
| const LEADERBOARD_DISPLAY_TYPE_NONE = 0; | |
| const LEADERBOARD_DISPLAY_TYPE_NUMERIC = 1; | |
| const LEADERBOARD_DISPLAY_TYPE_SECONDS = 2; | |
| const LEADERBOARD_DISPLAY_TYPE_MILLISECONDS = 3; | |
| const LEADERBOARD_SORT_METHOD_NONE = 0; | |
| const LEADERBOARD_SORT_METHOD_ASC = 1; | |
| const LEADERBOARD_SORT_METHOD_DESC = 2; | |
| /** | |
| * @var array | |
| */ | |
| private static $leaderboards = array(); | |
| /** | |
| * @var int | |
| */ | |
| protected $id; | |
| /** | |
| * @var string | |
| */ | |
| protected $url; | |
| /** | |
| * @var string | |
| */ | |
| protected $name; | |
| /** | |
| * @var int | |
| */ | |
| protected $entryCount; | |
| /** | |
| * @var int | |
| */ | |
| protected $sortMethod; | |
| /** | |
| * @var int | |
| */ | |
| protected $displayType; | |
| /** | |
| * Returns the leaderboard for the given game and leaderboard ID or name | |
| * | |
| * @param string $gameName The short name of the game | |
| * @param mixed $id The ID or name of the leaderboard to return | |
| * @return GameLeaderboard The matching leaderboard if available | |
| */ | |
| public static function getLeaderboard($gameName, $id) { | |
| $leaderboards = self::getLeaderboards($gameName); | |
| if(is_int($id)) { | |
| return $leaderboards[$id]; | |
| } else { | |
| foreach(array_values($leaderboards) as $board) { | |
| if($board->getName() == $id) { | |
| return $board; | |
| } | |
| } | |
| } | |
| } | |
| /** | |
| * Returns an array containing all of a game's leaderboards | |
| * | |
| * @param string $gameName The name of the game | |
| * @return array The leaderboards for this game | |
| */ | |
| public static function getLeaderboards($gameName) { | |
| if(!array_key_exists($gameName, self::$leaderboards)) { | |
| self::loadLeaderboards($gameName); | |
| } | |
| return self::$leaderboards[$gameName]; | |
| } | |
| /** | |
| * Loads the leaderboards of the specified games into the cache | |
| * | |
| * @param string $gameName The short name of the game | |
| * @throws SteamCondenserException if an error occurs while fetching the | |
| * leaderboards | |
| */ | |
| private static function loadLeaderboards($gameName) { | |
| $url = "http://steamcommunity.com/stats/$gameName/leaderboards/?xml=1"; | |
| $boardsData = new SimpleXMLElement(file_get_contents($url)); | |
| if(!empty($boardsData->error)) { | |
| throw new SteamCondenserException((string) $boardsData->error); | |
| } | |
| self::$leaderboards[$gameName] = array(); | |
| foreach($boardsData->leaderboard as $boardData) { | |
| $leaderboard = new GameLeaderboard($boardData); | |
| self::$leaderboards[$gameName][$leaderboard->getId()] = $leaderboard; | |
| } | |
| } | |
| /** | |
| * Creates a new leaderboard instance with the given XML data | |
| * | |
| * @param SimpleXMLElement $boardData The XML data of the leaderboard | |
| */ | |
| private function __construct(SimpleXMLElement $boardData) { | |
| $this->url = (string) $boardData->url; | |
| $this->id = (int) $boardData->lbid; | |
| $this->name = (string) $boardData->name; | |
| $this->entryCount = (int) $boardData->entries; | |
| $this->sortMethod = (int) $boardData->sortmethod; | |
| $this->displayType = (int) $boardData->displaytype; | |
| } | |
| /** | |
| * Returns the name of the leaderboard | |
| * | |
| * @return string The name of the leaderboard | |
| */ | |
| public function getName() { | |
| return $this->name; | |
| } | |
| /** | |
| * Returns the ID of the leaderboard | |
| * | |
| * @return int The ID of the leaderboard | |
| */ | |
| public function getId() { | |
| return $this->id; | |
| } | |
| /** | |
| * Returns the number of entries on this leaderboard | |
| * | |
| * @return int The number of entries on this leaderboard | |
| */ | |
| public function getEntryCount() { | |
| return $this->entryCount; | |
| } | |
| /** | |
| * Returns the method that is used to sort the entries on the leaderboard | |
| * | |
| * @return int The sort method | |
| */ | |
| public function getSortMethod() { | |
| return $this->sortMethod; | |
| } | |
| /** | |
| * Returns the display type of the scores on this leaderboard | |
| * | |
| * @return int The display type of the scores | |
| */ | |
| public function getDisplayType() { | |
| return $this->displayType; | |
| } | |
| /** | |
| * Returns the entry on this leaderboard for the user with the given | |
| * SteamID | |
| * | |
| * @param mixed $steamId The 64bit SteamID or the <var>SteamId</var> object | |
| * of the user | |
| * @return GameLeaderboardEntry The entry of the user if available | |
| */ | |
| public function getEntryForSteamId($steamId) { | |
| if(is_object($steamId)) { | |
| $id = $steamId->getSteamId64(); | |
| } else { | |
| $id = $steamId; | |
| } | |
| $fullurl = sprintf('%s&steamid=%s', $this->url, $id); | |
| $xml = new SimpleXMLElement(file_get_contents($fullurl)); | |
| if(!empty($xml->error)) { | |
| throw new SteamCondenserException((string) $xml->error); | |
| } | |
| foreach($xml->entries->entry as $entryData) { | |
| if($entryData->steamid == $id) { | |
| return new GameLeaderboardEntry($entryData, $this);; | |
| } | |
| } | |
| return null; | |
| } | |
| /** | |
| * Returns an array of entries on this leaderboard for the user with the | |
| * given SteamID and his/her friends | |
| * | |
| * @param mixed $steamId The 64bit SteamID or the <var>SteamId</var> object | |
| * of the user | |
| * @return array The entries of the user and his/her friends | |
| */ | |
| public function getEntryForSteamIdFriends($steamId) { | |
| if(is_object($steamId)) { | |
| $id = $steamId->getSteamId64(); | |
| } else { | |
| $id = $steamId; | |
| } | |
| $fullurl = sprintf('%s&steamid=%s', $this->url, $id); | |
| $xml = new SimpleXMLElement(file_get_contents($fullurl)); | |
| if(!empty($xml->error)) { | |
| throw new SteamCondenserException((string) $xml->error); | |
| } | |
| $entries = array(); | |
| foreach($xml->entries->entry as $entryData) { | |
| $rank = (int) $entryData->rank; | |
| $entries[$rank] = new GameLeaderboardEntry($entryData, $this); | |
| } | |
| return $entries; | |
| } | |
| /** | |
| * Returns the entries on this leaderboard for a given rank range | |
| * | |
| * The range is inclusive and a maximum of 5001 entries can be returned in | |
| * a single request. | |
| * | |
| * @param int $first The first entry to return from the leaderboard | |
| * @param int $last The last entry to return from the leaderboard | |
| * @return array The entries that match the given rank range | |
| */ | |
| public function getEntryRange($first, $last) { | |
| if($last < $first) { | |
| throw new SteamCondenserException('First entry must be prior to last entry for leaderboard entry lookup.'); | |
| } | |
| if(($last - $first) > 5000) { | |
| throw new SteamCondenserException('Leaderboard entry lookup is currently limited to a maximum of 5001 entries per request.'); | |
| } | |
| $fullurl = sprintf('%s&start=%d&end=%d', $this->url, $first, $last); | |
| $xml = new SimpleXMLElement(file_get_contents($fullurl)); | |
| if(!empty($xml->error)) { | |
| throw new SteamCondenserException((string) $xml->error); | |
| } | |
| $entries = array(); | |
| foreach($xml->entries->entry as $entryData) { | |
| $rank = (int) $entryData->rank; | |
| $entries[$rank] = new GameLeaderboardEntry($entryData, $this); | |
| } | |
| return $entries; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2011, Nicholas Hastings | |
| * 2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| /** | |
| * The GameLeaderboard class represents a single entry in a leaderboard | |
| * | |
| * @author Nicholas Hastings | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class GameLeaderboardEntry { | |
| /** | |
| * @var SteamId | |
| */ | |
| protected $steamId; | |
| /** | |
| * @var int | |
| */ | |
| protected $score; | |
| /** | |
| * @var int | |
| */ | |
| protected $rank; | |
| /** | |
| * @var GameLeaderboard | |
| */ | |
| protected $leaderboard; | |
| /** | |
| * Creates new entry instance for the given XML data and leaderboard | |
| * | |
| * @param SimpleXMLElement $entryData The XML data of the leaderboard of | |
| * the leaderboard entry | |
| * @param GameLeaderboard $leaderboard The leaderboard this entry belongs | |
| * to | |
| */ | |
| public function __construct(SimpleXMLElement $entryData, GameLeaderboard $leaderboard) { | |
| $this->steamId = SteamId::create((string) $entryData->steamid, false); | |
| $this->score = (int) $entryData->score; | |
| $this->rank = (int) $entryData->rank; | |
| $this->leaderboard = $leaderboard; | |
| } | |
| /** | |
| * Returns the Steam ID of this entry's player | |
| * | |
| * @return SteamId The Steam ID of the player | |
| */ | |
| public function getSteamId() { | |
| return $this->steamId; | |
| } | |
| /** | |
| * Returns the score of this entry | |
| * | |
| * @return int The score of this player | |
| */ | |
| public function getScore() { | |
| return $this->score; | |
| } | |
| /** | |
| * Returns the rank where this entry is listed in the leaderboard | |
| * | |
| * @return int The rank of this entry | |
| */ | |
| public function getRank() { | |
| return $this->rank; | |
| } | |
| /** | |
| * Returns the leaderboard this entry belongs to | |
| * | |
| * @return GameLeaderboard The leaderboard of this entry | |
| */ | |
| public function getLeaderboard() { | |
| return $this->leaderboard; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameAchievement.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameLeaderboard.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/XMLData.php'; | |
| /** | |
| * This class represents the game statistics for a single user and a specific | |
| * game | |
| * | |
| * It is subclassed for individual games if the games provide special | |
| * statistics that are unique to this game. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class GameStats extends XMLData { | |
| /** | |
| * @var array | |
| */ | |
| protected $achievements; | |
| /** | |
| * @var int | |
| */ | |
| protected $achievementsDone; | |
| /** | |
| * @var SteamGame | |
| */ | |
| protected $game; | |
| /** | |
| * @var SteamId | |
| */ | |
| protected $user; | |
| /** | |
| * Used to cache the XML data of the statistics for this game and this | |
| * user | |
| * | |
| * @var SimpleXMLElement | |
| */ | |
| protected $xmlData; | |
| /** | |
| * Creates a <var>GameStats</var> (or one of its subclasses) instance for | |
| * the given user and game | |
| * | |
| * @param string $steamId The custom URL or the 64bit Steam ID of the user | |
| * @param string $gameName The friendly name of the game | |
| * @return GameStats The game stats object for the given user and game | |
| */ | |
| public static function createGameStats($steamId, $gameName) { | |
| switch($gameName) { | |
| case 'alienswarm': | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/alien_swarm/AlienSwarmStats.php'; | |
| return new AlienSwarmStats($steamId); | |
| case 'cs:s': | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/css/CSSStats.php'; | |
| return new CSSStats($steamId); | |
| case 'defensegrid:awakening': | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/defense_grid/DefenseGridStats.php'; | |
| return new DefenseGridStats($steamId); | |
| case 'dod:s': | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/dods/DoDSStats.php'; | |
| return new DoDSStats($steamId); | |
| case 'l4d': | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/l4d/L4DStats.php'; | |
| return new L4DStats($steamId); | |
| case 'l4d2': | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/l4d/L4D2Stats.php'; | |
| return new L4D2Stats($steamId); | |
| case 'portal2': | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/portal2/Portal2Stats.php'; | |
| return new Portal2Stats($steamId); | |
| case 'tf2': | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Stats.php'; | |
| return new TF2Stats($steamId); | |
| default: | |
| return new GameStats($steamId, $gameName); | |
| } | |
| } | |
| /** | |
| * Returns the base Steam Community URL for the given player and game IDs | |
| * | |
| * @param string $userId The 64bit SteamID or custom URL of the user | |
| * @param mixed $gameId The application ID or short name of the game | |
| * @return string The base URL used for the given stats IDs | |
| */ | |
| protected static function _getBaseUrl($userId, $gameId) { | |
| $gameUrl = is_numeric($gameId) ? "appid/$gameId" : $gameId; | |
| if(is_numeric($userId)) { | |
| return "http://steamcommunity.com/profiles/$userId/stats/$gameUrl"; | |
| } else { | |
| return "http://steamcommunity.com/id/$userId/stats/$gameUrl"; | |
| } | |
| } | |
| /** | |
| * Creates a <var>GameStats</var> object and fetches data from the Steam | |
| * Community for the given user and game | |
| * | |
| * @param string $steamId The custom URL or the 64bit Steam ID of the user | |
| * @param string $gameId The app ID or friendly name of the game | |
| * @throws SteamCondenserException if the stats cannot be fetched | |
| */ | |
| protected function __construct($steamId, $gameId) { | |
| $this->user = SteamId::create($steamId, false); | |
| $url = self::_getBaseUrl($steamId, $gameId) . '?xml=all'; | |
| $this->xmlData = $this->getData($url); | |
| if($this->xmlData->error != null && !empty($this->xmlData->error)) { | |
| throw new SteamCondenserException((string) $this->xmlData->error); | |
| } | |
| $this->privacyState = (string) $this->xmlData->privacyState; | |
| if($this->isPublic()) { | |
| preg_match('#http://steamcommunity.com/+app/+([1-9][0-9]*)#', (string) $this->xmlData->game->gameLink, $appId); | |
| $this->game = SteamGame::create((int) $appId[1], $this->xmlData->game); | |
| $this->hoursPlayed = (string) $this->xmlData->stats->hoursPlayed; | |
| } | |
| } | |
| /** | |
| * Returns the achievements for this stats' user and game | |
| * | |
| * If the achievements' data hasn't been parsed yet, parsing is done now. | |
| * | |
| * @return array All achievements belonging to this game | |
| */ | |
| public function getAchievements() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->achievements)) { | |
| $this->achievementsDone = 0; | |
| foreach($this->xmlData->achievements->children() as $achievementData) { | |
| $this->achievements[] = new GameAchievement($this->user, $this->game, $achievementData); | |
| if((int) $achievementData->attributes()->closed) { | |
| $this->achievementsDone += 1; | |
| } | |
| } | |
| } | |
| return $this->achievements; | |
| } | |
| /** | |
| * Returns the number of achievements done by this player | |
| * | |
| * If achievements haven't been parsed yet for this player and this game, | |
| * parsing is done now. | |
| * | |
| * @return int The number of achievements completed | |
| * @see getAchievements() | |
| */ | |
| public function getAchievementsDone() { | |
| if(empty($this->achievements)) { | |
| $this->getAchievements(); | |
| } | |
| return $this->achievementsDone; | |
| } | |
| /** | |
| * Returns the percentage of achievements done by this player | |
| * <p> | |
| * If achievements haven't been parsed yet for this player and this game, | |
| * parsing is done now. | |
| * | |
| * @return float The percentage of achievements completed | |
| * @see #getAchievementsDone | |
| */ | |
| public function getAchievementsPercentage() { | |
| return $this->getAchievementsDone() / sizeof($this->achievements); | |
| } | |
| /** | |
| * Returns the base Steam Community URL for the stats contained in this | |
| * object | |
| * | |
| * @return string The base URL used for queries on these stats | |
| */ | |
| public function getBaseUrl() { | |
| return self::_getBaseUrl($this->user->getId(), $this->game->getId()); | |
| } | |
| /** | |
| * Returns the privacy setting of the Steam ID profile | |
| * | |
| * @return string The privacy setting of the Steam ID | |
| */ | |
| public function getPrivacyState() { | |
| return $this->privacyState; | |
| } | |
| /** | |
| * Returns the game these stats belong to | |
| * | |
| * @return SteamGame The game object | |
| */ | |
| public function getGame() { | |
| return $this->game; | |
| } | |
| /** | |
| * Returns the number of hours this game has been played by the player | |
| * | |
| * @return string The number of hours this game has been played | |
| */ | |
| public function getHoursPlayed() { | |
| return $this->hoursPlayed; | |
| } | |
| /** | |
| * Returns whether this Steam ID is publicly accessible | |
| * | |
| * @return bool <var>true</var> if this Steam ID is publicly accessible | |
| */ | |
| public function isPublic() { | |
| return $this->privacyState == 'public'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| /** | |
| * An abstract class implementing basic functionality for classes representing | |
| * game weapons | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| abstract class GameWeapon { | |
| protected $kills; | |
| protected $id; | |
| protected $shots; | |
| /** | |
| * Creates a new game weapon instance with the data provided | |
| * | |
| * @param SimpleXMLElement $weaponData The data representing this weapon | |
| */ | |
| public function __construct(SimpleXMLElement $weaponData) { | |
| $this->kills = (int) $weaponData->kills; | |
| } | |
| /** | |
| * Returns the average number of shots needed for a kill with this weapon | |
| * | |
| * @return float The average number of shots needed for a kill | |
| */ | |
| public function getAvgShotsPerKill() { | |
| return $this->shots / $this->kills; | |
| } | |
| /** | |
| * Returns the unique identifier for this weapon | |
| * | |
| * @return int The identifier of this weapon | |
| */ | |
| public function getId() { | |
| return $this->id; | |
| } | |
| /** | |
| * Returns the number of kills achieved with this weapon | |
| * | |
| * @return int The number of kills achieved | |
| */ | |
| public function getKills() { | |
| return $this->kills; | |
| } | |
| /** | |
| * Returns the number of shots fired with this weapon | |
| * | |
| * @return int The number of shots fired | |
| */ | |
| public function getShots() { | |
| return $this->shots; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameStats.php'; | |
| /** | |
| * This abstract class is a base class for statistics for Left4Dead and | |
| * Left4Dead 2. As both games have more or less the same statistics available | |
| * in the Steam Community the code for both is pretty much the same. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| abstract class AbstractL4DStats extends GameStats { | |
| /** | |
| * @var array The names of the special infected in Left4Dead | |
| */ | |
| protected static $SPECIAL_INFECTED = array('boomer', 'hunter', 'smoker', 'tank'); | |
| /** | |
| * @var array | |
| */ | |
| protected $favorites; | |
| /** | |
| * @var array | |
| */ | |
| protected $lifetimeStats; | |
| /** | |
| * @var array | |
| */ | |
| protected $mostRecentGame; | |
| /** | |
| * @var array | |
| */ | |
| protected $survivalStats; | |
| /** | |
| * @var array | |
| */ | |
| protected $teamplayStats; | |
| /** | |
| * @var array | |
| */ | |
| protected $versusStats; | |
| /** | |
| * @var array | |
| */ | |
| protected $weaponStats; | |
| /** | |
| * Creates a new instance of statistics for both, Left4Dead and Left4Dead 2 | |
| * parsing basic common data | |
| * | |
| * @param string $steamId The custom URL or 64bit Steam ID of the user | |
| * @param string $gameName The name of the game | |
| */ | |
| public function __construct($steamId, $gameName) { | |
| parent::__construct($steamId, $gameName); | |
| if($this->isPublic() && !empty($this->xmlData->stats->mostrecentgame)) { | |
| $this->mostRecentGame['difficulty'] = (string) $this->xmlData->stats->mostrecentgame->difficulty; | |
| $this->mostRecentGame['escaped'] = (bool) $this->xmlData->stats->mostrecentgame->bEscaped; | |
| $this->mostRecentGame['movie'] = (string) $this->xmlData->stats->mostrecentgame->movie; | |
| $this->mostRecentGame['timePlayed'] = (string) $this->xmlData->stats->mostrecentgame->time; | |
| } | |
| } | |
| /** | |
| * Returns an array of favorites for this user like weapons and character | |
| * | |
| * If the favorites haven't been parsed already, parsing is done now. | |
| * | |
| * @return array The favorites of this user | |
| */ | |
| public function getFavorites() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->favorites)) { | |
| $this->favorites = array(); | |
| $this->favorites['campaign'] = (string) $this->xmlData->stats->favorites->campaign; | |
| $this->favorites['campaignPercentage'] = (int) $this->xmlData->stats->favorites->campaignpct; | |
| $this->favorites['character'] = (string) $this->xmlData->stats->favorites->character; | |
| $this->favorites['characterPercentage'] = (int) $this->xmlData->stats->favorites->characterpct; | |
| $this->favorites['level1Weapon'] = (string) $this->xmlData->stats->favorites->weapon1; | |
| $this->favorites['level1Weapon1Percentage'] = (int) $this->xmlData->stats->favorites->weapon1pct; | |
| $this->favorites['level2Weapon'] = (string) $this->xmlData->stats->favorites->weapon2; | |
| $this->favorites['level2Weapon1Percentage'] = (int) $this->xmlData->stats->favorites->weapon2pct; | |
| } | |
| return $this->favorites; | |
| } | |
| /** | |
| * Returns an array of lifetime statistics for this user like the time | |
| * played | |
| * | |
| * If the lifetime statistics haven't been parsed already, parsing is done | |
| * now. | |
| * | |
| * @return array The lifetime statistics for this user | |
| */ | |
| public function getLifetimeStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->lifetimeStats)) { | |
| $this->lifetimeStats = array(); | |
| $this->lifetimeStats['finalesSurvived'] = (int) $this->xmlData->stats->lifetime->finales; | |
| $this->lifetimeStats['gamesPlayed'] = (int) $this->xmlData->stats->lifetime->gamesplayed; | |
| $this->lifetimeStats['finalesSurvivedPercentage'] = $this->lifetimeStats['finalesSurvived'] / $this->lifetimeStats['gamesPlayed']; | |
| $this->lifetimeStats['infectedKilled'] = (int) $this->xmlData->stats->lifetime->infectedkilled; | |
| $this->lifetimeStats['killsPerHour'] = (float) $this->xmlData->stats->lifetime->killsperhour; | |
| $this->lifetimeStats['avgKitsShared'] = (float) $this->xmlData->stats->lifetime->kitsshared; | |
| $this->lifetimeStats['avgKitsUsed'] = (float) $this->xmlData->stats->lifetime->kitsused; | |
| $this->lifetimeStats['avgPillsShared'] = (float) $this->xmlData->stats->lifetime->pillsshared; | |
| $this->lifetimeStats['avgPillsUsed'] = (float) $this->xmlData->stats->lifetime->pillused; | |
| $this->lifetimeStats['timePlayed'] = (string) $this->xmlData->stats->lifetime->timeplayed; | |
| } | |
| return $this->lifetimeStats; | |
| } | |
| /** | |
| * Returns an array of Survival statistics for this user like revived | |
| * teammates | |
| * | |
| * If the Survival statistics haven't been parsed already, parsing is done | |
| * now. | |
| * | |
| * @return array The Survival statistics for this user | |
| */ | |
| public function getSurvivalStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->survivalStats)) { | |
| $this->survivalStats = array(); | |
| $this->survivalStats['goldMedals'] = (int) $this->xmlData->stats->survival->goldmedals; | |
| $this->survivalStats['silverMedals'] = (int) $this->xmlData->stats->survival->silvermedals; | |
| $this->survivalStats['bronzeMedals'] = (int) $this->xmlData->stats->survival->bronzemedals; | |
| $this->survivalStats['roundsPlayed'] = (int) $this->xmlData->stats->survival->roundsplayed; | |
| $this->survivalStats['bestTime'] = (float) $this->xmlData->stats->survival->besttime; | |
| } | |
| return $this->survivalStats; | |
| } | |
| /** | |
| * Returns an array of teamplay statistics for this user like revived | |
| * teammates | |
| * | |
| * If the teamplay statistics haven't been parsed already, parsing is done | |
| * now. | |
| * | |
| * @return array The teamplay statistics for this | |
| */ | |
| public function getTeamplayStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->teamplayStats)) { | |
| $this->teamplayStats = array(); | |
| $this->teamplayStats['revived'] = (int) $this->xmlData->stats->teamplay->revived; | |
| $this->teamplayStats['mostRevivedDifficulty'] = (string) $this->xmlData->stats->teamplay->reviveddiff; | |
| $this->teamplayStats['avgRevived'] = (float) $this->xmlData->stats->teamplay->revivedavg; | |
| $this->teamplayStats['avgWasRevived'] = (float) $this->xmlData->stats->teamplay->wasrevivedavg; | |
| $this->teamplayStats['protected'] = (int) $this->xmlData->stats->teamplay->protected; | |
| $this->teamplayStats['mostProtectedDifficulty'] = (string) $this->xmlData->stats->teamplay->protecteddiff; | |
| $this->teamplayStats['avgProtected'] = (float) $this->xmlData->stats->teamplay->protectedavg; | |
| $this->teamplayStats['avgWasProtected'] = (float) $this->xmlData->stats->teamplay->wasprotectedavg; | |
| $this->teamplayStats['friendlyFireDamage'] = (int) $this->xmlData->stats->teamplay->ffdamage; | |
| $this->teamplayStats['mostFriendlyFireDifficulty'] = (string) $this->xmlData->stats->teamplay->ffdamagediff; | |
| $this->teamplayStats['avgFriendlyFireDamage'] = (float) $this->xmlData->stats->teamplay->ffdamageavg; | |
| } | |
| return $this->teamplayStats; | |
| } | |
| /** | |
| * Returns an array of Versus statistics for this user like percentage of | |
| * rounds won | |
| * | |
| * If the Versus statistics haven't been parsed already, parsing is done | |
| * now. | |
| * | |
| * @return array The Versus statistics for this user | |
| */ | |
| public function getVersusStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->versusStats)) { | |
| $this->versusStats = array(); | |
| $this->versusStats['gamesPlayed'] = (int) $this->xmlData->stats->versus->gamesplayed; | |
| $this->versusStats['gamesCompleted'] = (int) $this->xmlData->stats->versus->gamescompleted; | |
| $this->versusStats['finalesSurvived'] = (int) $this->xmlData->stats->versus->finales; | |
| $this->versusStats['finalesSurvivedPercentage'] = ($this->versusStats['gamesPlayed']) ? $this->versusStats['finalesSurvived'] / $this->versusStats['gamesPlayed'] : 0; | |
| $this->versusStats['points'] = (int) $this->xmlData->stats->versus->points; | |
| $this->versusStats['mostPointsInfected'] = (string) $this->xmlData->stats->versus->pointas; | |
| $this->versusStats['gamesWon'] = (int) $this->xmlData->stats->versus->gameswon; | |
| $this->versusStats['gamesLost'] = (int) $this->xmlData->stats->versus->gameslost; | |
| $this->versusStats['highestSurvivorScore'] = (int) $this->xmlData->stats->versus->survivorscore; | |
| foreach($this->SPECIAL_INFECTED() as $infected) { | |
| $this->versusStats[$infected] = array(); | |
| $this->versusStats[$infected]['specialAttacks'] = (int) $this->xmlData->stats->versus->{$infected . 'special'}; | |
| $this->versusStats[$infected]['mostDamage'] = (int) $this->xmlData->stats->versus->{$infected . 'dmg'}; | |
| $this->versusStats[$infected]['avgLifespan'] = (float) $this->xmlData->stats->versus->{$infected . 'lifespan'}; | |
| } | |
| } | |
| return $this->versusStats; | |
| } | |
| /** | |
| * Returns the names of the special infected in Left4Dead | |
| * | |
| * Hacky workaround for PHP not allowing arrays as class constants | |
| * | |
| * @return array The names of the special infected in Left4Dead | |
| */ | |
| protected function SPECIAL_INFECTED() { | |
| return self::$SPECIAL_INFECTED; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameWeapon.php'; | |
| /** | |
| * This abstract class is a base class for weapons in Left4Dead and Left4Dead 2 | |
| * as the weapon stats for both games are very similar | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| abstract class AbstractL4DWeapon extends GameWeapon { | |
| /** | |
| * @var string | |
| */ | |
| protected $accuracy; | |
| /** | |
| * @var string | |
| */ | |
| protected $headshotsPercentage; | |
| /** | |
| * @var string | |
| */ | |
| protected $killPercentage; | |
| /** | |
| * @var string | |
| */ | |
| protected $name; | |
| /** | |
| * @var string | |
| */ | |
| protected $shots; | |
| /** | |
| * Creates a new instance of weapon from the given XML data and parses | |
| * common data for both, <var>L4DWeapon</var> and <var>L4D2Weapon</var> | |
| * | |
| * @param SimpleXMLElement $weaponData The XML data for this weapon | |
| */ | |
| public function __construct(SimpleXMLElement $weaponData) { | |
| parent::__construct($weaponData); | |
| $this->accuracy = ((float) $weaponData->accuracy) * 0.01; | |
| $this->headshotsPercentage = ((float) $weaponData->headshots) * 0.01; | |
| $this->id = $weaponData->getName(); | |
| $this->shots = (int) $weaponData->shots; | |
| } | |
| /** | |
| * Returns the overall accuracy of the player with this weapon | |
| * | |
| * @return string The accuracy of the player with this weapon | |
| */ | |
| public function getAccuracy() { | |
| return $this->accuracy; | |
| } | |
| /** | |
| * Returns the percentage of kills with this weapon that have been | |
| * headshots | |
| * | |
| * @return string The percentage of headshots with this weapon | |
| */ | |
| public function getHeadshotsPercentage() { | |
| return $this->headshotsPercentage; | |
| } | |
| /** | |
| * Returns the ID of the weapon | |
| * | |
| * @return string The ID of the weapon | |
| */ | |
| public function getId() { | |
| return $this->id; | |
| } | |
| /** | |
| * Returns the percentage of overall kills of the player that have been | |
| * achieved with this weapon | |
| * | |
| * @return string The percentage of kills with this weapon | |
| */ | |
| public function getKillPercentage() { | |
| return $this->killPercentage; | |
| } | |
| /** | |
| * Returns the number of shots the player has fired with this weapon | |
| * | |
| * @return int The number of shots with this weapon | |
| */ | |
| public function getShots() { | |
| return $this->shots; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/SteamId.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/l4d/L4DMap.php'; | |
| /** | |
| * This class holds statistical information about a map played by a player in | |
| * Survival mode of Left4Dead 2 | |
| * | |
| * The basic information provided is more or less the same for Left4Dead and | |
| * Left4Dead 2, but parsing has to be done differently. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class L4D2Map extends L4DMap { | |
| /** | |
| * @var array The names of the special infected in Left4Dead 2 | |
| */ | |
| protected static $SPECIAL_INFECTED = array('boomer', 'charger', 'hunter', 'jockey', 'smoker', 'spitter', 'tank'); | |
| /** | |
| * @var array The items available in Left4Dead 2 | |
| */ | |
| private static $ITEMS = array('adrenaline', 'defibs', 'medkits', 'pills'); | |
| /** | |
| * @var array | |
| */ | |
| private $items; | |
| /** | |
| * @var array | |
| */ | |
| private $kills; | |
| /** | |
| * @var bool | |
| */ | |
| private $played; | |
| /** | |
| * @var array | |
| */ | |
| private $teammates; | |
| /** | |
| * Creates a new instance of a map based on the given XML data | |
| * | |
| * The map statistics for the Survival mode of Left4Dead 2 hold much more | |
| * information than those for Left4Dead, e.g. the teammates and items are | |
| * listed. | |
| * | |
| * @param SimpleXMLElement $mapData The XML data for this map | |
| */ | |
| public function __construct(SimpleXMLElement $mapData) { | |
| $this->bestTime = (float) $mapData->besttimeseconds; | |
| preg_match('#http://steamcommunity.com/public/images/gamestats/550/(.*)\.jpg#', (string) $mapData->img, $id); | |
| $this->id = $id[1]; | |
| $this->name = (string) $mapData->name; | |
| $this->played = ((int) $mapData->hasPlayed == 1); | |
| if($this->played) { | |
| $this->bestTime = (float) $mapData->besttimemilliseconds / 1000; | |
| $this->teammates = array(); | |
| foreach($mapData->teammates->children() as $teammate) { | |
| $this->teammates[] = new SteamId((string) $teammate, false); | |
| } | |
| $this->items = array(); | |
| foreach(self::$ITEMS as $item) { | |
| $this->items[$item] = (int) $mapData->{"item_$item"}; | |
| } | |
| $this->kills = array(); | |
| foreach(self::$INFECTED as $infected) { | |
| $this->kills[$infected] = (int) $mapData->{"kills_$infected"}; | |
| } | |
| switch((string) $mapData->medal) { | |
| case 'gold': | |
| $this->medal = self::GOLD; | |
| break; | |
| case 'silver': | |
| $this->medal = self::SILVER; | |
| break; | |
| case 'bronze': | |
| $this->medal = self::BRONZE; | |
| break; | |
| default: | |
| $this->medal = self::NONE; | |
| } | |
| } | |
| } | |
| /** | |
| * Returns statistics about the items used by the player on this map | |
| * | |
| * @return array The items used by the player | |
| */ | |
| public function getItems() { | |
| return $this->items; | |
| } | |
| /** | |
| * Returns the number of special infected killed by the player grouped by | |
| * the names of the special infected | |
| * | |
| * @return array The special infected killed by the player | |
| */ | |
| public function getKills() { | |
| return $this->kills; | |
| } | |
| /** | |
| * Returns the SteamIDs of the teammates of the player in his best game on | |
| * this map | |
| * | |
| * @return array The SteamIDs of the teammates in the best game | |
| */ | |
| public function getTeammates() { | |
| return $this->teammates; | |
| } | |
| /** | |
| * Returns whether the player has already played this map | |
| * | |
| * @return bool <var>true</var> if the player has already played this map | |
| */ | |
| public function isPlayed() { | |
| return $this->played; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/l4d/AbstractL4DStats.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/l4d/L4D2Map.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/l4d/L4D2Weapon.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/l4d/L4DExplosive.php'; | |
| /** | |
| * This class represents the game statistics for a single user in Left4Dead 2 | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class L4D2Stats extends AbstractL4DStats { | |
| /** | |
| * @var array The names of the special infected in Left4Dead 2 | |
| */ | |
| protected static $SPECIAL_INFECTED = array('boomer', 'charger', 'hunter', 'jockey', 'smoker', 'spitter', 'tank'); | |
| /** | |
| * @var array | |
| */ | |
| private $damagePercentages; | |
| /** | |
| * @var array | |
| */ | |
| private $scavengeStats; | |
| /** | |
| * Creates a <var>L4D2Stats</var> object by calling the super constructor | |
| * with the game name <var>"l4d2"</var> | |
| * | |
| * @param string $steamId The custom URL or 64bit Steam ID of the user | |
| */ | |
| public function __construct($steamId) { | |
| parent::__construct($steamId, 'l4d2'); | |
| $this->damagePercentages = array( | |
| 'melee' => (float) $this->xmlData->stats->weapons->meleePctDmg, | |
| 'pistols' => (float) $this->xmlData->stats->weapons->pistolsPctDmg, | |
| 'rifles' => (float) $this->xmlData->stats->weapons->bulletsPctDmg, | |
| 'shotguns' => (float) $this->xmlData->stats->weapons->shellsPctDmg | |
| ); | |
| } | |
| /** | |
| * Returns an array of lifetime statistics for this user like the time | |
| * played | |
| * | |
| * If the lifetime statistics haven't been parsed already, parsing is done | |
| * now. | |
| * | |
| * There are only a few additional lifetime statistics for Left4Dead 2 | |
| * which are not generated for Left4Dead, so this calls | |
| * <var>AbstractL4DStats#getLifetimeStats()</var> first and adds some | |
| * additional stats. | |
| * | |
| * @return array The lifetime statistics of the player in Left4Dead 2 | |
| */ | |
| public function getLifetimeStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->lifetimeStats)) { | |
| parent::getLifetimeStats(); | |
| $this->lifetimeStats['avgAdrenalineShared'] = (float) $this->xmlData->stats->lifetime->adrenalineshared; | |
| $this->lifetimeStats['avgAdrenalineUsed'] = (float) $this->xmlData->stats->lifetime->adrenalineused; | |
| $this->lifetimeStats['avgDefibrillatorsUsed'] = (float) $this->xmlData->stats->lifetime->defibrillatorsused; | |
| } | |
| return $this->lifetimeStats; | |
| } | |
| /** | |
| * Returns the percentage of damage done by this player with each weapon | |
| * type | |
| * | |
| * Available weapon types are <var>"melee"</var>, <var>"pistols"</var>, | |
| * <var>"rifles"</var> and <var>"shotguns"</var>. | |
| * | |
| * @return float The percentages of damage done with each weapon type | |
| */ | |
| public function getDamagePercentage() { | |
| return $this->DamagePercentage; | |
| } | |
| /** | |
| * Returns the percentage of damage done by this player with pistols | |
| * | |
| * @return float The percentage of damage done with pistols | |
| */ | |
| public function getPistolDamagePercentage() { | |
| return $this->pistolDamagePercentage; | |
| } | |
| /** | |
| * Returns the percentage of damage done by this player with rifles | |
| * | |
| * @return float The percentage of damage done with rifles | |
| */ | |
| public function getRifleDamagePercentage() { | |
| return $this->rifleDamagePercentage; | |
| } | |
| /** | |
| * Returns an array of Scavenge statistics for this user like the number of | |
| * Scavenge rounds played | |
| * | |
| * If the Scavenge statistics haven't been parsed already, parsing is done | |
| * now. | |
| * | |
| * @return array The Scavenge statistics of the player | |
| */ | |
| public function getScavengeStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->scavengeStats)) { | |
| $this->scavengeStats = array(); | |
| $this->scavengeStats['avgCansPerRound'] = (float) $this->xmlData->stats->scavenge->avgcansperround; | |
| $this->scavengeStats['perfectRounds'] = (int) $this->xmlData->stats->scavenge->perfect16canrounds; | |
| $this->scavengeStats['roundsLost'] = (int) $this->xmlData->stats->scavenge->roundslost; | |
| $this->scavengeStats['roundsPlayed'] = (int) $this->xmlData->stats->scavenge->roundsplayed; | |
| $this->scavengeStats['roundsWon'] = (int) $this->xmlData->stats->scavenge->roundswon; | |
| $this->scavengeStats['totalCans'] = (int) $this->xmlData->stats->scavenge->totalcans; | |
| $this->scavengeStats['maps'] = array(); | |
| foreach($this->xmlData->stats->scavenge->mapstats->children() as $mapData) { | |
| $map_id = (string) $mapData->name; | |
| $this->scavengeStats['maps'][$map_id] = array(); | |
| $this->scavengeStats['maps'][$map_id]['avgRoundScore'] = (int) $mapData->avgscoreperround; | |
| $this->scavengeStats['maps'][$map_id]['highestGameScore'] = (int) $mapData->highgamescore; | |
| $this->scavengeStats['maps'][$map_id]['highestRoundScore'] = (int) $mapData->avgscoreperround; | |
| $this->scavengeStats['maps'][$map_id]['name'] = (string) $mapData->fullname; | |
| $this->scavengeStats['maps'][$map_id]['roundsPlayed'] = (int) $mapData->roundsplayed; | |
| $this->scavengeStats['maps'][$map_id]['roundsWon'] = (int) $mapData->roundswon; | |
| } | |
| $this->scavengeStats['infected'] = array(); | |
| foreach($this->xmlData->stats->scavenge->infectedstats->children() as $infectedData) { | |
| $infectedId = (string) $infectedData->name; | |
| $this->scavengeStats['infected'][$infectedId] = array(); | |
| $this->scavengeStats['infected'][$infectedId]['maxDamagePerLife'] = (int) $infectedData->maxdmg1life; | |
| $this->scavengeStats['infected'][$infectedId]['maxPoursInterrupted'] = (int) $infectedData->maxpoursinterrupted; | |
| $this->scavengeStats['infected'][$infectedId]['specialAttacks'] = (int) $infectedData->specialattacks; | |
| } | |
| } | |
| return $this->scavengeStats; | |
| } | |
| /** | |
| * Returns the percentage of damage done by this player with shotguns | |
| * | |
| * @return float The percentage of damage done with shotguns | |
| */ | |
| public function getShotgunDamagePercentage() { | |
| return $this->shotgunDamagePercentage; | |
| } | |
| /** | |
| * Returns an array of Survival statistics for this user like revived | |
| * teammates | |
| * | |
| * If the Survival statistics haven't been parsed already, parsing is done | |
| * now. | |
| * | |
| * The XML layout for the Survival statistics for Left4Dead 2 differs a bit | |
| * from Left4Dead's Survival statistics. So we have to use a different way | |
| * of parsing for the maps and we use a different map class | |
| * (<var>L4D2Map</var>) which holds the additional information provided in | |
| * Left4Dead 2's statistics. | |
| * | |
| * @return array The Survival statistics of the player | |
| */ | |
| public function getSurvivalStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->survivalStats)) { | |
| parent::getSurvivalStats(); | |
| $this->survivalStats['maps'] = array(); | |
| foreach($this->xmlData->stats->survival->maps->children() as $mapData) { | |
| $map = new L4D2Map($mapData); | |
| $this->survivalStats['maps'][$map->getId()] = $map; | |
| } | |
| } | |
| return $this->survivalStats; | |
| } | |
| /** | |
| * Returns an array of <var>L4D2Weapon</var> for this user containing all | |
| * Left4Dead 2 weapons | |
| * | |
| * If the weapons haven't been parsed already, parsing is done now. | |
| * | |
| * @return array The weapon statistics for this player | |
| */ | |
| public function getWeaponStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->weaponStats)) { | |
| $this->weaponStats = array(); | |
| foreach($this->xmlData->stats->weapons->children() as $weaponData) { | |
| if(empty($weaponData)) { | |
| continue; | |
| } | |
| $weaponName = $weaponData->getName(); | |
| if(!in_array($weaponName, array('bilejars', 'molotov', 'pipes'))) { | |
| $weapon = new L4D2Weapon($weaponData); | |
| } | |
| else { | |
| $weapon = new L4DExplosive($weaponData); | |
| } | |
| $this->weaponStats[$weaponName] = $weapon; | |
| } | |
| } | |
| return $this->weaponStats; | |
| } | |
| /** | |
| * Returns the names of the special infected in Left4Dead 2 | |
| * | |
| * Hacky workaround for PHP not allowing arrays as class constants | |
| * | |
| * @return array The names of the special infected in Left4Dead 2 | |
| */ | |
| protected function SPECIAL_INFECTED() { | |
| return self::$SPECIAL_INFECTED; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/l4d/AbstractL4DWeapon.php'; | |
| /** | |
| * This class represents the statistics of a single weapon for a user in | |
| * Left4Dead 2 | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class L4D2Weapon extends AbstractL4DWeapon { | |
| /** | |
| * @var int | |
| */ | |
| private $damage; | |
| /** | |
| * @var string | |
| */ | |
| private $weaponGroup; | |
| /** | |
| * Creates a new instance of a weapon based on the given XML data | |
| * | |
| * @param SimpleXMLElement $weaponData The XML data of this weapon | |
| */ | |
| public function __construct(SimpleXMLElement $weaponData) { | |
| parent::__construct($weaponData); | |
| $this->damage = (int) $weaponData->damage; | |
| $this->killPercentage = ((float) $weaponData->pctkills) * 0.01; | |
| $this->weaponGroup = $weaponData['group']; | |
| } | |
| /** | |
| * Returns the amount of damage done by the player with this weapon | |
| * | |
| * @return int The damage done by this weapon | |
| */ | |
| public function getDamage() { | |
| return $this->damage; | |
| } | |
| /** | |
| * Returns the weapon group this weapon belongs to | |
| * | |
| * @return string The group this weapon belongs to | |
| */ | |
| public function getWeaponGroup() { | |
| return $this->weaponGroup; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameWeapon.php'; | |
| /** | |
| * This class represents the statistics of a single explosive weapon for a user | |
| * in Left4Dead | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class L4DExplosive extends GameWeapon { | |
| /** | |
| * Creates a new instance of an explosivve based on the given XML data | |
| * | |
| * @param SimpleXMLElement $weaponData The XML data of this explosive | |
| */ | |
| public function __construct(SimpleXMLElement $weaponData) { | |
| parent::__construct($weaponData); | |
| $this->id = $weaponData->getName(); | |
| $this->shots = (int) $weaponData->thrown; | |
| } | |
| /** | |
| * Returns the average number of killed zombies for one shot of this | |
| * explosive | |
| * | |
| * @return float The average number of kills per shot | |
| */ | |
| public function getAvgKillsPerShot() { | |
| return 1 / $this->getAvgShotsPerKill(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| /** | |
| * This class holds statistical information about a map played by a player in | |
| * Survival mode of Left4Dead | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class L4DMap { | |
| const GOLD = 1; | |
| const SILVER = 2; | |
| const BRONZE = 3; | |
| const NONE = 0; | |
| protected $bestTime; | |
| protected $id; | |
| protected $medal; | |
| protected $name; | |
| private $timesPlayed; | |
| /** | |
| * Creates a new instance of a Left4Dead Survival map based on the given | |
| * XML data | |
| * | |
| * @param SimpleXMLElement $mapData The XML data for this map | |
| */ | |
| public function __construct(SimpleXMLElement $mapData) { | |
| $this->bestTime = (float) $mapData->besttimeseconds; | |
| $this->id = $mapData->getName(); | |
| $this->name = (string) $mapData->name; | |
| $this->timesPlayed = (int) $mapData->timesplayed; | |
| switch((string) $mapData->medal) { | |
| case 'gold': | |
| $this->medal = self::GOLD; | |
| break; | |
| case 'silver': | |
| $this->medal = self::SILVER; | |
| break; | |
| case 'bronze': | |
| $this->medal = self::BRONZE; | |
| break; | |
| default: | |
| $this->medal = self::NONE; | |
| } | |
| } | |
| /** | |
| * Returns the best survival time of this player on this map | |
| * | |
| * @return float The best survival time of this player on this map | |
| */ | |
| public function getBestTime() { | |
| return $this->bestTime; | |
| } | |
| /** | |
| * Returns the ID of this map | |
| * | |
| * @return string The ID of this map | |
| */ | |
| public function getId() { | |
| return $this->id; | |
| } | |
| /** | |
| * Returns the highest medal this player has won on this map | |
| * | |
| * @return int The highest medal won by this player on this map | |
| */ | |
| public function getMedal() { | |
| return $this->medal; | |
| } | |
| /** | |
| * Returns the name of the map | |
| * | |
| * @return string The name of the map | |
| */ | |
| public function getName() { | |
| return $this->name; | |
| } | |
| /** | |
| * Returns the number of times this map has been played by this player | |
| * | |
| * @return int The number of times this map has been played | |
| */ | |
| public function getTimesPlayed() { | |
| return $this->timesPlayed; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/l4d/AbstractL4DStats.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/l4d/L4DExplosive.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/l4d/L4DMap.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/l4d/L4DWeapon.php'; | |
| /** | |
| * This class represents the game statistics for a single user in Left4Dead | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class L4DStats extends AbstractL4DStats { | |
| /** | |
| * Creates a <var>L4DStats</var> object by calling the super constructor | |
| * with the game name <var>"l4d"</var> | |
| * | |
| * @param string $steamId The custom URL or 64bit Steam ID of the user | |
| */ | |
| public function __construct($steamId) { | |
| parent::__construct($steamId, 'l4d'); | |
| } | |
| /** | |
| * Returns an array of Survival statistics for this user like revived | |
| * teammates | |
| * | |
| * If the Survival statistics haven't been parsed already, parsing is done | |
| * now. | |
| * | |
| * @return array The stats for the Survival mode | |
| */ | |
| public function getSurvivalStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->survivalStats)) { | |
| parent::getSurvivalStats(); | |
| $this->survivalStats['maps'] = array(); | |
| foreach($this->xmlData->stats->survival->maps->children() as $mapData) { | |
| $this->survivalStats['maps'][$mapData->getName()] = new L4DMap($mapData); | |
| } | |
| } | |
| return $this->survivalStats; | |
| } | |
| /** | |
| * Returns an array of <var>L4DWeapon</var> for this user containing all | |
| * Left4Dead weapons | |
| * | |
| * If the weapons haven't been parsed already, parsing is done now. | |
| * | |
| * @return array The weapon statistics | |
| */ | |
| public function getWeaponStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->weaponStats)) { | |
| $this->weaponStats = array(); | |
| foreach($this->xmlData->stats->weapons->children() as $weaponData) { | |
| $weaponName = $weaponData->getName(); | |
| if($weaponName != 'molotov' && $weaponName != 'pipes') { | |
| $weapon = new L4DWeapon($weaponData); | |
| } | |
| else { | |
| $weapon = new L4DExplosive($weaponData); | |
| } | |
| $this->weaponStats[$weaponName] = $weapon; | |
| } | |
| } | |
| return $this->weaponStats; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/l4d/AbstractL4DWeapon.php'; | |
| /** | |
| * This class represents the statistics of a single weapon for a user in | |
| * Left4Dead | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class L4DWeapon extends AbstractL4DWeapon { | |
| /** | |
| * Creates a new instance of a weapon based on the given XML data | |
| * | |
| * @param SimpleXMLElement $weaponData The XML data for this weapon | |
| */ | |
| public function __construct(SimpleXMLElement $weaponData) { | |
| parent::__construct($weaponData); | |
| $this->killPercentage = ((float) $weaponData->killpct) * 0.01; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2011-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameInventory.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/portal2/Portal2Item.php'; | |
| /** | |
| * Represents the inventory (aka. Robot Enrichment) of a Portal 2 player | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class Portal2Inventory extends GameInventory { | |
| const APP_ID = 620; | |
| const ITEM_CLASS = 'Portal2Item'; | |
| /** | |
| * This checks the cache for an existing inventory. If it exists it is | |
| * returned. Otherwise a new inventory is created. | |
| * | |
| * @param string $steamId The 64bit Steam ID or vanity URL of the user | |
| * @param bool $fetchNow Whether the data should be fetched now | |
| * @param bool $bypassCache Whether the cache should be bypassed | |
| * @return Portal2Inventory The inventory created from the given options | |
| */ | |
| public static function createInventory($steamId, $fetchNow = true, $bypassCache = false) { | |
| return parent::create(self::APP_ID, $steamId, $fetchNow, $bypassCache); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameItem.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/portal2/Portal2Inventory.php'; | |
| /** | |
| * Represents a Portal 2 item | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class Portal2Item extends GameItem { | |
| /** | |
| * @var array The names of the bots available in Portal 2 | |
| */ | |
| private static $BOTS = array('pbody', 'atlas'); | |
| /** | |
| * @var array | |
| */ | |
| private $equipped; | |
| /** | |
| * Creates a new instance of a Portal2Item with the given data | |
| * | |
| * @param Portal2Inventory $inventory The inventory this item is contained | |
| * in | |
| * @param array $itemData The data specifying this item | |
| * @throws WebApiException on Web API errors | |
| */ | |
| public function __construct(Portal2Inventory $inventory, $itemData) { | |
| parent::__construct($inventory, $itemData); | |
| $this->equipped = array(); | |
| for($botId = 0; $botId < sizeof(self::$BOTS); $botId++) { | |
| $this->equipped[self::$BOTS[$botId]] = (($itemData->inventory & (1 << 16 + $botId)) != 0); | |
| } | |
| } | |
| /** | |
| * Returns the name for each bot this player has equipped this item | |
| * | |
| * @return array The names of the bots this player has equipped this item | |
| */ | |
| public function getBotsEquipped() { | |
| $botsEquipped = array(); | |
| foreach($this->equipped as $botId => $equipped) { | |
| if($equipped) { | |
| $botsEquipped[] = $botId; | |
| } | |
| } | |
| return $botsEquipped; | |
| } | |
| /** | |
| * Returns whether this item is equipped by this player at all | |
| * | |
| * @return bool Whether this item is equipped by this player at all | |
| */ | |
| public function isEquipped() { | |
| return in_array(true, $this->equipped); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2011-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameStats.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/portal2/Portal2Inventory.php'; | |
| /** | |
| * This class represents the game statistics for a single user in Portal 2 | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class Portal2Stats extends GameStats { | |
| /** | |
| * @var Portal2Inventory | |
| */ | |
| private $inventory; | |
| /** | |
| * Creates a <var>Portal2Stats</var> object by calling the super | |
| * constructor with the game name <var>"portal2"</var> | |
| * | |
| * @param string $steamId The custom URL or 64bit Steam ID of the user | |
| */ | |
| public function __construct($steamId) { | |
| parent::__construct($steamId, 'portal2'); | |
| } | |
| /** | |
| * Returns the current Portal 2 inventory (a.k.a. Robot Enrichment) of this | |
| * player | |
| * | |
| * @return Portal2Inventory This player's Portal 2 backpack | |
| */ | |
| public function getInventory() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->inventory)) { | |
| $this->inventory = Portal2Inventory::createInventory($this->user->getId()); | |
| } | |
| return $this->inventory; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2011-2013, Sebastian Staudt | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameLeaderboard.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameStats.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/WebApi.php'; | |
| /** | |
| * This class represents a game available on Steam | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class SteamGame { | |
| /** | |
| * @var array | |
| */ | |
| private static $games = array(); | |
| /** | |
| * @var int | |
| */ | |
| private $appId; | |
| /** | |
| * @var string | |
| */ | |
| private $logoHash; | |
| /** | |
| * @var string | |
| */ | |
| private $name; | |
| /** | |
| * @var string | |
| */ | |
| private $shortName; | |
| /** | |
| * Creates a new or cached instance of the game specified by the given XML | |
| * data | |
| * | |
| * @param int $appId The application ID of the game | |
| * @param SimpleXMLElement $gameData The XML data of the game | |
| * @return SteamGame The game instance for the given data | |
| * @see __construct() | |
| */ | |
| public static function create($appId, SimpleXMLElement $gameData) { | |
| if(array_key_exists($appId, self::$games)) { | |
| return self::$games[$appId]; | |
| } else { | |
| return new SteamGame($appId, $gameData); | |
| } | |
| } | |
| /** | |
| * Checks if a game is up-to-date by reading information from a | |
| * <var>steam.inf</var> file and comparing it using the Web API | |
| * | |
| * @param string $path The file system path of the <var>steam.inf</var> | |
| * file | |
| * @return bool <var>true</var> if the game is up-to-date | |
| * @throws SteamCondenserException if the <var>steam.inf</var> is invalid | |
| */ | |
| public static function checkSteamInf($path) { | |
| $steamInf = file_get_contents($path); | |
| preg_match('/^\s*appID=(\d+)\s*$/im', $steamInf, $appId); | |
| preg_match('/^\s*PatchVersion=([\d\.]+)\s*$/im', $steamInf, $version); | |
| if($appId == null || $version == null) { | |
| throw new SteamCondenserException("The steam.inf file at \"$path\" is invalid."); | |
| } | |
| $appId = (int) $appId[1]; | |
| $version = (int) str_replace('.', '', $version[1]); | |
| return self::checkUpToDate($appId, $version); | |
| } | |
| /** | |
| * Returns whether the given version of the game with the given application | |
| * ID is up-to-date | |
| * | |
| * @param int $appId The application ID of the game to check | |
| * @param int $version The version to check against the Web API | |
| * @return boolean <var>true</var> if the given version is up-to-date | |
| * @throws SteamCondenserException if the Web API request fails | |
| */ | |
| public static function checkUpToDate($appId, $version) { | |
| $params = array('appid' => $appId, 'version' => $version); | |
| $result = WebApi::getJSON('ISteamApps', 'UpToDateCheck', 1, $params); | |
| $result = json_decode($result)->response; | |
| if(!$result->success) { | |
| throw new SteamCondenserException($result->error); | |
| } | |
| return $result->up_to_date; | |
| } | |
| /** | |
| * Creates a new instance of a game with the given data and caches it | |
| * | |
| * @param int $appId The application ID of the game | |
| * @param SimpleXMLElement $gameData The XML data of the game | |
| */ | |
| private function __construct($appId, SimpleXMLElement $gameData) { | |
| $this->appId = $appId; | |
| if(!empty($gameData->name)) { | |
| $logoUrl = (string) $gameData->logo; | |
| $this->name = (string) $gameData->name; | |
| if($gameData->globalStatsLink != null && !empty($gameData->globalStatsLink)) { | |
| preg_match('#http://steamcommunity.com/stats/([^?/]+)/achievements/#', (string) $gameData->globalStatsLink, $shortName); | |
| $this->shortName = strtolower($shortName[1]); | |
| } else { | |
| $this->shortName = null; | |
| } | |
| } else { | |
| $this->iconUrl = (string) $gameData->gameIcon; | |
| $logoUrl = (string) $gameData->gameLogo; | |
| $this->name = (string) $gameData->gameName; | |
| $this->shortName = strtolower((string) $gameData->gameFriendlyName); | |
| } | |
| preg_match("#/$appId/([0-9a-f]+).jpg#", $logoUrl, $logoHash); | |
| if (!empty($logoHash)) { | |
| $this->logoHash = strtolower($logoHash[1]); | |
| } | |
| self::$games[$appId] = $this; | |
| } | |
| /** | |
| * Returns the Steam application ID of this game | |
| * | |
| * @return int The Steam application ID of this game | |
| */ | |
| public function getAppId() { | |
| return $this->appId; | |
| } | |
| /** | |
| * Returns a unique identifier for this game | |
| * | |
| * This is either the numeric application ID or the unique short name | |
| * | |
| * @return mixed The application ID or short name of the game | |
| */ | |
| public function getId() { | |
| if((string) $this->appId == $this->shortName) { | |
| return $this->appId; | |
| } else { | |
| return $this->shortName; | |
| } | |
| } | |
| /** | |
| * Returns the leaderboard for this game and the given leaderboard ID or | |
| * name | |
| * | |
| * @param mixed $id The ID or name of the leaderboard to return | |
| * @return GameLeaderboard The matching leaderboard if available | |
| */ | |
| public function getLeaderboard($id) { | |
| return GameLeaderboard::getLeaderboard($this->shortName, $id); | |
| } | |
| /** | |
| * Returns an array containing all of this game's leaderboards | |
| * | |
| * @return array The leaderboards for this game | |
| */ | |
| public function getLeaderboards() { | |
| return GameLeaderboard::getLeaderboards($this->shortName); | |
| } | |
| /** | |
| * Returns the URL for the logo image of this game | |
| * | |
| * @return string The URL for the game logo | |
| */ | |
| public function getLogoUrl() { | |
| if ($this->logoHash == null) { | |
| return null; | |
| } else { | |
| return "http://media.steampowered.com/steamcommunity/public/images/apps/{$this->appId}/{$this->logoHash}.jpg"; | |
| } | |
| } | |
| /** | |
| * Returns the URL for the logo thumbnail image of this game | |
| * | |
| * @return string The URL for the game logo thumbnail | |
| */ | |
| public function getLogoThumbnailUrl() { | |
| if ($this->logoHash == null) { | |
| return null; | |
| } else { | |
| return "http://media.steampowered.com/steamcommunity/public/images/apps/{$this->appId}/{$this->logoHash}_thumb.jpg"; | |
| } | |
| } | |
| /** | |
| * Returns the full name of this game | |
| * | |
| * @return string The full name of this game | |
| */ | |
| public function getName() { | |
| return $this->name; | |
| } | |
| /** | |
| * Returns the overall number of players currently playing this game | |
| * | |
| * @return int The number of players playing this game | |
| */ | |
| public function getPlayerCount() { | |
| $params = array('appid' => $this->appId); | |
| $result = WebApi::getJSON('ISteamUserStats', 'GetNumberOfCurrentPlayers', 1, $params); | |
| $result = json_decode($result); | |
| return $result->response->player_count; | |
| } | |
| /** | |
| * Returns the short name of this game (also known as "friendly name") | |
| * | |
| * @return string|null | |
| * The short name of this game, or null if this game does not have a | |
| * short name. | |
| */ | |
| public function getShortName() { | |
| return $this->shortName; | |
| } | |
| /** | |
| * Returns the URL of this game's page in the Steam Store | |
| * | |
| * @return string This game's store page | |
| */ | |
| public function getStoreUrl() { | |
| return "http://store.steampowered.com/app/{$this->appId}"; | |
| } | |
| /** | |
| * Creates a stats object for the given user and this game | |
| * | |
| * @param string $steamId The custom URL or the 64bit Steam ID of the user | |
| * @return GameStats The stats of this game for the given user | |
| */ | |
| public function getUserStats($steamId) { | |
| if(!$this->hasStats()) { | |
| return null; | |
| } | |
| return GameStats::createGameStats($steamId, $this->shortName); | |
| } | |
| /** | |
| * Returns whether this game has statistics available | |
| * | |
| * @return bool <var>true</var> if this game has stats | |
| */ | |
| public function hasStats() { | |
| return $this->shortName != null; | |
| } | |
| /** | |
| * Returns whether the given version of this game is up-to-date | |
| * | |
| * @param int $version The version to check against the Web API | |
| * @return boolean <var>true</var> if the given version is up-to-date | |
| */ | |
| public function isUpToDate($version) { | |
| return self::checkUpToDate($this->appId, $version); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/SteamId.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/XMLData.php'; | |
| /** | |
| * The SteamGroup class represents a group in the Steam Community | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class SteamGroup extends XMLData { | |
| /** | |
| * @var array | |
| */ | |
| private static $steamGroups = array(); | |
| /** | |
| * @var String | |
| */ | |
| private $customUrl; | |
| /** | |
| * @var int | |
| */ | |
| private $fetchTime; | |
| /** | |
| * @var int | |
| */ | |
| private $groupId64; | |
| /** | |
| * @var array | |
| */ | |
| private $members; | |
| /** | |
| * Returns whether the requested group is already cached | |
| * | |
| * @param string $id The custom URL of the group specified by the group | |
| * admin or the 64bit group ID | |
| * @return bool <var>true</var> if this group is already cached | |
| */ | |
| public static function isCached($id) { | |
| return array_key_exists(strtolower($id), self::$steamGroups); | |
| } | |
| /** | |
| * Clears the group cache | |
| */ | |
| public static function clearCache() { | |
| self::$steamGroups = array(); | |
| } | |
| /** | |
| * Creates a new <var>SteamGroup</var> instance or gets an existing one | |
| * from the cache for the group with the given ID | |
| * | |
| * @param string $id The custom URL of the group specified by the group | |
| * admin or the 64bit group ID | |
| * @param bool $fetch if <var>true</var> the groups's data is loaded into | |
| * the object | |
| * @param bool $bypassCache If <var>true</var> an already cached instance | |
| * for this group will be ignored and a new one will be created | |
| * @return SteamGroup The <var>SteamGroup</var> instance of the requested | |
| * group | |
| */ | |
| public static function create($id, $fetch = true, $bypassCache = false) { | |
| $id = strtolower($id); | |
| if(self::isCached($id) && !$bypassCache) { | |
| $group = self::$steamGroups[$id]; | |
| if($fetch && !$group->isFetched()) { | |
| $group->fetchMembers(); | |
| } | |
| return $group; | |
| } else { | |
| return new SteamGroup($id, $fetch); | |
| } | |
| } | |
| /** | |
| * Creates a new <var>SteamGroup</var> instance for the group with the | |
| * given ID | |
| * | |
| * @param string $id The custom URL of the group specified by the group | |
| * admin or the 64bit group ID | |
| * @param bool $fetch if <var>true</var> the groups's data is loaded into | |
| * the object | |
| */ | |
| public function __construct($id, $fetch = true) { | |
| if(is_numeric($id)) { | |
| $this->groupId64 = $id; | |
| } else { | |
| $this->customUrl = $id; | |
| } | |
| $this->fetched = false; | |
| $this->members = array(); | |
| if($fetch) { | |
| $this->fetchMembers(); | |
| } | |
| $this->cache(); | |
| } | |
| /** | |
| * Saves this SteamGroup in the cache | |
| * | |
| * @return <var>false</var> if this group is already cached | |
| */ | |
| public function cache() { | |
| if(!array_key_exists($this->groupId64, self::$steamGroups)) { | |
| self::$steamGroups[$this->groupId64] = $this; | |
| if(!empty($this->customUrl) && | |
| !array_key_exists($this->customUrl, self::$steamGroups)) { | |
| self::$steamGroups[$this->customUrl] = $this; | |
| } | |
| } | |
| } | |
| /** | |
| * Loads the members of this group | |
| * | |
| * This might take several HTTP requests as the Steam Community splits this | |
| * data over several XML documents if the group has lots of members. | |
| */ | |
| public function fetchMembers() { | |
| if(empty($this->memberCount) || sizeof($this->members) == $this->memberCount) { | |
| $page = 0; | |
| } else { | |
| $page = 1; | |
| } | |
| do { | |
| $totalPages = $this->fetchPage(++$page); | |
| } while($page < $totalPages); | |
| $this->fetchTime = time(); | |
| } | |
| /** | |
| * Returns the base URL for this group's page | |
| * | |
| * This URL is different for groups having a custom URL. | |
| * | |
| * @return string The base URL for this group | |
| */ | |
| public function getBaseUrl() { | |
| if(empty($this->customUrl)) { | |
| return "http://steamcommunity.com/gid/{$this->groupId64}"; | |
| } else { | |
| return "http://steamcommunity.com/groups/{$this->customUrl}"; | |
| } | |
| } | |
| /** | |
| * Returns the custom URL of this group | |
| * | |
| * The custom URL is a admin specified unique string that can be used | |
| * instead of the 64bit SteamID as an identifier for a group. | |
| * | |
| * @return string The custom URL of this group | |
| */ | |
| public function getCustomUrl() { | |
| return $this->customUrl; | |
| } | |
| /** | |
| * Returns the time this group has been fetched | |
| * | |
| * @return int The timestamp of the last fetch time | |
| */ | |
| public function getFetchTime() { | |
| return $this->fetchTime; | |
| } | |
| /** | |
| * Returns this group's 64bit SteamID | |
| * | |
| * @return int This group's 64bit SteamID | |
| */ | |
| public function getGroupId64() { | |
| return $this->groupId64; | |
| } | |
| /** | |
| * Returns the number of members this group has | |
| * | |
| * If the members have already been fetched the size of the member array is | |
| * returned. Otherwise the group size is separately fetched without needing | |
| * multiple requests for big groups. | |
| * | |
| * @return int The number of this group's members | |
| * @see #fetchPage() | |
| */ | |
| public function getMemberCount() { | |
| if(empty($this->memberCount)) { | |
| $totalPages = $this->fetchPage(1); | |
| if($totalPages == 1) { | |
| $this->fetchTime = time(); | |
| } | |
| } | |
| return $this->memberCount; | |
| } | |
| /** | |
| * Returns the members of this group | |
| * | |
| * If the members haven't been fetched yet, this is done now. | |
| * | |
| * @return array The Steam ID's of the members of this group | |
| * @see #fetchMembers() | |
| */ | |
| public function getMembers() { | |
| if(sizeof($this->members) != $this->memberCount) { | |
| $this->fetchMembers(); | |
| } | |
| return $this->members; | |
| } | |
| /** | |
| * Returns whether the data for this group has already been fetched | |
| * | |
| * @return bool <var>true</var> if the group's members have been fetched | |
| */ | |
| public function isFetched() { | |
| return !empty($this->fetchTime); | |
| } | |
| /** | |
| * Fetches a specific page of the member listing of this group | |
| * | |
| * @param int $page The member page to fetch | |
| * @return int The total number of pages of this group's member listing | |
| * @see #fetchMembers() | |
| */ | |
| private function fetchPage($page) { | |
| $url = "{$this->getBaseUrl()}/memberslistxml?p=$page"; | |
| $memberData = $this->getData($url); | |
| if($page == 1) { | |
| $this->groupId64 = (string) $memberData->groupID64; | |
| } | |
| $this->memberCount = (int) $memberData->memberCount; | |
| $totalPages = (int) $memberData->totalPages; | |
| foreach($memberData->members->steamID64 as $member) { | |
| array_push($this->members, SteamId::create($member, false)); | |
| } | |
| return $totalPages; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/SteamCondenserException.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameStats.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/SteamGame.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/SteamGroup.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/XMLData.php'; | |
| /** | |
| * The SteamId class represents a Steam Community profile (also called Steam | |
| * ID) | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class SteamId extends XMLData { | |
| /** | |
| * @var array | |
| */ | |
| private static $steamIds = array(); | |
| /** | |
| * @var string | |
| */ | |
| private $customUrl; | |
| /** | |
| * @var int | |
| */ | |
| private $fetchTime; | |
| /** | |
| * @var array | |
| */ | |
| private $friends; | |
| /** | |
| * @var array | |
| */ | |
| private $games; | |
| /** | |
| * @var bool | |
| */ | |
| private $limited; | |
| /** | |
| * @var string | |
| */ | |
| private $nickname; | |
| /** | |
| * @var array | |
| */ | |
| private $playtimes; | |
| /** | |
| * @var string | |
| */ | |
| private $steamId64; | |
| /** | |
| * @var string | |
| */ | |
| private $tradeBanState; | |
| /** | |
| * Returns whether the requested Steam ID is already cached | |
| * | |
| * @param string $id The custom URL of the Steam ID specified by the player | |
| * or the 64bit SteamID | |
| * @return bool <var>true</var> if this Steam ID is already cached | |
| */ | |
| public static function isCached($id) { | |
| return array_key_exists(strtolower($id), self::$steamIds); | |
| } | |
| /** | |
| * Clears the Steam ID cache | |
| */ | |
| public static function clearCache() { | |
| self::$steamIds = array(); | |
| } | |
| /** | |
| * Converts a 64bit numeric SteamID as used by the Steam Community to a | |
| * SteamID as reported by game servers | |
| * | |
| * @param string $communityId The SteamID string as used by the Steam | |
| * Community | |
| * @return string The converted SteamID, like <var>STEAM_0:0:12345</var> | |
| * @throws SteamCondenserException if the community ID is to small | |
| */ | |
| public static function convertCommunityIdToSteamId($communityId) { | |
| $steamId1 = substr($communityId, -1) % 2; | |
| $steamId2a = intval(substr($communityId, 0, 4)) - 7656; | |
| $steamId2b = substr($communityId, 4) - 1197960265728; | |
| $steamId2b = $steamId2b - $steamId1; | |
| if($steamId2a <= 0 && $steamId2b <= 0) { | |
| throw new SteamCondenserException("SteamID $communityId is too small."); | |
| } | |
| return "STEAM_0:$steamId1:" . (($steamId2a + $steamId2b) / 2); | |
| } | |
| /** | |
| * Converts a SteamID as reported by game servers to a 64bit numeric | |
| * SteamID as used by the Steam Community | |
| * | |
| * @param string $steamId The SteamID string as used on servers, like | |
| * <var>STEAM_0:0:12345</var> | |
| * @return string The converted 64bit numeric SteamID | |
| * @throws SteamCondenserException if the SteamID doesn't have the correct | |
| * format | |
| */ | |
| public static function convertSteamIdToCommunityId($steamId) { | |
| if($steamId == 'STEAM_ID_LAN' || $steamId == 'BOT') { | |
| throw new SteamCondenserException("Cannot convert SteamID \"$steamId\" to a community ID."); | |
| } | |
| if (preg_match('/^STEAM_[0-1]:[0-1]:[0-9]+$/', $steamId)) { | |
| $steamId = explode(':', substr($steamId, 8)); | |
| $steamId = $steamId[0] + $steamId[1] * 2 + 1197960265728; | |
| return '7656' . $steamId; | |
| } elseif (preg_match('/^\[U:[0-1]:[0-9]+\]$/', $steamId)) { | |
| $steamId = explode(':', substr($steamId, 3, strlen($steamId) - 1)); | |
| $steamId = $steamId[0] + $steamId[1] + 1197960265727; | |
| return '7656' . $steamId; | |
| } else { | |
| throw new SteamCondenserException("SteamID \"$steamId\" doesn't have the correct format."); | |
| } | |
| } | |
| /** | |
| * Creates a new <var>SteamID</var> instance or gets an existing one from | |
| * the cache for the profile with the given ID | |
| * | |
| * @param string $id The custom URL of the Steam ID specified by player or | |
| * the 64bit SteamID | |
| * @param bool $fetch if <var>true</var> the profile's data is loaded into | |
| * the object | |
| * @param bool $bypassCache If <var>true</var> an already cached instance | |
| * for this Steam ID will be ignored and a new one will be created | |
| * @return SteamId The <var>SteamId</var> instance of the requested profile | |
| */ | |
| public static function create($id, $fetch = true, $bypassCache = false) { | |
| $id = strtolower($id); | |
| if(self::isCached($id) && !$bypassCache) { | |
| $steamId = self::$steamIds[$id]; | |
| if($fetch && !$steamId->isFetched()) { | |
| $steamId->fetchMembers(); | |
| } | |
| return $steamId; | |
| } else { | |
| return new SteamId($id, $fetch); | |
| } | |
| } | |
| /** | |
| * Creates a new <var>SteamId</var> instance using a SteamID as used on | |
| * servers | |
| * | |
| * The SteamID from the server is converted into a 64bit numeric SteamID | |
| * first before this is used to retrieve the corresponding Steam Community | |
| * profile. | |
| * | |
| * @param string $steamId The SteamID string as used on servers, like | |
| * <var>STEAM_0:0:12345</var> | |
| * @return SteamId The <var>SteamId</var> instance belonging to the given | |
| * SteamID | |
| * @see convertSteamIdToCommunityId() | |
| * @see __construct() | |
| */ | |
| public static function getFromSteamId($steamId) { | |
| return new SteamId(self::convertSteamIdToCommunityId($steamId)); | |
| } | |
| /** | |
| * Resolves a vanity URL of a Steam Community profile to a 64bit numeric | |
| * SteamID | |
| * | |
| * @param string $vanityUrl The vanity URL of a Steam Community profile | |
| * @return string The 64bit SteamID for the given vanity URL | |
| * @throws WebApiException if the request to Steam's Web API fails | |
| */ | |
| public static function resolveVanityUrl($vanityUrl) { | |
| $params = array('vanityurl' => $vanityUrl); | |
| $json = WebApi::getJSON('ISteamUser', 'ResolveVanityURL', 1, $params); | |
| $result = json_decode($json); | |
| $result = $result->response; | |
| if ($result->success != 1) { | |
| return null; | |
| } | |
| return $result->steamid; | |
| } | |
| /** | |
| * Creates a new <var>SteamId</var> instance for the given ID | |
| * | |
| * @param string $id The custom URL of the group specified by the player | |
| * or the 64bit SteamID | |
| * @param boolean $fetch if <var>true</var> the profile's data is loaded | |
| * into the object | |
| * @throws SteamCondenserException if the Steam ID data is not available, | |
| * e.g. when it is private | |
| */ | |
| public function __construct($id, $fetch = true) { | |
| if(is_numeric($id)) { | |
| $this->steamId64 = $id; | |
| } else { | |
| $this->customUrl = strtolower($id); | |
| } | |
| if($fetch) { | |
| $this->fetchData(); | |
| } | |
| $this->cache(); | |
| } | |
| /** | |
| * Saves this <var>SteamId</var> instance in the cache | |
| */ | |
| public function cache() { | |
| if(!array_key_exists($this->steamId64, self::$steamIds)) { | |
| self::$steamIds[$this->steamId64] = $this; | |
| if(!empty($this->customUrl) && | |
| !array_key_exists($this->customUrl, self::$steamIds)) { | |
| self::$steamIds[$this->customUrl] = $this; | |
| } | |
| } | |
| } | |
| /** | |
| * Fetchs data from the Steam Community by querying the XML version of the | |
| * profile specified by the ID of this Steam ID | |
| * | |
| * @throws SteamCondenserException if the Steam ID data is not available, | |
| * e.g. when it is private, or when it cannot be parsed | |
| */ | |
| public function fetchData() { | |
| $profile = $this->getData($this->getBaseUrl() . '?xml=1'); | |
| if(!empty($profile->error)) { | |
| throw new SteamCondenserException((string) $profile->error); | |
| } | |
| if(!empty($profile->privacyMessage)) { | |
| throw new SteamCondenserException((string) $profile->privacyMessage); | |
| } | |
| $this->nickname = htmlspecialchars_decode((string) $profile->steamID); | |
| $this->steamId64 = (string) $profile->steamID64; | |
| $this->limited = (bool)(int) $profile->isLimitedAccount; | |
| $this->tradeBanState = (string) $profile->tradeBanState; | |
| $this->vacBanned = (bool)(int) $profile->vacBanned; | |
| $this->imageUrl = substr((string) $profile->avatarIcon, 0, -4); | |
| $this->onlineState = (string) $profile->onlineState; | |
| $this->privacyState = (string) $profile->privacyState; | |
| $this->stateMessage = (string) $profile->stateMessage; | |
| $this->visibilityState = (int) $profile->visibilityState; | |
| if($this->isPublic()) { | |
| $this->customUrl = strtolower((string) $profile->customURL); | |
| $this->headLine = htmlspecialchars_decode((string) $profile->headline); | |
| $this->hoursPlayed = (float) $profile->hoursPlayed2Wk; | |
| $this->location = (string) $profile->location; | |
| $this->memberSince = (string) $profile->memberSince; | |
| $this->realName = htmlspecialchars_decode((string) $profile->realname); | |
| $this->steamRating = (float) $profile->steamRating; | |
| $this->summary = htmlspecialchars_decode((string) $profile->summary); | |
| } | |
| if(!empty($profile->mostPlayedGames)) { | |
| foreach($profile->mostPlayedGames->mostPlayedGame as $mostPlayedGame) { | |
| $this->mostPlayedGames[(string) $mostPlayedGame->gameName] = (float) $mostPlayedGame->hoursPlayed; | |
| } | |
| } | |
| if(!empty($profile->groups)) { | |
| foreach($profile->groups->group as $group) { | |
| $this->groups[] = SteamGroup::create((string) $group->groupID64, false); | |
| } | |
| } | |
| if(!empty($profile->weblinks)) { | |
| foreach($profile->weblinks->weblink as $link) { | |
| $this->links[htmlspecialchars_decode((string) $link->title)] = (string) $link->link; | |
| } | |
| } | |
| $this->fetchTime = time(); | |
| } | |
| /** | |
| * Fetches the friends of this user | |
| * | |
| * This creates a new <var>SteamId</var> instance for each of the friends | |
| * without fetching their data. | |
| * | |
| * @see getFriends() | |
| * @see __construct() | |
| * @throws SteamCondenserException if an error occurs while parsing the | |
| * data | |
| */ | |
| private function fetchFriends() { | |
| $friendsData = $this->getData($this->getBaseUrl() . '/friends?xml=1'); | |
| $this->friends = array(); | |
| foreach($friendsData->friends->friend as $friend) { | |
| $this->friends[] = SteamId::create((string) $friend, false); | |
| } | |
| } | |
| /** | |
| * Fetches the games this user owns | |
| * | |
| * @see getGames() | |
| * @throws SteamCondenserException if an error occurs while parsing the | |
| * data | |
| */ | |
| private function fetchGames() { | |
| $gamesData = $this->getData($this->getBaseUrl() . '/games?xml=1'); | |
| $this->games = array(); | |
| $this->playtimes = array(); | |
| foreach($gamesData->games->game as $gameData) { | |
| $appId = (int) $gameData->appID; | |
| $game = SteamGame::create($appId, $gameData); | |
| $this->games[$appId] = $game; | |
| $recent = (float) $gameData->hoursLast2Weeks; | |
| $total = (float) str_replace(',', '', $gameData->hoursOnRecord); | |
| $playtimes = array((int) ($recent * 60), (int) ($total * 60)); | |
| $this->playtimes[$appId] = $playtimes; | |
| } | |
| } | |
| /** | |
| * Tries to find a game instance with the given application ID or full name | |
| * or short name | |
| * | |
| * @param mixed $id The full or short name or the application ID of the | |
| * game | |
| * @return SteamGame The game found with the given ID | |
| * @throws SteamCondenserException if the user does not own the game or no | |
| * game with the given ID exists | |
| */ | |
| private function findGame($id) { | |
| $game = null; | |
| foreach($this->getGames() as $currentGame) { | |
| if($currentGame->getAppId() == $id || | |
| $currentGame->getShortName() == $id || | |
| $currentGame->getName() == $id) { | |
| $game = $currentGame; | |
| break; | |
| } | |
| } | |
| if($game == null) { | |
| if(is_int($id)) { | |
| $message = "This SteamID does not own a game with application ID {$id}."; | |
| } else { | |
| $message = "This SteamID does not own the game \"{$id}\"."; | |
| } | |
| throw new SteamCondenserException($message); | |
| } | |
| return $game; | |
| } | |
| /** | |
| * Returns the base URL for this Steam ID | |
| * | |
| * This URL is different for Steam IDs having a custom URL. | |
| * | |
| * @return string The base URL for this SteamID | |
| */ | |
| public function getBaseUrl() { | |
| if(empty($this->customUrl)) { | |
| return "http://steamcommunity.com/profiles/{$this->steamId64}"; | |
| } else { | |
| return "http://steamcommunity.com/id/{$this->customUrl}"; | |
| } | |
| } | |
| /** | |
| * Returns the custom URL of this Steam ID | |
| * | |
| * The custom URL is a user specified unique string that can be used | |
| * instead of the 64bit SteamID as an identifier for a Steam ID. | |
| * | |
| * <strong>Note:</strong> The custom URL is not necessarily the same as the | |
| * user's nickname. | |
| * | |
| * @return string The custom URL of this Steam ID | |
| */ | |
| public function getCustomUrl() { | |
| return $this->customUrl; | |
| } | |
| /** | |
| * Returns the time this group has been fetched | |
| * | |
| * @return int The timestamp of the last fetch time | |
| */ | |
| public function getFetchTime() { | |
| return $this->fetchTime; | |
| } | |
| /** | |
| * Returns the Steam Community friends of this user | |
| * | |
| * If the friends haven't been fetched yet, this is done now. | |
| * | |
| * @return array The friends of this user | |
| * @see fetchFriends() | |
| */ | |
| public function getFriends() { | |
| if(empty($this->friends)) { | |
| $this->fetchFriends(); | |
| } | |
| return $this->friends; | |
| } | |
| /** | |
| * Returns the URL of the full-sized version of this user's avatar | |
| * | |
| * @return string The URL of the full-sized avatar | |
| */ | |
| public function getFullAvatarUrl() { | |
| return $this->imageUrl . '_full.jpg'; | |
| } | |
| /** | |
| * Returns the games this user owns | |
| * | |
| * The keys of the hash are the games' application IDs and the values are | |
| * the corresponding game instances. | |
| * | |
| * If the friends haven't been fetched yet, this is done now. | |
| * | |
| * @return array The games this user owns | |
| * @see fetchGames() | |
| */ | |
| public function getGames() { | |
| if(empty($this->games)) { | |
| $this->fetchGames(); | |
| } | |
| return $this->games; | |
| } | |
| /** | |
| * Returns the stats for the given game for the owner of this SteamID | |
| * | |
| * @param mixed $id The full or short name or the application ID of the | |
| * game stats should be fetched for | |
| * @return GameStats The statistics for the game with the given name | |
| * @throws SteamCondenserException if the user does not own this game or it | |
| * does not have any stats | |
| */ | |
| public function getGameStats($id) { | |
| $game = $this->findGame($id); | |
| if(!$game->hasStats()) { | |
| throw new SteamCondenserException("\"{$game->getName()}\" does not have stats."); | |
| } | |
| if(empty($this->customUrl)) { | |
| return GameStats::createGameStats($this->steamId64, $game->getShortName()); | |
| } else { | |
| return GameStats::createGameStats($this->customUrl, $game->getShortName()); | |
| } | |
| } | |
| /** | |
| * Returns the URL of the icon version of this user's avatar | |
| * | |
| * @return string The URL of the icon-sized avatar | |
| */ | |
| public function getIconAvatarUrl() { | |
| return $this->imageUrl . '.jpg'; | |
| } | |
| /** | |
| * Returns a unique identifier for this Steam ID | |
| * | |
| * This is either the 64bit numeric SteamID or custom URL | |
| * | |
| * @return string The 64bit numeric SteamID or the custom URL | |
| */ | |
| public function getId() { | |
| if($this->customUrl == null) { | |
| return $this->steamId64; | |
| } else { | |
| return $this->customUrl; | |
| } | |
| } | |
| /** | |
| * Returns the URL of the medium-sized version of this user's avatar | |
| * | |
| * @return string The URL of the medium-sized avatar | |
| */ | |
| public function getMediumAvatarUrl() { | |
| return $this->imageUrl . '_medium.jpg'; | |
| } | |
| /** | |
| * Returns the Steam nickname of the user | |
| * | |
| * @return string The Steam nickname of the user | |
| */ | |
| public function getNickname() { | |
| return $this->nickname; | |
| } | |
| /** | |
| * @return String | |
| */ | |
| public function getSteamId64() { | |
| return $this->steamId64; | |
| } | |
| /** | |
| * Returns the time in minutes this user has played this game in the last | |
| * two weeks | |
| * | |
| * @param mixed $id The full or short name or the application ID of the | |
| * game | |
| * @return int The number of minutes this user played the given game in the | |
| * last two weeks | |
| */ | |
| public function getRecentPlaytime($id) { | |
| $game = $this->findGame($id); | |
| $playtimes = $this->playtimes[$game->getAppId()]; | |
| return $playtimes[0]; | |
| } | |
| /** | |
| * Returns the total time in minutes this user has played this game | |
| * | |
| * @param mixed $id The full or short name or the application ID of the | |
| * game | |
| * @return int The total number of minutes this user played the given game | |
| */ | |
| public function getTotalPlaytime($id) { | |
| $game = $this->findGame($id); | |
| $playtimes = $this->playtimes[$game->getAppId()]; | |
| return $playtimes[1]; | |
| } | |
| /** | |
| * Returns this user's ban state in Steam's trading system | |
| * | |
| * @return string This user's trading ban state | |
| */ | |
| public function getTradeBanState() { | |
| return $this->tradeBanState; | |
| } | |
| /** | |
| * Returns whether the owner of this Steam ID is VAC banned | |
| * | |
| * @return bool <var>true</var> if the user has been banned by VAC | |
| */ | |
| public function isBanned() { | |
| return $this->vacBanned; | |
| } | |
| /** | |
| * Returns whether the data for this Steam ID has already been fetched | |
| * | |
| * @return bool <var>true</var> if the Steam ID's data has been | |
| * fetched | |
| */ | |
| public function isFetched() { | |
| return !empty($this->fetchTime); | |
| } | |
| /** | |
| * Returns whether the owner of this Steam ID is playing a game | |
| * | |
| * @return bool <var>true</var> if the user is in-game | |
| */ | |
| public function isInGame() { | |
| return $this->onlineState == 'in-game'; | |
| } | |
| /** | |
| * Returns whether this Steam account is limited | |
| * | |
| * @return bool <var>true</var> if this account is limited | |
| */ | |
| public function isLimited() { | |
| return $this->limited; | |
| } | |
| /** | |
| * Returns whether the owner of this Steam ID is currently logged into | |
| * Steam | |
| * | |
| * @return bool <var>true</var> if the user is online | |
| */ | |
| public function isOnline() { | |
| return ($this->onlineState == 'online') || ($this->onlineState == 'in-game'); | |
| } | |
| /** | |
| * Returns whether this Steam ID is publicly accessible | |
| * | |
| * @return bool <var>true</var> if this Steam ID is public | |
| */ | |
| public function isPublic() { | |
| return $this->privacyState == 'public'; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2011-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Inventory.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Item.php'; | |
| /** | |
| * Represents the inventory (aka. Backpack) of a player of the public Team | |
| * Fortress 2 beta | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class TF2BetaInventory extends TF2Inventory { | |
| const APP_ID = 520; | |
| /** | |
| * This checks the cache for an existing inventory. If it exists it is | |
| * returned. Otherwise a new inventory is created. | |
| * | |
| * @param string $steamId The 64bit Steam ID or vanity URL of the user | |
| * @param bool $fetchNow Whether the data should be fetched now | |
| * @param bool $bypassCache Whether the cache should be bypassed | |
| * @return TF2BetaInventory The inventory created from the given options | |
| */ | |
| public static function createInventory($steamId, $fetchNow = true, $bypassCache = false) { | |
| return parent::create(self::APP_ID, $steamId, $fetchNow, $bypassCache); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameClass.php'; | |
| /** | |
| * Represents the stats for a Team Fortress 2 class for a specific user | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage communty | |
| */ | |
| class TF2Class extends GameClass { | |
| /** | |
| * @var int | |
| */ | |
| private $maxBuildingsDestroyed; | |
| /** | |
| * @var int | |
| */ | |
| private $maxCaptures; | |
| /** | |
| * @var int | |
| */ | |
| private $maxDamage; | |
| /** | |
| * @var int | |
| */ | |
| private $maxDefenses; | |
| /** | |
| * @var int | |
| */ | |
| private $maxDominations; | |
| /** | |
| * @var int | |
| */ | |
| private $maxKillAssists; | |
| /** | |
| * @var int | |
| */ | |
| private $maxKills; | |
| /** | |
| * @var int | |
| */ | |
| private $maxRevenges; | |
| /** | |
| * @var int | |
| */ | |
| private $maxScore; | |
| /** | |
| * @var int | |
| */ | |
| private $maxTimeAlive; | |
| /** | |
| * @var int | |
| */ | |
| private $playTime; | |
| /** | |
| * Creates a new TF2 class instance based on the assigned XML data | |
| * | |
| * @param SimpleXMLElement $classData The XML data for this class | |
| */ | |
| public function __construct(SimpleXMLElement $classData) { | |
| $this->name = (string) $classData->className; | |
| $this->maxBuildingsDestroyed = (int) $classData->ibuildingsdestroyed; | |
| $this->maxCaptures = (int) $classData->ipointcaptures; | |
| $this->maxDamage = (int) $classData->idamagedealt; | |
| $this->maxDefenses = (int) $classData->ipointdefenses; | |
| $this->maxDominations = (int) $classData->idominations; | |
| $this->maxKillAssists = (int) $classData->ikillassists; | |
| $this->maxKills = (int) $classData->inumberofkills; | |
| $this->maxRevenges = (int) $classData->irevenge; | |
| $this->maxScore = (int) $classData->ipointsscored; | |
| $this->maxTimeAlive = (int) $classData->iplaytime; | |
| $this->playTime = (int) $classData->playtimeSeconds; | |
| } | |
| /** | |
| * Returns the maximum number of buildings the player has destroyed in a | |
| * single life with this class | |
| * | |
| * @return int Maximum number of buildings destroyed | |
| */ | |
| public function getMaxBuildingsDestroyed() { | |
| return $this->maxBuildingsDestroyed; | |
| } | |
| /** | |
| * Returns the maximum number of points captured by the player in a single | |
| * life with this class | |
| * | |
| * @return int Maximum number of points captured | |
| */ | |
| public function getMaxCaptures() { | |
| return $this->maxCaptures; | |
| } | |
| /** | |
| * Returns the maximum damage dealt by the player in a single life with | |
| * this class | |
| * | |
| * @return int Maximum damage dealt | |
| */ | |
| public function getMaxDamage() { | |
| return $this->maxDamage; | |
| } | |
| /** | |
| * Returns the maximum number of defenses by the player in a single life | |
| * with this class | |
| * | |
| * @return int Maximum number of defenses | |
| */ | |
| public function getMaxDefenses() { | |
| return $this->maxDefnses; | |
| } | |
| /** | |
| * Returns the maximum number of dominations by the player in a single life | |
| * with this class | |
| * | |
| * @return int Maximum number of dominations | |
| */ | |
| public function getMaxDominations() { | |
| return $this->maxDominations; | |
| } | |
| /** | |
| * Returns the maximum number of times the the player assisted a teammate | |
| * with killing an enemy in a single life with this class | |
| * | |
| * @return int Maximum number of kill assists | |
| */ | |
| public function getMaxKillAssists() { | |
| return $this->maxKillAssists; | |
| } | |
| /** | |
| * Returns the maximum number of enemies killed by the player in a single | |
| * life with this class | |
| * | |
| * @return int Maximum number of kills | |
| */ | |
| public function getMaxKills() { | |
| return $this->maxKills; | |
| } | |
| /** | |
| * Returns the maximum number of revenges by the player in a single life | |
| * with this class | |
| * | |
| * @return int Maximum number of revenges | |
| */ | |
| public function getMaxRevenges() { | |
| return $this->maxRevenges; | |
| } | |
| /** | |
| * Returns the maximum number score achieved by the player in a single life | |
| * with this class | |
| * | |
| * @return int Maximum score | |
| */ | |
| public function getMaxScore() { | |
| return $this->maxScore; | |
| } | |
| /** | |
| * Returns the maximum lifetime by the player in a single life with this | |
| * class | |
| * | |
| * @return int Maximum lifetime | |
| */ | |
| public function getMaxTimeAlive() { | |
| return $this->maxTimeAlive; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Class.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Engineer.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Medic.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Sniper.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Spy.php'; | |
| /** | |
| * The <var>TF2ClassFactory</var> is used to created instances of | |
| * <var>TF2Class</var> based on the XML input data | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| abstract class TF2ClassFactory { | |
| /** | |
| * Creates a new instance of a TF2 class instance based on the given XML | |
| * data | |
| * | |
| * This returns an instance of <var>TF2Class</var> or its subclasses | |
| * <var>TF2Engineer</var>, <var>TF2Medic</var>, <var>TF2Sniper</var> or | |
| * <var>TF2Spy</var> depending on the given XML data. | |
| * | |
| * @param SimpleXMLElement $classData The XML data for the class | |
| * @return TF2Class The statistics for the given class data | |
| */ | |
| public static function getTF2Class(SimpleXMLElement $classData) { | |
| switch($classData->className) { | |
| case 'Engineer': | |
| return new TF2Engineer($classData); | |
| case 'Medic': | |
| return new TF2Medic($classData); | |
| case 'Sniper': | |
| return new TF2Sniper($classData); | |
| case 'Spy': | |
| return new TF2Spy($classData); | |
| default: | |
| return new TF2Class($classData); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Class.php'; | |
| /** | |
| * Represents the stats for the Team Fortress 2 Engineer class for a specific | |
| * user | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class TF2Engineer extends TF2Class { | |
| /** | |
| * @var int | |
| */ | |
| private $maxBuildingsBuilt; | |
| /** | |
| * @var int | |
| */ | |
| private $maxSentryKills; | |
| /** | |
| * @var int | |
| */ | |
| private $maxTeleports; | |
| /** | |
| * Creates a new instance of the Engineer class based on the given XML data | |
| * | |
| * @param SimpleXMLElement $classData The XML data for this Engineer | |
| */ | |
| public function __construct(SimpleXMLElement $classData) { | |
| parent::__construct($classData); | |
| $this->maxBuildingsBuilt = (int) $classData->ibuildingsbuilt; | |
| $this->maxTeleports = (int) $classData->inumteleports; | |
| $this->maxSentryKills = (int) $classData->isentrykills; | |
| } | |
| /** | |
| * Returns the maximum number of buildings built by the player in a single | |
| * life as an Engineer | |
| * | |
| * @return int Maximum number of buildings built | |
| */ | |
| public function getMaxBuildingsBuilt() { | |
| return $this->maxBuildingsBuilt; | |
| } | |
| /** | |
| * Returns the maximum number of enemies killed by sentry guns built by the | |
| * player in a single life as an Engineer | |
| * | |
| * @return int Maximum number of sentry kills | |
| */ | |
| public function getMaxSentryKills() { | |
| return $this->maxSentryKills; | |
| } | |
| /** | |
| * Returns the maximum number of teammates teleported by teleporters built | |
| * by the player in a single life as an Engineer | |
| * | |
| * @return int Maximum number of teleports | |
| */ | |
| public function getMaxTeleports() { | |
| return $this->maxTeleports; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2010-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/SteamId.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/WebApi.php'; | |
| /** | |
| * Represents the special Team Fortress 2 item Golden Wrench. It includes the | |
| * ID of the item, the serial number of the wrench, a reference to the SteamID | |
| * of the owner and the date this player crafted the wrench | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class TF2GoldenWrench { | |
| /** | |
| * @var array | |
| */ | |
| private static $goldenWrenches = null; | |
| /** | |
| * @var int | |
| */ | |
| private $date; | |
| /** | |
| * @var int | |
| */ | |
| private $id; | |
| /** | |
| * @var int | |
| */ | |
| private $number; | |
| /** | |
| * @var SteamId | |
| */ | |
| private $owner; | |
| /** | |
| * Returns all Golden Wrenches | |
| * | |
| * @return All Golden Wrenches | |
| * @throws SteamCondenserException If an error occurs querying the Web API | |
| * or the Steam Community | |
| */ | |
| public static function getGoldenWrenches() { | |
| if(self::$goldenWrenches == null) { | |
| self::$goldenWrenches = array(); | |
| $data = json_decode(WebApi::getJSON('ITFItems_440', 'GetGoldenWrenches', 2)); | |
| foreach($data->results->wrenches as $wrenchData) { | |
| self::$goldenWrenches[] = new TF2GoldenWrench($wrenchData); | |
| } | |
| } | |
| return self::$goldenWrenches; | |
| } | |
| /** | |
| * Creates a new instance of a Golden Wrench with the given data | |
| * | |
| * @param stdClass $wrenchData The JSON data for this wrench | |
| * @throws SteamCondenserException If the SteamId for the owner of the | |
| * wrench cannot be created | |
| */ | |
| private function __construct($wrenchData) { | |
| $this->date = (int) $wrenchData->timestamp; | |
| $this->id = (int) $wrenchData->itemID; | |
| $this->number = (int) $wrenchData->wrenchNumber; | |
| $this->owner = SteamId::create((string) $wrenchData->steamID, false); | |
| } | |
| /** | |
| * Returns the date this Golden Wrench has been crafted | |
| * | |
| * @return int The crafting date of this wrench | |
| */ | |
| public function getDate() { | |
| return $this->date; | |
| } | |
| /** | |
| * Returns the unique item ID of this Golden Wrench | |
| * | |
| * @return int The ID of this wrench | |
| */ | |
| public function getId() { | |
| return $this->id; | |
| } | |
| /** | |
| * Returns the serial number of this Golden Wrench | |
| * | |
| * @return The serial of this wrench | |
| */ | |
| public function getNumber() { | |
| return $this->number; | |
| } | |
| /** | |
| * Returns the SteamID of the owner of this Golden Wrench | |
| * | |
| * @return SteamId The owner of this wrench | |
| */ | |
| public function getOwner() { | |
| return $this->owner; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2010-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Item.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameInventory.php'; | |
| /** | |
| * Represents the inventory (aka. Backpack) of a Team Fortress 2 player | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class TF2Inventory extends GameInventory { | |
| const APP_ID = 440; | |
| const ITEM_CLASS = 'TF2Item'; | |
| /** | |
| * This checks the cache for an existing inventory. If it exists it is | |
| * returned. Otherwise a new inventory is created. | |
| * | |
| * @param string $steamId The 64bit Steam ID or vanity URL of the user | |
| * @param bool $fetchNow Whether the data should be fetched now | |
| * @param bool $bypassCache Whether the cache should be bypassed | |
| * @return TF2Inventory The inventory created from the given options | |
| */ | |
| public static function createInventory($steamId, $fetchNow = true, $bypassCache = false) { | |
| return parent::create(self::APP_ID, $steamId, $fetchNow, $bypassCache); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2010-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameItem.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Inventory.php'; | |
| /** | |
| * Represents a Team Fortress 2 item | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class TF2Item extends GameItem { | |
| /** | |
| * @var array The names of the Team Fortress 2 classes | |
| */ | |
| private static $CLASSES = array('scout', 'sniper', 'soldier', 'demoman', | |
| 'medic', 'heavy', 'pyro', 'spy'); | |
| /** | |
| * @var array | |
| */ | |
| private $equipped; | |
| /** | |
| * Creates a new instance of a TF2Item with the given data | |
| * | |
| * @param $inventory The inventory this item is contained in | |
| * @param $itemData The data specifying this item | |
| * @throws WebApiException on Web API errors | |
| */ | |
| public function __construct(TF2Inventory $inventory, $itemData) { | |
| parent::__construct($inventory, $itemData); | |
| $this->equipped = array(); | |
| foreach(self::$CLASSES as $classId => $className) { | |
| $this->equipped[$className] = ($itemData->inventory & (1 << 16 + $classId) != 0); | |
| } | |
| } | |
| /** | |
| * Returns the class symbols for each class this player has equipped this | |
| * item | |
| * | |
| * @return array The names of the classes this player has equipped this | |
| * item | |
| */ | |
| public function getClassesEquipped() { | |
| $classesEquipped = array(); | |
| foreach($this->equipped as $classId => $equipped) { | |
| if($equipped) { | |
| $classesEquipped[] = $classId; | |
| } | |
| } | |
| return $classesEquipped; | |
| } | |
| /** | |
| * Returns whether this item is equipped by this player at all | |
| * | |
| * @return bool <var>true</var> if the player has equipped this item at all | |
| */ | |
| public function isEquipped() { | |
| return in_array(true, $this->equipped); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Class.php'; | |
| /** | |
| * Represents the stats for the Team Fortress 2 Medic class for a specific user | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class TF2Medic extends TF2Class { | |
| /** | |
| * @var int | |
| */ | |
| private $maxHealthHealed; | |
| /** | |
| * @var int | |
| */ | |
| private $maxUberCharges; | |
| /** | |
| * Creates a new instance of the Medic class based on the given XML data | |
| * | |
| * @param SimpleXMLElement $classData The XML data for this Medic | |
| */ | |
| public function __construct(SimpleXMLElement $classData) { | |
| parent::__construct($classData); | |
| $this->maxUberCharges = (int) $classData->inuminvulnerable; | |
| $this->maxHealthHealed = (int) $classData->ihealthpointshealed; | |
| } | |
| /** | |
| * Returns the maximum health healed for teammates by the player in a | |
| * single life as a Medic | |
| * | |
| * @return Maximum health healed | |
| */ | |
| public function getMaxHealthHealed() { | |
| return $this->maxHealthHealed; | |
| } | |
| /** | |
| * Returns the maximum number of ÜberCharges provided by the player in a | |
| * single life as a Medic | |
| * | |
| * @return Maximum number of ÜberCharges | |
| */ | |
| public function getMaxUbercharges() { | |
| return $this->maxUbercharges; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Class.php'; | |
| /** | |
| * Represents the stats for the Team Fortress 2 Sniper class for a specific | |
| * user | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class TF2Sniper extends TF2Class { | |
| /** | |
| * @var int | |
| */ | |
| private $maxHeadshots; | |
| /** | |
| * Creates a new instance of the Sniper class based on the given XML data | |
| * | |
| * @param SimpleXMLElement $classData The XML data for this Sniper | |
| */ | |
| public function __construct(SimpleXMLElement $classData) { | |
| parent::__construct($classData); | |
| $this->maxHeadshots = (int) $classData->iheadshots; | |
| } | |
| /** | |
| * Returns the maximum number enemies killed with a headshot by the player | |
| * in single life as a Sniper | |
| * | |
| * @return int Maximum number of headshots | |
| */ | |
| public function getMaxHeadshots() { | |
| return $this->maxHeadshots; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Class.php'; | |
| /** | |
| * Represents the stats for the Team Fortress 2 Spy class for a specific user | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class TF2Spy extends TF2Class { | |
| /** | |
| * @var int | |
| */ | |
| private $maxBackstabs; | |
| /** | |
| * @var int | |
| */ | |
| private $maxHeadShots; | |
| /** | |
| * @var int | |
| */ | |
| private $maxHealthLeeched; | |
| /** | |
| * Creates a new instance of the Spy class based on the given XML data | |
| * | |
| * @param SimpleXMLElement $classData The XML data for this Spy | |
| */ | |
| public function __construct(SimpleXMLElement $classData) { | |
| parent::__construct($classData); | |
| $this->maxBackstabs = (int) $classData->ibackstabs; | |
| $this->maxHeadShots = (int) $classData->iheadshots; | |
| $this->maxHealthLeeched = (int) $classData->ihealthpointsleached; | |
| } | |
| /** | |
| * Returns the maximum health leeched from enemies by the player in a single | |
| * life as a Spy | |
| * | |
| * @return int Maximum health leeched | |
| */ | |
| public function getMaxBackstabs() { | |
| return $this->maxBackstabs; | |
| } | |
| /** | |
| * Returns the head shots by the player in a single life as a Spy | |
| * | |
| * @return int Maximum number of head shots | |
| */ | |
| public function getMaxHeadShots() | |
| { | |
| return $this->maxHeadShots; | |
| } | |
| /** | |
| * Returns the maximum health leeched from enemies by the player in a single | |
| * life as a Spy | |
| * | |
| * @return int Maximum health leeched | |
| */ | |
| public function getMaxHealthLeeched() { | |
| return $this->maxHealthLeeched; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/GameStats.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2BetaInventory.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2ClassFactory.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/community/tf2/TF2Inventory.php'; | |
| /** | |
| * This class represents the game statistics for a single user in Team Fortress | |
| * 2 | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class TF2Stats extends GameStats { | |
| /** | |
| * @var int | |
| */ | |
| private $accumulatedPoints; | |
| /** | |
| * @var array | |
| */ | |
| private $classStats; | |
| /** | |
| * @var TF2Inventory | |
| */ | |
| private $inventory; | |
| /** | |
| * @var int | |
| */ | |
| private $totalPlaytime; | |
| /** | |
| * Creates a new <var>TF2Stats</var> instance by calling the super | |
| * constructor with the game name <var>"tf2"</var> | |
| * | |
| * @param string $steamId The custom URL or 64bit Steam ID of the user | |
| * @param bool $beta if <var>true</var>, creates stats for the public TF2 | |
| * beta | |
| */ | |
| public function __construct($steamId, $beta = false) { | |
| parent::__construct($steamId, ($beta ? '520' : 'tf2')); | |
| if($this->isPublic()) { | |
| if(!empty($this->xmlData->stats->accumulatedPoints)) { | |
| $this->accumulatedPoints = (int) $this->xmlData->stats->accumulatedPoints; | |
| } | |
| if(!empty($this->xmlData->stats->secondsPlayedAllClassesLifetime)) { | |
| $this->totalPlaytime = (int) $this->xmlData->stats->secondsPlayedAllClassesLifetime; | |
| } | |
| } | |
| } | |
| /** | |
| * Returns the total points this player has achieved in his career | |
| * | |
| * @return int This player's accumulated points | |
| */ | |
| public function getAccumulatedPoints() { | |
| return $this->accumulatedPoints; | |
| } | |
| /** | |
| * Returns the statistics for all Team Fortress 2 classes for this user | |
| * | |
| * If the classes haven't been parsed already, parsing is done now. | |
| * | |
| * @return array An array storing individual stats for each Team Fortress 2 | |
| * class | |
| */ | |
| public function getClassStats() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->classStats)) { | |
| foreach($this->xmlData->stats->classData as $classData) { | |
| $this->classStats[$classData->className] = TF2ClassFactory::getTF2Class($classData); | |
| } | |
| } | |
| return $this->classStats; | |
| } | |
| /** | |
| * Returns the current Team Fortress 2 inventory (a.k.a. backpack) of this | |
| * player | |
| * | |
| * @return TF2Inventory This player's TF2 backpack | |
| */ | |
| public function getInventory() { | |
| if(!$this->isPublic()) { | |
| return null; | |
| } | |
| if(empty($this->inventory)) { | |
| $this->inventory = TF2Inventory::createInventory($this->user->getId()); | |
| } | |
| return $this->inventory; | |
| } | |
| /** | |
| * Returns the accumulated number of seconds this player has spent playing | |
| * as a TF2 class | |
| * | |
| * @return int Total seconds played as a TF2 class | |
| */ | |
| public function getTotalPlaytime() { | |
| return $this->totalPlaytime; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2010-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/WebApiException.php'; | |
| /** | |
| * This adds support for Steam Web API to classes needing this functionality. | |
| * The Web API requires you to register a domain with your Steam account to | |
| * acquire an API key. See http://steamcommunity.com/dev for further details. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| class WebApi { | |
| /** | |
| * @var Monolog\Logger The Monolog logger for this class | |
| */ | |
| private static $log; | |
| /** | |
| * @var string | |
| */ | |
| private static $apiKey = null; | |
| /** | |
| * @var WebApi | |
| */ | |
| protected static $instance = null; | |
| /** | |
| * @var bool | |
| */ | |
| protected static $secure = true; | |
| /** | |
| * Returns the Steam Web API key | |
| * | |
| * @return string The Steam Web API key | |
| */ | |
| public static function getApiKey() { | |
| return self::$apiKey; | |
| } | |
| /** | |
| * Returns a raw list of interfaces and their methods that are available in | |
| * Steam's Web API | |
| * | |
| * This can be used for reference when accessing interfaces and methods | |
| * that have not yet been implemented by Steam Condenser. | |
| * | |
| * @return array The list of interfaces and methods | |
| */ | |
| public static function getInterfaces() { | |
| $data = self::getJSON('ISteamWebAPIUtil', 'GetSupportedAPIList'); | |
| return json_decode($data)->apilist->interfaces; | |
| } | |
| /** | |
| * Fetches JSON data from Steam Web API using the specified interface, | |
| * method and version. Additional parameters are supplied via HTTP GET. | |
| * | |
| * @param string $interface The Web API interface to call, e.g. ISteamUser | |
| * @param string $method The Web API method to call, e.g. | |
| * GetPlayerSummaries | |
| * @param int $version The API method version to use | |
| * @param array $params Additional parameters to supply via HTTP GET | |
| * @return string Data is returned as a JSON-encoded string. | |
| */ | |
| public static function getJSON($interface, $method, $version = 1, $params = null) { | |
| return self::instance()->_getJSON($interface, $method, $version, $params); | |
| } | |
| /** | |
| * Fetches JSON data from Steam Web API using the specified interface, | |
| * method and version. Additional parameters are supplied via HTTP GET. | |
| * | |
| * @param string $interface The Web API interface to call, e.g. ISteamUser | |
| * @param string $method The Web API method to call, e.g. | |
| * GetPlayerSummaries | |
| * @param int $version The API method version to use | |
| * @param array $params Additional parameters to supply via HTTP GET | |
| * @return stdClass Data is returned as a json_decoded object | |
| */ | |
| public static function getJSONData($interface, $method, $version = 1, $params = null) { | |
| return self::instance()->_getJSONData($interface, $method, $version, $params); | |
| } | |
| /** | |
| * Fetches data from Steam Web API using the specified interface, method | |
| * and version. Additional parameters are supplied via HTTP GET. Data is | |
| * returned as a String in the given format. | |
| * | |
| * @param string $format The format to load from the API ('json', 'vdf', or | |
| * 'xml') | |
| * @param string $interface The Web API interface to call, e.g. ISteamUser | |
| * @param string $method The Web API method to call, e.g. | |
| * GetPlayerSummaries | |
| * @param int $version The API method version to use | |
| * @param array $params Additional parameters to supply via HTTP GET | |
| * @return string Data is returned as a String in the given format (which | |
| * may be 'json', 'vdf' or 'xml'). | |
| */ | |
| public static function load($format, $interface, $method, $version = 1, $params = null) { | |
| return self::instance()->_load($format, $interface, $method, $version, $params); | |
| } | |
| /** | |
| * Sets whether HTTPS should be used for the communication with the Web API | |
| * | |
| * @param bool $secure Whether to use HTTPS | |
| */ | |
| public static function setSecure($secure) { | |
| self::$secure = $secure; | |
| } | |
| /** | |
| * Returns a singleton instance of an internal <var>WebApi</var> object | |
| * | |
| * @return WebApi The internal <var>WebApi</var> instance | |
| */ | |
| private static function instance() { | |
| if (self::$instance == null) { | |
| self::$instance = new WebApi(); | |
| self::$log = new \Monolog\Logger('WebApi'); | |
| } | |
| return self::$instance; | |
| } | |
| /** | |
| * Sets the Steam Web API key | |
| * | |
| * @param string $apiKey The 128bit API key that has to be requested from | |
| * http://steamcommunity.com/dev | |
| * @throws WebApiException if the given API key is not a valid 128bit | |
| * hexadecimal string | |
| */ | |
| public static function setApiKey($apiKey) { | |
| if($apiKey != null && !preg_match('/^[0-9A-F]{32}$/', $apiKey)) { | |
| throw new WebApiException(WebApiException::INVALID_KEY); | |
| } | |
| self::$apiKey = $apiKey; | |
| } | |
| /** | |
| * Private constructor to prevent direct usage of <var>WebApi</var> | |
| * instances | |
| */ | |
| private function __construct() {} | |
| /** | |
| * Fetches JSON data from Steam Web API using the specified interface, | |
| * method and version. Additional parameters are supplied via HTTP GET. | |
| * | |
| * @param string $interface The Web API interface to call, e.g. ISteamUser | |
| * @param string $method The Web API method to call, e.g. | |
| * GetPlayerSummaries | |
| * @param int $version The API method version to use | |
| * @param array $params Additional parameters to supply via HTTP GET | |
| * @return string Data is returned as a JSON-encoded string. | |
| */ | |
| protected function _getJSON($interface, $method, $version = 1, $params = null) { | |
| return $this->load('json', $interface, $method, $version, $params); | |
| } | |
| /** | |
| * Fetches JSON data from Steam Web API using the specified interface, | |
| * method and version. Additional parameters are supplied via HTTP GET. | |
| * | |
| * @param string $interface The Web API interface to call, e.g. ISteamUser | |
| * @param string $method The Web API method to call, e.g. | |
| * GetPlayerSummaries | |
| * @param int $version The API method version to use | |
| * @param array $params Additional parameters to supply via HTTP GET | |
| * @return stdClass Data is returned as a json_decoded object | |
| * @throws WebApiException In case of any request failure | |
| */ | |
| protected function _getJSONData($interface, $method, $version = 1, $params = null) { | |
| $data = $this->getJSON($interface, $method, $version, $params); | |
| $result = json_decode($data)->result; | |
| if($result->status != 1) { | |
| throw new WebApiException(WebApiException::STATUS_BAD, $result->status, $result->statusDetail); | |
| } | |
| return $result; | |
| } | |
| /** | |
| * Fetches data from Steam Web API using the specified interface, method | |
| * and version. Additional parameters are supplied via HTTP GET. Data is | |
| * returned as a String in the given format. | |
| * | |
| * @param string $format The format to load from the API ('json', 'vdf', or | |
| * 'xml') | |
| * @param string $interface The Web API interface to call, e.g. ISteamUser | |
| * @param string $method The Web API method to call, e.g. | |
| * GetPlayerSummaries | |
| * @param int $version The API method version to use | |
| * @param array $params Additional parameters to supply via HTTP GET | |
| * @return string Data is returned as a String in the given format (which | |
| * may be 'json', 'vdf' or 'xml'). | |
| */ | |
| protected function _load($format, $interface, $method, $version = 1, $params = null) { | |
| $version = str_pad($version, 4, '0', STR_PAD_LEFT); | |
| $protocol = (self::$secure) ? 'https' : 'http'; | |
| $url = "$protocol://api.steampowered.com/$interface/$method/v$version/"; | |
| $params['format'] = $format; | |
| if (self::$apiKey != null) { | |
| $params['key'] = self::$apiKey; | |
| } | |
| if($params != null && !empty($params)) { | |
| $url .= '?'; | |
| $url_params = array(); | |
| foreach($params as $k => $v) { | |
| $url_params[] = "$k=$v"; | |
| } | |
| $url .= join('&', $url_params); | |
| } | |
| return $this->request($url); | |
| } | |
| /** | |
| * Fetches data from Steam Web API using the specified URL | |
| * | |
| * @param string $url The URL to load | |
| * @return string The data returned by the Web API | |
| * @throws WebApiException if the request failed | |
| */ | |
| protected function request($url) { | |
| self::$log->addDebug("Querying Steam Web API: " . str_replace(self::$apiKey, 'SECRET', $url)); | |
| $data = @file_get_contents($url); | |
| if(empty($data)) { | |
| preg_match('/^.* (\d{3}) (.*)$/', $http_response_header[0], $http_status); | |
| if($http_status[1] == 401) { | |
| throw new WebApiException(WebApiException::UNAUTHORIZED); | |
| } | |
| throw new WebApiException(WebApiException::HTTP_ERROR, $http_status[1], $http_status[2]); | |
| } | |
| return $data; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2009-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/SteamCondenserException.php'; | |
| /** | |
| * This class is used to streamline access to XML-based data resources | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage community | |
| */ | |
| abstract class XMLData { | |
| /** | |
| * Loads XML data from the given URL and returns it parsed into a | |
| * <var>SimpleXMLElement</var> | |
| * | |
| * @param string $url The URL to load the data from | |
| * @return SimpleXMLElement The parsed XML data | |
| * @throws SteamCondenserException if the data cannot be parsed | |
| */ | |
| protected function getData($url) { | |
| try { | |
| return @new SimpleXMLElement($url, 0, true); | |
| } catch (Exception $e) { | |
| throw new SteamCondenserException("XML could not be parsed", 0, $e); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacket.php'; | |
| /** | |
| * This packet class represents a A2M_GET_SERVERS_BATCH2 request sent to a | |
| * master server | |
| * | |
| * It is used to receive a list of game servers matching the specified filters. | |
| * | |
| * Filtering: | |
| * Instead of filtering the results sent by the master server locally, you | |
| * should at least use the following filters to narrow down the results sent by | |
| * the master server. Receiving all servers from the master server is taking | |
| * quite some time. | |
| * | |
| * Available filters: | |
| * <ul> | |
| * <li><var>\type\d</var>: Request only dedicated servers</li> | |
| * <li><var>\secure\1</var>: Request only secure servers</li> | |
| * <li><var>\gamedir\[mod]</var>: Request only servers of a specific mod</li> | |
| * <li><var>\map\[mapname]</var>: Request only servers running a specific | |
| * map</li> | |
| * <li><var>\linux\1</var>: Request only linux servers</li> | |
| * <li><var>\emtpy\1</var>: Request only <b>non</b>-empty servers</li> | |
| * <li><var>\full\1</var>: Request only servers <b>not</b> full</li> | |
| * <li><var>\proxy\1</var>: Request only spectator proxy servers</li> | |
| * </ul> | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage packets | |
| * @see MasterServer::getServers() | |
| */ | |
| class A2M_GET_SERVERS_BATCH2_Packet extends SteamPacket { | |
| private $filter; | |
| private $regionCode; | |
| private $startIp; | |
| /** | |
| * Creates a new A2M_GET_SERVERS_BATCH2 request object, filtering by the | |
| * given paramters | |
| * | |
| * @param int $regionCode The region code to filter servers by region. | |
| * @param string $startIp This should be the last IP received from the | |
| * master server or 0.0.0.0 | |
| * @param string $filter The filters to apply in the form | |
| * ("\filtername\value...") | |
| */ | |
| public function __construct($regionCode = MasterServer::REGION_ALL, $startIp = '0.0.0.0', $filter = '') { | |
| parent::__construct(SteamPacket::A2M_GET_SERVERS_BATCH2_HEADER); | |
| $this->filter = $filter; | |
| $this->regionCode = $regionCode; | |
| $this->startIp = $startIp; | |
| } | |
| /** | |
| * Returns the raw data representing this packet | |
| * | |
| * @return string A string containing the raw data of this request packet | |
| */ | |
| public function __toString() { | |
| return chr($this->headerData) . chr($this->regionCode) . $this->startIp . "\0" . $this->filter . "\0"; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacket.php'; | |
| /** | |
| * This packet class class represents a A2S_INFO request send to a game server | |
| * | |
| * It will cause the server to send some basic information about itself, e.g. | |
| * the running game, map and the number of players. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage packets | |
| * @see GameServer::updateServerInfo() | |
| */ | |
| class A2S_INFO_Packet extends SteamPacket { | |
| /** | |
| * Creates a new A2S_INFO request object | |
| */ | |
| public function __construct() { | |
| parent::__construct(SteamPacket::A2S_INFO_HEADER, "Source Engine Query\0"); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/RequestPacketWithChallenge.php'; | |
| /** | |
| * This packet class represents a A2S_PLAYER request send to a game server | |
| * | |
| * It is used to request the list of players currently playing on the server. | |
| * | |
| * This packet type requires the client to challenge the server in advance, | |
| * which is done automatically if required. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage packets | |
| * @see GameServer::updatePlayerInfo() | |
| */ | |
| class A2S_PLAYER_Packet extends RequestPacketWithChallenge { | |
| /** | |
| * Creates a new A2S_PLAYER request object including the challenge number | |
| * | |
| * @param int $challengeNumber The challenge number received from the | |
| * server | |
| */ | |
| public function __construct($challengeNumber = 0xFFFFFFFF) { | |
| parent::__construct(SteamPacket::A2S_PLAYER_HEADER, $challengeNumber); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/RequestPacketWithChallenge.php'; | |
| /** | |
| * This packet class represents a A2S_RULES request send to a game server | |
| * | |
| * The game server will return a list of currently active game rules, e.g. | |
| * <var>mp_friendlyfire = 1</var>. | |
| * | |
| * This packet type requires the client to challenge the server in advance, | |
| * which is done automatically if required. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage packets | |
| * @see GameServer::updateRulesInfo() | |
| */ | |
| class A2S_RULES_Packet extends RequestPacketWithChallenge { | |
| /** | |
| * Creates a new A2S_RULES request object including the challenge number | |
| * | |
| * @param int $challengeNumber The challenge number received from the | |
| * server | |
| */ | |
| public function __construct($challengeNumber = 0xFFFFFFFF) | |
| { | |
| parent::__construct(SteamPacket::A2S_RULES_HEADER, $challengeNumber); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacket.php'; | |
| /** | |
| * This packet class represents a A2S_SERVERQUERY_GETCHALLENGE request send to | |
| * a game server | |
| * | |
| * It is used to retrieve a challenge number from the game server, which helps | |
| * to identify the requesting client. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage packets | |
| * @see GameServer::updateChallengeNumber() | |
| */ | |
| class A2S_SERVERQUERY_GETCHALLENGE_Packet extends SteamPacket { | |
| /** | |
| * Creates a new A2S_SERVERQUERY_GETCHALLENGE request object | |
| */ | |
| public function __construct() { | |
| parent::__construct(SteamPacket::A2S_SERVERQUERY_GETCHALLENGE_HEADER); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacket.php'; | |
| /** | |
| * This packet class represents a M2A_SERVER_BATCH response replied by a master | |
| * server | |
| * | |
| * It contains a list of IP addresses and ports of game servers matching the | |
| * requested criteria. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage packets | |
| * @see MasterServer::getServers() | |
| */ | |
| class M2A_SERVER_BATCH_Packet extends SteamPacket { | |
| /** | |
| * @var array | |
| */ | |
| private $serverArray; | |
| /** | |
| * Creates a new M2A_SERVER_BATCH response object based on the given data | |
| * | |
| * @param string $data The raw packet data replied from the server | |
| * @throws PacketFormatException if the packet data is not well formatted | |
| */ | |
| public function __construct($data) { | |
| parent::__construct(SteamPacket::M2A_SERVER_BATCH_HEADER, $data); | |
| if($this->contentData->getByte() != 10) { | |
| throw new PacketFormatException('Master query response is missing additional 0x0A byte.'); | |
| } | |
| do { | |
| $firstOctet = $this->contentData->getByte(); | |
| $secondOctet = $this->contentData->getByte(); | |
| $thirdOctet = $this->contentData->getByte(); | |
| $fourthOctet = $this->contentData->getByte(); | |
| $portNumber = $this->contentData->getShort(); | |
| $portNumber = (($portNumber & 0xFF) << 8) + ($portNumber >> 8); | |
| $this->serverArray[] = "$firstOctet.$secondOctet.$thirdOctet.$fourthOctet:$portNumber"; | |
| } while($this->contentData->remaining() > 0); | |
| } | |
| /** | |
| * Returns the list of servers returned from the server in this packet | |
| * | |
| * @return array An array of server addresses (i.e. IP addresses + port | |
| * numbers) | |
| */ | |
| public function getServers() { | |
| return $this->serverArray; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONPacket.php'; | |
| /** | |
| * This packet class represents a SERVERDATA_AUTH request sent to a Source | |
| * server | |
| * | |
| * It is used to authenticate the client for RCON communication. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage rcon-packets | |
| * @see SourceServer::rconAuth() | |
| */ | |
| class RCONAuthRequest extends RCONPacket { | |
| /** | |
| * Creates a RCON authentication request for the given request ID and RCON | |
| * password | |
| * | |
| * @param int $requestId The request ID of the RCON connection | |
| * @param string $password The RCON password of the server | |
| */ | |
| public function __construct($requestId, $password) { | |
| parent::__construct($requestId, RCONPacket::SERVERDATA_AUTH, $password); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONPacket.php'; | |
| /** | |
| * This packet class represents a SERVERDATA_AUTH_RESPONSE packet sent by a | |
| * Source server | |
| * | |
| * It is used to indicate the success or failure of an authentication attempt | |
| * of a client for RCON communication. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage rcon-packets | |
| * @see SourceServer::rconAuth() | |
| */ | |
| class RCONAuthResponse extends RCONPacket { | |
| /** | |
| * Creates a RCON authentication response for the given request ID | |
| * | |
| * The request ID of the packet will match the client's request if | |
| * authentication was successful | |
| * | |
| * @param int $requestId The request ID of the RCON connection | |
| */ | |
| public function __construct($requestId) { | |
| parent::__construct($requestId, RCONPacket::SERVERDATA_AUTH_RESPONSE); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONPacket.php'; | |
| /** | |
| * This packet class represents a SERVERDATA_EXECCOMMAND packet sent to a | |
| * Source server | |
| * | |
| * It is used to request a command execution on the server. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage rcon-packets | |
| * @see SourceServer::rconExec() | |
| */ | |
| class RCONExecRequest extends RCONPacket { | |
| /** | |
| * Creates a RCON command execution request for the given request ID and | |
| * command | |
| * | |
| * @param int $requestId The request ID of the RCON connection | |
| * @param string $command The command to execute on the server | |
| */ | |
| public function __construct($requestId, $command) { | |
| parent::__construct($requestId, RCONPacket::SERVERDATA_EXECCOMMAND, $command); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONPacket.php'; | |
| /** | |
| * This packet class represents a SERVERDATA_RESPONSE_VALUE packet sent by a | |
| * Source server | |
| * | |
| * It is used to transport the output of a command from the server to the | |
| * client which requested the command execution. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage rcon-packets | |
| * @see SourceServer::rconExec() | |
| */ | |
| class RCONExecResponse extends RCONPacket { | |
| /** | |
| * Creates a RCON command response for the given request ID and command | |
| * output | |
| * | |
| * @param int $requestId The request ID of the RCON connection | |
| * @param string $commandResponse The output of the command executed on the | |
| * server | |
| */ | |
| public function __construct($requestId, $commandResponse) { | |
| parent::__construct($requestId, RCONPacket::SERVERDATA_RESPONSE_VALUE, $commandResponse); | |
| } | |
| /** | |
| * Returns the output of the command execution | |
| * | |
| * @return string The output of the command | |
| */ | |
| public function getResponse() { | |
| $response = $this->contentData->_array(); | |
| return substr($response, 0, strlen($response) - 2); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacket.php'; | |
| /** | |
| * This packet class represents a RCON request packet sent to a GoldSrc server | |
| * | |
| * It is used to request a command execution on the server. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage rcon-packets | |
| * @see GoldSrcServer::rconExec() | |
| */ | |
| class RCONGoldSrcRequest extends SteamPacket { | |
| /** | |
| * Creates a request for the given request string | |
| * | |
| * The request string has the form <var>rcon {challenge number} {RCON | |
| * password} {command}</var>. | |
| * | |
| * @param string $request The request string to send to the server | |
| */ | |
| public function __construct($request) { | |
| parent::__construct(0x00, $request); | |
| } | |
| /** | |
| * Returns the raw data representing this packet | |
| * | |
| * @return string A string containing the raw data of this request packet | |
| */ | |
| public function __toString() { | |
| return pack('Va*', 0xFFFFFFFF, $this->contentData->_array()); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONPacket.php'; | |
| /** | |
| * This packet class represents a RCON response packet sent by a GoldSrc server | |
| * | |
| * It is used to transport the output of a command from the server to the | |
| * client which requested the command execution. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage rcon-packets | |
| * @see GoldSrcServer::rconExec() | |
| */ | |
| class RCONGoldSrcResponse extends SteamPacket | |
| { | |
| /** | |
| * Creates a RCON command response for the given command output | |
| * | |
| * @param string $commandResponse The output of the command executed on the | |
| * server | |
| */ | |
| public function __construct($commandResponse) { | |
| parent::__construct(SteamPacket::RCON_GOLDSRC_RESPONSE_HEADER, $commandResponse); | |
| } | |
| /** | |
| * Returns the output of the command execution | |
| * | |
| * @return string The output of the command | |
| */ | |
| public function getResponse() { | |
| return substr($this->contentData->_array(), 0, -2); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacket.php'; | |
| /** | |
| * This module is included by all classes representing a packet used by | |
| * Source's RCON protocol | |
| * | |
| * It provides a basic implementation for initializing and serializing such a | |
| * packet. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage rcon-packets | |
| * @see RCONPacketFactory | |
| */ | |
| abstract class RCONPacket extends SteamPacket { | |
| /** | |
| * @var int Header for authentication requests | |
| */ | |
| const SERVERDATA_AUTH = 3; | |
| /** | |
| * @var int Header for replies to authentication attempts | |
| */ | |
| const SERVERDATA_AUTH_RESPONSE = 2; | |
| /** | |
| * @var int Header for command execution requests | |
| */ | |
| const SERVERDATA_EXECCOMMAND = 2; | |
| /** | |
| * @var int Header for packets with the output of a command execution | |
| */ | |
| const SERVERDATA_RESPONSE_VALUE = 0; | |
| /** | |
| * @var int The request ID used to identify the RCON communication | |
| */ | |
| private $requestId; | |
| /** | |
| * Creates a new RCON packet object with the given request ID, type and | |
| * content data | |
| * | |
| * @param int $requestId The request ID for the current RCON communication | |
| * @param int $rconHeader The header for the packet type | |
| * @param string $rconData The raw packet data | |
| */ | |
| public function __construct($requestId, $rconHeader, $rconData = null) { | |
| parent::__construct($rconHeader, "$rconData\0\0"); | |
| $this->requestId = $requestId; | |
| } | |
| /** | |
| * Returns the request ID used to identify the RCON communication | |
| * | |
| * @return int The request ID used to identify the RCON communication | |
| */ | |
| public function getRequestId() { | |
| return $this->requestId; | |
| } | |
| /** | |
| * Returns the raw data representing this packet | |
| * | |
| * @return string A string containing the raw data of this RCON packet | |
| */ | |
| public function __toString() { | |
| $contentData = $this->contentData->_array(); | |
| return pack('V3a*', strlen($contentData) + 8, $this->requestId, $this->headerData, $contentData); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'ByteBuffer.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacketFactory.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONAuthResponse.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONExecResponse.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONPacket.php'; | |
| /** | |
| * This module provides functionality to handle raw packet data for Source RCON | |
| * | |
| * It's is used to transform data bytes into packet objects for RCON | |
| * communication with Source servers. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage rcon-packets | |
| * @see RCONPacket | |
| */ | |
| abstract class RCONPacketFactory | |
| { | |
| /** | |
| * Creates a new packet object based on the header byte of the given raw | |
| * data | |
| * | |
| * @param string $rawData The raw data of the packet | |
| * @return RCONPacket The packet object generated from the packet data | |
| * @throws PacketFormatException if the packet header is not recognized | |
| */ | |
| public static function getPacketFromData($rawData) { | |
| $byteBuffer = new ByteBuffer($rawData); | |
| $requestId = $byteBuffer->getLong(); | |
| $header = $byteBuffer->getLong(); | |
| $data = $byteBuffer->getString(); | |
| switch($header) { | |
| case RCONPacket::SERVERDATA_AUTH_RESPONSE: | |
| return new RCONAuthResponse($requestId); | |
| case RCONPacket::SERVERDATA_RESPONSE_VALUE: | |
| return new RCONExecResponse($requestId, $data); | |
| default: | |
| throw new PacketFormatException('Unknown packet with header ' . dechex($header) . ' received.'); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONPacket.php'; | |
| /** | |
| * This packet class represents a special SERVERDATA_RESPONSE_VALUE packet | |
| * which is sent to the server | |
| * | |
| * It is used to determine the end of a RCON response from Source servers. | |
| * Packets of this type are sent after the actual RCON command and the empty | |
| * response packet from the server will indicate the end of the response. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage rcon-packets | |
| * @see SourceServer::rconExec() | |
| */ | |
| class RCONTerminator extends RCONPacket { | |
| /** | |
| * Creates a new RCON terminator packet instance for the given request ID | |
| * | |
| * @param int $requestId The request ID for the current RCON communication | |
| */ | |
| public function __construct($requestId) { | |
| parent::__construct($requestId, RCONPacket::SERVERDATA_RESPONSE_VALUE); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacket.php'; | |
| /** | |
| * This abstract class implements a method to generate raw packet data used by | |
| * request packets which send a challenge number | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage packets | |
| */ | |
| abstract class RequestPacketWithChallenge extends SteamPacket { | |
| /** | |
| * Returns the raw data representing this packet | |
| * | |
| * @return string A string containing the raw data of this request packet | |
| */ | |
| public function __toString() { | |
| return pack('cccccV', 0xFF, 0xFF, 0xFF, 0xFF, $this->headerData, $this->contentData->_array()); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/S2A_INFO_BasePacket.php'; | |
| /** | |
| * This class represents a S2A_INFO_DETAILED response packet sent by a Source | |
| * or GoldSrc server | |
| * | |
| * Out-of-date (before 10/24/2008) GoldSrc servers use an older format (see | |
| * {@link S2A_INFO_DETAILED_Packet}). | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage packets | |
| * @see GameServer::updateServerInfo() | |
| */ | |
| class S2A_INFO2_Packet extends S2A_INFO_BasePacket { | |
| const EDF_GAME_ID = 0x01; | |
| const EDF_GAME_PORT = 0x80; | |
| const EDF_SERVER_ID = 0x10; | |
| const EDF_SERVER_TAGS = 0x20; | |
| const EDF_SOURCE_TV = 0x40; | |
| /** | |
| * Creates a new S2A_INFO2 response object based on the given data | |
| * | |
| * @param string $data The raw packet data replied from the server | |
| */ | |
| public function __construct($data) { | |
| parent::__construct(SteamPacket::S2A_INFO2_HEADER, $data); | |
| $this->info['networkVersion'] = $this->contentData->getByte(); | |
| $this->info['serverName'] = $this->contentData->getString(); | |
| $this->info['mapName'] = $this->contentData->getString(); | |
| $this->info['gameDir'] = $this->contentData->getString(); | |
| $this->info['gameDesc'] = $this->contentData->getString(); | |
| $this->info['appId'] = $this->contentData->getShort(); | |
| $this->info['numberOfPlayers'] = $this->contentData->getByte(); | |
| $this->info['maxPlayers'] = $this->contentData->getByte(); | |
| $this->info['botNumber'] = $this->contentData->getByte(); | |
| $this->info['dedicated'] = chr($this->contentData->getByte()); | |
| $this->info['operatingSystem'] = chr($this->contentData->getByte()); | |
| $this->info['passwordProtected'] = $this->contentData->getByte() == 1; | |
| $this->info['secureServer'] = $this->contentData->getByte() == 1; | |
| $this->info['gameVersion'] = $this->contentData->getString(); | |
| if($this->contentData->remaining() > 0) { | |
| $extraDataFlag = $this->contentData->getByte(); | |
| if ($extraDataFlag & self::EDF_GAME_PORT) { | |
| $this->info['serverPort'] = $this->contentData->getShort(); | |
| } | |
| if ($extraDataFlag & self::EDF_SERVER_ID) { | |
| $this->info['serverId'] = $this->contentData->getUnsignedLong() | ($this->contentData->getUnsignedLong() << 32); | |
| } | |
| if ($extraDataFlag & self::EDF_SOURCE_TV) { | |
| $this->info['tvPort'] = $this->contentData->getShort(); | |
| $this->info['tvName'] = $this->contentData->getString(); | |
| } | |
| if ($extraDataFlag & self::EDF_SERVER_TAGS) { | |
| $this->info['serverTags'] = $this->contentData->getString(); | |
| } | |
| if ($extraDataFlag & self::EDF_GAME_ID) { | |
| $this->info['gameId'] = $this->contentData->getUnsignedLong() | ($this->contentData->getUnsignedLong() << 32); | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacket.php'; | |
| /** | |
| * This module implements methods to generate and access server information | |
| * from S2A_INFO_DETAILED and S2A_INFO2 response packets | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage packets | |
| * @see S2A_INFO_DETAILED_Packet | |
| * @see S2A_INFO2_Packet | |
| */ | |
| abstract class S2A_INFO_BasePacket extends SteamPacket { | |
| /** | |
| * @var array | |
| */ | |
| protected $info = array(); | |
| /** | |
| * Returns a generated array of server properties from the instance | |
| * variables of the packet object | |
| * | |
| * @return array The information provided by the server | |
| */ | |
| public function getInfo() { | |
| return $this->info; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/S2A_INFO_BasePacket.php'; | |
| /** | |
| * This class represents a S2A_INFO_DETAILED response packet sent by a GoldSrc | |
| * server | |
| * | |
| * @author Sebastian Staudt | |
| * @deprecated Only outdated GoldSrc servers (before 10/24/2008) use this | |
| * format. Newer ones use the same format as Source servers now | |
| * (see {@link S2A_INFO2_Packet}). | |
| * @package steam-condenser | |
| * @subpackage packets | |
| * @see GameServer::updateServerInfo() | |
| */ | |
| class S2A_INFO_DETAILED_Packet extends S2A_INFO_BasePacket { | |
| /** | |
| * Creates a new S2A_INFO_DETAILED response object based on the given data | |
| * | |
| * @param string $data The raw packet data replied from the server | |
| */ | |
| public function __construct($data) { | |
| parent::__construct(SteamPacket::S2A_INFO_DETAILED_HEADER, $data); | |
| $this->info['serverIp'] = $this->contentData->getString(); | |
| $this->info['serverName'] = $this->contentData->getString(); | |
| $this->info['mapName'] = $this->contentData->getString(); | |
| $this->info['gameDir'] = $this->contentData->getString(); | |
| $this->info['gameDescription'] = $this->contentData->getString(); | |
| $this->info['numberOfPlayers'] = $this->contentData->getByte(); | |
| $this->info['maxPlayers'] = $this->contentData->getByte(); | |
| $this->info['networkVersion'] = $this->contentData->getByte(); | |
| $this->info['dedicated'] = $this->contentData->getByte(); | |
| $this->info['operatingSystem'] = $this->contentData->getByte(); | |
| $this->info['passwordProtected'] = $this->contentData->getByte() == 1; | |
| $this->info['isMod'] = $this->contentData->getByte() == 1; | |
| if($this->isMod) { | |
| $this->info['modInfo']['urlInfo'] = $this->contentData->getString(); | |
| $this->info['modInfo']['urlDl'] = $this->contentData->getString(); | |
| $this->contentData->getByte(); | |
| if($this->contentData->remaining() == 12) { | |
| $this->info['modInfo']['modVersion'] = $this->contentData->getLong(); | |
| $this->info['modInfo']['modSize'] = $this->contentData->getLong(); | |
| $this->info['modInfo']['svOnly'] = ($this->contentData->getByte() == 1); | |
| $this->info['modInfo']['clDll'] = ($this->contentData->getByte() == 1); | |
| $this->info['secure'] = $this->contentData->getByte() == 1; | |
| $this->info['numberOfBots'] = $this->contentData->getByte(); | |
| } | |
| } else { | |
| $this->info['secure'] = $this->contentData->getByte() == 1; | |
| $this->info['numberOfBots'] = $this->contentData->getByte(); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2010-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacket.php'; | |
| /** | |
| * This class represents a S2A_LOGSTRING packet used to transfer log messages | |
| * | |
| * @package steam-condenser | |
| * @subpackage packets | |
| * @author Sebastian Staudt | |
| */ | |
| class S2A_LOGSTRING_Packet extends SteamPacket { | |
| /** | |
| * @var string The log message contained in this packet | |
| */ | |
| private $message; | |
| /** | |
| * Creates a new S2A_LOGSTRING object based on the given data | |
| * | |
| * @param string $data The raw packet data sent by the server | |
| */ | |
| public function __construct($data) { | |
| parent::__construct(SteamPacket::S2A_LOGSTRING_HEADER, $data); | |
| $this->contentData->getByte(); | |
| $this->message = $this->contentData->getString(); | |
| } | |
| /** | |
| * Returns the log message contained in this packet | |
| * | |
| * @return string The log message | |
| */ | |
| public function getMessage() { | |
| return $this->message; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/SteamPlayer.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacket.php'; | |
| /** | |
| * This class represents a S2A_PLAYER response sent by a game server | |
| * | |
| * It is used to transfer a list of players currently playing on the server. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage packets | |
| * @see GameServer::updatePlayerInfo() | |
| */ | |
| class S2A_PLAYER_Packet extends SteamPacket { | |
| /** | |
| * @var array | |
| */ | |
| private $playerHash; | |
| /** | |
| * Creates a new S2A_PLAYER response object based on the given data | |
| * | |
| * @param string $contentData The raw packet data sent by the server | |
| * @throws PacketFormatException if the packet data is missing | |
| */ | |
| public function __construct($contentData) { | |
| if (empty($contentData)) { | |
| throw new PacketFormatException('Wrong formatted S2A_RULES packet.'); | |
| } | |
| parent::__construct(SteamPacket::S2A_PLAYER_HEADER, $contentData); | |
| $this->contentData->getByte(); | |
| $this->playerHash = array(); | |
| while($this->contentData->remaining() > 0) { | |
| $playerData = array($this->contentData->getByte(), $this->contentData->getString(), $this->contentData->getLong(), $this->contentData->getFloat()); | |
| $this->playerHash[$playerData[1]] = new SteamPlayer($playerData[0], $playerData[1], $playerData[2], $playerData[3]); | |
| } | |
| } | |
| /** | |
| * Returns the list of active players provided by the server | |
| * | |
| * @return array All active players on the server | |
| */ | |
| public function getPlayerHash() { | |
| return $this->playerHash; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacket.php'; | |
| /** | |
| * This class represents a S2A_RULES response sent by a game server | |
| * | |
| * It is used to transfer a list of server rules (a.k.a. CVARs) with their | |
| * active values. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage packets | |
| * @see GameServer::updateRulesInfo() | |
| */ | |
| class S2A_RULES_Packet extends SteamPacket { | |
| /** | |
| * @var array | |
| */ | |
| private $rulesArray; | |
| /** | |
| * Creates a new S2A_RULES response object based on the given data | |
| * | |
| * @param string $contentData The raw packet data sent by the server | |
| * @throws PacketFormatException if the packet data is missing | |
| */ | |
| public function __construct($contentData) { | |
| if (empty($contentData)) { | |
| throw new PacketFormatException('Wrong formatted S2A_RULES packet.'); | |
| } | |
| parent::__construct(SteamPacket::S2A_RULES_HEADER, $contentData); | |
| $rulesCount = $this->contentData->getShort(); | |
| $this->rulesArray = array(); | |
| for($x = 0; $x < $rulesCount; $x++) { | |
| $rule = $this->contentData->getString(); | |
| $value = $this->contentData->getString(); | |
| if(empty($rule)) { | |
| break; | |
| } | |
| $this->rulesArray[$rule] = $value; | |
| } | |
| } | |
| /** | |
| * Returns the list of server rules (a.k.a. CVars) with the current values | |
| * | |
| * @return array A list of server rules | |
| */ | |
| public function getRulesArray() { | |
| return $this->rulesArray; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacket.php'; | |
| /** | |
| * This packet class represents a S2C_CHALLENGE response replied by a game | |
| * server | |
| * | |
| * It is used to provide a challenge number to a client requesting information | |
| * from the game server. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage packets | |
| * @see GameServer::updateChallengeNumber() | |
| */ | |
| class S2C_CHALLENGE_Packet extends SteamPacket { | |
| /** | |
| * Creates a new S2C_CHALLENGE response object based on the given data | |
| * | |
| * @param string $challengeNumber The raw packet data replied from the | |
| * server | |
| */ | |
| public function __construct($challengeNumber) { | |
| parent::__construct(SteamPacket::S2C_CHALLENGE_HEADER, $challengeNumber); | |
| } | |
| /** | |
| * Returns the challenge number received from the game server | |
| * | |
| * @return int The challenge number provided by the game server | |
| */ | |
| public function getChallengeNumber() { | |
| return $this->contentData->rewind()->getLong(); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'ByteBuffer.php'; | |
| /** | |
| * This module implements the basic functionality used by most of the packets | |
| * used in communication with master, Source or GoldSrc servers. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage packets | |
| * @see SteamPacketFactory | |
| */ | |
| abstract class SteamPacket { | |
| const S2A_INFO_DETAILED_HEADER = 0x6D; | |
| const A2S_INFO_HEADER = 0x54; | |
| const S2A_INFO2_HEADER = 0x49; | |
| const A2S_PLAYER_HEADER = 0x55; | |
| const S2A_PLAYER_HEADER = 0x44; | |
| const A2S_RULES_HEADER = 0x56; | |
| const S2A_RULES_HEADER = 0x45; | |
| const A2S_SERVERQUERY_GETCHALLENGE_HEADER = 0x57; | |
| const S2C_CHALLENGE_HEADER = 0x41; | |
| const A2M_GET_SERVERS_BATCH2_HEADER = 0x31; | |
| const C2M_CHECKMD5_HEADER = 0x4D; | |
| const M2A_SERVER_BATCH_HEADER = 0x66; | |
| const M2C_ISVALIDMD5_HEADER = 0x4E; | |
| const M2S_REQUESTRESTART_HEADER = 0x4F; | |
| const RCON_GOLDSRC_CHALLENGE_HEADER = 0x63; | |
| const RCON_GOLDSRC_NO_CHALLENGE_HEADER = 0x39; | |
| const RCON_GOLDSRC_RESPONSE_HEADER = 0x6C; | |
| const S2A_LOGSTRING_HEADER = 0x52; | |
| const S2M_HEARTBEAT2_HEADER = 0x30; | |
| /** | |
| * @var string This variable stores the content of the packet | |
| */ | |
| protected $contentData; | |
| /** | |
| * @var int This byte stores the type of the packet | |
| */ | |
| protected $headerData; | |
| /** | |
| * Creates a new packet object based on the given data | |
| * | |
| * @param int $headerData The packet header | |
| * @param string $contentData The raw data of the packet | |
| */ | |
| public function __construct($headerData, $contentData = null) { | |
| $this->headerData = $headerData; | |
| $this->contentData = ByteBuffer::wrap($contentData); | |
| } | |
| /** | |
| * @return ByteBuffer The data payload of the packet | |
| */ | |
| public function getData() { | |
| return $this->contentData; | |
| } | |
| /** | |
| * @return int The header of the packet | |
| */ | |
| public function getHeader() { | |
| return $this->headerData; | |
| } | |
| /** | |
| * Returns the raw data representing this packet | |
| * | |
| * @return string A string containing the raw data of this request packet | |
| */ | |
| public function __toString() { | |
| $packetData = pack('c5', 0xFF, 0xFF, 0xFF, 0xFF, $this->headerData); | |
| $packetData .= $this->contentData->_array(); | |
| return $packetData; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/PacketFormatException.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONGoldSrcResponse.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/S2A_INFO_DETAILED_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/A2S_INFO_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/S2A_INFO2_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/A2S_PLAYER_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/S2A_PLAYER_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/A2S_RULES_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/S2A_RULES_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/A2S_SERVERQUERY_GETCHALLENGE_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/S2C_CHALLENGE_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/A2M_GET_SERVERS_BATCH2_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/M2A_SERVER_BATCH_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/S2A_LOGSTRING_Packet.php'; | |
| /** | |
| * This module provides functionality to handle raw packet data, including data | |
| * split into several UDP / TCP packets and BZIP2 compressed data. It's the | |
| * main utility to transform data bytes into packet objects. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage packets | |
| * @see SteamPacket | |
| */ | |
| abstract class SteamPacketFactory { | |
| /** | |
| * Creates a new packet object based on the header byte of the given raw | |
| * data | |
| * | |
| * @param string $rawData The raw data of the packet | |
| * @throws PacketFormatException if the packet header is not recognized | |
| * @return SteamPacket The packet object generated from the packet data | |
| */ | |
| public static function getPacketFromData($rawData) { | |
| $header = ord($rawData[0]); | |
| $data = substr($rawData, 1); | |
| switch($header) { | |
| case SteamPacket::S2A_INFO_DETAILED_HEADER: | |
| return new S2A_INFO_DETAILED_Packet($data); | |
| case SteamPacket::A2S_INFO_HEADER: | |
| return new A2S_INFO_Packet(); | |
| case SteamPacket::S2A_INFO2_HEADER: | |
| return new S2A_INFO2_Packet($data); | |
| case SteamPacket::A2S_PLAYER_HEADER: | |
| return new A2S_PLAYER_Packet(); | |
| case SteamPacket::S2A_PLAYER_HEADER: | |
| return new S2A_PLAYER_Packet($data); | |
| case SteamPacket::A2S_RULES_HEADER: | |
| return new A2S_RULES_Packet(); | |
| case SteamPacket::S2A_RULES_HEADER: | |
| return new S2A_RULES_Packet($data); | |
| case SteamPacket::A2S_SERVERQUERY_GETCHALLENGE_HEADER: | |
| return new A2S_SERVERQUERY_GETCHALLENGE_Packet(); | |
| case SteamPacket::S2C_CHALLENGE_HEADER: | |
| return new S2C_CHALLENGE_Packet($data); | |
| case SteamPacket::A2M_GET_SERVERS_BATCH2_HEADER: | |
| return new A2M_GET_SERVERS_BATCH2_Packet($data); | |
| case SteamPacket::M2A_SERVER_BATCH_HEADER: | |
| return new M2A_SERVER_BATCH_Packet($data); | |
| case SteamPacket::RCON_GOLDSRC_CHALLENGE_HEADER: | |
| case SteamPacket::RCON_GOLDSRC_NO_CHALLENGE_HEADER: | |
| case SteamPacket::RCON_GOLDSRC_RESPONSE_HEADER: | |
| return new RCONGoldSrcResponse($data); | |
| case SteamPacket::S2A_LOGSTRING_HEADER: | |
| return new S2A_LOGSTRING_Packet($data); | |
| default: | |
| throw new PacketFormatException('Unknown packet with header 0x' . dechex($header) . ' received.'); | |
| } | |
| } | |
| /** | |
| * Reassembles the data of a split and/or compressed packet into a single | |
| * packet object | |
| * | |
| * @param array $splitPackets An array of packet data | |
| * @param bool $isCompressed whether the data of this packet is compressed | |
| * @param int $packetChecksum The CRC32 checksum of the decompressed | |
| * packet data | |
| * @throws PacketFormatException if the calculated CRC32 checksum does not | |
| * match the expected value | |
| * @return SteamPacket The reassembled packet | |
| * @see packetFromData() | |
| */ | |
| public static function reassemblePacket($splitPackets, $isCompressed = false, $packetChecksum = 0) { | |
| $packetData = ''; | |
| foreach($splitPackets as $splitPacket) { | |
| $packetData .= $splitPacket; | |
| } | |
| if($isCompressed) { | |
| $packetData = bzdecompress($packetData); | |
| if(crc32($packetData) != $packetChecksum) { | |
| throw new PacketFormatException('CRC32 checksum mismatch of uncompressed packet data.'); | |
| } | |
| } | |
| $packetData = substr($packetData, 4); | |
| return self::getPacketFromData($packetData); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/SteamCondenserException.php'; | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/TimeoutException.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/A2S_INFO_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/A2S_PLAYER_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/A2S_RULES_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/A2S_SERVERQUERY_GETCHALLENGE_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/servers/Server.php'; | |
| /** | |
| * This class is subclassed by classes representing different game server | |
| * implementations and provides the basic functionality to communicate with | |
| * them using the common query protocol | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage servers | |
| */ | |
| abstract class GameServer extends Server { | |
| const REQUEST_CHALLENGE = 0; | |
| const REQUEST_INFO = 1; | |
| const REQUEST_PLAYER = 2; | |
| const REQUEST_RULES = 3; | |
| /** | |
| * @var Monolog\Logger The Monolog logger for this class | |
| */ | |
| private static $log; | |
| /** | |
| * @var int The challenge number to communicate with the server | |
| */ | |
| protected $challengeNumber; | |
| /** | |
| * @var array Basic information about this server | |
| */ | |
| protected $infoHash; | |
| /** | |
| * @var int The response time of this server | |
| */ | |
| protected $ping; | |
| /** | |
| * @var array The players playing on this server | |
| */ | |
| protected $playerHash; | |
| /** | |
| * @var bool whether the RCON connection is already authenticated | |
| */ | |
| protected $rconAuthenticated; | |
| /** | |
| * @var array The settings applied on the server | |
| */ | |
| protected $rulesHash; | |
| /** | |
| * @var SteamSocket The socket of to communicate with the server | |
| */ | |
| protected $socket; | |
| /** | |
| * Parses the player attribute names supplied by <var>rcon status</var> | |
| * | |
| * @param string $statusHeader The header line provided by <var>rcon | |
| * status</var> | |
| * @return array Split player attribute names | |
| * @see splitPlayerStatus() | |
| */ | |
| protected function getPlayerStatusAttributes($statusHeader) { | |
| $statusAttributes = array(); | |
| foreach(preg_split("/\s+/", $statusHeader) as $attribute) { | |
| if($attribute == 'connected') { | |
| $statusAttributes[] = 'time'; | |
| } else if($attribute == 'frag') { | |
| $statusAttributes[] = 'score'; | |
| } else { | |
| $statusAttributes[] = $attribute; | |
| } | |
| } | |
| return $statusAttributes; | |
| } | |
| /** | |
| * Splits the player status obtained with <var>rcon status</var> | |
| * | |
| * @param array $attributes The attribute names | |
| * @param string $playerStatus The status line of a single player | |
| * @return array The attributes with the corresponding values for this | |
| * player | |
| * @see getPlayerStatusAttributes() | |
| */ | |
| protected function splitPlayerStatus($attributes, $playerStatus) { | |
| if($attributes[0] != 'userid') { | |
| $playerStatus = preg_replace('/^\d+ +/', '', $playerStatus); | |
| } | |
| $firstQuote = strpos($playerStatus, '"'); | |
| $lastQuote = strrpos($playerStatus, '"'); | |
| $data = array( | |
| substr($playerStatus, 0, $firstQuote), | |
| substr($playerStatus, $firstQuote + 1, $lastQuote - 1 - $firstQuote), | |
| substr($playerStatus, $lastQuote + 1) | |
| ); | |
| $data = array_merge( | |
| array_filter(preg_split("/\s+/", trim($data[0]))), | |
| array($data[1]), | |
| preg_split("/\s+/", trim($data[2])) | |
| ); | |
| $data = array_values($data); | |
| if(sizeof($attributes) > sizeof($data) && | |
| in_array('state', $attributes)) { | |
| array_splice($data, 3, 0, array(null, null, null)); | |
| } elseif(sizeof($attributes) < sizeof($data)) { | |
| unset($data[1]); | |
| $data = array_values($data); | |
| } | |
| $playerData = array(); | |
| for($i = 0; $i < sizeof($data); $i ++) { | |
| $playerData[$attributes[$i]] = $data[$i]; | |
| } | |
| return $playerData; | |
| } | |
| /** | |
| * Creates a new instance of a game server object | |
| * | |
| * @param string $address Either an IP address, a DNS name or one of them | |
| * combined with the port number. If a port number is given, e.g. | |
| * 'server.example.com:27016' it will override the second argument. | |
| * @param int $port The port the server is listening on | |
| * @throws SteamCondenserException if an host name cannot be resolved | |
| */ | |
| public function __construct($address, $port = 27015) { | |
| parent::__construct($address, $port); | |
| $this->rconAuthenticated = false; | |
| if (!isset(self::$log)) { | |
| //self::$log = new \Monolog\Logger('MasterServer'); | |
| } | |
| } | |
| /** | |
| * Returns the last measured response time of this server | |
| * | |
| * If the latency hasn't been measured yet, it is done when calling this | |
| * method for the first time. | |
| * | |
| * If this information is vital to you, be sure to call | |
| * {@link updatePing()} regularly to stay up-to-date. | |
| * | |
| * @return int The latency of this server in milliseconds | |
| * @see updatePing() | |
| */ | |
| public function getPing() { | |
| if($this->ping == null) { | |
| $this->updatePing(); | |
| } | |
| return $this->ping; | |
| } | |
| /** | |
| * Returns a list of players currently playing on this server | |
| * | |
| * If the players haven't been fetched yet, it is done when calling this | |
| * method for the first time. | |
| * | |
| * As the players and their scores change quite often be sure to update | |
| * this list regularly by calling {@link updatePlayers()} if you rely on | |
| * this information. | |
| * | |
| * @param string $rconPassword The RCON password of this server may be | |
| * provided to gather more detailed information on the players, like | |
| * STEAM_IDs. | |
| * @return array The players on this server | |
| * @see updatePlayers() | |
| */ | |
| public function getPlayers($rconPassword = null) { | |
| if($this->playerHash == null) { | |
| $this->updatePlayers($rconPassword); | |
| } | |
| return $this->playerHash; | |
| } | |
| /** | |
| * Returns the settings applied on the server. These settings are also | |
| * called rules. | |
| * | |
| * If the rules haven't been fetched yet, it is done when calling this | |
| * method for the first time. | |
| * | |
| * As the rules usually don't change often, there's almost no need to | |
| * update this hash. But if you need to, you can achieve this by calling | |
| * {@link updateRules()}. | |
| * | |
| * @return array The currently active server rules | |
| * @see updateRules() | |
| */ | |
| public function getRules() { | |
| if($this->rulesHash == null) { | |
| $this->updateRules(); | |
| } | |
| return $this->rulesHash; | |
| } | |
| /** | |
| * Returns an associative array with basic information on the server. | |
| * | |
| * If the server information haven't been fetched yet, it is done when | |
| * calling this method for the first time. | |
| * | |
| * The server information usually only changes on map change and when | |
| * players join or leave. As the latter changes can be monitored by calling | |
| * {@link updatePlayers()}, there's no need to call | |
| * {@link updateServerInfo()} very often. | |
| * | |
| * @return array Server attributes with their values | |
| * @see updateServerInfo() | |
| */ | |
| public function getServerInfo() { | |
| if($this->infoHash == null) { | |
| $this->updateServerInfo(); | |
| } | |
| return $this->infoHash; | |
| } | |
| /** | |
| * Initializes this server object with basic information | |
| * | |
| * @see updateChallengeNumber() | |
| * @see updatePing() | |
| * @see updateServerInfo() | |
| */ | |
| public function initialize() { | |
| $this->updatePing(); | |
| $this->updateServerInfo(); | |
| $this->updateChallengeNumber(); | |
| } | |
| /** | |
| * Receives a response from the server | |
| * | |
| * @return SteamPacket The response packet replied by the server | |
| */ | |
| protected function getReply() { | |
| return $this->socket->getReply(); | |
| } | |
| /** | |
| * Sends the specified request to the server and handles the returned | |
| * response | |
| * | |
| * Depending on the given request type this will fill the various data | |
| * attributes of the server object. | |
| * | |
| * @param int $requestType The type of request to send to the server | |
| * @param bool $repeatOnFailure Whether the request should be repeated, if | |
| * the replied packet isn't expected. This is useful to handle | |
| * missing challenge numbers, which will be automatically filled in, | |
| * although not requested explicitly. | |
| * @throws SteamCondenserException if either the request type or the | |
| * response packet is not known | |
| */ | |
| protected function handleResponseForRequest($requestType, $repeatOnFailure = true) { | |
| switch($requestType) { | |
| case self::REQUEST_CHALLENGE: | |
| $expectedResponse = 'S2C_CHALLENGE_Packet'; | |
| $requestPacket = new A2S_PLAYER_Packet(); | |
| break; | |
| case self::REQUEST_INFO: | |
| $expectedResponse = 'S2A_INFO_BasePacket'; | |
| $requestPacket = new A2S_INFO_Packet(); | |
| break; | |
| case self::REQUEST_PLAYER: | |
| $expectedResponse = 'S2A_PLAYER_Packet'; | |
| $requestPacket = new A2S_PLAYER_Packet($this->challengeNumber); | |
| break; | |
| case self::REQUEST_RULES: | |
| $expectedResponse = 'S2A_RULES_Packet'; | |
| $requestPacket = new A2S_RULES_Packet($this->challengeNumber); | |
| break; | |
| default: | |
| throw new SteamCondenserException('Called with wrong request type.'); | |
| } | |
| $this->sendRequest($requestPacket); | |
| $responsePacket = $this->getReply(); | |
| if($responsePacket instanceof S2A_INFO_BasePacket) { | |
| $this->infoHash = $responsePacket->getInfo(); | |
| } elseif($responsePacket instanceof S2A_PLAYER_Packet) { | |
| $this->playerHash = $responsePacket->getPlayerHash(); | |
| } elseif($responsePacket instanceof S2A_RULES_Packet) { | |
| $this->rulesHash = $responsePacket->getRulesArray(); | |
| } elseif($responsePacket instanceof S2C_CHALLENGE_Packet) { | |
| $this->challengeNumber = $responsePacket->getChallengeNumber(); | |
| } else { | |
| throw new SteamCondenserException('Response of type ' . get_class($responsePacket) . ' cannot be handled by this method.'); | |
| } | |
| if(!($responsePacket instanceof $expectedResponse)) { | |
| //self::$log->addInfo("Expected {$expectedResponse}, got " . get_class($responsePacket) . '.'); | |
| if($repeatOnFailure) { | |
| $this->handleResponseForRequest($requestType, false); | |
| } | |
| } | |
| } | |
| /** | |
| * Returns whether the RCON connection to this server is already | |
| * authenticated | |
| * | |
| * @return bool <var>true</var> if the RCON connection is authenticated | |
| * @see rconAuth() | |
| */ | |
| public function isRconAuthenticated() { | |
| return $this->rconAuthenticated; | |
| } | |
| /** | |
| * Authenticates the connection for RCON communication with the server | |
| * | |
| * @param string $password The RCON password of the server | |
| * @return bool whether authentication was successful | |
| * @see rconAuth() | |
| * @throws SteamCondenserException if a problem occurs while parsing the | |
| * reply | |
| * @throws TimeoutException if the request times out | |
| */ | |
| abstract public function rconAuth($password); | |
| /** | |
| * Remotely executes a command on the server via RCON | |
| * | |
| * @param string $command The command to execute on the server via RCON | |
| * @return string The output of the executed command | |
| * @see rconExec() | |
| * @throws SteamCondenserException if a problem occurs while parsing the | |
| * reply | |
| * @throws TimeoutException if the request times out | |
| */ | |
| abstract public function rconExec($command); | |
| /** | |
| * Sends a request packet to the server | |
| * | |
| * @param SteamPacket $requestData The request packet to send to the server | |
| */ | |
| protected function sendRequest(SteamPacket $requestData) { | |
| $this->socket->send($requestData); | |
| } | |
| /** | |
| * Sends a A2S_SERVERQUERY_GETCHALLENGE request to the server and updates | |
| * the challenge number used to communicate with this server | |
| * | |
| * There's usually no need to call this method explicitly, because | |
| * {@link handleResponseForRequest()} will automatically get the challenge | |
| * number when the server assigns a new one. | |
| * | |
| * @see handleResponseForRequest() | |
| * @see initialize() | |
| */ | |
| public function updateChallengeNumber() { | |
| $this->handleResponseForRequest(self::REQUEST_CHALLENGE); | |
| } | |
| /** | |
| * Sends a A2S_INFO request to the server and measures the time needed for | |
| * the reply | |
| * | |
| * If this information is vital to you, be sure to call this method | |
| * regularly to stay up-to-date. | |
| * | |
| * @return int The latency of this server in milliseconds | |
| * @see getPing() | |
| * @see initialize() | |
| */ | |
| public function updatePing() { | |
| $this->sendRequest(new A2S_INFO_Packet()); | |
| $startTime = microtime(true); | |
| $this->getReply(); | |
| $endTime = microtime(true); | |
| $this->ping = intval(round(($endTime - $startTime) * 1000)); | |
| return $this->ping; | |
| } | |
| /** | |
| * Sends a A2S_PLAYERS request to the server and updates the players' data | |
| * for this server | |
| * | |
| * As the players and their scores change quite often be sure to update | |
| * this list regularly by calling this method if you rely on this | |
| * information. | |
| * | |
| * @param string $rconPassword The RCON password of this server may be | |
| * provided to gather more detailed information on the players, like | |
| * STEAM_IDs. | |
| * @see getPlayers() | |
| * @see handleResponseForRequest() | |
| */ | |
| public function updatePlayers($rconPassword = null) { | |
| $this->handleResponseForRequest(self::REQUEST_PLAYER); | |
| if(!$this->rconAuthenticated) { | |
| if($rconPassword == null) { | |
| return; | |
| } | |
| $this->rconAuth($rconPassword); | |
| } | |
| $players = array(); | |
| foreach(explode("\n", $this->rconExec('status')) as $line) { | |
| if(strpos($line, '#') === 0 && $line != '#end') { | |
| $players[] = trim(substr($line, 1)); | |
| } | |
| } | |
| $attributes = $this->getPlayerStatusAttributes(array_shift($players)); | |
| foreach($players as $player) { | |
| $playerData = $this->splitPlayerStatus($attributes, $player); | |
| if(array_key_exists($playerData['name'], $this->playerHash)) { | |
| $this->playerHash[$playerData['name']]->addInformation($playerData); | |
| } | |
| } | |
| } | |
| /** | |
| * Sends a A2S_RULES request to the server and updates the rules of this | |
| * server | |
| * | |
| * As the rules usually don't change often, there's almost no need to | |
| * update this hash. But if you need to, you can achieve this by calling | |
| * this method. | |
| * | |
| * @see getRules() | |
| * @see handleResponseForRequest() | |
| */ | |
| public function updateRules() { | |
| $this->handleResponseForRequest(self::REQUEST_RULES); | |
| } | |
| /** | |
| * Sends a A2S_INFO request to the server and updates this server's basic | |
| * information | |
| * | |
| * The server information usually only changes on map change and when | |
| * players join or leave. As the latter changes can be monitored by calling | |
| * {@link updatePlayers()}, there's no need to call this method very often. | |
| * | |
| * @see getServerInfo() | |
| * @see handleResponseForRequest() | |
| * @see initialize() | |
| */ | |
| public function updateServerInfo() { | |
| $this->handleResponseForRequest(self::REQUEST_INFO); | |
| } | |
| /** | |
| * Returns a human-readable text representation of the server | |
| * | |
| * @return string Available information about the server in a | |
| * human-readable format | |
| */ | |
| public function __toString() { | |
| $returnString = ''; | |
| $returnString .= "Ping: {$this->ping}\n"; | |
| $returnString .= "Challenge number: {$this->challengeNumber}\n"; | |
| if($this->infoHash != null) { | |
| $returnString .= "Info:\n"; | |
| foreach($this->infoHash as $key => $value) { | |
| if(is_array($value)) { | |
| $returnString .= " {$key}:\n"; | |
| foreach($value as $subKey => $subValue) { | |
| $returnString .= " {$subKey} = {$subValue}\n"; | |
| } | |
| } else { | |
| $returnString .= " {$key}: {$value}\n"; | |
| } | |
| } | |
| } | |
| if($this->playerHash != null) { | |
| $returnString .= "Players:\n"; | |
| foreach($this->playerHash as $player) { | |
| $returnString .= " {$player}\n"; | |
| } | |
| } | |
| if($this->rulesHash != null) { | |
| $returnString .= "Rules:\n"; | |
| foreach($this->rulesHash as $key => $value) { | |
| $returnString .= " {$key}: {$value}\n"; | |
| } | |
| } | |
| return $returnString; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/servers/GameServer.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/servers/MasterServer.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/sockets/GoldSrcSocket.php'; | |
| /** | |
| * This class represents a GoldSrc game server and can be used to query | |
| * information about and remotely execute commands via RCON on the server | |
| * | |
| * A GoldSrc game server is an instance of the Half-Life Dedicated Server | |
| * (HLDS) running games using Valve's GoldSrc engine, like Half-Life | |
| * Deathmatch, Counter-Strike 1.6 or Team Fortress Classic. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage servers | |
| * @see SourceServer | |
| */ | |
| class GoldSrcServer extends GameServer { | |
| /** | |
| * @var bool | |
| */ | |
| protected $isHLTV; | |
| /** | |
| * @var string | |
| */ | |
| protected $rconPassword; | |
| /** | |
| * Returns a master server instance for the default master server for | |
| * GoldSrc games | |
| * | |
| * @return MasterServer The GoldSrc master server | |
| */ | |
| public static function getMaster() { | |
| return new MasterServer(MasterServer::GOLDSRC_MASTER_SERVER); | |
| } | |
| /** | |
| * Creates a new instance of a GoldSrc server object | |
| * | |
| * @param string $address Either an IP address, a DNS name or one of them | |
| * combined with the port number. If a port number is given, e.g. | |
| * 'server.example.com:27016' it will override the second argument. | |
| * @param int $port The port the server is listening on | |
| * @param bool $isHLTV HLTV servers need special treatment, so this is used | |
| * to determine if the server is a HLTV server | |
| * @throws SteamCondenserException if an host name cannot be resolved | |
| */ | |
| public function __construct($address, $port = 27015, $isHLTV = false) { | |
| parent::__construct($address, $port); | |
| $this->isHLTV = $isHLTV; | |
| } | |
| /** | |
| * Initializes the sockets to communicate with the GoldSrc server | |
| * | |
| * @see GoldSrcSocket | |
| */ | |
| public function initSocket() { | |
| $this->socket = new GoldSrcSocket($this->ipAddress, $this->port, $this->isHLTV); | |
| } | |
| /** | |
| * Saves the password for authenticating the RCON communication with the | |
| * server | |
| * | |
| * @param string $password The RCON password of the server | |
| * @return bool GoldSrc's RCON does not preauthenticate connections so | |
| * this method always returns <var>true</var> | |
| * @see rconAuth() | |
| */ | |
| public function rconAuth($password) { | |
| $this->rconPassword = $password; | |
| return true; | |
| } | |
| /** | |
| * Remotely executes a command on the server via RCON | |
| * | |
| * @param string $command The command to execute on the server via RCON | |
| * @return string The output of the executed command | |
| * @see rconExec() | |
| * @throws SteamCondenserException if a problem occurs while parsing the | |
| * reply | |
| * @throws TimeoutException if the request times out | |
| */ | |
| public function rconExec($command) { | |
| return trim($this->socket->rconExec($this->rconPassword, $command)); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/A2M_GET_SERVERS_BATCH2_Packet.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/servers/Server.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/sockets/MasterServerSocket.php'; | |
| /** | |
| * This class represents a Steam master server and can be used to get game | |
| * servers which are publicly available | |
| * | |
| * An intance of this class can be used much like Steam's server browser to get | |
| * a list of available game servers, including filters to narrow down the | |
| * search results. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage servers | |
| */ | |
| class MasterServer extends Server { | |
| /** | |
| * @var Monolog\Logger The Monolog logger for this class | |
| */ | |
| private static $log; | |
| /** | |
| * @var string The master server address to query for GoldSrc game servers | |
| */ | |
| const GOLDSRC_MASTER_SERVER = 'hl1master.steampowered.com:27011'; | |
| /** | |
| * @var string The master server address to query for GoldSrc game servers | |
| */ | |
| const SOURCE_MASTER_SERVER = 'hl2master.steampowered.com:27011'; | |
| /** | |
| * @var int The region code for the US east coast | |
| */ | |
| const REGION_US_EAST_COAST = 0x00; | |
| /** | |
| * @var int The region code for the US west coast | |
| */ | |
| const REGION_US_WEST_COAST = 0x01; | |
| /** | |
| * @var int The region code for South America | |
| */ | |
| const REGION_SOUTH_AMERICA = 0x02; | |
| /** | |
| * @var int The region code for Europe | |
| */ | |
| const REGION_EUROPE = 0x03; | |
| /** | |
| * @var int The region code for Asia | |
| */ | |
| const REGION_ASIA = 0x04; | |
| /** | |
| * @var int The region code for Australia | |
| */ | |
| const REGION_AUSTRALIA = 0x05; | |
| /** | |
| * @var int The region code for the Middle East | |
| */ | |
| const REGION_MIDDLE_EAST = 0x06; | |
| /** | |
| * @var int The region code for Africa | |
| */ | |
| const REGION_AFRICA = 0x07; | |
| /** | |
| * @var int The region code for the whole world | |
| */ | |
| const REGION_ALL = 0xFF; | |
| /** | |
| * @var int | |
| */ | |
| private static $retries = 3; | |
| /** | |
| * @var MasterServerSocket | |
| */ | |
| protected $socket; | |
| /** | |
| * Creates a new master server instance with the given address and port | |
| * | |
| * @param string $address Either an IP address, a DNS name or one of them | |
| * combined with the port number. If a port number is given, e.g. | |
| * 'server.example.com:27016' it will override the second argument. | |
| * @param int $port The port the server is listening on | |
| * @throws SteamCondenserException if an host name cannot be resolved | |
| */ | |
| public function __construct($address, $port = null) { | |
| parent::__construct($address, $port); | |
| if (!isset(self::$log)) { | |
| self::$log = new \Monolog\Logger('MasterServer'); | |
| } | |
| } | |
| /** | |
| * Sets the number of consecutive requests that may fail, before getting | |
| * the server list is cancelled (default: 3) | |
| * | |
| * @param int $retries The number of allowed retries | |
| */ | |
| public static function setRetries($retries) { | |
| self::$retries = $retries; | |
| } | |
| /** | |
| * Returns a list of game server matching the given region and filters | |
| * | |
| * Filtering: | |
| * Instead of filtering the results sent by the master server locally, you | |
| * should at least use the following filters to narrow down the results | |
| * sent by the master server. | |
| * | |
| * <b>Note:</b> Receiving all servers from the master server is taking | |
| * quite some time. | |
| * | |
| * Available filters: | |
| * | |
| * <ul> | |
| * <li><var>\type\d</var>: Request only dedicated servers | |
| * <li><var>\secure\1</var>: Request only secure servers | |
| * <li><var>\gamedir\[mod]</var>: Request only servers of a specific mod | |
| * <li><var>\map\[mapname]</var>: Request only servers running a specific | |
| * map | |
| * <li><var>\linux\1</var>: Request only linux servers | |
| * <li><var>\emtpy\1</var>: Request only **non**-empty servers | |
| * <li><var>\full\1</var>: Request only servers **not** full | |
| * <li><var>\proxy\1</var>: Request only spectator proxy servers | |
| * </ul> | |
| * | |
| * @param int $regionCode The region code to specify a location of the | |
| * game servers | |
| * @param string $filter The filters that game servers should match | |
| * @param bool $force Return a list of servers even if an error occured | |
| * while fetching them from the master server | |
| * @return array A list of game servers matching the given | |
| * region and filters | |
| * @see setTimeout() | |
| * @see A2M_GET_SERVERS_BATCH2_Packet | |
| * @throws SteamCondenserException if a problem occurs while parsing the | |
| * reply | |
| * @throws TimeoutException if too many timeouts occur while querying the | |
| * master server | |
| */ | |
| public function getServers($regionCode = MasterServer::REGION_ALL , $filter = '', $force = false) { | |
| $failCount = 0; | |
| $finished = false; | |
| $portNumber = 0; | |
| $hostName = '0.0.0.0'; | |
| $serverArray = array(); | |
| while(true) { | |
| $failCount = 0; | |
| try { | |
| do { | |
| $this->socket->send(new A2M_GET_SERVERS_BATCH2_Packet($regionCode, "$hostName:$portNumber", $filter)); | |
| try { | |
| $serverStringArray = $this->socket->getReply()->getServers(); | |
| foreach($serverStringArray as $serverString) { | |
| $serverString = explode(':', $serverString); | |
| $hostName = $serverString[0]; | |
| $portNumber = $serverString[1]; | |
| if($hostName != '0.0.0.0' && $portNumber != 0) { | |
| $serverArray[] = array($hostName, $portNumber); | |
| } else { | |
| $finished = true; | |
| } | |
| } | |
| $failCount = 0; | |
| } catch(TimeoutException $e) { | |
| $failCount ++; | |
| if($failCount == self::$retries) { | |
| throw $e; | |
| } | |
| self::$log->addInfo("Request to master server {$this->ipAddress} timed out, retrying..."); | |
| } | |
| } while(!$finished); | |
| break; | |
| } catch(TimeoutException $e) { | |
| if ($force) { | |
| break; | |
| } else if($this->rotateIp()) { | |
| throw $e; | |
| } | |
| self::$log->addInfo("Request to master server failed, retrying {$this->ipAddress}..."); | |
| } | |
| } | |
| return $serverArray; | |
| } | |
| /** | |
| * Initializes the socket to communicate with the master server | |
| * | |
| * @see MasterServerSocket | |
| */ | |
| public function initSocket() { | |
| $this->socket = new MasterServerSocket($this->ipAddress, $this->port); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2011-2012, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| /** | |
| * This class is subclassed by all classes implementing server functionality | |
| * | |
| * It provides basic name resolution features and the ability to rotate | |
| * between different IP addresses belonging to a single DNS name. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage servers | |
| */ | |
| abstract class Server { | |
| /** | |
| * @var array The currently selected IP address of this server | |
| */ | |
| protected $ipAddress; | |
| /** | |
| * @var array The IP addresses of this server | |
| */ | |
| protected $ipAddresses; | |
| /** | |
| * @var int The index of the currently selected IP address | |
| */ | |
| protected $ipIndex; | |
| /** | |
| * @var int The port of this server | |
| */ | |
| protected $port; | |
| /** | |
| * Creates a new server instance with the given address and port | |
| * | |
| * @param string $address Either an IP address, a DNS name or one of them | |
| * combined with the port number. If a port number is given, e.g. | |
| * 'server.example.com:27016' it will override the second argument. | |
| * @param int $port The port the server is listening on | |
| * @see initSocket() | |
| * @throws SteamCondenserException if an host name cannot be resolved | |
| */ | |
| public function __construct($address, $port = null) { | |
| $address = strval($address); | |
| if(strpos($address, ':') !== false) { | |
| $address = explode(':', $address, 2); | |
| $port = $address[1]; | |
| $address = $address[0]; | |
| } | |
| $this->ipAddresses = array(); | |
| $this->ipIndex = 0; | |
| $this->port = intval($port); | |
| $addresses = gethostbynamel($address); | |
| if(empty($addresses)) { | |
| throw new SteamCondenserException("Cannot resolve $address"); | |
| } | |
| foreach($addresses as $address) { | |
| $this->ipAddresses[] = $address; | |
| } | |
| $this->ipAddress = $this->ipAddresses[0]; | |
| $this->initSocket(); | |
| } | |
| /** | |
| * Disconnect the connections to this server | |
| * | |
| * <i>Note: | |
| * In the base implementation this does nothing, only connection-based | |
| * communication channels have to be disconnected.</i> | |
| */ | |
| public function disconnect() {} | |
| /** | |
| * Rotate this server's IP address to the next one in the IP list | |
| * | |
| * If this method returns <var>true</var>, it indicates that all IP | |
| * addresses have been used, hinting at the server(s) being unreachable. An | |
| * appropriate action should be taken to inform the user. | |
| * | |
| * Servers with only one IP address will always cause this method to return | |
| * <var>true</var> and the sockets will not be reinitialized. | |
| * | |
| * @return bool <var>true</var>, if the IP list reached its end. If the | |
| * list contains only one IP address, this method will instantly | |
| * return <var>true</var> | |
| * @see initSocket() | |
| */ | |
| public function rotateIp() { | |
| if(sizeof($this->ipAddresses) == 1) { | |
| return true; | |
| } | |
| $this->ipIndex = ($this->ipIndex + 1) % sizeof($this->ipAddresses); | |
| $this->ipAddress = $this->ipAddresses[$this->ipIndex]; | |
| $this->initSocket(); | |
| return $this->ipIndex == 0; | |
| } | |
| /** | |
| * Disconnects the connections to this server | |
| * | |
| * @see disconnect() | |
| */ | |
| public function __destruct() { | |
| $this->disconnect(); | |
| } | |
| /** | |
| * Initializes the socket(s) to communicate with the server | |
| * | |
| * Must be implemented in subclasses to prepare sockets for server | |
| * communication | |
| */ | |
| protected abstract function initSocket(); | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/RCONNoAuthException.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONAuthRequest.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONAuthResponse.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONExecRequest.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONTerminator.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/servers/GameServer.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/servers/MasterServer.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/sockets/RCONSocket.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/sockets/SourceSocket.php'; | |
| /** | |
| * This class represents a Source game server and can be used to query | |
| * information about and remotely execute commands via RCON on the server | |
| * | |
| * A Source game server is an instance of the Source Dedicated Server (SrcDS) | |
| * running games using Valve's Source engine, like Counter-Strike: Source, | |
| * Team Fortress 2 or Left4Dead. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage servers | |
| * @see GoldSrcServer | |
| */ | |
| class SourceServer extends GameServer { | |
| /** | |
| * @var bool Whether the RCON connection is already authenticated | |
| */ | |
| protected $rconAuthenticated; | |
| /** | |
| * @var int The request ID used for RCON request | |
| */ | |
| protected $rconRequestId; | |
| /** | |
| * @var RCONSocket The TCP socket to use for RCON communication | |
| */ | |
| protected $rconSocket; | |
| /** | |
| * Disconnects the TCP-based channel used for RCON commands | |
| * | |
| * @see RCONSocket::close() | |
| */ | |
| public function disconnect() { | |
| $this->rconSocket->close(); | |
| } | |
| /** | |
| * Returns a master server instance for the default master server for | |
| * Source games | |
| * | |
| * @return MasterServer The Source master server | |
| */ | |
| public static function getMaster() { | |
| return new MasterServer(MasterServer::SOURCE_MASTER_SERVER); | |
| } | |
| /** | |
| * Returns a random 16-bit integer used to identify RCON communication | |
| * packets | |
| * | |
| * @return int The request ID for RCON communication | |
| */ | |
| protected function generateRconRequestId() { | |
| return rand(0, pow(2, 16)); | |
| } | |
| /** | |
| * Initializes the sockets to communicate with the Source server | |
| * | |
| * @see RCONSocket | |
| * @see SourceSocket | |
| */ | |
| public function initSocket() { | |
| $this->rconSocket = new RCONSocket($this->ipAddress, $this->port); | |
| $this->socket = new SourceSocket($this->ipAddress, $this->port); | |
| } | |
| /** | |
| * Authenticates the connection for RCON communication with the server | |
| * | |
| * @param string $password The RCON password of the server | |
| * @return bool whether authentication was successful | |
| * @see rconExec() | |
| * @throws SteamCondenserException if a problem occurs while parsing the | |
| * reply | |
| * @throws TimeoutException if the request times out | |
| */ | |
| public function rconAuth($password) { | |
| $this->rconRequestId = $this->generateRconRequestId(); | |
| $this->rconSocket->send(new RCONAuthRequest($this->rconRequestId, $password)); | |
| try { | |
| $this->rconSocket->getReply(); | |
| $reply = $this->rconSocket->getReply(); | |
| $this->rconAuthenticated = $reply->getRequestId() == $this->rconRequestId; | |
| } catch (SocketException $e) { | |
| if (defined('SOCKET_ECONNRESET') && | |
| $e->getCode() == SOCKET_ECONNRESET) { | |
| throw new RCONBanException(); | |
| } else { | |
| throw $e; | |
| } | |
| } | |
| return $this->rconAuthenticated; | |
| } | |
| /** | |
| * Remotely executes a command on the server via RCON | |
| * | |
| * @param string $command The command to execute on the server via RCON | |
| * @return string The output of the executed command | |
| * @see rconAuth() | |
| * @throws RCONBanException if banned by the server | |
| * @throws RCONNoAuthException if not authenticated with the server | |
| * @throws SteamCondenserException if a problem occurs while parsing the | |
| * reply | |
| * @throws TimeoutException if the request times out | |
| */ | |
| public function rconExec($command) { | |
| if(!$this->rconAuthenticated) { | |
| throw new RCONNoAuthException(); | |
| } | |
| $this->rconSocket->send(new RCONExecRequest($this->rconRequestId, $command)); | |
| $isMulti = false; | |
| $response = array(); | |
| do { | |
| try { | |
| $responsePacket = $this->rconSocket->getReply(); | |
| if ($responsePacket instanceof RCONAuthResponse) { | |
| $this->rconAuthenticated = false; | |
| throw new RCONNoAuthException(); | |
| } | |
| if (!$isMulti && strlen($responsePacket->getResponse()) > 0) { | |
| $isMulti = true; | |
| $this->rconSocket->send(new RCONTerminator($this->rconRequestId)); | |
| } | |
| } catch (SocketException $e) { | |
| if (defined('SOCKET_ECONNRESET') && | |
| $e->getCode() == SOCKET_ECONNRESET) { | |
| $this->rconAuthenticated = false; | |
| throw new RCONNoAuthException(); | |
| } else { | |
| throw $e; | |
| } | |
| } | |
| $response[] = $responsePacket->getResponse(); | |
| } while($isMulti && !(empty($response[sizeof($response) - 2]) && empty($response[sizeof($response) - 1]))); | |
| return trim(join('', $response)); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/RCONBanException.php'; | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/RCONNoAuthException.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacket.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONGoldSrcRequest.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/sockets/SteamSocket.php'; | |
| /** | |
| * This class represents a socket used to communicate with game servers based | |
| * on the GoldSrc engine (e.g. Half-Life, Counter-Strike) | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage sockets | |
| */ | |
| class GoldSrcSocket extends SteamSocket { | |
| /** | |
| * @var Monolog\Logger The Monolog logger for this class | |
| */ | |
| private static $log; | |
| /** | |
| * @var boolean | |
| */ | |
| private $isHLTV; | |
| /** | |
| * @var long | |
| */ | |
| private $rconChallenge = -1; | |
| /** | |
| * Creates a new socket to communicate with the server on the given IP | |
| * address and port | |
| * | |
| * @param string $ipAddress Either the IP address or the DNS name of the | |
| * server | |
| * @param int $portNumber The port the server is listening on | |
| * @param bool $isHLTV <var>true</var> if the target server is a HTLV | |
| * instance. HLTV behaves slightly different for RCON commands, this | |
| * flag increases compatibility. | |
| */ | |
| public function __construct($ipAddress, $portNumber = 27015, $isHLTV = false) { | |
| parent::__construct($ipAddress, $portNumber); | |
| $this->isHLTV = $isHLTV; | |
| if (!isset(self::$log)) { | |
| self::$log = new \Monolog\Logger('GoldSrcSocket'); | |
| } | |
| } | |
| /** | |
| * Reads a packet from the socket | |
| * | |
| * The Source query protocol specifies a maximum packet size of 1,400 | |
| * bytes. Bigger packets will be split over several UDP packets. This | |
| * method reassembles split packets into single packet objects. | |
| * | |
| * @return SteamPacket The packet replied from the server | |
| */ | |
| public function getReply() { | |
| $bytesRead = $this->receivePacket(1400); | |
| if($this->buffer->getLong() == -2) { | |
| do { | |
| $requestId = $this->buffer->getLong(); | |
| $packetCountAndNumber = $this->buffer->getByte(); | |
| $packetCount = $packetCountAndNumber & 0xF; | |
| $packetNumber = ($packetCountAndNumber >> 4) + 1; | |
| $splitPackets[$packetNumber - 1] = $this->buffer->get(); | |
| self::$log->addDebug("Received packet $packetNumber of $packetCount for request #$requestId"); | |
| if(sizeof($splitPackets) < $packetCount) { | |
| try { | |
| $bytesRead = $this->receivePacket(); | |
| } catch(TimeoutException $e) { | |
| $bytesRead = 0; | |
| } | |
| } else { | |
| $bytesRead = 0; | |
| } | |
| } while($bytesRead > 0 && $this->buffer->getLong() == -2); | |
| $packet = SteamPacketFactory::reassemblePacket($splitPackets); | |
| } else { | |
| $packet = SteamPacketFactory::getPacketFromData($this->buffer->get()); | |
| } | |
| self::$log->addDebug("Received packet of type \"" . get_class($packet) . "\""); | |
| return $packet; | |
| } | |
| /** | |
| * Executes the given command on the server via RCON | |
| * | |
| * @param string $password The password to authenticate with the server | |
| * @param string $command The command to execute on the server | |
| * @return RCONGoldSrcResponse The response replied by the server | |
| * @see rconChallenge() | |
| * @see rconSend() | |
| * @throws RCONBanException if the IP of the local machine has been banned | |
| * on the game server | |
| * @throws RCONNoAuthException if the password is incorrect | |
| */ | |
| public function rconExec($password, $command) { | |
| if($this->rconChallenge == -1 || $this->isHLTV) { | |
| $this->rconGetChallenge(); | |
| } | |
| $this->rconSend("rcon {$this->rconChallenge} $password $command"); | |
| $this->rconSend("rcon {$this->rconChallenge} $password"); | |
| if($this->isHLTV) { | |
| try { | |
| $response = $this->getReply()->getResponse(); | |
| } catch(TimeoutException $e) { | |
| $response = ''; | |
| } | |
| } else { | |
| $response = $this->getReply()->getResponse(); | |
| } | |
| if(trim($response) == 'Bad rcon_password.') { | |
| throw new RCONNoAuthException(); | |
| } elseif(trim($response) == 'You have been banned from this server.') { | |
| throw new RCONBanException(); | |
| } | |
| do { | |
| $responsePart = $this->getReply()->getResponse(); | |
| $response .= $responsePart; | |
| } while(strlen($responsePart) > 0); | |
| return $response; | |
| } | |
| /** | |
| * Requests a challenge number from the server to be used for further | |
| * requests | |
| * | |
| * @throws RCONBanException if the IP of the local machine has been banned | |
| * on the game server | |
| * @see rconSend() | |
| */ | |
| public function rconGetChallenge() { | |
| $this->rconSend('challenge rcon'); | |
| $response = trim($this->getReply()->getResponse()); | |
| if($response == 'You have been banned from this server.') { | |
| throw new RCONBanException(); | |
| } | |
| $this->rconChallenge = floatval(substr($response, 14)); | |
| } | |
| /** | |
| * Wraps the given command in a RCON request packet and send it to the | |
| * server | |
| * | |
| * @param string $command The RCON command to send to the server | |
| */ | |
| public function rconSend($command) { | |
| $this->send(new RCONGoldSrcRequest($command)); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/PacketFormatException.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/sockets/SteamSocket.php'; | |
| /** | |
| * This class represents a socket used to communicate with master servers | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage sockets | |
| */ | |
| class MasterServerSocket extends SteamSocket { | |
| /** | |
| * @var Monolog\Logger The Monolog logger for this class | |
| */ | |
| private static $log; | |
| /** | |
| * Creates a new UDP socket to communicate with the server on the given IP | |
| * address and port | |
| * | |
| * @param string $ipAddress Either the IP address or the DNS name of the | |
| * server | |
| * @param int $portNumber The port the server is listening on | |
| */ | |
| public function __construct($ipAddress, $portNumber = 27015) { | |
| parent::__construct($ipAddress, $portNumber); | |
| if (!isset(self::$log)) { | |
| self::$log = new \Monolog\Logger('MasterServerSocket'); | |
| } | |
| } | |
| /** | |
| * Reads a single packet from the socket | |
| * | |
| * @return SteamPacket The packet replied from the server | |
| * @throws PacketFormatException if the packet has the wrong format | |
| */ | |
| public function getReply() { | |
| $this->receivePacket(1500); | |
| if($this->buffer->getLong() != -1) { | |
| throw new PacketFormatException("Master query response has wrong packet header."); | |
| } | |
| $packet = SteamPacketFactory::getPacketFromData($this->buffer->get()); | |
| self::$log->addDebug("Received reply of type \"" . get_class($packet) . "\""); | |
| return $packet; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'TCPSocket.php'; | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/RCONBanException.php'; | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/RCONNoAuthException.php'; | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/PacketFormatException.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONPacket.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/rcon/RCONPacketFactory.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/sockets/SteamSocket.php'; | |
| /** | |
| * This class represents a socket used for RCON communication with game servers | |
| * based on the Source engine (e.g. Team Fortress 2, Counter-Strike: Source) | |
| * | |
| * The Source engine uses a stateful TCP connection for RCON communication and | |
| * uses an additional socket of this type to handle RCON requests. | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage sockets | |
| */ | |
| class RCONSocket extends SteamSocket { | |
| /** | |
| * @var Monolog\Logger The Monolog logger for this class | |
| */ | |
| private static $log; | |
| /** | |
| * @var string | |
| */ | |
| private $ipAddress; | |
| /** | |
| * @var int | |
| */ | |
| private $portNumber; | |
| /** | |
| * Creates a new TCP socket to communicate with the server on the given IP | |
| * address and port | |
| * | |
| * @param string $ipAddress Either the IP address or the DNS name of the | |
| * server | |
| * @param int $portNumber The port the server is listening on | |
| */ | |
| public function __construct($ipAddress, $portNumber) { | |
| if (!isset(self::$log)) { | |
| // self::$log = new \Monolog\Logger('SourceSocket'); | |
| } | |
| $this->buffer = ByteBuffer::allocate(1400); | |
| $this->ipAddress = $ipAddress; | |
| $this->portNumber = $portNumber; | |
| } | |
| /** | |
| * Closes the underlying TCP socket if it exists | |
| * | |
| * @see SteamSocket::close() | |
| */ | |
| public function close() { | |
| if(!empty($this->socket)) { | |
| parent::close(); | |
| } | |
| } | |
| /** | |
| * Sends the given RCON packet to the server | |
| * | |
| * @param SteamPacket $dataPacket The RCON packet to send to the server | |
| */ | |
| public function send(SteamPacket $dataPacket) { | |
| if(empty($this->socket) || !$this->socket->isOpen()) { | |
| $this->socket = new TCPSocket(); | |
| $this->socket->connect($this->ipAddress, $this->portNumber, SteamSocket::$timeout); | |
| } | |
| parent::send($dataPacket); | |
| } | |
| /** | |
| * Reads a packet from the socket | |
| * | |
| * The Source RCON protocol allows packets of an arbitrary sice transmitted | |
| * using multiple TCP packets. The data is received in chunks and | |
| * concatenated into a single response packet. | |
| * | |
| * @return SteamPacket The packet replied from the server | |
| * @throws RCONBanException if the IP of the local machine has been banned | |
| * on the game server | |
| * @throws RCONNoAuthException if an authenticated connection has been | |
| * dropped by the server | |
| */ | |
| public function getReply() { | |
| if ($this->receivePacket(4) == 0) { | |
| $this->socket->close(); | |
| throw new RCONBanException(); | |
| } | |
| $packetSize = $this->buffer->getLong(); | |
| $remainingBytes = $packetSize; | |
| $packetData = ''; | |
| do { | |
| $receivedBytes = $this->receivePacket($remainingBytes); | |
| $remainingBytes -= $receivedBytes; | |
| $packetData .= $this->buffer->get(); | |
| } while($remainingBytes > 0); | |
| $packet = RCONPacketFactory::getPacketFromData($packetData); | |
| //self::$log->addDebug('Received packet of type ' . get_class($packet)); | |
| return $packet; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacketFactory.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/sockets/SteamSocket.php'; | |
| /** | |
| * This class represents a socket used to communicate with game servers based | |
| * on the Source engine (e.g. Team Fortress 2, Counter-Strike: Source) | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage sockets | |
| */ | |
| class SourceSocket extends SteamSocket { | |
| /** | |
| * @var Monolog\Logger The Monolog logger for this class | |
| */ | |
| private static $log; | |
| /** | |
| * Creates a new UDP socket to communicate with the Source server on the | |
| * given IP address and port | |
| * | |
| * @param string $ipAddress Either the IP address or the DNS name of the | |
| * server | |
| * @param int $portNumber The port the server is listening on | |
| */ | |
| public function __construct($ipAddress, $portNumber = 27015) { | |
| parent::__construct($ipAddress, $portNumber); | |
| if (!isset(self::$log)) { | |
| //self::$log = new \Monolog\Logger('SourceSocket'); | |
| } | |
| } | |
| /** | |
| * Reads a packet from the socket | |
| * | |
| * The Source query protocol specifies a maximum packet size of 1,400 | |
| * bytes. Bigger packets will be split over several UDP packets. This | |
| * method reassembles split packets into single packet objects. | |
| * Additionally Source may compress big packets using bzip2. Those packets | |
| * will be compressed. | |
| * | |
| * @return SteamPacket The packet replied from the server | |
| */ | |
| public function getReply() { | |
| $this->receivePacket(1400); | |
| $isCompressed = false; | |
| if($this->buffer->getLong() == -2) { | |
| do { | |
| $requestId = $this->buffer->getLong(); | |
| $isCompressed = (($requestId & 0x80000000) != 0); | |
| $packetCount = $this->buffer->getByte(); | |
| $packetNumber = $this->buffer->getByte() + 1; | |
| if($isCompressed) { | |
| $splitSize = $this->buffer->getLong(); | |
| $packetChecksum = $this->buffer->getUnsignedLong(); | |
| } else { | |
| $splitSize = $this->buffer->getShort(); | |
| } | |
| $splitPackets[$packetNumber] = $this->buffer->get(); | |
| self::$log->addDebug("Received packet $packetNumber of $packetCount for request #$requestId"); | |
| if(sizeof($splitPackets) < $packetCount) { | |
| try { | |
| $bytesRead = $this->receivePacket(); | |
| } catch(TimeoutException $e) { | |
| $bytesRead = 0; | |
| } | |
| } else { | |
| $bytesRead = 0; | |
| } | |
| } while($bytesRead > 0 && $this->buffer->getLong() == -2); | |
| if($isCompressed) { | |
| $packet = SteamPacketFactory::reassemblePacket($splitPackets, true, $packetChecksum); | |
| } else { | |
| $packet = SteamPacketFactory::reassemblePacket($splitPackets); | |
| } | |
| } else { | |
| $packet = SteamPacketFactory::getPacketFromData($this->buffer->get()); | |
| } | |
| if($isCompressed) { | |
| // self::$log->addDebug("Received compressed reply of type \"" . get_class($packet) . "\""); | |
| } else { | |
| // self::$log->addDebug("Received reply of type \"" . get_class($packet) . "\""); | |
| } | |
| return $packet; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'ByteBuffer.php'; | |
| require_once STEAM_CONDENSER_PATH . 'UDPSocket.php'; | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/SocketException.php'; | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/TimeoutException.php'; | |
| require_once STEAM_CONDENSER_PATH . 'steam/packets/SteamPacketFactory.php'; | |
| /** | |
| * This abstract class implements common functionality for sockets used to | |
| * connect to game and master servers | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| * @subpackage sockets | |
| */ | |
| abstract class SteamSocket { | |
| /** | |
| * @var Monolog\Logger The Monolog logger for this class | |
| */ | |
| private static $log; | |
| /** | |
| * @var int The default socket timeout | |
| */ | |
| protected static $timeout = 1000; | |
| /** | |
| * @var ByteBuffer | |
| */ | |
| protected $buffer; | |
| /** | |
| * @var UDPSocket | |
| */ | |
| protected $socket; | |
| /** | |
| * Sets the timeout for socket operations | |
| * | |
| * Any request that takes longer than this time will cause a {@link | |
| * TimeoutException}. | |
| * | |
| * @param int $timeout The amount of milliseconds before a request times | |
| * out | |
| */ | |
| public static function setTimeout($timeout) { | |
| self::$timeout = $timeout; | |
| } | |
| /** | |
| * Creates a new UDP socket to communicate with the server on the given IP | |
| * address and port | |
| * | |
| * @param string $ipAddress Either the IP address or the DNS name of the | |
| * server | |
| * @param int $portNumber The port the server is listening on | |
| */ | |
| public function __construct($ipAddress, $portNumber = 27015) { | |
| if (!isset(self::$log)) { | |
| // self::$log = new \Monolog\Logger('SteamSocket'); | |
| } | |
| $this->socket = new UDPSocket(); | |
| $this->socket->connect($ipAddress, $portNumber, 0); | |
| } | |
| /** | |
| * Closes this socket | |
| * | |
| * @see #close() | |
| */ | |
| public function __destruct() { | |
| $this->close(); | |
| } | |
| /** | |
| * Closes the underlying socket | |
| * | |
| * @see UDPSocket::close() | |
| */ | |
| public function close() { | |
| if(!empty($this->socket) && $this->socket->isOpen()) { | |
| $this->socket->close(); | |
| } | |
| } | |
| /** | |
| * Subclasses have to implement this method for their individual packet | |
| * formats | |
| * | |
| * @return SteamPacket The packet replied from the server | |
| */ | |
| abstract public function getReply(); | |
| /** | |
| * Reads the given amount of data from the socket and wraps it into the | |
| * buffer | |
| * | |
| * @param int $bufferLength The data length to read from the socket | |
| * @throws SocketException if an error occurs while reading data | |
| * @throws TimeoutException if no packet is received on time | |
| * @return int The number of bytes that have been read from the socket | |
| * @see ByteBuffer | |
| */ | |
| public function receivePacket($bufferLength = 0) { | |
| if(!$this->socket->select(self::$timeout)) { | |
| throw new TimeoutException(); | |
| } | |
| if($bufferLength == 0) { | |
| $this->buffer->clear(); | |
| } else { | |
| $this->buffer = ByteBuffer::allocate($bufferLength); | |
| } | |
| try { | |
| $data = $this->socket->recv($this->buffer->remaining()); | |
| } catch (SocketException $e) { | |
| if (defined('SOCKET_ECONNRESET') && | |
| $e->getCode() == SOCKET_ECONNRESET) { | |
| $this->socket->close(); | |
| } | |
| throw $e; | |
| } | |
| $this->buffer->put($data); | |
| $bytesRead = $this->buffer->position(); | |
| $this->buffer->rewind(); | |
| $this->buffer->limit($bytesRead); | |
| return $bytesRead; | |
| } | |
| /** | |
| * Sends the given packet to the server | |
| * | |
| * This converts the packet into a byte stream first before writing it to | |
| * the socket. | |
| * | |
| * @param SteamPacket $dataPacket The packet to send to the server | |
| * @see SteamPacket::__toString() | |
| */ | |
| public function send(SteamPacket $dataPacket) { | |
| //self::$log->addDebug("Sending packet of type \"" . get_class($dataPacket) . "\"..."); | |
| $this->socket->send($dataPacket->__toString()); | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2011, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/SteamCondenserException.php'; | |
| /** | |
| * This class represents a player connected to a game server | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| */ | |
| class SteamPlayer { | |
| /** | |
| * @var int | |
| */ | |
| private $clientPort; | |
| /** | |
| * @var float | |
| */ | |
| private $connectTime; | |
| /** | |
| * @var bool | |
| */ | |
| private $extended; | |
| /** | |
| * @var int | |
| */ | |
| private $id; | |
| /** | |
| * @var string | |
| */ | |
| private $ipAddress; | |
| /** | |
| * @var int | |
| */ | |
| private $loss; | |
| /** | |
| * @var string | |
| */ | |
| private $name; | |
| /** | |
| * @var int | |
| */ | |
| private $ping; | |
| /** | |
| * @var int | |
| */ | |
| private $rate; | |
| /** | |
| * @var int | |
| */ | |
| private $realId; | |
| /** | |
| * @var int | |
| */ | |
| private $score; | |
| /** | |
| * @var string | |
| */ | |
| private $state; | |
| /** | |
| * @var string | |
| */ | |
| private $steamId; | |
| /** | |
| * Creates a new player instancewith the given information | |
| * | |
| * @param int $id The ID of the player on the server | |
| * @param string $name The name of the player | |
| * @param int $score The score of the player | |
| * @param float $connectTime The time the player is connected to the | |
| * server | |
| */ | |
| public function __construct($id, $name, $score, $connectTime) { | |
| $this->connectTime = $connectTime; | |
| $this->id = $id; | |
| $this->name = $name; | |
| $this->score = $score; | |
| $this->extended = false; | |
| } | |
| /** | |
| * Extends a player object with information retrieved from a RCON call to | |
| * the status command | |
| * | |
| * @param string $playerData The player data retrieved from | |
| * <var>rcon status</var> | |
| * @throws SteamCondenserException if the information belongs to another | |
| * player | |
| */ | |
| public function addInformation($playerData) { | |
| if($playerData['name'] != $this->name) { | |
| throw new SteamCondenserException('Information to add belongs to a different player.'); | |
| } | |
| $this->extended = true; | |
| $this->realId = intval($playerData['userid']); | |
| if(array_key_exists('state', $playerData)) { | |
| $this->state = $playerData['state']; | |
| } | |
| $this->steamId = $playerData['uniqueid']; | |
| if(!$this->isBot()) { | |
| $this->loss = intval($playerData['loss']); | |
| $this->ping = intval($playerData['ping']); | |
| if(array_key_exists('adr', $playerData)) { | |
| $address = explode(':', $playerData['adr']); | |
| $this->ipAddress = $address[0]; | |
| $this->clientPort = intval($address[1]); | |
| } | |
| if(array_key_exists('rate', $playerData)) { | |
| $this->rate = $playerData['rate']; | |
| } | |
| } | |
| } | |
| /** | |
| * Returns the client port of this player | |
| * | |
| * @return int The client port of the player | |
| */ | |
| public function getClientPort() { | |
| return $this->clientPort; | |
| } | |
| /** | |
| * Returns the time this player is connected to the server | |
| * | |
| * @return float The connection time of the player | |
| */ | |
| public function getConnectTime() { | |
| return $this->connectTime; | |
| } | |
| /** | |
| * Returns the ID of this player | |
| * | |
| * @return int The ID of this player | |
| */ | |
| public function getId() { | |
| return $this->id; | |
| } | |
| /** | |
| * Returns the IP address of this player | |
| * | |
| * @return string The IP address of this player | |
| */ | |
| public function getIpAddress() { | |
| return $this->ipAddress; | |
| } | |
| /** | |
| * Returns the packet loss of this player's connection | |
| * | |
| * @return string The packet loss of this player's connection | |
| */ | |
| public function getLoss() { | |
| return $this->loss; | |
| } | |
| /** | |
| * Returns the nickname of this player | |
| * | |
| * @return string The name of this player | |
| */ | |
| public function getName() { | |
| return $this->name; | |
| } | |
| /** | |
| * Returns the ping of this player | |
| * | |
| * @return int The ping of this player | |
| */ | |
| public function getPing() { | |
| return $this->ping; | |
| } | |
| /** | |
| * Returns the rate of this player | |
| * | |
| * @return int The rate of this player | |
| */ | |
| public function getRate() { | |
| return $this->rate; | |
| } | |
| /** | |
| * Returns the real ID (as used on the server) of this player | |
| * | |
| * @return int The real ID of this player | |
| */ | |
| public function getRealId() { | |
| return $this->realId; | |
| } | |
| /** | |
| * Returns the score of this player | |
| * | |
| * @return int The score of this player | |
| */ | |
| public function getScore() { | |
| return $this->score; | |
| } | |
| /** | |
| * Returns the connection state of this player | |
| * | |
| * @return string The connection state of this player | |
| */ | |
| public function getState() { | |
| return $this->state; | |
| } | |
| /** | |
| * Returns the SteamID of this player | |
| * | |
| * @return string The SteamID of this player | |
| */ | |
| public function getSteamId() { | |
| return $this->steamId; | |
| } | |
| /** | |
| * Returns whether this player is a bot | |
| * | |
| * @return bool <var>true</var> if this player is a bot | |
| */ | |
| public function isBot() { | |
| return $this->steamId == 'BOT'; | |
| } | |
| /** | |
| * Returns whether this player object has extended information gathered | |
| * using RCON | |
| * | |
| * @return bool <var>true</var> if extended information for this player | |
| * is available | |
| */ | |
| public function isExtended() { | |
| return $this->extended; | |
| } | |
| /** | |
| * Returns a string representation of this player | |
| * | |
| * @return string A string representing this player | |
| */ | |
| public function __toString() { | |
| if($this->extended) { | |
| return "#{$this->realId} \"{$this->name}\", SteamID: {$this->steamId} Score: {$this->score}, Time: {$this->connectTime}"; | |
| } else { | |
| return "#{$this->id} \"{$this->name}\", Score: {$this->score}, Time: {$this->connectTime}"; | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'Socket.php'; | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/SteamCondenserException.php'; | |
| /** | |
| * This class represents a TCP socket | |
| * | |
| * It can connect to a remote host, send and receive packets | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| */ | |
| class TCPSocket extends Socket { | |
| /** | |
| * Connects the TCP socket to the host with the given IP address and port | |
| * number | |
| * | |
| * Depending on whether PHP's sockets extension is loaded, this uses either | |
| * <var>socket_create</var>/<var>socket_connect</var> or | |
| * <var>fsockopen</var>. | |
| * | |
| * @param string $ipAddress The IP address to connect to | |
| * @param int $portNumber The TCP port to connect to | |
| * @param int $timeout The timeout in milliseconds | |
| * @throws SocketException if an error occurs during connecting the socket | |
| */ | |
| public function connect($ipAddress, $portNumber, $timeout) { | |
| $this->ipAddress = $ipAddress; | |
| $this->portNumber = $portNumber; | |
| if($this->socketsEnabled) { | |
| if (!$this->socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) { | |
| throw new SocketException(socket_last_error($this->socket)); | |
| } | |
| socket_set_nonblock($this->socket); | |
| @socket_connect($this->socket, $ipAddress, $portNumber); | |
| $write = array($this->socket); | |
| $read = $except = array(); | |
| $sec = floor($timeout / 1000); | |
| $usec = $timeout % 1000; | |
| if(!socket_select($read, $write, $except, $sec, $usec)) { | |
| $errorCode = socket_last_error($this->socket); | |
| } else { | |
| $errorCode = socket_get_option($this->socket, SOL_SOCKET, SO_ERROR); | |
| } | |
| if ($errorCode) { | |
| throw new SocketException($errorCode); | |
| } | |
| socket_set_block($this->socket); | |
| } else { | |
| if (!$this->socket = @fsockopen("tcp://$ipAddress", $portNumber, $socketErrno, $socketErrstr, $timeout / 1000)) { | |
| throw new SocketException($socketErrstr); | |
| } | |
| stream_set_blocking($this->socket, true); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * This code is free software; you can redistribute it and/or modify it under | |
| * the terms of the new BSD License. | |
| * | |
| * Copyright (c) 2008-2013, Sebastian Staudt | |
| * | |
| * @license http://www.opensource.org/licenses/bsd-license.php New BSD License | |
| */ | |
| require_once STEAM_CONDENSER_PATH . 'Socket.php'; | |
| require_once STEAM_CONDENSER_PATH . 'exceptions/SteamCondenserException.php'; | |
| /** | |
| * This class represents a UDP socket | |
| * | |
| * It can connect to a remote host, send and receive packets | |
| * | |
| * @author Sebastian Staudt | |
| * @package steam-condenser | |
| */ | |
| class UDPSocket extends Socket { | |
| /** | |
| * Connects the UDP socket to the host with the given IP address and port | |
| * number | |
| * | |
| * Depending on whether PHP's sockets extension is loaded, this uses either | |
| * <var>socket_create</var>/<var>socket_connect</var> or | |
| * <var>fsockopen</var>. | |
| * | |
| * @param string $ipAddress The IP address to connect to | |
| * @param int $portNumber The UDP port to connect to | |
| * @param int $timeout The timeout in milliseconds | |
| * @throws SocketException if an error occurs during connecting the socket | |
| */ | |
| public function connect($ipAddress, $portNumber, $timeout) { | |
| $this->ipAddress = $ipAddress; | |
| $this->portNumber = $portNumber; | |
| if($this->socketsEnabled) { | |
| if(!$this->socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP)) { | |
| throw new SocketException(socket_last_error($this->socket)); | |
| } | |
| if(@!socket_connect($this->socket, $ipAddress, $portNumber)) { | |
| throw new SocketException(socket_last_error($this->socket)); | |
| } | |
| socket_set_block($this->socket); | |
| } else { | |
| if(!$this->socket = fsockopen("udp://$ipAddress", $portNumber, $socketErrno, $socketErrstr)) { | |
| throw new SocketException($socketErrstr); | |
| } | |
| stream_set_blocking($this->socket, true); | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * User: gannon | |
| * Date: 10/10/13 | |
| * Time: 1:00 PM | |
| * SDRCServerInfoWidget is the controller for the SDRC Server Info Widget for wordpress | |
| */ | |
| //add stem condinser | |
| include( plugin_dir_path( __FILE__ ) . 'lib/steam-condenser.php'); | |
| class SDRCServerInfoWidget extends WP_Widget { | |
| public function __construct() { | |
| $widget_ops = array('classname' => 'SDRCServerInfoWidget', 'description' => "Displays Server Info"); | |
| parent::WP_Widget(false, $name = 'SDRC Server Info Widget', $widget_ops); | |
| } | |
| /** | |
| * Draw THe widget | |
| * @param array $args | |
| * @param array $instance | |
| */ | |
| public function widget( $args, $instance ) { | |
| extract( $args ); | |
| $ip = $instance['ip']; | |
| $port = $instance['port']; | |
| $rcon = $instance['rcon']; | |
| //set up the data for the view | |
| $server = new SourceServer($ip,$port); | |
| $server_info =$server->getServerInfo(); | |
| $player_list = $server->getPlayers($rcon); | |
| //load tmplate file | |
| echo $before_widget; | |
| include( plugin_dir_path( __FILE__ ) . 'view/widget-main.tpl'); | |
| echo $after_widget; | |
| } | |
| public function form( $instance ) { | |
| /* Set up some default widget settings. */ | |
| $defaults = array( 'ip' => __('19.168.1.1', 'example'), 'port' => __('27015', 'example'),'rcon' => __('1234', 'example'), ); | |
| $instance = wp_parse_args( (array) $instance, $defaults ); ?> | |
| <!-- Server IP: Text Input --> | |
| <p> | |
| <label for="<?php echo $this->get_field_id( 'ip' ); ?>"><?php _e('Server IP:', 'hybrid'); ?></label> | |
| <input id="<?php echo $this->get_field_id( 'ip' ); ?>" name="<?php echo $this->get_field_name( 'ip' ); ?>" value="<?php echo $instance['ip']; ?>" style="width:100%;" /> | |
| </p> | |
| <!-- Server Port: Text Input --> | |
| <p> | |
| <label for="<?php echo $this->get_field_id( 'port' ); ?>"><?php _e('Server Port:', 'example'); ?></label> | |
| <input id="<?php echo $this->get_field_id( 'port' ); ?>" name="<?php echo $this->get_field_name( 'port' ); ?>" value="<?php echo $instance['port']; ?>" style="width:100%;" /> | |
| </p> | |
| <!-- Your Name: Text Input --> | |
| <p> | |
| <label for="<?php echo $this->get_field_id( 'rcon' ); ?>"><?php _e('RCON Password:', 'example'); ?></label> | |
| <input id="<?php echo $this->get_field_id( 'rcon' ); ?>" name="<?php echo $this->get_field_name( 'rcon' ); ?>" value="<?php echo $instance['rcon']; ?>" style="width:100%;" /> | |
| </p> | |
| <?php | |
| // include( plugin_dir_path( __FILE__ ) . 'lib/admin-menu.tpl'); | |
| } | |
| public function update( $new_instance, $old_instance ) { | |
| $instance = $old_instance; | |
| /* Strip tags for title and name to remove HTML (important for text inputs). */ | |
| $instance['ip'] = strip_tags( $new_instance['ip'] ); | |
| $instance['port'] = strip_tags( $new_instance['port'] ); | |
| $instance['rcon'] = strip_tags( $new_instance['rcon'] ); | |
| return $instance; | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <?php | |
| /** | |
| * Plugin Name: SDRC Server Info | |
| * Plugin URI: https://github.com/DavidGannon/SRCD-Server-Info | |
| * Description: A WordPress Plunging to Display SRCD Server info | |
| * Version: test | |
| * Author: David Gannon | |
| * Author URI: http://davidgannon.ca | |
| * License: GPL3 | |
| */ | |
| /** | |
| * Set up Hooks | |
| */ | |
| //add an admin menu hook | |
| add_action('admin_menu','srdc_server_info_admin_action'); | |
| //add widget hook | |
| add_action( 'widgets_init', 'SDRCServerInfoWidget_register' ); | |
| /** | |
| * Main admin set up | |
| */ | |
| function srdc_server_info_admin_action() | |
| { | |
| add_options_page('SDRC Server Info','SDRC Server Info','manage_options',__FILE__,'plugin_admin'); | |
| } | |
| /** | |
| * Admin Pae controller | |
| */ | |
| function plugin_admin(){ | |
| //load a view | |
| include( plugin_dir_path( __FILE__ ) . 'admin-menu.tpl'); | |
| } | |
| /** | |
| * Register widget | |
| */ | |
| function SDRCServerInfoWidget_register() { | |
| include( plugin_dir_path( __FILE__ ) . 'SDRCServerInfoWidget.php'); | |
| register_widget('SDRCServerInfoWidget'); | |
| } | |
| ?> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <h3 class="widget-title"><?php echo $server_info['serverName'] ; ?></h3> | |
| Map: <?php echo $server_info['mapName']; ?> <br /> | |
| <?php echo $server_info['numberOfPlayers'];?>/<?php echo $server_info['maxPlayers']; ?> | |
| <table> | |
| <thead> | |
| <tr> | |
| <td>Name</td> | |
| <td>Score</td> | |
| <td>Time</td> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| <?php foreach($player_list as $player):?> | |
| <tr> | |
| <td><?php echo $player->getName() ?></td> | |
| <td><?php echo $player->getScore() ?></td> | |
| <td><?php echo (round($player->getConnectTime()/60))." Min" ?></td> | |
| </tr> | |
| <?php endforeach; ?> | |
| </tbody> | |
| </table> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment