can creater & join lobby

This commit is contained in:
evanpelle
2024-10-14 20:45:31 -07:00
parent e490e23add
commit 42a6a2fcef
12 changed files with 481 additions and 347 deletions
+30 -6
View File
@@ -1,6 +1,4 @@
import {Config} from "../core/configuration/Config";
import {PseudoRandom} from "../core/PseudoRandom";
import WebSocket from 'ws';
import {ClientID, GameID} from "../core/Schemas";
import {v4 as uuidv4} from 'uuid';
import {Client} from "./Client";
@@ -14,8 +12,6 @@ export class GameManager {
private games: GameServer[] = []
private random = new PseudoRandom(123)
constructor(private config: Config) { }
gamesByPhase(phase: GamePhase): GameServer[] {
@@ -31,6 +27,23 @@ export class GameManager {
game.addClient(client, lastTurn)
}
createPrivateGame(): string {
const id = genSmallGameID()
this.games.push(new GameServer(id, Date.now(), false, this.config))
return id
}
// TODO: stop private games to prevent memory leak.
startPrivateGame(gameID: GameID) {
const game = this.games.find(g => g.id == gameID)
console.log(`found game ${game}`)
if (game) {
game.start()
} else {
throw new Error(`cannot start private game, game ${gameID} not found`)
}
}
tick() {
const lobbies = this.gamesByPhase(GamePhase.Lobby)
const active = this.gamesByPhase(GamePhase.Active)
@@ -40,10 +53,10 @@ export class GameManager {
if (now > this.lastNewLobby + this.config.gameCreationRate()) {
this.lastNewLobby = now
const id = uuidv4()
lobbies.push(new GameServer(id, now, this.config))
lobbies.push(new GameServer(id, now, true, this.config))
}
active.filter(g => !g.hasStarted()).forEach(g => {
active.filter(g => !g.hasStarted() && g.isPublic).forEach(g => {
g.start()
})
finished.forEach(g => {
@@ -51,4 +64,15 @@ export class GameManager {
})
this.games = [...lobbies, ...active]
}
}
function genSmallGameID(): string {
// Generate a UUID
const uuid: string = uuidv4();
// Convert UUID to base64
const base64: string = btoa(uuid);
// Take the first 4 characters of the base64 string
return base64.slice(0, 4);
}
+17 -5
View File
@@ -26,6 +26,7 @@ export class GameServer {
constructor(
public readonly id: string,
public readonly createdAt: number,
public readonly isPublic: boolean,
private config: Config,
) { }
@@ -129,6 +130,22 @@ export class GameServer {
}
phase(): GamePhase {
if (Date.now() > this.createdAt + this.config.lobbyLifetime() + this.maxGameDuration) {
console.warn(`game past max duration ${this.id}`)
return GamePhase.Finished
}
if (!this.isPublic) {
if (this._hasStarted) {
if (this.clients.length == 0) {
return GamePhase.Finished
} else {
return GamePhase.Active
}
} else {
return GamePhase.Lobby
}
}
if (Date.now() - this.createdAt < this.config.lobbyLifetime()) {
return GamePhase.Lobby
}
@@ -137,11 +154,6 @@ export class GameServer {
return GamePhase.Finished
}
if (Date.now() > this.createdAt + this.config.lobbyLifetime() + this.maxGameDuration) {
console.warn(`game past max duration ${this.id}`)
return GamePhase.Finished
}
return GamePhase.Active
}
+28 -2
View File
@@ -8,7 +8,8 @@ import {ClientMessage, ClientMessageSchema} from '../core/Schemas';
import {getConfig} from '../core/configuration/Config';
import {LogSeverity, slog} from './StructuredLog';
import {Client} from './Client';
import {GamePhase} from './GameServer';
import {GamePhase, GameServer} from './GameServer';
import {v4 as uuidv4} from 'uuid';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
@@ -22,6 +23,8 @@ app.use(express.static(path.join(__dirname, '../../out')));
app.use(express.json())
const gm = new GameManager(getConfig())
const privateGames = new Map<string, GameServer>()
// New GET endpoint to list lobbies
app.get('/lobbies', (req, res) => {
const now = Date.now()
@@ -32,6 +35,30 @@ app.get('/lobbies', (req, res) => {
});
});
app.post('/private_lobby', (req, res) => {
const id = gm.createPrivateGame()
console.log('creating private lobby with id ${id}')
res.json({
id: id
});
});
app.post('/start_private_lobby/:id', (req, res) => {
console.log(`starting private lobby with id ${req.params.id}`)
gm.startPrivateGame(req.params.id)
});
app.put('/private_lobby/:id', (req, res) => {
});
app.get('/private_lobby/:id', (req, res) => {
res.json({
hi: '5'
});
});
wss.on('connection', (ws) => {
ws.on('message', (message: string) => {
@@ -61,4 +88,3 @@ server.listen(PORT, () => {
});
runGame()