vimp-engine 0.7.2 → 0.8.0
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/package.json +11 -4
- package/src/client/InputListener.js +36 -0
- package/src/client/SoundManager.js +498 -0
- package/src/client/boot.js +113 -0
- package/src/client/components/controller/Auth.js +44 -0
- package/src/client/components/controller/CanvasManager.js +26 -0
- package/src/client/components/controller/Chat.js +56 -0
- package/src/client/components/controller/Controls.js +51 -0
- package/src/client/components/controller/Game.js +37 -0
- package/src/client/components/controller/Lobby.js +81 -0
- package/src/client/components/controller/LobbyAuth.js +41 -0
- package/src/client/components/controller/Panel.js +23 -0
- package/src/client/components/controller/Stat.js +33 -0
- package/src/client/components/controller/Vote.js +55 -0
- package/src/client/components/model/Auth.js +92 -0
- package/src/client/components/model/CanvasManager.js +319 -0
- package/src/client/components/model/Chat.js +119 -0
- package/src/client/components/model/Controls.js +120 -0
- package/src/client/components/model/Game.js +172 -0
- package/src/client/components/model/Lobby.js +226 -0
- package/src/client/components/model/LobbyAuth.js +161 -0
- package/src/client/components/model/Panel.js +70 -0
- package/src/client/components/model/Stat.js +77 -0
- package/src/client/components/model/Vote.js +216 -0
- package/src/client/components/view/Auth.js +167 -0
- package/src/client/components/view/CanvasManager.js +44 -0
- package/src/client/components/view/Chat.js +90 -0
- package/src/client/components/view/Controls.js +30 -0
- package/src/client/components/view/Game.js +48 -0
- package/src/client/components/view/Lobby.js +303 -0
- package/src/client/components/view/LobbyAuth.js +111 -0
- package/src/client/components/view/Panel.js +314 -0
- package/src/client/components/view/Stat.js +238 -0
- package/src/client/components/view/Vote.js +108 -0
- package/src/client/debug.js +158 -0
- package/src/client/lib/autostart.js +61 -0
- package/src/client/lib/contextTracker.js +46 -0
- package/src/client/lib/formBuilder.js +280 -0
- package/src/client/lib/hostGate.js +16 -0
- package/src/client/main.js +2011 -0
- package/src/client/network/HostConnectionManager.js +196 -0
- package/src/client/network/HostController.js +422 -0
- package/src/client/network/InlineHostBridge.js +152 -0
- package/src/client/network/LoopbackTransport.js +51 -0
- package/src/client/network/SignalingClient.js +146 -0
- package/src/client/network/WebRtcManager.js +147 -0
- package/src/client/network/WebSocketTransport.js +78 -0
- package/src/client/network/policyClose.js +54 -0
- package/src/client/network/workerSupport.js +34 -0
- package/src/client/providers/BakingProvider.js +88 -0
- package/src/client/providers/DependencyProvider.js +41 -0
- package/src/client/style.css +898 -0
- package/src/client/views/gameShell.js +190 -0
- package/src/client/views/includes/auth.pug +20 -0
- package/src/client/views/includes/chat.pug +5 -0
- package/src/client/views/includes/informer.pug +2 -0
- package/src/client/views/includes/lobby.pug +48 -0
- package/src/client/views/includes/lobbyAuth.pug +19 -0
- package/src/client/views/includes/panel.pug +3 -0
- package/src/client/views/includes/stat.pug +2 -0
- package/src/client/views/index.pug +8 -0
- package/src/config/closeCodes.js +18 -0
- package/src/config/env.js +61 -0
- package/src/devtools/ScenarioRunner.js +3 -8
- package/src/devtools/pluginLoader.js +8 -93
- package/src/host/HostGame.js +41 -3
- package/src/host/PortMachine.js +294 -0
- package/src/host/host.worker.js +29 -246
- package/src/host/identity.js +100 -0
- package/src/lib/clientIp.js +39 -0
- package/src/lib/loadGamePackage.js +122 -0
- package/src/lib/offlinePlayerData.js +18 -0
- package/src/standalone/index.js +125 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
// Singleton AuthCtrl
|
|
2
|
+
|
|
3
|
+
let authCtrl;
|
|
4
|
+
|
|
5
|
+
export default class AuthCtrl {
|
|
6
|
+
constructor(model, view) {
|
|
7
|
+
if (authCtrl) {
|
|
8
|
+
return authCtrl;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
authCtrl = this;
|
|
12
|
+
|
|
13
|
+
this._model = model;
|
|
14
|
+
this._view = view;
|
|
15
|
+
|
|
16
|
+
this._vPublic = view.publisher;
|
|
17
|
+
|
|
18
|
+
this._vPublic.on('input', 'update', this);
|
|
19
|
+
this._vPublic.on('enter', 'send', this);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// инициализация
|
|
23
|
+
init(data) {
|
|
24
|
+
for (const item of data) {
|
|
25
|
+
this._model.add(item);
|
|
26
|
+
}
|
|
27
|
+
this._view.showAuth();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// обновление
|
|
31
|
+
update(data) {
|
|
32
|
+
this._model.update(data);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// отправка данных
|
|
36
|
+
send() {
|
|
37
|
+
this._model.send();
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// разбор ответа сервера
|
|
41
|
+
parseRes(err) {
|
|
42
|
+
this._model.parseRes(err);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Singleton CanvasManagerCtrl
|
|
2
|
+
|
|
3
|
+
let canvasManagerCtrl;
|
|
4
|
+
|
|
5
|
+
export default class CanvasManagerCtrl {
|
|
6
|
+
constructor(model, view) {
|
|
7
|
+
if (canvasManagerCtrl) {
|
|
8
|
+
return canvasManagerCtrl;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
canvasManagerCtrl = this;
|
|
12
|
+
|
|
13
|
+
this._model = model;
|
|
14
|
+
this._view = view;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// обновляет представление относительно пользователя
|
|
18
|
+
updateCoords([x, y, cameraReset, shakeData]) {
|
|
19
|
+
this._model.updateCoords(x, y, cameraReset, shakeData);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// обновляет размеры
|
|
23
|
+
resize(data) {
|
|
24
|
+
this._model.resize(data);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// Singleton ChatCtrl
|
|
2
|
+
|
|
3
|
+
let chatCtrl;
|
|
4
|
+
|
|
5
|
+
export default class ChatCtrl {
|
|
6
|
+
constructor(model, view) {
|
|
7
|
+
if (chatCtrl) {
|
|
8
|
+
return chatCtrl;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
chatCtrl = this;
|
|
12
|
+
|
|
13
|
+
this._model = model;
|
|
14
|
+
this._view = view;
|
|
15
|
+
|
|
16
|
+
this._vPublic = view.publisher;
|
|
17
|
+
|
|
18
|
+
this._vPublic.on('newTimer', 'createTimer', this);
|
|
19
|
+
this._vPublic.on('oldTimer', 'removeTimer', this);
|
|
20
|
+
this._vPublic.on('message', 'sendMessage', this);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// открывает cmd
|
|
24
|
+
open() {
|
|
25
|
+
this._model.open();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// обновление состояния cmd по команде
|
|
29
|
+
updateCmd(cmd) {
|
|
30
|
+
if (cmd === 'enter') {
|
|
31
|
+
this._model.close(true);
|
|
32
|
+
} else if (cmd === 'escape') {
|
|
33
|
+
this._model.close(false);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// отправляет сообщение
|
|
38
|
+
sendMessage(message) {
|
|
39
|
+
this._model.sendMessage(message);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// добавляет сообщения
|
|
43
|
+
add(message) {
|
|
44
|
+
this._model.updateChat(message);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// добавляет таймер
|
|
48
|
+
createTimer(data) {
|
|
49
|
+
this._model.addToList(data);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// удаляет таймер
|
|
53
|
+
removeTimer() {
|
|
54
|
+
this._model.removeFromList();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// Singleton ControlsCtrl
|
|
2
|
+
|
|
3
|
+
let controlsCtrl;
|
|
4
|
+
|
|
5
|
+
export default class ControlsCtrl {
|
|
6
|
+
constructor(model, view) {
|
|
7
|
+
if (controlsCtrl) {
|
|
8
|
+
return controlsCtrl;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
controlsCtrl = this;
|
|
12
|
+
|
|
13
|
+
this._model = model;
|
|
14
|
+
this._view = view;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// добавляет клавишу
|
|
18
|
+
add(event) {
|
|
19
|
+
this._model.addKey(event);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// удаляет клавишу
|
|
23
|
+
remove(event) {
|
|
24
|
+
this._model.removeKey(event);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// задает текущий режим
|
|
28
|
+
switchMode(data) {
|
|
29
|
+
this._model.setMode(data.name, data.status);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// меняет набор клавиш
|
|
33
|
+
changeKeySet(keySet) {
|
|
34
|
+
this._model.changeKeySet(keySet);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// разблокирует возможность нажатия клавиш
|
|
38
|
+
enableKeys() {
|
|
39
|
+
this._model.setKeysEnabled(true);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// блокирует возможность нажатия клавиш
|
|
43
|
+
disableKeys() {
|
|
44
|
+
this._model.setKeysEnabled(false);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// скрывает курсор
|
|
48
|
+
resetCursorHideTimer() {
|
|
49
|
+
this._view.resetCursorHideTimer();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
// GameCtrl
|
|
2
|
+
|
|
3
|
+
export default class GameCtrl {
|
|
4
|
+
constructor(model, view) {
|
|
5
|
+
this._model = model;
|
|
6
|
+
this._view = view;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// обрабатывает данные
|
|
10
|
+
parse(constructor, instances) {
|
|
11
|
+
// если массив (без id) - это эффекты,
|
|
12
|
+
// которые проигрываются и самоуничтожаются
|
|
13
|
+
if (Array.isArray(instances)) {
|
|
14
|
+
for (let i = 0, len = instances.length; i < len; i += 1) {
|
|
15
|
+
this._model.createEffect(constructor, instances[i]);
|
|
16
|
+
}
|
|
17
|
+
} else {
|
|
18
|
+
for (const id in instances) {
|
|
19
|
+
if (Object.hasOwn(instances, id)) {
|
|
20
|
+
// если экземпляр существует - обновить
|
|
21
|
+
if (this._model.read(constructor, id)) {
|
|
22
|
+
this._model.update(constructor, id, instances[id]);
|
|
23
|
+
|
|
24
|
+
// иначе, если есть данные для создания экземпляра - создать
|
|
25
|
+
} else if (instances[id]) {
|
|
26
|
+
this._model.create(constructor, id, instances[id]);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// удаляет данные игры
|
|
34
|
+
remove(constructor, id) {
|
|
35
|
+
this._model.remove(constructor, id);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import Publisher from '../../../lib/Publisher.js';
|
|
2
|
+
|
|
3
|
+
// Singleton LobbyCtrl
|
|
4
|
+
|
|
5
|
+
let lobbyCtrl;
|
|
6
|
+
|
|
7
|
+
// Контроллер лобби: связывает view-события с моделью. Пинг видимых карточек
|
|
8
|
+
// дросселирует модель (pingHost возвращает false, если пинговали недавно).
|
|
9
|
+
// Leaderboard (lobby-page-plan): контроллер сам fetch не делает (как и модель) —
|
|
10
|
+
// пробрасывает смену активной игры через собственный publisher, который
|
|
11
|
+
// main.js слушает, чтобы вызвать fetchLeaderboard/fetchPlacement и вернуть
|
|
12
|
+
// результат в model.setLeaderboard/setPlacement. Единственный источник
|
|
13
|
+
// 'leaderboard-needed' — gameChanged() (main.js вызывает его один раз при
|
|
14
|
+
// открытии лобби для игры по умолчанию и на каждый change #lobby-game), не
|
|
15
|
+
// открытие вкладки — так пока в контроллере не завёлся второй, дублирующий
|
|
16
|
+
// путь загрузки (code review L4/L5: ветка "первое открытие вкладки" не могла
|
|
17
|
+
// сработать раньше gameChanged() при старте и рисковала уйти в fetch с
|
|
18
|
+
// gameId=null)
|
|
19
|
+
export default class LobbyCtrl {
|
|
20
|
+
constructor(model, view, clock = () => performance.now()) {
|
|
21
|
+
if (lobbyCtrl) {
|
|
22
|
+
return lobbyCtrl;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
lobbyCtrl = this;
|
|
26
|
+
|
|
27
|
+
this._model = model;
|
|
28
|
+
this._view = view;
|
|
29
|
+
this._clock = clock;
|
|
30
|
+
|
|
31
|
+
this.publisher = new Publisher();
|
|
32
|
+
|
|
33
|
+
const vp = view.publisher;
|
|
34
|
+
|
|
35
|
+
vp.on('search', 'search', this);
|
|
36
|
+
vp.on('more', 'loadMore', this);
|
|
37
|
+
vp.on('visible', 'pingHost', this);
|
|
38
|
+
vp.on('join', 'join', this);
|
|
39
|
+
vp.on('show-tab', 'showTab', this);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// показывает лобби и запрашивает первую страницу
|
|
43
|
+
open() {
|
|
44
|
+
this._view.show();
|
|
45
|
+
this._model.refresh();
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
close() {
|
|
49
|
+
this._view.hide();
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
search(text) {
|
|
53
|
+
this._model.setSearch(text);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
loadMore() {
|
|
57
|
+
this._model.loadMore();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
pingHost(hostId) {
|
|
61
|
+
this._model.pingHost(hostId, this._clock());
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
join(hostId) {
|
|
65
|
+
this._model.join(hostId);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
showTab(tab) {
|
|
69
|
+
this._view.showTab(tab);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// вызывается main.js при смене #lobby-game (селектор игры вне этого MVC),
|
|
73
|
+
// а также один раз при открытии лобби для активной по умолчанию игры —
|
|
74
|
+
// Leaderboard всегда готов заранее, до того как пользователь откроет
|
|
75
|
+
// вкладку (см. класс-комментарий выше)
|
|
76
|
+
gameChanged(gameId, title) {
|
|
77
|
+
this._view.setGameTitle(title);
|
|
78
|
+
|
|
79
|
+
this.publisher.emit('leaderboard-needed', gameId);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Singleton LobbyAuthCtrl
|
|
2
|
+
|
|
3
|
+
let lobbyAuthCtrl;
|
|
4
|
+
|
|
5
|
+
export default class LobbyAuthCtrl {
|
|
6
|
+
constructor(model, view) {
|
|
7
|
+
if (lobbyAuthCtrl) {
|
|
8
|
+
return lobbyAuthCtrl;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
lobbyAuthCtrl = this;
|
|
12
|
+
|
|
13
|
+
this._model = model;
|
|
14
|
+
this._view = view;
|
|
15
|
+
|
|
16
|
+
const vp = view.publisher;
|
|
17
|
+
|
|
18
|
+
vp.on('login', 'login', this);
|
|
19
|
+
vp.on('nick', 'submitNick', this);
|
|
20
|
+
vp.on('logout', 'logout', this);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// разбирает query string текущего location (OAuth-редиректы) либо
|
|
24
|
+
// восстанавливает сессию из localStorage; возвращает true, если query
|
|
25
|
+
// содержала auth-параметры (вызывающий должен подчистить адресную строку)
|
|
26
|
+
init(search) {
|
|
27
|
+
return this._model.boot(search);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
login(provider) {
|
|
31
|
+
window.location.href = this._model.loginUrl(provider);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
submitNick(nick) {
|
|
35
|
+
this._model.submitNick(nick);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
logout() {
|
|
39
|
+
this._model.logout();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// Singleton PanelCtrl
|
|
2
|
+
|
|
3
|
+
let panelCtrl;
|
|
4
|
+
|
|
5
|
+
export default class PanelCtrl {
|
|
6
|
+
constructor(model, view) {
|
|
7
|
+
if (panelCtrl) {
|
|
8
|
+
return panelCtrl;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
panelCtrl = this;
|
|
12
|
+
|
|
13
|
+
this._model = model;
|
|
14
|
+
this._view = view;
|
|
15
|
+
|
|
16
|
+
this._vPublic = view.publisher;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// обновляет пользовательскую панель
|
|
20
|
+
update(dataArr) {
|
|
21
|
+
this._model.update(dataArr);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Singleton StatCtrl
|
|
2
|
+
|
|
3
|
+
let statCtrl;
|
|
4
|
+
|
|
5
|
+
export default class StatCtrl {
|
|
6
|
+
constructor(model, view) {
|
|
7
|
+
if (statCtrl) {
|
|
8
|
+
return statCtrl;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
statCtrl = this;
|
|
12
|
+
|
|
13
|
+
this._model = model;
|
|
14
|
+
this._view = view;
|
|
15
|
+
|
|
16
|
+
this._vPublic = view.publisher;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// открывает статистику
|
|
20
|
+
open() {
|
|
21
|
+
this._model.open();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// закрывает статистику
|
|
25
|
+
close() {
|
|
26
|
+
this._model.close();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// обновляет
|
|
30
|
+
update(data) {
|
|
31
|
+
this._model.update(data);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Singleton VoteCtrl
|
|
2
|
+
|
|
3
|
+
let voteCtrl;
|
|
4
|
+
|
|
5
|
+
export default class VoteCtrl {
|
|
6
|
+
constructor(model, view) {
|
|
7
|
+
if (voteCtrl) {
|
|
8
|
+
return voteCtrl;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
voteCtrl = this;
|
|
12
|
+
|
|
13
|
+
this._model = model;
|
|
14
|
+
this._view = view;
|
|
15
|
+
|
|
16
|
+
this._vPublic = view.publisher;
|
|
17
|
+
|
|
18
|
+
this._vPublic.on('timer', 'assignTimer', this);
|
|
19
|
+
this._vPublic.on('clear', 'removeVote', this);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// включить
|
|
23
|
+
// data может быть:
|
|
24
|
+
// {name: 'templateName', params: ['p1',..], values: ['v1',..] || 'values'}
|
|
25
|
+
// ['val1', 'val2'];
|
|
26
|
+
open(data) {
|
|
27
|
+
// если данные - массив (values для созданного голосования)
|
|
28
|
+
if (Array.isArray(data)) {
|
|
29
|
+
this._model.updateValues(data);
|
|
30
|
+
// если данные - объект (данные для создания голосования)
|
|
31
|
+
} else if (typeof data === 'object' && data !== null) {
|
|
32
|
+
this._model.createWithTemplate(data);
|
|
33
|
+
this._model.open();
|
|
34
|
+
// иначе открыть меню
|
|
35
|
+
} else {
|
|
36
|
+
this._model.createMenu();
|
|
37
|
+
this._model.open();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// назначает ключ
|
|
42
|
+
assignKey(keyCode) {
|
|
43
|
+
this._model.update(keyCode);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// добавляет таймер
|
|
47
|
+
assignTimer(timerId) {
|
|
48
|
+
this._model.assignTimer(timerId);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// удаляет голосование
|
|
52
|
+
removeVote() {
|
|
53
|
+
this._model.complete();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import Publisher from '../../../lib/Publisher.js';
|
|
2
|
+
|
|
3
|
+
// Singleton AuthModel
|
|
4
|
+
|
|
5
|
+
let authModel;
|
|
6
|
+
|
|
7
|
+
export default class AuthModel {
|
|
8
|
+
constructor(validateAuth) {
|
|
9
|
+
if (authModel) {
|
|
10
|
+
return authModel;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
authModel = this;
|
|
14
|
+
|
|
15
|
+
this._validateAuth = validateAuth;
|
|
16
|
+
|
|
17
|
+
this._data = {};
|
|
18
|
+
this._options = {};
|
|
19
|
+
this._sendStatus = false;
|
|
20
|
+
|
|
21
|
+
this.publisher = new Publisher();
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// добавляет данные
|
|
25
|
+
add(data) {
|
|
26
|
+
const { name, value, options } = data;
|
|
27
|
+
this._data[name] = value;
|
|
28
|
+
this._options[name] = options;
|
|
29
|
+
|
|
30
|
+
this.publisher.emit('form', { name, value });
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// обновление данных
|
|
34
|
+
// если value невалиден, возвращается текущий value
|
|
35
|
+
update(data) {
|
|
36
|
+
const { name } = data;
|
|
37
|
+
const { regExp } = this._options[name] ?? {};
|
|
38
|
+
let { value } = data;
|
|
39
|
+
|
|
40
|
+
if (regExp) {
|
|
41
|
+
if (regExp.test(value)) {
|
|
42
|
+
this._data[name] = value;
|
|
43
|
+
} else {
|
|
44
|
+
this._data[name] = value = '';
|
|
45
|
+
}
|
|
46
|
+
} else {
|
|
47
|
+
this._data[name] = value;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
this.publisher.emit('form', { name, value });
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// отправка данных на сервер
|
|
54
|
+
send() {
|
|
55
|
+
const errors = this._validateAuth(this._data);
|
|
56
|
+
|
|
57
|
+
if (errors) {
|
|
58
|
+
this.parseRes(errors);
|
|
59
|
+
} else {
|
|
60
|
+
if (this._sendStatus) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
this.publisher.emit('socket', this._data);
|
|
65
|
+
|
|
66
|
+
this._sendStatus = true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// разбор ответа сервера
|
|
71
|
+
parseRes(err) {
|
|
72
|
+
const arr = [];
|
|
73
|
+
|
|
74
|
+
// если авторизация успешна
|
|
75
|
+
if (!err) {
|
|
76
|
+
Object.keys(this._data).forEach(key => {
|
|
77
|
+
const { storage } = this._options[key];
|
|
78
|
+
|
|
79
|
+
if (storage) {
|
|
80
|
+
arr.push({ name: storage, value: this._data[key] });
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
this.publisher.emit('ok', arr);
|
|
85
|
+
// иначе
|
|
86
|
+
} else {
|
|
87
|
+
this.publisher.emit('error', err);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
this._sendStatus = false;
|
|
91
|
+
}
|
|
92
|
+
}
|