From e2a027dde3d7cb168fc8c5fa52b6991ed5d6a396 Mon Sep 17 00:00:00 2001 From: Robbe Van Herck Date: Sat, 1 Sep 2018 13:04:01 +0200 Subject: [PATCH 01/10] Merge branch port_client into logging_port --- .../client/app/actions/matches/hosting.ts | 2 +- .../client/app/actions/matches/matches.ts | 70 +++--- .../client/app/components/matches/LogView.tsx | 11 +- .../app/components/play/lobby/Lobby.tsx | 227 +++++++++--------- .../app/components/play/lobby/SlotManager.ts | 47 ++-- planetwars/client/app/lib/match/MatchLog.ts | 26 +- planetwars/client/app/lib/match/index.ts | 4 +- planetwars/client/app/lib/match/utils.ts | 4 +- planetwars/client/app/reducers/hostPage.ts | 2 +- 9 files changed, 206 insertions(+), 187 deletions(-) diff --git a/planetwars/client/app/actions/matches/hosting.ts b/planetwars/client/app/actions/matches/hosting.ts index e2f7b723..dbf31132 100644 --- a/planetwars/client/app/actions/matches/hosting.ts +++ b/planetwars/client/app/actions/matches/hosting.ts @@ -9,4 +9,4 @@ export const changeBotSlot = actionCreator('CHANGE_BOT_SLOT'); export const selectMap = actionCreator('SELECT_MAP'); export const playerConnected = actionCreator('PLAYER_CONNECT'); export const playerDisconnected = actionCreator('PLAYER_DISCONNECT'); -export const serverStarted = actionCreator('SERVER_STARTED'); +export const serverStarted = actionCreator('SERVER_STARTED'); diff --git a/planetwars/client/app/actions/matches/matches.ts b/planetwars/client/app/actions/matches/matches.ts index 47dff0b0..cc3d31fb 100644 --- a/planetwars/client/app/actions/matches/matches.ts +++ b/planetwars/client/app/actions/matches/matches.ts @@ -37,7 +37,7 @@ function createHostedMatch(params: M.MatchParams): M.HostedMatch { return match; } -export function joinMatch(host: M.Address, bot: M.InternalBotSlot) { +export function joinMatch(address: M.Address, bot: M.InternalBotSlot) { return (dispatch: any, getState: any) => { const state: GState = getState(); @@ -48,7 +48,7 @@ export function joinMatch(host: M.Address, bot: M.InternalBotSlot) { type: M.MatchType.joined, status: M.MatchStatus.playing, timestamp: new Date(), - network: host, + network: address, logPath: Config.matchLogPath(matchId), bot, }; @@ -57,36 +57,35 @@ export function joinMatch(host: M.Address, bot: M.InternalBotSlot) { const [command, ...args] = stringArgv(state.bots[bot.botId].command); const botConfig = { command, args }; - const address = host; - const number = 1; + const host = address.host; + const port = address.port; const token = new Buffer(bot.token, 'hex'); - const connectionData = { token, address: host }; - const logger = new PwClient.Logger(match.logPath); - const clientParams = { token, address, logger, number, botConfig }; + const clientParams = { token, host, port, botConfig, clientId: 5 }; - PwClient.Client.connect({ - host: address.host, - port: address.port, + const clientReactor = new PwClient.Reactor(); + + clientReactor.dispatch(PwClient.events.RegisterClient.create({ + clientId: 5, // TODO: FIX THIS ASAP token: new Buffer(bot.token, 'hex'), - logger: new PwClient.Logger(match.logPath), - }).then((client) => { - const pwClient = new PwClient.PwClient(client, botConfig); - pwClient.onExit.subscribe(() => { + })); + try { + const pwClient = new PwClient.PwClient(clientParams); + clientReactor.on(PwClient.events.GameFinished).subscribe(() => { dispatch(completeMatch(match.uuid)); const title = 'Match ended'; const body = `A remote match has ended`; const link = `/matches/${match.uuid}`; dispatch(Notify.addNotification({ title, body, link, type: 'Finished' })); }); - }).catch((error) => { - console.log(error); - dispatch(handleMatchError(match.uuid, error)); + } catch (err) { + console.log(err); + dispatch(handleMatchError(match.uuid, err)); const title = 'Match errored'; const body = `A remote match on map has errored`; const link = `/matches/${match.uuid}`; dispatch(Notify.addNotification({ title, body, link, type: 'Error' })); - }); - }; + } + } } // https://github.com/ZeusWPI/MOZAIC/blob/1f9ab238e96028e3306bfe6b27920f70f9fba430/client/src/test.ts#L38 @@ -97,13 +96,13 @@ export function sendGo() { if (!matchParams) { throw Error('Under construction'); } const config = { - max_turns: matchParams.maxTurns, - map_file: state.maps[matchParams.map].mapPath, + maxTurns: matchParams.maxTurns, + mapPath: state.maps[matchParams.map].mapPath, }; if (runner) { console.log("running"); - runner.matchControl.startGame(config); + runner.dispatch(PwClient.events.StartGame.create(config)); } }; } @@ -140,7 +139,7 @@ export function runMatch() { }; }); - const config: PwClient.MatchParams = { + const config: PwClient.ServerParams = { address: params.address, logFile: match.logPath, ctrl_token: params.ctrl_token, @@ -148,31 +147,36 @@ export function runMatch() { console.log("This probably doesn't work!!!!"); - PwClient.MatchRunner.create(Config.matchRunner, config).then((runner) => { + try { + const server = new PwClient.ServerRunner(Config.matchRunner, config); + server.runServer(); + + const runner = new PwClient.Reactor(); + + dispatch(Host.serverStarted(runner)); - runner.matchControl.onPlayerConnected.subscribe((clientId) => { - dispatch(Host.playerConnected(players[clientId - 1].token)); + runner.on(PwClient.events.ClientConnected).subscribe((event) => { + dispatch(Host.playerConnected(players[event.clientId - 1].token)); }); - runner.matchControl.onPlayerDisconnected.subscribe((clientId) => { - dispatch(Host.playerDisconnected(players[clientId - 1].token)); + runner.on(PwClient.events.ClientDisconnected).subscribe((event) => { + dispatch(Host.playerDisconnected(players[event.clientId - 1].token)); }); - runner.onComplete.subscribe(() => { + server.onExit.subscribe(() => { dispatch(completeMatch(match.uuid)); const title = 'Match ended'; const body = `A match on map '${state.maps[params.map].name}' has ended`; const link = `/matches/${match.uuid}`; dispatch(Notify.addNotification({ title, body, link, type: 'Finished' })); }); - }) - .catch((error) => { + } catch (error) { dispatch(handleMatchError(match.uuid, error)); const title = 'Match errored'; const body = `A match on map '${state.maps[params.map].name}' has errored`; const link = `/matches/${match.uuid}`; dispatch(Notify.addNotification({ title, body, link, type: 'Error' })); - }); - }; + } + } } export function completeMatch(matchId: M.MatchId) { diff --git a/planetwars/client/app/components/matches/LogView.tsx b/planetwars/client/app/components/matches/LogView.tsx index c4196e88..ee2da671 100644 --- a/planetwars/client/app/components/matches/LogView.tsx +++ b/planetwars/client/app/components/matches/LogView.tsx @@ -4,7 +4,6 @@ import { MatchLog, GameState, Player, - PwTypes, } from '../../lib/match'; import * as classNames from 'classnames'; @@ -118,6 +117,9 @@ export const PlayerTurnView: SFC<{ turn: PlayerTurn }> = ({ turn }) => { case 'commands': { return ; } + default: { + return
"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAa"
; + } } }; @@ -143,9 +145,10 @@ export const ParseErrorView: SFC = (props) => { ); }; -export interface CommandsViewProps { commands: PwTypes.PlayerCommand[]; } +// TODO: typing +export interface CommandsViewProps { commands: any/*PlayerCommand[]*/; } export const CommandsView: SFC = (props) => { - const dispatches = props.commands.map((cmd, idx) => { + const dispatches = props.commands.map((cmd: any , idx: number) => { const isWarning = { [styles.warning]: !!cmd.error }; return (
  • @@ -171,7 +174,7 @@ export const DispatchError: SFC<{ error?: string }> = ({ error }) => { } }; -export const DispatchView: SFC<{ cmd: PwTypes.Command }> = ({ cmd }) => { +export const DispatchView: SFC<{ cmd: any /*Command*/ }> = ({ cmd }) => { const { ship_count, origin, destination } = cmd; return (
    diff --git a/planetwars/client/app/components/play/lobby/Lobby.tsx b/planetwars/client/app/components/play/lobby/Lobby.tsx index 1a817f91..a1623c6c 100644 --- a/planetwars/client/app/components/play/lobby/Lobby.tsx +++ b/planetwars/client/app/components/play/lobby/Lobby.tsx @@ -48,7 +48,8 @@ export interface RunningState { export class Lobby extends React.Component { private slotManager: SlotManager; - private server?: PwClient.MatchRunner; + private server?: PwClient.ServerRunner; + private matchReactor?: PwClient.Reactor; constructor(props: LobbyProps) { super(props); @@ -137,25 +138,28 @@ export class Lobby extends React.Component { const { name, command: fullCommand } = bot; const [command, ...args] = stringArgv(bot.command); - const botConfig = { name, command, args }; + const botConfig = { name , command, args }; - PwClient.Client.connect({ - token: Buffer.from(stringToken, 'hex'), + const client = new PwClient.PwClient({ host: config.address.host, port: config.address.port, - logger: this.server.logger, - }).then((client) => { - const _pwClient = new PwClient.PwClient(client, botConfig); - console.log('connected local bot'); - }); + token: Buffer.from(stringToken, 'hex'), + botConfig: { + command: botConfig.command, + args: botConfig.args, + }, + clientId: 5, + }) + client.run(); + console.log('connected local bot'); } private removeBot = (num: number) => this.slotManager.removeBot(num); private removeExternalBot = (token: M.Token, playerNum: number, clientId: number) => { if (!this.validifyRunning(this.state)) { return; } - if (this.server) { - this.server.matchControl.removePlayer(clientId); + if (this.server && this.matchReactor) { + this.matchReactor.dispatch(PwClient.events.RemoveClient.create({clientId})); this.slotManager.disconnectClient(clientId); this.slotManager.removeBot(playerNum); } @@ -197,60 +201,59 @@ export class Lobby extends React.Component { const params = { ctrl_token: ctrlToken, address: config.address, logFile }; console.log('launching server with', params); - // callbacks should be set on the current slotmanager, // not the one belonging to 'this'. (It changes when a match is launched). const slotManager = this.slotManager; - PwClient.MatchRunner.create(Config.matchRunner, params) - .then((server) => { - console.log('test proc'); - const slots = this.state.slots; - this.server = server; - this.slotManager.setMatchRunner(server); - this.server.onPlayerConnected.subscribe((clientId) => { - slotManager.connectClient(clientId); - }); - this.server.onPlayerDisconnected.subscribe((clientId) => { - slotManager.connectClient(clientId); - }); - - this.server.onComplete.subscribe(() => { - this.props.sendNotification( - "Match ended", - `A match on map '${ - this.state.type === "configuring" ? - "unknown" : - this.props.maps[this.state.config.mapId] - }' has ended`, - "Finished", - ); - }); - this.server.onError.subscribe(() => { - this.props.sendNotification( - "Match errored", - `A match on map '${ - this.state.type === "configuring" ? - "unknown" : - this.props.maps[this.state.config.mapId] - }' has errored`, - "Error", - ); - }); - const newState: RunningState = { - type: 'running', - config, - slots, - matchId, - logFile, - }; - this.setState(newState); - }) - .catch((err) => { - this.stopServer(); - alert(`Could not start game server: \n ${err}`); - console.log('Failed to start server.', err); + this.server = new PwClient.ServerRunner(Config.matchRunner, params); + this.server.runServer(); + + const slots = this.state.slots; + + const clientParams = { + host: config.address.host, + port: config.address.port, + token: Buffer.from(params.ctrl_token, 'hex'), + } + + try { + this.matchReactor = new PwClient.Reactor(); + this.slotManager.setMatchRunner(this.matchReactor); + + this.matchReactor.on(PwClient.events.ClientConnected).subscribe((event) => { + slotManager.connectClient(event.clientId); + }); + + this.matchReactor.on(PwClient.events.ClientDisconnected).subscribe((event) => { + slotManager.disconnectClient(event.clientId); + }); + + this.matchReactor.on(PwClient.events.GameFinished).subscribe(() => { + this.props.sendNotification( + "Match ended", + `A match on map '${ + this.state.type === "configuring" ? + "unknown" : + this.props.maps[this.state.config.mapId] + }' has ended`, + "Finished", + ); }); + // TODO: on error + + const newState: RunningState = { + type: 'running', + config, + slots, + matchId, + logFile, + }; + this.setState(newState); + } catch (err) { + this.stopServer(); + alert(`Could not start game server: \n ${err}`); + console.log('Failed to start server.', err); + } } private stopServer = () => { @@ -262,7 +265,7 @@ export class Lobby extends React.Component { } private launchGame = () => { - if (!this.server || !this.validifyRunning(this.state)) { + if (!this.matchReactor || !this.server || !this.validifyRunning(this.state)) { alert('Something went wrong'); return; } @@ -271,11 +274,11 @@ export class Lobby extends React.Component { const gameConf = Lib.exportConfig(this.state.config, this.props.maps); // Clear old listeners from the lobby - this.server.onPlayerConnected.clear(); - this.server.onPlayerDisconnected.clear(); + this.matchReactor.on(PwClient.events.ClientConnected).clear(); + this.matchReactor.on(PwClient.events.ClientDisconnected).clear(); // Bind completion listeners - this.server.onComplete.subscribe(() => { + this.server.onExit.subscribe(() => { this.props.onMatchComplete(matchId); }); this.server.onError.subscribe((err) => { @@ -283,59 +286,61 @@ export class Lobby extends React.Component { }); // Bind connection listeners - this.server.onPlayerDisconnected.subscribe( - (id: number) => this.props.onPlayerDisconnectDuringMatch(id)); - this.server.onPlayerConnected.subscribe( - (id: number) => this.props.onPlayerReconnectedDuringMatch(id)); + this.matchReactor.on(PwClient.events.ClientDisconnected).subscribe( + (event) => this.props.onPlayerDisconnectDuringMatch(event.clientId)); + this.matchReactor.on(PwClient.events.ClientConnected).subscribe( + (event) => this.props.onPlayerReconnectedDuringMatch(event.clientId)); // Start game - this.server.matchControl.startGame(gameConf) - // This gets procced when the game has actually started - .then(() => { - const { host, port, maxTurns, mapId } = this.props.config!; - if (!this.validifyRunning(this.state)) { return; } - const match: M.PlayingHostedMatch = { - uuid: this.state.matchId, - type: M.MatchType.hosted, - status: M.MatchStatus.playing, - maxTurns, - map: mapId!, - network: { host, port }, - timestamp: new Date(), - logPath: this.state.logFile, - players: this.state.slots.map((slot) => { - if (slot.bot) { - const botSlot: M.InternalBotSlot = { - type: M.BotSlotType.internal, - token: slot.token, - botId: slot.bot.uuid, - name: slot.name, - connected: slot.connected, - }; - return botSlot; - } else { - const botSlot: M.ExternalBotSlot = { - type: M.BotSlotType.external, - token: slot.token, - name: slot.name, - connected: slot.connected, - }; - return botSlot; - } - }), - }; - this.props.saveMatch(match); - this.resetState(); - }) - .catch((err) => { - alert('Failed to start match. See console for info.'); - console.log(err); - }); + const matchConfig = { + mapPath: gameConf.map_file, + maxTurns: gameConf.max_turns, + } + this.matchReactor.dispatch(PwClient.events.StartGame.create(matchConfig)); + try { + const { host, port, maxTurns, mapId } = this.props.config!; + if (!this.validifyRunning(this.state)) { return; } + const match: M.PlayingHostedMatch = { + uuid: this.state.matchId, + type: M.MatchType.hosted, + status: M.MatchStatus.playing, + maxTurns, + map: mapId!, + network: { host, port }, + timestamp: new Date(), + logPath: this.state.logFile, + players: this.state.slots.map((slot) => { + if (slot.bot) { + const botSlot: M.InternalBotSlot = { + type: M.BotSlotType.internal, + token: slot.token, + botId: slot.bot.uuid, + name: slot.name, + connected: slot.connected, + }; + return botSlot; + } else { + const botSlot: M.ExternalBotSlot = { + type: M.BotSlotType.external, + token: slot.token, + name: slot.name, + connected: slot.connected, + }; + return botSlot; + } + }), + }; + this.props.saveMatch(match); + this.resetState(); + } catch(err) { + alert('Failed to start match. See console for info.'); + console.log(err); + } } private killServer() { if (this.server) { - this.server.shutdown(); + this.server.killServer(); this.server = undefined; console.log('server killed'); } diff --git a/planetwars/client/app/components/play/lobby/SlotManager.ts b/planetwars/client/app/components/play/lobby/SlotManager.ts index 9b9ec513..fe3c459f 100644 --- a/planetwars/client/app/components/play/lobby/SlotManager.ts +++ b/planetwars/client/app/components/play/lobby/SlotManager.ts @@ -3,7 +3,7 @@ import { Chance } from 'chance'; import * as M from '../../../database/models'; import { generateToken } from '../../../utils/GameRunner'; import { WeakConfig, StrongConfig } from '../types'; -import { MatchRunner } from 'mozaic-client'; +import { Reactor, events, PwClient } from 'mozaic-client'; export interface Slot { name: string; @@ -17,7 +17,7 @@ export type Slots = { [token: string]: Slot }; export type Clients = { [clientId: number]: Slot}; export class SlotManager { - public matchRunner?: MatchRunner; + public matchReactor?: Reactor; public connectedClients: Set = new Set(); public slots: Slots; public slotList: string[]; @@ -84,21 +84,22 @@ export class SlotManager { this.notifyListeners(); } - public setMatchRunner(matchRunner: MatchRunner) { - this.matchRunner = matchRunner; + public setMatchRunner(matchReactor: Reactor) { + this.matchReactor = matchReactor; - matchRunner.onPlayerConnected.subscribe((clientId) => { - this.connectClient(clientId); + // TODO: typing + matchReactor.on(events.ClientConnected).subscribe((event: any) => { + this.connectClient(event.clientId); }); - matchRunner.onPlayerDisconnected.subscribe((clientId) => { - this.disconnectClient(clientId); + // TODO: typing + matchReactor.on(events.ClientDisconnected).subscribe((event: any) => { + this.disconnectClient(event.clientId); }); this.slotList.forEach((token) => { const slot = this.slots[token]; this.registerSlot(slot); - this.notifyListeners(); }); } @@ -111,24 +112,28 @@ export class SlotManager { } private registerSlot(slot: Slot) { - if (this.matchRunner) { + if (this.matchReactor) { const token = Buffer.from(slot.token, 'hex'); - this.matchRunner.matchControl.addPlayer(token).then((clientId) => { - slot.clientId = clientId; - this.clients[clientId] = slot; - this.notifyListeners(); - }); + this.matchReactor.dispatch(events.RegisterClient.create({ + clientId: slot.clientId, + token: Buffer.from(slot.token, 'utf-8'), + })); + if (slot.clientId) { + this.clients[slot.clientId] = slot; + } + this.notifyListeners(); } } private unregisterSlot(slot: Slot) { - if (this.matchRunner && slot.clientId) { + if (this.matchReactor && slot.clientId) { const clientId = slot.clientId; - this.matchRunner.matchControl.removePlayer(slot.clientId).then(() => { - delete this.clients[clientId]; - delete this.slots[slot.token]; - this.notifyListeners(); - }); + this.matchReactor.dispatch(events.RemoveClient.create({ + clientId: slot.clientId, + })); + delete this.clients[clientId]; + delete this.slots[slot.token]; + this.notifyListeners(); } } diff --git a/planetwars/client/app/lib/match/MatchLog.ts b/planetwars/client/app/lib/match/MatchLog.ts index c0f4b22a..2c033b32 100644 --- a/planetwars/client/app/lib/match/MatchLog.ts +++ b/planetwars/client/app/lib/match/MatchLog.ts @@ -1,5 +1,4 @@ -import { PwTypes } from 'mozaic-client'; -import { PlanetList, Expedition, Player } from './types'; +import { PlanetList, Expedition, Player, JsonExpedition, JsonPlanet } from './types'; import * as _ from 'lodash'; export abstract class MatchLog { @@ -19,7 +18,8 @@ export abstract class MatchLog { return this.gameStates[this.gameStates.length - 1].livingPlayers(); } - public abstract addEntry(entry: PwTypes.LogEntry): void; + // TODO: typing + public abstract addEntry(entry: any /*PlayerAction*/): void; protected getPlayerLog(playerNum: number) { let playerLog = this.playerLogs[playerNum]; @@ -32,7 +32,8 @@ export abstract class MatchLog { } export class HostedMatchLog extends MatchLog { - public addEntry(entry: PwTypes.LogEntry) { + // TODO: typing + public addEntry(entry: any) { switch (entry.type) { case "game_state": { const state = GameState.fromJson(entry.state); @@ -47,7 +48,8 @@ export class HostedMatchLog extends MatchLog { } export class JoinedMatchLog extends MatchLog { - public addEntry(entry: PwTypes.LogEntry) { + // TODO: typing + public addEntry(entry: any) { if (entry.type === 'player_entry') { // this should always be the case since this is a joined match const { player, record } = entry; @@ -70,9 +72,10 @@ export class GameState { this.expeditions = expeditions; } - public static fromJson(json: PwTypes.GameState) { + // TODO: typing + public static fromJson(json: any) { const planets: PlanetList = {}; - json.planets.forEach((p) => { + json.planets.forEach((p: JsonPlanet) => { planets[p.name] = { name: p.name, x: p.x, @@ -82,7 +85,7 @@ export class GameState { }; }); - const expeditions = json.expeditions.map((e) => { + const expeditions = json.expeditions.map((e: JsonExpedition) => { return { id: e.id, origin: planets[e.origin], @@ -118,7 +121,8 @@ export class PlayerLog { this.turns = []; } - public addRecord(record: PwTypes.LogRecord) { + // TODO: typing + public addRecord(record: any) { switch (record.type) { case 'step': { this.turns.push({ state: record.state }); @@ -137,9 +141,9 @@ export class PlayerLog { } export interface PlayerTurn { - state: PwTypes.GameState; + state: GameState; command?: string; - action?: PwTypes.PlayerAction; + action?: any /*PlayerAction*/; } export interface PlayerMap { diff --git a/planetwars/client/app/lib/match/index.ts b/planetwars/client/app/lib/match/index.ts index 00d2c87b..0f1456bd 100644 --- a/planetwars/client/app/lib/match/index.ts +++ b/planetwars/client/app/lib/match/index.ts @@ -2,6 +2,4 @@ import { MatchLog } from '.'; export { MatchLog, PlayerMap } from './MatchLog'; export * from './types'; -export * from './utils'; -// TODO: this is not exactly ideal -export { PwTypes } from 'mozaic-client'; +export * from './utils'; \ No newline at end of file diff --git a/planetwars/client/app/lib/match/utils.ts b/planetwars/client/app/lib/match/utils.ts index bfb23d17..bca55b6f 100644 --- a/planetwars/client/app/lib/match/utils.ts +++ b/planetwars/client/app/lib/match/utils.ts @@ -1,6 +1,5 @@ import * as M from '../../database/models'; import * as fs from 'fs'; -import { PwTypes } from '.'; import { MatchLog, HostedMatchLog, JoinedMatchLog } from './MatchLog'; export function emptyLog(type: M.MatchType): MatchLog { @@ -12,7 +11,8 @@ export function emptyLog(type: M.MatchType): MatchLog { } } -export function logFileEntries(path: string): PwTypes.LogEntry[] { +// TODO: typing +export function logFileEntries(path: string): any[] { const lines = fs.readFileSync(path, 'utf-8').trim().split('\n'); return lines.map((line: string) => JSON.parse(line)); } diff --git a/planetwars/client/app/reducers/hostPage.ts b/planetwars/client/app/reducers/hostPage.ts index e074e65f..670885ea 100644 --- a/planetwars/client/app/reducers/hostPage.ts +++ b/planetwars/client/app/reducers/hostPage.ts @@ -8,7 +8,7 @@ export interface HostPageState { slots: M.BotSlot[]; serverRunning: boolean; matchParams?: M.MatchParams; - runner?: PwClient.MatchRunner; + runner?: PwClient.Reactor; } const defaultState = { slots: [], serverRunning: false }; From 235911a568684db53b82545f86283f134e348d75 Mon Sep 17 00:00:00 2001 From: Robbe Van Herck Date: Sun, 2 Sep 2018 16:45:53 +0200 Subject: [PATCH 02/10] It compiles, again again --- client/src/index.ts | 9 +++++++-- client/src/replay.ts | 13 +------------ .../client/app/actions/matches/matches.ts | 18 +++++++++++++----- .../client/app/components/play/lobby/Lobby.tsx | 4 +++- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/client/src/index.ts b/client/src/index.ts index a839e8cc..5f9ba134 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -1,8 +1,13 @@ -import "./event_types"; - export { Address } from './networking/EventWire'; export { BotRunner, BotConfig } from './planetwars/BotRunner'; export { PwClient } from './planetwars/PwClient'; +export { Replayer } from "./replay"; +export { Reactor } from "./reactors/Reactor"; +export { ServerRunner, ServerParams } from "./planetwars/ServerRunner"; +export { Logger } from "./Logger"; +import * as events from "./eventTypes"; import * as PwTypes from './planetwars/PwTypes'; + +export { events }; export { PwTypes }; diff --git a/client/src/replay.ts b/client/src/replay.ts index 4e53f1a2..f6b2d6fc 100644 --- a/client/src/replay.ts +++ b/client/src/replay.ts @@ -49,15 +49,4 @@ export class Replayer { this.emit(logEvent); }); } -} - -const replayer = new Replayer(); - -// just print all events for now -Object.keys(events).forEach((eventName) => { - replayer.on(events[eventName]).subscribe((event) => { - console.log(event); - }); -}); - -replayer.replayFile('log.out'); +} \ No newline at end of file diff --git a/planetwars/client/app/actions/matches/matches.ts b/planetwars/client/app/actions/matches/matches.ts index cc3d31fb..a5f7ff91 100644 --- a/planetwars/client/app/actions/matches/matches.ts +++ b/planetwars/client/app/actions/matches/matches.ts @@ -11,6 +11,7 @@ import { Config } from '../../utils/Config'; import * as Notify from '../notifications'; import * as Host from './hosting'; import { actionCreator } from '../helpers'; +import { createWriteStream } from 'fs'; export const importMatchFromDB = actionCreator('IMPORT_MATCH_FROM_DB'); export const importMatchError = actionCreator('IMPORT_MATCH_ERROR'); @@ -60,12 +61,19 @@ export function joinMatch(address: M.Address, bot: M.InternalBotSlot) { const host = address.host; const port = address.port; const token = new Buffer(bot.token, 'hex'); - const clientParams = { token, host, port, botConfig, clientId: 5 }; - - const clientReactor = new PwClient.Reactor(); + const clientParams = { + token, + host, + port, + botConfig, + clientId: 5, // FIX QUICK + logSink: createWriteStream(match.logPath) + }; + const logger = new PwClient.Logger(clientParams.clientId, createWriteStream(match.logPath)); + const clientReactor = new PwClient.Reactor(logger); clientReactor.dispatch(PwClient.events.RegisterClient.create({ - clientId: 5, // TODO: FIX THIS ASAP + clientId: clientParams.clientId, token: new Buffer(bot.token, 'hex'), })); try { @@ -151,7 +159,7 @@ export function runMatch() { const server = new PwClient.ServerRunner(Config.matchRunner, config); server.runServer(); - const runner = new PwClient.Reactor(); + const runner = new PwClient.Reactor(new PwClient.Logger(0, createWriteStream(match.logPath))); dispatch(Host.serverStarted(runner)); diff --git a/planetwars/client/app/components/play/lobby/Lobby.tsx b/planetwars/client/app/components/play/lobby/Lobby.tsx index a1623c6c..7c316c9f 100644 --- a/planetwars/client/app/components/play/lobby/Lobby.tsx +++ b/planetwars/client/app/components/play/lobby/Lobby.tsx @@ -12,6 +12,7 @@ import Section from '../Section'; import { SlotList } from './SlotList'; import { ServerControls } from './ServerControls'; import { SlotManager, Slot } from './SlotManager'; +import { createWriteStream } from 'fs'; // tslint:disable-next-line:no-var-requires const styles = require('./Lobby.scss'); @@ -148,6 +149,7 @@ export class Lobby extends React.Component { command: botConfig.command, args: botConfig.args, }, + logSink: createWriteStream(this.state.logFile), clientId: 5, }) client.run(); @@ -217,7 +219,7 @@ export class Lobby extends React.Component { } try { - this.matchReactor = new PwClient.Reactor(); + this.matchReactor = new PwClient.Reactor(new PwClient.Logger(0, createWriteStream(logFile))); this.slotManager.setMatchRunner(this.matchReactor); this.matchReactor.on(PwClient.events.ClientConnected).subscribe((event) => { From 44de5e7934d1f34c5d60ccb1f825ffcb40e68208 Mon Sep 17 00:00:00 2001 From: Robbe Van Herck Date: Sun, 2 Sep 2018 18:25:04 +0200 Subject: [PATCH 03/10] Added Client ID --- .../client/app/actions/matches/matches.ts | 4 +-- .../client/app/components/join/Join.tsx | 26 ++++++++++++++----- .../app/components/play/lobby/Lobby.tsx | 6 +++-- .../app/components/play/lobby/SlotList.tsx | 9 ++++--- .../app/components/play/lobby/SlotManager.ts | 1 + planetwars/client/app/database/migrate.ts | 1 + planetwars/client/app/database/migrationV4.ts | 1 + planetwars/client/app/reducers/hostPage.ts | 1 + 8 files changed, 36 insertions(+), 13 deletions(-) diff --git a/planetwars/client/app/actions/matches/matches.ts b/planetwars/client/app/actions/matches/matches.ts index a5f7ff91..7a4d2089 100644 --- a/planetwars/client/app/actions/matches/matches.ts +++ b/planetwars/client/app/actions/matches/matches.ts @@ -66,8 +66,8 @@ export function joinMatch(address: M.Address, bot: M.InternalBotSlot) { host, port, botConfig, - clientId: 5, // FIX QUICK - logSink: createWriteStream(match.logPath) + clientId: bot.clientid, + logSink: createWriteStream(match.logPath), }; const logger = new PwClient.Logger(clientParams.clientId, createWriteStream(match.logPath)); const clientReactor = new PwClient.Reactor(logger); diff --git a/planetwars/client/app/components/join/Join.tsx b/planetwars/client/app/components/join/Join.tsx index 52004581..5b509a5f 100644 --- a/planetwars/client/app/components/join/Join.tsx +++ b/planetwars/client/app/components/join/Join.tsx @@ -24,6 +24,7 @@ export interface ImportCopy { name: string; host: string; port: number; + clientId: number; } export interface JoinState { @@ -32,6 +33,7 @@ export interface JoinState { token: string; lastClipboard: string; import?: ImportCopy; + clientId?: number; } export class Join extends React.Component { @@ -47,6 +49,7 @@ export class Join extends React.Component { }; this.setAddress = this.setAddress.bind(this); this.setToken = this.setToken.bind(this); + this.setClientid = this.setClientid.bind(this); this.setBotId = this.setBotId.bind(this); this.joinGame = this.joinGame.bind(this); } @@ -63,6 +66,10 @@ export class Join extends React.Component { + + + + { Import "{this.state.import.name}" from clipboard -
    ): + ) : undefined } @@ -95,17 +102,17 @@ export class Join extends React.Component { private importConfig = () => { if (!this.state.import) { return; } - const {host, port, name, token} = this.state.import; - this.setState({ address: {host, port}, token }); + const {host, port, name, token, clientId } = this.state.import; + this.setState({ address: {host, port}, token, clientId }); } private checkClipboard = () => { const clipBoardtext = clipboard.readText(); if (this.state.lastClipboard !== clipBoardtext) { try { - const {host, port, name, token} = JSON.parse(clipBoardtext); + const {host, port, name, token, clientId } = JSON.parse(clipBoardtext); if (host && port && name && token) { - this.setState({ import: { host, port, name, token } }); + this.setState({ import: { host, port, name, token, clientId } }); } else { this.setState({ import: undefined }); } @@ -118,7 +125,7 @@ export class Join extends React.Component { } private isValid() { - return this.state.botId && this.state.token; + return this.state.botId && this.state.token && this.state.clientId; } private setAddress(address: M.Address) { @@ -133,6 +140,12 @@ export class Join extends React.Component { }); } + private setClientid(evt: React.FormEvent) { + this.setState({ + clientId: parseInt(evt.currentTarget.value, 10), + }); + } + private setBotId(botId: M.BotId) { this.setState({ botId }); } @@ -144,6 +157,7 @@ export class Join extends React.Component { botId: this.state.botId!, name: this.props.allBots[this.state.botId!].name, connected: true, + clientid: this.state.clientId!, }; this.props.joinMatch(this.state.address, bot); } diff --git a/planetwars/client/app/components/play/lobby/Lobby.tsx b/planetwars/client/app/components/play/lobby/Lobby.tsx index 7c316c9f..a3935ca2 100644 --- a/planetwars/client/app/components/play/lobby/Lobby.tsx +++ b/planetwars/client/app/components/play/lobby/Lobby.tsx @@ -135,7 +135,7 @@ export class Lobby extends React.Component { const slotManager = this.slotManager; const { config } = this.state; - const { bot, token: stringToken } = slot; + const { bot, token: stringToken, clientId } = slot; const { name, command: fullCommand } = bot; const [command, ...args] = stringArgv(bot.command); @@ -150,7 +150,7 @@ export class Lobby extends React.Component { args: botConfig.args, }, logSink: createWriteStream(this.state.logFile), - clientId: 5, + clientId, }) client.run(); console.log('connected local bot'); @@ -319,6 +319,7 @@ export class Lobby extends React.Component { botId: slot.bot.uuid, name: slot.name, connected: slot.connected, + clientid: slot.clientId || 0, }; return botSlot; } else { @@ -327,6 +328,7 @@ export class Lobby extends React.Component { token: slot.token, name: slot.name, connected: slot.connected, + clientid: slot.clientId || 0, }; return botSlot; } diff --git a/planetwars/client/app/components/play/lobby/SlotList.tsx b/planetwars/client/app/components/play/lobby/SlotList.tsx index 579d86e3..2fa12dcc 100644 --- a/planetwars/client/app/components/play/lobby/SlotList.tsx +++ b/planetwars/client/app/components/play/lobby/SlotList.tsx @@ -52,7 +52,9 @@ export class SlotElement extends React.Component { public render() { const { slot, index } = this.props; - const { token, name } = slot; + const { token, name, clientId } = slot; + + console.log(slot); const kicked = (this.props.willBeKicked) ? (styles.kicked) : ''; return ( @@ -61,6 +63,7 @@ export class SlotElement extends React.Component {

    {token}

    Status: {this.statusToFriendly(slot)}

    Name: {name}

    +

    Client ID: {clientId}

    {this.getActions()}
    @@ -72,8 +75,8 @@ export class SlotElement extends React.Component { } private copyFull = (): void => { - const { slot: { token, name }, index, port, host } = this.props; - const data = { token, name, port, host }; + const { slot: { token, name, clientId }, index, port, host } = this.props; + const data = { token, name, port, host, clientId }; clipboard.writeText(JSON.stringify(data)); } diff --git a/planetwars/client/app/components/play/lobby/SlotManager.ts b/planetwars/client/app/components/play/lobby/SlotManager.ts index fe3c459f..79ee0685 100644 --- a/planetwars/client/app/components/play/lobby/SlotManager.ts +++ b/planetwars/client/app/components/play/lobby/SlotManager.ts @@ -35,6 +35,7 @@ export class SlotManager { public update(map: M.MapMeta) { while (this.slotList.length < map.slots) { const slot = this.createSlot(); + slot.clientId = this.slotList.length + 1; this.slotList.push(slot.token); } diff --git a/planetwars/client/app/database/migrate.ts b/planetwars/client/app/database/migrate.ts index e32bb007..d614c0fb 100644 --- a/planetwars/client/app/database/migrate.ts +++ b/planetwars/client/app/database/migrate.ts @@ -86,6 +86,7 @@ function upgradeV3(db: V3.DbSchema): V4.DbSchema { connected: true, botId: player, name: newBots[player].name, + clientid: -1, }}); const matchParams: V4.HostedMatchProps = { type: V4.MatchType.hosted, diff --git a/planetwars/client/app/database/migrationV4.ts b/planetwars/client/app/database/migrationV4.ts index f72c7467..c4dbb0df 100644 --- a/planetwars/client/app/database/migrationV4.ts +++ b/planetwars/client/app/database/migrationV4.ts @@ -155,6 +155,7 @@ export interface BotSlotProps { type: BotSlotType; token: Token; connected: boolean; // Maybe more info? + clientid: number; } export type ExternalBotSlot = BotSlotProps & { diff --git a/planetwars/client/app/reducers/hostPage.ts b/planetwars/client/app/reducers/hostPage.ts index 670885ea..14794f65 100644 --- a/planetwars/client/app/reducers/hostPage.ts +++ b/planetwars/client/app/reducers/hostPage.ts @@ -31,6 +31,7 @@ export function hostReducer(state: HostPageState = defaultState, action: any) { name: 'Player ' + i, token: generateToken(), connected: false, + clientid: i, }); } From c5072e926779290c1cfa0cdfba47dc8c30c5218b Mon Sep 17 00:00:00 2001 From: Robbe Van Herck Date: Thu, 6 Sep 2018 16:16:58 +0200 Subject: [PATCH 04/10] Hope this works --- client/src/planetwars/ServerRunner.ts | 1 + client/src/replay.ts | 6 ++++- .../client/app/components/info/Info.tsx | 13 ++++++++++ planetwars/client/app/lib/match/MatchLog.ts | 24 ++++++++++--------- planetwars/client/app/lib/match/index.ts | 4 +--- planetwars/client/app/lib/match/utils.ts | 13 ++++++++-- 6 files changed, 44 insertions(+), 17 deletions(-) diff --git a/client/src/planetwars/ServerRunner.ts b/client/src/planetwars/ServerRunner.ts index 8f541f86..b031b12a 100644 --- a/client/src/planetwars/ServerRunner.ts +++ b/client/src/planetwars/ServerRunner.ts @@ -76,6 +76,7 @@ export class ServerRunner { private writeConfigFile() { // TODO: maybe doing this async would be better const file = tmp.fileSync(); + console.log(file); const json = JSON.stringify(this.configJSON()); fs.writeFileSync(file.fd, json); return file.name; diff --git a/client/src/replay.ts b/client/src/replay.ts index f6b2d6fc..f514f260 100644 --- a/client/src/replay.ts +++ b/client/src/replay.ts @@ -1,4 +1,4 @@ -import { createReadStream } from "fs"; +import { createReadStream, ReadStream } from "fs"; import { ProtobufReader } from "./networking/ProtobufStream"; import * as protocol_root from './proto'; import { SimpleEventEmitter, EventType } from "./reactors/SimpleEventEmitter"; @@ -42,6 +42,10 @@ export class Replayer { public replayFile(path: string) { const logStream = createReadStream(path); + this.replayReadStream(logStream); + } + + public replayReadStream(logStream: ReadStream) { const messageStream = logStream.pipe(new ProtobufReader()); messageStream.on('data', (bytes: Uint8Array) => { diff --git a/planetwars/client/app/components/info/Info.tsx b/planetwars/client/app/components/info/Info.tsx index 55663e7d..a0a30730 100644 --- a/planetwars/client/app/components/info/Info.tsx +++ b/planetwars/client/app/components/info/Info.tsx @@ -1,3 +1,10 @@ +// ----------TEMP DEBUG TESTING---------- + +import {parseLogFile} from "../../lib/match/index"; +import { MatchType } from "../../database/models"; + +// ----------TEMP DEBUG TESTING---------- + import * as React from 'react'; import { shell } from 'electron'; @@ -18,6 +25,12 @@ export default class Info extends React.Component<{}, { mapToggled: boolean }> { } public render() { + // ----------TEMP DEBUG TESTING---------- + + parseLogFile("", MatchType.hosted); + + // ----------TEMP DEBUG TESTING---------- + const Readme = () => ( README diff --git a/planetwars/client/app/lib/match/MatchLog.ts b/planetwars/client/app/lib/match/MatchLog.ts index 2c033b32..c47281df 100644 --- a/planetwars/client/app/lib/match/MatchLog.ts +++ b/planetwars/client/app/lib/match/MatchLog.ts @@ -1,5 +1,6 @@ import { PlanetList, Expedition, Player, JsonExpedition, JsonPlanet } from './types'; import * as _ from 'lodash'; +import { events } from "mozaic-client"; export abstract class MatchLog { public playerLogs: PlayerMap; @@ -19,7 +20,7 @@ export abstract class MatchLog { } // TODO: typing - public abstract addEntry(entry: any /*PlayerAction*/): void; + public abstract addEntry(entry: any /* event */): void; protected getPlayerLog(playerNum: number) { let playerLog = this.playerLogs[playerNum]; @@ -34,14 +35,14 @@ export abstract class MatchLog { export class HostedMatchLog extends MatchLog { // TODO: typing public addEntry(entry: any) { - switch (entry.type) { - case "game_state": { - const state = GameState.fromJson(entry.state); + switch (entry.eventType) { + case events.GameStep: { + const {state} = entry; this.gameStates.push(state); break; } - case "player_entry": { - this.getPlayerLog(entry.player).addRecord(entry.record); + case events.PlayerAction: { + this.getPlayerLog(entry.clientId).addRecord(entry.action); } } } @@ -50,14 +51,15 @@ export class HostedMatchLog extends MatchLog { export class JoinedMatchLog extends MatchLog { // TODO: typing public addEntry(entry: any) { - if (entry.type === 'player_entry') { + console.log(entry); + if (entry.eventType === events.PlayerAction) { // this should always be the case since this is a joined match - const { player, record } = entry; + const { player, action } = entry; - this.getPlayerLog(player).addRecord(record); + this.getPlayerLog(player).addRecord(action); - if (player === 1 && record.type === 'step') { - this.gameStates.push(GameState.fromJson(record.state)); + if (player === 1 && action.type === 'step') { + this.gameStates.push(GameState.fromJson(action.state)); } } } diff --git a/planetwars/client/app/lib/match/index.ts b/planetwars/client/app/lib/match/index.ts index 0f1456bd..938e281f 100644 --- a/planetwars/client/app/lib/match/index.ts +++ b/planetwars/client/app/lib/match/index.ts @@ -1,5 +1,3 @@ -import { MatchLog } from '.'; - export { MatchLog, PlayerMap } from './MatchLog'; export * from './types'; -export * from './utils'; \ No newline at end of file +export * from './utils'; diff --git a/planetwars/client/app/lib/match/utils.ts b/planetwars/client/app/lib/match/utils.ts index bca55b6f..4d6b9bc4 100644 --- a/planetwars/client/app/lib/match/utils.ts +++ b/planetwars/client/app/lib/match/utils.ts @@ -1,6 +1,7 @@ import * as M from '../../database/models'; import * as fs from 'fs'; import { MatchLog, HostedMatchLog, JoinedMatchLog } from './MatchLog'; +import { Replayer, events } from "mozaic-client"; export function emptyLog(type: M.MatchType): MatchLog { switch (type) { @@ -19,9 +20,17 @@ export function logFileEntries(path: string): any[] { export function parseLogFile(path: string, type: M.MatchType): MatchLog { const log = emptyLog(type); - logFileEntries(path).forEach((entry) => { - log.addEntry(entry); + const replayer = new Replayer(); + + replayer.on(events.GameStep).subscribe((event) => { + log.addEntry(event); + }); + + replayer.on(events.PlayerAction).subscribe((event) => { + log.addEntry(event); }); + + replayer.replayFile(path); return log; } From 8fe50228df9ec86b28f7eaab7dfb223d5bf82757 Mon Sep 17 00:00:00 2001 From: Robbe Van Herck Date: Fri, 7 Sep 2018 17:43:38 +0200 Subject: [PATCH 05/10] Fixed HostedMatchLog --- client/src/index.ts | 1 + client/src/planetwars/ServerRunner.ts | 1 - .../client/app/components/info/Info.tsx | 3 +- planetwars/client/app/lib/match/MatchLog.ts | 76 ++++++++++--------- planetwars/client/app/lib/match/utils.ts | 4 + 5 files changed, 47 insertions(+), 38 deletions(-) diff --git a/client/src/index.ts b/client/src/index.ts index 5f9ba134..e2ae3984 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -5,6 +5,7 @@ export { Replayer } from "./replay"; export { Reactor } from "./reactors/Reactor"; export { ServerRunner, ServerParams } from "./planetwars/ServerRunner"; export { Logger } from "./Logger"; +export { Event } from "./reactors/SimpleEventEmitter" import * as events from "./eventTypes"; import * as PwTypes from './planetwars/PwTypes'; diff --git a/client/src/planetwars/ServerRunner.ts b/client/src/planetwars/ServerRunner.ts index b031b12a..8f541f86 100644 --- a/client/src/planetwars/ServerRunner.ts +++ b/client/src/planetwars/ServerRunner.ts @@ -76,7 +76,6 @@ export class ServerRunner { private writeConfigFile() { // TODO: maybe doing this async would be better const file = tmp.fileSync(); - console.log(file); const json = JSON.stringify(this.configJSON()); fs.writeFileSync(file.fd, json); return file.name; diff --git a/planetwars/client/app/components/info/Info.tsx b/planetwars/client/app/components/info/Info.tsx index a0a30730..66ec9815 100644 --- a/planetwars/client/app/components/info/Info.tsx +++ b/planetwars/client/app/components/info/Info.tsx @@ -27,7 +27,8 @@ export default class Info extends React.Component<{}, { mapToggled: boolean }> { public render() { // ----------TEMP DEBUG TESTING---------- - parseLogFile("", MatchType.hosted); + // console.log(parseLogFile("/home/robbe/log.out", MatchType.hosted)); + console.log(parseLogFile("/home/robbe/log.out", MatchType.joined)); // ----------TEMP DEBUG TESTING---------- diff --git a/planetwars/client/app/lib/match/MatchLog.ts b/planetwars/client/app/lib/match/MatchLog.ts index c47281df..f122efda 100644 --- a/planetwars/client/app/lib/match/MatchLog.ts +++ b/planetwars/client/app/lib/match/MatchLog.ts @@ -1,6 +1,6 @@ import { PlanetList, Expedition, Player, JsonExpedition, JsonPlanet } from './types'; import * as _ from 'lodash'; -import { events } from "mozaic-client"; +import { events, Event, PwTypes } from "mozaic-client"; export abstract class MatchLog { public playerLogs: PlayerMap; @@ -19,8 +19,7 @@ export abstract class MatchLog { return this.gameStates[this.gameStates.length - 1].livingPlayers(); } - // TODO: typing - public abstract addEntry(entry: any /* event */): void; + public abstract addEntry(entry: Event): void; protected getPlayerLog(playerNum: number) { let playerLog = this.playerLogs[playerNum]; @@ -33,35 +32,40 @@ export abstract class MatchLog { } export class HostedMatchLog extends MatchLog { - // TODO: typing - public addEntry(entry: any) { + public addEntry(entry: Event) { switch (entry.eventType) { + case events.PlayerAction: { + const entryPA = entry as events.PlayerAction; + + this.getPlayerLog(entryPA.clientId).addRecord(entry); + + break; + } case events.GameStep: { - const {state} = entry; - this.gameStates.push(state); + const entryGS = entry as events.GameStep; + + Object.keys(this.playerLogs).forEach((clientIdStr) => { + this.playerLogs[parseInt(clientIdStr, 10)].addRecord(entryGS); + }); + + this.gameStates.push(GameState.fromJson(JSON.parse(entryGS.state))); + break; } - case events.PlayerAction: { - this.getPlayerLog(entry.clientId).addRecord(entry.action); + case events.RegisterClient: { + const entryRC = entry as events.RegisterClient; + + this.getPlayerLog(entryRC.clientId); + + break; } } } } export class JoinedMatchLog extends MatchLog { - // TODO: typing - public addEntry(entry: any) { - console.log(entry); - if (entry.eventType === events.PlayerAction) { - // this should always be the case since this is a joined match - const { player, action } = entry; - - this.getPlayerLog(player).addRecord(action); - - if (player === 1 && action.type === 'step') { - this.gameStates.push(GameState.fromJson(action.state)); - } - } + public addEntry(entry: Event) { + // TODO } } @@ -74,8 +78,7 @@ export class GameState { this.expeditions = expeditions; } - // TODO: typing - public static fromJson(json: any) { + public static fromJson(json: PwTypes.GameState) { const planets: PlanetList = {}; json.planets.forEach((p: JsonPlanet) => { planets[p.name] = { @@ -123,21 +126,22 @@ export class PlayerLog { this.turns = []; } - // TODO: typing - public addRecord(record: any) { - switch (record.type) { - case 'step': { - this.turns.push({ state: record.state }); - break; - } - case 'command': { - this.turns[this.turns.length - 1].command = record.content; + public addRecord(record: Event) { + switch (record.eventType) { + case events.GameStep: { + const recordGS = record as events.GameStep; + this.turns.push({ state: JSON.parse(recordGS.state) }); break; } - case 'player_action': { - this.turns[this.turns.length - 1].action = record.action; + case events.PlayerAction: { + const recordPA = record as events.PlayerAction; + this.turns[this.turns.length - 1].command = recordPA.action; break; } + // case 'command': { + // this.turns[this.turns.length - 1].action = record.action; + // break; + // } } } } @@ -145,7 +149,7 @@ export class PlayerLog { export interface PlayerTurn { state: GameState; command?: string; - action?: any /*PlayerAction*/; + action?: PwTypes.PlayerAction; } export interface PlayerMap { diff --git a/planetwars/client/app/lib/match/utils.ts b/planetwars/client/app/lib/match/utils.ts index 4d6b9bc4..c9769622 100644 --- a/planetwars/client/app/lib/match/utils.ts +++ b/planetwars/client/app/lib/match/utils.ts @@ -30,6 +30,10 @@ export function parseLogFile(path: string, type: M.MatchType): MatchLog { log.addEntry(event); }); + replayer.on(events.RegisterClient).subscribe((event) => { + log.addEntry(event); + }); + replayer.replayFile(path); return log; } From ebf10b8e5348046ed54053982061ee6a7a65725e Mon Sep 17 00:00:00 2001 From: Robbe Van Herck Date: Mon, 10 Sep 2018 08:26:58 +0200 Subject: [PATCH 06/10] Somehow, a joined match-replayer does not emit any events... --- client/src/index.ts | 1 + .../client/app/actions/matches/matches.ts | 12 +++------- .../client/app/components/info/Info.tsx | 2 +- .../client/app/components/join/Join.tsx | 2 +- planetwars/client/app/lib/match/MatchLog.ts | 22 ++++++++++++++++++- 5 files changed, 27 insertions(+), 12 deletions(-) diff --git a/client/src/index.ts b/client/src/index.ts index e2ae3984..1e7e4915 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -6,6 +6,7 @@ export { Reactor } from "./reactors/Reactor"; export { ServerRunner, ServerParams } from "./planetwars/ServerRunner"; export { Logger } from "./Logger"; export { Event } from "./reactors/SimpleEventEmitter" +export { PwMatch } from "./planetwars/PwMatch" import * as events from "./eventTypes"; import * as PwTypes from './planetwars/PwTypes'; diff --git a/planetwars/client/app/actions/matches/matches.ts b/planetwars/client/app/actions/matches/matches.ts index 7a4d2089..f89ba3c2 100644 --- a/planetwars/client/app/actions/matches/matches.ts +++ b/planetwars/client/app/actions/matches/matches.ts @@ -60,7 +60,7 @@ export function joinMatch(address: M.Address, bot: M.InternalBotSlot) { const botConfig = { command, args }; const host = address.host; const port = address.port; - const token = new Buffer(bot.token, 'hex'); + const token = Buffer.from(bot.token, 'utf-8'); const clientParams = { token, host, @@ -69,22 +69,16 @@ export function joinMatch(address: M.Address, bot: M.InternalBotSlot) { clientId: bot.clientid, logSink: createWriteStream(match.logPath), }; - const logger = new PwClient.Logger(clientParams.clientId, createWriteStream(match.logPath)); - const clientReactor = new PwClient.Reactor(logger); - - clientReactor.dispatch(PwClient.events.RegisterClient.create({ - clientId: clientParams.clientId, - token: new Buffer(bot.token, 'hex'), - })); try { const pwClient = new PwClient.PwClient(clientParams); - clientReactor.on(PwClient.events.GameFinished).subscribe(() => { + pwClient.on(PwClient.events.GameFinished).subscribe(() => { dispatch(completeMatch(match.uuid)); const title = 'Match ended'; const body = `A remote match has ended`; const link = `/matches/${match.uuid}`; dispatch(Notify.addNotification({ title, body, link, type: 'Finished' })); }); + pwClient.run(); } catch (err) { console.log(err); dispatch(handleMatchError(match.uuid, err)); diff --git a/planetwars/client/app/components/info/Info.tsx b/planetwars/client/app/components/info/Info.tsx index 66ec9815..66cbddd5 100644 --- a/planetwars/client/app/components/info/Info.tsx +++ b/planetwars/client/app/components/info/Info.tsx @@ -28,7 +28,7 @@ export default class Info extends React.Component<{}, { mapToggled: boolean }> { // ----------TEMP DEBUG TESTING---------- // console.log(parseLogFile("/home/robbe/log.out", MatchType.hosted)); - console.log(parseLogFile("/home/robbe/log.out", MatchType.joined)); + console.log(parseLogFile("/home/robbe/joined_1.out", MatchType.joined)); // ----------TEMP DEBUG TESTING---------- diff --git a/planetwars/client/app/components/join/Join.tsx b/planetwars/client/app/components/join/Join.tsx index 5b509a5f..e1c6bd52 100644 --- a/planetwars/client/app/components/join/Join.tsx +++ b/planetwars/client/app/components/join/Join.tsx @@ -111,7 +111,7 @@ export class Join extends React.Component { if (this.state.lastClipboard !== clipBoardtext) { try { const {host, port, name, token, clientId } = JSON.parse(clipBoardtext); - if (host && port && name && token) { + if (host && port && name && token && clientId) { this.setState({ import: { host, port, name, token, clientId } }); } else { this.setState({ import: undefined }); diff --git a/planetwars/client/app/lib/match/MatchLog.ts b/planetwars/client/app/lib/match/MatchLog.ts index f122efda..652a4b7d 100644 --- a/planetwars/client/app/lib/match/MatchLog.ts +++ b/planetwars/client/app/lib/match/MatchLog.ts @@ -65,7 +65,27 @@ export class HostedMatchLog extends MatchLog { export class JoinedMatchLog extends MatchLog { public addEntry(entry: Event) { - // TODO + console.log(entry) + switch (entry.eventType) { + case events.PlayerAction: { + const entryPA = entry as events.PlayerAction; + + this.getPlayerLog(entryPA.clientId).addRecord(entry); + + break; + } + case events.GameStep: { + const entryGS = entry as events.GameStep; + + Object.keys(this.playerLogs).forEach((clientIdStr) => { + this.playerLogs[parseInt(clientIdStr, 10)].addRecord(entryGS); + }); + + this.gameStates.push(GameState.fromJson(JSON.parse(entryGS.state))); + + break; + } + } } } From c2ec466322a2f0f983f049986858c6ebb4b8ea9d Mon Sep 17 00:00:00 2001 From: Robbe Van Herck Date: Mon, 17 Sep 2018 16:15:55 +0200 Subject: [PATCH 07/10] It's alive :D --- client/src/index.ts | 2 +- client/src/replay.ts | 15 ++++++------ .../client/app/components/info/Info.tsx | 2 +- planetwars/client/app/lib/match/MatchLog.ts | 7 ++++-- planetwars/client/app/lib/match/utils.ts | 23 +++++++++++++------ 5 files changed, 31 insertions(+), 18 deletions(-) diff --git a/client/src/index.ts b/client/src/index.ts index 1e7e4915..830348ae 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -5,7 +5,7 @@ export { Replayer } from "./replay"; export { Reactor } from "./reactors/Reactor"; export { ServerRunner, ServerParams } from "./planetwars/ServerRunner"; export { Logger } from "./Logger"; -export { Event } from "./reactors/SimpleEventEmitter" +export { Event, SimpleEventEmitter } from "./reactors/SimpleEventEmitter" export { PwMatch } from "./planetwars/PwMatch" import * as events from "./eventTypes"; diff --git a/client/src/replay.ts b/client/src/replay.ts index f514f260..bdff52e3 100644 --- a/client/src/replay.ts +++ b/client/src/replay.ts @@ -2,6 +2,7 @@ import { createReadStream, ReadStream } from "fs"; import { ProtobufReader } from "./networking/ProtobufStream"; import * as protocol_root from './proto'; import { SimpleEventEmitter, EventType } from "./reactors/SimpleEventEmitter"; +import { SimpleEventDispatcher } from 'ste-simple-events'; import LogEvent = protocol_root.mozaic.log.LogEvent; import * as events from './eventTypes'; import { ISimpleEvent } from "ste-simple-events"; @@ -12,6 +13,7 @@ import { ISimpleEvent } from "ste-simple-events"; export class Replayer { emitters: {[clientId: number]: SimpleEventEmitter}; + public clientSpottedDispatcher: SimpleEventDispatcher = new SimpleEventDispatcher(); constructor() { this.emitters = {}; @@ -22,6 +24,7 @@ export class Replayer { if (!emitter) { emitter = new SimpleEventEmitter(); this.emitters[clientId] = emitter; + this.clientSpottedDispatcher.dispatch(clientId); } return emitter; } @@ -31,13 +34,11 @@ export class Replayer { } private emit(logEvent: LogEvent) { - const emitter = this.emitters[logEvent.clientId]; - if (emitter) { - emitter.handleWireEvent({ - typeId: logEvent.eventType, - data: logEvent.data, - }); - } + const emitter = this.clientStream(logEvent.clientId); + emitter.handleWireEvent({ + typeId: logEvent.eventType, + data: logEvent.data, + }); } public replayFile(path: string) { diff --git a/planetwars/client/app/components/info/Info.tsx b/planetwars/client/app/components/info/Info.tsx index 66cbddd5..c276ac4b 100644 --- a/planetwars/client/app/components/info/Info.tsx +++ b/planetwars/client/app/components/info/Info.tsx @@ -27,7 +27,7 @@ export default class Info extends React.Component<{}, { mapToggled: boolean }> { public render() { // ----------TEMP DEBUG TESTING---------- - // console.log(parseLogFile("/home/robbe/log.out", MatchType.hosted)); + console.log(parseLogFile("/home/robbe/log.out", MatchType.hosted)); console.log(parseLogFile("/home/robbe/joined_1.out", MatchType.joined)); // ----------TEMP DEBUG TESTING---------- diff --git a/planetwars/client/app/lib/match/MatchLog.ts b/planetwars/client/app/lib/match/MatchLog.ts index 652a4b7d..6304cd90 100644 --- a/planetwars/client/app/lib/match/MatchLog.ts +++ b/planetwars/client/app/lib/match/MatchLog.ts @@ -1,5 +1,4 @@ import { PlanetList, Expedition, Player, JsonExpedition, JsonPlanet } from './types'; -import * as _ from 'lodash'; import { events, Event, PwTypes } from "mozaic-client"; export abstract class MatchLog { @@ -19,6 +18,11 @@ export abstract class MatchLog { return this.gameStates[this.gameStates.length - 1].livingPlayers(); } + // This may be a hack... + public addPlayer(clientId: number) { + this.getPlayerLog(clientId); + } + public abstract addEntry(entry: Event): void; protected getPlayerLog(playerNum: number) { @@ -65,7 +69,6 @@ export class HostedMatchLog extends MatchLog { export class JoinedMatchLog extends MatchLog { public addEntry(entry: Event) { - console.log(entry) switch (entry.eventType) { case events.PlayerAction: { const entryPA = entry as events.PlayerAction; diff --git a/planetwars/client/app/lib/match/utils.ts b/planetwars/client/app/lib/match/utils.ts index c9769622..c0e3a6b5 100644 --- a/planetwars/client/app/lib/match/utils.ts +++ b/planetwars/client/app/lib/match/utils.ts @@ -1,7 +1,7 @@ import * as M from '../../database/models'; import * as fs from 'fs'; import { MatchLog, HostedMatchLog, JoinedMatchLog } from './MatchLog'; -import { Replayer, events } from "mozaic-client"; +import { Replayer, SimpleEventEmitter, events } from "mozaic-client"; export function emptyLog(type: M.MatchType): MatchLog { switch (type) { @@ -22,20 +22,29 @@ export function parseLogFile(path: string, type: M.MatchType): MatchLog { const log = emptyLog(type); const replayer = new Replayer(); - replayer.on(events.GameStep).subscribe((event) => { - log.addEntry(event); + registerStreamToLog(log, replayer); + + replayer.clientSpottedDispatcher.subscribe((clientId) => { + log.addPlayer(clientId); + registerStreamToLog(log, replayer.clientStream(clientId)); }); - replayer.on(events.PlayerAction).subscribe((event) => { + replayer.replayFile(path); + return log; +} + +function registerStreamToLog(log: MatchLog, stream: Replayer | SimpleEventEmitter) { + stream.on(events.GameStep).subscribe((event) => { log.addEntry(event); }); - replayer.on(events.RegisterClient).subscribe((event) => { + stream.on(events.PlayerAction).subscribe((event) => { log.addEntry(event); }); - replayer.replayFile(path); - return log; + stream.on(events.RegisterClient).subscribe((event) => { + log.addEntry(event); + }); } export function calcStats(log: MatchLog): M.MatchStats { From 58f81e076b68c9fd125a488ce83b8e582be4c857 Mon Sep 17 00:00:00 2001 From: Robbe Van Herck Date: Mon, 17 Sep 2018 16:19:55 +0200 Subject: [PATCH 08/10] Removed temp debug code --- planetwars/client/app/components/info/Info.tsx | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/planetwars/client/app/components/info/Info.tsx b/planetwars/client/app/components/info/Info.tsx index c276ac4b..55663e7d 100644 --- a/planetwars/client/app/components/info/Info.tsx +++ b/planetwars/client/app/components/info/Info.tsx @@ -1,10 +1,3 @@ -// ----------TEMP DEBUG TESTING---------- - -import {parseLogFile} from "../../lib/match/index"; -import { MatchType } from "../../database/models"; - -// ----------TEMP DEBUG TESTING---------- - import * as React from 'react'; import { shell } from 'electron'; @@ -25,13 +18,6 @@ export default class Info extends React.Component<{}, { mapToggled: boolean }> { } public render() { - // ----------TEMP DEBUG TESTING---------- - - console.log(parseLogFile("/home/robbe/log.out", MatchType.hosted)); - console.log(parseLogFile("/home/robbe/joined_1.out", MatchType.joined)); - - // ----------TEMP DEBUG TESTING---------- - const Readme = () => ( README From a7398477e1b2be4068ff69c53433bb23615f26ef Mon Sep 17 00:00:00 2001 From: Robbe Van Herck Date: Mon, 17 Sep 2018 17:34:58 +0200 Subject: [PATCH 09/10] Added decent createClientId --- .../client/app/components/play/lobby/SlotManager.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/planetwars/client/app/components/play/lobby/SlotManager.ts b/planetwars/client/app/components/play/lobby/SlotManager.ts index 79ee0685..3974f714 100644 --- a/planetwars/client/app/components/play/lobby/SlotManager.ts +++ b/planetwars/client/app/components/play/lobby/SlotManager.ts @@ -22,6 +22,7 @@ export class SlotManager { public slots: Slots; public slotList: string[]; public clients: Clients; + private lastClientId: number = 0; private onSlotChange: (self: SlotManager) => void; @@ -35,7 +36,6 @@ export class SlotManager { public update(map: M.MapMeta) { while (this.slotList.length < map.slots) { const slot = this.createSlot(); - slot.clientId = this.slotList.length + 1; this.slotList.push(slot.token); } @@ -143,9 +143,15 @@ export class SlotManager { name: new Chance().name({ prefix: true, nationality: 'it' }), token: generateToken(), connected: false, + clientId: this.createClientId(), }; this.slots[slot.token] = slot; this.registerSlot(slot); return slot; } + + private createClientId() { + this.lastClientId += 1; + return this.lastClientId; + } } From 48ad680dc77fe126f62643b2ffc4d6710bbdd162 Mon Sep 17 00:00:00 2001 From: Robbe Van Herck Date: Wed, 19 Sep 2018 15:31:26 +0200 Subject: [PATCH 10/10] I'm Stuck :( --- client/src/index.ts | 1 + .../client/app/actions/matches/matches.ts | 2 +- .../app/components/play/lobby/Lobby.tsx | 140 ++++++++++-------- .../app/components/play/lobby/SlotList.tsx | 2 - .../app/components/play/lobby/SlotManager.ts | 29 ++-- 5 files changed, 100 insertions(+), 74 deletions(-) diff --git a/client/src/index.ts b/client/src/index.ts index 830348ae..0ad580d4 100644 --- a/client/src/index.ts +++ b/client/src/index.ts @@ -7,6 +7,7 @@ export { ServerRunner, ServerParams } from "./planetwars/ServerRunner"; export { Logger } from "./Logger"; export { Event, SimpleEventEmitter } from "./reactors/SimpleEventEmitter" export { PwMatch } from "./planetwars/PwMatch" +export { Client } from "./networking/Client" import * as events from "./eventTypes"; import * as PwTypes from './planetwars/PwTypes'; diff --git a/planetwars/client/app/actions/matches/matches.ts b/planetwars/client/app/actions/matches/matches.ts index f89ba3c2..de0561f2 100644 --- a/planetwars/client/app/actions/matches/matches.ts +++ b/planetwars/client/app/actions/matches/matches.ts @@ -60,7 +60,7 @@ export function joinMatch(address: M.Address, bot: M.InternalBotSlot) { const botConfig = { command, args }; const host = address.host; const port = address.port; - const token = Buffer.from(bot.token, 'utf-8'); + const token = Buffer.from(bot.token, 'hex'); const clientParams = { token, host, diff --git a/planetwars/client/app/components/play/lobby/Lobby.tsx b/planetwars/client/app/components/play/lobby/Lobby.tsx index a3935ca2..6756ead6 100644 --- a/planetwars/client/app/components/play/lobby/Lobby.tsx +++ b/planetwars/client/app/components/play/lobby/Lobby.tsx @@ -6,6 +6,7 @@ import * as PwClient from 'mozaic-client'; import { Config } from '../../../utils/Config'; import { generateToken } from '../../../utils/GameRunner'; import * as M from '../../../database/models'; +import * as crypto from 'crypto'; import * as Lib from '../types'; import Section from '../Section'; @@ -50,7 +51,7 @@ export interface RunningState { export class Lobby extends React.Component { private slotManager: SlotManager; private server?: PwClient.ServerRunner; - private matchReactor?: PwClient.Reactor; + private match: PwClient.PwMatch; constructor(props: LobbyProps) { super(props); @@ -126,9 +127,10 @@ export class Lobby extends React.Component { } private connectLocalBot = (slot: Slot, playerNum: number) => { - if (!this.validifyRunning(this.state)) { return; } - if (!this.server) { return; } - if (!slot.bot || !slot.clientId) { return; } + if (!this.validifyRunning(this.state)) { console.log("invalid state"); return; } + if (!this.server) { console.log("server isn't running"); return; } + if (!slot.bot || !slot.clientId) { console.log("invalid slot"); return; } + console.log("connecting..."); // callbacks should be set on the current slotmanager, // not the one belonging to 'this'. (It changes when a match is launched). @@ -151,7 +153,7 @@ export class Lobby extends React.Component { }, logSink: createWriteStream(this.state.logFile), clientId, - }) + }); client.run(); console.log('connected local bot'); } @@ -160,8 +162,8 @@ export class Lobby extends React.Component { private removeExternalBot = (token: M.Token, playerNum: number, clientId: number) => { if (!this.validifyRunning(this.state)) { return; } - if (this.server && this.matchReactor) { - this.matchReactor.dispatch(PwClient.events.RemoveClient.create({clientId})); + if (this.server && this.match) { + this.match.send(PwClient.events.RemoveClient.create({clientId})); this.slotManager.disconnectClient(clientId); this.slotManager.removeBot(playerNum); } @@ -199,63 +201,85 @@ export class Lobby extends React.Component { // TODO this is dirty, cause we have to create a matchId already const matchId = Config.generateMatchId(); const ctrlToken = generateToken(); + const serverToken = crypto.randomBytes(16).toString("hex"); const logFile = Config.matchLogPath(matchId); - const params = { ctrl_token: ctrlToken, address: config.address, logFile }; - console.log('launching server with', params); + const serverParams: PwClient.ServerParams = { ctrl_token: serverToken, address: config.address, logFile }; + console.log('launching server with', serverParams); // callbacks should be set on the current slotmanager, // not the one belonging to 'this'. (It changes when a match is launched). const slotManager = this.slotManager; + const slots = this.state.slots; - this.server = new PwClient.ServerRunner(Config.matchRunner, params); + // Start the server + this.server = new PwClient.ServerRunner(Config.matchRunner, serverParams); this.server.runServer(); - const slots = this.state.slots; + const newState: RunningState = { + type: 'running', + config, + slots, + matchId, + logFile, + }; + this.setState(newState); const clientParams = { host: config.address.host, port: config.address.port, - token: Buffer.from(params.ctrl_token, 'hex'), - } + token: Buffer.from(ctrlToken, 'hex'), + }; + + // Create the control client + const emitter = new PwClient.SimpleEventEmitter(); + const controlClient = new PwClient.Client({ + token: serverToken, + ...clientParams, + }, emitter); + + emitter.on(PwClient.events.Connected).subscribe((_) => { + console.log("Creating match"); + controlClient.send(PwClient.events.CreateMatch.create({ + matchUuid: Buffer.from(matchId, "hex"), + controlToken: Buffer.from(ctrlToken, "hex"), + })); + }); - try { - this.matchReactor = new PwClient.Reactor(new PwClient.Logger(0, createWriteStream(logFile))); - this.slotManager.setMatchRunner(this.matchReactor); - - this.matchReactor.on(PwClient.events.ClientConnected).subscribe((event) => { - slotManager.connectClient(event.clientId); - }); - - this.matchReactor.on(PwClient.events.ClientDisconnected).subscribe((event) => { - slotManager.disconnectClient(event.clientId); - }); - - this.matchReactor.on(PwClient.events.GameFinished).subscribe(() => { - this.props.sendNotification( - "Match ended", - `A match on map '${ - this.state.type === "configuring" ? - "unknown" : - this.props.maps[this.state.config.mapId] - }' has ended`, - "Finished", - ); - }); - // TODO: on error - - const newState: RunningState = { - type: 'running', - config, - slots, - matchId, - logFile, - }; - this.setState(newState); - } catch (err) { - this.stopServer(); - alert(`Could not start game server: \n ${err}`); - console.log('Failed to start server.', err); - } + emitter.on(PwClient.events.MatchCreated).subscribe((e) => { + console.log("Created Match", e); + if (e.matchUuid.toString() === matchId) { + const logStream = createWriteStream(logFile); + + try { + this.match = new PwClient.PwMatch(clientParams, new PwClient.Logger(0, logStream)); + + this.match.on(PwClient.events.GameFinished).subscribe(() => { + this.props.sendNotification( + "Match ended", + `A match on map '${ + this.state.type === "configuring" ? + "unknown" : + this.props.maps[this.state.config.mapId] + }' has ended`, + "Finished", + ); + }); + + this.match.on(PwClient.events.Connected).subscribe(() => { + console.log("Match connected") + this.slotManager.setMatch(this.match); + }); + + this.match.connect(); + } catch (err) { + this.stopServer(); + alert(`Could not start game server: \n ${err}`); + console.error('Failed to start server.', err); + } + } + controlClient.exit(); + }); + controlClient.connect(); } private stopServer = () => { @@ -267,7 +291,7 @@ export class Lobby extends React.Component { } private launchGame = () => { - if (!this.matchReactor || !this.server || !this.validifyRunning(this.state)) { + if (!this.match || !this.server || !this.validifyRunning(this.state)) { alert('Something went wrong'); return; } @@ -276,21 +300,21 @@ export class Lobby extends React.Component { const gameConf = Lib.exportConfig(this.state.config, this.props.maps); // Clear old listeners from the lobby - this.matchReactor.on(PwClient.events.ClientConnected).clear(); - this.matchReactor.on(PwClient.events.ClientDisconnected).clear(); + this.match.on(PwClient.events.ClientConnected).clear(); + this.match.on(PwClient.events.ClientDisconnected).clear(); // Bind completion listeners this.server.onExit.subscribe(() => { this.props.onMatchComplete(matchId); }); this.server.onError.subscribe((err) => { - this.props.onMatchErrored(matchId, err) + this.props.onMatchErrored(matchId, err); }); // Bind connection listeners - this.matchReactor.on(PwClient.events.ClientDisconnected).subscribe( + this.match.on(PwClient.events.ClientDisconnected).subscribe( (event) => this.props.onPlayerDisconnectDuringMatch(event.clientId)); - this.matchReactor.on(PwClient.events.ClientConnected).subscribe( + this.match.on(PwClient.events.ClientConnected).subscribe( (event) => this.props.onPlayerReconnectedDuringMatch(event.clientId)); // Start game @@ -298,7 +322,7 @@ export class Lobby extends React.Component { mapPath: gameConf.map_file, maxTurns: gameConf.max_turns, } - this.matchReactor.dispatch(PwClient.events.StartGame.create(matchConfig)); + this.match.send(PwClient.events.StartGame.create(matchConfig)); try { const { host, port, maxTurns, mapId } = this.props.config!; if (!this.validifyRunning(this.state)) { return; } diff --git a/planetwars/client/app/components/play/lobby/SlotList.tsx b/planetwars/client/app/components/play/lobby/SlotList.tsx index 2fa12dcc..419ccc37 100644 --- a/planetwars/client/app/components/play/lobby/SlotList.tsx +++ b/planetwars/client/app/components/play/lobby/SlotList.tsx @@ -54,8 +54,6 @@ export class SlotElement extends React.Component { const { slot, index } = this.props; const { token, name, clientId } = slot; - console.log(slot); - const kicked = (this.props.willBeKicked) ? (styles.kicked) : ''; return (
    diff --git a/planetwars/client/app/components/play/lobby/SlotManager.ts b/planetwars/client/app/components/play/lobby/SlotManager.ts index 3974f714..7761cc59 100644 --- a/planetwars/client/app/components/play/lobby/SlotManager.ts +++ b/planetwars/client/app/components/play/lobby/SlotManager.ts @@ -3,7 +3,7 @@ import { Chance } from 'chance'; import * as M from '../../../database/models'; import { generateToken } from '../../../utils/GameRunner'; import { WeakConfig, StrongConfig } from '../types'; -import { Reactor, events, PwClient } from 'mozaic-client'; +import { PwMatch, events, PwClient } from 'mozaic-client'; export interface Slot { name: string; @@ -17,7 +17,7 @@ export type Slots = { [token: string]: Slot }; export type Clients = { [clientId: number]: Slot}; export class SlotManager { - public matchReactor?: Reactor; + public match?: PwMatch; public connectedClients: Set = new Set(); public slots: Slots; public slotList: string[]; @@ -85,19 +85,22 @@ export class SlotManager { this.notifyListeners(); } - public setMatchRunner(matchReactor: Reactor) { - this.matchReactor = matchReactor; + public setMatch(match: PwMatch) { + this.match = match; - // TODO: typing - matchReactor.on(events.ClientConnected).subscribe((event: any) => { + match.on(events.ClientConnected).subscribe((event: events.ClientConnected) => { + console.log("Got ClientConnected for " + event.clientId); this.connectClient(event.clientId); }); - // TODO: typing - matchReactor.on(events.ClientDisconnected).subscribe((event: any) => { + match.on(events.ClientDisconnected).subscribe((event: events.ClientDisconnected) => { this.disconnectClient(event.clientId); }); + match.on(events.RegisterClient).subscribe((evt: events.RegisterClient) => { + console.log("Got RegisterClient for " + evt.clientId); + }); + this.slotList.forEach((token) => { const slot = this.slots[token]; this.registerSlot(slot); @@ -113,11 +116,11 @@ export class SlotManager { } private registerSlot(slot: Slot) { - if (this.matchReactor) { + if (this.match) { const token = Buffer.from(slot.token, 'hex'); - this.matchReactor.dispatch(events.RegisterClient.create({ + this.match.send(events.RegisterClient.create({ clientId: slot.clientId, - token: Buffer.from(slot.token, 'utf-8'), + token, })); if (slot.clientId) { this.clients[slot.clientId] = slot; @@ -127,9 +130,9 @@ export class SlotManager { } private unregisterSlot(slot: Slot) { - if (this.matchReactor && slot.clientId) { + if (this.match && slot.clientId) { const clientId = slot.clientId; - this.matchReactor.dispatch(events.RemoveClient.create({ + this.match.send(events.RemoveClient.create({ clientId: slot.clientId, })); delete this.clients[clientId];