├── .gitignore ├── README.md ├── index.php └── steam ├── SteamApps.php ├── SteamGame.php ├── SteamUser.php └── SteamUtility.php /.gitignore: -------------------------------------------------------------------------------- 1 | /steam/private/apikey.inc.php 2 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | SteamAPI 2 | ======== 3 | 4 | SteamAPI is a PHP wrapper for interacting with Valve's Steam Community. 5 | 6 | SteamAPI offers the ability to: 7 | 8 | * pull entire player profiles, including most played games, Steam Ratings, and groups subscribed to; 9 | * get achievements and statistics schema for specific games (Steam apikey and json PHP extension required); 10 | * track user achievements 11 | * pull the latest App/Game Store List, and query the latest version of a game 12 | * check for online and offline servers for a given IP Address 13 | 14 | Hopefully over time, more functionality can be added to this API, including pulling global game statistics, group interaction if there's time! 15 | 16 | 17 | Overview 18 | -------- 19 | 20 | It's simple to integrate SteamAPI into your web application! 21 | 22 | To access user profiles, create a SteamUser object for the target user: 23 | 24 | 32 | 33 | 34 | More Information 35 | ---------------- 36 | * Looking for [API Documentation](/MattRyder/steamAPI/wiki/API-Documentation)? 37 | * Some [examples of usage](/MattRyder/steamAPI/wiki/Examples)? 38 | -------------------------------------------------------------------------------- /index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 |

Steam API Test

12 | 13 | getGamesList(); 25 | // print_r($games); 26 | 27 | // SteamApps Example, is "Garry's Mod" up to date?: 28 | $steamAppsObject = new SteamApps(); 29 | $data = $steamAppsObject->upToDateCheck(4000, 140415); 30 | print_r($data); 31 | 32 | // $game = new SteamGame(440); //New SteamGame with TF2's AppID set. 33 | // $news = $game->getNewsItems(); 34 | // print_r($news); 35 | 36 | 37 | ?> 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /steam/SteamApps.php: -------------------------------------------------------------------------------- 1 | apiKey = $apiKey; 29 | } 30 | } 31 | 32 | /** 33 | * WebAPI/GetAppList 34 | * - Returns a list of Apps, with their ID and Name set 35 | * @param boolean $reload Whether to miss cache and reload data 36 | */ 37 | function getAppList($reload = false) { 38 | $apiAction = "GetAppList/v2/?format=xml"; 39 | 40 | // Valve highly recommend caching this, it's quite a big GET 41 | if(isset($this->appList) && !$reload) { 42 | return $this->appList; 43 | } else { 44 | $this->appList = array(); 45 | } 46 | 47 | $apiUrl = self::API_BASE . $apiAction; 48 | $parsedData = SteamUtility::fetchDataFromUrl($apiUrl); 49 | 50 | if(!empty($parsedData)) { 51 | $i = 0; 52 | foreach ($parsedData->apps[0] as $app) { 53 | $this->appList[$i] = new stdClass(); 54 | $this->appList[$i]->appId = (string)$app->appid; 55 | $this->appList[$i]->name = (string)$app->name; 56 | $i++; 57 | } 58 | } 59 | return $this->appList; 60 | } 61 | 62 | /** 63 | * WebAPI/GetServersAtAddress 64 | * - Returns a list of Servers active for the given IP Address 65 | */ 66 | function getServersAtAddress($serverAddress) { 67 | $apiAction = "GetServersAtAddress/v1?format=xml"; 68 | $apiParams = "&addr=" . $serverAddress; 69 | 70 | if(empty($serverAddress)) { 71 | echo "Error: No server address given!", PHP_EOL; 72 | return NULL; 73 | } 74 | 75 | $this->serverList = array(); 76 | 77 | $apiUrl = self::API_BASE . $apiAction . $apiParams; 78 | $parsedData = SteamUtility::fetchDataFromUrl($apiUrl); 79 | 80 | if(!empty($parsedData)) { 81 | $i = 0; 82 | foreach ($parsedData->servers->server as $server) { 83 | $this->serverList[$i] = new stdClass(); 84 | $this->serverList[$i]->address = (string)$server->addr; 85 | $this->serverList[$i]->gmsindex = (string)$server->gmsindex; 86 | $this->serverList[$i]->appId = (string)$server->appid; 87 | $this->serverList[$i]->gameDir = (string)$server->gamedir; 88 | $this->serverList[$i]->region = (string)$server->region; 89 | $this->serverList[$i]->secure = (string)$server->secure; 90 | $this->serverList[$i]->lan = (string)$server->lan; 91 | $this->serverList[$i]->gamePort = (string)$server->gameport; 92 | $this->serverList[$i]->specPort = (string)$server->specPort; 93 | $i++; 94 | } 95 | } 96 | return $this->serverList; 97 | } 98 | 99 | /** 100 | * WebAPI/UpToDateCheck 101 | * - Checks if the given version of the app is up to date 102 | * @param string appId The ID of which app to check 103 | * @param string version The version that you want to check 104 | */ 105 | function upToDateCheck($appId, $version) { 106 | $apiAction = "UpToDateCheck/v1?format=xml"; 107 | 108 | if(empty($appId)) { 109 | echo "Error: No server address given!", PHP_EOL; 110 | return NULL; 111 | } 112 | if(empty($version)) { 113 | echo "Error: No version supplied!", PHP_EOL; 114 | return NULL; 115 | } 116 | 117 | // Set the params: 118 | $apiParams = "&appid=" . $appId; 119 | $apiParams .= "&version=" . $version; 120 | 121 | $this->versionCheck = new stdClass(); 122 | 123 | $apiUrl = self::API_BASE . $apiAction . $apiParams; 124 | $parsedData = SteamUtility::fetchDataFromUrl($apiUrl); 125 | 126 | if(!empty($parsedData) && (boolean)$parsedData->success) { 127 | $this->versionCheck->upToDate = (string)$parsedData->up_to_date; 128 | $this->versionCheck->isListable = (string)$parsedData->version_is_listable; 129 | $this->versionCheck->requiredVersion = (string)$parsedData->required_version; 130 | $this->versionCheck->message = (string)$parsedData->message; 131 | } 132 | return $this->versionCheck; 133 | } 134 | } 135 | 136 | ?> -------------------------------------------------------------------------------- /steam/SteamGame.php: -------------------------------------------------------------------------------- 1 | appID = $appID; 28 | if (!is_null($apiKey)) { 29 | $this->apiKey = $apiKey; 30 | } 31 | } 32 | 33 | /** 34 | * GetNewsItems - Gets the latest news posts about the SteamGame 35 | * @param $newsItemCount: How many news enties you want to get returned. 36 | * @param $maxLength: Maximum length of each news article 37 | * @return $gameNews: Array containing news entries. 38 | */ 39 | function getNewsItems($newsItemCount = 3, $maxLength = 300) { 40 | 41 | if($newsItemCount == NULL) 42 | $newsItemCount = 3; 43 | if($maxLength == NULL) 44 | $maxLength = 300; 45 | 46 | if(!empty($this->appID)) { 47 | 48 | $base = "http://api.steampowered.com/ISteamNews/GetNewsForApp/v0002/" 49 | . "?appid={$this->appID}&count={$newsItemCount}&maxlength={$maxLength}&format=xml"; 50 | 51 | $newsData = new SimpleXMLElement(SteamUtility::fetchURL($base)); 52 | 53 | $i = 0; 54 | foreach ($newsData->newsitems->newsitem as $item) { 55 | $this->gameNews = array( 56 | 'gid' => (string) $item->gid, 57 | 'title' => (string) $item->title, 58 | 'url' => (string) $item->url, 59 | 'is_external_url' => (string)$item->is_external_url, 60 | 'author' => (string)$item->author, 61 | 'contents' => (string)$item->contents, 62 | 'feedlabel' => (string)$item->feedlabel, 63 | 'date' => (string)$item->date, 64 | 'feedname' => (string)$item->feedname 65 | ); 66 | } 67 | 68 | return $this->gameNews; 69 | } else { 70 | return null; 71 | } 72 | } 73 | 74 | /** 75 | * GetSchemaForGame - Loads schema for a selected game 76 | * @param string $lang Language for descriptions 77 | * @return array Schema as an associative array cointaining ['achievements'] and ['stats'] 78 | */ 79 | function getSchema($lang = 'en') { 80 | if(!empty($this->appID)) { 81 | $base = "http://api.steampowered.com/ISteamUserStats/GetSchemaForGame/v0002/?key={$this->apiKey}&appid={$this->appID}&l={$lang}"; 82 | } 83 | 84 | $json = SteamUtility::fetchURL($base); 85 | if(!$json) { 86 | return null; 87 | } 88 | 89 | $gameSchema = json_decode($json, true); 90 | 91 | if (!$gameSchema) { 92 | return null; 93 | } 94 | 95 | $this->gameSchema = array( 96 | 'achievements' => $gameSchema['game']['availableGameStats']['achievements'], 97 | 'stats' => $gameSchema['game']['availableGameStats']['stats'] 98 | ); 99 | 100 | return $this->gameSchema; 101 | } 102 | 103 | /** 104 | * Sets an API key for api.steampowered.com 105 | * @param string $apiKey API key 106 | */ 107 | function setApiKey($apiKey) { 108 | $this->apiKey = $apiKey; 109 | } 110 | } 111 | 112 | ?> 113 | -------------------------------------------------------------------------------- /steam/SteamUser.php: -------------------------------------------------------------------------------- 1 | userID = $id; 36 | } 37 | else { 38 | $this->vanityURL = strtolower($id); 39 | } 40 | 41 | if (!is_null($apiKey)) { 42 | $this->apiKey = $apiKey; 43 | } 44 | 45 | $this->getProfileData(); 46 | } 47 | 48 | /** 49 | * GetProfileData 50 | * - Accesses Steam Profile XML and parses the data 51 | */ 52 | function getProfileData() { 53 | 54 | //Set Base URL for the query: 55 | if(empty($this->vanityURL)) { 56 | $base = "http://steamcommunity.com/profiles/{$this->userID}/?xml=1"; 57 | } else { 58 | $base = "http://steamcommunity.com/id/{$this->vanityURL}/?xml=1"; 59 | } 60 | 61 | try { 62 | $content = SteamUtility::fetchURL($base); 63 | if ($content) { 64 | $parsedData = new SimpleXMLElement($content); 65 | } else { 66 | return null; 67 | } 68 | } catch (Exception $e) { 69 | //echo "Whoops! Something went wrong!\n\nException Info:\n" . $e . "\n\n"; 70 | return null; 71 | } 72 | 73 | if(!empty($parsedData)) { 74 | $this->steamID64 = (string)$parsedData->steamID64; 75 | $this->steamID = (string)$parsedData->steamID; 76 | $this->stateMessage = (string)$parsedData->stateMessage; 77 | $this->visibilityState = (int)$parsedData->visibilityState; 78 | $this->privacyState = (string)$parsedData->privacyState; 79 | 80 | $this->avatarIcon = (string)$parsedData->avatarIcon; 81 | $this->avatarMedium = (string)$parsedData->avatarMedium; 82 | $this->avatarFull = (string)$parsedData->avatarFull; 83 | 84 | $this->vacBanned = (int)$parsedData->vacBanned; 85 | $this->tradeBanState = (string)$parsedData->tradeBanState; 86 | $this->isLimitedAccount = (string)$parsedData->isLimitedAccount; 87 | 88 | $this->onlineState = (string)$parsedData->onlineState; 89 | $this->inGameServerIP = (string)$parsedData->inGameServerIP; 90 | 91 | //If their account is public, get that info: 92 | if($this->privacyState == "public") { 93 | $this->customURL = (string)$parsedData->customURL; 94 | $this->memberSince = (string)$parsedData->memberSince; 95 | 96 | $this->steamRating = (float)$parsedData->steamRating; 97 | $this->hoursPlayed2Wk = (float)$parsedData->hoursPlayed2Wk; 98 | 99 | $this->headline = (string)$parsedData->headline; 100 | $this->location = (string)$parsedData->location; 101 | $this->realname = (string)$parsedData->realname; 102 | $this->summary = (string)$parsedData->summary; 103 | } 104 | 105 | //If they're in a game, grab that info: 106 | if($this->onlineState == "in-game") { 107 | $this->inGameInfo = array(); 108 | $this->inGameInfo["gameName"] = (string)$parsedData->inGameInfo->gameName; 109 | $this->inGameInfo["gameLink"] = (string)$parsedData->inGameInfo->gameLink; 110 | $this->inGameInfo["gameIcon"] = (string)$parsedData->inGameInfo->gameIcon; 111 | $this->inGameInfo["gameLogo"] = (string)$parsedData->inGameInfo->gameLogo; 112 | $this->inGameInfo["gameLogoSmall"] = (string)$parsedData->inGameInfo->gameLogoSmall; 113 | } 114 | 115 | //Get their most played video games: 116 | if(!empty($parsedData->mostPlayedGames)) { 117 | $this->mostPlayedGames = array(); 118 | 119 | $i = 0; 120 | foreach ($parsedData->mostPlayedGames->mostPlayedGame as $mostPlayedGame) { 121 | $this->mostPlayedGames[$i] = new stdClass(); 122 | $this->mostPlayedGames[$i]->gameName = (string)$mostPlayedGame->gameName; 123 | $this->mostPlayedGames[$i]->gameLink = (string)$mostPlayedGame->gameLink; 124 | $this->mostPlayedGames[$i]->gameIcon = (string)$mostPlayedGame->gameIcon; 125 | $this->mostPlayedGames[$i]->gameLogo = (string)$mostPlayedGame->gameLogo; 126 | $this->mostPlayedGames[$i]->gameLogoSmall = (string)$mostPlayedGame->gameLogoSmall; 127 | $this->mostPlayedGames[$i]->hoursPlayed = (string)$mostPlayedGame->hoursPlayed; 128 | $this->mostPlayedGames[$i]->hoursOnRecord = (string)$mostPlayedGame->hoursOnRecord; 129 | $this->mostPlayedGames[$i]->statsName = (string)$mostPlayedGame->statsName; 130 | $i++; 131 | } 132 | } 133 | 134 | //Any weblinks listed in their profile: 135 | if(!empty($parsedData->weblinks)) { 136 | $this->weblinks = array(); 137 | 138 | $i = 0; 139 | foreach ($parsedData->weblinks->weblink as $weblink) { 140 | $this->weblinks[$i]->title = (string)$weblink->title; 141 | $this->weblinks[$i]->link = (string)$weblink->link; 142 | $i++; 143 | } 144 | } 145 | 146 | //And grab any subscribed groups: 147 | if(!empty($parsedData->groups)) { 148 | $this->groups = array(); 149 | 150 | $i = 0; 151 | foreach ($parsedData->groups->group as $group) { 152 | $this->groups[$i] = new stdClass(); 153 | $this->groups[$i]->groupID64 = (string)$group->groupID64; 154 | $this->groups[$i]->groupName = (string)$group->groupName; 155 | $this->groups[$i]->groupURL = (string)$group->groupURL; 156 | $this->groups[$i]->headline = (string)$group->headline; 157 | $this->groups[$i]->summary = (string)$group->summary; 158 | 159 | $this->groups[$i]->avatarIcon = (string)$group->avatarIcon; 160 | $this->groups[$i]->avatarMedium = (string)$group->avatarMedium; 161 | $this->groups[$i]->avatarFull = (string)$group->avatarFull; 162 | 163 | $this->groups[$i]->memberCount = (string)$group->memberCount; 164 | $this->groups[$i]->membersInChat = (string)$group->membersInChat; 165 | $this->groups[$i]->membersInGame = (string)$group->membersInGame; 166 | $this->groups[$i]->membersOnline = (string)$group->membersOnline; 167 | 168 | $i++; 169 | } 170 | 171 | } 172 | } 173 | } 174 | 175 | /** 176 | * GetFriendsList 177 | * - Accesses Steam API's GetFriendsList and parses returned XML 178 | * - Gets each friends' SteamID64, relationship, and UNIX timestamp since being a friend 179 | * @return Zero-based array of friends. 180 | */ 181 | function getFriendsList() { 182 | 183 | $apikey = $this->apiKey; 184 | 185 | if(!empty($this->steamID64)) { 186 | //Setup URL to the steam API for the list: 187 | $baseURL = "http://api.steampowered.com/ISteamUser/GetFriendList/v0001/" 188 | . "?key={$apikey}&steamid={$this->steamID64}&relationship=friend&format=xml"; 189 | 190 | $parsedFL = new SimpleXMLElement(SteamUtility::fetchURL($baseURL)); 191 | $this->friendList = array(); 192 | 193 | $i = 0; 194 | foreach ($parsedFL->friends->friend as $friend) { 195 | $this->friendList[$i]->steamid = (string)$friend->steamid; 196 | $this->friendList[$i]->relationship = (string)$friend->relationship; 197 | $this->friendList[$i]->friend_since = (string)$friend->friend_since; 198 | $i++; 199 | } 200 | 201 | return $this->friendList; 202 | } 203 | } 204 | 205 | /** 206 | * GetGamesList 207 | * - Accesses Steam Profile Games XML and parses returned XML 208 | * - Gets each Game based on AppID, Game Name, Logo, Store Link, Hours on Record, (global & personal) Stats Links 209 | * @return Zero-based array of games. 210 | */ 211 | function getGamesList() { 212 | 213 | //Set Base URL for the query: 214 | if(empty($this->vanityURL)) { 215 | $base = "http://steamcommunity.com/profiles/{$this->userID}/games?xml=1"; 216 | } else { 217 | $base = "http://steamcommunity.com/id/{$this->vanityURL}/games?xml=1"; 218 | } 219 | 220 | try { 221 | $content = SteamUtility::fetchURL($base); 222 | if ($content) { 223 | $gamesData = new SimpleXMLElement($content); 224 | } else { 225 | return null; 226 | } 227 | } catch (Exception $e) { 228 | // Usually happens when service is down 229 | return null; 230 | } 231 | 232 | if(!empty($gamesData)) { 233 | $this->gamesList = array(); 234 | 235 | $i = 0; 236 | foreach ($gamesData->games->game as $game) { 237 | $this->gamesList[$i] = new stdClass(); 238 | $this->gamesList[$i]->appID = (string)$game->appID; 239 | $this->gamesList[$i]->name = (string)$game->name; 240 | $this->gamesList[$i]->logo = (string)$game->logo; 241 | $this->gamesList[$i]->storeLink = (string)$game->storeLink; 242 | $this->gamesList[$i]->hoursLast2Weeks = (string)$game->hoursLast2Weeks; 243 | $this->gamesList[$i]->hoursOnRecord = (string)$game->hoursOnRecord; 244 | $this->gamesList[$i]->statsLink = (string)$game->statsLink; 245 | $this->gamesList[$i]->globalStatsLink = (string)$game->globalStatsLink; 246 | $i++; 247 | } 248 | return $this->gamesList; 249 | } 250 | } 251 | 252 | /** 253 | * Returns achievements for a specific game found in user's profile. 254 | * @param string $gameName Game alias on steamcommunity.com, e.g. 'FM2012' 255 | * @return array An array of achievements or null on error 256 | */ 257 | function getAchievements($gameName) { 258 | //Set Base URL for the query: 259 | if(empty($this->vanityURL)) { 260 | $base = "http://steamcommunity.com/profiles/{$this->userID}/stats/{$gameName}?xml=1"; 261 | } else { 262 | $base = "http://steamcommunity.com/id/{$this->vanityURL}/stats/{$gameName}?xml=1"; 263 | } 264 | 265 | try { 266 | $content = SteamUtility::fetchURL($base); 267 | if ($content) { 268 | $gameStats = new SimpleXMLElement($content); 269 | } else { 270 | return null; 271 | } 272 | } catch (Exception $e) { 273 | // Usually happens when service is down 274 | return null; 275 | } 276 | 277 | if ($gameStats) { 278 | if ($gameStats->privacyState != 'public') { 279 | // Only public profiles are supported 280 | return null; 281 | } 282 | 283 | $achievements = array(); 284 | 285 | // Load achievements 286 | foreach ($gameStats->achievements->achievement as $ach) { 287 | $item = new stdClass(); 288 | $item->apiname = (string)$ach->apiname; 289 | $item->name = (string)$ach->name; 290 | $item->description = (string)$ach->description; 291 | if ($ach->attributes()->closed == 1) { 292 | $item->unlocked = 1; 293 | $item->icon = (string)$ach->iconClosed; 294 | $item->unlockTimestamp = (int)$ach->unlockTimestamp; 295 | } else { 296 | $item->unlocked = 0; 297 | $item->icon = (string)$ach->iconOpen; 298 | } 299 | $achievements[] = $item; 300 | } 301 | 302 | return $achievements; 303 | } 304 | } 305 | 306 | /** 307 | * ConvertToCommunityID 308 | * - Converts a 17-digit Community ID (e.g. 76561197960435530) into a SteamID (e.g. STEAM_0:1:3144145) 309 | * @return SteamID as a string 310 | */ 311 | function convertToCommunityID() { 312 | 313 | if(!empty($this->steamID64)) { 314 | 315 | $Y = $this->steamID64 % 2; //Parity bit at end of 64-bit ID 316 | $Z = gmp_and($this->steamID64, "0xFFFFFFFF"); //Get the Account ID 317 | $Z = gmp_strval(gmp_div($Z, 2)); 318 | 319 | return "STEAM_0:{$Y}:{$Z}"; 320 | } 321 | } 322 | 323 | /** 324 | * Sets an API key for api.steampowered.com 325 | * @param string $apiKey API key 326 | */ 327 | function setApiKey($apiKey) { 328 | $this->apiKey = $apiKey; 329 | } 330 | } 331 | ?> -------------------------------------------------------------------------------- /steam/SteamUtility.php: -------------------------------------------------------------------------------- 1 | array( 45 | 'timeout' => self::$connectTimeout 46 | ))); 47 | return file_get_contents($url, false, $ctx); 48 | } 49 | elseif (function_exists('curl_init')) 50 | { 51 | $handle = curl_init(); 52 | curl_setopt($handle, CURLOPT_URL, $url); 53 | curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); 54 | curl_setopt($handle, CURLOPT_TIMEOUT, self::$connectTimeout); 55 | return curl_exec($handle); 56 | } 57 | else 58 | { 59 | return false; 60 | } 61 | } 62 | 63 | /** 64 | * Returns boolean value of a php.ini setting 65 | * @param string $ini_name Setting name 66 | * @return boolean Setting value 67 | */ 68 | private static function iniGetBool($ini_name) { 69 | $ini_value = ini_get($ini_name); 70 | 71 | switch (strtolower($ini_value)) 72 | { 73 | case 'on': 74 | case 'yes': 75 | case 'true': 76 | return 'assert.active' !== $ini_name; 77 | 78 | case 'stdout': 79 | case 'stderr': 80 | return 'display_errors' === $ini_name; 81 | 82 | default: 83 | return (bool) (int) $ini_value; 84 | } 85 | } 86 | } 87 | --------------------------------------------------------------------------------