vantiv.io 1.0.0 → 1.0.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vantiv.io",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Enterprise WebSocket infrastructure for Highrise featuring spatial intelligence systems, memory-optimized architecture, and production-grade reliability for scalable application development",
5
5
  "keywords": [
6
6
  "highrise",
@@ -1,4 +1,4 @@
1
- const { payment_methods, default_skin } = require("highrise-core/src/constants/TypesConstants");
1
+ const { payment_methods, default_skin } = require("vantiv.io/src/constants/TypesConstants");
2
2
 
3
3
  class InventoryClass {
4
4
  constructor(bot) {
@@ -33,7 +33,7 @@ class MusicClass extends EventEmitter {
33
33
  initializeStreamer() {
34
34
  try {
35
35
  this.streamer = new IcecastStreamer(this.config.icecast);
36
- this.queue = new IcecastQueue(this.streamer, this.config.queue);
36
+ this.queue = new IcecastQueue(this.streamer, { ...this.config.queue, ...this.config.icecast});
37
37
 
38
38
  this.streamer.on('playbackStart', (track) => {
39
39
  this.emit('playbackStart', track);
@@ -1,7 +1,7 @@
1
- const PermissionManager = require("highrise-core/src/classes/Managers/PermissionManager");
2
- const CooldownManager = require("highrise-core/src/classes/Managers/Networking/CooldownManager");
3
- const DanceFloor = require("highrise-core/src/classes/Managers/DanceFloorManagers");
4
- const { Logger } = require("highrise-core/src/classes/Managers/Helpers/LoggerManager")
1
+ const PermissionManager = require("vantiv.io/src/classes/Managers/PermissionManager");
2
+ const CooldownManager = require("vantiv.io/src/classes/Managers/Networking/CooldownManager");
3
+ const DanceFloor = require("vantiv.io/src/classes/Managers/DanceFloorManagers");
4
+ const { Logger } = require("vantiv.io/src/classes/Managers/Helpers/LoggerManager")
5
5
 
6
6
  class Utils {
7
7
  constructor(bot, options) {
@@ -10,22 +10,25 @@ class IcecastStreamer extends EventEmitter {
10
10
  port: config.port || 8000,
11
11
  mount: config.mount || '/stream',
12
12
  sourcePassword: config.sourcePassword || 'hackme',
13
+ fallbackUrl: config.fallbackUrl || '',
14
+ fallbackEnabled: config.fallbackEnabled || false,
13
15
  audioFormat: config.audioFormat || 'mp3',
14
16
  audioBitrate: config.audioBitrate || '192k',
15
17
  audioSampleRate: config.audioSampleRate || 48000,
16
18
  audioChannels: config.audioChannels || 2,
17
19
  contentType: config.contentType || 'audio/mpeg'
18
20
  };
19
-
21
+
20
22
  this.ffmpegProcess = null;
21
- this.isStreaming = false;
23
+ this.fallbackProcess = null;
24
+ this.isStreaming = false; // Only for actual music
25
+ this.isFallbackActive = false; // Separate flag for fallback
22
26
  this.currentTrack = null;
23
-
27
+
24
28
  this.icecastUrl = `icecast://source:${this.config.sourcePassword}@${this.config.server}:${this.config.port}${this.config.mount}`;
25
29
  this.publicStreamUrl = `http://${this.config.server}:${this.config.port}${this.config.mount}`;
26
-
27
30
  }
28
-
31
+
29
32
  getFFmpegArgs(url) {
30
33
  return [
31
34
  '-re',
@@ -39,17 +42,34 @@ class IcecastStreamer extends EventEmitter {
39
42
  this.icecastUrl
40
43
  ];
41
44
  }
42
-
45
+
46
+ getFallbackFFmpegArgs() {
47
+ return [
48
+ '-re',
49
+ '-i', this.config.fallbackUrl,
50
+ '-f', this.config.audioFormat,
51
+ '-content_type', this.config.contentType,
52
+ '-vn',
53
+ '-ar', this.config.audioSampleRate.toString(),
54
+ '-ac', this.config.audioChannels.toString(),
55
+ '-b:a', this.config.audioBitrate,
56
+ this.icecastUrl
57
+ ];
58
+ }
59
+
43
60
  async streamToIcecast(url, metadata = {}) {
61
+ if (this.isFallbackActive) {
62
+ this.stopFallback();
63
+ await this.delay(200);
64
+ }
65
+
44
66
  if (this.ffmpegProcess) {
45
67
  this.stop();
46
68
  await this.delay(200);
47
69
  }
48
-
70
+
49
71
  return new Promise((resolve, reject) => {
50
- console.log(`Starting Icecast stream for: ${metadata.title || 'Unknown track'}`);
51
-
52
- this.currentTrack = {
72
+ this.currentTrack = new Track({
53
73
  url,
54
74
  title: metadata.title || 'Unknown Track',
55
75
  duration: metadata.duration || 0,
@@ -58,16 +78,17 @@ class IcecastStreamer extends EventEmitter {
58
78
  thumbnail: metadata.thumbnail,
59
79
  source: metadata.source || 'stream',
60
80
  startedAt: Date.now()
61
- };
62
-
81
+ });
82
+
63
83
  this.isStreaming = true;
64
-
84
+ this.isFallbackActive = false;
85
+
65
86
  const args = this.getFFmpegArgs(url);
66
87
  this.ffmpegProcess = spawn('ffmpeg', args);
67
-
88
+
68
89
  this.ffmpegProcess.stderr.on('data', (data) => {
69
90
  const message = data.toString();
70
-
91
+
71
92
  const durationMatch = message.match(/Duration: (\d+):(\d+):(\d+\.\d+)/);
72
93
  if (durationMatch) {
73
94
  const hours = parseInt(durationMatch[1]);
@@ -75,46 +96,44 @@ class IcecastStreamer extends EventEmitter {
75
96
  const seconds = parseFloat(durationMatch[3]);
76
97
  this.currentTrack.duration = hours * 3600 + minutes * 60 + seconds;
77
98
  }
78
-
99
+
79
100
  const timeMatch = message.match(/time=(\d+):(\d+):(\d+\.\d+)/);
80
101
  if (timeMatch) {
81
102
  const hours = parseInt(timeMatch[1]);
82
103
  const minutes = parseInt(timeMatch[2]);
83
104
  const seconds = parseFloat(timeMatch[3]);
84
105
  this.currentTrack.position = hours * 3600 + minutes * 60 + seconds;
85
-
106
+
86
107
  this.emit('progress', {
87
108
  position: this.currentTrack.position,
88
109
  duration: this.currentTrack.duration,
89
- progress: this.currentTrack.duration > 0 ?
110
+ progress: this.currentTrack.duration > 0 ?
90
111
  (this.currentTrack.position / this.currentTrack.duration) * 100 : 0
91
112
  });
92
113
  }
93
-
114
+
94
115
  if (message.includes('Stream mapping') || message.includes('Output')) {
95
- console.log('Icecast stream started successfully');
96
116
  this.emit('playbackStart', this.currentTrack);
97
117
  resolve();
98
118
  }
99
-
119
+
100
120
  if (message.includes('Error') || message.includes('Failed')) {
101
121
  console.error('FFmpeg error:', message.trim());
102
122
  this.emit('error', new Error(message.trim()));
103
123
  }
104
124
  });
105
-
125
+
106
126
  this.ffmpegProcess.on('close', (code) => {
107
- console.log(`Icecast stream ended with code ${code}`);
108
127
  const endedTrack = this.currentTrack;
109
-
128
+
110
129
  this.isStreaming = false;
111
130
  this.currentTrack = null;
112
131
  this.ffmpegProcess = null;
113
-
132
+
114
133
  this.emit('playbackEnd', endedTrack);
115
134
  this.emit('streamEnd', { code, track: endedTrack });
116
135
  });
117
-
136
+
118
137
  this.ffmpegProcess.on('error', (err) => {
119
138
  console.error('FFmpeg process error:', err);
120
139
  this.isStreaming = false;
@@ -124,26 +143,96 @@ class IcecastStreamer extends EventEmitter {
124
143
  });
125
144
  });
126
145
  }
127
-
146
+
147
+ startFallback() {
148
+ if (!this.config.fallbackUrl || this.isFallbackActive || this.isStreaming) {
149
+ return false;
150
+ }
151
+
152
+ if (this.ffmpegProcess) {
153
+ this.ffmpegProcess.kill('SIGKILL');
154
+ this.ffmpegProcess = null;
155
+ }
156
+
157
+ const args = this.getFallbackFFmpegArgs();
158
+ this.fallbackProcess = spawn('ffmpeg', args);
159
+
160
+ this.isFallbackActive = true;
161
+ this.isStreaming = false;
162
+
163
+ this.currentTrack = new Track({
164
+ url: this.config.fallbackUrl,
165
+ title: 'Fallback Music',
166
+ duration: 0,
167
+ requester: 'System',
168
+ requesterId: 'system',
169
+ source: 'fallback',
170
+ startedAt: Date.now(),
171
+ isFallback: true
172
+ });
173
+
174
+ this.fallbackProcess.stderr.on('data', (data) => {
175
+ const message = data.toString();
176
+
177
+ if (message.includes('Stream mapping') || message.includes('Output')) {
178
+ this.emit('fallbackStart', this.currentTrack);
179
+ }
180
+
181
+ if (message.includes('Error') || message.includes('Failed')) {
182
+ console.error('Fallback FFmpeg error:', message.trim());
183
+ }
184
+ });
185
+
186
+ this.fallbackProcess.on('close', (code) => {
187
+ this.isFallbackActive = false;
188
+ this.currentTrack = null;
189
+ this.fallbackProcess = null;
190
+
191
+ this.emit('fallbackEnd', { code });
192
+ });
193
+
194
+ this.fallbackProcess.on('error', (err) => {
195
+ console.error('Fallback FFmpeg process error:', err);
196
+ this.isFallbackActive = false;
197
+ this.currentTrack = null;
198
+ });
199
+
200
+ return true;
201
+ }
202
+
203
+ stopFallback() {
204
+ if (this.fallbackProcess) {
205
+ this.fallbackProcess.kill('SIGKILL');
206
+ this.fallbackProcess = null;
207
+ this.isFallbackActive = false;
208
+ this.currentTrack = null;
209
+ this.emit('fallbackStopped');
210
+ return true;
211
+ }
212
+ return false;
213
+ }
214
+
128
215
  stop() {
129
216
  if (this.ffmpegProcess) {
130
- console.log('Stopping Icecast stream...');
131
217
  this.ffmpegProcess.kill('SIGKILL');
132
218
  this.ffmpegProcess = null;
133
219
  this.isStreaming = false;
134
220
  this.emit('streamStopped');
135
221
  }
222
+
223
+ this.stopFallback();
136
224
  }
137
-
225
+
138
226
  getStatus() {
139
227
  return {
140
228
  isStreaming: this.isStreaming,
229
+ isFallbackActive: this.isFallbackActive,
141
230
  currentTrack: this.currentTrack,
142
231
  config: this.config,
143
232
  publicStreamUrl: this.publicStreamUrl
144
233
  };
145
234
  }
146
-
235
+
147
236
  getNowPlaying() {
148
237
  if (!this.currentTrack) return null;
149
238
 
@@ -151,15 +240,15 @@ class IcecastStreamer extends EventEmitter {
151
240
  track: this.currentTrack,
152
241
  position: this.currentTrack.position || 0,
153
242
  duration: this.currentTrack.duration || 0,
154
- progress: this.currentTrack.duration > 0 ?
243
+ progress: this.currentTrack.duration > 0 ?
155
244
  ((this.currentTrack.position || 0) / this.currentTrack.duration) * 100 : 0,
156
- remaining: this.currentTrack.duration > 0 ?
245
+ remaining: this.currentTrack.duration > 0 ?
157
246
  this.currentTrack.duration - (this.currentTrack.position || 0) : 0,
158
- elapsed: this.currentTrack.startedAt ?
247
+ elapsed: this.currentTrack.startedAt ?
159
248
  Math.floor((Date.now() - this.currentTrack.startedAt) / 1000) : 0
160
249
  };
161
250
  }
162
-
251
+
163
252
  updateConfig(newConfig) {
164
253
  this.config = { ...this.config, ...newConfig };
165
254
  this.icecastUrl = `icecast://source:${this.config.sourcePassword}@${this.config.server}:${this.config.port}${this.config.mount}`;
@@ -167,7 +256,7 @@ class IcecastStreamer extends EventEmitter {
167
256
  console.log('Icecast config updated');
168
257
  return this.config;
169
258
  }
170
-
259
+
171
260
  async delay(ms) {
172
261
  return new Promise(resolve => setTimeout(resolve, ms));
173
262
  }
@@ -184,6 +273,7 @@ class Track {
184
273
  this.addedAt = Date.now();
185
274
  this.thumbnail = data.thumbnail;
186
275
  this.source = data.source;
276
+ this.isFallback = data.isFallback || false;
187
277
  }
188
278
 
189
279
  getFormattedDuration() {
@@ -211,34 +301,65 @@ class IcecastQueue {
211
301
  this.maxHistory = config.maxHistory || 50;
212
302
  this.skipRequested = false;
213
303
 
304
+ this.fallbackEnabled = config.fallbackEnabled || false;
305
+ this.fallbackUrl = config.fallbackUrl || '';
306
+
214
307
  this.setupEventListeners();
308
+
309
+ this.checkAndStartFallback();
215
310
  }
216
-
311
+
217
312
  setupEventListeners() {
218
313
  this.streamer.on('playbackEnd', (track) => {
219
- if (track) {
314
+ if (track && !track.isFallback) {
220
315
  this.addToHistory(track, true);
221
316
  }
222
-
317
+
223
318
  if (this.skipRequested) {
224
319
  this.skipRequested = false;
225
320
  return;
226
321
  }
227
-
228
- if (this.loopMode === 'track' && track) {
322
+
323
+ if (this.loopMode === 'track' && track && !track.isFallback) {
229
324
  this.queue.unshift(new Track({ ...track }));
230
- } else if (this.loopMode === 'queue' && track) {
325
+ } else if (this.loopMode === 'queue' && track && !track.isFallback) {
231
326
  this.queue.push(new Track({ ...track }));
232
327
  }
233
-
328
+
234
329
  setTimeout(() => this.playNext(), 300);
235
330
  });
236
-
331
+
237
332
  this.streamer.on('playbackStart', (track) => {
238
333
  this.currentTrack = track;
239
334
  });
335
+
336
+ this.streamer.on('fallbackStart', (track) => {
337
+ this.currentTrack = track;
338
+ });
339
+
340
+ this.streamer.on('fallbackEnd', () => {
341
+ this.currentTrack = null;
342
+ this.checkAndStartFallback();
343
+ });
240
344
  }
241
345
 
346
+ checkAndStartFallback() {
347
+ if (this.queue.length === 0 &&
348
+ !this.streamer.isStreaming &&
349
+ !this.streamer.isFallbackActive &&
350
+ this.fallbackEnabled &&
351
+ this.fallbackUrl) {
352
+
353
+ setTimeout(() => {
354
+ if (this.queue.length === 0 &&
355
+ !this.streamer.isStreaming &&
356
+ !this.streamer.isFallbackActive) {
357
+ this.streamer.startFallback();
358
+ }
359
+ }, 1000);
360
+ }
361
+ }
362
+
242
363
  async add(track) {
243
364
  const isNewTrack = !this.queue.some(q => q.id === track.id);
244
365
  if (!isNewTrack) {
@@ -255,34 +376,42 @@ class IcecastQueue {
255
376
 
256
377
  return { position, added: true, isNowPlaying: false };
257
378
  }
258
-
379
+
259
380
  async addImmediate(track) {
260
- if (this.currentTrack) {
381
+ if (this.currentTrack && !this.currentTrack.isFallback) {
261
382
  this.queue.unshift(new Track({ ...this.currentTrack }));
262
383
  }
263
-
384
+
264
385
  this.queue.unshift(track);
265
386
  await this.skip();
266
387
  return { position: 1, added: true, isNowPlaying: true };
267
388
  }
268
-
389
+
269
390
  async playNext() {
270
- if (this.isProcessing || this.queue.length === 0) {
391
+ if (this.isProcessing) {
271
392
  return false;
272
393
  }
273
-
394
+
274
395
  this.isProcessing = true;
275
-
396
+
276
397
  try {
398
+ if (this.streamer.isFallbackActive) {
399
+ this.streamer.stopFallback();
400
+ await this.delay(200);
401
+ }
402
+
403
+ if (this.queue.length === 0) {
404
+ this.checkAndStartFallback();
405
+ return false;
406
+ }
407
+
277
408
  const nextTrack = this.queue.shift();
278
-
409
+
279
410
  if (!nextTrack?.url) {
280
411
  setTimeout(() => this.playNext(), 1000);
281
412
  return false;
282
413
  }
283
-
284
- console.log(`🎵 Playing on Icecast: ${nextTrack.title}`);
285
-
414
+
286
415
  await this.streamer.streamToIcecast(nextTrack.url, {
287
416
  title: nextTrack.title,
288
417
  duration: nextTrack.duration,
@@ -291,32 +420,31 @@ class IcecastQueue {
291
420
  thumbnail: nextTrack.thumbnail,
292
421
  source: nextTrack.source
293
422
  });
294
-
423
+
295
424
  return true;
296
425
  } catch (error) {
297
426
  console.error('Error playing next track:', error);
298
- // Retry with next track
299
427
  setTimeout(() => this.playNext(), 1000);
300
428
  return false;
301
429
  } finally {
302
430
  this.isProcessing = false;
303
431
  }
304
432
  }
305
-
433
+
306
434
  async skip() {
307
- if (!this.streamer.isStreaming) {
435
+ if (!this.streamer.isStreaming && this.streamer.isFallbackActive) {
308
436
  return false;
309
437
  }
310
-
438
+
311
439
  this.skipRequested = true;
312
440
  this.streamer.stop();
313
-
441
+
314
442
  await this.delay(100);
315
443
  await this.playNext();
316
-
444
+
317
445
  return true;
318
446
  }
319
-
447
+
320
448
  remove(position) {
321
449
  if (position < 1 || position > this.queue.length) {
322
450
  return null;
@@ -324,14 +452,19 @@ class IcecastQueue {
324
452
 
325
453
  return this.queue.splice(position - 1, 1)[0];
326
454
  }
327
-
455
+
328
456
  clear() {
329
457
  const cleared = [...this.queue];
330
458
  this.queue = [];
459
+
460
+ this.checkAndStartFallback();
461
+
331
462
  return cleared;
332
463
  }
333
-
464
+
334
465
  addToHistory(track, success = true) {
466
+ if (track.isFallback) return;
467
+
335
468
  const historyEntry = {
336
469
  ...track,
337
470
  playedAt: Date.now(),
@@ -345,14 +478,16 @@ class IcecastQueue {
345
478
  this.history.pop();
346
479
  }
347
480
  }
348
-
481
+
349
482
  getQueue() {
350
483
  return [...this.queue];
351
484
  }
352
-
485
+
353
486
  getStatus() {
354
487
  return {
355
- isPlaying: this.streamer.isStreaming,
488
+ isPlaying: this.streamer.isStreaming || this.streamer.isFallbackActive,
489
+ isMusicPlaying: this.streamer.isStreaming,
490
+ isFallbackActive: this.streamer.isFallbackActive,
356
491
  currentTrack: this.currentTrack,
357
492
  queueLength: this.queue.length,
358
493
  loopMode: this.loopMode,
@@ -360,10 +495,21 @@ class IcecastQueue {
360
495
  upcoming: this.queue.slice(0, 10)
361
496
  };
362
497
  }
363
-
498
+
364
499
  async delay(ms) {
365
500
  return new Promise(resolve => setTimeout(resolve, ms));
366
501
  }
502
+
503
+ startFallback() {
504
+ if (this.fallbackEnabled && this.fallbackUrl) {
505
+ return this.streamer.startFallback();
506
+ }
507
+ return false;
508
+ }
509
+
510
+ stopFallback() {
511
+ return this.streamer.stopFallback();
512
+ }
367
513
  }
368
514
 
369
515
  class YouTubeExtractor {
@@ -421,15 +567,15 @@ class IcecastServer {
421
567
  this.logger = config.logger
422
568
  this.setupExpress();
423
569
  }
424
-
570
+
425
571
  setupExpress() {
426
572
  this.app.use(express.json());
427
-
573
+
428
574
  this.app.get('/stream', (req, res) => {
429
575
  res.redirect(this.config.publicStreamUrl);
430
576
  });
431
577
  }
432
-
578
+
433
579
  start() {
434
580
  this.app.listen(this.port, () => {
435
581
  this.logger.success(`IcecastServer.start`, `running: http://localhost:${this.port}`);
@@ -1,5 +1,5 @@
1
- const ModelPool = require("highrise-core/src/utils/ModelPool");
2
- const { User, Position, Message, AnchorPosition, SessionMetadata, Voice, Direct, HiddenChannel, Tip, RoomModerate } = require('highrise-core/src/utils/Models')
1
+ const ModelPool = require("vantiv.io/src/utils/ModelPool");
2
+ const { User, Position, Message, AnchorPosition, SessionMetadata, Voice, Direct, HiddenChannel, Tip, RoomModerate } = require('vantiv.io/src/utils/Models')
3
3
 
4
4
  const modelPool = new ModelPool()
5
5
 
@@ -1,4 +1,4 @@
1
- const WebSocketConstants = require('highrise-core/src/constants/WebSocketConstants');
1
+ const WebSocketConstants = require('vantiv.io/src/constants/WebSocketConstants');
2
2
 
3
3
  class WebSocketHandlers {
4
4
  constructor(server) {
@@ -1,4 +1,4 @@
1
- const WebSocketConstants = require('highrise-core/src/constants/WebSocketConstants');
1
+ const WebSocketConstants = require('vantiv.io/src/constants/WebSocketConstants');
2
2
 
3
3
  class MetricsManager {
4
4
  constructor() {
@@ -1,4 +1,4 @@
1
- const WebSocketConstants = require('highrise-core/src/constants/WebSocketConstants');
1
+ const WebSocketConstants = require('vantiv.io/src/constants/WebSocketConstants');
2
2
  const EventEmitter = require('events');
3
3
  const WebSocket = require('ws');
4
4
 
@@ -109,37 +109,10 @@ class ConnectionManager extends EventEmitter {
109
109
  this.reconnecting = false;
110
110
 
111
111
  if (this.autoReconnect && !this.isManualDisconnect && !wasReconnecting) {
112
- const shouldReconnect = this._shouldReconnect(code, reasonStr);
113
-
114
- if (shouldReconnect) {
115
- this._scheduleReconnect();
116
- } else {
117
- this.logger.warn('ConnectionManager', 'Not reconnecting due to close code or reason', {
118
- code,
119
- reason: reasonStr
120
- });
121
- }
112
+ this._scheduleReconnect();
122
113
  }
123
114
  }
124
115
 
125
- _shouldReconnect(code, reason) {
126
- if (code === 1000 && reason.includes('Manual disconnect')) {
127
- return false;
128
- }
129
-
130
- if (code === 4001 || code === 4003 || code === 4004) {
131
- this.logger.error('ConnectionManager', 'Authentication failed, not reconnecting', { code, reason });
132
- return false;
133
- }
134
-
135
- if (code === 4009 || code === 4029) {
136
- this.logger.error('ConnectionManager', 'Rate limited or banned, not reconnecting', { code, reason });
137
- return false;
138
- }
139
-
140
- return true;
141
- }
142
-
143
116
  _handleError(error) {
144
117
  this.emit('error', error);
145
118
  this.logger.error('ConnectionManager', 'WebSocket error', {
@@ -162,19 +135,6 @@ class ConnectionManager extends EventEmitter {
162
135
  return;
163
136
  }
164
137
 
165
- const maxAttempts = WebSocketConstants.MAX_RECONNECT_ATTEMPTS || 10;
166
- if (this.reconnectAttempts >= maxAttempts) {
167
- this.logger.error('ConnectionManager', 'Max reconnection attempts reached', {
168
- attempts: this.reconnectAttempts,
169
- maxAttempts
170
- });
171
- this.emit('reconnectFailed', {
172
- attempts: this.reconnectAttempts,
173
- maxAttempts
174
- });
175
- return;
176
- }
177
-
178
138
  this._clearReconnectTimeout();
179
139
 
180
140
  const delay = Math.min(
@@ -9,7 +9,7 @@ const {
9
9
  RoomModerateHandler,
10
10
  HiddenChannelHandler,
11
11
  SessionMetadataHandler,
12
- } = require('highrise-core/src/classes/Handlers/EventHandlers');
12
+ } = require('vantiv.io/src/classes/Handlers/EventHandlers');
13
13
 
14
14
  class EventsManager {
15
15
  constructor(server) {
@@ -1,4 +1,4 @@
1
- const WebSocketConstants = require('highrise-core/src/constants/WebSocketConstants');
1
+ const WebSocketConstants = require('vantiv.io/src/constants/WebSocketConstants');
2
2
  const crypto = require('crypto');
3
3
 
4
4
  class KeepAliveManager {
@@ -7,18 +7,11 @@ class KeepAliveManager {
7
7
  this.logger = logger;
8
8
 
9
9
  this.interval = null;
10
- this.lastKeepaliveSent = 0;
11
- this.lastPongReceived = 0;
12
- this.consecutiveNoPong = 0;
13
- this.maxConsecutiveNoPong = 3;
14
- this.firstKeepaliveSent = false;
15
10
  }
16
11
 
17
12
  start() {
18
13
  this.stop();
19
14
 
20
- this.firstKeepaliveSent = false;
21
-
22
15
  this._sendKeepAlive();
23
16
 
24
17
  this.interval = setInterval(() => {
@@ -33,13 +26,11 @@ class KeepAliveManager {
33
26
  clearInterval(this.interval);
34
27
  this.interval = null;
35
28
  }
36
- this.consecutiveNoPong = 0;
37
- this.firstKeepaliveSent = false;
38
29
  }
39
30
 
40
31
  _sendKeepAlive() {
41
32
  if (!this.connectionManager.isConnected()) {
42
- this.logger.debug('KeepAliveManager', 'Skipping keepalive');
33
+ this.logger.debug('KeepAliveManager', 'Skipping keepalive - not connected');
43
34
  return;
44
35
  }
45
36
 
@@ -50,13 +41,6 @@ class KeepAliveManager {
50
41
  };
51
42
 
52
43
  this.connectionManager.send(keepalive);
53
- this.lastKeepaliveSent = Date.now();
54
-
55
- if (!this.firstKeepaliveSent) {
56
- this.firstKeepaliveSent = true;
57
- this.lastPongReceived = Date.now();
58
- return;
59
- }
60
44
 
61
45
  } catch (error) {
62
46
  this.logger.error('KeepAliveManager', 'Failed to send keepalive', {
@@ -65,41 +49,6 @@ class KeepAliveManager {
65
49
  }
66
50
  }
67
51
 
68
- _forceReconnect() {
69
- if (this.connectionManager.isConnected()) {
70
- this.connectionManager.disconnect(
71
- WebSocketConstants.ERROR_CODES.ABNORMAL_CLOSURE,
72
- 'Keepalive timeout'
73
- );
74
- }
75
- this.consecutiveNoPong = 0;
76
- }
77
-
78
- handlePong() {
79
- this.lastPongReceived = Date.now();
80
- this.consecutiveNoPong = 0;
81
-
82
- const latency = this.lastPongReceived - this.lastKeepaliveSent;
83
- if (latency > 10000) {
84
- this.logger.warn('KeepAliveManager', `High latency: ${latency}ms`);
85
- }
86
- }
87
-
88
- getStats() {
89
- const timeSinceLastPong = Date.now() - this.lastPongReceived;
90
- const timeSinceLastKeepalive = Date.now() - this.lastKeepaliveSent;
91
-
92
- return {
93
- isActive: this.interval !== null,
94
- lastKeepaliveSent: this.lastKeepaliveSent,
95
- lastPongReceived: this.lastPongReceived,
96
- timeSinceLastPong: timeSinceLastPong,
97
- timeSinceLastKeepalive: timeSinceLastKeepalive,
98
- consecutiveNoPong: this.consecutiveNoPong,
99
- healthStatus: this.firstKeepaliveSent ? (timeSinceLastPong < 45000 ? 'healthy' : 'degraded') : 'initializing'
100
- };
101
- }
102
-
103
52
  forceKeepAlive() {
104
53
  this._sendKeepAlive();
105
54
  this.logger.info('KeepAliveManager', 'Manual keepalive sent');
@@ -1,4 +1,4 @@
1
- const WebSocketConstants = require("highrise-core/src/constants/WebSocketConstants");
1
+ const WebSocketConstants = require("vantiv.io/src/constants/WebSocketConstants");
2
2
 
3
3
  class FireAndForgetSender {
4
4
  constructor(websocket) {
@@ -2,11 +2,10 @@ const WebSocketConstants = {
2
2
  // Connection
3
3
  KEEPALIVE_INTERVAL: 15000,
4
4
  MAX_RECONNECT_DELAY: 300000, // 5 minutes
5
- RECONNECT_BACKOFF_FACTOR: 1.5,
5
+ RECONNECT_BACKOFF_FACTOR: 1.1,
6
6
  DEFAULT_RECONNECT_DELAY: 5000,
7
7
  DEFAULT_AUTO_RECONNECT: true,
8
8
  MAX_RECONNECT_ATTEMPTS: 10,
9
- RECONNECT_BACKOFF_FACTOR: 1.5,
10
9
 
11
10
  // Logger Options
12
11
  DEFAULT_LOGGER_OPTIONS: {
@@ -1,8 +1,8 @@
1
- const HighriseWebsocket = require('highrise-core/src/core/HighriseWebsocket');
2
- const { ConfigValidator } = require('highrise-core/src/validators/ConfigValidator');
3
- const { checkVersion } = require('highrise-core/src/utils/versionCheck');
4
- const WebSocketConstants = require('highrise-core/src/constants/WebSocketConstants')
5
- const Utils = require('highrise-core/src/classes/Actions/Utils');
1
+ const HighriseWebsocket = require('vantiv.io/src/core/HighriseWebsocket');
2
+ const { ConfigValidator } = require('vantiv.io/src/validators/ConfigValidator');
3
+ const { checkVersion } = require('vantiv.io/src/utils/versionCheck');
4
+ const WebSocketConstants = require('vantiv.io/src/constants/WebSocketConstants')
5
+ const Utils = require('vantiv.io/src/classes/Actions/Utils');
6
6
 
7
7
  class Highrise extends HighriseWebsocket {
8
8
  constructor(events, userOptions = {}) {
@@ -35,9 +35,9 @@ class Highrise extends HighriseWebsocket {
35
35
  ? userOptions.customRoles
36
36
  : [],
37
37
 
38
- music: {
39
- enabled: userOptions.music.enabled || false,
40
- }
38
+ music: userOptions.music !== undefined
39
+ ? userOptions.music
40
+ : {}
41
41
  };
42
42
 
43
43
  const eventsValidation = ConfigValidator.validateEvents(events);
@@ -1,22 +1,22 @@
1
1
  const EventEmitter = require('events');
2
2
 
3
- const ConnectionManager = require('highrise-core/src/classes/Managers/Networking/ConnectionManager');
4
- const KeepAliveManager = require('highrise-core/src/classes/Managers/Networking/KeepAliveManager');
5
- const MessageHandler = require('highrise-core/src/classes/Managers/Networking/MessageHandler');
6
- const EventsManager = require('highrise-core/src/classes/Managers/Networking/EventsManager');
7
- const { FireAndForgetSender, RequestResponseSender } = require('highrise-core/src/classes/Managers/Networking/Request');
8
-
9
- const MetricsManager = require('highrise-core/src/classes/Managers/Helpers/MetricsManager');
10
- const CleanupManager = require('highrise-core/src/classes/Managers/Helpers/CleanupManager');
11
-
12
- const ChannelManager = require('highrise-core/src/classes/Managers/ChannelManager');
13
- const ConnectionValidator = require('highrise-core/src/validators/ConnectionValidator');
14
- const WebSocketHandlers = require('highrise-core/src/classes/Handlers/WebSocketHandlers');
15
-
16
- const { DirectClass } = require('highrise-core/src/classes/Actions/Direct');
17
- const { MovementCache } = require('highrise-core/src/classes/Caches/MovementCache');
18
- const AwaitClass = require('highrise-core/src/classes/Actions/Awaiter');
19
- const { Logger } = require('highrise-core/src/classes/Managers/Helpers/LoggerManager');
3
+ const ConnectionManager = require('vantiv.io/src/classes/Managers/Networking/ConnectionManager');
4
+ const KeepAliveManager = require('vantiv.io/src/classes/Managers/Networking/KeepAliveManager');
5
+ const MessageHandler = require('vantiv.io/src/classes/Managers/Networking/MessageHandler');
6
+ const EventsManager = require('vantiv.io/src/classes/Managers/Networking/EventsManager');
7
+ const { FireAndForgetSender, RequestResponseSender } = require('vantiv.io/src/classes/Managers/Networking/Request');
8
+
9
+ const MetricsManager = require('vantiv.io/src/classes/Managers/Helpers/MetricsManager');
10
+ const CleanupManager = require('vantiv.io/src/classes/Managers/Helpers/CleanupManager');
11
+
12
+ const ChannelManager = require('vantiv.io/src/classes/Managers/ChannelManager');
13
+ const ConnectionValidator = require('vantiv.io/src/validators/ConnectionValidator');
14
+ const WebSocketHandlers = require('vantiv.io/src/classes/Handlers/WebSocketHandlers');
15
+
16
+ const { DirectClass } = require('vantiv.io/src/classes/Actions/Direct');
17
+ const { MovementCache } = require('vantiv.io/src/classes/Caches/MovementCache');
18
+ const AwaitClass = require('vantiv.io/src/classes/Actions/Awaiter');
19
+ const { Logger } = require('vantiv.io/src/classes/Managers/Helpers/LoggerManager');
20
20
 
21
21
  class HighriseWebsocket extends EventEmitter {
22
22
  constructor(events, options = {}) {