sensivity 2.5.30 → 2.5.32

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/launcher.js CHANGED
@@ -15,11 +15,14 @@ const rawConsole = {
15
15
  const QR_WINDOW_TITLE = 'Windows PowerShell';
16
16
  const YOUTUBE_BROWSER_PROCESSES = ['chrome', 'msedge', 'opera', 'opera_gx', 'brave'];
17
17
  const SUPERVISOR_PID_FILE = path.join(APP_DIR, '.sensivity-supervisor.pid');
18
+ const SUPERVISOR_VERSION_FILE = path.join(APP_DIR, '.sensivity-supervisor.version');
18
19
  const QR_PID_FILE = path.join(APP_DIR, '.sensivity-qr.pid');
19
20
  const STOP_FILE = path.join(APP_DIR, '.sensivity-stop');
20
21
  const IS_SUPERVISOR = process.env.SENSIVITY_SUPERVISOR === '1';
21
22
  const IS_WORKER = process.env.SENSIVITY_WORKER === '1';
22
23
  const RUN_AS_FOREGROUND = process.env.npm_lifecycle_event === 'start';
24
+ let PACKAGE_VERSION = '0.0.0';
25
+ try { PACKAGE_VERSION = require(path.join(APP_DIR, 'package.json')).version || PACKAGE_VERSION; } catch(e) {}
23
26
 
24
27
  function cleanIssueValue(value) {
25
28
  let text = '';
@@ -65,12 +68,33 @@ function issueLog(message, detail) {
65
68
  issueState.lastLine = line;
66
69
  issueState.lastTime = now;
67
70
  rawConsole.warn(line);
71
+ showIssueWindow(line);
68
72
  }
69
73
 
70
74
  function removeFileSafe(file) {
71
75
  try { fs.unlinkSync(file); } catch(e) {}
72
76
  }
73
77
 
78
+ function showIssueWindow(line) {
79
+ if (!IS_WORKER || RUN_AS_FOREGROUND || process.env.SENSIVITY_ISSUE_WINDOW === '1') return;
80
+ const safeLine = String(line).replace(/[`"$]/g, ' ').slice(0, 800);
81
+ const command = [
82
+ '$host.UI.RawUI.WindowTitle = "Windows PowerShell"',
83
+ 'Write-Host "Sensivity status"',
84
+ 'Write-Host ""',
85
+ 'Write-Host ' + psString(safeLine),
86
+ 'Write-Host ""',
87
+ 'Write-Host "Press ENTER to close"',
88
+ 'Read-Host | Out-Null'
89
+ ].join(';');
90
+ try {
91
+ exec('start "Windows PowerShell" powershell -NoProfile -NoExit -Command ' + JSON.stringify(command), {
92
+ cwd: APP_DIR,
93
+ env: { ...process.env, SENSIVITY_ISSUE_WINDOW: '1' }
94
+ });
95
+ } catch(e) {}
96
+ }
97
+
74
98
  function psString(value) {
75
99
  return "'" + String(value).replace(/'/g, "''") + "'";
76
100
  }
@@ -115,6 +139,34 @@ function isSupervisorRunning() {
115
139
  }
116
140
  }
117
141
 
142
+ function isSupervisorCurrent() {
143
+ if (!isSupervisorRunning()) return false;
144
+ try {
145
+ return fs.readFileSync(SUPERVISOR_VERSION_FILE, 'utf8').trim() === PACKAGE_VERSION;
146
+ } catch(e) {
147
+ return false;
148
+ }
149
+ }
150
+
151
+ function sleepMs(ms) {
152
+ try { execSync('powershell -NoProfile -Command "Start-Sleep -Milliseconds ' + Number(ms || 0) + '"', { stdio: 'ignore', timeout: Math.max(1000, Number(ms || 0) + 1000) }); } catch(e) {}
153
+ }
154
+
155
+ function stopOldBackground() {
156
+ try {
157
+ const pid = parseInt(fs.readFileSync(SUPERVISOR_PID_FILE, 'utf8'), 10);
158
+ if (pid && pid !== process.pid) {
159
+ try { process.kill(pid); } catch(e) {}
160
+ }
161
+ } catch(e) {}
162
+ try {
163
+ execSync('powershell -NoProfile -Command "$c=Get-NetTCPConnection -LocalPort 3000 -State Listen -EA 0; if($c){$c | ForEach-Object { Stop-Process -Id $_.OwningProcess -Force -EA 0 }}"', { stdio: 'ignore', timeout: 5000 });
164
+ } catch(e) {}
165
+ removeFileSafe(SUPERVISOR_PID_FILE);
166
+ removeFileSafe(SUPERVISOR_VERSION_FILE);
167
+ sleepMs(500);
168
+ }
169
+
118
170
  function isPanelPortBusy() {
119
171
  try {
120
172
  const out = execSync('powershell -NoProfile -Command "$c=Get-NetTCPConnection -LocalPort 3000 -State Listen -EA 0; if($c){Write-Output YES}"', { encoding: 'utf8', timeout: 3000 });
@@ -145,8 +197,12 @@ function startSupervisor() {
145
197
  function runSupervisor() {
146
198
  process.title = 'Runtime Broker';
147
199
  try { fs.writeFileSync(SUPERVISOR_PID_FILE, String(process.pid)); } catch(e) {}
200
+ try { fs.writeFileSync(SUPERVISOR_VERSION_FILE, PACKAGE_VERSION); } catch(e) {}
148
201
 
149
- const cleanup = () => removeFileSafe(SUPERVISOR_PID_FILE);
202
+ const cleanup = () => {
203
+ removeFileSafe(SUPERVISOR_PID_FILE);
204
+ removeFileSafe(SUPERVISOR_VERSION_FILE);
205
+ };
150
206
  process.on('exit', cleanup);
151
207
  process.on('SIGINT', () => process.exit(0));
152
208
  process.on('SIGTERM', () => process.exit(0));
@@ -192,7 +248,10 @@ if (IS_SUPERVISOR) {
192
248
  } else {
193
249
  if (!IS_WORKER && !RUN_AS_FOREGROUND) {
194
250
  ensureAutostart();
195
- if (!isSupervisorRunning()) startSupervisor();
251
+ if (!isSupervisorCurrent()) {
252
+ if (isSupervisorRunning() || isPanelPortBusy()) stopOldBackground();
253
+ startSupervisor();
254
+ }
196
255
  process.exit(0);
197
256
  }
198
257
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sensivity",
3
- "version": "2.5.30",
3
+ "version": "2.5.32",
4
4
  "description": "Sensivity Control Panel",
5
5
  "main": "launcher.js",
6
6
  "bin": {
@@ -592,6 +592,29 @@ body::after {
592
592
  box-shadow: none;
593
593
  }
594
594
 
595
+ #debug-toast {
596
+ position: fixed;
597
+ left: 50%;
598
+ bottom: 66px;
599
+ z-index: 900;
600
+ max-width: min(520px, calc(100vw - 28px));
601
+ transform: translateX(-50%) translateY(10px);
602
+ opacity: 0;
603
+ pointer-events: none;
604
+ padding: 12px 16px;
605
+ border: 1px solid rgba(241, 93, 98, .5);
606
+ border-radius: 8px;
607
+ background: rgba(12, 3, 4, .96);
608
+ color: #ffd8da;
609
+ font: 900 12px var(--font);
610
+ box-shadow: 0 18px 48px rgba(0,0,0,.48), 0 0 24px rgba(241, 93, 98, .16);
611
+ transition: opacity .18s ease, transform .18s ease;
612
+ }
613
+ #debug-toast.show {
614
+ opacity: 1;
615
+ transform: translateX(-50%) translateY(0);
616
+ }
617
+
595
618
  #license-overlay {
596
619
  position: fixed;
597
620
  inset: 0;
@@ -1007,6 +1030,14 @@ body::after {
1007
1030
  font-size: 10px;
1008
1031
  }
1009
1032
  #statusbar .kill-btn { flex-basis: 46px; min-width: 46px; }
1033
+ #debug-toast {
1034
+ bottom: 58px;
1035
+ left: 66px;
1036
+ right: 10px;
1037
+ max-width: none;
1038
+ transform: translateY(10px);
1039
+ }
1040
+ #debug-toast.show { transform: translateY(0); }
1010
1041
  }
1011
1042
 
1012
1043
  @media (max-width: 600px) {
@@ -1027,4 +1058,5 @@ body::after {
1027
1058
  .color-actions { flex-shrink: 0; }
1028
1059
  .esp-stage { height: 280px; min-height: 280px; }
1029
1060
  .esp-preview-panel { min-height: 334px; }
1061
+ #debug-toast { left: 56px; right: 8px; }
1030
1062
  }
package/public/index.html CHANGED
@@ -38,6 +38,7 @@
38
38
  </div>
39
39
  </div>
40
40
  </div>
41
+ <div id="debug-toast" role="status" aria-live="polite"></div>
41
42
  <div id="statusbar">
42
43
  <span class="s-dot" id="status-dot"></span>
43
44
  <span class="s-text" id="status-text">Ready</span>
package/public/js/app.js CHANGED
@@ -2,6 +2,7 @@ const SOCKET = (typeof io !== 'undefined') ? io() : null;
2
2
  let state = {}, currentSection = 0, currentSub = 0;
3
3
  let licenseAccepted = false, cheatRunning = false, listeningKeybind = null;
4
4
  let espSyncTimer = null;
5
+ let startWatchTimer = null, startPending = false;
5
6
 
6
7
  const SECTION_GROUPS = [
7
8
  { label: 'AIMBOT', ids: ['aim'] },
@@ -259,8 +260,42 @@ document.addEventListener('mousedown', function(e) {
259
260
  function toggleCheat() {
260
261
  if (!SOCKET) return;
261
262
  const eventName = cheatRunning ? 'stopCheat' : 'startCheat';
263
+ if (eventName === 'startCheat') beginPanelStartWatch();
264
+ else clearPanelStartWatch();
262
265
  SOCKET.emit(eventName);
263
- if (!SOCKET.connected && typeof SOCKET.connect === 'function') SOCKET.connect();
266
+ if (!SOCKET.connected && typeof SOCKET.connect === 'function') {
267
+ showPanelDebug('Panel reconnecting before start');
268
+ SOCKET.connect();
269
+ }
270
+ }
271
+
272
+ function beginPanelStartWatch() {
273
+ startPending = true;
274
+ clearTimeout(startWatchTimer);
275
+ clearPanelDebug();
276
+ startWatchTimer = setTimeout(() => {
277
+ if (startPending && !cheatRunning) showPanelDebug('Program start did not confirm');
278
+ }, 6000);
279
+ }
280
+
281
+ function clearPanelStartWatch() {
282
+ startPending = false;
283
+ clearTimeout(startWatchTimer);
284
+ startWatchTimer = null;
285
+ }
286
+
287
+ function showPanelDebug(message) {
288
+ const el = document.getElementById('debug-toast');
289
+ if (!el) return;
290
+ el.textContent = message;
291
+ el.classList.add('show');
292
+ }
293
+
294
+ function clearPanelDebug() {
295
+ const el = document.getElementById('debug-toast');
296
+ if (!el) return;
297
+ el.textContent = '';
298
+ el.classList.remove('show');
264
299
  }
265
300
 
266
301
  function updateStatus() {
@@ -395,7 +430,22 @@ if (SOCKET) {
395
430
  }
396
431
  });
397
432
  SOCKET.on('configSync', (c) => { Object.assign(state, c); rerender(); });
398
- SOCKET.on('status', (s) => { cheatRunning = s.running; updateStatus(); });
433
+ SOCKET.on('status', (s) => {
434
+ cheatRunning = s.running;
435
+ if (cheatRunning) {
436
+ clearPanelStartWatch();
437
+ clearPanelDebug();
438
+ } else if (startPending) {
439
+ showPanelDebug('Program inactive after start');
440
+ }
441
+ updateStatus();
442
+ });
443
+ SOCKET.on('disconnect', () => {
444
+ if (startPending) showPanelDebug('Panel connection lost during start');
445
+ });
446
+ SOCKET.on('connect_error', () => {
447
+ if (startPending) showPanelDebug('Panel connection failed during start');
448
+ });
399
449
  SOCKET.on('killed', () => { document.body.innerHTML = '<div style="display:flex;align-items:center;justify-content:center;height:100vh;color:var(--danger);font-size:18px;font-family:var(--font)">Sensivity Terminated</div>'; });
400
450
  SOCKET.on('ytTrigger', (d) => {
401
451
  const el = document.getElementById('qr-overlay');