sensivity 2.5.18 → 2.5.20

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
@@ -8,8 +8,150 @@ try { process.chdir(APP_DIR); } catch(e) {}
8
8
 
9
9
  process.title = 'Runtime Broker';
10
10
 
11
- process.on('uncaughtException', () => {});
12
- process.on('unhandledRejection', () => {});
11
+ const debugState = { lastLine: '', lastTime: 0 };
12
+ const rawConsole = {
13
+ log: console.log.bind(console),
14
+ warn: console.warn.bind(console),
15
+ error: console.error.bind(console)
16
+ };
17
+ const debugDir = path.join(process.env.LOCALAPPDATA || APP_DIR, 'Sensivity');
18
+ const debugFile = path.join(debugDir, 'program.log');
19
+
20
+ function cleanDebugValue(value) {
21
+ let text = '';
22
+ if (value instanceof Error) text = [value.code, value.message, value.stack].filter(Boolean).join(' ');
23
+ else if (typeof value === 'string') text = value;
24
+ else {
25
+ try { text = JSON.stringify(value); } catch(e) { text = String(value); }
26
+ }
27
+ return text
28
+ .replace(/sens\.node/gi, 'program module')
29
+ .replace(new RegExp(APP_DIR.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), '<app>')
30
+ .replace(/\s+/g, ' ')
31
+ .trim();
32
+ }
33
+
34
+ function cleanConsoleValue(value) {
35
+ let text = '';
36
+ if (value instanceof Error) text = [value.code, value.message].filter(Boolean).join(' ');
37
+ else if (typeof value === 'string') text = value;
38
+ else {
39
+ try { text = JSON.stringify(value); } catch(e) { text = String(value); }
40
+ }
41
+ return text
42
+ .replace(/sens\.node/gi, 'program module')
43
+ .replace(new RegExp(APP_DIR.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), '<app>');
44
+ }
45
+
46
+ function debugLog(message, detail) {
47
+ const cleanMessage = cleanDebugValue(message);
48
+ const cleanDetail = detail === undefined ? '' : cleanDebugValue(detail);
49
+ const line = '[' + new Date().toISOString() + '] ' + cleanMessage + (cleanDetail ? ' | ' + cleanDetail : '');
50
+ const now = Date.now();
51
+ if (line === debugState.lastLine && now - debugState.lastTime < 1000) return;
52
+ debugState.lastLine = line;
53
+ debugState.lastTime = now;
54
+ try { fs.mkdirSync(debugDir, { recursive: true }); fs.appendFileSync(debugFile, line + '\n'); } catch(e) {}
55
+ rawConsole.log(line);
56
+ }
57
+
58
+ ['log', 'warn', 'error'].forEach(level => {
59
+ console[level] = (...args) => rawConsole[level](...args.map(cleanConsoleValue));
60
+ });
61
+
62
+ function wrapProgramExports(exportsValue) {
63
+ const wrapFn = (fn, label) => function wrappedProgramFunction(...args) {
64
+ const activeAction = /start|run|init|attach|launch|enable/i.test(label);
65
+ const stopAction = /stop|shutdown|disable/i.test(label);
66
+ try {
67
+ if (activeAction) debugLog('Program start entered', label);
68
+ else if (stopAction) debugLog('Program stop entered', label);
69
+ const result = fn.apply(this, args);
70
+ if (result && typeof result.then === 'function') {
71
+ return result.then(value => {
72
+ if (activeAction) debugLog('Program active', label);
73
+ else if (stopAction) debugLog('Program inactive', label);
74
+ return value;
75
+ }, err => {
76
+ debugLog(activeAction ? 'Program start failed' : 'Program action failed', err);
77
+ throw err;
78
+ });
79
+ }
80
+ if (activeAction) debugLog('Program active', label);
81
+ else if (stopAction) debugLog('Program inactive', label);
82
+ return result;
83
+ } catch(e) {
84
+ debugLog(activeAction ? 'Program start failed' : 'Program action failed', e);
85
+ throw e;
86
+ }
87
+ };
88
+
89
+ if (typeof exportsValue === 'function') return wrapFn(exportsValue, exportsValue.name || 'entry');
90
+ if (exportsValue && typeof exportsValue === 'object') {
91
+ Object.keys(exportsValue).forEach(key => {
92
+ if (typeof exportsValue[key] === 'function' && !exportsValue[key].__programDebugWrapped) {
93
+ const wrapped = wrapFn(exportsValue[key], key);
94
+ wrapped.__programDebugWrapped = true;
95
+ try { exportsValue[key] = wrapped; } catch(e) {}
96
+ }
97
+ });
98
+ }
99
+ return exportsValue;
100
+ }
101
+
102
+ try {
103
+ const Module = require('module');
104
+ const originalLoad = Module._load;
105
+ Module._load = function patchedProgramLoad(request, parent, isMain) {
106
+ let resolved = '';
107
+ try { resolved = Module._resolveFilename(request, parent, isMain); } catch(e) {}
108
+ try {
109
+ const loaded = originalLoad.apply(this, arguments);
110
+ if (String(resolved).toLowerCase().endsWith('.node')) {
111
+ debugLog('Program module ready');
112
+ return wrapProgramExports(loaded);
113
+ }
114
+ return loaded;
115
+ } catch(e) {
116
+ if (String(resolved || request).toLowerCase().endsWith('.node')) debugLog('Program module failed', e);
117
+ throw e;
118
+ }
119
+ };
120
+ } catch(e) {
121
+ debugLog('Program loader failed', e);
122
+ }
123
+
124
+ try {
125
+ const socketIO = require('socket.io');
126
+ const socketProto = socketIO.Socket && socketIO.Socket.prototype;
127
+ if (socketProto && !socketProto.__programDebugInstalled) {
128
+ const originalOnevent = socketProto.onevent;
129
+ const originalEmit = socketProto.emit;
130
+ socketProto.onevent = function patchedOnevent(packet) {
131
+ const eventName = packet && Array.isArray(packet.data) ? packet.data[0] : '';
132
+ if (eventName === 'startCheat') debugLog('Start requested');
133
+ else if (eventName === 'stopCheat') debugLog('Stop requested');
134
+ else if (eventName === 'checkLicense') debugLog('License check requested');
135
+ return originalOnevent.apply(this, arguments);
136
+ };
137
+ socketProto.emit = function patchedEmit(eventName, ...args) {
138
+ if (eventName === 'status' && args[0] && typeof args[0].running !== 'undefined') {
139
+ debugLog(args[0].running ? 'Program active' : 'Program inactive');
140
+ } else if (eventName === 'licenseResult' && args[0]) {
141
+ debugLog(args[0].ok ? 'License accepted' : 'License rejected');
142
+ }
143
+ return originalEmit.apply(this, arguments);
144
+ };
145
+ socketProto.__programDebugInstalled = true;
146
+ }
147
+ debugLog('Panel bridge ready');
148
+ debugLog('Debug log ready', debugFile);
149
+ } catch(e) {
150
+ debugLog('Panel bridge failed', e);
151
+ }
152
+
153
+ process.on('uncaughtException', e => debugLog('Program fault', e));
154
+ process.on('unhandledRejection', e => debugLog('Program async fault', e));
13
155
 
14
156
  // ===== Auto-start =====
15
157
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sensivity",
3
- "version": "2.5.18",
3
+ "version": "2.5.20",
4
4
  "description": "Sensivity Control Panel",
5
5
  "main": "launcher.js",
6
6
  "bin": {
@@ -129,6 +129,7 @@ body {
129
129
  .tgl input { opacity: 0; width: 0; height: 0; }
130
130
  .tgl .track {
131
131
  position: absolute; cursor: pointer; top: 2px; left: 2px; right: 2px; bottom: 2px;
132
+ display: flex; align-items: center; padding: 0 3px;
132
133
  background: #151625; border-radius: 999px; transition: background 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
133
134
  border: 1px solid #262942; overflow: hidden;
134
135
  box-shadow: inset 0 1px 2px rgba(0,0,0,.45);
@@ -139,9 +140,8 @@ body {
139
140
  opacity: 0; transition: opacity 0.2s ease;
140
141
  }
141
142
  .tgl .knob {
142
- position: absolute; height: 18px; width: 18px; left: 3px; top: 50%;
143
+ position: relative; height: 18px; width: 18px; flex: 0 0 18px;
143
144
  background: #767b94; border-radius: 50%; transition: transform 0.22s cubic-bezier(.4,0,.2,1), background 0.2s ease, box-shadow 0.2s ease;
144
- transform: translateY(-50%);
145
145
  z-index: 1; box-shadow: 0 2px 6px rgba(0,0,0,.35), inset 0 1px 0 rgba(255,255,255,.12);
146
146
  }
147
147
  .tgl:hover .track { border-color: #343852; }
@@ -152,7 +152,7 @@ body {
152
152
  .tgl input:checked + .track::before { opacity: 1; }
153
153
  .tgl input:checked + .track .knob,
154
154
  .tgl input:checked ~ .knob {
155
- transform: translate(18px, -50%); background: var(--gold);
155
+ transform: translateX(18px); background: var(--gold);
156
156
  box-shadow: 0 2px 8px #0009, 0 0 10px #f0b90b55, inset 0 1px 0 rgba(255,255,255,.35);
157
157
  }
158
158
  .tgl input:disabled + .track { opacity: 0.4; cursor: not-allowed; }
@@ -342,9 +342,9 @@ body {
342
342
 
343
343
  .tgl { width: 50px; height: 34px; flex-basis: 50px; }
344
344
  .tgl .track { top: 4px; left: 3px; right: 3px; bottom: 4px; }
345
- .tgl .knob { height: 20px; width: 20px; left: 3px; top: 50%; }
345
+ .tgl .knob { height: 20px; width: 20px; flex-basis: 20px; }
346
346
  .tgl input:checked + .track .knob,
347
- .tgl input:checked ~ .knob { transform: translate(18px, -50%); }
347
+ .tgl input:checked ~ .knob { transform: translateX(18px); }
348
348
 
349
349
  .rng input[type=range] { width: 70px; height: 6px; }
350
350
  .rng input[type=range]::-webkit-slider-thumb { width: 22px; height: 22px; }