From 095ca15093c07a9c2f3c768eb43313978b01d6d7 Mon Sep 17 00:00:00 2001
From: Shavitush
Date: Sun, 1 Nov 2015 05:34:06 +0200
Subject: [PATCH] Added a (really ugly) web interface that shows records in
maps.
Configure using config.php
---
webserver/config.php | 19 ++
webserver/functions.php | 77 +++++++
webserver/steamid.php | 457 ++++++++++++++++++++++++++++++++++++++++
webserver/timer.php | 184 ++++++++++++++++
4 files changed, 737 insertions(+)
create mode 100644 webserver/config.php
create mode 100644 webserver/functions.php
create mode 100644 webserver/steamid.php
create mode 100644 webserver/timer.php
diff --git a/webserver/config.php b/webserver/config.php
new file mode 100644
index 00000000..d6ecec0b
--- /dev/null
+++ b/webserver/config.php
@@ -0,0 +1,19 @@
+
diff --git a/webserver/functions.php b/webserver/functions.php
new file mode 100644
index 00000000..9fc00b8d
--- /dev/null
+++ b/webserver/functions.php
@@ -0,0 +1,77 @@
+ 3600)
+ {
+ $iHours = floor($iTemp / 3600.0);
+ $iTemp %= 3600;
+ }
+
+ $sHours = "";
+
+ if($iHours < 10)
+ {
+ $sHours = "0" . $iHours;
+ }
+
+ else
+ {
+ $sHours = $iHours;
+ }
+
+ $iMinutes = 0;
+
+ if($iTemp >= 60)
+ {
+ $iMinutes = floor($iTemp / 60.0);
+ $iTemp %= 60;
+ }
+
+ $sMinutes = "";
+
+ if($iMinutes < 10)
+ {
+ $sMinutes = "0" . $iMinutes;
+ }
+
+ else
+ {
+ $sMinutes = $iMinutes;
+ }
+
+ $fSeconds = (($iTemp) + $time - floor($time));
+
+ $sSeconds = "";
+
+ if($fSeconds < 10)
+ {
+ $sSeconds = "0" . number_format($fSeconds, 3);
+ }
+
+ else
+ {
+ $sSeconds = number_format($fSeconds, 3);
+ }
+
+ if($iHours > 0)
+ {
+ $newtime = $sHours . ":" . $sMinutes . ":" . $sSeconds . "s";
+ }
+
+ else if($iMinutes > 0)
+ {
+ $newtime = $sMinutes . ":" . $sSeconds . "s";
+ }
+
+ else
+ {
+ $newtime = number_format($fSeconds, 3) . "s";
+ }
+
+ return $newtime;
+}
+?>
diff --git a/webserver/steamid.php b/webserver/steamid.php
new file mode 100644
index 00000000..82c91cb8
--- /dev/null
+++ b/webserver/steamid.php
@@ -0,0 +1,457 @@
+reason = $reason;
+ parent::__construct( $text );
+ }
+}
+
+/** ---------------------------------------------------------------------------
+ * SteamID
+ *
+ * Contains a User Steam ID.
+ *
+ * @author Mukunda Johnson
+ */
+class SteamID {
+
+ // RAW Steam ID value as a string. (a plain number.)
+ public $value;
+
+ // Array of converted values. Indexed by FORMAT_xxx
+ // this is a cache of formatted values, filled in
+ // by Format or Parse.
+ public $formatted;
+
+ const FORMAT_AUTO = 0; // Auto-detect format --- this also supports
+ // other unlisted formats such as
+ // full profile URLs.
+ const FORMAT_STEAMID32 = 1; // Classic STEAM_x:y:zzzzzz | x = 0/1
+ const FORMAT_STEAMID64 = 2; // SteamID64: 7656119xxxxxxxxxx
+ const FORMAT_STEAMID3 = 3; // SteamID3 format: [U:1:xxxxxx]
+ const FORMAT_S32 = 4; // Raw 32-bit SIGNED format.
+ // this is a raw steamid index that overflows
+ // into negative bitspace.
+ // This is the format that SourceMod returns
+ // with GetSteamAccountID, and will always
+ // fit into a 32-bit signed variable. (e.g.
+ // a 32-bit PHP integer).
+ const FORMAT_RAW = 5; // Raw index. like 64-bit minus the base value.
+ const FORMAT_VANITY = 6; // Vanity URL name. Forward conversion only.
+
+
+ const STEAMID64_BASE = '76561197960265728';
+
+ // max allowed value. (sanity check)
+ // 2^36; update this in approx 2,400,000 years
+ const MAX_VALUE = '68719476736';
+
+ private static $steam_api_key = FALSE;
+ private static $default_detect_raw = FALSE;
+ private static $default_resolve_vanity = FALSE;
+
+ /** -----------------------------------------------------------------------
+ * Set an API key to use for resolving Custom URLs. If this isn't set
+ * custom URL resolution will be done by parsing the profile XML.
+ *
+ * @param string $key API Key
+ * @see http://steamcommunity.com/dev/apikey
+ */
+ public static function SetSteamAPIKey( $key ) {
+ if( empty($key) ) self::$steam_api_key = FALSE;
+ self::$steam_api_key = $key;
+ }
+
+ /** -----------------------------------------------------------------------
+ * Set the default setting for $detect_raw for Parse()
+ *
+ * @param bool $parseraw Default $detect_raw value, see Parse function.
+ */
+ public static function SetParseRawDefault( $parseraw ) {
+ self::$default_detect_raw = $parseraw;
+ }
+
+ /** -----------------------------------------------------------------------
+ * Set the default setting for $resolve_vanity for Parse()
+ *
+ * @param bool $resolve_vanity Default $resolve_vanity value,
+ * see Parse function.
+ */
+ public static function SetResolveVanityDefault( $resolve_vanity ) {
+ self::$default_resolve_vanity = $resolve_vanity;
+ }
+
+ /** -----------------------------------------------------------------------
+ * Construct an instance.
+ *
+ * @param string $raw Raw value of Steam ID.
+ */
+ private function __construct( $raw ) {
+ $this->value = $raw;
+ $this->formatted[ self::FORMAT_RAW ] = $raw;
+ }
+
+ /** -----------------------------------------------------------------------
+ * Make a cURL request and return the contents.
+ *
+ * @param string $url URL to request.
+ * @return string|false Contents of result or FALSE if the request failed.
+ */
+ private static function Curl( $url ) {
+
+ $ch = curl_init();
+ curl_setopt( $ch, CURLOPT_URL, $url );
+ curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
+ curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1 );
+
+ $data = curl_exec($ch);
+ curl_close($ch);
+
+ return $data;
+ }
+
+ /** -----------------------------------------------------------------------
+ * Parse a Steam ID.
+ *
+ * @param string $input Input to parse.
+ * @param int $format Input formatting, see FORMAT_ constants.
+ * Defaults to FORMAT_AUTO which detects the format.
+ * @param bool $resolve_vanity Detect and resolve vanity URLs. (only used
+ * with FORMAT_AUTO. Default option set with
+ * SetResolveVanityDefault.
+ * @param bool $detect_raw Detect and parse RAW values. (only used with
+ * FORMAT_AUTO. e.g "123" will resolve to the
+ * SteamID with the raw value 123, and not a
+ * vanity-url named "123". Default option set with
+ * SetParseRawDefault.
+ *
+ * @return SteamID|false SteamID instance or FALSE if the input is invalid
+ * or unsupported.
+ */
+ public static function Parse( $input,
+ $format = self::FORMAT_AUTO,
+ $resolve_vanity = null,
+ $detect_raw = null ) {
+
+ if( $detect_raw === null )
+ $detect_raw = self::$default_detect_raw;
+ if( $resolve_vanity === null )
+ $resolve_vanity = self::$default_resolve_vanity;
+
+ switch( $format ) {
+
+ case self::FORMAT_STEAMID32:
+
+ // validate STEAM_0/1:y:zzzzzz
+ if( !preg_match(
+ '/^STEAM_[0-1]:([0-1]):([0-9]+)$/',
+ $input, $matches ) ) {
+
+ return FALSE;
+ }
+
+ // convert to raw.
+ $a = bcmul( $matches[2], '2', 0 );
+ $a = bcadd( $a, $matches[1], 0 );
+
+ $result = new self( $a );
+ $result->formatted[ self::FORMAT_STEAMID32 ] = $input;
+ return $result;
+
+ case self::FORMAT_STEAMID64:
+
+ // allow digits only
+ if( !preg_match( '/^[0-9]+$/', $input ) ) return FALSE;
+
+ // convert to raw (subtract base)
+ $a = bcsub( $input, self::STEAMID64_BASE, 0 );
+
+ // sanity range check.
+ if( bccomp( $a, '0', 0 ) < 0 ) return FALSE;
+ if( bccomp( $a, self::MAX_VALUE, 0 ) > 0 ) return FALSE;
+
+ $result = new self( $a );
+ $result->formatted[ self::FORMAT_STEAMID64 ] = $input;
+ return $result;
+
+ case self::FORMAT_STEAMID3:
+
+ // validate [U:1:xxxxxx]
+ if( !preg_match( '/^\[U:1:([0-9]+)\]$/', $input, $matches ) ) {
+ return FALSE;
+ }
+
+ $a = $matches[1];
+
+ // sanity range check.
+ if( bccomp( $a, self::MAX_VALUE, 0 ) > 0 ) return FALSE;
+ $result = new self( $a );
+ $result->formatted[ self::FORMAT_STEAMID3 ] = $input;
+ return $result;
+
+ case self::FORMAT_S32:
+
+ // validate signed 32-bit format
+ if( !preg_match( '/^(-?[0-9]+)$/', $input ) ) {
+ return FALSE;
+ }
+
+ $a = $input;
+
+ // 32-bit range check
+ if( bccomp( $a, '2147483647', 0 ) > 0 ) return FALSE;
+ if( bccomp( $a, '-2147483648', 0 ) < 0 ) return FALSE;
+ if( bccomp( $a, '0', 0 ) < 0 ) {
+ $a = bcadd( $a, '4294967296', 0 );
+ }
+ $result = new self( $a );
+ $result->formatted[ self::FORMAT_S32 ] = $input;
+ return $result;
+
+ case self::FORMAT_RAW:
+
+ // validate digits only
+ if( !preg_match( '/^[0-9]+$/', $input ) ) {
+ return FALSE;
+ }
+
+ // sanity range check
+ if( bccomp( $input, self::MAX_VALUE, 0 ) > 0 ) return FALSE;
+ return new self( $input );
+
+ case self::FORMAT_VANITY:
+
+ // validate characters.
+ if( !preg_match( '/^[a-zA-Z0-9_-]{2,}$/', $input ) ) return FALSE;
+
+ $result = self::ConvertVanityURL( $input );
+ if( $result !== FALSE ) {
+ $result->formatted[ self::FORMAT_VANITY ] = $input;
+ return $result;
+ }
+ }
+
+ // Auto detect format:
+
+ $input = trim( $input );
+ $result = self::Parse( $input, self::FORMAT_STEAMID32 );
+ if( $result !== FALSE ) return $result;
+ $result = self::Parse( $input, self::FORMAT_STEAMID64 );
+ if( $result !== FALSE ) return $result;
+ $result = self::Parse( $input, self::FORMAT_STEAMID3 );
+ if( $result !== FALSE ) return $result;
+
+ if( preg_match(
+ '/^(?:https?:\/\/)?(?:www.)?steamcommunity.com\/profiles\/([0-9]+)\/*$/',
+ $input, $matches ) ) {
+
+ $result = self::Parse( $matches[1], self::FORMAT_STEAMID64 );
+ if( $result !== FALSE ) return $result;
+ }
+
+ if( $resolve_vanity ) {
+
+ // try the name directly
+ $result = self::Parse( $input, self::FORMAT_VANITY );
+ if( $result !== FALSE ) return $result;
+
+ // try a full URL.
+ if( preg_match(
+ '/^(?:https?:\/\/)?(?:www.)?steamcommunity.com\/id\/([a-zA-Z0-9_-]{2,})\/*$/',
+ $input, $matches ) ) {
+
+ $result = self::ConvertVanityURL( $matches[1] );
+ if( $result !== FALSE ) return $result;
+ }
+ }
+
+ if( $detect_raw ) {
+ $result = self::Parse( $input, self::FORMAT_S32 );
+ if( $result !== FALSE ) return $result;
+ $result = self::Parse( $input, self::FORMAT_RAW );
+ if( $result !== FALSE ) return $result;
+ }
+
+ // unknown stem
+ return FALSE;
+ }
+
+ /** -----------------------------------------------------------------------
+ * Convert a vanity URL into a SteamID instance.
+ *
+ * @param string $vanity_url_name The text part of the person's vanity URL.
+ * e.g http://steamcommunity.com/id/gabelogannewell
+ * would use "gabelogannewell"
+ * @return SteamID|false SteamID instance or FALSE on failure.
+ */
+ public static function ConvertVanityURL( $vanity_url_name ) {
+ if( empty($vanity_url_name) ) return FALSE;
+
+ if( self::$steam_api_key !== FALSE ) {
+ $response = self::Curl(
+ "http://api.steampowered.com/ISteamUser/ResolveVanityURL/v0001/?key="
+ .self::$steam_api_key
+ ."&vanityurl=$vanity_url_name" );
+ if( $response === FALSE ) {
+ throw new SteamIDResolutionException(
+ SteamIDResolutionException::CURL_FAILURE,
+ 'CURL Request Failed.' );
+ }
+
+ if( $response == "" ) {
+ throw new SteamIDResolutionException(
+ SteamIDResolutionException::VANITYURL_FAILED,
+ 'Steam failure.' );
+ }
+
+ $response = json_decode( $response );
+ if( $response === FALSE ) {
+ throw new SteamIDResolutionException(
+ SteamIDResolutionException::VANITYURL_FAILED,
+ 'Steam failure.' );
+ }
+
+ $response = $response->response;
+
+ if( $response->success == 42 ) {
+ throw new SteamIDResolutionException(
+ SteamIDResolutionException::VANITYURL_NOTFOUND,
+ 'Vanity URL doesn\'t exist.' );
+
+ }
+
+ if( $response->success != 1 ) {
+ throw new SteamIDResolutionException(
+ SteamIDResolutionException::VANITYURL_FAILED,
+ 'Steam failure.' );
+
+ }
+
+ $steamid = $response->steamid;
+
+ } else {
+ // fallback to xml parsing method.
+
+ $result = self::Curl( "http://steamcommunity.com/id/$vanity_url_name?xml=1" );
+ if( $result === FALSE ) {
+ throw new SteamIDResolutionException(
+ SteamIDResolutionException::CURL_FAILURE,
+ 'CURL Request Failed.' );
+ }
+
+ $parser = xml_parser_create('');
+ $values = array();
+ $indexes = array();
+ xml_parse_into_struct( $parser, $result, $values, $indexes );
+ xml_parser_free($parser);
+ if( !isset( $indexes['STEAMID64'] ) || is_null( $indexes['STEAMID64'] ) ) {
+
+ if( isset( $indexes['ERROR'] ) &&
+ trim($values[ $indexes['ERROR'][0] ]['value']) ==
+ 'The specified profile could not be found.' ) {
+
+ throw new SteamIDResolutionException(
+ SteamIDResolutionException::VANITYURL_NOTFOUND,
+ 'Vanity URL doesn\'t exist.' );
+ }
+
+ throw new SteamIDResolutionException(
+ SteamIDResolutionException::VANITYURL_FAILED,
+ 'Invalid Vanity URL or Steam failure.' );
+ }
+ $steamid = $indexes['STEAMID64'];
+ $steamid = $values[ $steamid[0] ]['value'];
+ }
+
+ return self::Parse( $steamid, self::FORMAT_STEAMID64 );
+ }
+
+ /** -----------------------------------------------------------------------
+ * Format this SteamID to a string.
+ *
+ * @param int $format Output format. See FORMAT_xxx constants.
+ * @return string|false Formatted Steam ID. FALSE if an invalid format is
+ * given or the desired format cannot contain the
+ * SteamID.
+ */
+ public function Format( $format ) {
+ if( isset( $this->formatted[$format] ) ) {
+ return $this->formatted[$format];
+ }
+
+ switch( $format ) {
+ case self::FORMAT_STEAMID32:
+ $z = bcdiv( $this->value, '2', 0 );
+ $y = bcmul( $z, '2', 0 );
+ $y = bcsub( $this->value, $y, 0 );
+ $formatted = "STEAM_1:$y:$z";
+ $this->formatted[$format] = $formatted;
+ return $formatted;
+
+ case self::FORMAT_STEAMID64:
+ $formatted = bcadd( $this->value, self::STEAMID64_BASE, 0 );
+ $this->formatted[$format] = $formatted;
+ return $formatted;
+
+ case self::FORMAT_STEAMID3:
+ $formatted = "[U:1:$this->value]";
+ $this->formatted[$format] = $formatted;
+ return $formatted;
+
+ case self::FORMAT_S32:
+ if( bccomp( $this->value, '4294967296', 0 ) >= 0 ) {
+ return FALSE; // too large for s32.
+ }
+
+ if( bccomp( $this->value, '2147483648', 0 ) >= 0 ) {
+ $formatted = bcsub( $this->value, '4294967296', 0 );
+ } else {
+ $formatted = $this->value;
+ }
+ $this->formatted[$format] = $formatted;
+ return $formatted;
+
+ // (raw is always cached)
+ }
+ return FALSE;
+ }
+
+}
+
+?>
diff --git a/webserver/timer.php b/webserver/timer.php
new file mode 100644
index 00000000..a66f42a8
--- /dev/null
+++ b/webserver/timer.php
@@ -0,0 +1,184 @@
+set_charset("utf8");
+
+$map = isset($_GET["map"]);
+
+function removeworkshop($mapname)
+{
+ if(strpos($mapname, "workshop/") !== false)
+ {
+ $pieces = explode("/", $mapname);
+
+ return $pieces[2];
+ }
+
+ return $mapname;
+}
+
+$style = 0;
+
+if(isset($_GET["style"]))
+{
+ $style = $_GET["style"];
+}
+?>
+
+
+
+
+
+
+
+ " . HOMEPAGE_TITLE . "");
+ }
+
+ else
+ {
+ echo("[" . ($style == 0? "NM":"SW") . " Records] " . removeworkshop($_GET["map"]) . "");
+ } ?>
+
+
+
+ Home
+
+
+
+ prepare("SELECT p.id, p.map, u.auth, u.name, p.time, p.jumps FROM playertimes p JOIN users u ON p.auth = u.auth WHERE map = ? AND style = ? ORDER BY time ASC LIMIT " . RECORD_LIMIT . ";"))
+ {
+ $stmt->bind_param("ss", $_GET["map"], $_GET["style"]);
+ $stmt->execute();
+
+ $stmt->store_result();
+
+ $rows = $stmt->num_rows;
+
+ $stmt->bind_result($id, $map, $auth, $name, $time, $jumps);
+
+ echo "Number of records: " . number_format($rows) . ".
";
+
+ if($rows > 0)
+ {
+ $first = true;
+
+ $rank = 1;
+
+ while($row = $stmt->fetch())
+ {
+ if($first)
+ {
+ echo("[" . ($style == 0? "Forwards":"Sideways") . " Records] " . removeworkshop($_GET["map"]) . "
");
+
+ ?>
+
+ | Rank |
+ Record ID |
+ SteamID3 |
+ Player |
+ Time |
+ Jumps |
+
+
+
+ | # |
+ |
+ Format(SteamID::FORMAT_STEAMID64) . "/\">" . $auth . ""); ?> |
+ |
+
+
+ |
+ |
+
+ ");
+ }
+ }
+
+ else
+ {
+ echo "No results. Press Home to get the map list.
";
+ }
+
+ $stmt->close();
+ }
+
+ else
+ {
+ $result = mysqli_query($connection, "SELECT DISTINCT map FROM mapzones ORDER BY map ASC;");
+
+ if($result->num_rows > 0)
+ {
+ echo 'Click a map name in order to auto-fill the form.
';
+
+ while($row = $result->fetch_assoc())
+ {
+ echo "" . removeworkshop($row["map"]) . "";
+ }
+ }
+
+ else
+ {
+ echo "No results";
+ }
+ }
+ ?>
+
+
+close(); ?>