diff --git a/src/client/transport/local.ts b/src/client/transport/local.ts index 9a64de74f..a82b0bcb5 100644 --- a/src/client/transport/local.ts +++ b/src/client/transport/local.ts @@ -20,6 +20,8 @@ import type { State, } from '../../types'; import { getFilterPlayerView } from '../../master/filter-player-view'; +import { createMatch } from '../../server/util'; +import * as StorageAPI from '../../server/db/base'; /** * Returns null if it is not a bot's turn. @@ -63,6 +65,40 @@ export class LocalMaster extends Master { callback: (data: TransportData) => void ) => void; + async onSync( + matchID: string, + playerID: string | null | undefined, + credentials?: string, + numPlayers = 2 + ): Promise { + // If the game doesn't exist, then create one on demand. + // TODO: Move this out of the sync call. + const match = createMatch({ + game: this.game, + unlisted: true, + numPlayers: numPlayers, + setupData: undefined, + }); + + if ('setupDataError' in match) { + return { error: 'game requires setupData' }; + } + + const state = match.initialState; + const initialState = state; + const metadata = match.metadata; + + this.subscribeCallback({ state, matchID }); + + if (StorageAPI.isSynchronous(this.storageAPI)) { + this.storageAPI.createMatch(matchID, { initialState, metadata }); + } else { + await this.storageAPI.createMatch(matchID, { initialState, metadata }); + } + + super.onSync(matchID, playerID, credentials, numPlayers); + } + constructor({ game, bots, storageKey, persist }: LocalMasterOpts) { const clientCallbacks: Record void> = {}; const initializedBots = {}; diff --git a/src/master/master.ts b/src/master/master.ts index c17e003d9..76a97f6c4 100644 --- a/src/master/master.ts +++ b/src/master/master.ts @@ -26,7 +26,6 @@ import type { PlayerID, ChatMessage, } from '../types'; -import { createMatch } from '../server/util'; import type { Auth } from '../server/auth'; import * as StorageAPI from '../server/db/base'; import type { Operation } from 'rfc6902'; @@ -336,7 +335,7 @@ export class Master { ? this.storageAPI.fetch(key, fetchOpts) : await this.storageAPI.fetch(key, fetchOpts); - let { state, initialState, log, metadata } = fetchResult; + const { state, initialState, log, metadata } = fetchResult; if (this.auth && playerID !== undefined && playerID !== null) { const isAuthentic = await this.auth.authenticateCredentials({ @@ -349,32 +348,6 @@ export class Master { } } - // If the game doesn't exist, then create one on demand. - // TODO: Move this out of the sync call. - if (state === undefined) { - const match = createMatch({ - game: this.game, - unlisted: true, - numPlayers, - setupData: undefined, - }); - - if ('setupDataError' in match) { - return { error: 'game requires setupData' }; - } - - initialState = state = match.initialState; - metadata = match.metadata; - - this.subscribeCallback({ state, matchID }); - - if (StorageAPI.isSynchronous(this.storageAPI)) { - this.storageAPI.createMatch(key, { initialState, metadata }); - } else { - await this.storageAPI.createMatch(key, { initialState, metadata }); - } - } - const filteredMetadata = metadata ? filterMatchData(metadata) : undefined; const syncInfo: SyncInfo = {