better game join logic, create dev and prod configs

This commit is contained in:
evanpelle
2024-08-17 12:42:18 -07:00
parent ed4201ab8c
commit 0ea670d975
13 changed files with 92 additions and 44 deletions
+2 -2
View File
@@ -20,13 +20,13 @@ export class GameManager {
return this.games.filter(g => g.phase() == phase)
}
addClient(client: Client, gameID: GameID) {
addClient(client: Client, gameID: GameID, lastTurn: number) {
const game = this.games.find(g => g.id == gameID)
if (!game) {
console.log(`game id ${gameID} not found`)
return
}
game.addClient(client)
game.addClient(client, lastTurn)
}
tick() {
+13 -10
View File
@@ -25,10 +25,10 @@ export class GameServer {
constructor(
public readonly id: string,
public readonly createdAt: number,
private settings: Config,
private config: Config,
) { }
public addClient(client: Client) {
public addClient(client: Client, lastTurn: number) {
console.log(`game ${this.id} adding client ${client.id}`)
// Remove stale client if this is a reconnect
this.clients = this.clients.filter(c => c.id != client.id)
@@ -46,29 +46,32 @@ export class GameServer {
// In case a client joined the game late and missed the start message.
if (this._hasStarted) {
this.sendStartGameMsg(client.ws)
this.sendStartGameMsg(client.ws, lastTurn)
}
}
public startTime(): number {
return this.createdAt + this.config.lobbyLifetime()
}
public start() {
this._hasStarted = true
this.clients.forEach(c => {
console.log(`game ${this.id} sending start message to ${c.id}`)
this.sendStartGameMsg(c.ws)
this.sendStartGameMsg(c.ws, 0)
})
this.endTurnIntervalID = setInterval(() => this.endTurn(), this.settings.turnIntervalMs());
this.endTurnIntervalID = setInterval(() => this.endTurn(), this.config.turnIntervalMs());
}
private addIntent(intent: Intent) {
this.intents.push(intent)
}
private sendStartGameMsg(ws: WebSocket) {
private sendStartGameMsg(ws: WebSocket, lastTurn: number) {
ws.send(JSON.stringify(ServerStartGameMessageSchema.parse(
{
type: "start",
// TODO: this could get large
turns: this.turns
turns: this.turns.slice(lastTurn)
}
)))
}
@@ -106,10 +109,10 @@ export class GameServer {
}
phase(): GamePhase {
if (Date.now() - this.createdAt < this.settings.lobbyLifetime()) {
if (Date.now() - this.createdAt < this.config.lobbyLifetime()) {
return GamePhase.Lobby
}
if (Date.now() - this.createdAt < this.settings.lobbyLifetime() + this.gameDuration) {
if (Date.now() - this.createdAt < this.config.lobbyLifetime() + this.gameDuration) {
return GamePhase.Active
}
return GamePhase.Finished
+4 -3
View File
@@ -8,6 +8,7 @@ import {Client} from './Client';
import {ClientMessage, ClientMessageSchema} from '../core/Schemas';
import {defaultConfig} from '../core/configuration/DefaultConfig';
import {GamePhase} from './GameServer';
import {getConfig} from '../core/configuration/Config';
@@ -23,12 +24,12 @@ const wss = new WebSocketServer({server});
app.use(express.static(path.join(__dirname, '../../out')));
app.use(express.json())
const gm = new GameManager(defaultConfig)
const gm = new GameManager(getConfig())
// New GET endpoint to list lobbies
app.get('/lobbies', (req, res) => {
res.json({
lobbies: gm.gamesByPhase(GamePhase.Lobby).map(g => g.id),
lobbies: gm.gamesByPhase(GamePhase.Lobby).map(g => ({id: g.id, startTime: g.startTime()})),
});
});
@@ -39,7 +40,7 @@ wss.on('connection', (ws) => {
const clientMsg: ClientMessage = ClientMessageSchema.parse(JSON.parse(message))
if (clientMsg.type == "join") {
console.log('got join request')
gm.addClient(new Client(clientMsg.clientID, ws), clientMsg.gameID)
gm.addClient(new Client(clientMsg.clientID, ws), clientMsg.gameID, clientMsg.lastTurn)
}
// TODO: send error message
})