WingMan

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 4  →  ?path2? @ 5
/trunk/WingMan/WingManForm.cs
@@ -1,67 +1,118 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Resources;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Gma.System.MouseKeyHook;
using WingMan.Communication;
using WingMan.Host;
using WingMan.MouseKey;
using WingMan.Properties;
 
namespace WingMan
{
public partial class WingManForm : Form
{
private MQTTServer MQTTServer { get; set; }
public WingManForm()
{
InitializeComponent();
 
private MQTTClient MQTTClient { get; set; }
MQTTCommunication = new MQTTCommunication();
 
private SemaphoreSlim MQTTServerSemaphore {get; set;} = new SemaphoreSlim(1, 1);
MouseKeyBindings = new MouseKeyBindings(new List<MouseKeyBinding>());
 
private SemaphoreSlim MQTTClientSemaphore { get; set; } = new SemaphoreSlim(1, 1);
HelmBindingSource = new BindingSource
{
DataSource = MouseKeyBindings.Bindings
};
HelmBindingsListBox.DisplayMember = "DisplayName";
HelmBindingsListBox.ValueMember = "Keys";
HelmBindingsListBox.DataSource = HelmBindingSource;
 
private static IKeyboardMouseEvents MouseKeyApplicationHook { get; set; }
MouseKeyBindingsExchange = new MouseKeyBindingsExchange();
WingBindingSource = new BindingSource
{
DataSource = MouseKeyBindingsExchange.ExchangeBindings
};
WingBindingsComboBox.DisplayMember = "Nick";
WingBindingsComboBox.ValueMember = "Names";
WingBindingsComboBox.DataSource = WingBindingSource;
 
private static IKeyboardMouseEvents MouseKeyGlobalHook { get; set; }
// Start lobby message synchronizer.
LobbyMessageSynchronizer = new LobbyMessageSynchronizer(MQTTCommunication);
LobbyMessageSynchronizer.OnLobbyMessageReceived += OnLobbyMessageReceived;
 
private List<string> MouseKeyCombo { get; set; }
// Start mouse key bindings synchronizer.
MouseKeyBindingsSynchronizer = new MouseKeyBindingsSynchronizer(MouseKeyBindings, MQTTCommunication);
MouseKeyBindingsSynchronizer.OnMouseKeyBindingsSynchronized += OnMouseKeyBindingsSynchronized;
}
 
private HelmBindings HelmBindings { get; set; }
private void OnMouseKeyBindingsSynchronized(object sender, MouseKeyBindingsSynchronizedEventArgs e)
{
this.Invoke((MethodInvoker) delegate
{
foreach (var binding in e.ExchangeBindings)
{
ActivityTextBox.AppendText(
$"{Strings.Synchronized_bindings_with_client} : {binding.Nick} : {binding.Names.Count}{Environment.NewLine}");
 
private BindingSource HelmBindingSource { get; set; }
 
public ConcurrentDictionary<string, HelmBindings> WingBindings { get; set; }
var exchangeBindings = MouseKeyBindingsExchange.ExchangeBindings.FirstOrDefault(exchangeBinding =>
string.Equals(exchangeBinding.Nick, binding.Nick, StringComparison.Ordinal));
 
public WingManForm()
{
InitializeComponent();
// If the nick has not been registered add it.
if (exchangeBindings == null)
{
MouseKeyBindingsExchange.ExchangeBindings.Add(binding);
continue;
}
 
MouseKeyGlobalHook = Hook.GlobalEvents();
// If the nick has been added, then update the binding names.
exchangeBindings.Names = binding.Names;
 
MQTTClient = new MQTTClient(this);
MQTTServer = new MQTTServer(this);
// Update wing list box.
var selectedExchangeBinding = (MouseKeyBindingExchange)WingBindingsComboBox.SelectedItem;
if (selectedExchangeBinding == null || !string.Equals(selectedExchangeBinding.Nick, binding.Nick))
continue;
 
HelmBindings = new HelmBindings();
HelmBindings.Bindings = new List<HelmBinding>();
WingBindingsListBox.Items.Clear();
WingBindingsListBox.DisplayMember = "Name";
WingBindingsListBox.ValueMember = "Name";
WingBindingsListBox.Items.AddRange(exchangeBindings.Names.Select(name => (object)name).ToArray());
 
HelmBindingSource = new BindingSource();
HelmBindingSource.DataSource = HelmBindings.Bindings;
}
 
HelmBindingsListBox.DisplayMember = "DisplayName";
HelmBindingsListBox.ValueMember = "Keys";
HelmBindingsListBox.DataSource = HelmBindingSource;
WingBindingSource.ResetBindings(false);
 
WingBindings = new ConcurrentDictionary<string, HelmBindings>();
});
}
 
private static IKeyboardMouseEvents MouseKeyApplicationHook { get; set; }
 
private List<string> MouseKeyCombo { get; set; }
 
private MouseKeyBindings MouseKeyBindings { get; }
 
private BindingSource HelmBindingSource { get; }
 
private BindingSource WingBindingSource { get; set; }
 
private MouseKeyBindingsExchange MouseKeyBindingsExchange { get; set; }
 
public MQTTCommunication MQTTCommunication { get; set; }
 
public LobbyMessageSynchronizer LobbyMessageSynchronizer { get; set; }
 
public MouseKeyBindingsSynchronizer MouseKeyBindingsSynchronizer { get; set; }
 
private void OnLobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e)
{
LobbyTextBox.Invoke((MethodInvoker) delegate
{
LobbyTextBox.AppendText($"{e.Nick} : {e.Message}{Environment.NewLine}");
});
}
 
private void AddressTextBoxClick(object sender, EventArgs e)
{
Address.BackColor = Color.Empty;
@@ -75,15 +126,18 @@
private async void HostButtonClickAsync(object sender, EventArgs e)
{
// Stop the MQTT server if it is running.
if (MQTTServer.ServerRunning)
if (MQTTCommunication.Running)
{
await StopServer();
toolStripStatusLabel.Text = Properties.Strings.Server_stopped;
await MQTTCommunication.Stop().ConfigureAwait(false);
toolStripStatusLabel.Text = Strings.Server_stopped;
HostButton.BackColor = Color.Empty;
 
// Enable controls.
ConnectButton.Enabled = true;
EnableConnectionControls();
Address.Enabled = true;
Port.Enabled = true;
Nick.Enabled = true;
 
return;
}
 
@@ -91,29 +145,17 @@
return;
 
// Start the MQTT server.
await StartServer(ipAddress, port, nick);
toolStripStatusLabel.Text = Properties.Strings.Server_started;
await MQTTCommunication.Start(MQTTCommunicationType.Server, ipAddress, port, nick).ConfigureAwait(false);
toolStripStatusLabel.Text = Strings.Server_started;
HostButton.BackColor = Color.Aquamarine;
 
// Disable controls
ConnectButton.Enabled = false;
DisableConnectionControls();
}
 
private void DisableConnectionControls()
{
Address.Enabled = false;
Port.Enabled = false;
Nick.Enabled = false;
}
 
private void EnableConnectionControls()
{
Address.Enabled = true;
Port.Enabled = true;
Nick.Enabled = true;
}
 
private bool ValidateAddressPort(out IPAddress address, out int port, out string nick)
{
address = IPAddress.Any;
@@ -159,41 +201,17 @@
return true;
}
 
private async Task StartServer(IPAddress ipAddress, int port, string nick)
{
await MQTTServerSemaphore.WaitAsync();
try
{
await MQTTServer.Start(ipAddress, port, nick);
}
finally
{
MQTTServerSemaphore.Release();
}
}
 
private async Task StopServer()
{
await MQTTServerSemaphore.WaitAsync();
try
{
await MQTTServer.Stop();
}
finally
{
MQTTServerSemaphore.Release();
}
}
 
private async void ConnectButtonClickAsync(object sender, EventArgs e)
{
if (MQTTClient.ClientRunning)
if (MQTTCommunication.Running)
{
await StopClient();
ConnectButton.Text = Properties.Strings.Connect;
await MQTTCommunication.Stop().ConfigureAwait(false);
ConnectButton.Text = Strings.Connect;
ConnectButton.BackColor = Color.Empty;
 
EnableConnectionControls();
Address.Enabled = true;
Port.Enabled = true;
Nick.Enabled = true;
HostButton.Enabled = true;
return;
}
@@ -201,57 +219,26 @@
if (!ValidateAddressPort(out var ipAddress, out var port, out var nick))
return;
 
await StartClient(ipAddress, port, nick);
await MQTTCommunication.Start(MQTTCommunicationType.Client, ipAddress, port, nick).ConfigureAwait(false);
 
toolStripStatusLabel.Text = Properties.Strings.Client_started;
ConnectButton.Text = Properties.Strings.Disconnect;
toolStripStatusLabel.Text = Strings.Client_started;
ConnectButton.Text = Strings.Disconnect;
ConnectButton.BackColor = Color.Aquamarine;
 
HostButton.Enabled = false;
DisableConnectionControls();
Address.Enabled = false;
Port.Enabled = false;
Nick.Enabled = false;
}
 
private async Task StopClient()
{
await MQTTClientSemaphore.WaitAsync();
try
{
await MQTTClient.Stop();
}
finally
{
MQTTClientSemaphore.Release();
}
}
 
private async Task StartClient(IPAddress ipAddress, int port, string nick)
{
await MQTTClientSemaphore.WaitAsync();
try
{
await MQTTClient.Start(ipAddress, port, nick);
}
finally
{
MQTTClientSemaphore.Release();
}
}
 
private async void LobbySayTextBoxKeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode != Keys.Enter)
return;
 
if (MQTTServer.ServerRunning)
{
await MQTTServer.BroadcastLobbyMessage(LobbySayTextBox.Text);
}
await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text).ConfigureAwait(false);
 
if (MQTTClient.ClientRunning)
{
await MQTTClient.BroadcastLobbyMessage(LobbySayTextBox.Text);
}
 
LobbySayTextBox.Text = string.Empty;
}
 
private void HelmAddButtonClick(object sender, EventArgs e)
@@ -271,21 +258,18 @@
MouseKeyApplicationHook.KeyUp += MouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown += MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.MouseUp += MouseKeyHookOnMouseUp;
 
}
 
private void MouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
{
HelmBindings.Bindings.Add(new HelmBinding
{
Keys = MouseKeyCombo,
Name = HelmNameTextBox.Text
});
MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo));
 
HelmBindingSource.ResetBindings(false);
 
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
 
MouseKeyApplicationHook.Dispose();
 
@@ -295,16 +279,14 @@
 
private void MouseKeyHookOnMouseUp(object sender, MouseEventArgs e)
{
HelmBindings.Bindings.Add(new HelmBinding
{
Keys = MouseKeyCombo,
Name = HelmNameTextBox.Text
});
MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo));
 
HelmBindingSource.ResetBindings(false);
 
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
 
MouseKeyApplicationHook.Dispose();
 
@@ -315,7 +297,7 @@
 
private void MouseKeyHookOnMouseDown(object sender, MouseEventArgs e)
{
MouseKeyCombo.Add(MouseButtonToName(e.Button));
MouseKeyCombo.Add(e.Button.ToDisplayName());
}
 
private void MouseKeyHookOnKeyDown(object sender, KeyEventArgs e)
@@ -322,7 +304,7 @@
{
e.SuppressKeyPress = true;
 
MouseKeyCombo.Add(KeyCodeToName((int) e.KeyCode));
MouseKeyCombo.Add(e.KeyCode.ToDisplayName());
}
 
private void HelmNameTextBoxClick(object sender, EventArgs e)
@@ -330,431 +312,33 @@
HelmNameTextBox.BackColor = Color.Empty;
}
 
private string MouseButtonToName(MouseButtons button)
private void HelmRemoveButtonClick(object sender, EventArgs e)
{
var mouseButton = string.Empty;
switch (button)
{
case MouseButtons.Left:
mouseButton = "Left Mouse Button";
break;
case MouseButtons.Middle:
mouseButton = "Middle Mouse Button";
break;
case MouseButtons.Right:
mouseButton = "Right Mouse Button";
break;
}
var helmBinding = (MouseKeyBinding) HelmBindingsListBox.SelectedItem;
if (helmBinding == null)
return;
 
return mouseButton;
MouseKeyBindings.Bindings.Remove(helmBinding);
HelmBindingSource.ResetBindings(false);
}
 
private string KeyCodeToName(int code)
private async void LobbySayButtonClick(object sender, EventArgs e)
{
var keyString = string.Empty;
switch (code)
{
case 0:
break;
case 1:
keyString = "Mouse Left";
break;
case 2:
keyString = "Mouse Right";
break;
case 3:
keyString = "Cancel";
break;
case 4:
keyString = "Mouse Middle";
break;
case 5:
keyString = "Special 1";
break;
case 6:
keyString = "Special 2";
break;
case 8:
keyString = "Back";
break;
case 9:
keyString = "TAB";
break;
case 12:
keyString = "Clear";
break;
case 13:
keyString = "Enter";
break;
case 16:
keyString = "Shift";
break;
case 17:
keyString = "Ctrl";
break;
case 18:
keyString = "Menu";
break;
case 19:
keyString = "Pause";
break;
case 20:
keyString = "Caps Lock";
break;
case 21:
keyString = "Kana/Hangul";
break;
case 23:
keyString = "Junja";
break;
case 24:
keyString = "Final";
break;
case 25:
keyString = "Hanja/Kanji";
break;
case 27:
keyString = "Esc";
break;
case 28:
keyString = "Convert";
break;
case 29:
keyString = "NonConvert";
break;
case 30:
keyString = "Accept";
break;
case 31:
keyString = "Mode";
break;
case 32:
keyString = "Space";
break;
case 33:
keyString = "Page Up";
break;
case 34:
keyString = "Page Down";
break;
case 35:
keyString = "End";
break;
case 36:
keyString = "Home";
break;
case 37:
keyString = "Left";
break;
case 38:
keyString = "Up";
break;
case 39:
keyString = "Right";
break;
case 40:
keyString = "Down";
break;
case 41:
keyString = "Select";
break;
case 42:
keyString = "Print";
break;
case 43:
keyString = "Execute";
break;
case 44:
keyString = "Snapshot";
break;
case 45:
keyString = "Insert";
break;
case 46:
keyString = "Delete";
break;
case 47:
keyString = "Help";
break;
case 48:
keyString = "Num 0";
break;
case 49:
keyString = "Num 1";
break;
case 50:
keyString = "Num 2";
break;
case 51:
keyString = "Num 3";
break;
case 52:
keyString = "Num 4";
break;
case 53:
keyString = "Num 5";
break;
case 54:
keyString = "Num 6";
break;
case 55:
keyString = "Num 7";
break;
case 56:
keyString = "Num 8";
break;
case 57:
keyString = "Num 9";
break;
case 65:
keyString = "A";
break;
case 66:
keyString = "B";
break;
case 67:
keyString = "C";
break;
case 68:
keyString = "D";
break;
case 69:
keyString = "E";
break;
case 70:
keyString = "F";
break;
case 71:
keyString = "G";
break;
case 72:
keyString = "H";
break;
case 73:
keyString = "I";
break;
case 74:
keyString = "J";
break;
case 75:
keyString = "K";
break;
case 76:
keyString = "L";
break;
case 77:
keyString = "M";
break;
case 78:
keyString = "N";
break;
case 79:
keyString = "O";
break;
case 80:
keyString = "P";
break;
case 81:
keyString = "Q";
break;
case 82:
keyString = "R";
break;
case 83:
keyString = "S";
break;
case 84:
keyString = "T";
break;
case 85:
keyString = "U";
break;
case 86:
keyString = "V";
break;
case 87:
keyString = "W";
break;
case 88:
keyString = "X";
break;
case 89:
keyString = "Y";
break;
case 90:
keyString = "Z";
break;
case 91:
keyString = "Windows Left";
break;
case 92:
keyString = "Windows Right";
break;
case 93:
keyString = "Application";
break;
case 95:
keyString = "Sleep";
break;
case 96:
keyString = "NumPad 0";
break;
case 97:
keyString = "NumPad 1";
break;
case 98:
keyString = "NumPad 2";
break;
case 99:
keyString = "NumPad 3";
break;
case 100:
keyString = "NumPad 4";
break;
case 101:
keyString = "NumPad 5";
break;
case 102:
keyString = "NumPad 6";
break;
case 103:
keyString = "NumPad 7";
break;
case 104:
keyString = "NumPad 8";
break;
case 105:
keyString = "NumPad 9";
break;
case 106:
keyString = "NumPad *";
break;
case 107:
keyString = "NumPad +";
break;
case 108:
keyString = "NumPad .";
break;
case 109:
keyString = "NumPad -";
break;
case 110:
keyString = "NumPad ,";
break;
case 111:
keyString = "NumPad /";
break;
case 112:
keyString = "F1";
break;
case 113:
keyString = "F2";
break;
case 114:
keyString = "F3";
break;
case 115:
keyString = "F4";
break;
case 116:
keyString = "F5";
break;
case 117:
keyString = "F6";
break;
case 118:
keyString = "F7";
break;
case 119:
keyString = "F8";
break;
case 120:
keyString = "F9";
break;
case 121:
keyString = "F10";
break;
case 122:
keyString = "F11";
break;
case 123:
keyString = "F12";
break;
case 124:
keyString = "F13";
break;
case 125:
keyString = "F14";
break;
case 126:
keyString = "F15";
break;
case 127:
keyString = "F16";
break;
case 128:
keyString = "F17";
break;
case 129:
keyString = "F18";
break;
case 130:
keyString = "F19";
break;
case 131:
keyString = "F20";
break;
case 132:
keyString = "F21";
break;
case 133:
keyString = "F22";
break;
case 134:
keyString = "F23";
break;
case 135:
keyString = "F24";
break;
case 144:
keyString = "Num lock";
break;
case 145:
keyString = "Scroll";
break;
case 160:
keyString = "Shift Left";
break;
case 161:
keyString = "Shift Right";
break;
case 162:
keyString = "Ctrl Left";
break;
case 163:
keyString = "Ctrl Right";
break;
case 164:
keyString = "Menu Left";
break;
case 165:
keyString = "Menu Right";
break;
default:
break;
}
await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text).ConfigureAwait(false);
 
return keyString;
LobbySayTextBox.Text = string.Empty;
}
 
private void HelmRemoveButtonClick(object sender, EventArgs e)
private void WingBindingsComboBoxIndexChanged(object sender, EventArgs e)
{
var helmBinding = (HelmBinding)HelmBindingsListBox.SelectedItem;
if (helmBinding == null)
var exchangeBinding = (MouseKeyBindingExchange) WingBindingsComboBox.SelectedItem;
if (exchangeBinding == null)
return;
 
HelmBindings.Bindings.Remove(helmBinding);
HelmBindingSource.ResetBindings(false);
WingBindingsListBox.Items.Clear();
WingBindingsListBox.DisplayMember = "Name";
WingBindingsListBox.ValueMember = "Name";
WingBindingsListBox.Items.AddRange(exchangeBinding.Names.Select(name => (object)name).ToArray());
}
}
}