vimp-engine 0.36.0 → 0.37.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vimp-engine",
3
- "version": "0.36.0",
3
+ "version": "0.37.1",
4
4
  "description": "VIMP — движок-приложение (мастер, P2P-транспорт, Worker-хост, мета, MVC-каркас клиента)",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -17,6 +17,7 @@ export default class ChatModel {
17
17
  this._cacheMin = data.cacheMin || 200;
18
18
  this._cacheMax = data.cacheMax || 300;
19
19
  this._messages = data.messages || {};
20
+ this._defaults = data.defaultMessages || {};
20
21
 
21
22
  this._formatMessage = data.formatMessage;
22
23
  this._sanitizeMessage = data.sanitizeMessage;
@@ -49,6 +50,20 @@ export default class ChatModel {
49
50
  }
50
51
  }
51
52
 
53
+ // текст шаблона: строка игры важнее умолчания движка; '' — игра
54
+ // заглушила сообщение; null/нет индекса — английское умолчание
55
+ _template(group, index) {
56
+ const own = this._messages[group]?.[index];
57
+
58
+ if (typeof own === 'string') {
59
+ return own === '' ? null : own;
60
+ }
61
+
62
+ const fallback = this._defaults[group]?.[index];
63
+
64
+ return typeof fallback === 'string' && fallback !== '' ? fallback : null;
65
+ }
66
+
52
67
  // обновляет чат-лист. Данные могут быть 2-х видов:
53
68
  // - в виде строки '<группа шаблонов>:<номер шаблона>:<параметры>'
54
69
  // - в виде массива [<текст сообщения>,<имя автора>,<тип для класса>,
@@ -58,12 +73,14 @@ export default class ChatModel {
58
73
  if (typeof arr === 'string') {
59
74
  arr = arr.split(':');
60
75
 
76
+ const template = this._template(arr[0], arr[1]);
77
+
61
78
  // если сообщений не найдено
62
- if (!this._messages[arr[0]] || !this._messages[arr[0]][arr[1]]) {
79
+ if (template === null) {
63
80
  return;
64
81
  }
65
82
 
66
- let message = this._messages[arr[0]][arr[1]];
83
+ let message = template;
67
84
  const params = arr[2];
68
85
 
69
86
  // если есть параметры
@@ -50,6 +50,7 @@ import { dispatchSocketMessage } from './lib/socketDispatch.js';
50
50
  import { pickActiveGame, isGameAvailable } from './lib/pickActiveGame.js';
51
51
  import { readCoreAbi, dispatchCoreOp, ABI_UNKNOWN } from '../lib/coreAbi.js';
52
52
  import { ABI_OP_DEBUG_JSON } from '../config/abiOps.js';
53
+ import engineChatMessages from '../config/chatMessages.js';
53
54
  import { createDebugApi, debugLog, DEBUG_PREFIX } from './debug.js';
54
55
  import { buildClientCoreConfig } from '../lib/clientCoreConfig.js';
55
56
  import { buildSnapshotKeysById } from '../lib/reconstructHot.js';
@@ -1147,6 +1148,7 @@ function runModules(data) {
1147
1148
  cacheMin: chatData.params.cacheMin,
1148
1149
  cacheMax: chatData.params.cacheMax,
1149
1150
  messages: chatData.params.messages,
1151
+ defaultMessages: engineChatMessages,
1150
1152
  sanitizeMessage,
1151
1153
  formatMessage,
1152
1154
  });
@@ -172,8 +172,22 @@ export default class GuestSession {
172
172
  let reconnectAttempt = 0;
173
173
 
174
174
  publisher.on('close', () => {
175
- const { baseDelay, maxDelay } = this._config.reconnect;
176
- const delay = Math.min(maxDelay, baseDelay * 2 ** reconnectAttempt);
175
+ const {
176
+ baseDelay,
177
+ maxDelay,
178
+ hostFirstDelay = 0,
179
+ } = this._config.reconnect;
180
+ // хост: мастер держит комнату hostDisconnectGraceMs — первая попытка
181
+ // сразу, дальше тот же бэкофф, сдвинутый на одну ступень
182
+ const isHost = Boolean(this._hostRole.controller);
183
+ const delay =
184
+ isHost && reconnectAttempt === 0
185
+ ? hostFirstDelay
186
+ : Math.min(
187
+ maxDelay,
188
+ baseDelay *
189
+ 2 ** (isHost ? reconnectAttempt - 1 : reconnectAttempt),
190
+ );
177
191
 
178
192
  reconnectAttempt += 1;
179
193
  this._timers.setTimeout(() => this._signaling.connect(), delay);
@@ -0,0 +1,45 @@
1
+ // Английские тексты движковых кодов чата по умолчанию (группы s, v, m, c, n);
2
+ // индекс = номер кода. Лежат здесь, а не в clientDefaults: при слиянии
3
+ // конфига массивы заменяются целиком, и массив `s` игры стёр бы умолчания.
4
+ // Правило перекрытия: строка игры по тому же индексу важнее умолчания;
5
+ // '' — игра заглушает сообщение; null/нет индекса — берётся умолчание.
6
+ // Новый код движка добавляется в ENGINE_MESSAGE_CODES (host/meta/modules/chat/
7
+ // systemMessages.js), сюда и в RESERVED правила B8 одним изменением —
8
+ // за этим следит tests/config/chatMessages.test.js.
9
+ export default {
10
+ s: [
11
+ 'Team {0} is full. Your current team: {1}',
12
+ 'Your team: {0}',
13
+ 'Your new team: {0}',
14
+ 'Your new status: spectator',
15
+ '{0} killed {1}',
16
+ '{0} joined the game',
17
+ '{0} left the game',
18
+ 'Host changed',
19
+ 'You are no longer the host (connection lost)',
20
+ 'Host changed: the previous host was lagging',
21
+ 'Host changed: the previous host went inactive',
22
+ 'Host changed: the previous host had a poor connection',
23
+ ],
24
+ v: [
25
+ 'A vote has been created',
26
+ 'Voting has started',
27
+ 'Your vote has been accepted',
28
+ 'Voting is temporarily unavailable',
29
+ 'Vote passed',
30
+ 'Vote failed',
31
+ 'Usage: /changehost',
32
+ 'You are the host — use “Hand over host” in the room menu',
33
+ 'No connection to the master server',
34
+ 'A host vote was held recently',
35
+ 'No other player can host',
36
+ 'A host vote is already in progress',
37
+ 'A host vote is not possible right now',
38
+ 'Vote to change host passed ({0}/{1})',
39
+ 'Vote to change host failed ({0}/{1})',
40
+ 'Host vote cancelled',
41
+ ],
42
+ m: ['Current map: {0}', 'Next map: {0}'],
43
+ c: ['Command not found', 'Your rank: {0}'],
44
+ n: ['Invalid name', '{0} changed name to {1}'],
45
+ };
@@ -172,8 +172,12 @@ export default {
172
172
  defaultLeaderboardPeriod: 'all',
173
173
 
174
174
  // переподключение сигнального WS хоста (комната без него выпадает из
175
- // выдачи мастера): экспоненциальный бэкофф от baseDelay до maxDelay (мс)
175
+ // выдачи мастера): экспоненциальный бэкофф от baseDelay до maxDelay (мс).
176
+ // Вкладка-хост переподключается первой попыткой сразу (hostFirstDelay):
177
+ // мастер держит её комнату master:room:hostDisconnectGraceMs, и вторая
178
+ // попытка (через baseDelay) тоже должна уложиться в выдержку
176
179
  reconnect: {
180
+ hostFirstDelay: 0,
177
181
  baseDelay: 1000,
178
182
  maxDelay: 30000,
179
183
  },
@@ -87,9 +87,13 @@ export default {
87
87
  room: {
88
88
  // отсоединённый участник ещё считается в комнате (реконнект сигналинга)
89
89
  memberGraceMs: 15000,
90
- // обрыв WS хоста запускает миграцию сразу (reclaim_host до регистрации
91
- // преемника её отменяет, этап 7.0); если повысить некого — комната
92
- // ждёт reclaim_host столько, потом уборка мигрирует или закрывает её
90
+ // обрыв WS хоста запускает миграцию не сразу, а через столько, если хост
91
+ // не вернулся reclaim_host'ом и ни один гость не сообщил host_unreachable
92
+ // (host_leaving мигрирует сразу); reclaim_host после начала миграции, до
93
+ // регистрации преемника, её отменяет (этап 7.0)
94
+ hostDisconnectGraceMs: 2000,
95
+ // повышать некого — комната ждёт reclaim_host столько, потом уборка
96
+ // мигрирует или закрывает её
93
97
  hostReclaimGraceMs: 10000,
94
98
  // потолок строки карточки комнаты в лобби (gameConfig.lobbyInfo игры)
95
99
  maxInfoLength: 48,
@@ -3,8 +3,8 @@ import { ERROR, skip, verdict } from '../result.js';
3
3
  // Регистрация игровых кодов — слепой Object.assign поверх движкового
4
4
  // реестра: код в зарезервированном диапазоне затирает движковое сообщение
5
5
  // без предупреждения, и вместо «Vote passed» игрок видит игровой текст.
6
- // Диапазоны — длины движковых групп (client/config/chat messages).
7
- const RESERVED = { s: 11, v: 15, m: 1, c: 1, n: 1 };
6
+ // Диапазоны — длины движковых групп (config/chatMessages.js).
7
+ export const RESERVED = { s: 11, v: 15, m: 1, c: 1, n: 1 };
8
8
 
9
9
  export default {
10
10
  id: 'B8',
@@ -1,8 +1,9 @@
1
1
  // Реестр кодов системных сообщений чата. Движковые группы: s (статусы),
2
2
  // v (голосования), m (карты), c (команды), n (имена). Игровые коды
3
3
  // (у танков — группа b:*) добавляются через registerCodes и не должны
4
- // пересекаться с движковыми группами. Тексты шаблонов — на клиенте.
5
- const MESSAGE_CODES = {
4
+ // пересекаться с движковыми группами. Английские тексты движковых кодов — config/chatMessages.js,
5
+ // игровых — на клиенте (конфиг игры).
6
+ export const ENGINE_MESSAGE_CODES = Object.freeze({
6
7
  TEAMS_TEAM_FULL: 's:0', // Team {0} is full. Your current team: {1}
7
8
  TEAMS_YOUR_TEAM: 's:1', // Your team: {0}
8
9
  TEAMS_NEW_TEAM: 's:2', // Your new team: {0}
@@ -48,7 +49,10 @@ const MESSAGE_CODES = {
48
49
 
49
50
  NAME_INVALID: 'n:0', // Invalid name
50
51
  NAME_CHANGED: 'n:1', // {0} changed name to {1}
51
- };
52
+ });
53
+
54
+ // изменяемый реестр: движковые коды + игровые из registerCodes
55
+ const MESSAGE_CODES = { ...ENGINE_MESSAGE_CODES };
52
56
 
53
57
  /**
54
58
  * Регистрирует игровые коды системных сообщений (merge в реестр движка).
@@ -57,41 +57,6 @@ export default {
57
57
  chat: {
58
58
  params: {
59
59
  messages: {
60
- s: [
61
- 'Team {0} is full. Your current team: {1}',
62
- 'Your team: {0}',
63
- 'Your new team: {0}',
64
- 'Your new status: spectator',
65
- '{0} killed {1}',
66
- '{0} joined the game',
67
- '{0} left the game',
68
- 'Host changed',
69
- 'You are no longer the host (connection lost)',
70
- 'Host changed: the previous host was lagging',
71
- 'Host changed: the previous host went inactive',
72
- 'Host changed: the previous host had a poor connection',
73
- ],
74
- v: [
75
- 'A vote has been created',
76
- 'Voting has started',
77
- 'Your vote has been accepted',
78
- 'Voting is temporarily unavailable',
79
- 'Vote passed',
80
- 'Vote failed',
81
- 'Usage: /changehost',
82
- 'You are the host — use “Hand over host” in the room menu',
83
- 'No connection to the master server',
84
- 'A host vote was held recently',
85
- 'No other player can host',
86
- 'A host vote is already in progress',
87
- 'A host vote is not possible right now',
88
- 'Vote to change host passed ({0}/{1})',
89
- 'Vote to change host failed ({0}/{1})',
90
- 'Host vote cancelled',
91
- ],
92
- m: ['Current map: {0}', 'Next map: {0}'],
93
- c: ['Command not found'],
94
- n: ['Invalid name', '{0} changed name to {1}'],
95
60
  g: ['{0} scripted participant(s) spawned'],
96
61
  },
97
62
  },