mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-28 18:34:16 +00:00
have client send winner to server
This commit is contained in:
@@ -16,6 +16,8 @@ export class LocalServer {
|
||||
|
||||
private paused = false
|
||||
|
||||
private winner: ClientID | null = null
|
||||
|
||||
|
||||
constructor(
|
||||
private serverConfig: ServerConfig,
|
||||
@@ -58,6 +60,9 @@ export class LocalServer {
|
||||
}
|
||||
this.intents.push(clientMsg.intent)
|
||||
}
|
||||
if (clientMsg.type == "winner") {
|
||||
this.winner = clientMsg.winner
|
||||
}
|
||||
}
|
||||
|
||||
private endTurn() {
|
||||
@@ -92,7 +97,8 @@ export class LocalServer {
|
||||
players,
|
||||
this.turns,
|
||||
this.startedAt,
|
||||
Date.now()
|
||||
Date.now(),
|
||||
this.winner
|
||||
)
|
||||
// Clear turns because beacon only supports up to 64kb
|
||||
record.turns = []
|
||||
|
||||
+23
-1
@@ -2,7 +2,7 @@ import { Config, ServerConfig } from "../core/configuration/Config"
|
||||
import { SendLogEvent } from "../core/Consolex"
|
||||
import { EventBus, GameEvent } from "../core/EventBus"
|
||||
import { AllianceRequest, AllPlayers, Cell, GameType, Player, PlayerID, PlayerType, UnitType } from "../core/game/Game"
|
||||
import { ClientID, ClientIntentMessageSchema, ClientJoinMessageSchema, GameID, Intent, ServerMessage, ServerMessageSchema, ClientPingMessageSchema, GameConfig, ClientLogMessageSchema } from "../core/Schemas"
|
||||
import { ClientID, ClientIntentMessageSchema, ClientJoinMessageSchema, GameID, Intent, ServerMessage, ServerMessageSchema, ClientPingMessageSchema, GameConfig, ClientLogMessageSchema, ClientSendWinnerSchema } from "../core/Schemas"
|
||||
import { LobbyConfig } from "./ClientGameRunner"
|
||||
import { LocalServer } from "./LocalServer"
|
||||
import { UsernameInput } from "./UsernameInput";
|
||||
@@ -93,6 +93,12 @@ export class SendSetTargetTroopRatioEvent implements GameEvent {
|
||||
) { }
|
||||
}
|
||||
|
||||
export class SendWinnerEvent implements GameEvent {
|
||||
constructor(
|
||||
public readonly winner: ClientID
|
||||
) { }
|
||||
}
|
||||
|
||||
export class Transport {
|
||||
|
||||
private socket: WebSocket
|
||||
@@ -132,6 +138,7 @@ export class Transport {
|
||||
|
||||
this.eventBus.on(SendLogEvent, (e) => this.onSendLogEvent(e))
|
||||
this.eventBus.on(PauseGameEvent, (e) => this.onPauseGameEvent(e))
|
||||
this.eventBus.on(SendWinnerEvent, (e) => this.onSendWinnerEvent(e))
|
||||
}
|
||||
|
||||
private startPing() {
|
||||
@@ -375,6 +382,21 @@ export class Transport {
|
||||
}
|
||||
}
|
||||
|
||||
private onSendWinnerEvent(event: SendWinnerEvent) {
|
||||
if (this.isLocal || this.socket.readyState === WebSocket.OPEN) {
|
||||
const msg = ClientSendWinnerSchema.parse({
|
||||
type: "winner",
|
||||
clientID: this.lobbyConfig.clientID,
|
||||
gameID: this.lobbyConfig.gameID,
|
||||
winner: event.winner,
|
||||
})
|
||||
this.sendMsg(JSON.stringify(msg))
|
||||
} else {
|
||||
console.log('WebSocket is not open. Current state:', this.socket.readyState);
|
||||
console.log('attempting reconnect')
|
||||
}
|
||||
}
|
||||
|
||||
private sendIntent(intent: Intent) {
|
||||
if (this.isLocal || this.socket.readyState === WebSocket.OPEN) {
|
||||
const msg = ClientIntentMessageSchema.parse({
|
||||
|
||||
@@ -81,6 +81,7 @@ export function createRenderer(canvas: HTMLCanvasElement, game: GameView, eventB
|
||||
if (!(winModel instanceof WinModal)) {
|
||||
console.error('win modal not found')
|
||||
}
|
||||
winModel.eventBus = eventBus
|
||||
winModel.game = game
|
||||
|
||||
const optionsMenu = document.querySelector('options-menu') as OptionsMenu
|
||||
|
||||
@@ -7,6 +7,8 @@ import { Layer } from './Layer';
|
||||
import { GameUpdateType } from '../../../core/game/GameUpdates';
|
||||
import { PseudoRandom } from '../../../core/PseudoRandom';
|
||||
import { simpleHash } from '../../../core/Util';
|
||||
import { EventBus } from '../../../core/EventBus';
|
||||
import { SendWinnerEvent } from '../../Transport';
|
||||
|
||||
|
||||
const lowRadiationVictoryQuotes = [
|
||||
@@ -147,6 +149,7 @@ export const defeatQuotes = [
|
||||
@customElement('win-modal')
|
||||
export class WinModal extends LitElement implements Layer {
|
||||
public game: GameView
|
||||
public eventBus: EventBus
|
||||
|
||||
|
||||
private rand: PseudoRandom;
|
||||
@@ -300,6 +303,7 @@ export class WinModal extends LitElement implements Layer {
|
||||
this.game.updatesSinceLastTick()[GameUpdateType.WinUpdate]
|
||||
.forEach(wu => {
|
||||
const winner = this.game.playerBySmallID(wu.winnerID) as PlayerView
|
||||
this.eventBus.emit(new SendWinnerEvent(winner.clientID()))
|
||||
if (winner == this.game.myPlayer()) {
|
||||
this._title = 'You Won!'
|
||||
if (this.game.numTilesWithFallout() / this.game.numLandTiles() > .6) {
|
||||
|
||||
+11
-3
@@ -31,13 +31,14 @@ export type BuildUnitIntent = z.infer<typeof BuildUnitIntentSchema>
|
||||
export type Turn = z.infer<typeof TurnSchema>
|
||||
export type GameConfig = z.infer<typeof GameConfigSchema>
|
||||
|
||||
export type ClientMessage = ClientPingMessage | ClientIntentMessage | ClientJoinMessage | ClientLogMessage
|
||||
export type ClientMessage = ClientSendWinnerMessage | ClientPingMessage | ClientIntentMessage | ClientJoinMessage | ClientLogMessage
|
||||
export type ServerMessage = ServerSyncMessage | ServerStartGameMessage | ServerPingMessage
|
||||
|
||||
export type ServerSyncMessage = z.infer<typeof ServerTurnMessageSchema>
|
||||
export type ServerStartGameMessage = z.infer<typeof ServerStartGameMessageSchema>
|
||||
export type ServerPingMessage = z.infer<typeof ServerPingMessageSchema>
|
||||
|
||||
export type ClientSendWinnerMessage = z.infer<typeof ClientSendWinnerSchema>
|
||||
export type ClientPingMessage = z.infer<typeof ClientPingMessageSchema>
|
||||
export type ClientIntentMessage = z.infer<typeof ClientIntentMessageSchema>
|
||||
export type ClientJoinMessage = z.infer<typeof ClientJoinMessageSchema>
|
||||
@@ -224,11 +225,16 @@ export const ServerMessageSchema = z.union([
|
||||
// Client
|
||||
|
||||
const ClientBaseMessageSchema = z.object({
|
||||
type: z.enum(['join', 'intent', 'ping', 'log']),
|
||||
type: z.enum(['winner', 'join', 'intent', 'ping', 'log']),
|
||||
clientID: ID,
|
||||
gameID: ID,
|
||||
})
|
||||
|
||||
export const ClientSendWinnerSchema = ClientBaseMessageSchema.extend({
|
||||
type: z.literal('winner'),
|
||||
winner: ID,
|
||||
})
|
||||
|
||||
export const ClientLogMessageSchema = ClientBaseMessageSchema.extend({
|
||||
type: z.literal('log'),
|
||||
severity: z.nativeEnum(LogSeverity),
|
||||
@@ -254,6 +260,7 @@ export const ClientJoinMessageSchema = ClientBaseMessageSchema.extend({
|
||||
})
|
||||
|
||||
export const ClientMessageSchema = z.union([
|
||||
ClientSendWinnerSchema,
|
||||
ClientPingMessageSchema,
|
||||
ClientIntentMessageSchema,
|
||||
ClientJoinMessageSchema,
|
||||
@@ -276,5 +283,6 @@ export const GameRecordSchema = z.object({
|
||||
durationSeconds: z.number(),
|
||||
date: SafeString,
|
||||
num_turns: z.number(),
|
||||
turns: z.array(TurnSchema)
|
||||
turns: z.array(TurnSchema),
|
||||
winner: ID.nullable()
|
||||
})
|
||||
|
||||
+4
-2
@@ -2,7 +2,7 @@ import { v4 as uuidv4 } from 'uuid';
|
||||
import twemoji from 'twemoji';
|
||||
import DOMPurify from 'dompurify';
|
||||
import { Cell, Game, Player, Unit } from "./game/Game";
|
||||
import { GameConfig, GameID, GameRecord, PlayerRecord, Turn } from './Schemas';
|
||||
import { ClientID, GameConfig, GameID, GameRecord, PlayerRecord, Turn } from './Schemas';
|
||||
import { customAlphabet, nanoid } from 'nanoid';
|
||||
import { andFN, GameMap, manhattanDistFN, TileRef } from './game/GameMap';
|
||||
|
||||
@@ -207,7 +207,8 @@ export function CreateGameRecord(
|
||||
players: PlayerRecord[],
|
||||
turns: Turn[],
|
||||
start: number,
|
||||
end: number
|
||||
end: number,
|
||||
winner: ClientID | null
|
||||
): GameRecord {
|
||||
const record: GameRecord = {
|
||||
id: id,
|
||||
@@ -235,6 +236,7 @@ export function CreateGameRecord(
|
||||
record.players = players
|
||||
record.durationSeconds = Math.floor((record.endTimestampMS - record.startTimestampMS) / 1000)
|
||||
record.num_turns = turns.length
|
||||
record.winner = winner
|
||||
return record;
|
||||
}
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@ async function archiveToBigQuery(gameRecord: GameRecord) {
|
||||
duration_seconds: gameRecord.durationSeconds,
|
||||
number_turns: gameRecord.num_turns,
|
||||
game_mode: gameRecord.gameConfig.gameType,
|
||||
winner: null,
|
||||
winner: gameRecord.winner,
|
||||
difficulty: gameRecord.gameConfig.difficulty,
|
||||
map: gameRecord.gameConfig.gameMap,
|
||||
players: gameRecord.players.map(p => ({
|
||||
|
||||
@@ -5,7 +5,6 @@ import WebSocket from 'ws';
|
||||
import { slog } from "./StructuredLog";
|
||||
import { CreateGameRecord } from "../core/Util";
|
||||
import { archive } from "./Archive";
|
||||
import { arc } from "d3";
|
||||
|
||||
|
||||
export enum GamePhase {
|
||||
@@ -31,6 +30,8 @@ export class GameServer {
|
||||
|
||||
private lastPingUpdate = 0
|
||||
|
||||
private winner: ClientID | null = null
|
||||
|
||||
constructor(
|
||||
public readonly id: string,
|
||||
public readonly createdAt: number,
|
||||
@@ -89,6 +90,9 @@ export class GameServer {
|
||||
this.lastPingUpdate = Date.now()
|
||||
client.lastPing = Date.now()
|
||||
}
|
||||
if (clientMsg.type == "winner") {
|
||||
this.winner = clientMsg.winner
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(`error handline websocket request in game server: ${error}`)
|
||||
}
|
||||
@@ -190,7 +194,8 @@ export class GameServer {
|
||||
playerRecords,
|
||||
this.turns,
|
||||
this._startTime,
|
||||
Date.now()
|
||||
Date.now(),
|
||||
this.winner
|
||||
)
|
||||
)
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user