first commit

This commit is contained in:
Lars Behrends
2025-10-17 13:29:28 +02:00
commit 929ee43001
85 changed files with 10361 additions and 0 deletions

View 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
}
}