Introduce Profile Information endpoint

This commit is contained in:
ErickSkrauch 2022-12-15 23:05:00 +01:00
parent bbc85be65b
commit f0bc064dbc
No known key found for this signature in database
GPG Key ID: 669339FCBB30EE0E
6 changed files with 282 additions and 1 deletions

View File

@ -5,6 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased] ## [Unreleased]
### Added
- [Profile Information](https://wiki.vg/Mojang_API#Profile_Information) endpoint.
## [0.2.1] - 2020-06-10 ## [0.2.1] - 2020-06-10
### Added ### Added

View File

@ -13,6 +13,7 @@ use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\HandlerStack; use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Uri; use GuzzleHttp\Psr7\Uri;
use GuzzleHttp\RequestOptions;
use InvalidArgumentException; use InvalidArgumentException;
use Ramsey\Uuid\Uuid; use Ramsey\Uuid\Uuid;
@ -524,7 +525,7 @@ class Api {
* *
* @url https://wiki.vg/Mojang_API#Statistics * @url https://wiki.vg/Mojang_API#Statistics
*/ */
public function statistics(array $metricKeys) { public function statistics(array $metricKeys) { // TODO: missing return type annotation
$response = $this->getClient()->request('POST', 'https://api.mojang.com/orders/statistics', [ $response = $this->getClient()->request('POST', 'https://api.mojang.com/orders/statistics', [
'json' => [ 'json' => [
'metricKeys' => $metricKeys, 'metricKeys' => $metricKeys,
@ -535,6 +536,43 @@ class Api {
return new Response\StatisticsResponse($body['total'], $body['last24h'], $body['saleVelocityPerSeconds']); return new Response\StatisticsResponse($body['total'], $body['last24h'], $body['saleVelocityPerSeconds']);
} }
/**
* @param string $accessToken
* @return \Ely\Mojang\Response\MinecraftServicesProfileResponse
* @throws GuzzleException
* @see https://wiki.vg/Mojang_API#Profile_Information
*/
public function getProfile(string $accessToken): Response\MinecraftServicesProfileResponse {
$response = $this->getClient()->request('GET', 'https://api.minecraftservices.com/minecraft/profile', [
RequestOptions::HEADERS => [
'Authorization' => 'Bearer ' . $accessToken,
],
]);
$body = $this->decode($response->getBody()->getContents());
return new Response\MinecraftServicesProfileResponse(
$body['id'],
$body['name'],
array_map(function(array $item) {
return new Response\MinecraftServicesProfileSkin(
$item['id'],
$item['state'],
$item['url'],
$item['variant'],
$item['alias'] ?? null
);
}, $body['skins']),
array_map(function(array $item) {
return new Response\MinecraftServicesProfileCape(
$item['id'],
$item['state'],
$item['url'],
$item['alias']
);
}, $body['capes'])
);
}
/** /**
* @return ClientInterface * @return ClientInterface
*/ */

View File

@ -0,0 +1,58 @@
<?php
declare(strict_types=1);
namespace Ely\Mojang\Response;
/**
* @see https://wiki.vg/Mojang_API#Profile_Information
*/
class MinecraftServicesProfileCape {
/**
* @var string
*/
private $id;
/**
* @var string
*/
private $state;
/**
* @var string
*/
private $url;
/**
* @var string
*/
private $alias;
public function __construct(string $id, string $state, string $url, string $alias) {
$this->id = $id;
$this->state = $state;
$this->url = $url;
$this->alias = $alias;
}
public function getId(): string {
return $this->id;
}
/**
* TODO: figure out literal for not active state
* @return 'ACTIVE'
*/
public function getState(): string {
return $this->state;
}
public function getUrl(): string {
return $this->url;
}
public function getAlias(): string {
return $this->alias;
}
}

View File

@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace Ely\Mojang\Response;
/**
* @see https://wiki.vg/Mojang_API#Profile_Information
*/
class MinecraftServicesProfileResponse {
/**
* @var string
*/
private $id;
/**
* @var string
*/
private $name;
/**
* @var MinecraftServicesProfileSkin[]
*/
private $skins;
/**
* @var MinecraftServicesProfileCape[]
*/
private $capes;
/**
* @param string $id
* @param string $name
* @param MinecraftServicesProfileSkin[] $skins
* @param MinecraftServicesProfileCape[] $capes
*/
public function __construct(string $id, string $name, array $skins, array $capes) {
$this->id = $id;
$this->name = $name;
$this->skins = $skins;
$this->capes = $capes;
}
public function getId(): string {
return $this->id;
}
public function getName(): string {
return $this->name;
}
/**
* @return MinecraftServicesProfileSkin[]
*/
public function getSkins(): array {
return $this->skins;
}
/**
* @return MinecraftServicesProfileCape[]
*/
public function getCapes(): array {
return $this->capes;
}
}

View File

@ -0,0 +1,74 @@
<?php
declare(strict_types=1);
namespace Ely\Mojang\Response;
/**
* @see https://wiki.vg/Mojang_API#Profile_Information
*/
class MinecraftServicesProfileSkin {
/**
* @var string
*/
private $id;
/**
* @var string
*/
private $state;
/**
* @var string
*/
private $url;
/**
* @var string
*/
private $variant;
/**
* @var string|null
*/
private $alias;
public function __construct(string $id, string $state, string $url, string $variant, ?string $alias) {
$this->id = $id;
$this->state = $state;
$this->url = $url;
$this->variant = $variant;
$this->alias = $alias;
}
public function getId(): string {
return $this->id;
}
/**
* TODO: figure out literal for not active state
* @return 'ACTIVE'
*/
public function getState(): string {
return $this->state;
}
public function getUrl(): string {
return $this->url;
}
/**
* @return 'CLASSIC'|'SLIM'
*/
public function getVariant(): string {
return $this->variant;
}
/**
* Doesn't show up for some reason for some accounts
*/
public function getAlias(): ?string {
return $this->alias;
}
}

View File

@ -735,6 +735,49 @@ class ApiTest extends TestCase {
$this->assertSame(1.32, $result->getSaleVelocityPerSeconds()); $this->assertSame(1.32, $result->getSaleVelocityPerSeconds());
} }
public function testGetProfile(): void {
$this->mockHandler->append($this->createResponse(200, [
'id' => '86f6e3695b764412a29820cac1d4d0d6',
'name' => 'MockUsername',
'skins' => [
[
'id' => 'b647c354-16b0-47e3-8340-5d328b4215c1',
'state' => 'ACTIVE',
'url' => 'http://textures.minecraft.net/texture/3b60a1f6d562f52aaebbf1434f1de147933a3affe0e764fa49ea057536623cd3',
'variant' => 'SLIM',
],
],
'capes' => [
[
'id' => '402d2b1a-48a5-4177-8173-85b0d1d04889',
'state' => 'ACTIVE',
'url' => 'http://textures.minecraft.net/texture/153b1a0dfcbae953cdeb6f2c2bf6bf79943239b1372780da44bcbb29273131da',
'alias' => 'Minecon2013',
],
],
]));
$result = $this->api->getProfile('mock access token');
/** @var \Psr\Http\Message\RequestInterface $request */
$request = $this->history[0]['request'];
$this->assertSame('Bearer mock access token', $request->getHeaderLine('Authorization'));
$this->assertSame('86f6e3695b764412a29820cac1d4d0d6', $result->getId());
$this->assertSame('MockUsername', $result->getName());
$this->assertCount(1, $result->getSkins());
$this->assertSame('b647c354-16b0-47e3-8340-5d328b4215c1', $result->getSkins()[0]->getId());
$this->assertSame('ACTIVE', $result->getSkins()[0]->getState());
$this->assertSame('http://textures.minecraft.net/texture/3b60a1f6d562f52aaebbf1434f1de147933a3affe0e764fa49ea057536623cd3', $result->getSkins()[0]->getUrl());
$this->assertSame('SLIM', $result->getSkins()[0]->getVariant());
$this->assertNull($result->getSkins()[0]->getAlias());
$this->assertCount(1, $result->getCapes());
$this->assertSame('402d2b1a-48a5-4177-8173-85b0d1d04889', $result->getCapes()[0]->getId());
$this->assertSame('ACTIVE', $result->getCapes()[0]->getState());
$this->assertSame('http://textures.minecraft.net/texture/153b1a0dfcbae953cdeb6f2c2bf6bf79943239b1372780da44bcbb29273131da', $result->getCapes()[0]->getUrl());
$this->assertSame('Minecon2013', $result->getCapes()[0]->getAlias());
}
private function createResponse(int $statusCode, array $response): ResponseInterface { private function createResponse(int $statusCode, array $response): ResponseInterface {
return new Response($statusCode, ['content-type' => 'json'], json_encode($response)); return new Response($statusCode, ['content-type' => 'json'], json_encode($response));
} }