/trunk/WingMan/MouseKey/KeySimulator.cs/KeySimulator.cs |
@@ -0,0 +1,122 @@ |
using System; |
using System.IO; |
using System.Threading; |
using System.Threading.Tasks; |
using System.Windows.Forms; |
using MQTTnet; |
using SimWinInput; |
using WingMan.Communication; |
|
namespace WingMan.MouseKey |
{ |
public class KeySimulator : IDisposable |
{ |
public delegate void MouseKeyBindingExecuting(object sender, KeyBindingExecutingEventArgs args); |
|
public KeySimulator(LocalKeyBindings localLocalKeyBindings, MqttCommunication mqttCommunication, |
TaskScheduler formTaskScheduler, CancellationToken cancellationToken) |
{ |
LocalLocalKeyBindings = localLocalKeyBindings; |
MqttCommunication = mqttCommunication; |
TaskScheduler = formTaskScheduler; |
CancellationToken = cancellationToken; |
|
MqttCommunication.OnMessageReceived += OnMqttMessageReceived; |
} |
|
private MqttCommunication MqttCommunication { get; } |
private TaskScheduler TaskScheduler { get; } |
private CancellationToken CancellationToken { get; } |
private LocalKeyBindings LocalLocalKeyBindings { get; } |
|
public void Dispose() |
{ |
MqttCommunication.OnMessageReceived -= OnMqttMessageReceived; |
} |
|
public event MouseKeyBindingExecuting OnMouseKeyBindingExecuting; |
|
private async void OnMqttMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e) |
{ |
if (e.ApplicationMessage.Topic != "execute") |
return; |
|
using (var memoryStream = new MemoryStream(e.ApplicationMessage.Payload)) |
{ |
var executeMouseKeyBinding = |
(ExecuteKeyBinding) ExecuteKeyBinding.XmlSerializer.Deserialize(memoryStream); |
|
// Do not process own mouse key bindings. |
if (!string.Equals(executeMouseKeyBinding.Nick, MqttCommunication.Nick, StringComparison.Ordinal)) |
return; |
|
await Task.Delay(0, CancellationToken) |
.ContinueWith( |
_ => OnMouseKeyBindingExecuting?.Invoke(sender, |
new KeyBindingExecutingEventArgs(executeMouseKeyBinding.Nick, |
executeMouseKeyBinding.Name)), |
CancellationToken, |
TaskContinuationOptions.None, TaskScheduler); |
|
Simulate(executeMouseKeyBinding); |
} |
} |
|
private void Simulate(ExecuteKeyBinding executeBinding) |
{ |
foreach (var localBinding in LocalLocalKeyBindings.Bindings) |
{ |
if (!string.Equals(localBinding.Name, executeBinding.Name, StringComparison.Ordinal)) |
continue; |
|
// Press |
foreach (var key in localBinding.Keys) |
{ |
if (KeyConversion.StringToKeys.TryGetValue(key, out var pressKey)) |
{ |
SimKeyboard.KeyDown(pressKey); |
continue; |
} |
|
if (KeyConversion.StringToMouseButtons.TryGetValue(key, out var pressMouse)) |
switch (pressMouse) |
{ |
case MouseButtons.Left: |
SimMouse.Act(SimMouse.Action.LeftButtonDown, Cursor.Position.X, Cursor.Position.Y); |
break; |
case MouseButtons.Middle: |
SimMouse.Act(SimMouse.Action.MiddleButtonDown, Cursor.Position.X, Cursor.Position.Y); |
break; |
case MouseButtons.Right: |
SimMouse.Act(SimMouse.Action.RightButtonDown, Cursor.Position.X, Cursor.Position.Y); |
break; |
} |
} |
|
// Depress |
foreach (var key in localBinding.Keys) |
{ |
if (KeyConversion.StringToKeys.TryGetValue(key, out var pressKey)) |
{ |
SimKeyboard.KeyUp(pressKey); |
continue; |
} |
|
if (KeyConversion.StringToMouseButtons.TryGetValue(key, out var pressMouse)) |
switch (pressMouse) |
{ |
case MouseButtons.Left: |
SimMouse.Act(SimMouse.Action.LeftButtonUp, Cursor.Position.X, Cursor.Position.Y); |
break; |
case MouseButtons.Middle: |
SimMouse.Act(SimMouse.Action.MiddleButtonUp, Cursor.Position.X, Cursor.Position.Y); |
break; |
case MouseButtons.Right: |
SimMouse.Act(SimMouse.Action.RightButtonUp, Cursor.Position.X, Cursor.Position.Y); |
break; |
} |
} |
} |
} |
} |
} |