mirror of
https://github.com/ceratic/MediaCollectorLibary.git
synced 2026-05-13 23:56:46 +02:00
first commit
This commit is contained in:
166
app/Services/SteamSyncService.php
Normal file
166
app/Services/SteamSyncService.php
Normal file
@@ -0,0 +1,166 @@
|
||||
<?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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user