Skip to content

Commit

Permalink
move log out of game state
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolodavis committed Mar 18, 2020
1 parent 776a836 commit d4de9e2
Show file tree
Hide file tree
Showing 11 changed files with 294 additions and 238 deletions.
10 changes: 0 additions & 10 deletions src/core/initialize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,20 +57,10 @@ export function InitializeGame({
// state updates are only allowed from clients that
// are at the same version that the server.
_stateID: 0,
// A copy of the initial state so that
// the log can replay actions on top of it.
// TODO: This should really be stored in a different
// part of the DB and not inside the state object.
_initial: {},
};

initial = game.flow.init(initial);
initial = plugins.Flush(initial, { game });

function deepCopy<T>(obj: T): T {
return parse(stringify(obj));
}
initial._initial = deepCopy(initial);

return initial;
}
21 changes: 5 additions & 16 deletions src/master/master.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,22 +125,6 @@ describe('update', () => {
expect(value.args[1]).toMatchObject({
G: {},
deltalog: undefined,
log: undefined,
_initial: {
G: {},
_initial: {},
_redo: [],
_stateID: 0,
_undo: [],
ctx: {
currentPlayer: '0',
numPlayers: 2,
phase: null,
playOrder: ['0', '1'],
playOrderPos: 0,
turn: 1,
},
},
_redo: [],
_stateID: 1,
_undo: [],
Expand Down Expand Up @@ -400,6 +384,11 @@ describe('authentication', () => {
});

describe('redactLog', () => {
test('no-op with undefined log', () => {
const result = redactLog(undefined, '0');
expect(result).toBeUndefined();
});

test('no redactedMoves', () => {
const logEvents = [
{
Expand Down
72 changes: 33 additions & 39 deletions src/master/master.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,17 @@ export class Master {
? action.payload.credentials
: undefined;
if (IsSynchronous(this.storageAPI)) {
const gameMetadata = this.storageAPI.getMetadata(gameID);
const playerMetadata = getPlayerMetadata(gameMetadata, playerID);
isActionAuthentic = this.shouldAuth(gameMetadata)
const { metadata } = this.storageAPI.fetch(gameID, { metadata: true });
const playerMetadata = getPlayerMetadata(metadata, playerID);
isActionAuthentic = this.shouldAuth(metadata)
? this.auth(credentials, playerMetadata)
: true;
} else {
const gameMetadata = await this.storageAPI.getMetadata(gameID);
const playerMetadata = getPlayerMetadata(gameMetadata, playerID);
isActionAuthentic = this.shouldAuth(gameMetadata)
const { metadata } = await this.storageAPI.fetch(gameID, {
metadata: true,
});
const playerMetadata = getPlayerMetadata(metadata, playerID);
isActionAuthentic = this.shouldAuth(metadata)
? await this.auth(credentials, playerMetadata)
: true;
}
Expand All @@ -205,11 +207,13 @@ export class Master {
const key = gameID;

let state: State;
let result: StorageAPI.FetchResult;
if (IsSynchronous(this.storageAPI)) {
state = this.storageAPI.getState(key);
result = this.storageAPI.fetch(key, { state: true });
} else {
state = await this.storageAPI.getState(key);
result = await this.storageAPI.fetch(key, { state: true });
}
state = result.state;

if (state === undefined) {
logging.error(`game not found, gameID=[${key}]`);
Expand Down Expand Up @@ -263,8 +267,6 @@ export class Master {
return;
}

let log = store.getState().log || [];

// Update server's version of the store.
store.dispatch(action);
state = store.getState();
Expand All @@ -279,16 +281,9 @@ export class Master {
const filteredState = {
...state,
G: this.game.playerView(state.G, state.ctx, playerID),
ctx: { ...state.ctx, _random: undefined },
log: undefined,
deltalog: undefined,
_undo: [],
_redo: [],
_initial: {
...state._initial,
_undo: [],
_redo: [],
},
};

const log = redactLog(state.deltalog, playerID);
Expand All @@ -299,16 +294,10 @@ export class Master {
};
});

// TODO: We currently attach the log back into the state
// object before storing it, but this should probably
// sit in a different part of the database eventually.
log = [...log, ...state.deltalog];
const stateWithLog = { ...state, log };

if (IsSynchronous(this.storageAPI)) {
this.storageAPI.setState(key, stateWithLog);
this.storageAPI.setState(key, state);
} else {
await this.storageAPI.setState(key, stateWithLog);
await this.storageAPI.setState(key, state);
}
}

Expand All @@ -320,22 +309,36 @@ export class Master {
const key = gameID;

let state: State;
let log: LogEntry[];
let gameMetadata: Server.GameMetadata;
let filteredGameMetadata: { id: number; name?: string }[];
let result: StorageAPI.FetchResult;

if (IsSynchronous(this.storageAPI)) {
const api = this.storageAPI as StorageAPI.Sync;
state = api.getState(key);
gameMetadata = api.getMetadata(gameID);
result = api.fetch(key, {
state: true,
metadata: true,
log: true,
});
} else {
state = await this.storageAPI.getState(key);
gameMetadata = await this.storageAPI.getMetadata(gameID);
result = await this.storageAPI.fetch(key, {
state: true,
metadata: true,
log: true,
});
}

state = result.state;
log = result.log;
gameMetadata = result.metadata;

if (gameMetadata) {
filteredGameMetadata = Object.values(gameMetadata.players).map(player => {
return { id: player.id, name: player.name };
});
}

// If the game doesn't exist, then create one on demand.
// TODO: Move this out of the sync call.
if (state === undefined) {
Expand All @@ -349,29 +352,20 @@ export class Master {
if (IsSynchronous(this.storageAPI)) {
const api = this.storageAPI as StorageAPI.Sync;
api.setState(key, state);
state = api.getState(key);
} else {
await this.storageAPI.setState(key, state);
state = await this.storageAPI.getState(key);
}
}

const filteredState = {
...state,
G: this.game.playerView(state.G, state.ctx, playerID),
ctx: { ...state.ctx, _random: undefined },
log: undefined,
deltalog: undefined,
_undo: [],
_redo: [],
_initial: {
...state._initial,
_undo: [],
_redo: [],
},
};

const log = redactLog(state.log, playerID);
log = redactLog(log, playerID);

this.transportAPI.send({
playerID,
Expand Down
Loading

0 comments on commit d4de9e2

Please sign in to comment.