mirror of
				https://github.com/elyby/accounts.git
				synced 2025-05-31 14:11:46 +05:30 
			
		
		
		
	Added support of the onUnknownProfileRespondWithUuid when calling Chrly endpoint
				
					
				
			This commit is contained in:
		| @@ -35,9 +35,37 @@ return [ | ||||
|                         ]; | ||||
|                     } | ||||
|  | ||||
|                     public function profile(string $username, bool $signed = false): ?array { | ||||
|                     public function profile(string $username, bool $signed = false, ?string $fallbackUuid = null): ?array { | ||||
|                         if ($username === 'NotSynchronized') { | ||||
|                             return null; | ||||
|                             if ($fallbackUuid === null) { | ||||
|                                 return null; | ||||
|                             } | ||||
|  | ||||
|                             $profile = [ | ||||
|                                 'name' => $username, | ||||
|                                 'id' => $fallbackUuid, | ||||
|                                 'properties' => [ | ||||
|                                     [ | ||||
|                                         'name' => 'textures', | ||||
|                                         'value' => base64_encode(json_encode([ | ||||
|                                             'timestamp' => Carbon\Carbon::now()->getPreciseTimestamp(3), | ||||
|                                             'profileId' => $fallbackUuid, | ||||
|                                             'profileName' => $username, | ||||
|                                             'textures' => new ArrayObject(), | ||||
|                                         ])), | ||||
|                                     ], | ||||
|                                     [ | ||||
|                                         'name' => 'ely', | ||||
|                                         'value' => 'but why are you asking?', | ||||
|                                     ], | ||||
|                                 ], | ||||
|                             ]; | ||||
|  | ||||
|                             if ($signed) { | ||||
|                                 $profile['properties'][0]['signature'] = 'signature'; | ||||
|                             } | ||||
|  | ||||
|                             return $profile; | ||||
|                         } | ||||
|  | ||||
|                         $account = common\models\Account::findOne(['username' => $username]); | ||||
|   | ||||
| @@ -39,12 +39,17 @@ class SkinsSystemApi { | ||||
|      * @return array|null | ||||
|      * @throws \GuzzleHttp\Exception\GuzzleException | ||||
|      */ | ||||
|     public function profile(string $username, bool $signed = false): ?array { | ||||
|         $url = "/profile/{$username}"; | ||||
|     public function profile(string $username, bool $signed = false, ?string $fallbackUuid = null): ?array { | ||||
|         $query = []; | ||||
|         if ($signed) { | ||||
|             $url .= '?unsigned=false'; | ||||
|             $query['unsigned'] = 'false'; | ||||
|         } | ||||
|  | ||||
|         if ($fallbackUuid !== null) { | ||||
|             $query['onUnknownProfileRespondWithUuid'] = $fallbackUuid; | ||||
|         } | ||||
|  | ||||
|         $url = "/profile/{$username}" . empty($query) ? '' : http_build_query($query); | ||||
|         $response = $this->getClient()->request('GET', $this->buildUrl($url)); | ||||
|         if ($response->getStatusCode() !== 200) { | ||||
|             return null; | ||||
|   | ||||
| @@ -3,8 +3,6 @@ declare(strict_types=1); | ||||
|  | ||||
| namespace common\models; | ||||
|  | ||||
| use ArrayObject; | ||||
| use Carbon\Carbon; | ||||
| use common\components\SkinsSystemApi; | ||||
| use GuzzleHttp\Client as GuzzleHttpClient; | ||||
| use GuzzleHttp\Exception\GuzzleException; | ||||
| @@ -12,6 +10,8 @@ use Yii; | ||||
|  | ||||
| class Textures { | ||||
|  | ||||
|     private const MAX_RETRIES = 3; | ||||
|  | ||||
|     protected Account $account; | ||||
|  | ||||
|     public function __construct(Account $account) { | ||||
| @@ -20,62 +20,19 @@ class Textures { | ||||
|  | ||||
|     public function getMinecraftResponse(bool $signed = false): array { | ||||
|         $uuid = str_replace('-', '', $this->account->uuid); | ||||
|         $profile = $this->getProfile($signed); | ||||
|         if ($profile === null) { | ||||
|             // This case shouldn't happen at all, but synchronization isn't perfect and sometimes | ||||
|             // information might be not updated. Provide fallback solution | ||||
|             $profile = [ | ||||
|                 'name' => $this->account->username, | ||||
|                 'id' => $uuid, | ||||
|                 'properties' => [ | ||||
|                     [ | ||||
|                         'name' => 'textures', | ||||
|                         'value' => base64_encode(json_encode([ | ||||
|                             'timestamp' => Carbon::now()->getPreciseTimestamp(3), | ||||
|                             'profileId' => $uuid, | ||||
|                             'profileName' => $this->account->username, | ||||
|                             'textures' => new ArrayObject(), // Force {} rather than [] when json_encode | ||||
|                         ])), | ||||
|                     ], | ||||
|                     [ | ||||
|                         'name' => 'ely', | ||||
|                         'value' => 'but why are you asking?', | ||||
|                     ], | ||||
|                 ], | ||||
|             ]; | ||||
|  | ||||
|             if ($signed) { | ||||
|                 // I don't remember why this value has been used, but it was, so keep the same behavior until | ||||
|                 // figure out why it was made in this way | ||||
|                 $profile['properties'][0]['signature'] = 'Cg=='; | ||||
|             } | ||||
|         } elseif ($profile['id'] !== $uuid) { | ||||
|         $profile = $this->getProfile($uuid, $signed); | ||||
|         if ($profile['id'] !== $uuid) { | ||||
|             // Also a case that shouldn't happen, but is technically possible | ||||
|             $profile['id'] = $uuid; | ||||
|         } | ||||
|  | ||||
|         if ($signed) { | ||||
|             // This is a completely impossible case. But the most impossible things happen most of the time. | ||||
|             // We have received complaints that sometimes an empty value comes in the signature field. | ||||
|             // This code is an attempt at an investigation. If no such cases are reported for the foreseeable future, | ||||
|             // then this code can be removed | ||||
|             foreach ($profile['properties'] as &$property) { | ||||
|                 if ($property['name'] === 'textures') { | ||||
|                     if (!isset($property['signature'])) { | ||||
|                         Yii::warning('Signature was required, but field was not returned from the skinsystem\'s server'); | ||||
|                         $property['signature'] = 'Cg=='; | ||||
|                     } elseif (empty($property['signature'])) { | ||||
|                         Yii::warning('Signature was required, but contains an empty value from skinsystem\'s server'); | ||||
|                         $property['signature'] = 'Cg=='; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return $profile; | ||||
|     } | ||||
|  | ||||
|     private function getProfile(bool $signed): ?array { | ||||
|     /** | ||||
|      * @throws \GuzzleHttp\Exception\GuzzleException | ||||
|      */ | ||||
|     private function getProfile(string $uuid, bool $signed): array { | ||||
|         /** @var SkinsSystemApi $api */ | ||||
|         $api = Yii::$container->get(SkinsSystemApi::class); | ||||
|         if (YII_ENV_PROD) { | ||||
| @@ -85,13 +42,20 @@ class Textures { | ||||
|             ])); | ||||
|         } | ||||
|  | ||||
|         try { | ||||
|             return $api->profile($this->account->username, $signed); | ||||
|         } catch (GuzzleException $e) { | ||||
|             Yii::warning('Cannot get textures from skinsystem.ely.by. Exception message is ' . $e->getMessage()); | ||||
|         // It will be better to handle retries with Guzzle middleware, but for speed I'll do it in place | ||||
|         $lastException = null; | ||||
|         for ($i = 0; $i < self::MAX_RETRIES; $i++) { | ||||
|             try { | ||||
|                 return $api->profile($this->account->username, $signed, $uuid); | ||||
|             } catch (GuzzleException $e) { | ||||
|                 $lastException = $e; | ||||
|                 sleep(1); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return null; | ||||
|         Yii::warning('Cannot get textures from skinsystem.ely.by. Exception message is ' . $lastException->getMessage()); | ||||
|  | ||||
|         throw $lastException; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user