mirror of
https://github.com/randyjc/Rahoot.git
synced 2026-03-13 20:15:35 +01:00
159 lines
4.0 KiB
TypeScript
159 lines
4.0 KiB
TypeScript
import Game from "@rahoot/socket/services/game"
|
|
import dayjs from "dayjs"
|
|
|
|
interface EmptyGame {
|
|
since: number
|
|
game: Game
|
|
}
|
|
|
|
class Registry {
|
|
private static instance: Registry | null = null
|
|
private games: Game[] = []
|
|
private emptyGames: EmptyGame[] = []
|
|
private cleanupInterval: ReturnType<typeof setTimeout> | null = null
|
|
private readonly EMPTY_GAME_TIMEOUT_MINUTES = 5
|
|
private readonly CLEANUP_INTERVAL_MS = 60_000
|
|
|
|
private constructor() {
|
|
this.startCleanupTask()
|
|
}
|
|
|
|
static getInstance(): Registry {
|
|
Registry.instance ||= new Registry()
|
|
|
|
return Registry.instance
|
|
}
|
|
|
|
addGame(game: Game): void {
|
|
this.games.push(game)
|
|
console.log(`Game ${game.gameId} added. Total games: ${this.games.length}`)
|
|
}
|
|
|
|
getGameById(gameId: string): Game | undefined {
|
|
return this.games.find((g) => g.gameId === gameId)
|
|
}
|
|
|
|
getGameByInviteCode(inviteCode: string): Game | undefined {
|
|
return this.games.find((g) => g.inviteCode === inviteCode)
|
|
}
|
|
|
|
getPlayerGame(clientId: string): Game | undefined {
|
|
return this.games.find((g) =>
|
|
g.players.some((p) => p.clientId === clientId)
|
|
)
|
|
}
|
|
|
|
getManagerGame(clientId: string): Game | undefined {
|
|
return this.games.find((g) => g.manager.clientId === clientId)
|
|
}
|
|
|
|
getGameByManagerSocketId(socketId: string): Game | undefined {
|
|
return this.games.find((g) => g.manager.id === socketId)
|
|
}
|
|
|
|
getGameByPlayerSocketId(socketId: string): Game | undefined {
|
|
return this.games.find((g) => g.players.some((p) => p.id === socketId))
|
|
}
|
|
|
|
markGameAsEmpty(game: Game): void {
|
|
const alreadyEmpty = this.emptyGames.find(
|
|
(g) => g.game.gameId === game.gameId
|
|
)
|
|
|
|
if (!alreadyEmpty) {
|
|
this.emptyGames.push({
|
|
since: dayjs().unix(),
|
|
game,
|
|
})
|
|
console.log(
|
|
`Game ${game.gameId} marked as empty. Total empty games: ${this.emptyGames.length}`
|
|
)
|
|
}
|
|
}
|
|
|
|
reactivateGame(gameId: string): void {
|
|
const initialLength = this.emptyGames.length
|
|
this.emptyGames = this.emptyGames.filter((g) => g.game.gameId !== gameId)
|
|
|
|
if (this.emptyGames.length < initialLength) {
|
|
console.log(
|
|
`Game ${gameId} reactivated. Remaining empty games: ${this.emptyGames.length}`
|
|
)
|
|
}
|
|
}
|
|
|
|
removeGame(gameId: string): boolean {
|
|
const initialLength = this.games.length
|
|
this.games = this.games.filter((g) => g.gameId !== gameId)
|
|
this.emptyGames = this.emptyGames.filter((g) => g.game.gameId !== gameId)
|
|
|
|
const removed = this.games.length < initialLength
|
|
|
|
if (removed) {
|
|
console.log(`Game ${gameId} removed. Total games: ${this.games.length}`)
|
|
}
|
|
|
|
return removed
|
|
}
|
|
|
|
getAllGames(): Game[] {
|
|
return [...this.games]
|
|
}
|
|
|
|
getGameCount(): number {
|
|
return this.games.length
|
|
}
|
|
|
|
getEmptyGameCount(): number {
|
|
return this.emptyGames.length
|
|
}
|
|
|
|
private cleanupEmptyGames(): void {
|
|
const now = dayjs()
|
|
const stillEmpty = this.emptyGames.filter(
|
|
(g) =>
|
|
now.diff(dayjs.unix(g.since), "minute") <
|
|
this.EMPTY_GAME_TIMEOUT_MINUTES
|
|
)
|
|
|
|
if (stillEmpty.length === this.emptyGames.length) {
|
|
return
|
|
}
|
|
|
|
const removed = this.emptyGames.filter((g) => !stillEmpty.includes(g))
|
|
const removedGameIds = removed.map((r) => r.game.gameId)
|
|
|
|
this.games = this.games.filter((g) => !removedGameIds.includes(g.gameId))
|
|
this.emptyGames = stillEmpty
|
|
|
|
console.log(
|
|
`Removed ${removed.length} empty game(s). Remaining games: ${this.games.length}`
|
|
)
|
|
}
|
|
|
|
private startCleanupTask(): void {
|
|
this.cleanupInterval = setInterval(() => {
|
|
this.cleanupEmptyGames()
|
|
}, this.CLEANUP_INTERVAL_MS)
|
|
|
|
console.log("Game cleanup task started")
|
|
}
|
|
|
|
stopCleanupTask(): void {
|
|
if (this.cleanupInterval) {
|
|
clearInterval(this.cleanupInterval)
|
|
this.cleanupInterval = null
|
|
console.log("Game cleanup task stopped")
|
|
}
|
|
}
|
|
|
|
cleanup(): void {
|
|
this.stopCleanupTask()
|
|
this.games = []
|
|
this.emptyGames = []
|
|
console.log("Registry cleaned up")
|
|
}
|
|
}
|
|
|
|
export default Registry
|