mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-13 23:56:46 +02:00
167 lines
5.2 KiB
PHP
167 lines
5.2 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\Game;
|
|
use GuzzleHttp\Client;
|
|
use Exception;
|
|
|
|
class SteamSyncService extends BaseSyncService
|
|
{
|
|
private Client $httpClient;
|
|
private ?string $apiKey;
|
|
private string $steamId;
|
|
private int $processedCount = 0;
|
|
private int $newCount = 0;
|
|
private int $updatedCount = 0;
|
|
|
|
public function __construct(\PDO $pdo, array $source)
|
|
{
|
|
parent::__construct($pdo, $source);
|
|
$this->httpClient = new Client([
|
|
'timeout' => 30,
|
|
'headers' => [
|
|
'User-Agent' => 'MediaCollector/1.0'
|
|
]
|
|
]);
|
|
$this->apiKey = $source['api_key'];
|
|
|
|
// Steam ID can be configured in source config or use a default test account
|
|
$this->steamId = $source['config']['steam_id'] ?? '76561198000000000'; // Default test Steam ID
|
|
}
|
|
|
|
protected function executeSync(string $syncType): void
|
|
{
|
|
if (empty($this->apiKey)) {
|
|
throw new Exception('Steam API key not configured');
|
|
}
|
|
|
|
$this->logProgress('Starting Steam library sync...');
|
|
|
|
// Get Steam user game library
|
|
$games = $this->getSteamLibrary();
|
|
|
|
foreach ($games as $gameData) {
|
|
$this->syncGame($gameData);
|
|
$this->processedCount++;
|
|
}
|
|
|
|
$this->logProgress("Processed {$this->processedCount} Steam games");
|
|
}
|
|
|
|
private function getSteamLibrary(): array
|
|
{
|
|
try {
|
|
// Steam Web API: GetOwnedGames
|
|
$response = $this->httpClient->get('https://api.steampowered.com/IPlayerService/GetOwnedGames/v1/', [
|
|
'query' => [
|
|
'key' => $this->apiKey,
|
|
'steamid' => $this->steamId,
|
|
'format' => 'json',
|
|
'include_appinfo' => 'true',
|
|
'include_played_free_games' => 'true'
|
|
]
|
|
]);
|
|
|
|
$data = json_decode($response->getBody(), true);
|
|
|
|
if (!isset($data['response']['games'])) {
|
|
throw new Exception('No games found in Steam library');
|
|
}
|
|
|
|
return $data['response']['games'];
|
|
} catch (Exception $e) {
|
|
throw new Exception('Failed to fetch Steam library: ' . $e->getMessage());
|
|
}
|
|
}
|
|
|
|
private function syncGame(array $gameData): void
|
|
{
|
|
$gameModel = new Game($this->pdo);
|
|
|
|
// Check if game already exists
|
|
$existingGame = $gameModel->findAll([
|
|
'steam_app_id' => $gameData['appid'],
|
|
'source_id' => $this->source['id']
|
|
]);
|
|
|
|
// Get additional game details from Steam API
|
|
$gameDetails = $this->getGameDetails($gameData['appid']);
|
|
|
|
$gameData = [
|
|
'title' => $gameData['name'],
|
|
'game_key' => Game::generateGameKey($gameData['name'], 'steam'),
|
|
'steam_app_id' => $gameData['appid'],
|
|
'playtime_minutes' => intval($gameData['playtime_forever']),
|
|
'platform' => 'PC',
|
|
'source_id' => $this->source['id'],
|
|
'last_played_at' => isset($gameData['rt_time_last_played']) && $gameData['rt_time_last_played'] > 0
|
|
? date('Y-m-d H:i:s', $gameData['rt_time_last_played'])
|
|
: null,
|
|
'metadata' => json_encode([
|
|
'appid' => $gameData['appid'],
|
|
'playtime_windows' => $gameData['playtime_windows_forever'] ?? 0,
|
|
'playtime_mac' => $gameData['playtime_mac_forever'] ?? 0,
|
|
'playtime_linux' => $gameData['playtime_linux_forever'] ?? 0,
|
|
'img_icon_url' => $gameDetails['img_icon_url'] ?? null,
|
|
'img_logo_url' => $gameDetails['img_logo_url'] ?? null,
|
|
'has_community_visible_stats' => $gameDetails['has_community_visible_stats'] ?? false
|
|
])
|
|
];
|
|
|
|
if (empty($existingGame)) {
|
|
$gameModel->create($gameData);
|
|
$this->newCount++;
|
|
} else {
|
|
$gameModel->update($existingGame[0]['id'], $gameData);
|
|
$this->updatedCount++;
|
|
}
|
|
}
|
|
|
|
private function getGameDetails(int $appId): array
|
|
{
|
|
try {
|
|
// Steam Web API: GetAppDetails
|
|
$response = $this->httpClient->get('https://store.steampowered.com/api/appdetails/', [
|
|
'query' => [
|
|
'appids' => $appId,
|
|
'cc' => 'US',
|
|
'l' => 'english'
|
|
]
|
|
]);
|
|
|
|
$data = json_decode($response->getBody(), true);
|
|
$appData = $data[$appId] ?? [];
|
|
|
|
if (!$appData['success']) {
|
|
return [];
|
|
}
|
|
|
|
return $appData['data'] ?? [];
|
|
} catch (Exception $e) {
|
|
// Return empty array if details can't be fetched
|
|
return [];
|
|
}
|
|
}
|
|
|
|
protected function getProcessedCount(): int
|
|
{
|
|
return $this->processedCount;
|
|
}
|
|
|
|
protected function getNewCount(): int
|
|
{
|
|
return $this->newCount;
|
|
}
|
|
|
|
protected function getUpdatedCount(): int
|
|
{
|
|
return $this->updatedCount;
|
|
}
|
|
|
|
protected function getDeletedCount(): int
|
|
{
|
|
return 0; // Steam doesn't provide deletion info in this context
|
|
}
|
|
}
|