-
Notifications
You must be signed in to change notification settings - Fork 0
/
manager.js
56 lines (50 loc) · 1.87 KB
/
manager.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
const uuid = require('uuid');
const path = require('path');
const Keyv = require('keyv');
const { KeyvFile } = require('keyv-file');
// Manager holds the current state of all games.
// Games are persisted to file using keyv with a TTL of 8 days. Modifying a game resets its TTL.
class Manager {
constructor() {
this.store = new Keyv({
namespace: 'games',
store: new KeyvFile({
filename: path.join(process.env.HOME, 'initiative.kv')
}),
ttl: 8 * 24 * 3600 * 1000 // 8 days
})
this.store.on('error', (err) => console.log('Connection Error', err));
}
async NewGame(characters) {
const newGame = {
id: uuid.v4(),
created: Date.now(),
characters: characters.map((c) => ({ name: c.name, initiative: parseInt(c.initiative) })),
currentRound: 1,
currentCharIndex: 0
}
if (newGame.characters.some((c) => isNaN(c.initiative))) {
throw 'Invalid initiative value';
}
// TODO: Check return of store.set().
await this.store.set(newGame.id, newGame);
return newGame.id;
}
// Returns the game with the given ID, or undefined if no such game exists.
async Get(gameID) { return await this.store.get(gameID); }
async Update(gameID, game) {
const existingGame = await this.Get(gameID);
if (!existingGame) {
// TODO: throw an error?
return;
}
// Only copy certain fields over the existing object.
Object.assign(existingGame, {
characters: game.characters.map((c) => ({ name: c.name, initiative: c.initiative })),
currentRound: game.currentRound,
currentCharIndex: game.currentCharIndex
})
await this.store.set(gameID, existingGame);
}
}
exports.Manager = Manager;