-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updated you and layout changes and doco
- Loading branch information
Showing
27 changed files
with
1,849 additions
and
461 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
node_modules | ||
dist | ||
dist-server | ||
.git | ||
.gitignore | ||
.env | ||
.env.* | ||
*.log | ||
.DS_Store | ||
.vscode | ||
.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
{"timestamp":"2025-01-17T01:19:56.040Z","level":"info","message":"Sending config to client (sensitive data redacted)","component":"Server","data":{"libraryPath":"","usersPath":"/config/users","cachePath":"/config/cache/artwork","steamGridDbApiKey":"","debugEnabled":false,"users":{}}} | ||
{"timestamp":"2025-01-17T01:19:56.056Z","level":"info","message":"Sending config to client (sensitive data redacted)","component":"Server","data":{"libraryPath":"","usersPath":"/config/users","cachePath":"/config/cache/artwork","steamGridDbApiKey":"","debugEnabled":false,"users":{}}} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
|
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
import fs from 'fs/promises'; | ||
import path from 'path'; | ||
import { SteamGame } from '../../src/types/config'; | ||
import { serverLog } from '../utils/logger.js'; | ||
|
||
interface GameData { | ||
games: Record<number, SteamGame>; // All known games indexed by appId | ||
userGames: Record<string, number[]>; // User -> array of appIds they own | ||
lastUpdated: Record<string, string>; // User -> ISO timestamp of last update | ||
} | ||
|
||
export class GameManager { | ||
private static instance: GameManager; | ||
private data: GameData; | ||
private readonly gamesPath = '/config/games.json'; | ||
|
||
private constructor() { | ||
this.data = { | ||
games: {}, | ||
userGames: {}, | ||
lastUpdated: {} | ||
}; | ||
} | ||
|
||
static async getInstance(): Promise<GameManager> { | ||
if (!GameManager.instance) { | ||
GameManager.instance = new GameManager(); | ||
await GameManager.instance.loadGames(); | ||
} | ||
return GameManager.instance; | ||
} | ||
|
||
private async loadGames(): Promise<void> { | ||
try { | ||
serverLog('debug', 'Loading games data...', 'GameManager'); | ||
const gamesData = await fs.readFile(this.gamesPath, 'utf-8'); | ||
this.data = JSON.parse(gamesData); | ||
serverLog('info', 'Games data loaded successfully', 'GameManager'); | ||
} catch (error) { | ||
// If file doesn't exist, we'll use default empty data | ||
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') { | ||
serverLog('error', 'Error loading games data', 'GameManager', error); | ||
} | ||
} | ||
} | ||
|
||
private async saveGames(): Promise<void> { | ||
try { | ||
serverLog('debug', 'Saving games data...', 'GameManager'); | ||
await fs.mkdir(path.dirname(this.gamesPath), { recursive: true }); | ||
await fs.writeFile(this.gamesPath, JSON.stringify(this.data, null, 2)); | ||
serverLog('info', 'Games data saved successfully', 'GameManager'); | ||
} catch (error) { | ||
serverLog('error', 'Failed to save games data', 'GameManager', error); | ||
throw new Error('Failed to save games data'); | ||
} | ||
} | ||
|
||
async updateUserGames(username: string, games: SteamGame[]): Promise<void> { | ||
try { | ||
serverLog('debug', 'Updating user games', 'GameManager', { username, gameCount: games.length }); | ||
|
||
// Update the global games list | ||
games.forEach(game => { | ||
this.data.games[game.appid] = game; | ||
}); | ||
|
||
// Update user's game list | ||
this.data.userGames[username] = games.map(game => game.appid); | ||
this.data.lastUpdated[username] = new Date().toISOString(); | ||
|
||
await this.saveGames(); | ||
serverLog('info', 'User games updated successfully', 'GameManager', { username }); | ||
} catch (error) { | ||
serverLog('error', 'Failed to update user games', 'GameManager', error); | ||
throw error; | ||
} | ||
} | ||
|
||
async getUserGames(username: string): Promise<SteamGame[]> { | ||
const appIds = this.data.userGames[username] || []; | ||
return appIds.map(appId => this.data.games[appId]); | ||
} | ||
|
||
async getAllGames(): Promise<SteamGame[]> { | ||
return Object.values(this.data.games); | ||
} | ||
|
||
getLastUpdated(username: string): string | null { | ||
return this.data.lastUpdated[username] || null; | ||
} | ||
|
||
async deleteUserGames(username: string): Promise<void> { | ||
try { | ||
serverLog('debug', 'Deleting user games', 'GameManager', { username }); | ||
delete this.data.userGames[username]; | ||
delete this.data.lastUpdated[username]; | ||
await this.saveGames(); | ||
serverLog('info', 'User games deleted successfully', 'GameManager', { username }); | ||
} catch (error) { | ||
serverLog('error', 'Failed to delete user games', 'GameManager', error); | ||
throw error; | ||
} | ||
} | ||
} |
Oops, something went wrong.