@gamepark/react-client 6.38.5 → 7.0.0-beta.2

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.
Files changed (317) hide show
  1. package/dist/Actions/ActionFailed.d.ts +6 -6
  2. package/dist/Actions/ActionFailed.js +4 -8
  3. package/dist/Actions/ActionFailed.js.map +1 -1
  4. package/dist/Actions/AnimationComplete.d.ts +6 -6
  5. package/dist/Actions/AnimationComplete.js +4 -8
  6. package/dist/Actions/AnimationComplete.js.map +1 -1
  7. package/dist/Actions/AnimationPaused.d.ts +6 -6
  8. package/dist/Actions/AnimationPaused.js +4 -8
  9. package/dist/Actions/AnimationPaused.js.map +1 -1
  10. package/dist/Actions/AnimationStart.d.ts +5 -5
  11. package/dist/Actions/AnimationStart.js +1 -4
  12. package/dist/Actions/AnimationStart.js.map +1 -1
  13. package/dist/Actions/ClearFailures.d.ts +1 -5
  14. package/dist/Actions/ClearFailures.js +3 -9
  15. package/dist/Actions/ClearFailures.js.map +1 -1
  16. package/dist/Actions/GameNotificationsReceived.d.ts +8 -10
  17. package/dist/Actions/GameNotificationsReceived.js +2 -9
  18. package/dist/Actions/GameNotificationsReceived.js.map +1 -1
  19. package/dist/Actions/GameOver.d.ts +16 -16
  20. package/dist/Actions/GameOver.js +4 -8
  21. package/dist/Actions/GameOver.js.map +1 -1
  22. package/dist/Actions/GameStateLoaded.d.ts +16 -16
  23. package/dist/Actions/GameStateLoaded.js +7 -20
  24. package/dist/Actions/GameStateLoaded.js.map +1 -1
  25. package/dist/Actions/MovePlayed.d.ts +11 -11
  26. package/dist/Actions/MovePlayed.js +3 -2
  27. package/dist/Actions/MovePlayed.js.map +1 -1
  28. package/dist/Actions/MoveUndone.d.ts +7 -7
  29. package/dist/Actions/MoveUndone.js +4 -9
  30. package/dist/Actions/MoveUndone.js.map +1 -1
  31. package/dist/Actions/PlayerQuit.d.ts +5 -11
  32. package/dist/Actions/PlayerQuit.js +2 -19
  33. package/dist/Actions/PlayerQuit.js.map +1 -1
  34. package/dist/Actions/SetAnimationsSpeed.d.ts +1 -6
  35. package/dist/Actions/SetAnimationsSpeed.js +3 -9
  36. package/dist/Actions/SetAnimationsSpeed.js.map +1 -1
  37. package/dist/Actions/giveUp.d.ts +1 -0
  38. package/dist/Actions/giveUp.js +3 -0
  39. package/dist/Actions/giveUp.js.map +1 -0
  40. package/dist/Actions/index.d.ts +7 -12
  41. package/dist/Actions/index.js +7 -28
  42. package/dist/Actions/index.js.map +1 -1
  43. package/dist/Actions/loadGameState.d.ts +14 -0
  44. package/dist/Actions/loadGameState.js +3 -0
  45. package/dist/Actions/loadGameState.js.map +1 -0
  46. package/dist/Actions/playMove.d.ts +10 -0
  47. package/dist/Actions/playMove.js +3 -0
  48. package/dist/Actions/playMove.js.map +1 -0
  49. package/dist/Actions/receiveNotifications.d.ts +8 -0
  50. package/dist/Actions/receiveNotifications.js +3 -0
  51. package/dist/Actions/receiveNotifications.js.map +1 -0
  52. package/dist/Actions/removePlayer.d.ts +5 -0
  53. package/dist/Actions/removePlayer.js +3 -0
  54. package/dist/Actions/removePlayer.js.map +1 -0
  55. package/dist/Actions/reportFailure.d.ts +1 -0
  56. package/dist/Actions/reportFailure.js +3 -0
  57. package/dist/Actions/reportFailure.js.map +1 -0
  58. package/dist/Actions/setGameOver.d.ts +2 -0
  59. package/dist/Actions/setGameOver.js +3 -0
  60. package/dist/Actions/setGameOver.js.map +1 -0
  61. package/dist/Actions/startAnimation.d.ts +1 -0
  62. package/dist/Actions/startAnimation.js +3 -0
  63. package/dist/Actions/startAnimation.js.map +1 -0
  64. package/dist/Actions/undoMove.d.ts +5 -0
  65. package/dist/Actions/undoMove.js +4 -0
  66. package/dist/Actions/undoMove.js.map +1 -0
  67. package/dist/Chat/ChatChannel.d.ts +5 -5
  68. package/dist/Chat/ChatChannel.js +1 -2
  69. package/dist/Chat/Message.d.ts +6 -6
  70. package/dist/Chat/Message.js +1 -2
  71. package/dist/Chat/index.d.ts +2 -2
  72. package/dist/Chat/index.js +2 -18
  73. package/dist/Chat/index.js.map +1 -1
  74. package/dist/Deckbuilding/Deck.d.ts +5 -5
  75. package/dist/Deckbuilding/Deck.js +1 -2
  76. package/dist/Deckbuilding/index.d.ts +4 -4
  77. package/dist/Deckbuilding/index.js +4 -24
  78. package/dist/Deckbuilding/index.js.map +1 -1
  79. package/dist/Deckbuilding/useDeleteDeck.d.ts +5 -2
  80. package/dist/Deckbuilding/useDeleteDeck.js +9 -15
  81. package/dist/Deckbuilding/useDeleteDeck.js.map +1 -1
  82. package/dist/Deckbuilding/useMyDecks.d.ts +3 -2
  83. package/dist/Deckbuilding/useMyDecks.js +8 -14
  84. package/dist/Deckbuilding/useMyDecks.js.map +1 -1
  85. package/dist/Deckbuilding/useSaveDeck.d.ts +5 -2
  86. package/dist/Deckbuilding/useSaveDeck.js +9 -15
  87. package/dist/Deckbuilding/useSaveDeck.js.map +1 -1
  88. package/dist/EjectPlayer/EjectPlayer.d.ts +1 -6
  89. package/dist/EjectPlayer/EjectPlayer.js +2 -8
  90. package/dist/EjectPlayer/EjectPlayer.js.map +1 -1
  91. package/dist/EjectPlayer/index.d.ts +1 -1
  92. package/dist/EjectPlayer/index.js +1 -17
  93. package/dist/EjectPlayer/index.js.map +1 -1
  94. package/dist/Failure/Failure.d.ts +6 -6
  95. package/dist/Failure/Failure.js +6 -9
  96. package/dist/Failure/Failure.js.map +1 -1
  97. package/dist/Failure/index.d.ts +1 -1
  98. package/dist/Failure/index.js +1 -17
  99. package/dist/Failure/index.js.map +1 -1
  100. package/dist/GiveUp/GiveUp.d.ts +7 -7
  101. package/dist/GiveUp/GiveUp.js +2 -5
  102. package/dist/GiveUp/GiveUp.js.map +1 -1
  103. package/dist/GiveUp/index.d.ts +1 -1
  104. package/dist/GiveUp/index.js +1 -17
  105. package/dist/GiveUp/index.js.map +1 -1
  106. package/dist/Hooks/index.d.ts +5 -5
  107. package/dist/Hooks/index.js +5 -21
  108. package/dist/Hooks/index.js.map +1 -1
  109. package/dist/Hooks/useChatMessages.d.ts +7 -12
  110. package/dist/Hooks/useChatMessages.js +44 -51
  111. package/dist/Hooks/useChatMessages.js.map +1 -1
  112. package/dist/Hooks/useMessageAuthor.d.ts +4 -4
  113. package/dist/Hooks/useMessageAuthor.js +13 -18
  114. package/dist/Hooks/useMessageAuthor.js.map +1 -1
  115. package/dist/Hooks/useOptions.d.ts +2 -2
  116. package/dist/Hooks/useOptions.js +4 -8
  117. package/dist/Hooks/useOptions.js.map +1 -1
  118. package/dist/Hooks/useRematch.d.ts +7 -7
  119. package/dist/Hooks/useRematch.js +18 -19
  120. package/dist/Hooks/useRematch.js.map +1 -1
  121. package/dist/Hooks/useSendMessage.d.ts +4 -1
  122. package/dist/Hooks/useSendMessage.js +6 -14
  123. package/dist/Hooks/useSendMessage.js.map +1 -1
  124. package/dist/Log/StartLiveLog.d.ts +1 -4
  125. package/dist/Log/StartLiveLog.js +3 -5
  126. package/dist/Log/StartLiveLog.js.map +1 -1
  127. package/dist/Log/StopLiveLog.d.ts +2 -5
  128. package/dist/Log/StopLiveLog.js +6 -9
  129. package/dist/Log/StopLiveLog.js.map +1 -1
  130. package/dist/Log/index.d.ts +4 -4
  131. package/dist/Log/index.js +4 -20
  132. package/dist/Log/index.js.map +1 -1
  133. package/dist/Log/useLogControls.d.ts +7 -7
  134. package/dist/Log/useLogControls.js +18 -22
  135. package/dist/Log/useLogControls.js.map +1 -1
  136. package/dist/PlayerTime/PlayerTime.d.ts +11 -11
  137. package/dist/PlayerTime/PlayerTime.js +1 -2
  138. package/dist/PlayerTime/index.d.ts +1 -1
  139. package/dist/PlayerTime/index.js +1 -17
  140. package/dist/PlayerTime/index.js.map +1 -1
  141. package/dist/Rematch/RematchQueries.d.ts +19 -19
  142. package/dist/Rematch/RematchQueries.js +23 -13
  143. package/dist/Rematch/RematchQueries.js.map +1 -1
  144. package/dist/Rematch/index.d.ts +1 -1
  145. package/dist/Rematch/index.js +1 -17
  146. package/dist/Rematch/index.js.map +1 -1
  147. package/dist/Sound/MuteSounds.d.ts +2 -5
  148. package/dist/Sound/MuteSounds.js +7 -10
  149. package/dist/Sound/MuteSounds.js.map +1 -1
  150. package/dist/Sound/UnmuteSounds.d.ts +1 -4
  151. package/dist/Sound/UnmuteSounds.js +3 -5
  152. package/dist/Sound/UnmuteSounds.js.map +1 -1
  153. package/dist/Sound/index.d.ts +3 -3
  154. package/dist/Sound/index.js +3 -19
  155. package/dist/Sound/index.js.map +1 -1
  156. package/dist/Sound/useSoundControls.d.ts +7 -7
  157. package/dist/Sound/useSoundControls.js +18 -22
  158. package/dist/Sound/useSoundControls.js.map +1 -1
  159. package/dist/Store/DisplayedAction.d.ts +15 -15
  160. package/dist/Store/DisplayedAction.js +12 -19
  161. package/dist/Store/DisplayedAction.js.map +1 -1
  162. package/dist/Store/GamePageState.d.ts +27 -28
  163. package/dist/Store/GamePageState.js +1 -2
  164. package/dist/Store/PlayedMove.d.ts +5 -5
  165. package/dist/Store/PlayedMove.js +1 -2
  166. package/dist/Store/endAnimation.d.ts +1 -0
  167. package/dist/Store/endAnimation.js +3 -0
  168. package/dist/Store/endAnimation.js.map +1 -0
  169. package/dist/Store/gameMiddleware.d.ts +4 -4
  170. package/dist/Store/gameMiddleware.js +34 -41
  171. package/dist/Store/gameMiddleware.js.map +1 -1
  172. package/dist/Store/gameReducer.d.ts +14 -20
  173. package/dist/Store/gameReducer.js +462 -525
  174. package/dist/Store/gameReducer.js.map +1 -1
  175. package/dist/Store/index.d.ts +4 -3
  176. package/dist/Store/index.js +4 -19
  177. package/dist/Store/index.js.map +1 -1
  178. package/dist/Store/localMovePreviewMiddleware.d.ts +4 -4
  179. package/dist/Store/localMovePreviewMiddleware.js +19 -18
  180. package/dist/Store/localMovePreviewMiddleware.js.map +1 -1
  181. package/dist/Store/store.d.ts +13 -0
  182. package/dist/Store/store.js +27 -0
  183. package/dist/Store/store.js.map +1 -0
  184. package/dist/Tutorial/PlayTutorialMoves.d.ts +1 -9
  185. package/dist/Tutorial/PlayTutorialMoves.js +2 -6
  186. package/dist/Tutorial/PlayTutorialMoves.js.map +1 -1
  187. package/dist/Tutorial/Tutorial.d.ts +5 -5
  188. package/dist/Tutorial/Tutorial.js +1 -2
  189. package/dist/Tutorial/TutorialDescription.d.ts +7 -7
  190. package/dist/Tutorial/TutorialDescription.js +1 -2
  191. package/dist/Tutorial/index.d.ts +4 -4
  192. package/dist/Tutorial/index.js +4 -20
  193. package/dist/Tutorial/index.js.map +1 -1
  194. package/dist/Tutorial/useTutorial.d.ts +2 -2
  195. package/dist/Tutorial/useTutorial.js +12 -22
  196. package/dist/Tutorial/useTutorial.js.map +1 -1
  197. package/dist/Types/GameAI.d.ts +1 -1
  198. package/dist/Types/GameAI.js +1 -2
  199. package/dist/Types/GameData.d.ts +18 -18
  200. package/dist/Types/GameData.js +1 -2
  201. package/dist/Types/GameMessage.d.ts +8 -8
  202. package/dist/Types/GameMessage.js +1 -2
  203. package/dist/Types/GameMode.d.ts +6 -6
  204. package/dist/Types/GameMode.js +7 -10
  205. package/dist/Types/GameMode.js.map +1 -1
  206. package/dist/Types/GameNotification.d.ts +6 -6
  207. package/dist/Types/GameNotification.js +1 -2
  208. package/dist/Types/GameOptions.d.ts +9 -9
  209. package/dist/Types/GameOptions.js +5 -8
  210. package/dist/Types/GameOptions.js.map +1 -1
  211. package/dist/Types/MovePlayedNotification.d.ts +9 -9
  212. package/dist/Types/MovePlayedNotification.js +6 -12
  213. package/dist/Types/MovePlayedNotification.js.map +1 -1
  214. package/dist/Types/MoveUndoneNotification.d.ts +8 -8
  215. package/dist/Types/MoveUndoneNotification.js +6 -12
  216. package/dist/Types/MoveUndoneNotification.js.map +1 -1
  217. package/dist/Types/Player.d.ts +13 -13
  218. package/dist/Types/Player.js +1 -2
  219. package/dist/Types/PlayerQuitReason.d.ts +4 -4
  220. package/dist/Types/PlayerQuitReason.js +5 -8
  221. package/dist/Types/PlayerQuitReason.js.map +1 -1
  222. package/dist/Types/ProxyGameData.d.ts +13 -13
  223. package/dist/Types/ProxyGameData.js +1 -2
  224. package/dist/Types/Tournament.d.ts +4 -4
  225. package/dist/Types/Tournament.js +1 -2
  226. package/dist/Types/index.d.ts +12 -12
  227. package/dist/Types/index.js +12 -28
  228. package/dist/Types/index.js.map +1 -1
  229. package/dist/User/User.d.ts +6 -6
  230. package/dist/User/User.js +1 -2
  231. package/dist/User/index.d.ts +2 -2
  232. package/dist/User/index.js +2 -18
  233. package/dist/User/index.js.map +1 -1
  234. package/dist/User/useMe.d.ts +4 -4
  235. package/dist/User/useMe.js +10 -21
  236. package/dist/User/useMe.js.map +1 -1
  237. package/dist/animations/Animation.d.ts +6 -6
  238. package/dist/animations/Animation.js +1 -2
  239. package/dist/animations/AnimationContext.d.ts +8 -8
  240. package/dist/animations/AnimationContext.js +1 -2
  241. package/dist/animations/AnimationState.d.ts +6 -6
  242. package/dist/animations/AnimationState.js +1 -2
  243. package/dist/animations/AnimationStep.d.ts +6 -6
  244. package/dist/animations/AnimationStep.js +7 -10
  245. package/dist/animations/AnimationStep.js.map +1 -1
  246. package/dist/animations/Animations.d.ts +8 -8
  247. package/dist/animations/Animations.js +15 -22
  248. package/dist/animations/Animations.js.map +1 -1
  249. package/dist/animations/AnimationsListener.d.ts +6 -0
  250. package/dist/animations/AnimationsListener.js +54 -0
  251. package/dist/animations/AnimationsListener.js.map +1 -0
  252. package/dist/animations/AnimationsListenerCreator.d.ts +2 -4
  253. package/dist/animations/AnimationsListenerCreator.js +40 -50
  254. package/dist/animations/AnimationsListenerCreator.js.map +1 -1
  255. package/dist/animations/animationMiddleware.d.ts +4 -0
  256. package/dist/animations/animationMiddleware.js +50 -0
  257. package/dist/animations/animationMiddleware.js.map +1 -0
  258. package/dist/animations/index.d.ts +5 -6
  259. package/dist/animations/index.js +5 -22
  260. package/dist/animations/index.js.map +1 -1
  261. package/dist/api/Client/GameClientAPI.d.ts +24 -24
  262. package/dist/api/Client/GameClientAPI.js +116 -165
  263. package/dist/api/Client/GameClientAPI.js.map +1 -1
  264. package/dist/api/Client/GameNotificationsListener.d.ts +5 -5
  265. package/dist/api/Client/GameNotificationsListener.js +62 -113
  266. package/dist/api/Client/GameNotificationsListener.js.map +1 -1
  267. package/dist/api/Client/RemoteGameLoader.d.ts +4 -5
  268. package/dist/api/Client/RemoteGameLoader.js +66 -62
  269. package/dist/api/Client/RemoteGameLoader.js.map +1 -1
  270. package/dist/api/Client/RemoteGameProvider.d.ts +7 -7
  271. package/dist/api/Client/RemoteGameProvider.js +19 -70
  272. package/dist/api/Client/RemoteGameProvider.js.map +1 -1
  273. package/dist/api/Client/apollo-client.d.ts +2 -2
  274. package/dist/api/Client/apollo-client.js +40 -58
  275. package/dist/api/Client/apollo-client.js.map +1 -1
  276. package/dist/api/Client/index.d.ts +4 -3
  277. package/dist/api/Client/index.js +4 -19
  278. package/dist/api/Client/index.js.map +1 -1
  279. package/dist/api/Client/pusher.d.ts +2 -0
  280. package/dist/api/Client/pusher.js +9 -0
  281. package/dist/api/Client/pusher.js.map +1 -0
  282. package/dist/api/GameAPI.d.ts +10 -10
  283. package/dist/api/GameAPI.js +1 -2
  284. package/dist/api/Local/ConsoleTools.d.ts +25 -25
  285. package/dist/api/Local/ConsoleTools.js +78 -86
  286. package/dist/api/Local/ConsoleTools.js.map +1 -1
  287. package/dist/api/Local/GameLocalAPI.d.ts +44 -44
  288. package/dist/api/Local/GameLocalAPI.js +442 -540
  289. package/dist/api/Local/GameLocalAPI.js.map +1 -1
  290. package/dist/api/Local/LocalGameProvider.d.ts +15 -15
  291. package/dist/api/Local/LocalGameProvider.js +18 -58
  292. package/dist/api/Local/LocalGameProvider.js.map +1 -1
  293. package/dist/api/Local/index.d.ts +1 -1
  294. package/dist/api/Local/index.js +1 -17
  295. package/dist/api/Local/index.js.map +1 -1
  296. package/dist/api/index.d.ts +2 -2
  297. package/dist/api/index.js +2 -18
  298. package/dist/api/index.js.map +1 -1
  299. package/dist/index.d.ts +16 -18
  300. package/dist/index.js +16 -36
  301. package/dist/index.js.map +1 -1
  302. package/dist/util/ArrayUtil.d.ts +2 -2
  303. package/dist/util/ArrayUtil.js +16 -21
  304. package/dist/util/ArrayUtil.js.map +1 -1
  305. package/package.json +66 -65
  306. package/dist/Actions/ActionType.d.ts +0 -3
  307. package/dist/Actions/ActionType.js +0 -8
  308. package/dist/Actions/ActionType.js.map +0 -1
  309. package/dist/Scoring/ScoringDescription.d.ts +0 -8
  310. package/dist/Scoring/ScoringDescription.js +0 -3
  311. package/dist/Scoring/ScoringDescription.js.map +0 -1
  312. package/dist/Scoring/index.d.ts +0 -1
  313. package/dist/Scoring/index.js +0 -18
  314. package/dist/Scoring/index.js.map +0 -1
  315. package/dist/util/TimeUtil.d.ts +0 -2
  316. package/dist/util/TimeUtil.js +0 -27
  317. package/dist/util/TimeUtil.js.map +0 -1
@@ -1,541 +1,443 @@
1
- "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- return new (P || (P = Promise))(function (resolve, reject) {
16
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
- step((generator = generator.apply(thisArg, _arguments || [])).next());
20
- });
21
- };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
- }
48
- };
49
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
50
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
51
- if (ar || !(i in from)) {
52
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
53
- ar[i] = from[i];
54
- }
55
- }
56
- return to.concat(ar || Array.prototype.slice.call(from));
57
- };
58
- var __importDefault = (this && this.__importDefault) || function (mod) {
59
- return (mod && mod.__esModule) ? mod : { "default": mod };
60
- };
61
- Object.defineProperty(exports, "__esModule", { value: true });
62
- exports.GameLocalAPI = void 0;
63
- var rules_api_1 = require("@gamepark/rules-api");
64
- var assert_1 = __importDefault(require("assert"));
65
- var Actions_1 = require("../../Actions");
66
- var Failure_1 = require("../../Failure");
67
- var Types_1 = require("../../Types");
68
- var ArrayUtil_1 = require("../../util/ArrayUtil");
69
- var GameLocalAPI = (function () {
70
- function GameLocalAPI(_a) {
71
- var Rules = _a.Rules, ServerRules = _a.ServerRules, GameSetup = _a.GameSetup, ai = _a.ai, game = _a.game, storage = _a.storage, optionsSpec = _a.optionsSpec, tutorial = _a.tutorial;
72
- this.lastActionId = 0;
73
- this.notificationsCount = 0;
74
- this.autoPlayersCounter = 0;
75
- this.aiProcessing = false;
76
- this.tutorialMovesToPlay = 0;
77
- this.storage = storage !== null && storage !== void 0 ? storage : game;
78
- this.Rules = ServerRules !== null && ServerRules !== void 0 ? ServerRules : Rules;
79
- this.gameSetup = new GameSetup();
80
- this.ClientRules = Rules;
81
- this.optionsSpec = optionsSpec;
82
- this.ai = ai;
83
- this.tutorial = tutorial;
84
- }
85
- GameLocalAPI.prototype.init = function (dispatch) {
86
- var _a;
87
- this.dispatch = dispatch;
88
- var animationsSpeed = parseFloat(localStorage.getItem('animationsSpeed') || '1');
89
- this.dispatch((0, Actions_1.setAnimationsSpeed)(animationsSpeed));
90
- var data = this.initLocalStore();
91
- var visibleActions = data.actions.filter(function (action) { return !(0, rules_api_1.isSecretAction)(action) || !action.secrets.some(function (secret) { return secret.recipient === data.playerId; }); });
92
- var notifications = this.getNotifications(data);
93
- this.notificationsCount = notifications.length;
94
- var dataToTransfer = {
95
- myPlayerId: data.playerId, setup: data.setup, state: data.state,
96
- notifications: notifications,
97
- players: data.players, options: (_a = data.options) !== null && _a !== void 0 ? _a : { speed: Types_1.GameSpeed.Disabled, maxSpareTime: 0, maxExceedTime: 0 },
98
- mode: data.tutorial ? Types_1.GameMode.TUTORIAL : Types_1.GameMode.FRIENDLY, notificationsChannel: '', endDate: null, tournament: null
99
- };
100
- var initialGame = new this.Rules(JSON.parse(JSON.stringify(data.setup)));
101
- var rules = new this.Rules(data.state);
102
- var isOver = rules.isOver(data.players.map(function (p) { return p.id; }));
103
- if (isOver) {
104
- dataToTransfer.endDate = new Date();
105
- }
106
- if ((0, rules_api_1.hasHiddenInformation)(initialGame) && !isOver) {
107
- dataToTransfer.setup = verifyNonMutation(function () { return (0, rules_api_1.getGameView)(initialGame, data.playerId); }, function () { return initialGame.game; }, 'getView must not change the game state');
108
- if (visibleActions.length < data.actions.length) {
109
- dataToTransfer.setup = JSON.parse(JSON.stringify(dataToTransfer.setup));
110
- (0, rules_api_1.replayActions)(initialGame, visibleActions);
111
- dataToTransfer.state = verifyNonMutation(function () { return (0, rules_api_1.getGameView)(initialGame, data.playerId); }, function () { return initialGame.game; }, 'getView must not change the game state');
112
- }
113
- else {
114
- if ((0, rules_api_1.hasHiddenInformation)(rules)) {
115
- dataToTransfer.state = verifyNonMutation(function () { return (0, rules_api_1.getGameView)(rules, data.playerId); }, function () { return rules.game; }, 'getView must not change the game state');
116
- }
117
- }
118
- }
119
- mimicDataTransfer(dataToTransfer).then(function (gameData) { return dispatch((0, Actions_1.gameStateLoaded)(gameData)); });
120
- };
121
- GameLocalAPI.prototype.initLocalStore = function () {
122
- var _a;
123
- var localStore = localStorage.getItem(this.storage);
124
- if (localStore) {
125
- var data = JSON.parse(localStore);
126
- if (process.env.NODE_ENV !== 'development' && this.tutorial && !data.tutorial) {
127
- return this.newTutorial();
128
- }
129
- if (((_a = this.tutorial) === null || _a === void 0 ? void 0 : _a.version) && data.tutorial && data.tutorial !== this.tutorial.version) {
130
- return this.newTutorial();
131
- }
132
- if (data.actions.length > 0 && !data.actions[0].id) {
133
- data.actions.forEach(function (action, index) {
134
- if (!action.id)
135
- action.id = index.toString();
136
- });
137
- localStorage.setItem(this.storage, JSON.stringify(data));
138
- }
139
- if (data.actions.length > 0) {
140
- var lastActionId = parseInt(data.actions[data.actions.length - 1].id);
141
- if (!isNaN(lastActionId)) {
142
- this.lastActionId = lastActionId;
143
- }
144
- }
145
- return data;
146
- }
147
- else {
148
- return this.tutorial ? this.newTutorial() : this.newGame();
149
- }
150
- };
151
- GameLocalAPI.prototype.getNotifications = function (data) {
152
- var rules = new this.Rules(JSON.parse(JSON.stringify(data.setup)));
153
- var actions = data.actions.filter(function (action) { return !(0, rules_api_1.isSecretAction)(action) || !action.secrets.some(function (secret) { return secret.recipient === data.playerId; }); });
154
- if ((0, rules_api_1.hasHiddenInformation)(rules) && !new this.Rules(data.state).isOver(data.players.map(function (p) { return p.id; }))) {
155
- var clientGame = new this.ClientRules(JSON.parse(JSON.stringify((0, rules_api_1.getGameView)(rules, data.playerId))), { player: data.playerId });
156
- var notifications = [];
157
- var _loop_1 = function (action) {
158
- var moveView = verifyNonMutation(function () { return (0, rules_api_1.getMoveView)(rules, JSON.parse(JSON.stringify(action.move)), data.playerId); }, function () { return rules.game; }, 'getMoveView must not change the state of the game');
159
- clientGame.play(JSON.parse(JSON.stringify(moveView)));
160
- rules.play(JSON.parse(JSON.stringify(action.move)));
161
- var consequences = [];
162
- var _loop_2 = function (move) {
163
- var moveView_1 = verifyNonMutation(function () { return (0, rules_api_1.getMoveView)(rules, JSON.parse(JSON.stringify(move)), data.playerId); }, function () { return rules.game; }, 'getMoveView must not change the state of the game');
164
- consequences.push(moveView_1);
165
- clientGame.play(JSON.parse(JSON.stringify(moveView_1)));
166
- rules.play(JSON.parse(JSON.stringify(move)));
167
- };
168
- for (var _a = 0, _b = action.consequences; _a < _b.length; _a++) {
169
- var move = _b[_a];
170
- _loop_2(move);
171
- }
172
- notifications.push((0, Types_1.movePlayedNotification)(__assign(__assign({}, action), { move: moveView, consequences: consequences })));
173
- };
174
- for (var _i = 0, actions_1 = actions; _i < actions_1.length; _i++) {
175
- var action = actions_1[_i];
176
- _loop_1(action);
177
- }
178
- var serverGameView = JSON.parse(JSON.stringify((0, rules_api_1.getGameView)(rules, data.playerId)), function (_, value) { return sortObjectKeys(value); });
179
- var clientGameView = JSON.parse(JSON.stringify(clientGame.game), function (_, value) { return sortObjectKeys(value); });
180
- try {
181
- assert_1.default.deepStrictEqual(serverGameView, clientGameView);
182
- }
183
- catch (e) {
184
- console.error('Something is wrong with rules.getView or rules.getMoveView implementation: the view is not the same when moveViews are applied');
185
- console.error('Game view when moves are applied then getView is executed:', serverGameView);
186
- console.error('Game view when moves views are applied from the setup state:', clientGameView);
187
- console.error('If not fixed, there can be bugs especially with the UNDO features.');
188
- }
189
- return notifications;
190
- }
191
- else {
192
- return actions.map(function (action) { return (0, Types_1.movePlayedNotification)(action); });
193
- }
194
- };
195
- GameLocalAPI.prototype.newTutorial = function () {
196
- var _a;
197
- if (!this.tutorial) {
198
- throw new Error('Pass a Tutorial in the options of createGameStore first');
199
- }
200
- var _b = this.tutorial.setupTutorial(), state = _b[0], players = _b[1];
201
- return this.initGameStore(state, players, (_a = this.tutorial.version) !== null && _a !== void 0 ? _a : 1);
202
- };
203
- GameLocalAPI.prototype.getGameOptions = function (arg) {
204
- if (arg === void 0) { arg = 2; }
205
- var options = typeof arg === 'object' ? arg : { players: typeof arg === 'number' ? arg : 2 };
206
- if (typeof options.players !== 'number' && !Array.isArray(options.players))
207
- options.players = 2;
208
- if (this.optionsSpec && (0, rules_api_1.isWithPlayerOptions)(this.optionsSpec)) {
209
- if (typeof options.players === 'number') {
210
- options.players = __spreadArray([], Array(options.players), true).map(function () { return ({}); });
211
- }
212
- else {
213
- for (var i = 0; i < options.players.length; i++) {
214
- if (typeof options.players[i] !== 'object')
215
- options.players[i] = {};
216
- }
217
- }
218
- var _loop_3 = function (option) {
219
- var playerOptionValue = this_1.optionsSpec.players[option];
220
- var optionValues = (0, rules_api_1.generatePlayersOption)(options.players.map(function (p) { var _a; return (_a = p[option]) !== null && _a !== void 0 ? _a : null; }), playerOptionValue);
221
- for (var i = 0; i < options.players.length; i++) {
222
- options.players[i][option] = optionValues[i];
223
- }
224
- };
225
- var this_1 = this;
226
- for (var option in this.optionsSpec.players) {
227
- _loop_3(option);
228
- }
229
- }
230
- return options;
231
- };
232
- GameLocalAPI.prototype.newGame = function (arg) {
233
- if (arg === void 0) { arg = 2; }
234
- var options = this.getGameOptions(arg);
235
- var playerIds = this.optionsSpec && (0, rules_api_1.isWithPlayerIdOptions)(this.optionsSpec) ?
236
- options.players.map(function (player) { return player.id; })
237
- : (Array.isArray(options.players) ? options.players : __spreadArray([], Array(options.players), true)).map(function (_, index) { return index + 1; });
238
- var players = playerIds.map(function (id) { return ({ id: id }); });
239
- return this.initGameStore(this.gameSetup.setup(options), players);
240
- };
241
- GameLocalAPI.prototype.initGameStore = function (game, players, tutorial) {
242
- var rules = new this.Rules(game);
243
- var playerId = players[0].id;
244
- (0, rules_api_1.applyAutomaticMoves)(rules);
245
- var setup = JSON.parse(JSON.stringify(rules.game));
246
- var localStore = { players: players, setup: setup, state: rules.game, actions: [], playerId: playerId, monkeyOpponents: !!tutorial, tutorial: tutorial };
247
- localStorage.setItem(this.storage, JSON.stringify(localStore));
248
- return localStore;
249
- };
250
- GameLocalAPI.prototype.getLocalStore = function () {
251
- return JSON.parse(localStorage.getItem(this.storage));
252
- };
253
- GameLocalAPI.prototype.play = function (move) {
254
- var _this = this;
255
- return mimicDataTransfer(move).then(function (move) {
256
- var _a;
257
- var localStore = _this.getLocalStore();
258
- var rules = new _this.Rules(localStore.state);
259
- if (!verifyNonMutation(function () { return rules.isLegalMove(localStore.playerId, move); }, function () { return rules.game; }, 'isLegalMove and getLegalMoves must not change the game state')) {
260
- console.error('This move is not authorized right now: ' + JSON.stringify(move));
261
- if (_this.tutorial) {
262
- (_a = _this.dispatch) === null || _a === void 0 ? void 0 : _a.call(_this, (0, Actions_1.actionFailed)(Failure_1.Failure.TUTORIAL_MOVE_EXPECTED));
263
- }
264
- if (rules.getLegalMoves) {
265
- console.info('Legal moves are:', rules.getLegalMoves(localStore.playerId));
266
- }
267
- return;
268
- }
269
- _this.autoPlayersCounter = 0;
270
- _this.playActions(localStore.playerId, [move]);
271
- }).catch(function (error) {
272
- console.error('The move could not be applied due to this error:', error);
273
- throw error;
274
- });
275
- };
276
- GameLocalAPI.prototype.playActions = function (playerId, moves) {
277
- var _a;
278
- var _this = this;
279
- var _b, _c;
280
- var localStore = this.getLocalStore();
281
- var game = new this.Rules(localStore.state);
282
- var actions = [];
283
- var notifications = [];
284
- if ((0, rules_api_1.hasHiddenInformation)(game)) {
285
- for (var _i = 0, moves_1 = moves; _i < moves_1.length; _i++) {
286
- var move = moves_1[_i];
287
- var recipients = (0, rules_api_1.hasSecretInformation)(game) && game.getPlayerMoveView ? localStore.players.map(function (player) { return player.id; }) : [];
288
- var id = (++this.lastActionId).toString();
289
- var _d = (0, rules_api_1.playActionWithViews)(game, move, playerId, recipients, id), action = _d.action, views = _d.views;
290
- if ((0, rules_api_1.hasSecretInformation)(game) && game.keepMoveSecret) {
291
- var _loop_4 = function (secretAction) {
292
- var secretToPlayer = secretAction.secrets.find(function (secret) { return secret.recipient === localStore.playerId; });
293
- if (secretToPlayer && !game.keepMoveSecret(secretAction.move, localStore.playerId)) {
294
- notifications.push((0, Types_1.movePlayedNotification)(secretToPlayer.action));
295
- }
296
- secretAction.secrets = secretAction.secrets.filter(function (secret) { return secret.recipient === undefined || game.keepMoveSecret(secretAction.move, secret.recipient); });
297
- if (secretAction.secrets.length === 1) {
298
- delete secretAction.secrets;
299
- }
300
- };
301
- for (var _e = 0, _f = localStore.actions.filter(rules_api_1.isSecretAction); _e < _f.length; _e++) {
302
- var secretAction = _f[_e];
303
- _loop_4(secretAction);
304
- }
305
- var secrets = [];
306
- var _loop_5 = function (player) {
307
- var view = (_b = views.find(function (view) { return view.recipient === player.id; })) !== null && _b !== void 0 ? _b : views.find(function (view) { return !view.recipient; });
308
- if (player.id !== playerId && game.keepMoveSecret(move, player.id)) {
309
- secrets.push({ recipient: player.id, action: view.action });
310
- }
311
- else if (player.id === localStore.playerId) {
312
- notifications.push((0, Types_1.movePlayedNotification)(view.action));
313
- }
314
- };
315
- for (var _g = 0, _h = localStore.players; _g < _h.length; _g++) {
316
- var player = _h[_g];
317
- _loop_5(player);
318
- }
319
- var spectatorView = views.find(function (view) { return view.recipient === undefined; });
320
- if (secrets.length) {
321
- action.secrets = secrets;
322
- secrets.push(spectatorView);
323
- }
324
- else if (localStore.playerId === undefined) {
325
- notifications.push((0, Types_1.movePlayedNotification)(spectatorView.action));
326
- }
327
- }
328
- else {
329
- var view = (_c = views.find(function (view) { return view.recipient === localStore.playerId; })) !== null && _c !== void 0 ? _c : views.find(function (view) { return !view.recipient; });
330
- notifications.push((0, Types_1.movePlayedNotification)(view.action));
331
- }
332
- actions.push(action);
333
- }
334
- }
335
- else {
336
- for (var _j = 0, moves_2 = moves; _j < moves_2.length; _j++) {
337
- var move = moves_2[_j];
338
- var id = (++this.lastActionId).toString();
339
- var action = (0, rules_api_1.playAction)(game, move, playerId);
340
- action.id = id;
341
- actions.push(action);
342
- notifications.push((0, Types_1.movePlayedNotification)(action));
343
- }
344
- }
345
- var index = this.incrementNotificationsCount(notifications.length);
346
- mimicDataTransfer({ notifications: notifications, index: index }, { sizeWarn: 9000 }).then(function (data) {
347
- return _this.dispatch((0, Actions_1.gameNotificationsReceived)(data.notifications, data.index, localStore.players));
348
- });
349
- (_a = localStore.actions).push.apply(_a, actions);
350
- localStorage.setItem(this.storage, JSON.stringify(localStore));
351
- setTimeout(function () { return _this.runAutoPlayers(); }, 100 + Math.random() * 100);
352
- };
353
- GameLocalAPI.prototype.incrementNotificationsCount = function (quantity) {
354
- if (quantity === void 0) { quantity = 1; }
355
- var previousValue = this.notificationsCount;
356
- this.notificationsCount += quantity;
357
- return previousValue;
358
- };
359
- GameLocalAPI.prototype.undo = function (arg, ignoreRules) {
360
- var _this = this;
361
- if (arg === void 0) { arg = 1; }
362
- if (typeof arg === 'string') {
363
- mimicDataTransfer(arg).then(function (actionId) {
364
- var localStore = _this.getLocalStore();
365
- var index = (0, ArrayUtil_1.findLastIndex)(localStore.actions, function (action) { return action.id === actionId; });
366
- if (index === -1)
367
- return;
368
- var action = localStore.actions[index];
369
- if (!ignoreRules) {
370
- var game = new _this.Rules(localStore.state);
371
- if (!(0, rules_api_1.hasUndo)(game))
372
- return console.error('This game does not have UNDO feature');
373
- if (!game.canUndo(action, localStore.actions.slice(index + 1)))
374
- return console.error('Trying to UNDO a move while it is forbidden');
375
- }
376
- localStore.actions.splice(index, 1);
377
- var rules = new _this.Rules(JSON.parse(JSON.stringify(localStore.setup)));
378
- (0, rules_api_1.replayActions)(rules, localStore.actions);
379
- localStore.state = rules.game;
380
- localStorage.setItem(_this.storage, JSON.stringify(localStore));
381
- if (!(0, rules_api_1.isSecretAction)(action) || !action.secrets.some(function (secret) { return secret.recipient === localStore.playerId; })) {
382
- mimicDataTransfer({ notification: (0, Types_1.moveUndoneNotification)(action, index), index: _this.incrementNotificationsCount() }).then(function (data) {
383
- return _this.dispatch((0, Actions_1.gameNotificationsReceived)([data.notification], data.index, localStore.players));
384
- });
385
- }
386
- });
387
- }
388
- else if (arg > 0) {
389
- var actions = this.getLocalStore().actions;
390
- if (!actions.length)
391
- return console.warn('Cannot undo, no actions were played yet');
392
- for (var i = actions.length - 1; i > actions.length - 1 - arg; i--) {
393
- this.undo(actions[i].id, true);
394
- }
395
- }
396
- };
397
- GameLocalAPI.prototype.startBots = function () {
398
- var localStore = this.getLocalStore();
399
- localStore.monkeyOpponents = true;
400
- localStorage.setItem(this.storage, JSON.stringify(localStore));
401
- this.autoPlayersCounter = 0;
402
- this.runAutoPlayers();
403
- };
404
- GameLocalAPI.prototype.stopBots = function () {
405
- var localStore = this.getLocalStore();
406
- localStore.monkeyOpponents = false;
407
- localStorage.setItem(this.storage, JSON.stringify(localStore));
408
- };
409
- GameLocalAPI.prototype.runAutoPlayers = function () {
410
- var _a;
411
- return __awaiter(this, void 0, void 0, function () {
412
- var localStore, rules, nextExpectedMove, expectedMoves, expectedMove_1, player, player, moves;
413
- return __generator(this, function (_b) {
414
- switch (_b.label) {
415
- case 0:
416
- if (this.autoPlayersCounter > 100) {
417
- console.warn('The automatic players played 100 times. There might be an infinite loop, stopping now.');
418
- return [2];
419
- }
420
- localStore = this.getLocalStore();
421
- rules = new this.Rules(localStore.state);
422
- if (rules.isOver(localStore.players.map(function (player) { return player.id; }))) {
423
- console.info('Game is over');
424
- (_a = this.dispatch) === null || _a === void 0 ? void 0 : _a.call(this, (0, Actions_1.gameOver)([]));
425
- return [2];
426
- }
427
- if (localStore.tutorial && this.tutorial) {
428
- if (!this.tutorialMovesToPlay)
429
- return [2];
430
- nextExpectedMove = this.tutorial.getNextMove(rules, localStore.actions.length);
431
- if (nextExpectedMove) {
432
- expectedMoves = Array.isArray(nextExpectedMove) ? nextExpectedMove : [nextExpectedMove];
433
- if (expectedMoves.some(function (expectedMove) { return rules.isLegalMove(localStore.playerId, expectedMove); })) {
434
- if (this.tutorialMovesToPlay !== Infinity) {
435
- this.tutorialMovesToPlay = 0;
436
- }
437
- return [2];
438
- }
439
- expectedMove_1 = expectedMoves[0];
440
- player = localStore.players.find(function (player) { return rules.isLegalMove(player.id, expectedMove_1); });
441
- if (player) {
442
- this.tutorialMovesToPlay--;
443
- return [2, this.playActions(player.id, [expectedMove_1])];
444
- }
445
- else {
446
- console.error('Tutorial expects a move that no player can play: ', expectedMove_1);
447
- }
448
- }
449
- }
450
- if (!(localStore.monkeyOpponents && !this.aiProcessing)) return [3, 3];
451
- player = localStore.players.find(function (player) { return player.id !== localStore.playerId && rules.isTurnToPlay(player.id); });
452
- if (!player) return [3, 2];
453
- this.aiProcessing = true;
454
- return [4, this.getAI(player.id)(rules.game, player.id)];
455
- case 1:
456
- moves = _b.sent();
457
- this.aiProcessing = false;
458
- if (moves.length) {
459
- this.playActions(player.id, moves);
460
- this.autoPlayersCounter++;
461
- }
462
- else {
463
- console.error("Player ".concat(player.id, " is active but did not return any move to play!"));
464
- }
465
- return [3, 3];
466
- case 2:
467
- if (localStore.playerId === undefined || !rules.isTurnToPlay(localStore.playerId)) {
468
- console.error('Game is not over but there is no active player!');
469
- }
470
- _b.label = 3;
471
- case 3: return [2];
472
- }
473
- });
474
- });
475
- };
476
- GameLocalAPI.prototype.getAI = function (playerId) {
477
- if (this.ai)
478
- return this.ai;
479
- var bot = new rules_api_1.RandomBot(this.Rules, playerId);
480
- return function (game) { return Promise.resolve(bot.run(game)); };
481
- };
482
- GameLocalAPI.prototype.setPlayerName = function (name, playerId) {
483
- var localStore = this.getLocalStore();
484
- var player = localStore.players.find(function (player) { return player.id === (playerId || localStore.playerId); });
485
- if (!player) {
486
- throw new Error('Player not found');
487
- }
488
- player.name = name;
489
- localStorage.setItem(this.storage, JSON.stringify(localStore));
490
- };
491
- GameLocalAPI.prototype.setAnimationsSpeed = function (speed) {
492
- if (speed === void 0) { speed = 1; }
493
- this.dispatch((0, Actions_1.setAnimationsSpeed)(speed));
494
- localStorage.setItem('animationsSpeed', speed.toString());
495
- };
496
- GameLocalAPI.prototype.eject = function () {
497
- };
498
- GameLocalAPI.prototype.giveUp = function () {
499
- };
500
- GameLocalAPI.prototype.playTutorialMoves = function (quantity) {
501
- var _this = this;
502
- if (quantity) {
503
- this.tutorialMovesToPlay += quantity;
504
- this.autoPlayersCounter = 0;
505
- setTimeout(function () { return _this.runAutoPlayers(); }, 100 + Math.random() * 100);
506
- }
507
- else {
508
- this.tutorialMovesToPlay = 0;
509
- }
510
- };
511
- return GameLocalAPI;
512
- }());
513
- exports.GameLocalAPI = GameLocalAPI;
514
- function mimicDataTransfer(data, options) {
515
- if (options === void 0) { options = {}; }
516
- var _a = options.sizeWarn, sizeWarn = _a === void 0 ? 0 : _a, _b = options.duration, duration = _b === void 0 ? 100 : _b;
517
- var stringData = JSON.stringify(data !== null && data !== void 0 ? data : null);
518
- data = JSON.parse(stringData);
519
- if (sizeWarn && stringData) {
520
- if (stringData.length > sizeWarn) {
521
- console.warn("Notification payload of ".concat(stringData.length, " bytes exceeds ").concat(sizeWarn, " bytes, which can cause extra http requests."), stringData);
522
- }
523
- }
524
- return new Promise(function (resolve) { return setTimeout(function () { return resolve(data); }, duration); });
525
- }
526
- function verifyNonMutation(operation, getState, message) {
527
- var initialState = JSON.stringify(getState());
528
- var result = operation();
529
- var finalState = JSON.stringify(getState());
530
- (0, assert_1.default)(initialState === finalState, message);
531
- return result;
532
- }
533
- function sortObjectKeys(value) {
534
- if (typeof value !== 'object' || value === null)
535
- return value;
536
- return Object.keys(value).sort().reduce(function (obj, key) {
537
- obj[key] = value[key];
538
- return obj;
539
- }, {});
540
- }
1
+ import { applyAutomaticMoves, generatePlayersOption, getGameView, getMoveView, hasHiddenInformation, hasSecretInformation, hasUndo, isSecretAction, isWithPlayerIdOptions, isWithPlayerOptions, playAction, playActionWithViews, RandomBot, replayActions } from '@gamepark/rules-api';
2
+ import assert from 'assert';
3
+ import { receiveNotifications, setAnimationsSpeed, setGameOver } from '../../Actions';
4
+ import { loadGameState } from '../../Actions/loadGameState';
5
+ import { reportFailure } from '../../Actions/reportFailure';
6
+ import { Failure } from '../../Failure';
7
+ import { GameMode, GameSpeed, movePlayedNotification, moveUndoneNotification } from '../../Types';
8
+ import { findLastIndex } from '../../util/ArrayUtil';
9
+ export class GameLocalAPI {
10
+ storage;
11
+ gameSetup;
12
+ Rules;
13
+ ClientRules;
14
+ optionsSpec;
15
+ ai;
16
+ tutorial;
17
+ dispatch;
18
+ lastActionId = 0;
19
+ notificationsCount = 0;
20
+ autoPlayersCounter = 0;
21
+ aiProcessing = false;
22
+ tutorialMovesToPlay = 0;
23
+ constructor({ Rules, ServerRules, GameSetup, ai, game, storage, optionsSpec, tutorial }) {
24
+ this.storage = storage ?? game;
25
+ this.Rules = ServerRules ?? Rules;
26
+ this.gameSetup = new GameSetup();
27
+ this.ClientRules = Rules;
28
+ this.optionsSpec = optionsSpec;
29
+ this.ai = ai;
30
+ this.tutorial = tutorial;
31
+ }
32
+ init(dispatch) {
33
+ this.dispatch = dispatch;
34
+ const animationsSpeed = parseFloat(localStorage.getItem('animationsSpeed') || '1');
35
+ this.dispatch(setAnimationsSpeed(animationsSpeed));
36
+ const data = this.initLocalStore();
37
+ const visibleActions = data.actions.filter(action => !isSecretAction(action) || !action.secrets.some(secret => secret.recipient === data.playerId));
38
+ const notifications = this.getNotifications(data);
39
+ this.notificationsCount = notifications.length;
40
+ const dataToTransfer = {
41
+ myPlayerId: data.playerId, setup: data.setup, state: data.state, notifications,
42
+ players: data.players, options: data.options ?? { speed: GameSpeed.Disabled, maxSpareTime: 0, maxExceedTime: 0 },
43
+ mode: data.tutorial ? GameMode.TUTORIAL : GameMode.FRIENDLY, notificationsChannel: '', endDate: null, tournament: null
44
+ };
45
+ const initialGame = new this.Rules(JSON.parse(JSON.stringify(data.setup)));
46
+ const rules = new this.Rules(data.state);
47
+ const isOver = rules.isOver(data.players.map(p => p.id));
48
+ if (isOver) {
49
+ dataToTransfer.endDate = new Date();
50
+ }
51
+ if (hasHiddenInformation(initialGame) && !isOver) {
52
+ dataToTransfer.setup = verifyNonMutation(() => getGameView(initialGame, data.playerId), () => initialGame.game, 'getView must not change the game state');
53
+ if (visibleActions.length < data.actions.length) {
54
+ dataToTransfer.setup = JSON.parse(JSON.stringify(dataToTransfer.setup));
55
+ replayActions(initialGame, visibleActions);
56
+ dataToTransfer.state = verifyNonMutation(() => getGameView(initialGame, data.playerId), () => initialGame.game, 'getView must not change the game state');
57
+ }
58
+ else {
59
+ if (hasHiddenInformation(rules)) {
60
+ dataToTransfer.state = verifyNonMutation(() => getGameView(rules, data.playerId), () => rules.game, 'getView must not change the game state');
61
+ }
62
+ }
63
+ }
64
+ mimicDataTransfer(dataToTransfer).then(gameData => this.dispatch(loadGameState({
65
+ ...(gameData), playerId: gameData.myPlayerId ?? undefined, serverTime: undefined, endDate: gameData.endDate ?? undefined,
66
+ tournament: gameData.tournament ?? undefined
67
+ })));
68
+ }
69
+ initLocalStore() {
70
+ const localStore = localStorage.getItem(this.storage);
71
+ if (localStore) {
72
+ const data = JSON.parse(localStore);
73
+ if (process.env.NODE_ENV !== 'development' && this.tutorial && !data.tutorial) {
74
+ return this.newTutorial();
75
+ }
76
+ if (this.tutorial?.version && data.tutorial && data.tutorial !== this.tutorial.version) {
77
+ return this.newTutorial();
78
+ }
79
+ if (data.actions.length > 0 && !data.actions[0].id) {
80
+ data.actions.forEach((action, index) => {
81
+ if (!action.id)
82
+ action.id = index.toString();
83
+ });
84
+ localStorage.setItem(this.storage, JSON.stringify(data));
85
+ }
86
+ if (data.actions.length > 0) {
87
+ const lastActionId = parseInt(data.actions[data.actions.length - 1].id);
88
+ if (!isNaN(lastActionId)) {
89
+ this.lastActionId = lastActionId;
90
+ }
91
+ }
92
+ return data;
93
+ }
94
+ else {
95
+ return this.tutorial ? this.newTutorial() : this.newGame();
96
+ }
97
+ }
98
+ getNotifications(data) {
99
+ const rules = new this.Rules(JSON.parse(JSON.stringify(data.setup)));
100
+ const actions = data.actions.filter(action => !isSecretAction(action) || !action.secrets.some(secret => secret.recipient === data.playerId));
101
+ if (hasHiddenInformation(rules) && !new this.Rules(data.state).isOver(data.players.map(p => p.id))) {
102
+ const clientGame = new this.ClientRules(JSON.parse(JSON.stringify(getGameView(rules, data.playerId))), { player: data.playerId });
103
+ const notifications = [];
104
+ for (const action of actions) {
105
+ const moveView = verifyNonMutation(() => getMoveView(rules, JSON.parse(JSON.stringify(action.move)), data.playerId), () => rules.game, 'getMoveView must not change the state of the game');
106
+ clientGame.play(JSON.parse(JSON.stringify(moveView)));
107
+ rules.play(JSON.parse(JSON.stringify(action.move)));
108
+ const consequences = [];
109
+ for (const move of action.consequences) {
110
+ const moveView = verifyNonMutation(() => getMoveView(rules, JSON.parse(JSON.stringify(move)), data.playerId), () => rules.game, 'getMoveView must not change the state of the game');
111
+ consequences.push(moveView);
112
+ clientGame.play(JSON.parse(JSON.stringify(moveView)));
113
+ rules.play(JSON.parse(JSON.stringify(move)));
114
+ }
115
+ notifications.push(movePlayedNotification({ ...action, move: moveView, consequences }));
116
+ }
117
+ const serverGameView = JSON.parse(JSON.stringify(getGameView(rules, data.playerId)), (_, value) => sortObjectKeys(value));
118
+ const clientGameView = JSON.parse(JSON.stringify(clientGame.game), (_, value) => sortObjectKeys(value));
119
+ try {
120
+ assert.deepStrictEqual(serverGameView, clientGameView);
121
+ }
122
+ catch (e) {
123
+ console.error('Something is wrong with rules.getView or rules.getMoveView implementation: the view is not the same when moveViews are applied');
124
+ console.error('Game view when moves are applied then getView is executed:', serverGameView);
125
+ console.error('Game view when moves views are applied from the setup state:', clientGameView);
126
+ console.error('If not fixed, there can be bugs especially with the UNDO features.');
127
+ }
128
+ return notifications;
129
+ }
130
+ else {
131
+ return actions.map(action => movePlayedNotification(action));
132
+ }
133
+ }
134
+ newTutorial() {
135
+ if (!this.tutorial) {
136
+ throw new Error('Pass a Tutorial in the options of createGameStore first');
137
+ }
138
+ const [state, players] = this.tutorial.setupTutorial();
139
+ return this.initGameStore(state, players, this.tutorial.version ?? 1);
140
+ }
141
+ getGameOptions(arg = 2) {
142
+ const options = typeof arg === 'object' ? arg : { players: typeof arg === 'number' ? arg : 2 };
143
+ if (typeof options.players !== 'number' && !Array.isArray(options.players))
144
+ options.players = 2;
145
+ if (this.optionsSpec && isWithPlayerOptions(this.optionsSpec)) {
146
+ if (typeof options.players === 'number') {
147
+ options.players = [...Array(options.players)].map(() => ({}));
148
+ }
149
+ else {
150
+ for (let i = 0; i < options.players.length; i++) {
151
+ if (typeof options.players[i] !== 'object')
152
+ options.players[i] = {};
153
+ }
154
+ }
155
+ for (const option in this.optionsSpec.players) {
156
+ const playerOptionValue = this.optionsSpec.players[option];
157
+ const optionValues = generatePlayersOption(options.players.map((p) => p[option] ?? null), playerOptionValue);
158
+ for (let i = 0; i < options.players.length; i++) {
159
+ options.players[i][option] = optionValues[i];
160
+ }
161
+ }
162
+ }
163
+ return options;
164
+ }
165
+ newGame(arg = 2) {
166
+ const options = this.getGameOptions(arg);
167
+ const playerIds = this.optionsSpec && isWithPlayerIdOptions(this.optionsSpec) ?
168
+ options.players.map((player) => player.id)
169
+ : (Array.isArray(options.players) ? options.players : [...Array(options.players)]).map((_, index) => index + 1);
170
+ const players = playerIds.map(id => ({ id }));
171
+ return this.initGameStore(this.gameSetup.setup(options), players);
172
+ }
173
+ initGameStore(game, players, tutorial) {
174
+ const rules = new this.Rules(game);
175
+ const playerId = players[0].id;
176
+ applyAutomaticMoves(rules);
177
+ const setup = JSON.parse(JSON.stringify(rules.game));
178
+ const localStore = { players, setup, state: rules.game, actions: [], playerId, monkeyOpponents: !!tutorial, tutorial };
179
+ localStorage.setItem(this.storage, JSON.stringify(localStore));
180
+ return localStore;
181
+ }
182
+ getLocalStore() {
183
+ return JSON.parse(localStorage.getItem(this.storage));
184
+ }
185
+ play(move) {
186
+ return mimicDataTransfer(move).then(move => {
187
+ const localStore = this.getLocalStore();
188
+ const rules = new this.Rules(localStore.state);
189
+ if (!verifyNonMutation(() => rules.isLegalMove(localStore.playerId, move), () => rules.game, 'isLegalMove and getLegalMoves must not change the game state')) {
190
+ console.error('This move is not authorized right now: ' + JSON.stringify(move));
191
+ if (this.tutorial) {
192
+ this.dispatch?.(reportFailure(Failure.TUTORIAL_MOVE_EXPECTED));
193
+ }
194
+ if (rules.getLegalMoves) {
195
+ console.info('Legal moves are:', rules.getLegalMoves(localStore.playerId));
196
+ }
197
+ return;
198
+ }
199
+ this.autoPlayersCounter = 0;
200
+ this.playActions(localStore.playerId, [move]);
201
+ }).catch(error => {
202
+ console.error('The move could not be applied due to this error:', error);
203
+ throw error;
204
+ });
205
+ }
206
+ playActions(playerId, moves) {
207
+ const localStore = this.getLocalStore();
208
+ const game = new this.Rules(localStore.state);
209
+ const actions = [];
210
+ const notifications = [];
211
+ if (hasHiddenInformation(game)) {
212
+ for (const move of moves) {
213
+ const recipients = hasSecretInformation(game) && game.getPlayerMoveView ? localStore.players.map(player => player.id) : [];
214
+ const id = (++this.lastActionId).toString();
215
+ const { action, views } = playActionWithViews(game, move, playerId, recipients, id);
216
+ if (hasSecretInformation(game) && game.keepMoveSecret) {
217
+ for (const secretAction of localStore.actions.filter(isSecretAction)) {
218
+ const secretToPlayer = secretAction.secrets.find(secret => secret.recipient === localStore.playerId);
219
+ if (secretToPlayer && !game.keepMoveSecret(secretAction.move, localStore.playerId)) {
220
+ notifications.push(movePlayedNotification(secretToPlayer.action));
221
+ }
222
+ secretAction.secrets = secretAction.secrets.filter(secret => secret.recipient === undefined || game.keepMoveSecret(secretAction.move, secret.recipient));
223
+ if (secretAction.secrets.length === 1) {
224
+ delete secretAction.secrets;
225
+ }
226
+ }
227
+ const secrets = [];
228
+ for (const player of localStore.players) {
229
+ const view = views.find(view => view.recipient === player.id) ?? views.find(view => !view.recipient);
230
+ if (player.id !== playerId && game.keepMoveSecret(move, player.id)) {
231
+ secrets.push({ recipient: player.id, action: view.action });
232
+ }
233
+ else if (player.id === localStore.playerId) {
234
+ notifications.push(movePlayedNotification(view.action));
235
+ }
236
+ }
237
+ const spectatorView = views.find(view => view.recipient === undefined);
238
+ if (secrets.length) {
239
+ action.secrets = secrets;
240
+ secrets.push(spectatorView);
241
+ }
242
+ else if (localStore.playerId === undefined) {
243
+ notifications.push(movePlayedNotification(spectatorView.action));
244
+ }
245
+ }
246
+ else {
247
+ const view = views.find(view => view.recipient === localStore.playerId) ?? views.find(view => !view.recipient);
248
+ notifications.push(movePlayedNotification(view.action));
249
+ }
250
+ actions.push(action);
251
+ }
252
+ }
253
+ else {
254
+ for (const move of moves) {
255
+ const id = (++this.lastActionId).toString();
256
+ const action = playAction(game, move, playerId);
257
+ action.id = id;
258
+ actions.push(action);
259
+ notifications.push(movePlayedNotification(action));
260
+ }
261
+ }
262
+ const index = this.incrementNotificationsCount(notifications.length);
263
+ mimicDataTransfer({ notifications, index }, { sizeWarn: 9000 }).then(data => this.dispatch(receiveNotifications({
264
+ notifications: data.notifications,
265
+ notificationsIndex: data.index,
266
+ players: localStore.players,
267
+ serverTime: undefined
268
+ })));
269
+ localStore.actions.push(...actions);
270
+ localStorage.setItem(this.storage, JSON.stringify(localStore));
271
+ setTimeout(() => this.runAutoPlayers(), 100 + Math.random() * 100);
272
+ }
273
+ incrementNotificationsCount(quantity = 1) {
274
+ const previousValue = this.notificationsCount;
275
+ this.notificationsCount += quantity;
276
+ return previousValue;
277
+ }
278
+ undo(arg = 1, ignoreRules) {
279
+ if (typeof arg === 'string') {
280
+ mimicDataTransfer(arg).then(actionId => {
281
+ const localStore = this.getLocalStore();
282
+ const index = findLastIndex(localStore.actions, action => action.id === actionId);
283
+ if (index === -1)
284
+ return;
285
+ const action = localStore.actions[index];
286
+ if (!ignoreRules) {
287
+ const game = new this.Rules(localStore.state);
288
+ if (!hasUndo(game))
289
+ return console.error('This game does not have UNDO feature');
290
+ if (!game.canUndo(action, localStore.actions.slice(index + 1)))
291
+ return console.error('Trying to UNDO a move while it is forbidden');
292
+ }
293
+ localStore.actions.splice(index, 1);
294
+ const rules = new this.Rules(JSON.parse(JSON.stringify(localStore.setup)));
295
+ replayActions(rules, localStore.actions);
296
+ localStore.state = rules.game;
297
+ localStorage.setItem(this.storage, JSON.stringify(localStore));
298
+ if (!isSecretAction(action) || !action.secrets.some(secret => secret.recipient === localStore.playerId)) {
299
+ mimicDataTransfer({ notification: moveUndoneNotification(action, index), index: this.incrementNotificationsCount() }).then(data => this.dispatch(receiveNotifications({
300
+ notifications: [data.notification],
301
+ notificationsIndex: data.index,
302
+ players: localStore.players,
303
+ serverTime: undefined
304
+ })));
305
+ }
306
+ });
307
+ }
308
+ else if (arg > 0) {
309
+ const actions = this.getLocalStore().actions;
310
+ if (!actions.length)
311
+ return console.warn('Cannot undo, no actions were played yet');
312
+ for (let i = actions.length - 1; i > actions.length - 1 - arg; i--) {
313
+ this.undo(actions[i].id, true);
314
+ }
315
+ }
316
+ }
317
+ startBots() {
318
+ const localStore = this.getLocalStore();
319
+ localStore.monkeyOpponents = true;
320
+ localStorage.setItem(this.storage, JSON.stringify(localStore));
321
+ this.autoPlayersCounter = 0;
322
+ this.runAutoPlayers();
323
+ }
324
+ stopBots() {
325
+ const localStore = this.getLocalStore();
326
+ localStore.monkeyOpponents = false;
327
+ localStorage.setItem(this.storage, JSON.stringify(localStore));
328
+ }
329
+ async runAutoPlayers() {
330
+ if (this.autoPlayersCounter > 100) {
331
+ console.warn('The automatic players played 100 times. There might be an infinite loop, stopping now.');
332
+ return;
333
+ }
334
+ const localStore = this.getLocalStore();
335
+ const rules = new this.Rules(localStore.state);
336
+ if (rules.isOver(localStore.players.map(player => player.id))) {
337
+ console.info('Game is over');
338
+ this.dispatch?.(setGameOver([]));
339
+ return;
340
+ }
341
+ if (localStore.tutorial && this.tutorial) {
342
+ if (!this.tutorialMovesToPlay)
343
+ return;
344
+ const nextExpectedMove = this.tutorial.getNextMove(rules, localStore.actions.length);
345
+ if (nextExpectedMove) {
346
+ const expectedMoves = Array.isArray(nextExpectedMove) ? nextExpectedMove : [nextExpectedMove];
347
+ if (expectedMoves.some(expectedMove => rules.isLegalMove(localStore.playerId, expectedMove))) {
348
+ if (this.tutorialMovesToPlay !== Infinity) {
349
+ this.tutorialMovesToPlay = 0;
350
+ }
351
+ return;
352
+ }
353
+ const expectedMove = expectedMoves[0];
354
+ const player = localStore.players.find(player => rules.isLegalMove(player.id, expectedMove));
355
+ if (player) {
356
+ this.tutorialMovesToPlay--;
357
+ return this.playActions(player.id, [expectedMove]);
358
+ }
359
+ else {
360
+ console.error('Tutorial expects a move that no player can play: ', expectedMove);
361
+ }
362
+ }
363
+ }
364
+ if (localStore.monkeyOpponents && !this.aiProcessing) {
365
+ const player = localStore.players.find(player => player.id !== localStore.playerId && rules.isTurnToPlay(player.id));
366
+ if (player) {
367
+ this.aiProcessing = true;
368
+ const moves = await this.getAI(player.id)(rules.game, player.id);
369
+ this.aiProcessing = false;
370
+ if (moves.length) {
371
+ this.playActions(player.id, moves);
372
+ this.autoPlayersCounter++;
373
+ }
374
+ else {
375
+ console.error(`Player ${player.id} is active but did not return any move to play!`);
376
+ }
377
+ }
378
+ else if (localStore.playerId === undefined || !rules.isTurnToPlay(localStore.playerId)) {
379
+ console.error('Game is not over but there is no active player!');
380
+ }
381
+ }
382
+ }
383
+ getAI(playerId) {
384
+ if (this.ai)
385
+ return this.ai;
386
+ const bot = new RandomBot(this.Rules, playerId);
387
+ return (game) => Promise.resolve(bot.run(game));
388
+ }
389
+ setPlayerName(name, playerId) {
390
+ const localStore = this.getLocalStore();
391
+ const player = localStore.players.find(player => player.id === (playerId || localStore.playerId));
392
+ if (!player) {
393
+ throw new Error('Player not found');
394
+ }
395
+ player.name = name;
396
+ localStorage.setItem(this.storage, JSON.stringify(localStore));
397
+ }
398
+ setAnimationsSpeed(speed = 1) {
399
+ this.dispatch(setAnimationsSpeed(speed));
400
+ localStorage.setItem('animationsSpeed', speed.toString());
401
+ }
402
+ eject() {
403
+ }
404
+ giveUp() {
405
+ }
406
+ playTutorialMoves(quantity) {
407
+ if (quantity) {
408
+ this.tutorialMovesToPlay += quantity;
409
+ this.autoPlayersCounter = 0;
410
+ setTimeout(() => this.runAutoPlayers(), 100 + Math.random() * 100);
411
+ }
412
+ else {
413
+ this.tutorialMovesToPlay = 0;
414
+ }
415
+ }
416
+ }
417
+ function mimicDataTransfer(data, options = {}) {
418
+ const { sizeWarn = 0, duration = 100 } = options;
419
+ const stringData = JSON.stringify(data ?? null);
420
+ data = JSON.parse(stringData);
421
+ if (sizeWarn && stringData) {
422
+ if (stringData.length > sizeWarn) {
423
+ console.warn(`Notification payload of ${stringData.length} bytes exceeds ${sizeWarn} bytes, which can cause extra http requests.`, stringData);
424
+ }
425
+ }
426
+ return new Promise(resolve => setTimeout(() => resolve(data), duration));
427
+ }
428
+ function verifyNonMutation(operation, getState, message) {
429
+ const initialState = JSON.stringify(getState());
430
+ const result = operation();
431
+ const finalState = JSON.stringify(getState());
432
+ assert(initialState === finalState, message);
433
+ return result;
434
+ }
435
+ function sortObjectKeys(value) {
436
+ if (typeof value !== 'object' || value === null)
437
+ return value;
438
+ return Object.keys(value).sort().reduce((obj, key) => {
439
+ obj[key] = value[key];
440
+ return obj;
441
+ }, {});
442
+ }
541
443
  //# sourceMappingURL=GameLocalAPI.js.map