├── .env.example ├── .github └── workflows │ └── php.yml ├── .gitignore ├── LICENSE ├── README.md ├── composer.json ├── composer.lock ├── docker-compose.yml ├── docker └── php │ └── 8.1 │ └── Dockerfile ├── examples ├── app │ ├── GetAppList.txt │ └── appDetails.txt ├── global │ └── convertId.txt ├── group │ └── GetGroupSummary.txt ├── item │ └── GetPlayerItems.txt ├── news │ └── GetNewsForApp.txt ├── package │ └── packageDetails.txt ├── player │ ├── GetBadges.txt │ ├── GetCommunityBadgeProgress.txt │ ├── GetOwnedGames.txt │ ├── GetPlayerLevelDetails.txt │ ├── GetRecentlyPlayedGames.txt │ ├── GetSteamLevel.txt │ └── IsPlayingSharedGame.txt └── user │ ├── GetFriendList.txt │ ├── GetPlayerBans.txt │ ├── GetPlayerSummaries.txt │ ├── ResolveVanityURL.txt │ └── stats │ ├── GetGlobalAchievementPercentageForApp.txt │ ├── GetPlayerAchievements.txt │ ├── GetSchemaForGame.txt │ ├── GetUserStatsForGame.txt │ └── GetUserStatsForGameAll.txt ├── phpunit.xml ├── rector.php ├── src ├── Syntax │ └── SteamApi │ │ ├── Client.php │ │ ├── Containers │ │ ├── Achievement.php │ │ ├── App.php │ │ ├── BaseContainer.php │ │ ├── Game.php │ │ ├── GameDetails.php │ │ ├── Group.php │ │ ├── Group │ │ │ ├── Details.php │ │ │ └── MemberDetails.php │ │ ├── Id.php │ │ ├── Item.php │ │ ├── Package.php │ │ ├── Player.php │ │ └── Player │ │ │ └── Level.php │ │ ├── Exceptions │ │ ├── ApiArgumentRequired.php │ │ ├── ApiCallFailedException.php │ │ ├── ClassNotFoundException.php │ │ ├── InvalidApiKeyException.php │ │ └── UnrecognizedId.php │ │ ├── Facades │ │ └── SteamApi.php │ │ ├── Inventory.php │ │ ├── Resources │ │ └── countries.json │ │ ├── Steam │ │ ├── App.php │ │ ├── Group.php │ │ ├── Item.php │ │ ├── News.php │ │ ├── Package.php │ │ ├── Player.php │ │ ├── User.php │ │ └── User │ │ │ └── Stats.php │ │ ├── SteamApiServiceProvider.php │ │ └── SteamId.php └── config │ ├── .gitkeep │ └── config.php └── tests ├── AppTest.php ├── BaseTester.php ├── GroupTest.php ├── IdTest.php ├── ItemTest.php ├── NewsTest.php ├── PackageTest.php ├── PlayerTest.php ├── UserStatsTest.php └── UserTest.php /.env.example: -------------------------------------------------------------------------------- 1 | # Steam API key for testing 2 | apiKey= 3 | XDEBUG_MODE=coverage 4 | PHP_VERSION=8.1 5 | -------------------------------------------------------------------------------- /.github/workflows/php.yml: -------------------------------------------------------------------------------- 1 | name: Unit Tests 2 | 3 | on: 4 | push: 5 | workflow_dispatch: 6 | schedule: 7 | - cron: "0 0 1 * *" 8 | 9 | jobs: 10 | test: 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | php: [ '8.1', '8.2', '8.3' ] 15 | continue-on-error: true 16 | steps: 17 | - uses: actions/checkout@v4 18 | 19 | - name: Setup PHP 20 | uses: shivammathur/setup-php@v2 21 | with: 22 | php-version: ${{ matrix.php }} 23 | extensions: bcmath, simplexml, libxml, curl, json, sodium 24 | coverage: pcov 25 | 26 | - name: Mitigate Composer lock issues 27 | run: composer update 28 | 29 | - name: PHP ${{ matrix.php }} - Validate composer.json and composer.lock 30 | run: composer validate 31 | 32 | - name: PHP ${{ matrix.php }} - Cache Composer packages 33 | id: composer-cache 34 | uses: actions/cache@v4 35 | with: 36 | path: vendor 37 | key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }} 38 | restore-keys: | 39 | ${{ runner.os }}-php- 40 | 41 | - name: PHP ${{ matrix.php }} - Install dependencies 42 | if: steps.composer-cache.outputs.cache-hit != 'true' 43 | run: composer install 44 | 45 | - name: PHP ${{ matrix.php }} - Run coverage test suite 46 | env: 47 | apiKey: ${{ secrets.STEAM_API_KEY }} 48 | run: composer run-script test 49 | 50 | - name: Publish Test Coverage 51 | uses: paambaati/codeclimate-action@v6 52 | if: ${{ matrix.php }} == '8.1' && ${{ github.ref }} == 'master' 53 | env: 54 | apiKey: ${{ secrets.STEAM_API_KEY }} 55 | CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }} 56 | XDEBUG_MODE: coverage 57 | with: 58 | coverageCommand: composer run-script coverage 59 | coverageLocations: ${{github.workspace}}/coverage.clover:clover 60 | debug: true 61 | 62 | - uses: sarisia/actions-status-discord@v1 63 | if: ${{ failure() }} 64 | with: 65 | status: ${{ job.status }} 66 | webhook: ${{ secrets.DISCORD_WEBHOOK }} 67 | title: "${{ matrix.php }}: Tests failed." 68 | color: 'red' 69 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | /vendor 3 | /coverage 4 | composer.phar 5 | .DS_Store 6 | ocular.phar 7 | uploadTests.sh 8 | .env 9 | .phpunit.* 10 | *.clover 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Travis Blasingame 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Steam API 2 | 3 | [![Join the chat at https://gitter.im/syntaxerrors/Steam](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/syntaxerrors/Steam?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) 4 | 5 | ![Unit Tests](https://github.com/syntaxerrors/Steam/workflows/Unit%20Tests/badge.svg) 6 | [![Maintainability](https://api.codeclimate.com/v1/badges/eb99d8de80e750fd4c27/maintainability)](https://codeclimate.com/github/syntaxerrors/Steam/maintainability) 7 | 8 | [![Latest Stable Version](https://poser.pugx.org/syntax/steam-api/v/stable.svg)](https://packagist.org/packages/syntax/steam-api) 9 | [![Total Downloads](https://poser.pugx.org/syntax/steam-api/downloads.svg)](https://packagist.org/packages/syntax/steam-api) 10 | [![License](https://poser.pugx.org/syntax/steam-api/license.svg)](https://packagist.org/packages/syntax/steam-api) 11 | 12 | **Version Support** 13 | `Laravel >= 10.0` 14 | `PHP >= 8.1` 15 | 16 | - [Installation](#installation) 17 | - [Usage](#usage) 18 | - [Contributors](#contributors) 19 | 20 | This package provides an easy way to get details from the Steam API service. The services it can access are: 21 | 22 | - `ISteamNews` 23 | - `IPlayerService` 24 | - `ISteamUser` 25 | - `ISteamUserStats` 26 | - `ISteamApp` 27 | 28 | ## Installation 29 | 30 | Begin by installing this package with composer. 31 | 32 | "require": { 33 | "syntax/steam-api": "3.*" 34 | } 35 | 36 | Next, update composer from the terminal. 37 | 38 | composer update syntax/steam-api 39 | 40 | > Alternately, you can run "composer require syntax/steam-api:dev-master" from the command line. 41 | 42 | Lastly, publish the config file. You can get your API key from [Steam](http://steamcommunity.com/dev/apikey). 43 | 44 | php artisan vendor:publish --provider="Syntax\SteamApi\SteamApiServiceProvider" 45 | 46 | ## Usage 47 | 48 | ```php 49 | use Syntax\SteamApi\Facades\SteamApi; 50 | 51 | /** Get Portal 2 */ 52 | $apps = SteamApi::app()->appDetails(620); 53 | 54 | echo $app->first()->name; 55 | ``` 56 | 57 | Each service from the Steam API has its own methods you can use. 58 | 59 | - [Global](#global) 60 | - [News](#news) 61 | - [Player](#player) 62 | - [User](#user) 63 | - [User Stats](#user-stats) 64 | - [App](#app) 65 | - [Package](#package) 66 | - [Item](#item) 67 | - [Group](#group) 68 | 69 | ### Global 70 | These are methods that are available to each service. 71 | 72 | #### convertId 73 | This will convert the given steam ID to each type of steam ID (64 bit, 32 bit and steam ID3). 74 | 75 | ##### Arguments 76 | 77 | Name | Type | Description | Required | Default 78 | -----|------|-------------|----------|--------- 79 | id| string | The id you want to convert | Yes 80 | format | string | The format you want back. | No | null 81 | 82 | > Possible formats are ID64, id64, 64, ID32, id32, 32, ID3, id3 and 3. 83 | 84 | ##### Example usage 85 | 86 | ```php 87 | SteamApi::convertId($id, $format); 88 | ``` 89 | 90 | > Example Output: [convertId](./examples/global/convertId.txt) 91 | 92 | ### News 93 | The [Steam News](https://developer.valvesoftware.com/wiki/Steam_Web_API#GetNewsForApp_.28v0002.29) web api is used to get articles for games. 94 | 95 | ```php 96 | SteamApi::news() 97 | ``` 98 | 99 | #### GetNewsForApp 100 | This method will get the news articles for a given app ID. It has three parameters. 101 | 102 | ##### Arguments 103 | 104 | Name | Type | Description | Required | Default 105 | -----|------|-------------|----------|--------- 106 | appId| int | The id for the app you want news on | Yes 107 | count | int | The number of news items to return | No | 5 108 | maxlength | int | The maximum number of characters to return | No | null 109 | 110 | ##### Example usage 111 | 112 | ```php 113 | GetNewsForApp($appId, 5, 500)->newsitems; 115 | ?> 116 | ``` 117 | 118 | > Example Output: [GetNewsForApp](./examples/news/GetNewsForApp.txt) 119 | 120 | ### Player 121 | The [Player Service](https://developer.valvesoftware.com/wiki/Steam_Web_API#GetOwnedGames_.28v0001.29) is used to get details on players. 122 | 123 | When instantiating the player class, you are required to pass a steamId or Steam community ID. 124 | 125 | ```php 126 | SteamApi::player($steamId) 127 | ``` 128 | 129 | #### GetSteamLevel 130 | This method will return the level of the Steam user given. It simply returns the integer of their current level. 131 | 132 | 133 | > Example Output: [GetSteamLevel](./examples/player/GetSteamLevel.txt) 134 | 135 | #### GetPlayerLevelDetails 136 | This will return a Syntax\Containers\Player_Level object with full details for the players level. 137 | 138 | 139 | > Example Output: [GetPlayerLevelDetails](./examples/player/GetPlayerLevelDetails.txt) 140 | 141 | #### GetBadges 142 | This call will give you a list of the badges that the player currently has. There is currently no schema for badges, so all you will get is the ID and details. 143 | 144 | 145 | > Example Output: [GetBadges](./examples/player/GetBadges.txt) 146 | 147 | #### GetOwnedGames 148 | GetOwnedGames returns a list of games a player owns along with some playtime information, if the profile is publicly visible. Private, friends-only, and other privacy settings are not supported unless you are asking for your own personal details (i.e. the WebAPI key you are using is linked to the steamID you are requesting). 149 | 150 | ##### Arguments 151 | 152 | Name | Type | Description | Required | Default 153 | -----|------|-------------|----------|--------- 154 | includeAppInfo| boolean | Whether or not to include game details | No | true 155 | includePlayedFreeGames | boolean | Whether or not to include free games | No | false 156 | appIdsFilter | array | An array of appIds. These will be the only ones returned if the user has them | No | array() 157 | 158 | 159 | > Example Output: [GetOwnedGames](./examples/player/GetOwnedGames.txt) 160 | 161 | #### GetRecentlyPlayedGames 162 | GetRecentlyPlayedGames returns a list of games a player has played in the last two weeks, if the profile is publicly visible. Private, friends-only, and other privacy settings are not supported unless you are asking for your own personal details (i.e. the WebAPI key you are using is linked to the steamID you are requesting). 163 | 164 | ##### Arguments 165 | 166 | Name | Type | Description | Required | Default 167 | -----|------|-------------|----------|--------- 168 | count| int | The number of games to return | No | null 169 | 170 | > Example Output: [GetRecentlyPlayedGames](./examples/player/GetRecentlyPlayedGames.txt) 171 | 172 | #### IsPlayingSharedGame 173 | IsPlayingSharedGame returns the original owner's SteamID if a borrowing account is currently playing this game. If the game is not borrowed or the borrower currently doesn't play this game, the result is always 0. 174 | 175 | ##### Arguments 176 | 177 | Name | Type | Description | Required | Default 178 | -----|------|-------------|----------|--------- 179 | appId| int | The game to check for | Yes | 180 | 181 | 182 | > Example Output: [IsPlayingSharedGame](./examples/player/IsPlayingSharedGame.txt) 183 | 184 | ### User 185 | The [User](https://developer.valvesoftware.com/wiki/Steam_Web_API#GetFriendList_.28v0001.29) WebAPI call is used to get details about the user specifically. 186 | 187 | When instantiating the user class, you are required to pass at least one steamId or steam community ID. 188 | 189 | ```php 190 | SteamApi::user($steamId) 191 | ``` 192 | 193 | #### ResolveVanityURL 194 | This will return details on the user from their display name. 195 | 196 | ##### Arguments 197 | 198 | Name | Type | Description | Required | Default 199 | -----|------|-------------|----------|--------- 200 | displayName| string | The display name to get the steam ID for. In `http://steamcommunity.com/id/gabelogannewell` it would be `gabelogannewell`. | Yes | NULL 201 | 202 | ```php 203 | $player = SteamApi::user($steamId)->ResolveVanityURL('gabelogannewell'); 204 | ``` 205 | 206 | > Example Output: [ResolveVanityURL](./examples/user/ResolveVanityURL.txt) 207 | 208 | #### GetPlayerSummaries 209 | This will return details on one or more users. 210 | 211 | ##### Arguments 212 | 213 | Name | Type | Description | Required | Default 214 | -----|------|-------------|----------|--------- 215 | steamId| int[] | An array of (or singular) steam ID(s) to get details for | No | Steam ID passed to user() 216 | 217 | ```php 218 | // One user 219 | $steamId = 76561197960287930; 220 | $player = SteamApi::user($steamId)->GetPlayerSummaries()[0]; 221 | 222 | // Several users 223 | $steamIds = [76561197960287930, 76561197968575517] 224 | $players = SteamApi::user($steamIds)->GetPlayerSummaries(); 225 | ``` 226 | 227 | > Example Output: [GetPlayerSummaries](./examples/user/GetPlayerSummaries.txt) 228 | 229 | #### GetFriendList 230 | Returns the friend list of any Steam user, provided his Steam Community profile visibility is set to "Public". 231 | 232 | ##### Arguments 233 | 234 | Name | Type | Description | Required | Default 235 | -----|------|-------------|----------|--------- 236 | relationship| string (all or friend) | The type of friends to get | No | all 237 | summaries| bool (true or false) | To return the friend player summaries, or only steamIds | No | true 238 | 239 | Once the list of friends is gathered, if `summaries` is not set to `false`; it is passed through [GetPlayerSummaries](#GetPlayerSummaries). This allows you to get back a collection of Player objects. 240 | 241 | 242 | > Example Output: [GetFriendList](./examples/user/GetFriendList.txt) 243 | 244 | #### GetPlayerBans 245 | Returns the possible bans placed on the provided steam ID(s). 246 | 247 | ##### Arguments 248 | 249 | Name | Type | Description | Required | Default 250 | -----|------|-------------|----------|--------- 251 | steamId| int[] | An array of (or singular) steam id(s) to get details for | No | Steam id passed to user() 252 | 253 | 254 | > Example Output: [GetPlayerBans](./examples/user/GetPlayerBans.txt) 255 | 256 | ### User Stats 257 | The [User Stats](https://developer.valvesoftware.com/wiki/Steam_Web_API#GetPlayerAchievements_.28v0001.29) WebAPI call is used to get details about a user's gaming. 258 | 259 | When instantiating the user stats class, you are required to pass a steamID or Steam community ID. 260 | 261 | ```php 262 | SteamApi::userStats($steamId) 263 | ``` 264 | 265 | #### GetPlayerAchievements 266 | Returns a list of achievements for this user by app ID. 267 | 268 | ##### Arguments 269 | 270 | Name | Type | Description | Required | Default 271 | -----|------|-------------|----------|--------- 272 | appId| int | The id of the game you want the user's achievements in | Yes | 273 | 274 | 275 | > Example Output: [GetPlayerAchievements](./examples/user/stats/GetPlayerAchievements.txt) 276 | 277 | #### GetGlobalAchievementPercentagesForApp 278 | This method will return a list of all achievements for the specified game and the percentage of all users that have unlocked each achievement. 279 | 280 | ##### Arguments 281 | 282 | Name | Type | Description | Required | Default 283 | -----|------|-------------|----------|--------- 284 | appId| int | The ID of the game you want the user's achievements in | Yes | 285 | 286 | 287 | > Example Output: [GetGlobalAchievementPercentagesForApp](./examples/user/stats/GetGlobalAchievementPercentageForApp.txt) 288 | 289 | #### GetUserStatsForGame 290 | Returns a list of achievements for this user by app ID. 291 | 292 | ##### Arguments 293 | 294 | Name | Type | Description | Required | Default 295 | -----|------|-------------|----------|--------- 296 | appId| int | The ID of the game you want the user's achievements in | Yes | 297 | all| boolean | If you want all stats and not just the achievements set to true.| No | FALSE 298 | 299 | 300 | > Example Output: [GetUserStatsForGame](./examples/user/stats/GetUserStatsForGame.txt) | [GetUserStatsForGame (all)](./examples/user/stats/GetUserStatsForGameAll.txt) 301 | 302 | #### GetSchemaForGame 303 | Returns a list of game details, including achievements and stats. 304 | 305 | ##### Arguments 306 | 307 | Name | Type | Description | Required | Default 308 | -----|------|-------------|----------|--------- 309 | appId| int | The ID of the game you want the details for. | Yes | 310 | 311 | 312 | > Example Output: [GetSchemaForGame](./examples/user/stats/GetSchemaForGame.txt) 313 | 314 | ### App 315 | This area will get details for games. 316 | 317 | ```php 318 | SteamApi::app() 319 | ``` 320 | 321 | #### appDetails 322 | This gets all the details for a game. This is most of the information from the store page of a game. 323 | 324 | ##### Arguments 325 | 326 | Name | Type | Description | Required | Default 327 | -----|------|-------------|----------|--------- 328 | appIds| int[] | The ids of the games you want details for | Yes | 329 | cc | string | The cc is the country code, you can get appropriate currency values according to [ISO 3166-1](https://wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements) | No | 330 | l | string | The l is the language parameter, you can get the appropriate language according to [ISO 639-1](https://wikipedia.org/wiki/List_of_ISO_639-1_codes) | No | 331 | 332 | 333 | > Example Output: [appDetails](./examples/app/appDetails.txt) 334 | 335 | #### GetAppList 336 | This method will return an array of app objects directly from Steam. It includes the appID and the app name. 337 | 338 | > Example Output: [GetAppList](./examples/app/GetAppList.txt) 339 | 340 | ### Package 341 | This method will get details for packages. 342 | 343 | ```php 344 | SteamApi::package() 345 | ``` 346 | 347 | #### packageDetails 348 | This gets all the details for a package. This is most of the information from the store page of a package. 349 | 350 | ##### Arguments 351 | 352 | Name | Type | Description | Required | Default 353 | -----|------|-------------|----------|--------- 354 | packIds| int[] | The ids of the packages you want details for | Yes | 355 | cc | string | The cc is the country code, you can get appropriate currency values according to [ISO 3166-1](https://wikipedia.org/wiki/ISO_3166-1) | No | 356 | l | string | The l is the language parameter, you can get the appropriate language according to [ISO 639-1](https://wikipedia.org/wiki/ISO_639-1) (If there is one) | No | 357 | 358 | 359 | > Example Output: [packageDetails](./examples/package/packageDetails.txt) 360 | 361 | ### Item 362 | This method will get user inventory for item. 363 | 364 | ```php 365 | SteamApi::item() 366 | ``` 367 | 368 | #### GetPlayerItems 369 | This gets all the item for a user inventory. 370 | 371 | ##### Arguments 372 | 373 | Name | Type | Description | Required | Default 374 | -----|------|-------------|----------|--------- 375 | appId| int | The appid of the game you want for | Yes | 376 | steamid | int | The steamid of the Steam user you want for | Yes | 377 | 378 | ⚠️ **Now known to supports**:`440`, `570`, `620`, `730`, `205790`, `221540`, `238460` 379 | 380 | > Example Output: [GetPlayerItems](./examples/item/GetPlayerItems.txt) 381 | 382 | ### Group 383 | This service is used to get details on a Steam group. 384 | 385 | ```php 386 | SteamApi::group() 387 | ``` 388 | 389 | #### GetGroupSummary 390 | This method will get the details for a group. 391 | 392 | ##### Arguments 393 | 394 | Name | Type | Description | Required | Default 395 | -----|------|-------------|----------|--------- 396 | group| string or int | The ID or the name of the group. | Yes 397 | 398 | ##### Example usage 399 | 400 | ```php 401 | GetGroupSummary('Valve'); 403 | ?> 404 | ``` 405 | 406 | > Example Output: [GetGroupSummary](./examples/group/GetGroupSummary.txt) 407 | 408 | ## Testing the Steam Package 409 | 410 | A Steam API key must be provided or most tests will fail. 411 | 412 | **Run Tests** 413 | ``` 414 | # Build container 415 | docker-compose build 416 | 417 | # Install dependancies 418 | docker-compose run --rm php composer install 419 | 420 | # Run tests (assumes apiKey is set in .env file) 421 | docker-compose run --rm php composer test 422 | 423 | # Or with the apiKey inline 424 | docker-compose run --rm -e api=YOUR_STEAM_API_KEY php composer test 425 | 426 | # With coverage 427 | docker-compose run --rm php composer coverage 428 | 429 | # Play around 430 | docker-compose run --rm php bash 431 | ``` 432 | 433 | ## Contributors 434 | - [Stygiansabyss](https://github.com/stygiansabyss) 435 | - [nicekiwi](https://github.com/nicekiwi) 436 | - [rannmann](https://github.com/rannmann) 437 | - [Amegatron](https://github.com/Amegatron) 438 | - [mjmarianetti](https://github.com/mjmarianetti) 439 | - [MaartenStaa](https://github.com/MaartenStaa) 440 | - [JRizzle88](https://github.com/JRizzle88) 441 | - [jastend](https://github.com/jastend) 442 | - [Teakowa](https://github.com/Teakowa) 443 | - [Ben Sherred](https://github.com/bensherred) 444 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "syntax/steam-api", 3 | "description": "A steam-api client for Laravel 10+", 4 | "version": "3.0.0", 5 | "license": "MIT", 6 | "authors": [ 7 | { 8 | "name": "Stygian", 9 | "email": "stygian.warlock.v2@gmail.com" 10 | } 11 | ], 12 | "require": { 13 | "php": "^8.1", 14 | "laravel/framework": "^10.0|^11.0", 15 | "guzzlehttp/guzzle": "^7.8", 16 | "ext-bcmath": "*", 17 | "ext-simplexml": "*", 18 | "ext-libxml": "*", 19 | "ext-curl": "*", 20 | "ext-json": "*" 21 | }, 22 | "require-dev": { 23 | "phpunit/phpunit": "^10.5|^11.0", 24 | "orchestra/testbench": "^8.0", 25 | "vlucas/phpdotenv": "^5.6", 26 | "rector/rector": "^1.0" 27 | }, 28 | "autoload": { 29 | "psr-4": { 30 | "Syntax\\SteamApi\\": "src/Syntax/SteamApi" 31 | } 32 | }, 33 | "extra": { 34 | "laravel": { 35 | "providers": [ 36 | "Syntax\\SteamApi\\SteamApiServiceProvider" 37 | ] 38 | } 39 | }, 40 | "minimum-stability": "stable", 41 | "scripts": { 42 | "test": "XDEBUG_MODE=off vendor/bin/phpunit -d memory_limit=512M", 43 | "coverage": "XDEBUG_MODE=coverage vendor/bin/phpunit -d memory_limit=512M --coverage-clover=coverage.clover", 44 | "coverage:html": "XDEBUG_MODE=coverage vendor/bin/phpunit -d memory_limit=512M --coverage-html ./coverage" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | php: 3 | build: ./docker/php/${PHP_VERSION:-8.1} 4 | volumes: 5 | - $PWD:/srv/app:delegated 6 | -------------------------------------------------------------------------------- /docker/php/8.1/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:8.1-alpine 2 | 3 | # Install deps 4 | RUN apk --update add linux-headers bash autoconf build-base wget curl git zip unzip zlib-dev shadow libpq binutils-dev 5 | 6 | # Install PHP extensions 7 | RUN docker-php-ext-install exif pcntl bcmath 8 | 9 | RUN pecl install xdebug \ 10 | && docker-php-ext-enable xdebug 11 | 12 | # Get latest Composer 13 | COPY --from=composer:latest /usr/bin/composer /usr/bin/composer 14 | 15 | # Set Working Dir 16 | WORKDIR /srv/app 17 | -------------------------------------------------------------------------------- /examples/app/GetAppList.txt: -------------------------------------------------------------------------------- 1 | Array 2 | ( 3 | [0] => stdClass Object 4 | ( 5 | [appid] => 5 6 | [name] => Dedicated Server 7 | ) 8 | 9 | [1] => stdClass Object 10 | ( 11 | [appid] => 7 12 | [name] => Steam Client 13 | ) 14 | 15 | [2] => stdClass Object 16 | ( 17 | [appid] => 8 18 | [name] => winui2 19 | ) 20 | 21 | [3] => stdClass Object 22 | ( 23 | [appid] => 10 24 | [name] => Counter-Strike 25 | ) 26 | 27 | [4] => stdClass Object 28 | ( 29 | [appid] => 20 30 | [name] => Team Fortress Classic 31 | ) 32 | 33 | [5] => stdClass Object 34 | ( 35 | [appid] => 30 36 | [name] => Day of Defeat 37 | ) 38 | 39 | ) 40 | -------------------------------------------------------------------------------- /examples/app/appDetails.txt: -------------------------------------------------------------------------------- 1 | Array 2 | ( 3 | [0] => Syntax\SteamApi\Containers\App Object 4 | ( 5 | [id] => 620 6 | [type] => game 7 | [name] => Portal 2 8 | [controllerSupport] => full 9 | [description] => Portal 2 draws from the award-winning formula of innovative gameplay, story, and music that earned the original Portal over 70 industry accolades and created a cult following.

The single-player portion of Portal 2 introduces a cast of dynamic new characters, a host of fresh puzzle elements, and a much larger set of devious test chambers. Players will explore never-before-seen areas of the Aperture Science Labs and be reunited with GLaDOS, the occasionally murderous computer companion who guided them through the original game.

The game’s two-player cooperative mode features its own entirely separate campaign with a unique story, test chambers, and two new player characters. This new mode forces players to reconsider everything they thought they knew about portals. Success will require them to not just act cooperatively, but to think cooperatively.

Product Features
10 | [about] => Portal 2 draws from the award-winning formula of innovative gameplay, story, and music that earned the original Portal over 70 industry accolades and created a cult following.

The single-player portion of Portal 2 introduces a cast of dynamic new characters, a host of fresh puzzle elements, and a much larger set of devious test chambers. Players will explore never-before-seen areas of the Aperture Science Labs and be reunited with GLaDOS, the occasionally murderous computer companion who guided them through the original game.

The game’s two-player cooperative mode features its own entirely separate campaign with a unique story, test chambers, and two new player characters. This new mode forces players to reconsider everything they thought they knew about portals. Success will require them to not just act cooperatively, but to think cooperatively.

Product Features
11 | [fullgame] => stdClass Object 12 | ( 13 | [appid] => 14 | [name] => No parent game found 15 | ) 16 | 17 | [header] => https://steamcdn-a.akamaihd.net/steam/apps/620/header.jpg?t=1512411524 18 | [website] => http://www.thinkwithportals.com/ 19 | [pcRequirements] => stdClass Object 20 | ( 21 | [minimum] => Minimum:
22 | ) 23 | 24 | [legal] => None 25 | [developers] => Illuminate\Support\Collection Object 26 | ( 27 | [items:protected] => Array 28 | ( 29 | [0] => Valve 30 | ) 31 | 32 | ) 33 | 34 | [publishers] => Illuminate\Support\Collection Object 35 | ( 36 | [items:protected] => Array 37 | ( 38 | [0] => Valve 39 | ) 40 | 41 | ) 42 | 43 | [price] => stdClass Object 44 | ( 45 | [currency] => CHF 46 | [initial] => 1050 47 | [final] => 1050 48 | [discount_percent] => 0 49 | ) 50 | 51 | [platforms] => stdClass Object 52 | ( 53 | [windows] => 1 54 | [mac] => 1 55 | [linux] => 1 56 | ) 57 | 58 | [metacritic] => stdClass Object 59 | ( 60 | [score] => 95 61 | [url] => http://www.metacritic.com/game/pc/portal-2?ftag=MCD-06-10aaa1f 62 | ) 63 | 64 | [categories] => Illuminate\Support\Collection Object 65 | ( 66 | [items:protected] => Array 67 | ( 68 | [0] => stdClass Object 69 | ( 70 | [id] => 2 71 | [description] => Single-player 72 | ) 73 | 74 | [1] => stdClass Object 75 | ( 76 | [id] => 9 77 | [description] => Co-op 78 | ) 79 | 80 | [2] => stdClass Object 81 | ( 82 | [id] => 22 83 | [description] => Steam Achievements 84 | ) 85 | 86 | [3] => stdClass Object 87 | ( 88 | [id] => 28 89 | [description] => Full controller support 90 | ) 91 | 92 | [4] => stdClass Object 93 | ( 94 | [id] => 29 95 | [description] => Steam Trading Cards 96 | ) 97 | 98 | [5] => stdClass Object 99 | ( 100 | [id] => 13 101 | [description] => Captions available 102 | ) 103 | 104 | [6] => stdClass Object 105 | ( 106 | [id] => 30 107 | [description] => Steam Workshop 108 | ) 109 | 110 | [7] => stdClass Object 111 | ( 112 | [id] => 23 113 | [description] => Steam Cloud 114 | ) 115 | 116 | [8] => stdClass Object 117 | ( 118 | [id] => 15 119 | [description] => Stats 120 | ) 121 | 122 | [9] => stdClass Object 123 | ( 124 | [id] => 17 125 | [description] => Includes level editor 126 | ) 127 | 128 | [10] => stdClass Object 129 | ( 130 | [id] => 14 131 | [description] => Commentary available 132 | ) 133 | 134 | ) 135 | 136 | ) 137 | 138 | [genres] => Illuminate\Support\Collection Object 139 | ( 140 | [items:protected] => Array 141 | ( 142 | [0] => stdClass Object 143 | ( 144 | [id] => 1 145 | [description] => Action 146 | ) 147 | 148 | [1] => stdClass Object 149 | ( 150 | [id] => 25 151 | [description] => Adventure 152 | ) 153 | 154 | ) 155 | 156 | ) 157 | 158 | [release] => stdClass Object 159 | ( 160 | [coming_soon] => 161 | [date] => 18 Apr, 2011 162 | ) 163 | 164 | [requiredAge] => 0 165 | [isFree] => 166 | [shortDescription] => The "Perpetual Testing Initiative" has been expanded to allow you to design co-op puzzles for you and your friends! 167 | [supportedLanguages] => English*, French*, German*, Spanish*, Czech, Danish, Dutch, Finnish, Hungarian, Italian, Japanese, Korean, Norwegian, Polish, Portuguese, Romanian, Russian*, Simplified Chinese, Swedish, Thai, Traditional Chinese, Turkish
*languages with full audio support 168 | [recommendations] => stdClass Object 169 | ( 170 | [total] => 126510 171 | ) 172 | 173 | [achievements] => stdClass Object 174 | ( 175 | [total] => 51 176 | [highlighted] => Array 177 | ( 178 | [0] => stdClass Object 179 | ( 180 | [name] => Wake Up Call 181 | [path] => https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/620/SURVIVE_CONTAINER_RIDE.jpg 182 | ) 183 | 184 | [1] => stdClass Object 185 | ( 186 | [name] => You Monster 187 | [path] => https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/620/WAKE_UP.jpg 188 | ) 189 | 190 | [2] => stdClass Object 191 | ( 192 | [name] => Undiscouraged 193 | [path] => https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/620/LASER.jpg 194 | ) 195 | 196 | [3] => stdClass Object 197 | ( 198 | [name] => Bridge Over Troubling Water 199 | [path] => https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/620/BRIDGE.jpg 200 | ) 201 | 202 | [4] => stdClass Object 203 | ( 204 | [name] => SaBOTour 205 | [path] => https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/620/BREAK_OUT.jpg 206 | ) 207 | 208 | [5] => stdClass Object 209 | ( 210 | [name] => Stalemate Associate 211 | [path] => https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/620/STALEMATE_ASSOCIATE.jpg 212 | ) 213 | 214 | [6] => stdClass Object 215 | ( 216 | [name] => Tater Tote 217 | [path] => https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/620/ADDICTED_TO_SPUDS.jpg 218 | ) 219 | 220 | [7] => stdClass Object 221 | ( 222 | [name] => Vertically Unchallenged 223 | [path] => https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/620/BLUE_GEL.jpg 224 | ) 225 | 226 | [8] => stdClass Object 227 | ( 228 | [name] => Stranger Than Friction 229 | [path] => https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/620/ORANGE_GEL.jpg 230 | ) 231 | 232 | [9] => stdClass Object 233 | ( 234 | [name] => White Out 235 | [path] => https://steamcdn-a.akamaihd.net/steamcommunity/public/images/apps/620/WHITE_GEL.jpg 236 | ) 237 | 238 | ) 239 | 240 | ) 241 | 242 | [dlc] => Illuminate\Support\Collection Object 243 | ( 244 | [items:protected] => Array 245 | ( 246 | [0] => 323180 247 | ) 248 | 249 | ) 250 | 251 | ) 252 | 253 | ) 254 | -------------------------------------------------------------------------------- /examples/global/convertId.txt: -------------------------------------------------------------------------------- 1 | stdClass Object 2 | ( 3 | [id32] => "STEAM_1:1:9846342" 4 | [id64] => "76561197979958413" 5 | [id3] => "[U:1:19692685]"" 6 | ) 7 | -------------------------------------------------------------------------------- /examples/item/GetPlayerItems.txt: -------------------------------------------------------------------------------- 1 | Array 2 | ( 3 | [numberOfBackpackSlots] => 50 4 | [items] => Illuminate\Support\Collection Object 5 | ( 6 | [items:protected] => Array 7 | ( 8 | [0] => Syntax\SteamApi\Containers\Item Object 9 | ( 10 | [id] => 5787837042 11 | [originalId] => 5787837042 12 | [defIndex] => 166 13 | [level] => 5 14 | [quality] => 6 15 | [quantity] => 1 16 | [inventory] => 0 17 | [origin] => 0 18 | [flags] => Array 19 | ( 20 | [trade] => 21 | [craft] => 1 22 | ) 23 | 24 | [containedItem] => 25 | [style] => 26 | [attributes] => Array 27 | ( 28 | [0] => stdClass Object 29 | ( 30 | [defindex] => 143 31 | [value] => 1406566784 32 | [float_value] => 1842591301632 33 | ) 34 | 35 | [1] => stdClass Object 36 | ( 37 | [defindex] => 746 38 | [value] => 1065353216 39 | [float_value] => 1 40 | ) 41 | 42 | [2] => stdClass Object 43 | ( 44 | [defindex] => 292 45 | [value] => 1115684864 46 | [float_value] => 64 47 | ) 48 | 49 | [3] => stdClass Object 50 | ( 51 | [defindex] => 388 52 | [value] => 1115684864 53 | [float_value] => 64 54 | ) 55 | 56 | [4] => stdClass Object 57 | ( 58 | [defindex] => 153 59 | [value] => 1065353216 60 | [float_value] => 1 61 | ) 62 | 63 | ) 64 | 65 | [custom] => Array 66 | ( 67 | [name] => 68 | [description] => 69 | ) 70 | 71 | ) 72 | 73 | [1] => Syntax\SteamApi\Containers\Item Object 74 | ( 75 | [id] => 5787837069 76 | [originalId] => 5787837069 77 | [defIndex] => 877 78 | [level] => 1 79 | [quality] => 1 80 | [quantity] => 1 81 | [inventory] => 3221225480 82 | [origin] => 13 83 | [flags] => Array 84 | ( 85 | [trade] => 1 86 | [craft] => 1 87 | ) 88 | 89 | [containedItem] => 90 | [style] => 91 | [attributes] => Array 92 | ( 93 | [0] => stdClass Object 94 | ( 95 | [defindex] => 746 96 | [value] => 1065353216 97 | [float_value] => 1 98 | ) 99 | 100 | [1] => stdClass Object 101 | ( 102 | [defindex] => 292 103 | [value] => 1115684864 104 | [float_value] => 64 105 | ) 106 | 107 | [2] => stdClass Object 108 | ( 109 | [defindex] => 388 110 | [value] => 1115684864 111 | [float_value] => 64 112 | ) 113 | 114 | ) 115 | 116 | [custom] => Array 117 | ( 118 | [name] => 119 | [description] => 120 | ) 121 | 122 | ) 123 | 124 | [2] => Syntax\SteamApi\Containers\Item Object 125 | ( 126 | [id] => 5787837070 127 | [originalId] => 5787837070 128 | [defIndex] => 878 129 | [level] => 1 130 | [quality] => 1 131 | [quantity] => 1 132 | [inventory] => 3221225480 133 | [origin] => 13 134 | [flags] => Array 135 | ( 136 | [trade] => 1 137 | [craft] => 1 138 | ) 139 | 140 | [containedItem] => 141 | [style] => 0 142 | [attributes] => Array 143 | ( 144 | [0] => stdClass Object 145 | ( 146 | [defindex] => 746 147 | [value] => 1065353216 148 | [float_value] => 1 149 | ) 150 | 151 | [1] => stdClass Object 152 | ( 153 | [defindex] => 292 154 | [value] => 1115684864 155 | [float_value] => 64 156 | ) 157 | 158 | [2] => stdClass Object 159 | ( 160 | [defindex] => 388 161 | [value] => 1115684864 162 | [float_value] => 64 163 | ) 164 | 165 | ) 166 | 167 | [custom] => Array 168 | ( 169 | [name] => 170 | [description] => 171 | ) 172 | 173 | ) 174 | 175 | [3] => Syntax\SteamApi\Containers\Item Object 176 | ( 177 | [id] => 5787837071 178 | [originalId] => 5787837071 179 | [defIndex] => 879 180 | [level] => 1 181 | [quality] => 1 182 | [quantity] => 1 183 | [inventory] => 3221225480 184 | [origin] => 13 185 | [flags] => Array 186 | ( 187 | [trade] => 1 188 | [craft] => 1 189 | ) 190 | 191 | [containedItem] => 192 | [style] => 0 193 | [attributes] => Array 194 | ( 195 | [0] => stdClass Object 196 | ( 197 | [defindex] => 746 198 | [value] => 1065353216 199 | [float_value] => 1 200 | ) 201 | 202 | [1] => stdClass Object 203 | ( 204 | [defindex] => 292 205 | [value] => 1115684864 206 | [float_value] => 64 207 | ) 208 | 209 | [2] => stdClass Object 210 | ( 211 | [defindex] => 388 212 | [value] => 1115684864 213 | [float_value] => 64 214 | ) 215 | 216 | ) 217 | 218 | [custom] => Array 219 | ( 220 | [name] => 221 | [description] => 222 | ) 223 | 224 | ) 225 | 226 | [4] => Syntax\SteamApi\Containers\Item Object 227 | ( 228 | [id] => 5787837154 229 | [originalId] => 5787837154 230 | [defIndex] => 5867 231 | [level] => 1 232 | [quality] => 6 233 | [quantity] => 1 234 | [inventory] => 3221225473 235 | [origin] => 0 236 | [flags] => Array 237 | ( 238 | [trade] => 1 239 | [craft] => 1 240 | ) 241 | 242 | [containedItem] => 243 | [style] => 0 244 | [attributes] => Array 245 | ( 246 | [0] => stdClass Object 247 | ( 248 | [defindex] => 2046 249 | [value] => 1065353216 250 | [float_value] => 1 251 | ) 252 | 253 | [1] => stdClass Object 254 | ( 255 | [defindex] => 187 256 | [value] => 1121189888 257 | [float_value] => 106 258 | ) 259 | 260 | [2] => stdClass Object 261 | ( 262 | [defindex] => 744 263 | [value] => 1 264 | [float_value] => 1.4012984643248E-45 265 | ) 266 | 267 | [3] => stdClass Object 268 | ( 269 | [defindex] => 528 270 | [value] => 1169641472 271 | [float_value] => 5866 272 | ) 273 | 274 | [4] => stdClass Object 275 | ( 276 | [defindex] => 731 277 | [value] => 1065353216 278 | [float_value] => 1 279 | ) 280 | 281 | [5] => stdClass Object 282 | ( 283 | [defindex] => 815 284 | [value] => 1 285 | [float_value] => 1.4012984643248E-45 286 | ) 287 | 288 | ) 289 | 290 | [custom] => Array 291 | ( 292 | [name] => 293 | [description] => 294 | ) 295 | 296 | ) 297 | 298 | ) 299 | 300 | ) 301 | 302 | ) 303 | 304 | -------------------------------------------------------------------------------- /examples/news/GetNewsForApp.txt: -------------------------------------------------------------------------------- 1 | Array 2 | ( 3 | [0] => stdClass Object 4 | ( 5 | [gid] => 521614150601956190 6 | [title] => Think Of All The Things We Learned In Portal 2 7 | [url] => http://store.steampowered.com/news/externalpost/rps/521614150601956190 8 | [is_external_url] => 1 9 | [author] => contact@rockpapershotgun.com (Philippa Warr) 10 | [contents] => Have you ever idly wondered whether GLaDOS might have been up to more research and testing than the Portal games let on? A study from Florida State University into the effects of playing Portal 2 on a variety of skills won’t do much to ease your fears, then. According to the study, spending eight hours playing Portal 2 is more effective at improving a range of cognitive skills than a dedicated brain training program called Lumosity. … 11 | [feedlabel] => Rock, Paper, Shotgun 12 | [date] => 1412265624 13 | [feedname] => rps 14 | ) 15 | 16 | [1] => stdClass Object 17 | ( 18 | [gid] => 521614150561342440 19 | [title] => Think Of All The Things We Learned In Portal 2 20 | [url] => http://store.steampowered.com/news/externalpost/rps/521614150561342440 21 | [is_external_url] => 1 22 | [author] => contact@rockpapershotgun.com (Philippa Warr) 23 | [contents] => Have you ever idly wondered whether GLaDOS might have been up to more research and testing than the Portal games let on? A study from Florida State University into the effects of playing Portal 2 on a variety of skills won’t do much to ease your fears, then. According to the study, spending eight hours playing Portal 2 is more effective at improving a range of cognitive skills than a dedicated brain training program called Lumosity. … 24 | [feedlabel] => Rock, Paper, Shotgun 25 | [date] => 1412265624 26 | [feedname] => rps 27 | ) 28 | 29 | [2] => stdClass Object 30 | ( 31 | [gid] => 521613514271155690 32 | [title] => Steam Music Player Out Of Beta, Valve s Soundtracks Free 33 | [url] => http://store.steampowered.com/news/externalpost/rps/521613514271155690 34 | [is_external_url] => 1 35 | [author] => contact@rockpapershotgun.com (Graham Smith) 36 | [contents] => In almost every strategy, management or sim game I play, I will immediately turn off the music which comes with the game in favour of my own. That means that Steam Music Player sounds like a good idea to me even if I long ago abandoned mp3s in favour of streaming. The built-in functionality, which lets you browse your music library and control playback from in-game using the Steam overlay, has just left beta after its initial announcement back in February. To celebrate, Valve have made the sound... 37 | [feedlabel] => Rock, Paper, Shotgun 38 | [date] => 1411657215 39 | [feedname] => rps 40 | ) 41 | 42 | [3] => stdClass Object 43 | ( 44 | [gid] => 521612880947759679 45 | [title] => Introducing The Portal Merchandise Workshop 46 | [url] => http://store.steampowered.com/news/externalpost/portal2_blog/521612880947759679 47 | [is_external_url] => 1 48 | [author] => 49 | [contents] => It seems Dota 2 and Team Fortress 2 have launched Merchandise Workshops, where the community can submit, vote on and sell their own non-virtual, actually real t-shirts and posters. And so far, the response from their communities has been overwhelmingly positive. So we thought: What if we applied that same idea, but to a good game, with a smarter, more attractive community? Introducing the Portal Merchandise Workshop, where you can heroes can bravely design their own Portal universe concepts. "Bu... 50 | [feedlabel] => Portal 2 Blog 51 | [date] => 1410973260 52 | [feedname] => portal2_blog 53 | ) 54 | 55 | [4] => stdClass Object 56 | ( 57 | [gid] => 552009088168130714 58 | [title] => Midweek Madness - Portal 2, 75% Off 59 | [url] => http://store.steampowered.com/news/14193/ 60 | [is_external_url] => 61 | [author] => Valve 62 | [contents] => Save 75% on Portal 2 during this week's Midweek Madness*! Portal 2 draws from the award-winning formula of innovative gameplay, story, and music that earned the original Portal over 70 industry accolades and created a cult following. The single-player portion of Portal 2 introduces a cast of dynamic new characters, a host of fresh puzzle elements, and a much larger set of devious test chambers. Players will explore never-before-seen areas of the Aperture Science Labs and be reunited with GLaDOS,... 63 | [feedlabel] => Announcement 64 | [date] => 1408467600 65 | [feedname] => steam_announce 66 | ) 67 | 68 | ) -------------------------------------------------------------------------------- /examples/package/packageDetails.txt: -------------------------------------------------------------------------------- 1 | Array 2 | ( 3 | [0] => stdClass Object 4 | ( 5 | [id] => 76710 6 | [name] => Just Cause 3 XL 7 | [page_image] => https: //steamcdn-a.akamaihd.net/steam/subs/76710/header.jpg?t=1449600260 8 | [header] => https: //steamcdn-a.akamaihd.net/steam/subs/76710/header_ratio.jpg?t=1449600260 9 | [small_logo] => https: //steamcdn-a.akamaihd.net/steam/subs/76710/capsule_231x87.jpg?t=1449600260 10 | [apps] => Array( 11 | [0] => stdClass Object( 12 | [id] => 225540 13 | [name] => Just Cause™ 3 14 | ) 15 | 16 | [1] => stdClass Object( 17 | [id] => 401850 18 | [name] => Just Cause™ 3 DLC: Air, Land & Sea Expansion Pass 19 | ) 20 | 21 | ) 22 | 23 | [page_content] => none[price] => stdClass Object( 24 | [currency] => USD 25 | [initial] => 4499 26 | [final] => 4499 27 | [discount_percent] => 0 28 | [individual] => 4498 29 | ) 30 | 31 | [platforms] => stdClass Object( 32 | [windows] => 1 33 | [mac] => 34 | [linux] => 35 | ) 36 | 37 | [release] => stdClass Object( 38 | [coming_soon] => 39 | [date] => 40 | ) 41 | 42 | [controller] => stdClass Object( 43 | [full_gamepad] => 1 44 | ) 45 | 46 | ) 47 | ) -------------------------------------------------------------------------------- /examples/player/GetBadges.txt: -------------------------------------------------------------------------------- 1 | stdClass Object 2 | ( 3 | [badges] => Array 4 | ( 5 | [0] => stdClass Object 6 | ( 7 | [badgeid] => 16 8 | [level] => 1 9 | [completion_time] => 1404061200 10 | [xp] => 150 11 | [scarcity] => 877623 12 | ) 13 | 14 | [1] => stdClass Object 15 | ( 16 | [badgeid] => 2 17 | [level] => 2 18 | [completion_time] => 1394212133 19 | [xp] => 200 20 | [scarcity] => 1990152 21 | ) 22 | 23 | [2] => stdClass Object 24 | ( 25 | [badgeid] => 13 26 | [level] => 124 27 | [completion_time] => 1268659900 28 | [xp] => 353 29 | [scarcity] => 1243165 30 | ) 31 | 32 | [3] => stdClass Object 33 | ( 34 | [badgeid] => 1 35 | [level] => 4 36 | [completion_time] => 1268659900 37 | [xp] => 200 38 | [scarcity] => 46831294 39 | ) 40 | 41 | ) 42 | 43 | [player_xp] => 903 44 | [player_level] => 9 45 | [player_xp_needed_to_level_up] => 97 46 | [player_xp_needed_current_level] => 900 47 | ) -------------------------------------------------------------------------------- /examples/player/GetCommunityBadgeProgress.txt: -------------------------------------------------------------------------------- 1 | stdClass Object 2 | ( 3 | [quests] => Array 4 | ( 5 | [0] => stdClass Object 6 | ( 7 | [questid] => 101 8 | [completed] => 1 9 | ) 10 | 11 | [1] => stdClass Object 12 | ( 13 | [questid] => 102 14 | [completed] => 1 15 | ) 16 | 17 | [2] => stdClass Object 18 | ( 19 | [questid] => 103 20 | [completed] => 1 21 | ) 22 | 23 | [3] => stdClass Object 24 | ( 25 | [questid] => 104 26 | [completed] => 1 27 | ) 28 | 29 | [4] => stdClass Object 30 | ( 31 | [questid] => 105 32 | [completed] => 1 33 | ) 34 | 35 | [5] => stdClass Object 36 | ( 37 | [questid] => 106 38 | [completed] => 39 | ) 40 | 41 | [6] => stdClass Object 42 | ( 43 | [questid] => 108 44 | [completed] => 1 45 | ) 46 | 47 | [7] => stdClass Object 48 | ( 49 | [questid] => 109 50 | [completed] => 1 51 | ) 52 | 53 | [8] => stdClass Object 54 | ( 55 | [questid] => 110 56 | [completed] => 1 57 | ) 58 | 59 | [9] => stdClass Object 60 | ( 61 | [questid] => 111 62 | [completed] => 1 63 | ) 64 | 65 | [10] => stdClass Object 66 | ( 67 | [questid] => 112 68 | [completed] => 1 69 | ) 70 | 71 | [11] => stdClass Object 72 | ( 73 | [questid] => 113 74 | [completed] => 1 75 | ) 76 | 77 | [12] => stdClass Object 78 | ( 79 | [questid] => 114 80 | [completed] => 1 81 | ) 82 | 83 | [13] => stdClass Object 84 | ( 85 | [questid] => 115 86 | [completed] => 1 87 | ) 88 | 89 | [14] => stdClass Object 90 | ( 91 | [questid] => 116 92 | [completed] => 1 93 | ) 94 | 95 | [15] => stdClass Object 96 | ( 97 | [questid] => 117 98 | [completed] => 1 99 | ) 100 | 101 | [16] => stdClass Object 102 | ( 103 | [questid] => 118 104 | [completed] => 1 105 | ) 106 | 107 | [17] => stdClass Object 108 | ( 109 | [questid] => 119 110 | [completed] => 1 111 | ) 112 | 113 | [18] => stdClass Object 114 | ( 115 | [questid] => 120 116 | [completed] => 1 117 | ) 118 | 119 | [19] => stdClass Object 120 | ( 121 | [questid] => 121 122 | [completed] => 1 123 | ) 124 | 125 | [20] => stdClass Object 126 | ( 127 | [questid] => 122 128 | [completed] => 1 129 | ) 130 | 131 | [21] => stdClass Object 132 | ( 133 | [questid] => 123 134 | [completed] => 1 135 | ) 136 | 137 | [22] => stdClass Object 138 | ( 139 | [questid] => 124 140 | [completed] => 141 | ) 142 | 143 | [23] => stdClass Object 144 | ( 145 | [questid] => 125 146 | [completed] => 147 | ) 148 | 149 | [24] => stdClass Object 150 | ( 151 | [questid] => 126 152 | [completed] => 1 153 | ) 154 | 155 | [25] => stdClass Object 156 | ( 157 | [questid] => 127 158 | [completed] => 1 159 | ) 160 | 161 | ) 162 | 163 | ) -------------------------------------------------------------------------------- /examples/player/GetOwnedGames.txt: -------------------------------------------------------------------------------- 1 | Syntax\SteamApi\Collection Object 2 | ( 3 | [items:protected] => Array 4 | ( 5 | [104] => Syntax\SteamApi\Containers\Game Object 6 | ( 7 | [appId] => 251570 8 | [name] => 7 Days to Die 9 | [playtimeTwoWeeks] => 0 10 | [playtimeTwoWeeksReadable] => 0 minutes 11 | [playtimeForever] => 12 12 | [playtimeForeverReadable] => 12 minutes 13 | [icon] => http://media.steampowered.com/steamcommunity/public/images/apps/251570/c8f826b116770525b68e7b4e37ad83ca044ae760.jpg 14 | [logo] => http://media.steampowered.com/steamcommunity/public/images/apps/251570/d2f0fb2b63983bf5c5a1b627b59ce754788308df.jpg 15 | [header] => http://cdn.steampowered.com/v/gfx/apps/251570/header.jpg 16 | [hasCommunityVisibleStats] => 1 17 | ) 18 | 19 | [32] => Syntax\SteamApi\Containers\Game Object 20 | ( 21 | [appId] => 22650 22 | [name] => Alien Breed 2: Assault 23 | [playtimeTwoWeeks] => 0 24 | [playtimeTwoWeeksReadable] => 0 minutes 25 | [playtimeForever] => 0 26 | [playtimeForeverReadable] => 0 minutes 27 | [icon] => http://media.steampowered.com/steamcommunity/public/images/apps/22650/a10e00aa5fc77cc14deb38f7da48e5da40b18503.jpg 28 | [logo] => http://media.steampowered.com/steamcommunity/public/images/apps/22650/57b8df3a30a02c1a013fa6301563dcc2e941ef11.jpg 29 | [header] => http://cdn.steampowered.com/v/gfx/apps/22650/header.jpg 30 | [hasCommunityVisibleStats] => 1 31 | ) 32 | 33 | [33] => Syntax\SteamApi\Containers\Game Object 34 | ( 35 | [appId] => 22670 36 | [name] => Alien Breed 3: Descent 37 | [playtimeTwoWeeks] => 0 38 | [playtimeTwoWeeksReadable] => 0 minutes 39 | [playtimeForever] => 0 40 | [playtimeForeverReadable] => 0 minutes 41 | [icon] => http://media.steampowered.com/steamcommunity/public/images/apps/22670/276d9c54a181c2baf809c53c6172a5475866e693.jpg 42 | [logo] => http://media.steampowered.com/steamcommunity/public/images/apps/22670/6bd254a867864ef8b4e6d2b979547e9c67d669a3.jpg 43 | [header] => http://cdn.steampowered.com/v/gfx/apps/22670/header.jpg 44 | [hasCommunityVisibleStats] => 1 45 | ) 46 | 47 | [31] => Syntax\SteamApi\Containers\Game Object 48 | ( 49 | [appId] => 22610 50 | [name] => Alien Breed: Impact 51 | [playtimeTwoWeeks] => 0 52 | [playtimeTwoWeeksReadable] => 0 minutes 53 | [playtimeForever] => 0 54 | [playtimeForeverReadable] => 0 minutes 55 | [icon] => http://media.steampowered.com/steamcommunity/public/images/apps/22610/963d4d2b346f7258940a9bb9c8a5e319ec1bc781.jpg 56 | [logo] => http://media.steampowered.com/steamcommunity/public/images/apps/22610/fcf02acbd58c5a7ee29f15df2e849054d1f3a021.jpg 57 | [header] => http://cdn.steampowered.com/v/gfx/apps/22610/header.jpg 58 | [hasCommunityVisibleStats] => 1 59 | ) 60 | 61 | ) 62 | 63 | ) -------------------------------------------------------------------------------- /examples/player/GetPlayerLevelDetails.txt: -------------------------------------------------------------------------------- 1 | Syntax\SteamApi\Containers\Player\Level Object 2 | ( 3 | [playerXp] => 903 4 | [playerLevel] => 9 5 | [xpToLevelUp] => 97 6 | [xpForCurrentLevel] => 900 7 | [currentLevelFloor] => 900 8 | [currentLevelCeieling] => 1000 9 | [percentThroughLevel] => 97 10 | ) -------------------------------------------------------------------------------- /examples/player/GetRecentlyPlayedGames.txt: -------------------------------------------------------------------------------- 1 | Syntax\SteamApi\Collection Object 2 | ( 3 | [items:protected] => Array 4 | ( 5 | [3] => Syntax\SteamApi\Containers\Game Object 6 | ( 7 | [appId] => 214490 8 | [name] => Alien: Isolation 9 | [playtimeTwoWeeks] => 73 10 | [playtimeTwoWeeksReadable] => 1 hours 13 minutes 11 | [playtimeForever] => 73 12 | [playtimeForeverReadable] => 1 hours 13 minutes 13 | [icon] => http://media.steampowered.com/steamcommunity/public/images/apps/214490/7bf964858835da75630a43ac0ddbf0f66a40902f.jpg 14 | [logo] => http://media.steampowered.com/steamcommunity/public/images/apps/214490/6cdbe0113548dad8cee3d24fbace9abe298ac9af.jpg 15 | [header] => http://cdn.steampowered.com/v/gfx/apps/214490/header.jpg 16 | [hasCommunityVisibleStats] => 0 17 | ) 18 | 19 | [1] => Syntax\SteamApi\Containers\Game Object 20 | ( 21 | [appId] => 258970 22 | [name] => Gauntletâ„¢ 23 | [playtimeTwoWeeks] => 148 24 | [playtimeTwoWeeksReadable] => 2 hours 28 minutes 25 | [playtimeForever] => 148 26 | [playtimeForeverReadable] => 2 hours 28 minutes 27 | [icon] => http://media.steampowered.com/steamcommunity/public/images/apps/258970/76e95a57a669c30984c9dcd32879536746d75de9.jpg 28 | [logo] => http://media.steampowered.com/steamcommunity/public/images/apps/258970/0b9cae9548f1a6dea05ecfb8ef886a6211189128.jpg 29 | [header] => http://cdn.steampowered.com/v/gfx/apps/258970/header.jpg 30 | [hasCommunityVisibleStats] => 0 31 | ) 32 | 33 | [4] => Syntax\SteamApi\Containers\Game Object 34 | ( 35 | [appId] => 249130 36 | [name] => LEGO MARVEL Super Heroes 37 | [playtimeTwoWeeks] => 46 38 | [playtimeTwoWeeksReadable] => 46 minutes 39 | [playtimeForever] => 46 40 | [playtimeForeverReadable] => 46 minutes 41 | [icon] => http://media.steampowered.com/steamcommunity/public/images/apps/249130/8462ed9e1004624c7109233eafd7098211da9f86.jpg 42 | [logo] => http://media.steampowered.com/steamcommunity/public/images/apps/249130/8b012ffdf2cb13e6f71cdf3606ce053c888ff3b5.jpg 43 | [header] => http://cdn.steampowered.com/v/gfx/apps/249130/header.jpg 44 | [hasCommunityVisibleStats] => 0 45 | ) 46 | 47 | [2] => Syntax\SteamApi\Containers\Game Object 48 | ( 49 | [appId] => 241930 50 | [name] => Middle-earth: Shadow of Mordor 51 | [playtimeTwoWeeks] => 71 52 | [playtimeTwoWeeksReadable] => 1 hours 21 minutes 53 | [playtimeForever] => 81 54 | [playtimeForeverReadable] => 1 hours 21 minutes 55 | [icon] => http://media.steampowered.com/steamcommunity/public/images/apps/241930/161afab3c9f725f593635723cc64a7fbeb324ead.jpg 56 | [logo] => http://media.steampowered.com/steamcommunity/public/images/apps/241930/00631b918ee8799ff48b3d91d9eb0d3278aafa83.jpg 57 | [header] => http://cdn.steampowered.com/v/gfx/apps/241930/header.jpg 58 | [hasCommunityVisibleStats] => 0 59 | ) 60 | 61 | [0] => Syntax\SteamApi\Containers\Game Object 62 | ( 63 | [appId] => 221680 64 | [name] => Rocksmith 2014 65 | [playtimeTwoWeeks] => 150 66 | [playtimeTwoWeeksReadable] => 2 hours 30 minutes 67 | [playtimeForever] => 753 68 | [playtimeForeverReadable] => 12 hours 33 minutes 69 | [icon] => http://media.steampowered.com/steamcommunity/public/images/apps/221680/26c3d3ad45c9386e909613e5d115e73955501844.jpg 70 | [logo] => http://media.steampowered.com/steamcommunity/public/images/apps/221680/f7d201a1638d020101fade6d8d51cf09c33b3b1c.jpg 71 | [header] => http://cdn.steampowered.com/v/gfx/apps/221680/header.jpg 72 | [hasCommunityVisibleStats] => 0 73 | ) 74 | 75 | ) 76 | 77 | ) -------------------------------------------------------------------------------- /examples/player/GetSteamLevel.txt: -------------------------------------------------------------------------------- 1 | 9 -------------------------------------------------------------------------------- /examples/player/IsPlayingSharedGame.txt: -------------------------------------------------------------------------------- 1 | 76561198022436617 -------------------------------------------------------------------------------- /examples/user/GetFriendList.txt: -------------------------------------------------------------------------------- 1 | Array 2 | ( 3 | [0] => Syntax\SteamApi\Containers\Player Object 4 | ( 5 | [steamId] => 76561198022436617 6 | [steamIds] => stdClass Object 7 | ( 8 | [id32] => "STEAM_1:1:9846342" 9 | [id64] => "76561198022436617" 10 | [id3] => "[U:1:19692685]"" 11 | ) 12 | [communityVisibilityState] => 3 13 | [profileState] => 1 14 | [personaName] => Stygian 15 | [lastLogoff] => October 8th, 2014 10:50am 16 | [profileUrl] => http://steamcommunity.com/id/stygiansabyss/ 17 | [avatar] => 18 | [avatarMedium] => 19 | [avatarFull] => 20 | [personaState] => Online 21 | [primaryClanId] => 103582791435113986 22 | [timecreated] => March 15th, 2010 01:31pm 23 | [personaStateFlags] => 0 24 | ) 25 | [1] => Syntax\SteamApi\Containers\Player Object 26 | ( 27 | [steamId] => 76561198028432364 28 | [steamIds] => stdClass Object 29 | ( 30 | [id32] => "STEAM_1:1:9846342" 31 | [id64] => "76561198028432364" 32 | [id3] => "[U:1:19692685]"" 33 | ) 34 | [communityVisibilityState] => 3 35 | [profileState] => 1 36 | [personaName] => [GoB] Bindusara 37 | [lastLogoff] => October 8th, 2014 05:39am 38 | [profileUrl] => http://steamcommunity.com/id/bindusara/ 39 | [avatar] => 40 | [avatarMedium] => 41 | [avatarFull] => 42 | [personaState] => Online 43 | [primaryClanId] => 103582791432779431 44 | [timecreated] => August 1st, 2010 04:38am 45 | [personaStateFlags] => 0 46 | ) 47 | 48 | ) 49 | -------------------------------------------------------------------------------- /examples/user/GetPlayerBans.txt: -------------------------------------------------------------------------------- 1 | Array 2 | ( 3 | [0] => stdClass Object 4 | ( 5 | [SteamId] => 76561197979958413 6 | [CommunityBanned] => 7 | [VACBanned] => 8 | [NumberOfVACBans] => 0 9 | [DaysSinceLastBan] => 0 10 | [EconomyBan] => banned 11 | ) 12 | 13 | ) 14 | -------------------------------------------------------------------------------- /examples/user/GetPlayerSummaries.txt: -------------------------------------------------------------------------------- 1 | Array 2 | ( 3 | [0] => Syntax\SteamApi\Containers\Player Object 4 | ( 5 | [steamId] => 76561198022436617 6 | [steamIds] => Syntax\SteamApi\Containers\Id Object 7 | ( 8 | [id32] => STEAM_1:1:31085444 9 | [id64] => 76561198022436617 10 | [id3] => [U:1:62170889] 11 | [communityId] => STEAM_1:1:31085444 12 | [steamId] => 76561198022436617 13 | ) 14 | [communityVisibilityState] => 3 15 | [profileState] => 1 16 | [personaName] => Stygian 17 | [lastLogoff] => October 8th, 2014 10:50am 18 | [profileUrl] => http://steamcommunity.com/id/stygiansabyss/ 19 | [avatar] => 20 | [avatarMedium] => 21 | [avatarFull] => 22 | [avatarUrl] => http://media.steampowered.com/steamcommunity/public/images/avatars/3a/3a718856298ce108a71dfd5b0bc5eb913a8ff650.jpg 23 | [avatarMediumUrl] => http://media.steampowered.com/steamcommunity/public/images/avatars/3a/3a718856298ce108a71dfd5b0bc5eb913a8ff650_medium.jpg 24 | [avatarFullUrl] => http://media.steampowered.com/steamcommunity/public/images/avatars/3a/3a718856298ce108a71dfd5b0bc5eb913a8ff650_full.jpg 25 | [personaState] => Online 26 | [personaStateId] => 3 27 | [realName] => Joe Smith 28 | [primaryClanId] => 103582791435113986 29 | [timecreated] => March 15th, 2010 01:31pm 30 | [personaStateFlags] => 0 31 | [locCountryCode] => US 32 | [locStateCode] => TX 33 | [locCityId] => 3620 34 | [location] => stdClass Object 35 | ( 36 | [country] => United States 37 | [state] => Texas 38 | [city] => Dallas 39 | ) 40 | [commentPermission]=> 1 41 | [gameDetails] => stdClass Object 42 | ( 43 | [gameId] => 252950 44 | [serverIp] => null 45 | [serverSteamId] => null 46 | [extraInfo] => Rocket League 47 | ) 48 | ) 49 | 50 | ) 51 | -------------------------------------------------------------------------------- /examples/user/ResolveVanityURL.txt: -------------------------------------------------------------------------------- 1 | stdClass Object 2 | ( 3 | [id32] => STEAM_1:0:11101 4 | [id64] => 76561197960287930 5 | [id3] => [U:1:22202] 6 | ) -------------------------------------------------------------------------------- /examples/user/stats/GetGlobalAchievementPercentageForApp.txt: -------------------------------------------------------------------------------- 1 | Array 2 | ( 3 | [0] => stdClass Object 4 | ( 5 | [name] => explosive_exit 6 | [percent] => 60.344631195068 7 | ) 8 | 9 | [1] => stdClass Object 10 | ( 11 | [name] => suddenly_skewered 12 | [percent] => 42.981929779053 13 | ) 14 | 15 | [2] => stdClass Object 16 | ( 17 | [name] => precision_strike 18 | [percent] => 40.083293914795 19 | ) 20 | 21 | [3] => stdClass Object 22 | ( 23 | [name] => the_undeath_of_khamun 24 | [percent] => 38.004730224609 25 | ) 26 | 27 | [4] => stdClass Object 28 | ( 29 | [name] => as_luck_would_have_it 30 | [percent] => 33.594764709473 31 | ) 32 | 33 | [5] => stdClass Object 34 | ( 35 | [name] => besting_the_beast_of_orox 36 | [percent] => 23.76727104187 37 | ) 38 | 39 | [6] => stdClass Object 40 | ( 41 | [name] => icy_tomb 42 | [percent] => 22.661437988281 43 | ) 44 | 45 | [7] => stdClass Object 46 | ( 47 | [name] => eye_for_an_eye 48 | [percent] => 15.825128555298 49 | ) 50 | 51 | [8] => stdClass Object 52 | ( 53 | [name] => furious_charge 54 | [percent] => 15.571806907654 55 | ) 56 | 57 | [9] => stdClass Object 58 | ( 59 | [name] => morak_defeated 60 | [percent] => 13.494199752808 61 | ) 62 | 63 | [10] => stdClass Object 64 | ( 65 | [name] => deader_than_dead 66 | [percent] => 10.665216445923 67 | ) 68 | 69 | [11] => stdClass Object 70 | ( 71 | [name] => embracing_the_end 72 | [percent] => 8.6481952667236 73 | ) 74 | 75 | [12] => stdClass Object 76 | ( 77 | [name] => seriously_severed 78 | [percent] => 8.6143236160278 79 | ) 80 | 81 | [13] => stdClass Object 82 | ( 83 | [name] => heroic_hunger 84 | [percent] => 7.664014339447 85 | ) 86 | 87 | [14] => stdClass Object 88 | ( 89 | [name] => dying_for_a_living 90 | [percent] => 4.6241703033447 91 | ) 92 | 93 | [15] => stdClass Object 94 | ( 95 | [name] => dropper_of_treasure 96 | [percent] => 2.8013129234314 97 | ) 98 | 99 | [16] => stdClass Object 100 | ( 101 | [name] => scarred_veteran 102 | [percent] => 1.8548201322556 103 | ) 104 | 105 | [17] => stdClass Object 106 | ( 107 | [name] => hardened_champion 108 | [percent] => 1.7990039587021 109 | ) 110 | 111 | [18] => stdClass Object 112 | ( 113 | [name] => pyromancer 114 | [percent] => 1.5619037151337 115 | ) 116 | 117 | [19] => stdClass Object 118 | ( 119 | [name] => crypt_kicker 120 | [percent] => 1.5447294712067 121 | ) 122 | 123 | [20] => stdClass Object 124 | ( 125 | [name] => formidable_fortune 126 | [percent] => 1.2575376033783 127 | ) 128 | 129 | [21] => stdClass Object 130 | ( 131 | [name] => artful_dodger 132 | [percent] => 1.0457216501236 133 | ) 134 | 135 | [22] => stdClass Object 136 | ( 137 | [name] => cave_crusher 138 | [percent] => 0.87016260623932 139 | ) 140 | 141 | [23] => stdClass Object 142 | ( 143 | [name] => mummy_slayer 144 | [percent] => 0.86586904525757 145 | ) 146 | 147 | [24] => stdClass Object 148 | ( 149 | [name] => stormcaller 150 | [percent] => 0.62972295284271 151 | ) 152 | 153 | [25] => stdClass Object 154 | ( 155 | [name] => accomplished_master 156 | [percent] => 0.61684221029282 157 | ) 158 | 159 | [26] => stdClass Object 160 | ( 161 | [name] => bombardier 162 | [percent] => 0.53097093105316 163 | ) 164 | 165 | [27] => stdClass Object 166 | ( 167 | [name] => whirling_death 168 | [percent] => 0.5056865811348 169 | ) 170 | 171 | [28] => stdClass Object 172 | ( 173 | [name] => slayer 174 | [percent] => 0.36065948009491 175 | ) 176 | 177 | [29] => stdClass Object 178 | ( 179 | [name] => temple_toppler 180 | [percent] => 0.33060455322266 181 | ) 182 | 183 | [30] => stdClass Object 184 | ( 185 | [name] => the_captains_special 186 | [percent] => 0.27383404970169 187 | ) 188 | 189 | [31] => stdClass Object 190 | ( 191 | [name] => eating_off_the_floor 192 | [percent] => 0.18128387629986 193 | ) 194 | 195 | [32] => stdClass Object 196 | ( 197 | [name] => lich_slayer 198 | [percent] => 0.1602931022644 199 | ) 200 | 201 | [33] => stdClass Object 202 | ( 203 | [name] => frostweaver 204 | [percent] => 0.14884360134602 205 | ) 206 | 207 | [34] => stdClass Object 208 | ( 209 | [name] => giant_spider_slayer 210 | [percent] => 0.1264216452837 211 | ) 212 | 213 | [35] => stdClass Object 214 | ( 215 | [name] => skeleton_slayer 216 | [percent] => 0.12594458460808 217 | ) 218 | 219 | [36] => stdClass Object 220 | ( 221 | [name] => grunt_slayer 222 | [percent] => 0.097797878086567 223 | ) 224 | 225 | [37] => stdClass Object 226 | ( 227 | [name] => cultist_slayer 228 | [percent] => 0.095889627933502 229 | ) 230 | 231 | [38] => stdClass Object 232 | ( 233 | [name] => orc_slayer 234 | [percent] => 0.078238300979137 235 | ) 236 | 237 | [39] => stdClass Object 238 | ( 239 | [name] => demon_slayer 240 | [percent] => 0.076330050826073 241 | ) 242 | 243 | [40] => stdClass Object 244 | ( 245 | [name] => as_luck_would_have_it_1 246 | [percent] => 0.020036637783051 247 | ) 248 | 249 | [41] => stdClass Object 250 | ( 251 | [name] => burned_alive 252 | [percent] => 0.020036637783051 253 | ) 254 | 255 | [42] => stdClass Object 256 | ( 257 | [name] => as_luck_would_have_it_3 258 | [percent] => 0.018128387629986 259 | ) 260 | 261 | [43] => stdClass Object 262 | ( 263 | [name] => slayer_1 264 | [percent] => 0.016697200015187 265 | ) 266 | 267 | [44] => stdClass Object 268 | ( 269 | [name] => faithful_customer 270 | [percent] => 0.012403633445501 271 | ) 272 | 273 | [45] => stdClass Object 274 | ( 275 | [name] => mummy_slayer_3 276 | [percent] => 0.012403633445501 277 | ) 278 | 279 | [46] => stdClass Object 280 | ( 281 | [name] => slayer_2 282 | [percent] => 0.010495381429791 283 | ) 284 | 285 | [47] => stdClass Object 286 | ( 287 | [name] => heroic_hunger_3 288 | [percent] => 0.010018318891525 289 | ) 290 | 291 | [48] => stdClass Object 292 | ( 293 | [name] => dying_for_a_living_3 294 | [percent] => 0.0090641938149929 295 | ) 296 | 297 | [49] => stdClass Object 298 | ( 299 | [name] => skeleton_slayer_3 300 | [percent] => 0.008110067807138 301 | ) 302 | 303 | [50] => stdClass Object 304 | ( 305 | [name] => faithful_customer_3 306 | [percent] => 0.008110067807138 307 | ) 308 | 309 | [51] => stdClass Object 310 | ( 311 | [name] => riddles_of_the_grave_3 312 | [percent] => 0.0076330048032105 313 | ) 314 | 315 | [52] => stdClass Object 316 | ( 317 | [name] => formidable_fortune_3 318 | [percent] => 0.0071559422649443 319 | ) 320 | 321 | [53] => stdClass Object 322 | ( 323 | [name] => dropper_of_treasure_3 324 | [percent] => 0.0066788792610168 325 | ) 326 | 327 | [54] => stdClass Object 328 | ( 329 | [name] => cultist_slayer_3 330 | [percent] => 0.0062018167227507 331 | ) 332 | 333 | [55] => stdClass Object 334 | ( 335 | [name] => eating_off_the_floor_3 336 | [percent] => 0.0057247541844845 337 | ) 338 | 339 | [56] => stdClass Object 340 | ( 341 | [name] => goblin_slayer_3 342 | [percent] => 0.0057247541844845 343 | ) 344 | 345 | [57] => stdClass Object 346 | ( 347 | [name] => secrets_of_the_flame_3 348 | [percent] => 0.0057247541844845 349 | ) 350 | 351 | [58] => stdClass Object 352 | ( 353 | [name] => mysteries_in_the_dark 354 | [percent] => 0.0042935656383634 355 | ) 356 | 357 | [59] => stdClass Object 358 | ( 359 | [name] => riddles_of_the_grave 360 | [percent] => 0.0042935656383634 361 | ) 362 | 363 | [60] => stdClass Object 364 | ( 365 | [name] => deader_than_dead_3 366 | [percent] => 0.0042935656383634 367 | ) 368 | 369 | [61] => stdClass Object 370 | ( 371 | [name] => secrets_of_the_flame 372 | [percent] => 0.0038165024016052 373 | ) 374 | 375 | [62] => stdClass Object 376 | ( 377 | [name] => rude_interruption 378 | [percent] => 0.0038165024016052 379 | ) 380 | 381 | [63] => stdClass Object 382 | ( 383 | [name] => slayer_3 384 | [percent] => 0.0038165024016052 385 | ) 386 | 387 | [64] => stdClass Object 388 | ( 389 | [name] => orc_slayer_3 390 | [percent] => 0.0038165024016052 391 | ) 392 | 393 | [65] => stdClass Object 394 | ( 395 | [name] => lich_slayer_3 396 | [percent] => 0.0028623770922422 397 | ) 398 | 399 | [66] => stdClass Object 400 | ( 401 | [name] => giant_spider_slayer_3 402 | [percent] => 0.0028623770922422 403 | ) 404 | 405 | [67] => stdClass Object 406 | ( 407 | [name] => whirling_death_3 408 | [percent] => 0.0023853140883148 409 | ) 410 | 411 | [68] => stdClass Object 412 | ( 413 | [name] => hardened_champion_3 414 | [percent] => 0.0023853140883148 415 | ) 416 | 417 | [69] => stdClass Object 418 | ( 419 | [name] => frostweaver_3 420 | [percent] => 0.0023853140883148 421 | ) 422 | 423 | [70] => stdClass Object 424 | ( 425 | [name] => cold_hearted_3 426 | [percent] => 0.0023853140883148 427 | ) 428 | 429 | [71] => stdClass Object 430 | ( 431 | [name] => generous_3 432 | [percent] => 0.0023853140883148 433 | ) 434 | 435 | [72] => stdClass Object 436 | ( 437 | [name] => cave_crusher_3 438 | [percent] => 0.0019082512008026 439 | ) 440 | 441 | [73] => stdClass Object 442 | ( 443 | [name] => stormcaller_3 444 | [percent] => 0.0019082512008026 445 | ) 446 | 447 | [74] => stdClass Object 448 | ( 449 | [name] => bombardier_3 450 | [percent] => 0.0019082512008026 451 | ) 452 | 453 | [75] => stdClass Object 454 | ( 455 | [name] => blessed_by_the_gods_3 456 | [percent] => 0.0019082512008026 457 | ) 458 | 459 | [76] => stdClass Object 460 | ( 461 | [name] => blessed_by_the_gods 462 | [percent] => 0.0019082512008026 463 | ) 464 | 465 | [77] => stdClass Object 466 | ( 467 | [name] => artful_dodger_3 468 | [percent] => 0.0019082512008026 469 | ) 470 | 471 | [78] => stdClass Object 472 | ( 473 | [name] => trailblazer_3 474 | [percent] => 0.0019082512008026 475 | ) 476 | 477 | [79] => stdClass Object 478 | ( 479 | [name] => unruly_3 480 | [percent] => 0.0019082512008026 481 | ) 482 | 483 | [80] => stdClass Object 484 | ( 485 | [name] => accomplished_master_3 486 | [percent] => 0.0019082512008026 487 | ) 488 | 489 | [81] => stdClass Object 490 | ( 491 | [name] => temple_toppler_3 492 | [percent] => 0.0019082512008026 493 | ) 494 | 495 | [82] => stdClass Object 496 | ( 497 | [name] => pyromancer_3 498 | [percent] => 0.0019082512008026 499 | ) 500 | 501 | [83] => stdClass Object 502 | ( 503 | [name] => mysteries_in_the_dark_3 504 | [percent] => 0.0019082512008026 505 | ) 506 | 507 | [84] => stdClass Object 508 | ( 509 | [name] => light_footed_3 510 | [percent] => 0.0019082512008026 511 | ) 512 | 513 | [85] => stdClass Object 514 | ( 515 | [name] => scarred_veteran_3 516 | [percent] => 0.0019082512008026 517 | ) 518 | 519 | [86] => stdClass Object 520 | ( 521 | [name] => heedless_3 522 | [percent] => 0.0019082512008026 523 | ) 524 | 525 | [87] => stdClass Object 526 | ( 527 | [name] => crypt_kicker_3 528 | [percent] => 0.0019082512008026 529 | ) 530 | 531 | [88] => stdClass Object 532 | ( 533 | [name] => dragon_slayer_3 534 | [percent] => 0.0014311885461211 535 | ) 536 | 537 | [89] => stdClass Object 538 | ( 539 | [name] => daemon_slayer_3 540 | [percent] => 0.0014311885461211 541 | ) 542 | 543 | [90] => stdClass Object 544 | ( 545 | [name] => dragon_slayer 546 | [percent] => 0.0014311885461211 547 | ) 548 | 549 | [91] => stdClass Object 550 | ( 551 | [name] => schizofrenic_3 552 | [percent] => 0.00047706280020066 553 | ) 554 | 555 | [92] => stdClass Object 556 | ( 557 | [name] => 558 | [percent] => 0 559 | ) 560 | 561 | [93] => stdClass Object 562 | ( 563 | [name] => generous 564 | [percent] => 0 565 | ) 566 | 567 | ) -------------------------------------------------------------------------------- /examples/user/stats/GetPlayerAchievements.txt: -------------------------------------------------------------------------------- 1 | Array 2 | ( 3 | [0] => Syntax\SteamApi\Containers\Achievement Object 4 | ( 5 | [apiName] => supervictorious 6 | [achieved] => 1 7 | [name] => Super Victorious 8 | [description] => Win a total of 30 games across any game mode 9 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/710fa884cc942b05b4ff2856eda4a1eebe909f21.jpg 10 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/9396ab7802bc827abefb5f13a4bdb04e05c5a079.jpg 11 | [unlockTimestamp] => 1438237608 12 | ) 13 | 14 | [1] => Syntax\SteamApi\Containers\Achievement Object 15 | ( 16 | [apiName] => helenspride 17 | [achieved] => 1 18 | [name] => Helen's Pride 19 | [description] => Score 6 Goals in a single game 20 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/d25f78987a4f8a3500172ef5c8019c02684ae2ba.jpg 21 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/05065c20c22438f791a5f23f20c154483299f90c.jpg 22 | [unlockTimestamp] => 1437893827 23 | ) 24 | 25 | [2] => Syntax\SteamApi\Containers\Achievement Object 26 | ( 27 | [apiName] => battlecarcollector 28 | [achieved] => 1 29 | [name] => Battle-Car Collector 30 | [description] => Unlock all Battle-Cars 31 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/b69193ec416423e20757130026768b5c71bf3177.jpg 32 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/5e2ccf8b81120ed738f7d498dd3f06a55cc64d2d.jpg 33 | [unlockTimestamp] => 1437894786 34 | ) 35 | 36 | [3] => Syntax\SteamApi\Containers\Achievement Object 37 | ( 38 | [apiName] => dropsinthebucket 39 | [achieved] => 1 40 | [name] => Drops in the Bucket 41 | [description] => Collect 50 Items 42 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/19c6744ebc45507a746469e1ba71e9654bf77a11.jpg 43 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/1b8bca57551d91dfbba27004505cd1e8a2cc9e58.jpg 44 | [unlockTimestamp] => 1438310461 45 | ) 46 | 47 | [4] => Syntax\SteamApi\Containers\Achievement Object 48 | ( 49 | [apiName] => greasemonkey 50 | [achieved] => 1 51 | [name] => Grease Monkey 52 | [description] => Customize every slot on a single Battle-Car 53 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/ba582e59dd4672ffe1752c47b76ba7eb1a650454.jpg 54 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/aec92c92c1cd8c21576c117f1db6c0d2fadaba75.jpg 55 | [unlockTimestamp] => 1437894861 56 | ) 57 | 58 | [5] => Syntax\SteamApi\Containers\Achievement Object 59 | ( 60 | [apiName] => pitchveteran 61 | [achieved] => 1 62 | [name] => Pitch Veteran 63 | [description] => Play a total of 20 games across any game mode 64 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/c55951a42ba66003406158faf90e28dbe6458b0c.jpg 65 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/7edacce7bce74a838fd3057ff2a3f8448d73b1c8.jpg 66 | [unlockTimestamp] => 1437806004 67 | ) 68 | 69 | [6] => Syntax\SteamApi\Containers\Achievement Object 70 | ( 71 | [apiName] => breakshot 72 | [achieved] => 1 73 | [name] => Break Shot 74 | [description] => Score a goal by hitting your opponent into the ball 75 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/89997d040ba3905a9e5360a30082b803b1bc921b.jpg 76 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/9b1ed566f6ab42bc5c31eba103ad86eae12ab505.jpg 77 | [unlockTimestamp] => 1437798363 78 | ) 79 | 80 | [7] => Syntax\SteamApi\Containers\Achievement Object 81 | ( 82 | [apiName] => turbocharger 83 | [achieved] => 1 84 | [name] => Turbocharger 85 | [description] => Use your Rocket Boost for a total of 5 minutes 86 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/ea22e69de9d44c05e6ce497db64e6d82b1d53187.jpg 87 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/89130dffe20e4286e7331d97c76bd0287c49d568.jpg 88 | [unlockTimestamp] => 1437799271 89 | ) 90 | 91 | [8] => Syntax\SteamApi\Containers\Achievement Object 92 | ( 93 | [apiName] => minutetowinit 94 | [achieved] => 1 95 | [name] => Minute to Win it 96 | [description] => With only 60 seconds left, Win a game in which you were tied or trailing 97 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/fdd5ce73dc1c612c407bfac38da013efac61c1a9.jpg 98 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/8ec891467a1ad518daf8dd2de98364256a911643.jpg 99 | [unlockTimestamp] => 1437798554 100 | ) 101 | 102 | [9] => Syntax\SteamApi\Containers\Achievement Object 103 | ( 104 | [apiName] => speeddemon 105 | [achieved] => 1 106 | [name] => Speed Demon 107 | [description] => Completely fill and then empty your Rocket Boost 10 times in a single match 108 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/c11e603e583346392b6568ad96ebfbd1f98477d0.jpg 109 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/5c1602039641935b70bc1c4492a15a6db8a52605.jpg 110 | [unlockTimestamp] => 1437799638 111 | ) 112 | 113 | [10] => Syntax\SteamApi\Containers\Achievement Object 114 | ( 115 | [apiName] => pickmeup 116 | [achieved] => 1 117 | [name] => Pick-Me Up 118 | [description] => Collect 5 Items 119 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/9c53a15a1d1f1722691b1471448ec0fc6eab6be2.jpg 120 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/bcbd911e0605c930d3714dbec61ab8429cf6c5a4.jpg 121 | [unlockTimestamp] => 1437799131 122 | ) 123 | 124 | [11] => Syntax\SteamApi\Containers\Achievement Object 125 | ( 126 | [apiName] => wallcrawler 127 | [achieved] => 1 128 | [name] => Wall-Crawler 129 | [description] => Drive on the dome walls for a total of 5 minutes 130 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/35d5f16bcd2a67e64026c3beb5fc130013c12b4e.jpg 131 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/e307dbbe620e0b4530917e7fa764dcbc49b8e1c2.jpg 132 | [unlockTimestamp] => 1437801013 133 | ) 134 | 135 | [12] => Syntax\SteamApi\Containers\Achievement Object 136 | ( 137 | [apiName] => featherinyourrecap 138 | [achieved] => 1 139 | [name] => Feather in Your Recap 140 | [description] => Watch a save file in Replay mode 141 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/74262e7580d0e3f17030c7694c0fad7920f99b87.jpg 142 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/3431cbdb828b3ac557afd552ccecea12b742c458.jpg 143 | [unlockTimestamp] => 1438311420 144 | ) 145 | 146 | [13] => Syntax\SteamApi\Containers\Achievement Object 147 | ( 148 | [apiName] => winner 149 | [achieved] => 1 150 | [name] => Winner 151 | [description] => Win a total of 5 games across any mode 152 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/e274145b3c21a55f80e0070f5dd46364da10eb05.jpg 153 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/b269d797cbcccf4d68529a2ff1a524d9626996fe.jpg 154 | [unlockTimestamp] => 1437801180 155 | ) 156 | 157 | [14] => Syntax\SteamApi\Containers\Achievement Object 158 | ( 159 | [apiName] => cleansheet 160 | [achieved] => 1 161 | [name] => Clean Sheet 162 | [description] => Win a game without giving up a single Goal 163 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/7c4125ea4f6d81ecf50589094fc92778a94661e8.jpg 164 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/fec9c436d6f05c3a904c7d9ad52449f1e6b1b0ad.jpg 165 | [unlockTimestamp] => 1437894785 166 | ) 167 | 168 | [15] => Syntax\SteamApi\Containers\Achievement Object 169 | ( 170 | [apiName] => triplethreat 171 | [achieved] => 1 172 | [name] => Triple Threat 173 | [description] => Win a 3v3 game 174 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/4811e355b1f84729f517098deb9b12fc2afc3a34.jpg 175 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/20590bb380acb604d2d6d1be1a54eef904c6d68b.jpg 176 | [unlockTimestamp] => 1437798554 177 | ) 178 | 179 | [16] => Syntax\SteamApi\Containers\Achievement Object 180 | ( 181 | [apiName] => doubleup 182 | [achieved] => 1 183 | [name] => Double Up 184 | [description] => Win a 2v2 game 185 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/13f0dccfdb88573115dafea639791866fd6484ad.jpg 186 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/70a08315760189a7a078d99848d534b03b332962.jpg 187 | [unlockTimestamp] => 1438310460 188 | ) 189 | 190 | [17] => Syntax\SteamApi\Containers\Achievement Object 191 | ( 192 | [apiName] => singlesclub 193 | [achieved] => 1 194 | [name] => Singles Club 195 | [description] => Win a 1v1 game 196 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/8e03bd6011ba4eed45630b0cf7a8787e9ea6d1bf.jpg 197 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/4263c0e66c5ca77853c377a19d6d9b02061c7de3.jpg 198 | [unlockTimestamp] => 1437797261 199 | ) 200 | 201 | [18] => Syntax\SteamApi\Containers\Achievement Object 202 | ( 203 | [apiName] => perfectstart 204 | [achieved] => 1 205 | [name] => Perfect Start 206 | [description] => Win your first game of the Season 207 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/6c478f5e5023bc27aea9d72ed5d2b36a298ae46d.jpg 208 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/a9cd85d387f1a46d419d5f5482892a69395679b4.jpg 209 | [unlockTimestamp] => 1437892059 210 | ) 211 | 212 | [19] => Syntax\SteamApi\Containers\Achievement Object 213 | ( 214 | [apiName] => knowthedrill 215 | [achieved] => 1 216 | [name] => Know the Drill 217 | [description] => Complete a Practice Drill 218 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/44f63dd8f08d7692d5528c3a8831ea3b171140f0.jpg 219 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/210eaa485f56902c3e16387c4d1de272dc444c32.jpg 220 | [unlockTimestamp] => 1437796456 221 | ) 222 | 223 | [20] => Syntax\SteamApi\Containers\Achievement Object 224 | ( 225 | [apiName] => traveler 226 | [achieved] => 1 227 | [name] => Traveler 228 | [description] => Play in every Rocket League stadium 229 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/4484dc4e2b83e3cd093411923a61e0d7868d564c.jpg 230 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/507a58a09cf6eb92ca99ad125fca5334174c0a2a.jpg 231 | [unlockTimestamp] => 1437800246 232 | ) 233 | 234 | [21] => Syntax\SteamApi\Containers\Achievement Object 235 | ( 236 | [apiName] => tinkerer 237 | [achieved] => 1 238 | [name] => Tinkerer 239 | [description] => Customize one slot on a single Battle-Car 240 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/e461f3103d5a8f49b851d4a0d3aff723a5376d5a.jpg 241 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/a3131a8eba30a7e0e68986a3d8ef7535b5eabf1e.jpg 242 | [unlockTimestamp] => 1437795500 243 | ) 244 | 245 | [22] => Syntax\SteamApi\Containers\Achievement Object 246 | ( 247 | [apiName] => firsttimer 248 | [achieved] => 1 249 | [name] => First-Timer 250 | [description] => Score your first Goal 251 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/2a870e59a1101ebf87c0e8aef9f95a6d900fa454.jpg 252 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/494d0e131443ebbb8c3bffdb884b707ac0ba5203.jpg 253 | [unlockTimestamp] => 1437796922 254 | ) 255 | 256 | [23] => Syntax\SteamApi\Containers\Achievement Object 257 | ( 258 | [apiName] => barrasbravas 259 | [achieved] => 1 260 | [name] => Barras Bravas 261 | [description] => Play an Online game with a Friend 262 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/2b74674e9d9f2c04cf59a60bb226a1c67cbdd024.jpg 263 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/392e39f23a3b0bec553fd262c1c0ad564e21019b.jpg 264 | [unlockTimestamp] => 1437796889 265 | ) 266 | 267 | [24] => Syntax\SteamApi\Containers\Achievement Object 268 | ( 269 | [apiName] => virtuoso 270 | [achieved] => 0 271 | [name] => Virtuoso 272 | [description] => Unlock all original Achievements 273 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/d63287a74492218ac97000af0147f6e40bd51f1d.jpg 274 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/33f14554d8cb38d7ecefd98dbb765e21efc26f20.jpg 275 | [unlockTimestamp] => 276 | ) 277 | 278 | [25] => Syntax\SteamApi\Containers\Achievement Object 279 | ( 280 | [apiName] => stocked 281 | [achieved] => 0 282 | [name] => Stocked 283 | [description] => Collect all Items 284 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/689d4370df62dab7b3f904d4f7b182310958efd2.jpg 285 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/f36ef329ccfc916aff310c3237ef92f6f194579c.jpg 286 | [unlockTimestamp] => 287 | ) 288 | 289 | [26] => Syntax\SteamApi\Containers\Achievement Object 290 | ( 291 | [apiName] => farfaraway 292 | [achieved] => 0 293 | [name] => Far, Far Away... 294 | [description] => Drive a total of 500 km 295 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/c3c40f439d804bbcf892229ed76b2bedb25058c7.jpg 296 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/ae25bf8b5ffe14f37e3e971276f1314fd0b5f6d1.jpg 297 | [unlockTimestamp] => 298 | ) 299 | 300 | [27] => Syntax\SteamApi\Containers\Achievement Object 301 | ( 302 | [apiName] => champion 303 | [achieved] => 0 304 | [name] => Champion 305 | [description] => Win the Season Championship 306 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/ef9fc46837a6a31b2fedd4d227f27cd3af0a9867.jpg 307 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/60d3c3176775495281f222c10675dddc2b4ad9cd.jpg 308 | [unlockTimestamp] => 309 | ) 310 | 311 | [28] => Syntax\SteamApi\Containers\Achievement Object 312 | ( 313 | [apiName] => thestreak 314 | [achieved] => 0 315 | [name] => The Streak 316 | [description] => Win 10 games in a row across any mode 317 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/9974f05905881b45c7a2dbbd3c84d5e8c57fa01a.jpg 318 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/7413ea8cb240492e6bea29e31300d2963ccd65a2.jpg 319 | [unlockTimestamp] => 320 | ) 321 | 322 | [29] => Syntax\SteamApi\Containers\Achievement Object 323 | ( 324 | [apiName] => rocketeer 325 | [achieved] => 0 326 | [name] => Rocketeer 327 | [description] => Complete the regular Season 328 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/90d781a6891727c11ddec87f6535bd74d22ef580.jpg 329 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/90dbc6fc26cf20b84910374cdc427f3738719339.jpg 330 | [unlockTimestamp] => 331 | ) 332 | 333 | [30] => Syntax\SteamApi\Containers\Achievement Object 334 | ( 335 | [apiName] => ridersblock 336 | [achieved] => 0 337 | [name] => Rider's Block 338 | [description] => Make 20 Saves 339 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/bfc6762c212bec0612729c07f669d3a910963071.jpg 340 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/a9dbcbf9eadbed9cb5523548d5be85cda7e16839.jpg 341 | [unlockTimestamp] => 342 | ) 343 | 344 | [31] => Syntax\SteamApi\Containers\Achievement Object 345 | ( 346 | [apiName] => drillsergeant 347 | [achieved] => 0 348 | [name] => Drill Sergeant 349 | [description] => Complete every Practice Drill (any difficulty) 350 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/1722cf4d9f19e2f8f64d2d44485323c2216ed4ec.jpg 351 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/ea6d1769868939b99d024a6256946bf0934d00a6.jpg 352 | [unlockTimestamp] => 353 | ) 354 | 355 | [32] => Syntax\SteamApi\Containers\Achievement Object 356 | ( 357 | [apiName] => teamplayer 358 | [achieved] => 0 359 | [name] => Team Player 360 | [description] => Play against every team in a Season 361 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/8e893a17e7cdd62e051dc69b73d4c484eed402d5.jpg 362 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/93ae9471624053ccb2c4243b3a3eabc8312c121f.jpg 363 | [unlockTimestamp] => 364 | ) 365 | 366 | [33] => Syntax\SteamApi\Containers\Achievement Object 367 | ( 368 | [apiName] => sarpbcforever 369 | [achieved] => 0 370 | [name] => SARPBC Forever 371 | [description] => Play with both classic Battle-Cars 372 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/0c41f15dbb9323dc0822eae6616c82fca137af8b.jpg 373 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/ecd41aec3ddc6f9114d5251a413af2994248a6d1.jpg 374 | [unlockTimestamp] => 375 | ) 376 | 377 | [34] => Syntax\SteamApi\Containers\Achievement Object 378 | ( 379 | [apiName] => stillashowoff 380 | [achieved] => 0 381 | [name] => Still A Show-Off 382 | [description] => Score a goal while reversing 383 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/c991bb3e47b1e33169f699a8331f73889186f021.jpg 384 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/ccea164eac4e859c3b6778253d2f47d2a0b6ce8d.jpg 385 | [unlockTimestamp] => 386 | ) 387 | 388 | [35] => Syntax\SteamApi\Containers\Achievement Object 389 | ( 390 | [apiName] => friendly 391 | [achieved] => 0 392 | [name] => Friendly 393 | [description] => Play an Exhibition match 394 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/96eb1d571ab406ac143c6d768292c0a8714ffe65.jpg 395 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/0235fb209b67a27cdf406b4c1d00094c1054e725.jpg 396 | [unlockTimestamp] => 397 | ) 398 | 399 | [36] => Syntax\SteamApi\Containers\Achievement Object 400 | ( 401 | [apiName] => skyhigh 402 | [achieved] => 0 403 | [name] => Sky High 404 | [description] => Score an Aerial Goal 405 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/60b1f8b5d598d01186c8d2c2600b268a13bee63d.jpg 406 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/b81801f3a078924e54f84e98337419810106f37b.jpg 407 | [unlockTimestamp] => 408 | ) 409 | 410 | [37] => Syntax\SteamApi\Containers\Achievement Object 411 | ( 412 | [apiName] => allfours 413 | [achieved] => 0 414 | [name] => All Fours 415 | [description] => Win a 4v4 game 416 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/6d16a566ac4c1c79720ee79d43c2d7f527a93dbd.jpg 417 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/d21faf6bb60918ebab768d0b35a4e3698e2aa20d.jpg 418 | [unlockTimestamp] => 419 | ) 420 | 421 | [38] => Syntax\SteamApi\Containers\Achievement Object 422 | ( 423 | [apiName] => gladiator 424 | [achieved] => 0 425 | [name] => Gladiator 426 | [description] => Play a game on Utopia Coliseum 427 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/954409ee668ab6149a5bd007ae5f93b6ccc2aef8.jpg 428 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/0c27ce9c3c1fe3e7c025e684816cf3a2ce686a55.jpg 429 | [unlockTimestamp] => 430 | ) 431 | 432 | [39] => Syntax\SteamApi\Containers\Achievement Object 433 | ( 434 | [apiName] => winningiswinning 435 | [achieved] => 0 436 | [name] => Winning is Winning 437 | [description] => Win a Season Championship using Dominus or Takumi in every game 438 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/9aab4ee9614d12bcf3e7c7c5fb4441370dcae12b.jpg 439 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/158d9ba3fe60b7befe32c0c29313b0dd7109b6cc.jpg 440 | [unlockTimestamp] => 441 | ) 442 | 443 | [40] => Syntax\SteamApi\Containers\Achievement Object 444 | ( 445 | [apiName] => aninchand62miles 446 | [achieved] => 0 447 | [name] => An Inch and 62 Miles 448 | [description] => Drive 100 km with either the Cristiano or Spinner Wheels 449 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/0919f99fd4f9a67f7aad68c703b3afc639625d51.jpg 450 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/d89c612e5e92250ca1dd2107c098340e1469a08f.jpg 451 | [unlockTimestamp] => 452 | ) 453 | 454 | [41] => Syntax\SteamApi\Containers\Achievement Object 455 | ( 456 | [apiName] => rideordie 457 | [achieved] => 0 458 | [name] => Ride or Die 459 | [description] => Equip both Dominus and Takumi with a new Decal and Paint Finish, then win a game 460 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/9e498c5a0429ff2d7894ccd4501e5613a9db76aa.jpg 461 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/914697bd315b51b4f170b0054144280b02e07ebd.jpg 462 | [unlockTimestamp] => 463 | ) 464 | 465 | [42] => Syntax\SteamApi\Containers\Achievement Object 466 | ( 467 | [apiName] => dontlookback 468 | [achieved] => 0 469 | [name] => Don't Look Back 470 | [description] => Use the Burnout or Nitrous Rocket Boost for a total of 10 minutes 471 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/e6002d682ed3b2356509ce8a48d09bdc50f67977.jpg 472 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/793e5ce0698ac9bd893dc36bdbd69d5081a802cc.jpg 473 | [unlockTimestamp] => 474 | ) 475 | 476 | [43] => Syntax\SteamApi\Containers\Achievement Object 477 | ( 478 | [apiName] => familynotfriends 479 | [achieved] => 0 480 | [name] => Family, Not Friends 481 | [description] => Play a complete game with both Dominus and Takumi 482 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/e3e5c5012a74323f3f3a005a481feabe40c7bd8b.jpg 483 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/02b23f206188e0ced0b236b47a30e6e09859e3bf.jpg 484 | [unlockTimestamp] => 485 | ) 486 | 487 | [44] => Syntax\SteamApi\Containers\Achievement Object 488 | ( 489 | [apiName] => driftking 490 | [achieved] => 0 491 | [name] => Drift King 492 | [description] => Perform a 180 powerslide with both the Cristiano and Spinner Wheels 493 | [icon] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/9c27899d8b0e2fd45029cdd6906055f4cd963c48.jpg 494 | [iconGray] => http://cdn.akamai.steamstatic.com/steamcommunity/public/images/apps/252950/83ef17be796d9b9b1640e34b5db6002683e03330.jpg 495 | [unlockTimestamp] => 496 | ) 497 | 498 | ) -------------------------------------------------------------------------------- /examples/user/stats/GetUserStatsForGame.txt: -------------------------------------------------------------------------------- 1 | Array 2 | ( 3 | [0] => stdClass Object 4 | ( 5 | [name] => explosive_exit 6 | [achieved] => 1 7 | ) 8 | 9 | [1] => stdClass Object 10 | ( 11 | [name] => suddenly_skewered 12 | [achieved] => 1 13 | ) 14 | 15 | [2] => stdClass Object 16 | ( 17 | [name] => the_undeath_of_khamun 18 | [achieved] => 1 19 | ) 20 | 21 | ) -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ./tests/ 6 | 7 | 8 | 9 | 10 | ./src 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /rector.php: -------------------------------------------------------------------------------- 1 | paths([ 12 | __DIR__ . '/src', 13 | __DIR__ . '/tests', 14 | ]); 15 | 16 | // register a single rule 17 | $rectorConfig->rule(InlineConstructorDefaultToPropertyRector::class); 18 | $rectorConfig->rule(AddPropertyTypeDeclarationRector::class); 19 | 20 | // define sets of rules 21 | $rectorConfig->sets([ 22 | LevelSetList::UP_TO_PHP_82, 23 | ]); 24 | }; 25 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Client.php: -------------------------------------------------------------------------------- 1 | getApiKey(); 68 | 69 | $this->client = new GuzzleClient(); 70 | $this->apiKey = $apiKey; 71 | 72 | // Set up the Ids 73 | $this->setUpFormatted(); 74 | } 75 | 76 | public function get(): static 77 | { 78 | return $this; 79 | } 80 | 81 | public function getSteamId() 82 | { 83 | return $this->steamId; 84 | } 85 | 86 | /** 87 | * @param null $arguments 88 | * 89 | * @return stdClass 90 | * 91 | * @throws ApiArgumentRequired 92 | * @throws ApiCallFailedException 93 | * @throws GuzzleException 94 | */ 95 | protected function setUpService($arguments = null): stdClass 96 | { 97 | // Services have a different url syntax 98 | if ($arguments == null) { 99 | throw new ApiArgumentRequired; 100 | } 101 | 102 | $parameters = [ 103 | 'key' => $this->apiKey, 104 | 'format' => $this->apiFormat, 105 | 'input_json' => $arguments, 106 | ]; 107 | 108 | $steamUrl = $this->buildUrl(true); 109 | 110 | // Build the query string 111 | $parameters = http_build_query($parameters); 112 | 113 | // Send the request and get the results 114 | $request = new Request('GET', $steamUrl . '?' . $parameters); 115 | $response = $this->sendRequest($request); 116 | 117 | // Pass the results back 118 | return $response->body; 119 | } 120 | 121 | /** 122 | * @throws GuzzleException 123 | * @throws ApiCallFailedException 124 | */ 125 | protected function setUpClient(array $arguments = []) 126 | { 127 | $versionFlag = ! is_null($this->version); 128 | $steamUrl = $this->buildUrl($versionFlag); 129 | 130 | $parameters = [ 131 | 'key' => $this->apiKey, 132 | 'format' => $this->apiFormat, 133 | ]; 134 | 135 | if (! empty($arguments)) { 136 | $parameters = array_merge($arguments, $parameters); 137 | } 138 | 139 | // Build the query string 140 | $parameters = http_build_query($parameters); 141 | 142 | $headers = []; 143 | if (array_key_exists('l', $arguments)) { 144 | $headers = [ 145 | 'Accept-Language' => $arguments['l'], 146 | ]; 147 | } 148 | 149 | // Send the request and get the results 150 | $request = new Request('GET', $steamUrl . '?' . $parameters, $headers); 151 | $response = $this->sendRequest($request); 152 | 153 | // Pass the results back 154 | return $response->body; 155 | } 156 | 157 | protected function setUpXml(array $arguments = []): \SimpleXMLElement|null 158 | { 159 | $steamUrl = $this->buildUrl(); 160 | 161 | // Build the query string 162 | $parameters = http_build_query($arguments); 163 | 164 | // Pass the results back 165 | libxml_use_internal_errors(true); 166 | $result = simplexml_load_file($steamUrl . '?' . $parameters); 167 | 168 | if (! $result) { 169 | return null; 170 | } 171 | 172 | return $result; 173 | } 174 | 175 | public function getRedirectUrl(): void 176 | { 177 | $ch = curl_init(); 178 | curl_setopt($ch, CURLOPT_URL, $this->url); 179 | curl_setopt($ch, CURLOPT_HEADER, true); 180 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); 181 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); 182 | 183 | curl_exec($ch); 184 | $this->url = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); 185 | curl_close($ch); 186 | } 187 | 188 | /** 189 | * 190 | * @param Request $request 191 | * @return stdClass 192 | * @throws ApiCallFailedException 193 | * @throws GuzzleException 194 | */ 195 | protected function sendRequest(Request $request): stdClass 196 | { 197 | // Try to get the result. Handle the possible exceptions that can arise 198 | try { 199 | $response = $this->client->send($request); 200 | 201 | $result = new stdClass(); 202 | $result->code = $response->getStatusCode(); 203 | $result->body = json_decode((string) $response->getBody(), null, 512, JSON_THROW_ON_ERROR); 204 | } catch (ClientException $e) { 205 | throw new ApiCallFailedException($e->getMessage(), $e->getResponse()->getStatusCode(), $e); 206 | } catch (ServerException $e) { 207 | throw new ApiCallFailedException('Api call failed to complete due to a server error.', $e->getResponse()->getStatusCode(), $e); 208 | } catch (Exception $e) { 209 | throw new ApiCallFailedException($e->getMessage(), $e->getCode(), $e); 210 | } 211 | 212 | // For some resources, the Steam API responds with an empty response 213 | if (empty($result->body)) { 214 | throw new ApiCallFailedException('API call failed due to empty response', $result->code); 215 | } 216 | 217 | if (empty((array)$result->body)) { 218 | throw new ApiCallFailedException('Api call failed to complete due to an empty response.', $result->code); 219 | } 220 | 221 | // If all worked out, return the result 222 | return $result; 223 | } 224 | 225 | private function buildUrl($version = false): string 226 | { 227 | // Set up the basic url 228 | $url = $this->url . ($this->interface ?? '') . '/' . $this->method . '/'; 229 | 230 | // If we have a version, add it 231 | if ($version) { 232 | return $url . $this->version . '/'; 233 | } 234 | 235 | return $url; 236 | } 237 | 238 | /** 239 | * @throws ClassNotFoundException 240 | * @throws UnrecognizedId 241 | */ 242 | public function __call($name, $arguments) 243 | { 244 | // Handle a steamId being passed 245 | if (! empty($arguments) && count($arguments) == 1) { 246 | $this->steamId = $arguments[0]; 247 | 248 | $this->convertSteamIdTo64(); 249 | } 250 | 251 | // Inside the root steam directory 252 | $class = ucfirst((string) $name); 253 | $steamClass = '\Syntax\SteamApi\Steam\\' . $class; 254 | 255 | if (class_exists($steamClass)) { 256 | return new $steamClass($this->steamId); 257 | } 258 | 259 | // Inside a nested directory 260 | $class = implode('\\', preg_split('/(?=[A-Z])/', $class, -1, PREG_SPLIT_NO_EMPTY)); 261 | $steamClass = '\Syntax\SteamApi\Steam\\' . $class; 262 | 263 | if (class_exists($steamClass)) { 264 | return new $steamClass($this->steamId); 265 | } 266 | 267 | // Nothing found 268 | throw new ClassNotFoundException($name); 269 | } 270 | 271 | /** 272 | * @param Collection $objects 273 | * 274 | * @return Collection 275 | */ 276 | protected function sortObjects(Collection $objects): Collection 277 | { 278 | return $objects->sortBy(fn($object) => $object->name); 279 | } 280 | 281 | /** 282 | * @param string $method 283 | * @param string $version 284 | */ 285 | protected function setApiDetails(string $method, string $version): void 286 | { 287 | $this->method = $method; 288 | $this->version = $version; 289 | } 290 | 291 | /** 292 | * @throws ApiArgumentRequired 293 | * @throws ApiCallFailedException 294 | * @throws GuzzleException 295 | * @throws \JsonException 296 | */ 297 | protected function getServiceResponse($arguments) 298 | { 299 | $arguments = json_encode($arguments, JSON_THROW_ON_ERROR); 300 | 301 | // Get the client 302 | $body = $this->setUpService($arguments); 303 | 304 | if (!isset($body->response) || empty((array)$body->response)) { 305 | throw new ApiCallFailedException('Api call failed to complete due to an empty response.', 500); 306 | } 307 | 308 | return $body->response; 309 | } 310 | 311 | /** 312 | * @throws ApiCallFailedException 313 | * @throws GuzzleException 314 | */ 315 | protected function getClientResponse($arguments) 316 | { 317 | // Get the client 318 | $body = $this->setUpClient($arguments); 319 | 320 | if (!isset($body->response) || empty((array)$body->response)) { 321 | throw new ApiCallFailedException('Api call failed to complete due to an empty response.', 500); 322 | } 323 | 324 | return $body->response; 325 | } 326 | 327 | /** 328 | * @return string 329 | * @throws Exceptions\InvalidApiKeyException 330 | */ 331 | protected function getApiKey(): string 332 | { 333 | $apiKey = Config::get('steam-api.steamApiKey'); 334 | 335 | if ($apiKey == 'YOUR-API-KEY') { 336 | throw new Exceptions\InvalidApiKeyException(); 337 | } 338 | 339 | if (is_null($apiKey) || $apiKey === '' || $apiKey == []) { 340 | $apiKey = getenv('apiKey'); 341 | } 342 | 343 | return $apiKey; 344 | } 345 | 346 | /** 347 | * @throws UnrecognizedId 348 | */ 349 | private function convertSteamIdTo64(): void 350 | { 351 | if (is_array($this->steamId)) { 352 | array_walk( 353 | /** 354 | * @throws UnrecognizedId 355 | */ 356 | $this->steamId, function (&$id) { 357 | // Convert the id to all types and grab the 64 bit version 358 | $id = $this->convertToAll($id)->id64; 359 | }); 360 | } else { 361 | // Convert the id to all types and grab the 64 bit version 362 | $this->steamId = $this->convertToAll($this->steamId)->id64; 363 | } 364 | } 365 | } 366 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Containers/Achievement.php: -------------------------------------------------------------------------------- 1 | apiName = (string) $achievement->apiname; 24 | $this->achieved = (int)(string) $achievement['closed']; 25 | $this->name = (string) $achievement->name; 26 | $this->description = (string) $achievement->description; 27 | $this->icon = (string) $achievement->iconClosed; 28 | $this->iconGray = (string) $achievement->iconOpen; 29 | $this->unlockTimestamp = isset($achievement->unlockTimestamp) ? (int)(string) $achievement->unlockTimestamp : null; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Containers/App.php: -------------------------------------------------------------------------------- 1 | id = $app->steam_appid; 68 | $this->type = $app->type; 69 | $this->name = $app->name; 70 | $this->controllerSupport = $this->checkIssetField($app, 'controller_support', 'None'); 71 | $this->description = $app->detailed_description; 72 | $this->about = $app->about_the_game; 73 | $this->fullgame = $this->checkIssetField($app, 'fullgame', $this->getFakeFullgameObject()); 74 | $this->header = $app->header_image; 75 | $this->website = $this->checkIsNullField($app, 'website', 'None'); 76 | $this->pcRequirements = $app->pc_requirements; 77 | $this->legal = $this->checkIssetField($app, 'legal_notice', 'None'); 78 | $this->developers = $this->checkIssetCollection($app, 'developers'); 79 | $this->publishers = new Collection($app->publishers); 80 | $this->price = $this->checkIssetField($app, 'price_overview', $this->getFakePriceObject()); 81 | $this->platforms = $app->platforms; 82 | $this->metacritic = $this->checkIssetField($app, 'metacritic', $this->getFakeMetacriticObject()); 83 | $this->categories = $this->checkIssetCollection($app, 'categories'); 84 | $this->genres = $this->checkIssetCollection($app, 'genres'); 85 | $this->release = $app->release_date; 86 | $this->requiredAge = (int)$app->required_age; 87 | $this->isFree = $app->is_free; 88 | $this->shortDescription = $app->short_description; 89 | $this->supportedLanguages = $this->checkIssetField($app, 'supported_languages', 'None'); 90 | $this->recommendations = $this->checkIssetField($app, 'recommendations', $this->getFakeRecommendationsObject()); 91 | $this->achievements = $this->checkIssetField($app, 'achievements', $this->getFakeAchievementsObject()); 92 | $this->dlc = $this->checkIssetCollection($app, 'dlc', new Collection()); 93 | $this->movies = $this->checkIssetCollection($app, 'movies', new Collection()); 94 | 95 | } 96 | 97 | protected function getFakeMetacriticObject(): stdClass 98 | { 99 | $object = new stdClass(); 100 | $object->url = null; 101 | $object->score = 'No Score'; 102 | return $object; 103 | } 104 | 105 | protected function getFakePriceObject(): stdClass 106 | { 107 | $object = new stdClass(); 108 | $object->final = 'No price found'; 109 | return $object; 110 | } 111 | 112 | protected function getFakeFullgameObject(): stdClass 113 | { 114 | $object = new stdClass(); 115 | $object->appid = null; 116 | $object->name = 'No parent game found'; 117 | return $object; 118 | } 119 | 120 | protected function getFakeRecommendationsObject(): stdClass 121 | { 122 | $object = new stdClass(); 123 | $object->total = 0; 124 | return $object; 125 | } 126 | 127 | protected function getFakeAchievementsObject(): stdClass 128 | { 129 | $object = new stdClass(); 130 | $object->total = 0; 131 | return $object; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Containers/BaseContainer.php: -------------------------------------------------------------------------------- 1 | $field) ? $app->$field : $value; 18 | } 19 | 20 | /** 21 | * @param $app 22 | * @param string $field 23 | * 24 | * @return mixed 25 | */ 26 | protected function checkIssetField($app, string $field, mixed $value = null): mixed 27 | { 28 | return $app->$field ?? $value; 29 | } 30 | 31 | /** 32 | * @param $app 33 | * @param string $field 34 | * @param mixed|null $value 35 | * @return mixed 36 | */ 37 | protected function checkIssetCollection($app, string $field, mixed $value = null): mixed 38 | { 39 | return isset($app->$field) ? new Collection($app->$field) : $value; 40 | } 41 | 42 | /** 43 | * @param string $image 44 | * 45 | * @return string 46 | */ 47 | protected function getImageForAvatar(string $image): string 48 | { 49 | return ''; 50 | } 51 | 52 | /** 53 | * Very simple pluralize helper for days, hours, minutes. 54 | * This is not an end all solution to pluralization. 55 | * 56 | * @param $word 57 | * @param $count 58 | * 59 | * @return string 60 | */ 61 | protected function pluralize($word, $count): string 62 | { 63 | if ((int) $count === 1) { 64 | return $word .' '; 65 | } 66 | 67 | return $word .'s '; 68 | } 69 | 70 | /** 71 | * Convert a value from pure minutes into something easily digestible. 72 | * 73 | * @param $minutes 74 | * 75 | * @return string 76 | */ 77 | protected function convertFromMinutes($minutes): string 78 | { 79 | $seconds = $minutes * 60; 80 | 81 | $secondsInAMinute = 60; 82 | $secondsInAnHour = 60 * $secondsInAMinute; 83 | $secondsInADay = 24 * $secondsInAnHour; 84 | 85 | // extract days 86 | $days = floor($seconds / $secondsInADay); 87 | 88 | // extract hours 89 | $hourSeconds = $seconds % $secondsInADay; 90 | $hours = floor($hourSeconds / $secondsInAnHour); 91 | 92 | // extract minutes 93 | $minuteSeconds = $hourSeconds % $secondsInAnHour; 94 | $minutes = floor($minuteSeconds / $secondsInAMinute); 95 | 96 | // return the final string 97 | $output = ''; 98 | 99 | if ($days > 0) { 100 | $output .= $days . ' ' . $this->pluralize('day', $days); 101 | } 102 | 103 | if ($hours > 0) { 104 | $output .= $hours . ' ' . $this->pluralize('hour', $hours); 105 | } 106 | 107 | $output .= $minutes . ' ' . $this->pluralize('minute', $minutes); 108 | 109 | return $output; 110 | } 111 | } 112 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Containers/Game.php: -------------------------------------------------------------------------------- 1 | appId = $app->appid; 30 | $this->name = $this->checkIssetField($app, 'name'); 31 | $this->playtimeTwoWeeks = $this->checkIssetField($app, 'playtime_2weeks', 0); 32 | $this->playtimeTwoWeeksReadable = $this->convertFromMinutes($this->playtimeTwoWeeks); 33 | $this->playtimeForever = $this->checkIssetField($app, 'playtime_forever', 0); 34 | $this->playtimeForeverReadable = $this->convertFromMinutes($this->playtimeForever); 35 | $this->icon = $this->checkIssetImage($app, 'img_icon_url'); 36 | $this->logo = $this->checkIssetImage($app, 'img_logo_url'); 37 | $this->header = 'http://cdn.akamai.steamstatic.com/steam/apps/' . $this->appId . '/header.jpg'; 38 | $this->hasCommunityVisibleStats = $this->checkIssetField($app, 'has_community_visible_stats', 0); 39 | } 40 | 41 | /** 42 | * @param $app 43 | * @param string $field 44 | * @param string|null $value 45 | * 46 | * @return null|string 47 | */ 48 | protected function checkIssetImage($app, string $field, string $value = null): ?string 49 | { 50 | return isset($app->$field) ? $this->getImageForGame($app->appid, $app->$field) : $value; 51 | } 52 | 53 | protected function getImageForGame($appId, $hash): ?string 54 | { 55 | if ($hash != null) { 56 | return 'http://media.steampowered.com/steamcommunity/public/images/apps/' . $appId . '/' . $hash . '.jpg'; 57 | } 58 | 59 | return null; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Containers/GameDetails.php: -------------------------------------------------------------------------------- 1 | checkIssetField($gameDetails, 'gameid'); 20 | 21 | $this->serverIp = $this->checkIssetField($gameDetails, 'gameserverip'); 22 | $this->serverSteamId = $this->checkIssetField($gameDetails, 'gameserversteamid'); 23 | $this->extraInfo = $this->checkIssetField($gameDetails, 'gameextrainfo'); 24 | $this->lobbyId = $this->checkIssetField($gameDetails, 'lobbysteamid'); 25 | $this->gameId = is_null($gameId) ? null : (int)$gameId; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Containers/Group.php: -------------------------------------------------------------------------------- 1 | groupID64 = (string)$group->groupID64; 29 | $this->groupDetails = new Details($group->groupDetails); 30 | $this->memberDetails = new MemberDetails($group->groupDetails); 31 | $this->startingMember = (int)(string)$group->startingMember; 32 | 33 | $this->members = new Collection; 34 | 35 | foreach ($group->members->steamID64 as $member) { 36 | $this->members->add((new Client)->convertId((string)$member)); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Containers/Group/Details.php: -------------------------------------------------------------------------------- 1 | name = (string)$details->groupName; 32 | $this->url = (string)$details->groupUrl; 33 | $this->headline = (string)$details->headline; 34 | $this->summary = (string)$details->summary; 35 | $this->avatarIcon = $this->getImageForAvatar((string)$details->avatarIcon); 36 | $this->avatarMedium = $this->getImageForAvatar((string)$details->avatarMedium); 37 | $this->avatarFull = $this->getImageForAvatar((string)$details->avatarFull); 38 | $this->avatarIconUrl = (string)$details->avatarIcon; 39 | $this->avatarMediumUrl = (string)$details->avatarMedium; 40 | $this->avatarFullUrl = (string)$details->avatarFull; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Containers/Group/MemberDetails.php: -------------------------------------------------------------------------------- 1 | count = (int)(string)$details->memberCount; 18 | $this->inChat = (int)(string)$details->membersInChat; 19 | $this->inGame = (int)(string)$details->membersInGame; 20 | $this->online = (int)(string)$details->membersOnline; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Containers/Id.php: -------------------------------------------------------------------------------- 1 | convertId($id); 27 | 28 | $this->id32 = $steamIds->id32; 29 | $this->id64 = $steamIds->id64; 30 | $this->id3 = $steamIds->id3; 31 | 32 | $this->steamId = $this->id64; 33 | $this->communityId = $this->id32; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Containers/Item.php: -------------------------------------------------------------------------------- 1 | id = $item->id; 36 | $this->originalId = $item->original_id; 37 | $this->defIndex = $item->defindex; 38 | $this->level = $item->level; 39 | $this->quality = $item->quality; 40 | $this->quantity = $item->quantity; 41 | $this->inventory = $item->inventory; 42 | $this->origin = $this->checkIssetField($item, 'origin'); 43 | $this->containedItem = $this->checkIssetField($item, 'contained_item'); 44 | $this->style = $this->checkIssetField($item, 'style'); 45 | $this->attributes = $this->checkIssetField($item, 'attributes'); 46 | 47 | $this->flags = [ 48 | 'trade' => ! $this->checkIssetField($item, 'flag_cannot_trade', false), 49 | 'craft' => ! $this->checkIssetField($item, 'flag_cannot_craft', false), 50 | ]; 51 | $this->custom = [ 52 | 'name' => $this->checkIssetField($item, 'custom_name'), 53 | 'description' => $this->checkIssetField($item, 'custom_desc'), 54 | ]; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Containers/Package.php: -------------------------------------------------------------------------------- 1 | id = (int) $id; 22 | $this->name = $package->name; 23 | $this->apps = $package->apps; 24 | $this->page_content = $this->checkIssetField($package, 'page_content', 'none'); 25 | $this->header = $this->checkIssetField($package, 'header_image', 'none'); 26 | $this->small_logo = $this->checkIssetField($package, 'small_logo', 'none'); 27 | $this->page_image = $this->checkIssetField($package, 'page_image', 'none'); 28 | $this->price = $this->checkIssetField($package, 'price', $this->getFakePriceObject()); 29 | $this->platforms = $package->platforms; 30 | $this->controller = $package->controller; 31 | $this->release = $package->release_date; 32 | } 33 | 34 | protected function getFakePriceObject(): \stdClass 35 | { 36 | $object = new \stdClass(); 37 | $object->final = 'No price found'; 38 | return $object; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Containers/Player.php: -------------------------------------------------------------------------------- 1 | steamId = $player->steamid; 60 | $this->steamIds = (new Id((int)$this->steamId)); 61 | $this->communityVisibilityState = $player->communityvisibilitystate; 62 | $this->profileState = $this->checkIssetField($player, 'profilestate'); 63 | $this->personaName = $player->personaname; 64 | $this->lastLogoff = date('F jS, Y h:ia', $this->checkIssetField($player, 'lastlogoff')); 65 | $this->profileUrl = $player->profileurl; 66 | $this->avatar = $this->getImageForAvatar($player->avatar); 67 | $this->avatarMedium = $this->getImageForAvatar($player->avatarmedium); 68 | $this->avatarFull = $this->getImageForAvatar($player->avatarfull); 69 | $this->avatarUrl = $player->avatar; 70 | $this->avatarMediumUrl = $player->avatarmedium; 71 | $this->avatarFullUrl = $player->avatarfull; 72 | $this->personaState = $this->convertPersonaState($player->personastate); 73 | $this->personaStateId = $player->personastate; 74 | $this->realName = $this->checkIssetField($player, 'realname'); 75 | $this->primaryClanId = $this->checkIssetField($player, 'primaryclanid'); 76 | $this->timecreated = $this->checkIssetField($player, 'timecreated'); 77 | $this->personaStateFlags = $this->checkIssetField($player, 'personastateflags'); 78 | $this->locCountryCode = $this->checkIssetField($player, 'loccountrycode'); 79 | $this->locStateCode = $this->checkIssetField($player, 'locstatecode'); 80 | $this->locCityId = $this->checkIssetField($player, 'loccityid'); 81 | $this->location = $this->getLocation(); 82 | $this->commentPermission = $this->checkIssetField($player, 'commentpermission'); 83 | 84 | $gameDetails = [ 85 | 'gameServerIp' => $this->checkIssetField($player, 'gameserverip'), 86 | 'gameServerSteamId' => $this->checkIssetField($player, 'gameserversteamid'), 87 | 'gameExtraInfo' => $this->checkIssetField($player, 'gameextrainfo'), 88 | 'gameId' => $this->checkIssetField($player, 'gameid'), 89 | ]; 90 | 91 | if (! empty(array_filter($gameDetails))) 92 | { 93 | $this->gameDetails = (new GameDetails($player)); 94 | } 95 | } 96 | 97 | /** 98 | * @throws \JsonException 99 | */ 100 | protected function getLocation(): \stdClass 101 | { 102 | $countriesFile = json_decode(\file_get_contents(__DIR__ . '/../Resources/countries.json'), null, 512, JSON_THROW_ON_ERROR); 103 | $result = new \stdClass; 104 | 105 | if ($this->locCountryCode != null && isset($countriesFile->{$this->locCountryCode})) { 106 | $result->country = $countriesFile->{$this->locCountryCode}->name; 107 | 108 | if ($this->locStateCode != null && isset($countriesFile->{$this->locCountryCode}->states->{$this->locStateCode})) { 109 | $result->state = $countriesFile->{$this->locCountryCode}->states->{$this->locStateCode}->name; 110 | } 111 | 112 | if ($this->locCityId != null && isset($countriesFile->{$this->locCountryCode}->states->{$this->locStateCode}) && ! empty($countriesFile->{$this->locCountryCode}->states->{$this->locStateCode}->cities)) { 113 | if (isset($countriesFile->{$this->locCountryCode}->states->{$this->locStateCode}->cities->{$this->locCityId})) { 114 | $result->city = $countriesFile->{$this->locCountryCode}->states->{$this->locStateCode}->cities->{$this->locCityId}->name; 115 | } 116 | } 117 | } 118 | 119 | return $result; 120 | } 121 | 122 | protected function convertPersonaState(int $personaState): string 123 | { 124 | return match ($personaState) { 125 | 0 => 'Offline', 126 | 1 => 'Online', 127 | 2 => 'Busy', 128 | 3 => 'Away', 129 | 4 => 'Snooze', 130 | 5 => 'Looking to Trade', 131 | 6 => 'Looking to Play', 132 | default => 'Unknown', 133 | }; 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Containers/Player/Level.php: -------------------------------------------------------------------------------- 1 | playerXp = $levelDetails->player_xp; 24 | $this->playerLevel = $levelDetails->player_level; 25 | $this->xpToLevelUp = $levelDetails->player_xp_needed_to_level_up; 26 | $this->xpForCurrentLevel = $levelDetails->player_xp_needed_current_level; 27 | 28 | $this->currentLevelFloor = $this->xpForCurrentLevel; 29 | $this->currentLevelCeiling = $this->playerXp + $this->xpToLevelUp; 30 | 31 | // arbitrary range formula. n = value in the middle ( n - min ) / ( max - min ) * 100 32 | $this->percentThroughLevel = ($this->playerXp - $this->currentLevelFloor) / ($this->currentLevelCeiling - $this->currentLevelFloor) * 100; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Exceptions/ApiArgumentRequired.php: -------------------------------------------------------------------------------- 1 | url = 'http://store.steampowered.com/'; 23 | $this->interface = 'api'; 24 | } 25 | 26 | /** 27 | * @param $appIds 28 | * @param null $country 29 | * @param null $language 30 | * @return Collection 31 | * @throws ApiCallFailedException 32 | * @throws GuzzleException 33 | */ 34 | public function appDetails($appIds, $country = null, $language = null): Collection 35 | { 36 | // Set up the api details 37 | $this->method = 'appdetails'; 38 | $this->version = null; 39 | 40 | // Set up the arguments 41 | $arguments = [ 42 | 'appids' => $appIds, 43 | 'cc' => $country, 44 | 'l' => $language, 45 | ]; 46 | 47 | // Get the client 48 | $client = $this->setUpClient($arguments); 49 | 50 | return $this->convertToObjects($client); 51 | } 52 | 53 | /** 54 | * @throws ApiCallFailedException 55 | * @throws GuzzleException 56 | */ 57 | public function GetAppList() 58 | { 59 | // Set up the api details 60 | $this->url = 'http://api.steampowered.com/'; 61 | $this->interface = 'ISteamApps'; 62 | $this->method = __FUNCTION__; 63 | $this->version = 'v0001'; 64 | 65 | // Get the client 66 | $client = $this->setUpClient(); 67 | 68 | return $client->applist->apps->app; 69 | } 70 | 71 | protected function convertToObjects($apps): Collection 72 | { 73 | $convertedApps = $this->convertGames($apps); 74 | 75 | return $this->sortObjects($convertedApps); 76 | } 77 | 78 | /** 79 | * @param $apps 80 | * 81 | * @return Collection 82 | */ 83 | protected function convertGames($apps): Collection 84 | { 85 | $convertedApps = new Collection(); 86 | 87 | foreach ($apps as $app) { 88 | if (isset($app->data)) { 89 | $convertedApps->add(new AppContainer($app->data)); 90 | } 91 | } 92 | 93 | return $convertedApps; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Steam/Group.php: -------------------------------------------------------------------------------- 1 | method = 'memberslistxml'; 14 | 15 | if (is_numeric($group)) { 16 | $this->url = 'http://steamcommunity.com/gid/'; 17 | } else { 18 | $this->url = 'http://steamcommunity.com/groups/'; 19 | } 20 | 21 | $this->url = $this->url . $group; 22 | 23 | // Set up the arguments 24 | $arguments = [ 25 | 'xml' => 1, 26 | ]; 27 | 28 | // Get the client 29 | $client = $this->setUpXml($arguments); 30 | 31 | // Clean up the games 32 | return new GroupContainer($client); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Steam/Item.php: -------------------------------------------------------------------------------- 1 | url = 'http://store.steampowered.com/'; 19 | $this->isService = true; 20 | $this->interface = 'api'; 21 | } 22 | 23 | /** 24 | * @throws ApiCallFailedException 25 | * @throws GuzzleException 26 | */ 27 | public function GetPlayerItems($appId, $steamId): Inventory 28 | { 29 | // Set up the api details 30 | $this->url = 'http://api.steampowered.com/'; 31 | $this->interface = 'IEconItems_' . $appId; 32 | $this->method = __FUNCTION__; 33 | $this->version = 'v0001'; 34 | 35 | $arguments = ['steamId' => $steamId]; 36 | 37 | $client = $this->setUpClient($arguments); 38 | 39 | // Clean up the items 40 | $items = $this->convertToObjects($client->result->items); 41 | 42 | // Return a full inventory 43 | return new Inventory($client->result->num_backpack_slots, $items); 44 | } 45 | 46 | protected function convertToObjects($items): Collection 47 | { 48 | return $this->convertItems($items); 49 | } 50 | 51 | /** 52 | * @param array $items 53 | * 54 | * @return Collection 55 | */ 56 | protected function convertItems(array $items): Collection 57 | { 58 | $convertedItems = new Collection(); 59 | 60 | foreach ($items as $item) { 61 | $convertedItems->add(new ItemContainer($item)); 62 | } 63 | 64 | return $convertedItems; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Steam/News.php: -------------------------------------------------------------------------------- 1 | interface = 'ISteamNews'; 15 | } 16 | 17 | /** 18 | * @throws ApiCallFailedException 19 | * @throws GuzzleException 20 | */ 21 | public function GetNewsForApp($appId, $count = 5, $maxLength = null) 22 | { 23 | // Set up the api details 24 | $this->method = __FUNCTION__; 25 | $this->version = 'v0002'; 26 | 27 | // Set up the arguments 28 | $arguments = [ 29 | 'appid' => $appId, 30 | 'count' => $count, 31 | ]; 32 | 33 | if (! is_null($maxLength)) { 34 | $arguments['maxlength'] = $maxLength; 35 | } 36 | 37 | // Get the client 38 | $client = $this->setUpClient($arguments); 39 | 40 | return $client->appnews; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Steam/Package.php: -------------------------------------------------------------------------------- 1 | url = 'http://store.steampowered.com/'; 18 | $this->interface = 'api'; 19 | } 20 | 21 | /** 22 | * @throws ApiCallFailedException 23 | * @throws GuzzleException 24 | */ 25 | public function packageDetails($packId, $cc = null, $language = null): Collection 26 | { 27 | // Set up the api details 28 | $this->method = 'packagedetails'; 29 | $this->version = null; 30 | // Set up the arguments 31 | $arguments = [ 32 | 'packageids' => $packId, 33 | 'cc' => $cc, 34 | 'l' => $language, 35 | ]; 36 | // Get the client 37 | $client = $this->setUpClient($arguments); 38 | 39 | return $this->convertToObjects($client, $packId); 40 | } 41 | 42 | protected function convertToObjects($package, $packId): Collection 43 | { 44 | $convertedPacks = $this->convertPacks($package, $packId); 45 | return $this->sortObjects($convertedPacks); 46 | } 47 | 48 | /** 49 | * @param $packages 50 | * @param $packId 51 | * @return Collection 52 | */ 53 | protected function convertPacks($packages, $packId): Collection 54 | { 55 | $convertedPacks = new Collection(); 56 | foreach ($packages as $package) { 57 | if (isset($package->data)) { 58 | $convertedPacks->add(new PackageContainer($package->data, $packId)); 59 | } 60 | } 61 | 62 | return $convertedPacks; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Steam/Player.php: -------------------------------------------------------------------------------- 1 | interface = 'IPlayerService'; 19 | $this->isService = true; 20 | $this->steamId = $steamId; 21 | } 22 | 23 | /** 24 | * @throws ApiCallFailedException 25 | * @throws ApiArgumentRequired 26 | * @throws GuzzleException 27 | * @throws \JsonException 28 | */ 29 | public function GetSteamLevel() 30 | { 31 | // Set up the api details 32 | $this->setApiDetails(__FUNCTION__, 'v0001'); 33 | 34 | // Set up the arguments 35 | $arguments = ['steamId' => $this->steamId]; 36 | 37 | // Get the client 38 | $client = $this->getServiceResponse($arguments); 39 | 40 | return $client->player_level; 41 | } 42 | 43 | /** 44 | * @throws ApiCallFailedException 45 | * @throws ApiArgumentRequired 46 | * @throws GuzzleException 47 | * @throws \JsonException 48 | */ 49 | public function GetPlayerLevelDetails(): ?Level 50 | { 51 | $details = $this->GetBadges(); 52 | 53 | if(count((array)$details) == 0){ 54 | return null; 55 | } 56 | 57 | return new Level($details); 58 | } 59 | 60 | /** 61 | * @throws ApiCallFailedException 62 | * @throws ApiArgumentRequired 63 | * @throws GuzzleException 64 | * @throws \JsonException 65 | */ 66 | public function GetBadges() 67 | { 68 | // Set up the api details 69 | $this->setApiDetails(__FUNCTION__, 'v0001'); 70 | 71 | // Set up the arguments 72 | $arguments = ['steamId' => $this->steamId]; 73 | 74 | // Get the client 75 | return $this->getServiceResponse($arguments); 76 | } 77 | 78 | /** 79 | * @throws ApiArgumentRequired 80 | * @throws ApiCallFailedException 81 | * @throws GuzzleException 82 | * @throws \JsonException 83 | */ 84 | public function GetCommunityBadgeProgress($badgeId = null) 85 | { 86 | // Set up the api details 87 | $this->setApiDetails(__FUNCTION__, 'v0001'); 88 | 89 | // Set up the arguments 90 | $arguments = ['steamId' => $this->steamId]; 91 | if ($badgeId != null) { 92 | $arguments['badgeid'] = $badgeId; 93 | } 94 | 95 | // Get the client 96 | return $this->getServiceResponse($arguments); 97 | } 98 | 99 | /** 100 | * @throws ApiCallFailedException 101 | * @throws ApiArgumentRequired 102 | * @throws GuzzleException 103 | * @throws \JsonException 104 | */ 105 | public function GetOwnedGames($includeAppInfo = true, $includePlayedFreeGames = false, $appIdsFilter = []): Collection 106 | { 107 | // Set up the api details 108 | $this->setApiDetails(__FUNCTION__, 'v0001'); 109 | 110 | // Set up the arguments 111 | $arguments = ['steamId' => $this->steamId]; 112 | if ($includeAppInfo) { 113 | $arguments['include_appinfo'] = $includeAppInfo; 114 | } 115 | if ($includePlayedFreeGames) { 116 | $arguments['include_played_free_games'] = $includePlayedFreeGames; 117 | } 118 | 119 | $appIdsFilter = (array) $appIdsFilter; 120 | 121 | if (count($appIdsFilter) > 0) { 122 | $arguments['appids_filter'] = $appIdsFilter; 123 | } 124 | 125 | // Get the client 126 | $client = $this->getServiceResponse($arguments); 127 | 128 | // Clean up the games 129 | return $this->convertToObjects($client->games ?? []); 130 | } 131 | 132 | /** 133 | * @throws ApiCallFailedException 134 | * @throws ApiArgumentRequired 135 | * @throws GuzzleException 136 | * @throws \JsonException 137 | */ 138 | public function GetRecentlyPlayedGames($count = null): ?Collection 139 | { 140 | // Set up the api details 141 | $this->setApiDetails(__FUNCTION__, 'v0001'); 142 | 143 | // Set up the arguments 144 | $arguments = ['steamId' => $this->steamId]; 145 | if (! is_null($count)) { 146 | $arguments['count'] = $count; 147 | } 148 | 149 | // Get the client 150 | $client = $this->getServiceResponse($arguments); 151 | 152 | if (isset($client->total_count) && $client->total_count > 0) { 153 | // Clean up the games 154 | return $this->convertToObjects($client->games); 155 | } 156 | 157 | return null; 158 | } 159 | 160 | /** 161 | * @throws ApiCallFailedException 162 | * @throws ApiArgumentRequired 163 | * @throws GuzzleException 164 | * @throws \JsonException 165 | * @deprecated - use ISteamUser.CheckAppOwnership 166 | */ 167 | public function IsPlayingSharedGame($appIdPlaying): string 168 | { 169 | // Set up the api details 170 | $this->setApiDetails(__FUNCTION__, 'v0001'); 171 | 172 | // Set up the arguments 173 | $arguments = [ 174 | 'steamId' => $this->steamId, 175 | 'appid_playing' => $appIdPlaying, 176 | ]; 177 | 178 | // Get the client 179 | $client = $this->getServiceResponse($arguments); 180 | 181 | return $client->lender_steamid; 182 | } 183 | 184 | protected function convertToObjects($games): Collection 185 | { 186 | $convertedGames = $this->convertGames($games); 187 | 188 | return $this->sortObjects($convertedGames); 189 | } 190 | 191 | private function convertGames($games): Collection 192 | { 193 | $convertedGames = new Collection; 194 | 195 | foreach ($games as $game) { 196 | $convertedGames->add(new Game($game)); 197 | } 198 | 199 | return $convertedGames; 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Steam/User.php: -------------------------------------------------------------------------------- 1 | interface = 'ISteamUser'; 24 | $this->steamId = $steamId; 25 | } 26 | 27 | /** 28 | * Get the user_ids for a display name. 29 | * 30 | * @param null $displayName Custom name from steam profile link. 31 | * 32 | * @return mixed 33 | * 34 | * @throws ApiArgumentRequired 35 | * @throws ApiCallFailedException 36 | * @throws GuzzleException 37 | * @throws UnrecognizedId 38 | * @throws \JsonException 39 | */ 40 | public function ResolveVanityURL($displayName = null): mixed 41 | { 42 | // This only works with a display name. Make sure we have one. 43 | if ($displayName == null) { 44 | throw new UnrecognizedId('You must pass a display name for this call.'); 45 | } 46 | 47 | // Set up the api details 48 | $this->method = __FUNCTION__; 49 | $this->version = 'v0001'; 50 | 51 | $results = $this->getClientResponse(['vanityurl' => $displayName]); 52 | 53 | // Return the full steam ID object for the display name. 54 | return $results->message ?? $this->convertId($results->steamid); 55 | } 56 | 57 | /** 58 | * @param string|null $steamId 59 | * 60 | * @return array 61 | */ 62 | public function GetPlayerSummaries(string $steamId = null): array 63 | { 64 | // Set up the api details 65 | $this->method = __FUNCTION__; 66 | $this->version = 'v0002'; 67 | 68 | if ($steamId == null) { 69 | $steamId = $this->steamId; 70 | } 71 | 72 | $steamId = implode(',', (array)$steamId); 73 | 74 | $chunks = array_chunk(explode(',', $steamId), 100); 75 | 76 | $map = array_map($this->getChunkedPlayerSummaries(...), $chunks); 77 | 78 | return $this->compressPlayerSummaries($map); 79 | } 80 | 81 | /** 82 | * @param $chunk 83 | * @return array 84 | * @throws ApiCallFailedException 85 | * @throws GuzzleException 86 | * @throws \JsonException 87 | * @throws ApiArgumentRequired 88 | */ 89 | private function getChunkedPlayerSummaries($chunk): array 90 | { 91 | // Set up the arguments 92 | $arguments = [ 93 | 'steamids' => implode(',', $chunk), 94 | ]; 95 | 96 | // Get the client 97 | $client = $this->setUpClient($arguments)->response; 98 | 99 | // Clean up the games 100 | return $this->convertToObjects($client->players); 101 | } 102 | 103 | private function compressPlayerSummaries($summaries): array 104 | { 105 | $result = []; 106 | $keys = array_keys($summaries); 107 | 108 | foreach ($keys as $key) { 109 | $result = array_merge($result, $summaries[$key]); 110 | } 111 | 112 | return $result; 113 | } 114 | 115 | /** 116 | * @throws ApiCallFailedException 117 | * @throws GuzzleException 118 | */ 119 | public function GetPlayerBans($steamId = null) 120 | { 121 | // Set up the api details 122 | $this->method = __FUNCTION__; 123 | $this->version = 'v1'; 124 | 125 | if ($steamId == null) { 126 | $steamId = $this->steamId; 127 | } 128 | 129 | // Set up the arguments 130 | $arguments = [ 131 | 'steamids' => implode(',', (array)$steamId), 132 | ]; 133 | 134 | // Get the client 135 | $client = $this->setUpClient($arguments); 136 | 137 | return $client->players; 138 | } 139 | 140 | /** 141 | * @throws ApiCallFailedException 142 | * @throws GuzzleException 143 | */ 144 | public function GetFriendList($relationship = 'all', $summaries = true): array 145 | { 146 | // Set up the api details 147 | $this->method = __FUNCTION__; 148 | $this->version = 'v0001'; 149 | 150 | if (! in_array($relationship, $this->friendRelationships)) { 151 | throw new InvalidArgumentException('Provided relationship [' . $relationship . '] is not valid. Please select from: ' . implode(', ', $this->friendRelationships)); 152 | } 153 | 154 | // Set up the arguments 155 | $arguments = [ 156 | 'steamid' => $this->steamId, 157 | 'relationship' => $relationship, 158 | ]; 159 | 160 | // Get the client 161 | $client = $this->setUpClient($arguments)->friendslist; 162 | 163 | // Clean up the games 164 | $steamIds = []; 165 | 166 | foreach ($client->friends as $friend) { 167 | $steamIds[] = $friend->steamid; 168 | } 169 | 170 | if($summaries) { 171 | $friends = $this->GetPlayerSummaries(implode(',', $steamIds)); 172 | } else { 173 | $friends = $steamIds; 174 | } 175 | 176 | return $friends; 177 | } 178 | 179 | protected function convertToObjects($players): array 180 | { 181 | $cleanedPlayers = []; 182 | 183 | foreach ($players as $player) { 184 | if(property_exists($player, 'steamid')) { 185 | $cleanedPlayers[] = new PlayerContainer($player); 186 | } 187 | } 188 | 189 | return $cleanedPlayers; 190 | } 191 | } 192 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/Steam/User/Stats.php: -------------------------------------------------------------------------------- 1 | interface = 'ISteamUserStats'; 17 | $this->steamId = $steamId; 18 | } 19 | 20 | /** 21 | * @param $appId 22 | * 23 | * @return array|null 24 | * @throws GuzzleException 25 | * @throws ApiCallFailedException 26 | * @deprecated 27 | * 28 | */ 29 | public function GetPlayerAchievementsAPI($appId): ?array 30 | { 31 | // Set up the api details 32 | $this->method = 'GetPlayerAchievementsAPI'; 33 | $this->version = 'v0001'; 34 | 35 | // Set up the arguments 36 | $arguments = [ 37 | 'steamid' => $this->steamId, 38 | 'appid' => $appId, 39 | 'l' => 'english', 40 | ]; 41 | 42 | // Get the client 43 | $stats = $this->GetSchemaForGame($appId); 44 | 45 | // Make sure the game has achievements 46 | if ($stats == null || $stats->game->availableGameStats->achievements == null) { 47 | return null; 48 | } 49 | 50 | $client = $this->setUpClient($arguments)->playerstats; 51 | $stats = $stats->game->availableGameStats->achievements; 52 | 53 | // Clean up the games 54 | return $this->convertToObjects($client->achievements); 55 | } 56 | 57 | public function GetPlayerAchievements($appId): ?array 58 | { 59 | // Set up the api details 60 | $this->interface = null; 61 | $this->method = 'achievements'; 62 | 63 | if (is_numeric($this->steamId)) { 64 | $this->url = 'http://steamcommunity.com/profiles/'; 65 | } else { 66 | $this->url = 'http://steamcommunity.com/id/'; 67 | } 68 | 69 | $this->url = $this->url . $this->steamId . '/stats/' . $appId; 70 | 71 | // Set up the arguments 72 | $arguments = [ 73 | 'xml' => 1, 74 | ]; 75 | 76 | try { 77 | // Get the client 78 | $client = $this->setUpXml($arguments); 79 | 80 | // Clean up the games 81 | return $this->convertToObjects($client->achievements->achievement); 82 | } catch (Exception) { 83 | // In rare cases, games can force the use of a simplified name instead of an app ID 84 | // In these cases, try again by grabbing the redirected url. 85 | if (is_int($appId)) { 86 | $this->getRedirectUrl(); 87 | 88 | try { 89 | // Get the client 90 | $client = $this->setUpXml($arguments); 91 | 92 | // Clean up the games 93 | return $this->convertToObjects($client->achievements->achievement); 94 | } catch (Exception) { 95 | return null; 96 | } 97 | } 98 | 99 | // If the name and ID fail, return null. 100 | return null; 101 | } 102 | } 103 | 104 | /** 105 | * @throws ApiCallFailedException 106 | * @throws GuzzleException 107 | */ 108 | public function GetGlobalAchievementPercentagesForApp($gameId) 109 | { 110 | // Set up the api details 111 | $this->method = __FUNCTION__; 112 | $this->version = 'v0002'; 113 | 114 | // Set up the arguments 115 | $arguments = [ 116 | 'gameid' => $gameId, 117 | 'l' => 'english', 118 | ]; 119 | 120 | // Get the client 121 | $client = $this->setUpClient($arguments)->achievementpercentages; 122 | 123 | return $client->achievements; 124 | } 125 | 126 | /** 127 | * @param $appId int Steam 64 id 128 | * @param $all bool Return all stats when true and only achievements when false 129 | * 130 | * @return mixed 131 | * @throws ApiCallFailedException 132 | * @throws GuzzleException 133 | */ 134 | public function GetUserStatsForGame(int $appId, bool $all = false): mixed 135 | { 136 | // Set up the api details 137 | $this->method = __FUNCTION__; 138 | $this->version = 'v0002'; 139 | 140 | // Set up the arguments 141 | $arguments = [ 142 | 'steamid' => $this->steamId, 143 | 'appid' => $appId, 144 | 'l' => 'english', 145 | ]; 146 | 147 | // Get the client 148 | $client = $this->setUpClient($arguments)->playerstats; 149 | 150 | // Games like DOTA and CS:GO have additional stats here. Return everything if they are wanted. 151 | if ($all === true) { 152 | return $client; 153 | } 154 | 155 | return $client->achievements; 156 | } 157 | 158 | /** 159 | * @param $appId 160 | * 161 | * @return mixed 162 | * @throws ApiCallFailedException 163 | * @throws GuzzleException 164 | * @link https://wiki.teamfortress.com/wiki/WebAPI/GetSchemaForGame 165 | * 166 | */ 167 | public function GetSchemaForGame($appId): mixed 168 | { 169 | // Set up the api details 170 | $this->method = __FUNCTION__; 171 | $this->version = 'v0002'; 172 | 173 | // Set up the arguments 174 | $arguments = [ 175 | 'appid' => $appId, 176 | 'l' => 'english', 177 | ]; 178 | 179 | // Get the client 180 | return $this->setUpClient($arguments); 181 | } 182 | 183 | protected function convertToObjects($achievements): array 184 | { 185 | $cleanedAchievements = []; 186 | 187 | foreach ($achievements as $achievement) { 188 | $cleanedAchievements[] = new Achievement($achievement); 189 | } 190 | 191 | return $cleanedAchievements; 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/SteamApiServiceProvider.php: -------------------------------------------------------------------------------- 1 | publishes([__DIR__ . '/../../config/config.php' => config_path('steam-api.php')]); 17 | } 18 | 19 | /** 20 | * Register the service provider. 21 | * 22 | * @return void 23 | */ 24 | public function register(): void 25 | { 26 | $this->app->singleton('steam-api', fn () => new Client()); 27 | } 28 | 29 | /** 30 | * Get the services provided by the provider. 31 | * 32 | * @return string[] 33 | */ 34 | public function provides(): array 35 | { 36 | return ['steam-api']; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/Syntax/SteamApi/SteamId.php: -------------------------------------------------------------------------------- 1 | convertToAll($id); 31 | 32 | switch ($format) { 33 | case 'ID32': 34 | case 'id32': 35 | case 32: 36 | return $this->formatted->{self::$ID32}; 37 | case 'ID64': 38 | case 'id64': 39 | case 64: 40 | return $this->formatted->{self::$ID64}; 41 | case 'ID3': 42 | case 'id3': 43 | case 3: 44 | return $this->formatted->{self::$ID3}; 45 | default: 46 | return $this->formatted; 47 | } 48 | } 49 | 50 | protected function setUpFormatted(): void 51 | { 52 | $this->formatted = new \stdClass(); 53 | $this->formatted->{self::$ID32} = null; 54 | $this->formatted->{self::$ID64} = null; 55 | $this->formatted->{self::$ID3} = null; 56 | } 57 | 58 | /** 59 | * @throws UnrecognizedId 60 | */ 61 | private function convertToAll($id) 62 | { 63 | [$type, $matches] = $this->determineIDType($id); 64 | 65 | $this->getRawValue($id, $type, $matches); 66 | 67 | // Convert to each type 68 | $this->convertToID32(); 69 | $this->convertToID64(); 70 | $this->convertToID3(); 71 | 72 | return $this->formatted; 73 | } 74 | 75 | private function convertToID32(): void 76 | { 77 | $z = bcdiv($this->rawValue, '2', 0); 78 | $y = bcmul($z, '2', 0); 79 | $y = bcsub($this->rawValue, $y, 0); 80 | $formatted = "STEAM_1:$y:$z"; 81 | $this->formatted->{self::$ID32} = $formatted; 82 | } 83 | 84 | private function convertToID64(): void 85 | { 86 | $formatted = bcadd($this->rawValue, self::$id64Base, 0); 87 | $this->formatted->{self::$ID64} = $formatted; 88 | } 89 | 90 | private function convertToID3(): void 91 | { 92 | $formatted = "[U:1:$this->rawValue]"; 93 | $this->formatted->{self::$ID3} = $formatted; 94 | } 95 | 96 | /** 97 | * @throws UnrecognizedId 98 | */ 99 | private function determineIDType($id): array 100 | { 101 | $id = trim((string) $id); 102 | 103 | if (preg_match('/^STEAM_[0-1]:([0-1]):([0-9]+)$/', $id, $matches)) { 104 | return ['ID32', $matches]; 105 | } 106 | if (preg_match('/^[0-9]+$/', $id)) { 107 | return ['ID64', null]; 108 | } 109 | if (preg_match('/^\[U:1:([0-9]+)\]$/', $id, $matches)) { 110 | return ['ID3', $matches]; 111 | } 112 | 113 | throw new UnrecognizedId('Id [' . $id . '] is not recognized as a steam id.'); 114 | } 115 | 116 | /** 117 | * Get a raw value from any type of steam id 118 | * 119 | * @param $id 120 | * @param $type 121 | * @param $matches 122 | */ 123 | private function getRawValue($id, $type, $matches): void 124 | { 125 | switch ($type) { 126 | case 'ID32': 127 | $this->rawValue = bcmul((string) $matches[2], '2', 0); 128 | $this->rawValue = bcadd($this->rawValue, (string) $matches[1], 0); 129 | 130 | $this->formatted->{self::$ID32} = $id; 131 | 132 | break; 133 | case 'ID64': 134 | $this->rawValue = bcsub((string) $id, self::$id64Base, 0); 135 | 136 | $this->formatted->{self::$ID64} = $id; 137 | 138 | break; 139 | case 'ID3': 140 | $this->rawValue = $matches[1]; 141 | 142 | $this->formatted->{self::$ID3} = $id; 143 | 144 | break; 145 | } 146 | } 147 | 148 | } 149 | -------------------------------------------------------------------------------- /src/config/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syntaxerrors/Steam/c4524c68b9467502b4838cc15e0c2f0900153ff1/src/config/.gitkeep -------------------------------------------------------------------------------- /src/config/config.php: -------------------------------------------------------------------------------- 1 | env('STEAM_API_KEY'), 19 | 20 | ]; 21 | -------------------------------------------------------------------------------- /tests/AppTest.php: -------------------------------------------------------------------------------- 1 | steamClient->app()->appDetails($this->appId); 12 | 13 | $this->assertCount(1, $details); 14 | 15 | $detail = $details->first(); 16 | 17 | $this->checkAppProperties($detail); 18 | $this->checkClasses($detail); 19 | } 20 | 21 | /** @test */ 22 | public function it_gets_a_list_of_all_apps() 23 | { 24 | $apps = $this->steamClient->app()->GetAppList(); 25 | 26 | $this->assertGreaterThan(0, $apps); 27 | $this->assertObjectHasProperties(['appid', 'name'], $apps[0]); 28 | } 29 | 30 | /** 31 | * @param $detail 32 | */ 33 | private function checkClasses($detail): void 34 | { 35 | $this->assertInstanceOf(\Syntax\SteamApi\Containers\App::class, $detail); 36 | $this->assertInstanceOf(\Illuminate\Support\Collection::class, $detail->developers); 37 | $this->assertInstanceOf(\Illuminate\Support\Collection::class, $detail->publishers); 38 | $this->assertInstanceOf(\Illuminate\Support\Collection::class, $detail->categories); 39 | $this->assertInstanceOf(\Illuminate\Support\Collection::class, $detail->genres); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /tests/BaseTester.php: -------------------------------------------------------------------------------- 1 | load(); 39 | } 40 | 41 | $this->steamClient = new Client(); 42 | } 43 | 44 | /** @test */ 45 | public function empty_test() 46 | { 47 | $this->assertTrue(true); 48 | } 49 | 50 | protected function assertObjectHasProperties($attributes, $object): void 51 | { 52 | foreach ($attributes as $attribute) { 53 | $this->assertObjectHasProperty($attribute, $object); 54 | } 55 | } 56 | 57 | protected function checkSteamIdsProperties($steamId): void 58 | { 59 | $attributes = [ 60 | 'id32', 'id64', 'id3', 'communityId', 'steamId' 61 | ]; 62 | $this->assertObjectHasProperties($attributes, $steamId); 63 | } 64 | 65 | protected function checkPlayerProperties($friendsList): void 66 | { 67 | $attributes = [ 68 | 'steamId', 'steamIds', 'communityVisibilityState', 'profileState', 'lastLogoff', 'profileUrl', 'realName', 'primaryClanId', 'timecreated' 69 | ]; 70 | $this->assertObjectHasProperties($attributes, $friendsList[0]); 71 | 72 | $attributes = [ 73 | 'avatar', 'avatarMedium', 'avatarFull', 'avatarUrl', 'avatarMediumUrl', 'avatarFullUrl', 74 | ]; 75 | $this->assertObjectHasProperties($attributes, $friendsList[0]); 76 | 77 | $attributes = [ 78 | 'personaName', 'personaState', 'personaStateId', 'personaStateFlags' 79 | ]; 80 | $this->assertObjectHasProperties($attributes, $friendsList[0]); 81 | 82 | $attributes = [ 83 | 'locCountryCode', 'locStateCode', 'locCityId', 'location' 84 | ]; 85 | $this->assertObjectHasProperties($attributes, $friendsList[0]); 86 | 87 | $this->checkSteamIdsProperties($friendsList[0]->steamIds); 88 | } 89 | 90 | protected function checkAchievementProperties($achievement): void 91 | { 92 | $attributes = [ 93 | 'apiName', 'achieved', 'name', 'description' 94 | ]; 95 | $this->assertObjectHasProperties($attributes, $achievement); 96 | } 97 | 98 | protected function checkAppProperties($app): void 99 | { 100 | $this->checkMainAppProperties($app); 101 | $this->checkGeneralAppProperties($app); 102 | $this->checkNestedAppProperties($app); 103 | } 104 | 105 | protected function checkPackageProperties($package): void 106 | { 107 | $this->checkNestedPackageProperties($package); 108 | } 109 | 110 | protected function checkGroupProperties($group): void 111 | { 112 | $this->checkGroupMainSummaryProperties($group); 113 | $this->checkGroupDetailProperties($group); 114 | $this->checkGroupMemberDetailsProperties($group); 115 | $this->checkGroupMemberProperties($group); 116 | } 117 | 118 | /** 119 | * @param $item 120 | */ 121 | protected function checkItemProperties($item): void 122 | { 123 | $attributes = ['id', 'originalId', 'level', 'quality', 'quantity']; 124 | $this->assertObjectHasProperties($attributes, $item); 125 | } 126 | 127 | /** 128 | * @param $app 129 | */ 130 | private function checkMainAppProperties($app): void 131 | { 132 | $attributes = [ 133 | 'id', 'type', 'name', 'controllerSupport', 'description', 'about', 'fullgame', 'header', 'website', 'shortDescription' 134 | ]; 135 | $this->assertObjectHasProperties($attributes, $app); 136 | } 137 | 138 | /** 139 | * @param $app 140 | */ 141 | private function checkGeneralAppProperties($app): void 142 | { 143 | $attributes = [ 144 | 'pcRequirements', 'legal', 'developers', 'publishers', 'price', 'platforms', 'metacritic', 'categories', 'genres', 'release', 'requiredAge', 'isFree', 'supportedLanguages', 'recommendations' 145 | ]; 146 | $this->assertObjectHasProperties($attributes, $app); 147 | } 148 | 149 | /** 150 | * @param $app 151 | */ 152 | private function checkNestedAppProperties($app): void 153 | { 154 | $this->assertObjectHasProperty('minimum', $app->pcRequirements); 155 | 156 | $attributes = ['currency', 'initial', 'final', 'discount_percent']; 157 | $this->assertObjectHasProperties($attributes, $app->price); 158 | 159 | $attributes = ['windows', 'mac', 'linux']; 160 | $this->assertObjectHasProperties($attributes, $app->platforms); 161 | 162 | $attributes = ['score', 'url']; 163 | $this->assertObjectHasProperties($attributes, $app->metacritic); 164 | 165 | $attributes = ['total']; 166 | $this->assertObjectHasProperties($attributes, $app->recommendations); 167 | 168 | $attributes = ['total']; 169 | $this->assertObjectHasProperties($attributes, $app->achievements); 170 | } 171 | 172 | /** 173 | * @param $package 174 | */ 175 | private function checkNestedPackageProperties($package): void 176 | { 177 | $attributes = ['currency', 'initial', 'final', 'discount_percent', 'individual']; 178 | $this->assertObjectHasProperties($attributes, $package->price); 179 | 180 | $attributes = ['windows', 'mac', 'linux']; 181 | $this->assertObjectHasProperties($attributes, $package->platforms); 182 | } 183 | 184 | /** 185 | * @param $group 186 | */ 187 | private function checkGroupMainSummaryProperties($group): void 188 | { 189 | $this->assertObjectHasProperty('groupID64', $group); 190 | $this->assertObjectHasProperty('groupDetails', $group); 191 | $this->assertObjectHasProperty('memberDetails', $group); 192 | $this->assertObjectHasProperty('startingMember', $group); 193 | $this->assertObjectHasProperty('members', $group); 194 | } 195 | 196 | /** 197 | * @param $group 198 | */ 199 | private function checkGroupDetailProperties($group): void 200 | { 201 | $this->assertObjectHasProperty('name', $group->groupDetails); 202 | $this->assertObjectHasProperty('url', $group->groupDetails); 203 | $this->assertObjectHasProperty('headline', $group->groupDetails); 204 | $this->assertObjectHasProperty('summary', $group->groupDetails); 205 | $this->assertObjectHasProperty('avatarIcon', $group->groupDetails); 206 | $this->assertObjectHasProperty('avatarMedium', $group->groupDetails); 207 | $this->assertObjectHasProperty('avatarFull', $group->groupDetails); 208 | $this->assertObjectHasProperty('avatarIconUrl', $group->groupDetails); 209 | $this->assertObjectHasProperty('avatarMediumUrl', $group->groupDetails); 210 | $this->assertObjectHasProperty('avatarFullUrl', $group->groupDetails); 211 | } 212 | 213 | /** 214 | * @param $group 215 | */ 216 | private function checkGroupMemberDetailsProperties($group): void 217 | { 218 | $this->assertObjectHasProperty('count', $group->memberDetails); 219 | $this->assertObjectHasProperty('inChat', $group->memberDetails); 220 | $this->assertObjectHasProperty('inGame', $group->memberDetails); 221 | $this->assertObjectHasProperty('online', $group->memberDetails); 222 | } 223 | 224 | /** 225 | * @param $group 226 | */ 227 | private function checkGroupMemberProperties($group): void 228 | { 229 | $startingMember = $group->members->get($group->startingMember); 230 | 231 | $this->assertObjectHasProperty('id32', $startingMember); 232 | $this->assertObjectHasProperty('id64', $startingMember); 233 | $this->assertObjectHasProperty('id3', $startingMember); 234 | } 235 | 236 | protected function expectApiCallFailedException(string $message): void 237 | { 238 | $this->expectException(\Syntax\SteamApi\Exceptions\ApiCallFailedException::class); 239 | $this->expectExceptionMessage($message); 240 | } 241 | 242 | protected function expectEmptyResponseException(): void 243 | { 244 | $this->expectApiCallFailedException( 'Api call failed to complete due to an empty response'); 245 | } 246 | 247 | } 248 | -------------------------------------------------------------------------------- /tests/GroupTest.php: -------------------------------------------------------------------------------- 1 | steamClient->group()->GetGroupSummary($this->groupId); 12 | 13 | $this->checkGroupProperties($group); 14 | $this->checkClasses($group); 15 | } 16 | 17 | /** @test */ 18 | public function it_gets_a_summary_of_a_group_by_name() 19 | { 20 | $group = $this->steamClient->group()->GetGroupSummary($this->groupName); 21 | 22 | $this->checkGroupProperties($group); 23 | $this->checkClasses($group); 24 | } 25 | 26 | /** 27 | * @param $group 28 | */ 29 | protected function checkClasses($group): void 30 | { 31 | $this->assertInstanceOf(\Syntax\SteamApi\Containers\Group::class, $group); 32 | $this->assertInstanceOf(\Syntax\SteamApi\Containers\Group\Details::class, $group->groupDetails); 33 | $this->assertInstanceOf(\Syntax\SteamApi\Containers\Group\MemberDetails::class, $group->memberDetails); 34 | $this->assertInstanceOf(\Illuminate\Support\Collection::class, $group->members); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /tests/IdTest.php: -------------------------------------------------------------------------------- 1 | steamClient->convertId($this->id64); 16 | 17 | $this->assertEquals($this->id32, $ids->id32); 18 | $this->assertEquals($this->id64, $ids->id64); 19 | $this->assertEquals($this->id3, $ids->id3); 20 | } 21 | 22 | } 23 | -------------------------------------------------------------------------------- /tests/ItemTest.php: -------------------------------------------------------------------------------- 1 | steamClient->item()->GetPlayerItems($this->appId, 76561198022436617); 12 | 13 | $this->assertCount(3, $inventory->items); 14 | 15 | $item = $inventory->items->first(); 16 | 17 | $this->checkItemProperties($item); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/NewsTest.php: -------------------------------------------------------------------------------- 1 | steamClient->news()->GetNewsForApp($this->appId, 1, 20); 12 | 13 | $this->assertObjectHasProperty('appid', $newsArticle); 14 | $this->assertEquals($this->appId, $newsArticle->appid); 15 | $this->assertObjectHasProperty('newsitems', $newsArticle); 16 | $this->assertGreaterThan(0, count($newsArticle->newsitems)); 17 | 18 | $attributes = [ 19 | 'gid', 'title', 'url', 'is_external_url', 'author', 'contents', 'feedlabel', 'date', 'feedname' 20 | ]; 21 | $this->assertObjectHasProperties($attributes, $newsArticle->newsitems[0]); 22 | 23 | $this->assertTrue(strlen(strip_tags((string) $newsArticle->newsitems[0]->contents)) <= 23); 24 | } 25 | 26 | /** @test */ 27 | public function it_gets_more_than_1_news_article_by_app_id() 28 | { 29 | $newsArticle = $this->steamClient->news()->GetNewsForApp($this->appId); 30 | 31 | $this->assertGreaterThan(1, count($newsArticle->newsitems)); 32 | 33 | return $newsArticle; 34 | } 35 | 36 | /** 37 | * @test 38 | * 39 | * @depends it_gets_more_than_1_news_article_by_app_id 40 | * 41 | * @param $defaultNewsCall 42 | */ 43 | public function it_has_full_news_article_by_app_id($defaultNewsCall) 44 | { 45 | foreach ($defaultNewsCall->newsitems as $newsItem) { 46 | if (strlen(strip_tags((string) $newsItem->contents)) > 0) { 47 | $this->assertGreaterThan(23, strlen(strip_tags((string) $newsItem->contents))); 48 | } 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /tests/PackageTest.php: -------------------------------------------------------------------------------- 1 | steamClient->package()->packageDetails($this->packageId); 12 | 13 | $this->assertCount(1, $details); 14 | 15 | $detail = $details->first(); 16 | 17 | $this->checkPackageProperties($detail); 18 | $this->checkPackageClasses($detail); 19 | } 20 | 21 | /** 22 | * @param $detail 23 | */ 24 | private function checkPackageClasses($detail): void 25 | { 26 | $this->assertInstanceOf(\Syntax\SteamApi\Containers\Package::class, $detail); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/PlayerTest.php: -------------------------------------------------------------------------------- 1 | steamClient->player($this->id64)->GetSteamLevel(); 12 | 13 | $this->assertIsInt($steamLevel); 14 | } 15 | 16 | /** @test */ 17 | public function it_gets_the_player_details_by_user_id() 18 | { 19 | $details = $this->steamClient->player($this->id64)->GetPlayerLevelDetails(); 20 | 21 | $this->assertInstanceOf(\Syntax\SteamApi\Containers\Player\Level::class, $details); 22 | 23 | $attributes = [ 24 | 'playerXp', 'playerLevel', 'xpToLevelUp', 'xpForCurrentLevel', 'currentLevelFloor', 25 | 'currentLevelCeiling', 'percentThroughLevel' 26 | ]; 27 | $this->assertObjectHasProperties($attributes, $details); 28 | } 29 | 30 | /** @test */ 31 | public function it_gets_the_badges_by_user_id() 32 | { 33 | $badges = $this->steamClient->player($this->id64)->GetBadges(); 34 | 35 | $attributes = ['badges', 'player_xp', 'player_level', 'player_xp_needed_to_level_up', 'player_xp_needed_current_level']; 36 | $this->assertObjectHasProperties($attributes, $badges); 37 | 38 | $attributes = ['badgeid', 'level', 'completion_time', 'xp', 'scarcity']; 39 | $this->assertObjectHasProperties($attributes, $badges->badges[0]); 40 | } 41 | 42 | /** @test */ 43 | public function it_gets_the_badge_progress_by_user_id() 44 | { 45 | $this->expectApiCallFailedException('Api call failed to complete due to an empty response'); 46 | 47 | $progress = $this->steamClient->player($this->id64)->GetCommunityBadgeProgress(); 48 | 49 | $this->assertObjectHasProperty('quests', $progress); 50 | 51 | $attributes = ['questid', 'completed']; 52 | $this->assertObjectHasProperties($attributes, $progress->quests[0]); 53 | } 54 | 55 | /** @test */ 56 | public function it_gets_the_owned_games_by_user_id() 57 | { 58 | $games = $this->steamClient->player($this->id64)->GetOwnedGames(); 59 | 60 | $this->assertInstanceOf(\Illuminate\Support\Collection::class, $games); 61 | $this->assertInstanceOf(\Syntax\SteamApi\Containers\Game::class, $games->first()); 62 | 63 | $attributes = [ 64 | 'appId', 'name', 'playtimeTwoWeeks', 'playtimeTwoWeeksReadable', 'playtimeForever', 'playtimeForeverReadable', 65 | 'icon', 'logo', 'header', 'hasCommunityVisibleStats' 66 | ]; 67 | $this->assertObjectHasProperties($attributes, $games->first()); 68 | } 69 | 70 | /** @test */ 71 | public function it_gets_the_owned_games_by_user_id_without_app_details() 72 | { 73 | $games = $this->steamClient->player($this->id64)->GetOwnedGames(false); 74 | 75 | $this->assertInstanceOf(\Illuminate\Support\Collection::class, $games); 76 | $this->assertInstanceOf(\Syntax\SteamApi\Containers\Game::class, $games->first()); 77 | 78 | $attributes = [ 79 | 'appId', 'name', 'playtimeTwoWeeks', 'playtimeTwoWeeksReadable', 'playtimeForever', 'playtimeForeverReadable', 80 | 'icon', 'logo', 'header', 'hasCommunityVisibleStats' 81 | ]; 82 | $this->assertObjectHasProperties($attributes, $games->first()); 83 | 84 | $this->assertNull($games->first()->name); 85 | $this->assertNull($games->first()->icon); 86 | $this->assertNull($games->first()->logo); 87 | } 88 | 89 | /** @test */ 90 | public function it_filters_the_owned_games_by_user_id() 91 | { 92 | $games = $this->steamClient->player($this->id64)->GetOwnedGames(true, false, 400); 93 | 94 | $this->assertInstanceOf(\Illuminate\Support\Collection::class, $games); 95 | $this->assertInstanceOf(\Syntax\SteamApi\Containers\Game::class, $games->first()); 96 | $this->assertEquals(1, $games->count()); 97 | 98 | $attributes = [ 99 | 'appId', 'name', 'playtimeTwoWeeks', 'playtimeTwoWeeksReadable', 'playtimeForever', 'playtimeForeverReadable', 100 | 'icon', 'logo', 'header', 'hasCommunityVisibleStats' 101 | ]; 102 | $this->assertObjectHasProperties($attributes, $games->first()); 103 | } 104 | 105 | /** @test */ 106 | public function it_gets_recently_played_games_by_user_id() 107 | { 108 | $games = $this->steamClient->player($this->id64)->GetRecentlyPlayedGames(); 109 | 110 | $this->assertInstanceOf(\Illuminate\Support\Collection::class, $games); 111 | $this->assertInstanceOf(\Syntax\SteamApi\Containers\Game::class, $games->first()); 112 | 113 | $attributes = [ 114 | 'appId', 'name', 'playtimeTwoWeeks', 'playtimeTwoWeeksReadable', 'playtimeForever', 'playtimeForeverReadable', 115 | 'icon', 'logo', 'header', 'hasCommunityVisibleStats' 116 | ]; 117 | $this->assertObjectHasProperties($attributes, $games->first()); 118 | } 119 | 120 | /** @test */ 121 | public function it_gets_a_single_recently_played_game_by_user_id() 122 | { 123 | $games = $this->steamClient->player($this->id64)->GetRecentlyPlayedGames(1); 124 | 125 | $this->assertInstanceOf(\Illuminate\Support\Collection::class, $games); 126 | $this->assertInstanceOf(\Syntax\SteamApi\Containers\Game::class, $games->first()); 127 | $this->assertEquals(1, $games->count()); 128 | 129 | $attributes = [ 130 | 'appId', 'name', 'playtimeTwoWeeks', 'playtimeTwoWeeksReadable', 'playtimeForever', 'playtimeForeverReadable', 131 | 'icon', 'logo', 'header', 'hasCommunityVisibleStats' 132 | ]; 133 | $this->assertObjectHasProperties($attributes, $games->first()); 134 | } 135 | 136 | /** @test */ 137 | public function it_checks_if_playing_a_shared_game_by_user_and_app_id() 138 | { 139 | $this->expectEmptyResponseException(); 140 | 141 | $playingSharedGame = $this->steamClient->player($this->id64)->IsPlayingSharedGame($this->appId); 142 | 143 | $this->assertNotNull($playingSharedGame); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /tests/UserStatsTest.php: -------------------------------------------------------------------------------- 1 | steamClient->userStats($this->id64)->GetPlayerAchievements(359320); 12 | 13 | $this->assertNull($achievements); 14 | } 15 | 16 | /** @test */ 17 | public function it_gets_the_users_achievements_for_a_game() 18 | { 19 | $achievements = $this->steamClient->userStats(76561198022436617)->GetPlayerAchievements(252950); 20 | 21 | $this->assertInstanceOf(\Syntax\SteamApi\Containers\Achievement::class, $achievements[0]); 22 | $this->checkAchievementProperties($achievements[0]); 23 | } 24 | 25 | /** @test */ 26 | public function it_gets_the_global_achievement_percentage_for_a_game() 27 | { 28 | $achievements = $this->steamClient->userStats($this->id64)->GetGlobalAchievementPercentagesForApp($this->appId); 29 | 30 | $this->assertGreaterThan(0, $achievements); 31 | 32 | $attributes = ['name', 'percent']; 33 | $this->assertObjectHasProperties($attributes, $achievements[0]); 34 | } 35 | 36 | /** @test */ 37 | public function it_gets_the_user_stats_for_a_game() 38 | { 39 | $stats = $this->steamClient->userStats(76_561_198_159_417_876)->GetUserStatsForGame($this->appId); 40 | 41 | $this->assertTrue(is_array($stats)); 42 | 43 | $attributes = ['name', 'achieved']; 44 | $this->assertObjectHasProperties($attributes, $stats[0]); 45 | } 46 | 47 | /** @test */ 48 | public function it_gets_all_the_user_stats_for_a_game() 49 | { 50 | $stats = $this->steamClient->userStats(76_561_198_159_417_876)->GetUserStatsForGame($this->appId, true); 51 | 52 | $this->assertTrue(is_object($stats)); 53 | 54 | $attributes = ['name', 'achieved']; 55 | $this->assertObjectHasProperties($attributes, $stats->achievements[0]); 56 | 57 | $attributes = ['name', 'value']; 58 | $this->assertObjectHasProperties($attributes, $stats->stats[0]); 59 | } 60 | 61 | /** @test */ 62 | public function it_gets_all_the_stats_for_a_game() 63 | { 64 | $stats = $this->steamClient->userStats(76_561_198_159_417_876)->GetSchemaForGame($this->appId); 65 | 66 | $this->assertTrue(is_object($stats)); 67 | 68 | $attributes = ['gameName', 'gameVersion', 'availableGameStats']; 69 | $this->assertObjectHasProperties($attributes, $stats->game); 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /tests/UserTest.php: -------------------------------------------------------------------------------- 1 | id32, $this->altId64]; 16 | 17 | $userService = $this->steamClient->user($steamIds); 18 | 19 | $this->assertCount(2, $userService->getSteamId()); 20 | $this->assertEquals($this->id64, $userService->getSteamId()[0]); 21 | } 22 | 23 | /** 24 | * @test 25 | * @throws UnrecognizedId 26 | * @throws GuzzleException 27 | * @throws ApiCallFailedException 28 | */ 29 | public function it_throws_an_exception_when_no_display_name_is_provided() 30 | { 31 | if (method_exists($this, 'setExpectedException')) { 32 | $this->setExpectedException(\Syntax\SteamApi\Exceptions\UnrecognizedId::class); 33 | } else { 34 | $this->expectException(\Syntax\SteamApi\Exceptions\UnrecognizedId::class); 35 | } 36 | 37 | $steamObject = $this->steamClient->user($this->id64)->ResolveVanityURL(); 38 | 39 | $this->assertEquals('No match', $steamObject); 40 | } 41 | 42 | /** @test 43 | * @throws ApiCallFailedException 44 | * @throws GuzzleException 45 | * @throws UnrecognizedId 46 | */ 47 | public function it_returns_no_match_from_an_invalid_display_name() 48 | { 49 | $steamObject = $this->steamClient->user($this->id64)->ResolveVanityURL('stygiansabyssINVALID'); 50 | 51 | $this->assertEquals('No match', $steamObject); 52 | } 53 | 54 | /** @test 55 | * @throws ApiCallFailedException 56 | * @throws GuzzleException 57 | * @throws UnrecognizedId 58 | */ 59 | public function it_gets_the_steam_id_from_a_display_name() 60 | { 61 | $steamObject = $this->steamClient->user(76561198022436617)->ResolveVanityURL('stygiansabyss'); 62 | 63 | $this->assertEquals(76561198022436617, $steamObject->id64); 64 | } 65 | 66 | /** @test */ 67 | public function it_gets_the_base_users_player_summary() 68 | { 69 | $friendsList = $this->steamClient->user($this->id64)->GetPlayerSummaries(); 70 | 71 | $this->assertCount(1, $friendsList); 72 | $this->checkPlayerProperties($friendsList); 73 | $this->checkPlayerClasses($friendsList); 74 | } 75 | 76 | /** @test */ 77 | public function it_gets_the_supplied_users_player_summary() 78 | { 79 | $friendsList = $this->steamClient->user($this->id64)->GetPlayerSummaries($this->altId64); 80 | 81 | $this->assertCount(1, $friendsList); 82 | $this->checkPlayerProperties($friendsList); 83 | $this->checkPlayerClasses($friendsList); 84 | 85 | $this->assertNotEquals($friendsList[0]->steamId, $this->id64); 86 | } 87 | 88 | /** @test */ 89 | public function it_gets_all_users_in_friend_list() 90 | { 91 | $friendsList = $this->steamClient->user($this->id64)->GetFriendList('all'); 92 | 93 | $this->assertGreaterThan(0, $friendsList); 94 | 95 | $this->checkPlayerProperties($friendsList); 96 | $this->checkPlayerClasses($friendsList); 97 | } 98 | 99 | /** @test */ 100 | public function it_gets_friend_users_in_friend_list() 101 | { 102 | $friendsList = $this->steamClient->user($this->id64)->GetFriendList('friend'); 103 | 104 | $this->assertGreaterThan(0, $friendsList); 105 | 106 | $this->checkPlayerProperties($friendsList); 107 | $this->checkPlayerClasses($friendsList); 108 | } 109 | 110 | /** @test */ 111 | public function it_throws_exception_to_invalid_relationship_types() 112 | { 113 | $expectedMessage = 'Provided relationship [nonFriend] is not valid. Please select from: all, friend'; 114 | 115 | if (method_exists($this, 'setExpectedException')) { 116 | $this->setExpectedException('InvalidArgumentException', $expectedMessage); 117 | } else { 118 | $this->expectException('InvalidArgumentException'); 119 | $this->expectExceptionMessage($expectedMessage); 120 | } 121 | 122 | $this->steamClient->user($this->id64)->GetFriendList('nonFriend'); 123 | } 124 | 125 | /** @test */ 126 | public function it_gets_the_bans_for_the_base_user() 127 | { 128 | $bans = $this->steamClient->user($this->id64)->GetPlayerBans(); 129 | 130 | $this->assertCount(1, $bans); 131 | 132 | $attributes = ['SteamId', 'CommunityBanned', 'VACBanned', 'NumberOfVACBans', 'DaysSinceLastBan', 'EconomyBan']; 133 | $this->assertObjectHasProperties($attributes, $bans[0]); 134 | } 135 | 136 | /** @test */ 137 | public function it_gets_the_bans_for_the_supplied_user() 138 | { 139 | $bans = $this->steamClient->user($this->id64)->GetPlayerBans($this->altId64); 140 | 141 | $this->assertCount(1, $bans); 142 | 143 | $attributes = ['SteamId', 'CommunityBanned', 'VACBanned', 'NumberOfVACBans', 'DaysSinceLastBan', 'EconomyBan']; 144 | $this->assertObjectHasProperties($attributes, $bans[0]); 145 | 146 | $this->assertNotEquals($bans[0]->SteamId, $this->id64); 147 | } 148 | 149 | private function checkPlayerClasses($friendsList): void 150 | { 151 | $this->assertInstanceOf(\Syntax\SteamApi\Containers\Player::class, $friendsList[0]); 152 | $this->assertInstanceOf(\Syntax\SteamApi\Containers\Id::class, $friendsList[0]->steamIds); 153 | } 154 | } 155 | --------------------------------------------------------------------------------