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 +144 -2
- package/package.json +1 -1
- package/public/css/style.css +5 -5
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
|
-
|
|
12
|
-
|
|
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
package/public/css/style.css
CHANGED
|
@@ -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:
|
|
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:
|
|
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;
|
|
345
|
+
.tgl .knob { height: 20px; width: 20px; flex-basis: 20px; }
|
|
346
346
|
.tgl input:checked + .track .knob,
|
|
347
|
-
.tgl input:checked ~ .knob { transform:
|
|
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; }
|