From 399a1482ffa6f3be81040513cca75aa4a58a0388 Mon Sep 17 00:00:00 2001 From: evanpelle Date: Sat, 12 Oct 2024 14:52:56 -0700 Subject: [PATCH] single player in progress --- src/core/GameSocket.ts | 58 +++++++++++++++++++++++++++++++++++++++++ src/core/LocalServer.ts | 33 +++++++++++++++++++++-- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/src/core/GameSocket.ts b/src/core/GameSocket.ts index 7f42fb3bd..309d6e436 100644 --- a/src/core/GameSocket.ts +++ b/src/core/GameSocket.ts @@ -77,4 +77,62 @@ export class LocalSocket implements WebSocket { throw new Error("Method not implemented."); } +} + +export class GameMessageEvent implements MessageEvent { + + readonly data: any; + readonly origin: string; + readonly lastEventId: string; + readonly source: WindowProxy | null; + readonly ports: ReadonlyArray; + + constructor(data: any) { + this.data = data; + } + returnValue: boolean; + srcElement: EventTarget; + initEvent(type: string, bubbles?: boolean, cancelable?: boolean): void { + throw new Error("Method not implemented."); + } + NONE: 0; + CAPTURING_PHASE: 1; + AT_TARGET: 2; + BUBBLING_PHASE: 3; + + // MessageEvent interface methods + initMessageEvent(type: string, bubbles?: boolean, cancelable?: boolean, data?: any, origin?: string, lastEventId?: string, source?: WindowProxy | null, ports?: MessagePort[]): void { + // This method is deprecated, so we'll leave it as a no-op + console.warn('initMessageEvent is deprecated'); + } + + // Event interface properties and methods + readonly bubbles: boolean = false; + readonly cancelBubble: boolean = false; + readonly cancelable: boolean = false; + readonly composed: boolean = false; + readonly currentTarget: EventTarget | null = null; + readonly defaultPrevented: boolean = false; + readonly eventPhase: number = Event.NONE; + readonly isTrusted: boolean = false; + readonly target: EventTarget | null = null; + readonly timeStamp: number = Date.now(); + readonly type: string = 'message'; + + // Event interface methods + composedPath(): EventTarget[] { + return []; + } + + preventDefault(): void { + // No-op for this example + } + + stopImmediatePropagation(): void { + // No-op for this example + } + + stopPropagation(): void { + // No-op for this example + } } \ No newline at end of file diff --git a/src/core/LocalServer.ts b/src/core/LocalServer.ts index ba210cc55..d75b14882 100644 --- a/src/core/LocalServer.ts +++ b/src/core/LocalServer.ts @@ -1,12 +1,22 @@ import {Config} from "./configuration/Config"; -import {LocalSocket} from "./GameSocket"; -import {ClientMessage, ClientMessageSchema} from "./Schemas"; +import {GameMessageEvent, LocalSocket} from "./GameSocket"; +import {ClientMessage, ClientMessageSchema, Intent, ServerTurnMessageSchema, Turn} from "./Schemas"; export class LocalServer { + private gameID = "LOCAL" + public localSocket: LocalSocket + private turns: Turn[] = [] + private intents: Intent[] = [] + + private endTurnIntervalID + + + constructor(private config: Config) { + this.endTurnIntervalID = setInterval(() => this.endTurn(), this.config.turnIntervalMs()); } onConnect() { @@ -16,6 +26,25 @@ export class LocalServer { onMessage(message: string) { const clientMsg: ClientMessage = ClientMessageSchema.parse(JSON.parse(message)) if (clientMsg.type == "intent") { + this.intents.push(clientMsg.intent) } } + + private endTurn() { + const pastTurn: Turn = { + turnNumber: this.turns.length, + gameID: this.gameID, + intents: this.intents + } + this.turns.push(pastTurn) + this.intents = [] + + const msg = JSON.stringify(ServerTurnMessageSchema.parse( + { + type: "turn", + turn: pastTurn + } + )) + this.localSocket.onmessage(new GameMessageEvent(msg)) + } } \ No newline at end of file