@mnbroatch/boardgame.io 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +102 -0
- package/ai/package.json +7 -0
- package/client/package.json +7 -0
- package/core/package.json +7 -0
- package/debug/package.json +7 -0
- package/dist/boardgameio.es.js +14238 -0
- package/dist/boardgameio.js +14277 -0
- package/dist/boardgameio.min.js +16 -0
- package/dist/cjs/Debug-9d141c06.js +9586 -0
- package/dist/cjs/ai-e0e8a768.js +377 -0
- package/dist/cjs/ai.js +20 -0
- package/dist/cjs/client-76dec77b.js +258 -0
- package/dist/cjs/client-a22d7500.js +524 -0
- package/dist/cjs/client.js +26 -0
- package/dist/cjs/core.js +52 -0
- package/dist/cjs/debug.js +18 -0
- package/dist/cjs/filter-player-view-bb02e2f6.js +89 -0
- package/dist/cjs/initialize-267fcd69.js +61 -0
- package/dist/cjs/internal.js +25 -0
- package/dist/cjs/master-2904879d.js +320 -0
- package/dist/cjs/master.js +18 -0
- package/dist/cjs/multiplayer.js +23 -0
- package/dist/cjs/plugin-random-7425844d.js +229 -0
- package/dist/cjs/plugins.js +59 -0
- package/dist/cjs/react-native.js +182 -0
- package/dist/cjs/react.js +727 -0
- package/dist/cjs/reducer-16eec232.js +1203 -0
- package/dist/cjs/server.js +4087 -0
- package/dist/cjs/socketio-7a0837eb.js +478 -0
- package/dist/cjs/testing.js +30 -0
- package/dist/cjs/transport-b1874dfa.js +37 -0
- package/dist/cjs/turn-order-b2ff8740.js +1136 -0
- package/dist/cjs/util-fcfd8fb8.js +140 -0
- package/dist/esm/Debug-0141fe2d.js +9577 -0
- package/dist/esm/ai-5c06e761.js +371 -0
- package/dist/esm/ai.js +8 -0
- package/dist/esm/client-2e653027.js +522 -0
- package/dist/esm/client-5f57c3f2.js +255 -0
- package/dist/esm/client.js +16 -0
- package/dist/esm/core.js +40 -0
- package/dist/esm/debug.js +10 -0
- package/dist/esm/filter-player-view-2c6cc96f.js +87 -0
- package/dist/esm/initialize-11d626ca.js +59 -0
- package/dist/esm/internal.js +10 -0
- package/dist/esm/master-fa8f2e43.js +318 -0
- package/dist/esm/master.js +10 -0
- package/dist/esm/multiplayer.js +14 -0
- package/dist/esm/plugin-random-087f861e.js +226 -0
- package/dist/esm/plugins.js +55 -0
- package/dist/esm/react-native.js +173 -0
- package/dist/esm/react.js +716 -0
- package/dist/esm/reducer-c46da7e5.js +1198 -0
- package/dist/esm/socketio-c22ffa65.js +455 -0
- package/dist/esm/testing.js +26 -0
- package/dist/esm/transport-ce07b771.js +35 -0
- package/dist/esm/turn-order-376d315e.js +1091 -0
- package/dist/esm/util-b6147cef.js +135 -0
- package/dist/types/packages/ai.d.ts +5 -0
- package/dist/types/packages/client.d.ts +3 -0
- package/dist/types/packages/core.d.ts +5 -0
- package/dist/types/packages/debug.d.ts +2 -0
- package/dist/types/packages/internal.d.ts +8 -0
- package/dist/types/packages/master.d.ts +2 -0
- package/dist/types/packages/multiplayer.d.ts +3 -0
- package/dist/types/packages/plugins.d.ts +3 -0
- package/dist/types/packages/react-native.d.ts +2 -0
- package/dist/types/packages/react.d.ts +3 -0
- package/dist/types/packages/server.d.ts +6 -0
- package/dist/types/packages/testing.d.ts +1 -0
- package/dist/types/src/ai/ai.d.ts +53 -0
- package/dist/types/src/ai/ai.test.d.ts +1 -0
- package/dist/types/src/ai/bot.d.ts +40 -0
- package/dist/types/src/ai/mcts-bot.d.ts +60 -0
- package/dist/types/src/ai/random-bot.d.ts +27 -0
- package/dist/types/src/client/client.d.ts +104 -0
- package/dist/types/src/client/client.test.d.ts +1 -0
- package/dist/types/src/client/debug/tests/debug.test.d.ts +1 -0
- package/dist/types/src/client/manager.d.ts +61 -0
- package/dist/types/src/client/react.d.ts +75 -0
- package/dist/types/src/client/react.ssr.test.d.ts +4 -0
- package/dist/types/src/client/react.test.d.ts +1 -0
- package/dist/types/src/client/transport/dummy.d.ts +18 -0
- package/dist/types/src/client/transport/local.d.ts +59 -0
- package/dist/types/src/client/transport/local.test.d.ts +1 -0
- package/dist/types/src/client/transport/socketio.d.ts +45 -0
- package/dist/types/src/client/transport/socketio.test.d.ts +1 -0
- package/dist/types/src/client/transport/transport.d.ts +50 -0
- package/dist/types/src/client/transport/transport.test.d.ts +1 -0
- package/dist/types/src/core/action-creators.d.ts +144 -0
- package/dist/types/src/core/action-types.d.ts +10 -0
- package/dist/types/src/core/backwards-compatibility.d.ts +12 -0
- package/dist/types/src/core/constants.d.ts +6 -0
- package/dist/types/src/core/errors.d.ts +15 -0
- package/dist/types/src/core/flow.d.ts +28 -0
- package/dist/types/src/core/flow.test.d.ts +1 -0
- package/dist/types/src/core/game-methods.d.ts +9 -0
- package/dist/types/src/core/game.d.ts +26 -0
- package/dist/types/src/core/game.test.d.ts +1 -0
- package/dist/types/src/core/initialize.d.ts +9 -0
- package/dist/types/src/core/logger.d.ts +2 -0
- package/dist/types/src/core/player-view.d.ts +7 -0
- package/dist/types/src/core/player-view.test.d.ts +1 -0
- package/dist/types/src/core/reducer.d.ts +155 -0
- package/dist/types/src/core/reducer.test.d.ts +1 -0
- package/dist/types/src/core/turn-order.d.ts +179 -0
- package/dist/types/src/core/turn-order.test.d.ts +8 -0
- package/dist/types/src/lobby/client.d.ts +194 -0
- package/dist/types/src/lobby/client.test.d.ts +1 -0
- package/dist/types/src/lobby/connection.d.ts +44 -0
- package/dist/types/src/lobby/connection.test.d.ts +1 -0
- package/dist/types/src/lobby/create-match-form.d.ts +26 -0
- package/dist/types/src/lobby/login-form.d.ts +23 -0
- package/dist/types/src/lobby/match-instance.d.ts +31 -0
- package/dist/types/src/lobby/react.d.ts +113 -0
- package/dist/types/src/lobby/react.ssr.test.d.ts +4 -0
- package/dist/types/src/lobby/react.test.d.ts +1 -0
- package/dist/types/src/master/filter-player-view.d.ts +96 -0
- package/dist/types/src/master/filter-player-view.test.d.ts +1 -0
- package/dist/types/src/master/master.d.ts +94 -0
- package/dist/types/src/master/master.test.d.ts +1 -0
- package/dist/types/src/plugins/events/events.d.ts +54 -0
- package/dist/types/src/plugins/events/events.test.d.ts +1 -0
- package/dist/types/src/plugins/main.d.ts +75 -0
- package/dist/types/src/plugins/main.test.d.ts +1 -0
- package/dist/types/src/plugins/plugin-events.d.ts +5 -0
- package/dist/types/src/plugins/plugin-immer.d.ts +7 -0
- package/dist/types/src/plugins/plugin-immer.test.d.ts +1 -0
- package/dist/types/src/plugins/plugin-log.d.ts +14 -0
- package/dist/types/src/plugins/plugin-log.test.d.ts +1 -0
- package/dist/types/src/plugins/plugin-player.d.ts +29 -0
- package/dist/types/src/plugins/plugin-player.test.d.ts +1 -0
- package/dist/types/src/plugins/plugin-random.d.ts +4 -0
- package/dist/types/src/plugins/plugin-serializable.d.ts +7 -0
- package/dist/types/src/plugins/plugin-serializable.test.d.ts +1 -0
- package/dist/types/src/plugins/random/random.alea.d.ts +19 -0
- package/dist/types/src/plugins/random/random.d.ts +54 -0
- package/dist/types/src/plugins/random/random.test.d.ts +1 -0
- package/dist/types/src/server/api.d.ts +13 -0
- package/dist/types/src/server/api.test.d.ts +1 -0
- package/dist/types/src/server/auth.d.ts +38 -0
- package/dist/types/src/server/auth.test.d.ts +1 -0
- package/dist/types/src/server/cors.d.ts +4 -0
- package/dist/types/src/server/cors.test.d.ts +1 -0
- package/dist/types/src/server/db/base.d.ts +192 -0
- package/dist/types/src/server/db/flatfile.d.ts +44 -0
- package/dist/types/src/server/db/flatfile.test.d.ts +1 -0
- package/dist/types/src/server/db/index.d.ts +4 -0
- package/dist/types/src/server/db/index.test.d.ts +1 -0
- package/dist/types/src/server/db/inmemory.d.ts +43 -0
- package/dist/types/src/server/db/inmemory.test.d.ts +1 -0
- package/dist/types/src/server/db/localstorage.d.ts +7 -0
- package/dist/types/src/server/db/localstorage.test.d.ts +1 -0
- package/dist/types/src/server/index.d.ts +68 -0
- package/dist/types/src/server/index.test.d.ts +1 -0
- package/dist/types/src/server/transport/pubsub/generic-pub-sub.d.ts +6 -0
- package/dist/types/src/server/transport/pubsub/in-memory-pub-sub.d.ts +7 -0
- package/dist/types/src/server/transport/pubsub/in-memory-pub-sub.test.d.ts +1 -0
- package/dist/types/src/server/transport/socketio-simultaneous.test.d.ts +1 -0
- package/dist/types/src/server/transport/socketio.d.ts +65 -0
- package/dist/types/src/server/transport/socketio.test.d.ts +1 -0
- package/dist/types/src/server/util.d.ts +35 -0
- package/dist/types/src/testing/mock-random.d.ts +15 -0
- package/dist/types/src/testing/mock-random.test.d.ts +1 -0
- package/dist/types/src/types.d.ts +387 -0
- package/internal/package.json +7 -0
- package/master/package.json +7 -0
- package/multiplayer/package.json +7 -0
- package/package.json +211 -0
- package/plugins/package.json +7 -0
- package/react/package.json +7 -0
- package/react-native/package.json +7 -0
- package/server/package.json +6 -0
- package/src/ai/ai.test.ts +433 -0
- package/src/ai/ai.ts +84 -0
- package/src/ai/bot.ts +122 -0
- package/src/ai/mcts-bot.ts +331 -0
- package/src/ai/random-bot.ts +20 -0
- package/src/client/client.test.ts +993 -0
- package/src/client/client.ts +588 -0
- package/src/client/debug/Debug.svelte +239 -0
- package/src/client/debug/Menu.svelte +65 -0
- package/src/client/debug/ai/AI.svelte +215 -0
- package/src/client/debug/ai/Options.svelte +48 -0
- package/src/client/debug/info/Info.svelte +22 -0
- package/src/client/debug/info/Item.svelte +24 -0
- package/src/client/debug/log/Log.svelte +157 -0
- package/src/client/debug/log/LogEvent.svelte +149 -0
- package/src/client/debug/log/LogMetadata.svelte +7 -0
- package/src/client/debug/log/PhaseMarker.svelte +27 -0
- package/src/client/debug/log/TurnMarker.svelte +23 -0
- package/src/client/debug/main/ClientSwitcher.svelte +59 -0
- package/src/client/debug/main/Controls.svelte +58 -0
- package/src/client/debug/main/Hotkey.svelte +84 -0
- package/src/client/debug/main/InteractiveFunction.svelte +85 -0
- package/src/client/debug/main/Main.svelte +121 -0
- package/src/client/debug/main/Move.svelte +68 -0
- package/src/client/debug/main/PlayerInfo.svelte +70 -0
- package/src/client/debug/mcts/Action.svelte +22 -0
- package/src/client/debug/mcts/MCTS.svelte +78 -0
- package/src/client/debug/mcts/Table.svelte +98 -0
- package/src/client/debug/tests/JSONTree.mock.svelte +3 -0
- package/src/client/debug/tests/debug.test.ts +183 -0
- package/src/client/debug/utils/shortcuts.js +50 -0
- package/src/client/debug/utils/shortcuts.test.js +49 -0
- package/src/client/manager.ts +177 -0
- package/src/client/react-native.js +136 -0
- package/src/client/react-native.test.js +229 -0
- package/src/client/react.ssr.test.tsx +24 -0
- package/src/client/react.test.tsx +213 -0
- package/src/client/react.tsx +192 -0
- package/src/client/transport/dummy.ts +19 -0
- package/src/client/transport/local.test.ts +353 -0
- package/src/client/transport/local.ts +230 -0
- package/src/client/transport/socketio.test.ts +328 -0
- package/src/client/transport/socketio.ts +210 -0
- package/src/client/transport/transport.test.ts +27 -0
- package/src/client/transport/transport.ts +95 -0
- package/src/core/action-creators.ts +159 -0
- package/src/core/action-types.ts +18 -0
- package/src/core/backwards-compatibility.ts +23 -0
- package/src/core/constants.ts +6 -0
- package/src/core/errors.ts +35 -0
- package/src/core/flow.test.ts +2433 -0
- package/src/core/flow.ts +897 -0
- package/src/core/game-methods.ts +9 -0
- package/src/core/game.test.ts +286 -0
- package/src/core/game.ts +114 -0
- package/src/core/initialize.ts +77 -0
- package/src/core/logger.test.js +90 -0
- package/src/core/logger.ts +18 -0
- package/src/core/player-view.test.ts +50 -0
- package/src/core/player-view.ts +39 -0
- package/src/core/reducer.test.ts +991 -0
- package/src/core/reducer.ts +532 -0
- package/src/core/turn-order.test.ts +1123 -0
- package/src/core/turn-order.ts +473 -0
- package/src/lobby/client.test.ts +385 -0
- package/src/lobby/client.ts +358 -0
- package/src/lobby/connection.test.ts +207 -0
- package/src/lobby/connection.ts +162 -0
- package/src/lobby/create-match-form.tsx +122 -0
- package/src/lobby/login-form.tsx +75 -0
- package/src/lobby/match-instance.tsx +135 -0
- package/src/lobby/react.ssr.test.tsx +22 -0
- package/src/lobby/react.test.tsx +594 -0
- package/src/lobby/react.tsx +402 -0
- package/src/master/filter-player-view.test.ts +381 -0
- package/src/master/filter-player-view.ts +102 -0
- package/src/master/master.test.ts +1068 -0
- package/src/master/master.ts +492 -0
- package/src/plugins/events/events.test.ts +108 -0
- package/src/plugins/events/events.ts +209 -0
- package/src/plugins/main.test.ts +411 -0
- package/src/plugins/main.ts +314 -0
- package/src/plugins/plugin-events.ts +40 -0
- package/src/plugins/plugin-immer.test.ts +86 -0
- package/src/plugins/plugin-immer.ts +37 -0
- package/src/plugins/plugin-log.test.ts +37 -0
- package/src/plugins/plugin-log.ts +40 -0
- package/src/plugins/plugin-player.test.ts +172 -0
- package/src/plugins/plugin-player.ts +100 -0
- package/src/plugins/plugin-random.ts +40 -0
- package/src/plugins/plugin-serializable.test.ts +40 -0
- package/src/plugins/plugin-serializable.ts +55 -0
- package/src/plugins/random/random.alea.ts +109 -0
- package/src/plugins/random/random.test.ts +167 -0
- package/src/plugins/random/random.ts +198 -0
- package/src/server/api.test.ts +1699 -0
- package/src/server/api.ts +527 -0
- package/src/server/auth.test.ts +275 -0
- package/src/server/auth.ts +89 -0
- package/src/server/cors.test.ts +121 -0
- package/src/server/cors.ts +7 -0
- package/src/server/db/base.ts +296 -0
- package/src/server/db/flatfile.test.ts +221 -0
- package/src/server/db/flatfile.ts +228 -0
- package/src/server/db/index.test.ts +8 -0
- package/src/server/db/index.ts +12 -0
- package/src/server/db/inmemory.test.ts +143 -0
- package/src/server/db/inmemory.ts +143 -0
- package/src/server/db/localstorage.test.ts +73 -0
- package/src/server/db/localstorage.ts +44 -0
- package/src/server/index.test.ts +265 -0
- package/src/server/index.ts +175 -0
- package/src/server/transport/pubsub/generic-pub-sub.ts +11 -0
- package/src/server/transport/pubsub/in-memory-pub-sub.test.ts +47 -0
- package/src/server/transport/pubsub/in-memory-pub-sub.ts +28 -0
- package/src/server/transport/socketio-simultaneous.test.ts +603 -0
- package/src/server/transport/socketio.test.ts +303 -0
- package/src/server/transport/socketio.ts +279 -0
- package/src/server/util.ts +85 -0
- package/src/testing/mock-random.test.ts +45 -0
- package/src/testing/mock-random.ts +27 -0
- package/src/types.ts +511 -0
- package/testing/package.json +7 -0
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
import { S as Sync } from './util-b6147cef.js';
|
|
2
|
+
import { M as Master } from './master-fa8f2e43.js';
|
|
3
|
+
import { T as Transport } from './transport-ce07b771.js';
|
|
4
|
+
import { g as getFilterPlayerView } from './filter-player-view-2c6cc96f.js';
|
|
5
|
+
import * as ioNamespace from 'socket.io-client';
|
|
6
|
+
|
|
7
|
+
/*
|
|
8
|
+
* Copyright 2017 The boardgame.io Authors
|
|
9
|
+
*
|
|
10
|
+
* Use of this source code is governed by a MIT-style
|
|
11
|
+
* license that can be found in the LICENSE file or at
|
|
12
|
+
* https://opensource.org/licenses/MIT.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* InMemory data storage.
|
|
16
|
+
*/
|
|
17
|
+
class InMemory extends Sync {
|
|
18
|
+
/**
|
|
19
|
+
* Creates a new InMemory storage.
|
|
20
|
+
*/
|
|
21
|
+
constructor() {
|
|
22
|
+
super();
|
|
23
|
+
this.state = new Map();
|
|
24
|
+
this.initial = new Map();
|
|
25
|
+
this.metadata = new Map();
|
|
26
|
+
this.log = new Map();
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Create a new match.
|
|
30
|
+
*
|
|
31
|
+
* @override
|
|
32
|
+
*/
|
|
33
|
+
createMatch(matchID, opts) {
|
|
34
|
+
this.initial.set(matchID, opts.initialState);
|
|
35
|
+
this.setState(matchID, opts.initialState);
|
|
36
|
+
this.setMetadata(matchID, opts.metadata);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Write the match metadata to the in-memory object.
|
|
40
|
+
*/
|
|
41
|
+
setMetadata(matchID, metadata) {
|
|
42
|
+
this.metadata.set(matchID, metadata);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Write the match state to the in-memory object.
|
|
46
|
+
*/
|
|
47
|
+
setState(matchID, state, deltalog) {
|
|
48
|
+
if (deltalog && deltalog.length > 0) {
|
|
49
|
+
const log = this.log.get(matchID) || [];
|
|
50
|
+
this.log.set(matchID, [...log, ...deltalog]);
|
|
51
|
+
}
|
|
52
|
+
this.state.set(matchID, state);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Fetches state for a particular matchID.
|
|
56
|
+
*/
|
|
57
|
+
fetch(matchID, opts) {
|
|
58
|
+
const result = {};
|
|
59
|
+
if (opts.state) {
|
|
60
|
+
result.state = this.state.get(matchID);
|
|
61
|
+
}
|
|
62
|
+
if (opts.metadata) {
|
|
63
|
+
result.metadata = this.metadata.get(matchID);
|
|
64
|
+
}
|
|
65
|
+
if (opts.log) {
|
|
66
|
+
result.log = this.log.get(matchID) || [];
|
|
67
|
+
}
|
|
68
|
+
if (opts.initialState) {
|
|
69
|
+
result.initialState = this.initial.get(matchID);
|
|
70
|
+
}
|
|
71
|
+
return result;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Remove the match state from the in-memory object.
|
|
75
|
+
*/
|
|
76
|
+
wipe(matchID) {
|
|
77
|
+
this.state.delete(matchID);
|
|
78
|
+
this.metadata.delete(matchID);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Return all keys.
|
|
82
|
+
*
|
|
83
|
+
* @override
|
|
84
|
+
*/
|
|
85
|
+
listMatches(opts) {
|
|
86
|
+
return [...this.metadata.entries()]
|
|
87
|
+
.filter(([, metadata]) => {
|
|
88
|
+
if (!opts) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
if (opts.gameName !== undefined &&
|
|
92
|
+
metadata.gameName !== opts.gameName) {
|
|
93
|
+
return false;
|
|
94
|
+
}
|
|
95
|
+
if (opts.where !== undefined) {
|
|
96
|
+
if (opts.where.isGameover !== undefined) {
|
|
97
|
+
const isGameover = metadata.gameover !== undefined;
|
|
98
|
+
if (isGameover !== opts.where.isGameover) {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (opts.where.updatedBefore !== undefined &&
|
|
103
|
+
metadata.updatedAt >= opts.where.updatedBefore) {
|
|
104
|
+
return false;
|
|
105
|
+
}
|
|
106
|
+
if (opts.where.updatedAfter !== undefined &&
|
|
107
|
+
metadata.updatedAt <= opts.where.updatedAfter) {
|
|
108
|
+
return false;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return true;
|
|
112
|
+
})
|
|
113
|
+
.map(([key]) => key);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
class WithLocalStorageMap extends Map {
|
|
118
|
+
constructor(key) {
|
|
119
|
+
super();
|
|
120
|
+
this.key = key;
|
|
121
|
+
const cache = JSON.parse(localStorage.getItem(this.key)) || [];
|
|
122
|
+
cache.forEach((entry) => this.set(...entry));
|
|
123
|
+
}
|
|
124
|
+
sync() {
|
|
125
|
+
const entries = [...this.entries()];
|
|
126
|
+
localStorage.setItem(this.key, JSON.stringify(entries));
|
|
127
|
+
}
|
|
128
|
+
set(key, value) {
|
|
129
|
+
super.set(key, value);
|
|
130
|
+
this.sync();
|
|
131
|
+
return this;
|
|
132
|
+
}
|
|
133
|
+
delete(key) {
|
|
134
|
+
const result = super.delete(key);
|
|
135
|
+
this.sync();
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* locaStorage data storage.
|
|
141
|
+
*/
|
|
142
|
+
class LocalStorage extends InMemory {
|
|
143
|
+
constructor(storagePrefix = 'bgio') {
|
|
144
|
+
super();
|
|
145
|
+
const StorageMap = (stateKey) => new WithLocalStorageMap(`${storagePrefix}_${stateKey}`);
|
|
146
|
+
this.state = StorageMap('state');
|
|
147
|
+
this.initial = StorageMap('initial');
|
|
148
|
+
this.metadata = StorageMap('metadata');
|
|
149
|
+
this.log = StorageMap('log');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/*
|
|
154
|
+
* Copyright 2018 The boardgame.io Authors
|
|
155
|
+
*
|
|
156
|
+
* Use of this source code is governed by a MIT-style
|
|
157
|
+
* license that can be found in the LICENSE file or at
|
|
158
|
+
* https://opensource.org/licenses/MIT.
|
|
159
|
+
*/
|
|
160
|
+
/**
|
|
161
|
+
* Returns null if it is not a bot's turn.
|
|
162
|
+
* Otherwise, returns a playerID of a bot that may play now.
|
|
163
|
+
*/
|
|
164
|
+
function GetBotPlayer(state, bots) {
|
|
165
|
+
if (state.ctx.gameover !== undefined) {
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
if (state.ctx.activePlayers) {
|
|
169
|
+
for (const key of Object.keys(bots)) {
|
|
170
|
+
if (key in state.ctx.activePlayers) {
|
|
171
|
+
return key;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
else if (state.ctx.currentPlayer in bots) {
|
|
176
|
+
return state.ctx.currentPlayer;
|
|
177
|
+
}
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Creates a local version of the master that the client
|
|
182
|
+
* can interact with.
|
|
183
|
+
*/
|
|
184
|
+
class LocalMaster extends Master {
|
|
185
|
+
constructor({ game, bots, storageKey, persist }) {
|
|
186
|
+
const clientCallbacks = {};
|
|
187
|
+
const initializedBots = {};
|
|
188
|
+
if (game && game.ai && bots) {
|
|
189
|
+
for (const playerID in bots) {
|
|
190
|
+
const bot = bots[playerID];
|
|
191
|
+
initializedBots[playerID] = new bot({
|
|
192
|
+
game,
|
|
193
|
+
enumerate: game.ai.enumerate,
|
|
194
|
+
seed: game.seed,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
const send = ({ playerID, ...data }) => {
|
|
199
|
+
const callback = clientCallbacks[playerID];
|
|
200
|
+
if (callback !== undefined) {
|
|
201
|
+
callback(filterPlayerView(playerID, data));
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
const filterPlayerView = getFilterPlayerView(game);
|
|
205
|
+
const transportAPI = {
|
|
206
|
+
send,
|
|
207
|
+
sendAll: (payload) => {
|
|
208
|
+
for (const playerID in clientCallbacks) {
|
|
209
|
+
send({ playerID, ...payload });
|
|
210
|
+
}
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
const storage = persist ? new LocalStorage(storageKey) : new InMemory();
|
|
214
|
+
super(game, storage, transportAPI);
|
|
215
|
+
this.connect = (playerID, callback) => {
|
|
216
|
+
clientCallbacks[playerID] = callback;
|
|
217
|
+
};
|
|
218
|
+
this.subscribe(({ state, matchID }) => {
|
|
219
|
+
if (!bots) {
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const botPlayer = GetBotPlayer(state, initializedBots);
|
|
223
|
+
if (botPlayer !== null) {
|
|
224
|
+
setTimeout(async () => {
|
|
225
|
+
const botAction = await initializedBots[botPlayer].play(state, botPlayer);
|
|
226
|
+
await this.onUpdate(botAction.action, state._stateID, matchID, botAction.action.payload.playerID);
|
|
227
|
+
}, 100);
|
|
228
|
+
}
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Local
|
|
234
|
+
*
|
|
235
|
+
* Transport interface that embeds a GameMaster within it
|
|
236
|
+
* that you can connect multiple clients to.
|
|
237
|
+
*/
|
|
238
|
+
class LocalTransport extends Transport {
|
|
239
|
+
/**
|
|
240
|
+
* Creates a new Mutiplayer instance.
|
|
241
|
+
* @param {string} matchID - The game ID to connect to.
|
|
242
|
+
* @param {string} playerID - The player ID associated with this client.
|
|
243
|
+
* @param {string} gameName - The game type (the `name` field in `Game`).
|
|
244
|
+
* @param {string} numPlayers - The number of players.
|
|
245
|
+
*/
|
|
246
|
+
constructor({ master, ...opts }) {
|
|
247
|
+
super(opts);
|
|
248
|
+
this.master = master;
|
|
249
|
+
}
|
|
250
|
+
sendChatMessage(matchID, chatMessage) {
|
|
251
|
+
const args = [
|
|
252
|
+
matchID,
|
|
253
|
+
chatMessage,
|
|
254
|
+
this.credentials,
|
|
255
|
+
];
|
|
256
|
+
this.master.onChatMessage(...args);
|
|
257
|
+
}
|
|
258
|
+
sendAction(state, action) {
|
|
259
|
+
this.master.onUpdate(action, state._stateID, this.matchID, this.playerID);
|
|
260
|
+
}
|
|
261
|
+
requestSync() {
|
|
262
|
+
this.master.onSync(this.matchID, this.playerID, this.credentials, this.numPlayers);
|
|
263
|
+
}
|
|
264
|
+
connect() {
|
|
265
|
+
this.setConnectionStatus(true);
|
|
266
|
+
this.master.connect(this.playerID, (data) => this.notifyClient(data));
|
|
267
|
+
this.requestSync();
|
|
268
|
+
}
|
|
269
|
+
disconnect() {
|
|
270
|
+
this.setConnectionStatus(false);
|
|
271
|
+
}
|
|
272
|
+
updateMatchID(id) {
|
|
273
|
+
this.matchID = id;
|
|
274
|
+
this.connect();
|
|
275
|
+
}
|
|
276
|
+
updatePlayerID(id) {
|
|
277
|
+
this.playerID = id;
|
|
278
|
+
this.connect();
|
|
279
|
+
}
|
|
280
|
+
updateCredentials(credentials) {
|
|
281
|
+
this.credentials = credentials;
|
|
282
|
+
this.connect();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Global map storing local master instances.
|
|
287
|
+
*/
|
|
288
|
+
const localMasters = new Map();
|
|
289
|
+
/**
|
|
290
|
+
* Create a local transport.
|
|
291
|
+
*/
|
|
292
|
+
function Local({ bots, persist, storageKey } = {}) {
|
|
293
|
+
return (transportOpts) => {
|
|
294
|
+
const { gameKey, game } = transportOpts;
|
|
295
|
+
let master;
|
|
296
|
+
const instance = localMasters.get(gameKey);
|
|
297
|
+
if (instance &&
|
|
298
|
+
instance.bots === bots &&
|
|
299
|
+
instance.storageKey === storageKey &&
|
|
300
|
+
instance.persist === persist) {
|
|
301
|
+
master = instance.master;
|
|
302
|
+
}
|
|
303
|
+
if (!master) {
|
|
304
|
+
master = new LocalMaster({ game, bots, persist, storageKey });
|
|
305
|
+
localMasters.set(gameKey, { master, bots, persist, storageKey });
|
|
306
|
+
}
|
|
307
|
+
return new LocalTransport({ master, ...transportOpts });
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/*
|
|
312
|
+
* Copyright 2017 The boardgame.io Authors
|
|
313
|
+
*
|
|
314
|
+
* Use of this source code is governed by a MIT-style
|
|
315
|
+
* license that can be found in the LICENSE file or at
|
|
316
|
+
* https://opensource.org/licenses/MIT.
|
|
317
|
+
*/
|
|
318
|
+
const io = ioNamespace.default;
|
|
319
|
+
/**
|
|
320
|
+
* SocketIO
|
|
321
|
+
*
|
|
322
|
+
* Transport interface that interacts with the Master via socket.io.
|
|
323
|
+
*/
|
|
324
|
+
class SocketIOTransport extends Transport {
|
|
325
|
+
/**
|
|
326
|
+
* Creates a new Multiplayer instance.
|
|
327
|
+
* @param {object} socket - Override for unit tests.
|
|
328
|
+
* @param {object} socketOpts - Options to pass to socket.io.
|
|
329
|
+
* @param {object} store - Redux store
|
|
330
|
+
* @param {string} matchID - The game ID to connect to.
|
|
331
|
+
* @param {string} playerID - The player ID associated with this client.
|
|
332
|
+
* @param {string} credentials - Authentication credentials
|
|
333
|
+
* @param {string} gameName - The game type (the `name` field in `Game`).
|
|
334
|
+
* @param {string} numPlayers - The number of players.
|
|
335
|
+
* @param {string} server - The game server in the form of 'hostname:port'. Defaults to the server serving the client if not provided.
|
|
336
|
+
*/
|
|
337
|
+
constructor({ socket, socketOpts, server, ...opts }) {
|
|
338
|
+
super(opts);
|
|
339
|
+
this.server = server;
|
|
340
|
+
this.socket = socket;
|
|
341
|
+
this.socketOpts = socketOpts;
|
|
342
|
+
}
|
|
343
|
+
sendAction(state, action) {
|
|
344
|
+
const args = [
|
|
345
|
+
action,
|
|
346
|
+
state._stateID,
|
|
347
|
+
this.matchID,
|
|
348
|
+
this.playerID,
|
|
349
|
+
];
|
|
350
|
+
this.socket.emit('update', ...args);
|
|
351
|
+
}
|
|
352
|
+
sendChatMessage(matchID, chatMessage) {
|
|
353
|
+
const args = [
|
|
354
|
+
matchID,
|
|
355
|
+
chatMessage,
|
|
356
|
+
this.credentials,
|
|
357
|
+
];
|
|
358
|
+
this.socket.emit('chat', ...args);
|
|
359
|
+
}
|
|
360
|
+
connect() {
|
|
361
|
+
if (!this.socket) {
|
|
362
|
+
if (this.server) {
|
|
363
|
+
let server = this.server;
|
|
364
|
+
if (server.search(/^https?:\/\//) == -1) {
|
|
365
|
+
server = 'http://' + this.server;
|
|
366
|
+
}
|
|
367
|
+
if (server.slice(-1) != '/') {
|
|
368
|
+
// add trailing slash if not already present
|
|
369
|
+
server = server + '/';
|
|
370
|
+
}
|
|
371
|
+
this.socket = io(server + this.gameName, this.socketOpts);
|
|
372
|
+
}
|
|
373
|
+
else {
|
|
374
|
+
this.socket = io('/' + this.gameName, this.socketOpts);
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
// Called when another player makes a move and the
|
|
378
|
+
// master broadcasts the update as a patch to other clients (including
|
|
379
|
+
// this one).
|
|
380
|
+
this.socket.on('patch', (matchID, prevStateID, stateID, patch, deltalog) => {
|
|
381
|
+
this.notifyClient({
|
|
382
|
+
type: 'patch',
|
|
383
|
+
args: [matchID, prevStateID, stateID, patch, deltalog],
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
// Called when another player makes a move and the
|
|
387
|
+
// master broadcasts the update to other clients (including
|
|
388
|
+
// this one).
|
|
389
|
+
this.socket.on('update', (matchID, state, deltalog) => {
|
|
390
|
+
this.notifyClient({
|
|
391
|
+
type: 'update',
|
|
392
|
+
args: [matchID, state, deltalog],
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
// Called when the client first connects to the master
|
|
396
|
+
// and requests the current game state.
|
|
397
|
+
this.socket.on('sync', (matchID, syncInfo) => {
|
|
398
|
+
this.notifyClient({ type: 'sync', args: [matchID, syncInfo] });
|
|
399
|
+
});
|
|
400
|
+
// Called when new player joins the match or changes
|
|
401
|
+
// it's connection status
|
|
402
|
+
this.socket.on('matchData', (matchID, matchData) => {
|
|
403
|
+
this.notifyClient({ type: 'matchData', args: [matchID, matchData] });
|
|
404
|
+
});
|
|
405
|
+
this.socket.on('chat', (matchID, chatMessage) => {
|
|
406
|
+
this.notifyClient({ type: 'chat', args: [matchID, chatMessage] });
|
|
407
|
+
});
|
|
408
|
+
// Keep track of connection status.
|
|
409
|
+
this.socket.on('connect', () => {
|
|
410
|
+
// Initial sync to get game state.
|
|
411
|
+
this.requestSync();
|
|
412
|
+
this.setConnectionStatus(true);
|
|
413
|
+
});
|
|
414
|
+
this.socket.on('disconnect', () => {
|
|
415
|
+
this.setConnectionStatus(false);
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
disconnect() {
|
|
419
|
+
this.socket.close();
|
|
420
|
+
this.socket = null;
|
|
421
|
+
this.setConnectionStatus(false);
|
|
422
|
+
}
|
|
423
|
+
requestSync() {
|
|
424
|
+
if (this.socket) {
|
|
425
|
+
const args = [
|
|
426
|
+
this.matchID,
|
|
427
|
+
this.playerID,
|
|
428
|
+
this.credentials,
|
|
429
|
+
this.numPlayers,
|
|
430
|
+
];
|
|
431
|
+
this.socket.emit('sync', ...args);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
updateMatchID(id) {
|
|
435
|
+
this.matchID = id;
|
|
436
|
+
this.requestSync();
|
|
437
|
+
}
|
|
438
|
+
updatePlayerID(id) {
|
|
439
|
+
this.playerID = id;
|
|
440
|
+
this.requestSync();
|
|
441
|
+
}
|
|
442
|
+
updateCredentials(credentials) {
|
|
443
|
+
this.credentials = credentials;
|
|
444
|
+
this.requestSync();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
function SocketIO({ server, socketOpts } = {}) {
|
|
448
|
+
return (transportOpts) => new SocketIOTransport({
|
|
449
|
+
server,
|
|
450
|
+
socketOpts,
|
|
451
|
+
...transportOpts,
|
|
452
|
+
});
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
export { Local as L, SocketIO as S };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { R as RandomPlugin } from './plugin-random-087f861e.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test helper that creates a plugin to override the built-in random API.
|
|
5
|
+
*
|
|
6
|
+
* @param overrides - A map of method names to mock functions.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const game = {
|
|
10
|
+
* plugins: [
|
|
11
|
+
* MockRandom({ D6: () => 1 }),
|
|
12
|
+
* ],
|
|
13
|
+
* };
|
|
14
|
+
*/
|
|
15
|
+
const MockRandom = (overrides = {}) => {
|
|
16
|
+
// Don’t include the original flush method, otherwise when the
|
|
17
|
+
// built-in random plugin flushes, it won’t have access to the
|
|
18
|
+
// state it needs.
|
|
19
|
+
const { flush, ...rest } = RandomPlugin;
|
|
20
|
+
return {
|
|
21
|
+
...rest,
|
|
22
|
+
api: (context) => ({ ...RandomPlugin.api(context), ...overrides }),
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export { MockRandom };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright 2017 The boardgame.io Authors
|
|
3
|
+
*
|
|
4
|
+
* Use of this source code is governed by a MIT-style
|
|
5
|
+
* license that can be found in the LICENSE file or at
|
|
6
|
+
* https://opensource.org/licenses/MIT.
|
|
7
|
+
*/
|
|
8
|
+
class Transport {
|
|
9
|
+
constructor({ transportDataCallback, gameName, playerID, matchID, credentials, numPlayers, }) {
|
|
10
|
+
/** Callback to let the client know when the connection status has changed. */
|
|
11
|
+
this.connectionStatusCallback = () => { };
|
|
12
|
+
this.isConnected = false;
|
|
13
|
+
this.transportDataCallback = transportDataCallback;
|
|
14
|
+
this.gameName = gameName || 'default';
|
|
15
|
+
this.playerID = playerID || null;
|
|
16
|
+
this.matchID = matchID || 'default';
|
|
17
|
+
this.credentials = credentials;
|
|
18
|
+
this.numPlayers = numPlayers || 2;
|
|
19
|
+
}
|
|
20
|
+
/** Subscribe to connection state changes. */
|
|
21
|
+
subscribeToConnectionStatus(fn) {
|
|
22
|
+
this.connectionStatusCallback = fn;
|
|
23
|
+
}
|
|
24
|
+
/** Transport implementations should call this when they connect/disconnect. */
|
|
25
|
+
setConnectionStatus(isConnected) {
|
|
26
|
+
this.isConnected = isConnected;
|
|
27
|
+
this.connectionStatusCallback();
|
|
28
|
+
}
|
|
29
|
+
/** Transport implementations should call this when they receive data from a master. */
|
|
30
|
+
notifyClient(data) {
|
|
31
|
+
this.transportDataCallback(data);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { Transport as T };
|