snakeia-server 1.1.3-3
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/.dockerignore +2 -0
- package/.drone.yml +18 -0
- package/Dockerfile +10 -0
- package/GameEngineMultithreading.js +350 -0
- package/GameEngineMultithreadingController.js +232 -0
- package/LICENCE.txt +674 -0
- package/README.md +330 -0
- package/assets/css/bootstrap.min.css +7 -0
- package/assets/css/flat-ui.min.css +1 -0
- package/assets/css/main.css +110 -0
- package/assets/favicon.ico +0 -0
- package/assets/fonts/delius-regular.ttf +0 -0
- package/assets/fonts/delius-regular.woff +0 -0
- package/assets/fonts/flat-ui-pro-icons-regular.eot +0 -0
- package/assets/fonts/flat-ui-pro-icons-regular.svg +126 -0
- package/assets/fonts/flat-ui-pro-icons-regular.ttf +0 -0
- package/assets/fonts/flat-ui-pro-icons-regular.woff +0 -0
- package/assets/img/logo.png +0 -0
- package/assets/js/bootstrap.bundle.min.js +7 -0
- package/assets/js/jquery.min.js +2 -0
- package/config/default.json +38 -0
- package/docker-compose.yml +16 -0
- package/locales/en.json +65 -0
- package/locales/fr.json +65 -0
- package/package.json +38 -0
- package/server.js +1580 -0
- package/views/admin.html +305 -0
- package/views/authentication.html +78 -0
- package/views/banned.html +38 -0
- package/views/index.html +41 -0
package/.dockerignore
ADDED
package/.drone.yml
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
kind: pipeline
|
|
2
|
+
name: default
|
|
3
|
+
|
|
4
|
+
steps:
|
|
5
|
+
- name: build
|
|
6
|
+
image: node
|
|
7
|
+
commands:
|
|
8
|
+
- npm install
|
|
9
|
+
- name: publish
|
|
10
|
+
image: plugins/docker
|
|
11
|
+
settings:
|
|
12
|
+
repo: eliastik/snakeia-server
|
|
13
|
+
username:
|
|
14
|
+
from_secret: REGISTRY_USER
|
|
15
|
+
password:
|
|
16
|
+
from_secret: REGISTRY_PASSWORD
|
|
17
|
+
tags:
|
|
18
|
+
- latest
|
package/Dockerfile
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
FROM node:20-alpine
|
|
2
|
+
RUN addgroup -S snakeia-server && adduser -S snakeia-server -G snakeia-server && chown -R snakeia-server:snakeia-server /home/snakeia-server
|
|
3
|
+
RUN apk add git
|
|
4
|
+
WORKDIR /home/snakeia-server/server
|
|
5
|
+
COPY package*.json ./
|
|
6
|
+
COPY . .
|
|
7
|
+
RUN chown -R snakeia-server:snakeia-server /home/snakeia-server
|
|
8
|
+
USER snakeia-server
|
|
9
|
+
RUN npm install
|
|
10
|
+
ENTRYPOINT npm run start
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2020 Eliastik (eliastiksofts.com)
|
|
3
|
+
*
|
|
4
|
+
* This file is part of "SnakeIA Server".
|
|
5
|
+
*
|
|
6
|
+
* "SnakeIA Server" is free software: you can redistribute it and/or modify
|
|
7
|
+
* it under the terms of the GNU General Public License as published by
|
|
8
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
* (at your option) any later version.
|
|
10
|
+
*
|
|
11
|
+
* "SnakeIA Server" is distributed in the hope that it will be useful,
|
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
* GNU General Public License for more details.
|
|
15
|
+
*
|
|
16
|
+
* You should have received a copy of the GNU General Public License
|
|
17
|
+
* along with "SnakeIA Server". If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
*/
|
|
19
|
+
const { isMainThread, parentPort } = require('worker_threads');
|
|
20
|
+
const snakeia = require("snakeia");
|
|
21
|
+
const GameConstants = snakeia.GameConstants;
|
|
22
|
+
const Position = snakeia.Position;
|
|
23
|
+
const Grid = snakeia.Grid;
|
|
24
|
+
const Snake = snakeia.Snake;
|
|
25
|
+
const GameEngine = snakeia.GameEngine;
|
|
26
|
+
const seedrandom = require("seedrandom");
|
|
27
|
+
|
|
28
|
+
let game;
|
|
29
|
+
|
|
30
|
+
function copySnakes(snakes) {
|
|
31
|
+
var copy = JSON.parse(JSON.stringify(snakes));
|
|
32
|
+
|
|
33
|
+
if(copy) {
|
|
34
|
+
for(var i = 0; i < copy.length; i++) {
|
|
35
|
+
delete copy[i]["grid"];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return copy;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function copyGrid(grid) {
|
|
43
|
+
var copy = JSON.parse(JSON.stringify(grid));
|
|
44
|
+
|
|
45
|
+
if(copy) {
|
|
46
|
+
copy.rngGrid = null;
|
|
47
|
+
copy.rngGame = null;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return copy;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function parseSnakes(snakes, grid) {
|
|
54
|
+
if(game) {
|
|
55
|
+
var grid = grid != null ? grid : game.grid;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
grid = Object.assign(new Grid(), grid);
|
|
59
|
+
|
|
60
|
+
if(!snakes && game) {
|
|
61
|
+
snakes = game.snakes;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
for(var i = 0; i < snakes.length; i++) {
|
|
65
|
+
snakes[i].grid = grid;
|
|
66
|
+
snakes[i] = Object.assign(new Snake(), snakes[i]);
|
|
67
|
+
|
|
68
|
+
for(var j = 0; j < snakes[i].queue.length; j++) {
|
|
69
|
+
snakes[i].queue[j] = Object.assign(new Position(), snakes[i].queue[j]);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
snakes[i].initAI();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
grid: grid,
|
|
77
|
+
snakes: snakes
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if(!isMainThread) {
|
|
82
|
+
parentPort.on("message", (data) => {
|
|
83
|
+
const type = data.type;
|
|
84
|
+
const keys = Object.keys(data);
|
|
85
|
+
|
|
86
|
+
if(type == "init") {
|
|
87
|
+
const parsed = parseSnakes(data.snakes, data.grid);
|
|
88
|
+
const grid = parsed["grid"];
|
|
89
|
+
const snakes = parsed["snakes"];
|
|
90
|
+
|
|
91
|
+
if(!game) {
|
|
92
|
+
game = new GameEngine(grid, snakes, data.speed, data.enablePause, data.enableRetry, data.progressiveSpeed);
|
|
93
|
+
game.init();
|
|
94
|
+
|
|
95
|
+
parentPort.postMessage({
|
|
96
|
+
type: "init",
|
|
97
|
+
"snakes": copySnakes(game.snakes),
|
|
98
|
+
"grid": copyGrid(game.grid),
|
|
99
|
+
"enablePause": game.enablePause,
|
|
100
|
+
"enableRetry": game.enableRetry,
|
|
101
|
+
"progressiveSpeed": game.progressiveSpeed,
|
|
102
|
+
"offsetFrame": game.speed * GameConstants.Setting.TIME_MULTIPLIER,
|
|
103
|
+
"errorOccurred": game.errorOccurred
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
game.onReset(() => {
|
|
107
|
+
parentPort.postMessage({
|
|
108
|
+
type: "reset",
|
|
109
|
+
"paused": game.paused,
|
|
110
|
+
"isReseted": game.isReseted,
|
|
111
|
+
"exited": game.exited,
|
|
112
|
+
"snakes": copySnakes(game.snakes),
|
|
113
|
+
"grid": copyGrid(game.grid),
|
|
114
|
+
"numFruit": game.numFruit,
|
|
115
|
+
"ticks": game.ticks,
|
|
116
|
+
"scoreMax": game.scoreMax,
|
|
117
|
+
"gameOver": game.gameOver,
|
|
118
|
+
"gameFinished": game.gameFinished,
|
|
119
|
+
"gameMazeWin": game.gameMazeWin,
|
|
120
|
+
"starting": game.starting,
|
|
121
|
+
"initialSpeed": game.initialSpeed,
|
|
122
|
+
"speed": game.speed,
|
|
123
|
+
"offsetFrame": game.speed * GameConstants.Setting.TIME_MULTIPLIER,
|
|
124
|
+
"confirmReset": false,
|
|
125
|
+
"confirmExit": false,
|
|
126
|
+
"getInfos": false,
|
|
127
|
+
"getInfosGame": false,
|
|
128
|
+
"errorOccurred": game.errorOccurred,
|
|
129
|
+
"aiStuck": game.aiStuck,
|
|
130
|
+
"precAiStuck": false
|
|
131
|
+
});
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
game.onStart(() => {
|
|
135
|
+
parentPort.postMessage({
|
|
136
|
+
type: "start",
|
|
137
|
+
"snakes": copySnakes(game.snakes),
|
|
138
|
+
"grid": copyGrid(game.grid),
|
|
139
|
+
"starting": game.starting,
|
|
140
|
+
"countBeforePlay": game.countBeforePlay,
|
|
141
|
+
"paused": game.paused,
|
|
142
|
+
"isReseted": game.isReseted,
|
|
143
|
+
"confirmReset": false,
|
|
144
|
+
"confirmExit": false,
|
|
145
|
+
"getInfos": false,
|
|
146
|
+
"getInfosGame": false,
|
|
147
|
+
"errorOccurred": game.errorOccurred
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
game.onPause(() => {
|
|
152
|
+
parentPort.postMessage({
|
|
153
|
+
type: "pause",
|
|
154
|
+
"paused": game.paused,
|
|
155
|
+
"confirmReset": false,
|
|
156
|
+
"confirmExit": false,
|
|
157
|
+
"getInfos": false,
|
|
158
|
+
"getInfosGame": false,
|
|
159
|
+
"errorOccurred": game.errorOccurred
|
|
160
|
+
});
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
game.onContinue(() => {
|
|
164
|
+
parentPort.postMessage({
|
|
165
|
+
type: "continue",
|
|
166
|
+
"confirmReset": false,
|
|
167
|
+
"confirmExit": false,
|
|
168
|
+
"getInfos": false,
|
|
169
|
+
"getInfosGame": false,
|
|
170
|
+
"errorOccurred": game.errorOccurred
|
|
171
|
+
});
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
game.onStop(() => {
|
|
175
|
+
parentPort.postMessage({
|
|
176
|
+
type: "stop",
|
|
177
|
+
"paused": game.paused,
|
|
178
|
+
"scoreMax": game.scoreMax,
|
|
179
|
+
"gameOver": game.gameOver,
|
|
180
|
+
"gameFinished": game.gameFinished,
|
|
181
|
+
"confirmReset": false,
|
|
182
|
+
"confirmExit": false,
|
|
183
|
+
"getInfos": false,
|
|
184
|
+
"getInfosGame": false,
|
|
185
|
+
"errorOccurred": game.errorOccurred
|
|
186
|
+
});
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
game.onExit(() => {
|
|
190
|
+
parentPort.postMessage({
|
|
191
|
+
type: "exit",
|
|
192
|
+
"paused": game.paused,
|
|
193
|
+
"gameOver": game.gameOver,
|
|
194
|
+
"gameFinished": game.gameFinished,
|
|
195
|
+
"exited": game.exited,
|
|
196
|
+
"confirmReset": false,
|
|
197
|
+
"confirmExit": false,
|
|
198
|
+
"getInfos": false,
|
|
199
|
+
"getInfosGame": false,
|
|
200
|
+
"errorOccurred": game.errorOccurred
|
|
201
|
+
});
|
|
202
|
+
});
|
|
203
|
+
|
|
204
|
+
game.onKill(() => {
|
|
205
|
+
parentPort.postMessage({
|
|
206
|
+
type: "kill",
|
|
207
|
+
"paused": game.paused,
|
|
208
|
+
"gameOver": game.gameOver,
|
|
209
|
+
"killed": game.killed,
|
|
210
|
+
"snakes": copySnakes(game.snakes),
|
|
211
|
+
"grid": copyGrid(game.grid),
|
|
212
|
+
"gameFinished": game.gameFinished,
|
|
213
|
+
"confirmReset": false,
|
|
214
|
+
"confirmExit": false,
|
|
215
|
+
"getInfos": false,
|
|
216
|
+
"getInfosGame": false,
|
|
217
|
+
"errorOccurred": game.errorOccurred
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
game.onScoreIncreased(() => {
|
|
222
|
+
parentPort.postMessage({ type: "scoreIncreased" });
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
game.onUpdate(() => {
|
|
226
|
+
parentPort.postMessage({
|
|
227
|
+
type: "update",
|
|
228
|
+
"paused": game.paused,
|
|
229
|
+
"isReseted": game.isReseted,
|
|
230
|
+
"exited": game.exited,
|
|
231
|
+
"snakes": copySnakes(game.snakes),
|
|
232
|
+
"grid": copyGrid(game.grid),
|
|
233
|
+
"numFruit": game.numFruit,
|
|
234
|
+
"ticks": game.ticks,
|
|
235
|
+
"scoreMax": game.scoreMax,
|
|
236
|
+
"gameOver": game.gameOver,
|
|
237
|
+
"gameFinished": game.gameFinished,
|
|
238
|
+
"gameMazeWin": game.gameMazeWin,
|
|
239
|
+
"starting": game.starting,
|
|
240
|
+
"initialSpeed": game.initialSpeed,
|
|
241
|
+
"speed": game.speed,
|
|
242
|
+
"countBeforePlay": game.countBeforePlay,
|
|
243
|
+
"numFruit": game.numFruit,
|
|
244
|
+
"offsetFrame": 0,
|
|
245
|
+
"errorOccurred": game.errorOccurred,
|
|
246
|
+
"aiStuck": game.aiStuck
|
|
247
|
+
});
|
|
248
|
+
});
|
|
249
|
+
|
|
250
|
+
game.onUpdateCounter(() => {
|
|
251
|
+
parentPort.postMessage({
|
|
252
|
+
type: "updateCounter",
|
|
253
|
+
"paused": game.paused,
|
|
254
|
+
"isReseted": game.isReseted,
|
|
255
|
+
"exited": game.exited,
|
|
256
|
+
"snakes": copySnakes(game.snakes),
|
|
257
|
+
"grid": copyGrid(game.grid),
|
|
258
|
+
"numFruit": game.numFruit,
|
|
259
|
+
"ticks": game.ticks,
|
|
260
|
+
"scoreMax": game.scoreMax,
|
|
261
|
+
"gameOver": game.gameOver,
|
|
262
|
+
"gameFinished": game.gameFinished,
|
|
263
|
+
"gameMazeWin": game.gameMazeWin,
|
|
264
|
+
"starting": game.starting,
|
|
265
|
+
"initialSpeed": game.initialSpeed,
|
|
266
|
+
"speed": game.speed,
|
|
267
|
+
"countBeforePlay": game.countBeforePlay,
|
|
268
|
+
"numFruit": game.numFruit,
|
|
269
|
+
"errorOccurred": game.errorOccurred
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
} else {
|
|
273
|
+
game.snakes = snakes;
|
|
274
|
+
game.grid = grid;
|
|
275
|
+
game.countBeforePlay = 3;
|
|
276
|
+
game.init();
|
|
277
|
+
}
|
|
278
|
+
} else if(game) {
|
|
279
|
+
switch(type) {
|
|
280
|
+
case "reset":
|
|
281
|
+
game.reset();
|
|
282
|
+
break;
|
|
283
|
+
case "start":
|
|
284
|
+
game.start();
|
|
285
|
+
break;
|
|
286
|
+
case "stop":
|
|
287
|
+
game.stop();
|
|
288
|
+
break;
|
|
289
|
+
case "finish":
|
|
290
|
+
game.stop(true);
|
|
291
|
+
break;
|
|
292
|
+
case "stop":
|
|
293
|
+
game.stop(false);
|
|
294
|
+
break;
|
|
295
|
+
case "pause":
|
|
296
|
+
game.pause();
|
|
297
|
+
break;
|
|
298
|
+
case "kill":
|
|
299
|
+
game.kill();
|
|
300
|
+
break;
|
|
301
|
+
case "tick":
|
|
302
|
+
game.paused = false;
|
|
303
|
+
game.countBeforePlay = -1;
|
|
304
|
+
game.tick();
|
|
305
|
+
break;
|
|
306
|
+
case "exit":
|
|
307
|
+
game.exit();
|
|
308
|
+
break;
|
|
309
|
+
case "forceStart":
|
|
310
|
+
game.forceStart();
|
|
311
|
+
break;
|
|
312
|
+
case "key":
|
|
313
|
+
if(keys.length > 1) {
|
|
314
|
+
const key = data.key;
|
|
315
|
+
const numSnake = data.numSnake;
|
|
316
|
+
|
|
317
|
+
var playerSnake = game.getPlayer(numSnake, GameConstants.PlayerType.HUMAN) || game.getPlayer(numSnake, GameConstants.PlayerType.HYBRID_HUMAN_AI);
|
|
318
|
+
|
|
319
|
+
if(playerSnake) {
|
|
320
|
+
playerSnake.lastKey = key;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
break;
|
|
324
|
+
case "setGameOver":
|
|
325
|
+
if(keys.length > 1) {
|
|
326
|
+
const numSnake = data.numSnake;
|
|
327
|
+
|
|
328
|
+
var playerSnake = game.getPlayer(numSnake, GameConstants.PlayerType.HUMAN) || game.getPlayer(numSnake, GameConstants.PlayerType.HYBRID_HUMAN_AI);
|
|
329
|
+
|
|
330
|
+
if(playerSnake) {
|
|
331
|
+
playerSnake.gameOver = true;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
case "init":
|
|
335
|
+
if(data.length > 1) {
|
|
336
|
+
if(data.key == "snakes") {
|
|
337
|
+
var d = parseSnakes(data.data);
|
|
338
|
+
game.snakes = d.snakes;
|
|
339
|
+
} else if(data.key == "grid") {
|
|
340
|
+
var d = parseSnakes(null, data.data);
|
|
341
|
+
game.grid = d.grid;
|
|
342
|
+
} else {
|
|
343
|
+
game[data.key] = data.data;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
break;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
});
|
|
350
|
+
}
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (C) 2020 Eliastik (eliastiksofts.com)
|
|
3
|
+
*
|
|
4
|
+
* This file is part of "SnakeIA Server".
|
|
5
|
+
*
|
|
6
|
+
* "SnakeIA Server" is free software: you can redistribute it and/or modify
|
|
7
|
+
* it under the terms of the GNU General Public License as published by
|
|
8
|
+
* the Free Software Foundation, either version 3 of the License, or
|
|
9
|
+
* (at your option) any later version.
|
|
10
|
+
*
|
|
11
|
+
* "SnakeIA Server" is distributed in the hope that it will be useful,
|
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
14
|
+
* GNU General Public License for more details.
|
|
15
|
+
*
|
|
16
|
+
* You should have received a copy of the GNU General Public License
|
|
17
|
+
* along with "SnakeIA Server". If not, see <http://www.gnu.org/licenses/>.
|
|
18
|
+
*/
|
|
19
|
+
const { Worker } = require('worker_threads');
|
|
20
|
+
const snakeia = require("snakeia");
|
|
21
|
+
const GameEngine = snakeia.GameEngine;
|
|
22
|
+
const Grid = snakeia.Grid;
|
|
23
|
+
const Snake = snakeia.Snake;
|
|
24
|
+
const Position = snakeia.Position;
|
|
25
|
+
let logger;
|
|
26
|
+
|
|
27
|
+
class GameEngineMultithreadingController extends GameEngine {
|
|
28
|
+
constructor(grid, snakes, speed, enablePause, enableRetry, progressiveSpeed) {
|
|
29
|
+
super(grid, snakes, speed, enablePause, enableRetry, progressiveSpeed);
|
|
30
|
+
this.worker = new Worker("./GameEngineMultithreading.js");
|
|
31
|
+
this.eventsInit = false;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
init() {
|
|
35
|
+
if(!this.eventsInit) {
|
|
36
|
+
this.worker.on("message", (data) => {
|
|
37
|
+
const type = data.type;
|
|
38
|
+
const dataKeys = Object.keys(data);
|
|
39
|
+
|
|
40
|
+
if(dataKeys.length > 1) {
|
|
41
|
+
let grid = this.grid;
|
|
42
|
+
let snakes = this.snakes;
|
|
43
|
+
|
|
44
|
+
if(data.grid) {
|
|
45
|
+
grid = Object.assign(new Grid(), data.grid);
|
|
46
|
+
data.grid = grid;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if(data.snakes) {
|
|
50
|
+
for(let i = 0; i < data.snakes.length; i++) {
|
|
51
|
+
data.snakes[i].grid = grid;
|
|
52
|
+
data.snakes[i] = Object.assign(new Snake(), data.snakes[i]);
|
|
53
|
+
|
|
54
|
+
for(let j = 0; j < data.snakes[i].queue.length; j++) {
|
|
55
|
+
data.snakes[i].queue[j] = Object.assign(new Position(), data.snakes[i].queue[j]);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
snakes = data.snakes;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
this.snakes = snakes;
|
|
63
|
+
this.grid = grid;
|
|
64
|
+
|
|
65
|
+
for(let i = 0; i < dataKeys.length; i++) {
|
|
66
|
+
if(dataKeys[i] != "snakes" && dataKeys[i] != "grid") {
|
|
67
|
+
this[dataKeys[i]] = data[dataKeys[i]];
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
switch(type) {
|
|
73
|
+
case "reset":
|
|
74
|
+
this.reactor.dispatchEvent("onReset");
|
|
75
|
+
break;
|
|
76
|
+
case "start":
|
|
77
|
+
this.reactor.dispatchEvent("onStart");
|
|
78
|
+
break;
|
|
79
|
+
case "pause":
|
|
80
|
+
this.reactor.dispatchEvent("onPause");
|
|
81
|
+
break;
|
|
82
|
+
case "continue":
|
|
83
|
+
this.reactor.dispatchEvent("onContinue");
|
|
84
|
+
break;
|
|
85
|
+
case "stop":
|
|
86
|
+
this.reactor.dispatchEvent("onStop");
|
|
87
|
+
break;
|
|
88
|
+
case "exit":
|
|
89
|
+
this.reactor.dispatchEvent("onExit");
|
|
90
|
+
break;
|
|
91
|
+
case "kill":
|
|
92
|
+
this.reactor.dispatchEvent("onKill");
|
|
93
|
+
break;
|
|
94
|
+
case "scoreIncreased":
|
|
95
|
+
this.reactor.dispatchEvent("onScoreIncreased");
|
|
96
|
+
break;
|
|
97
|
+
case "update":
|
|
98
|
+
this.reactor.dispatchEvent("onUpdate");
|
|
99
|
+
break;
|
|
100
|
+
case "updateCounter":
|
|
101
|
+
this.reactor.dispatchEvent("onUpdateCounter");
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
this.worker.on("error", (error) => {
|
|
107
|
+
if(logger) logger.error("Error in GameEngineMultithreading", error);
|
|
108
|
+
this.errorOccurred = true;
|
|
109
|
+
this.reactor.dispatchEvent("onStop");
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
this.worker.on("exit", () => {
|
|
113
|
+
this.gameFinished = true;
|
|
114
|
+
this.reactor.dispatchEvent("onStop");
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
this.eventsInit = true;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if(this.grid) {
|
|
121
|
+
this.grid.rngGrid = null;
|
|
122
|
+
this.grid.rngGame = null;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
this.worker.postMessage({
|
|
126
|
+
type: "init",
|
|
127
|
+
grid: this.grid,
|
|
128
|
+
snakes: this.snakes,
|
|
129
|
+
speed: this.speed,
|
|
130
|
+
enablePause: this.enablePause,
|
|
131
|
+
enableRetry: this.enableRetry,
|
|
132
|
+
progressiveSpeed: this.progressiveSpeed
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
reset() {
|
|
137
|
+
if(this.worker) this.worker.postMessage({ type: "reset" });
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
start() {
|
|
141
|
+
if(this.worker) this.worker.postMessage({ type: "start" });
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
stop(finish) {
|
|
145
|
+
if(this.worker) this.worker.postMessage({ type: finish ? "finish" : "stop" });
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
finish(finish) {
|
|
149
|
+
if(this.worker) this.worker.postMessage({ type: finish ? "finish" : "stop" });
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
pause() {
|
|
153
|
+
if(this.worker) this.worker.postMessage({ type: "pause" });
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
kill() {
|
|
157
|
+
if(this.worker) {
|
|
158
|
+
this.worker.postMessage({ type: "kill" });
|
|
159
|
+
this.worker.terminate();
|
|
160
|
+
this.worker = null;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
tick() {
|
|
165
|
+
if(this.worker) this.worker.postMessage({ type: "tick" });
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
exit() {
|
|
169
|
+
if(this.worker) this.worker.postMessage({ type: "exit" });
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
key(key, numSnake) {
|
|
173
|
+
if(this.worker) this.worker.postMessage({ type: "key", key: key, numSnake: numSnake });
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
setGameOver(numSnake) {
|
|
177
|
+
if(this.worker) this.worker.postMessage({ type: "setGameOver", numSnake: numSnake });
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
forceStart() {
|
|
181
|
+
if(this.worker) this.worker.postMessage({ type: "forceStart" });
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
updateEngine(key, data) {
|
|
185
|
+
if(this.worker) this.worker.postMessage({ type: "update", key: key, data: data });
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
onReset(callback) {
|
|
189
|
+
this.reactor.addEventListener("onReset", callback);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
onStart(callback) {
|
|
193
|
+
this.reactor.addEventListener("onStart", callback);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
onContinue(callback) {
|
|
197
|
+
this.reactor.addEventListener("onContinue", callback);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
onStop(callback) {
|
|
201
|
+
this.reactor.addEventListener("onStop", callback);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
onPause(callback) {
|
|
205
|
+
this.reactor.addEventListener("onPause", callback);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
onExit(callback) {
|
|
209
|
+
this.reactor.addEventListener("onExit", callback);
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
onKill(callback) {
|
|
213
|
+
this.reactor.addEventListener("onKill", callback);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
onScoreIncreased(callback) {
|
|
217
|
+
this.reactor.addEventListener("onScoreIncreased", callback);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
onUpdate(callback) {
|
|
221
|
+
this.reactor.addEventListener("onUpdate", callback);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
onUpdateCounter(callback) {
|
|
225
|
+
this.reactor.addEventListener("onUpdateCounter", callback);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
module.exports = function(l) {
|
|
230
|
+
logger = l;
|
|
231
|
+
return GameEngineMultithreadingController;
|
|
232
|
+
};
|