1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 | export default function createGameActionMiddleware(actions) {
|
11 | const actionMap = {};
|
12 | Object.keys(actions).forEach(key => {
|
13 | const value = actions[key];
|
14 | if (typeof value !== "string" || key !== value) {
|
15 | return;
|
16 | }
|
17 | const camelCase = value
|
18 | .split("_")
|
19 | .map(word => word[0].toUpperCase() + word.slice(1).toLowerCase())
|
20 | .join("");
|
21 | const actionCreator = camelCase[0].toLowerCase() + camelCase.slice(1);
|
22 | if (actions[actionCreator]) {
|
23 | actionMap[value] = actions[actionCreator];
|
24 | }
|
25 | });
|
26 |
|
27 | |
28 |
|
29 |
|
30 | function checkActionAllowed(state, action) {
|
31 |
|
32 | if (!actions[action.type]) {
|
33 | return;
|
34 | }
|
35 |
|
36 | if (!state.game || !state.game.turn) {
|
37 | return;
|
38 | }
|
39 | const sender = action.agent || state.client.keys.id;
|
40 | if (state.game.nextActions.length > 0) {
|
41 | const queueUser = state.game.nextActions[0].playerId;
|
42 | if (sender !== queueUser) {
|
43 | throw new Error(
|
44 | `queue wants user ${queueUser} but user ${sender} acted`
|
45 | );
|
46 | }
|
47 | }
|
48 |
|
49 | else if (state.game.allowedActions[action.type] !== true) {
|
50 | throw new Error(
|
51 | `${sender} attempted to do non-allowed action ${action.type}`
|
52 | );
|
53 | } else if (state.game.turn !== sender) {
|
54 | throw new Error(
|
55 | `${sender} acted out of turn; it's ${state.game.turn}'s turn`
|
56 | );
|
57 | }
|
58 | }
|
59 |
|
60 | return function gameActionMiddleware(store) {
|
61 | return next => {
|
62 | return action => {
|
63 | const state = store.getState();
|
64 | let { dispatch, getState } = store;
|
65 | checkActionAllowed(state, action);
|
66 | if (
|
67 | !state.client.loadingState &&
|
68 | actionMap[action.type] &&
|
69 | action._fromQueue &&
|
70 | !action._dispatchedFromQueue
|
71 | ) {
|
72 | action = actionMap[action.type](action);
|
73 | dispatch = action =>
|
74 | store.dispatch({
|
75 | ...action,
|
76 | _fromQueue: true,
|
77 | _dispatchedFromQueue: true
|
78 | });
|
79 | }
|
80 |
|
81 | if (typeof action === "function") {
|
82 | return action(dispatch, getState);
|
83 | }
|
84 | return next(action);
|
85 | };
|
86 | };
|
87 | };
|
88 | }
|