WingMan

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 4  →  ?path2? @ 5
File deleted
/trunk/WingMan/LobbyMessage.cs
File deleted
/trunk/WingMan/HelmBindings.cs
File deleted
/trunk/WingMan/HelmBinding.cs
File deleted
/trunk/WingMan/Communication/MQTTServer.cs
File deleted
/trunk/WingMan/Communication/MQTTClient.cs
/trunk/WingMan/Communication/MQTTCommunication.cs
@@ -0,0 +1,296 @@
using System;
using System.Net;
using System.Threading.Tasks;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Server;
using MqttClientConnectedEventArgs = MQTTnet.Client.MqttClientConnectedEventArgs;
using MqttClientDisconnectedEventArgs = MQTTnet.Client.MqttClientDisconnectedEventArgs;
 
namespace WingMan.Communication
{
public class MQTTCommunication
{
public MQTTCommunication(IPAddress ipAddress, int port, string nick) :this()
{
IPAddress = ipAddress;
Port = port;
Nick = nick;
}
 
public MQTTCommunication()
{
Client = new MqttFactory().CreateManagedMqttClient();
Server = new MqttFactory().CreateMqttServer();
}
 
private IManagedMqttClient Client { get; }
 
private IMqttServer Server { get; }
 
public bool Running { get; set; }
 
public string Nick { get; set; }
 
private IPAddress IPAddress { get; set; }
 
private int Port { get; set; }
 
public MQTTCommunicationType Type { get; set; }
 
public delegate void MessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e);
 
public event MessageReceived OnMessageReceived;
 
public delegate void ClientConnected(object sender, MqttClientConnectedEventArgs e);
 
public event ClientConnected OnClientConnected;
 
public delegate void ClientDisconnected(object sender, MqttClientDisconnectedEventArgs e);
 
public event ClientDisconnected OnClientDisconnected;
 
public delegate void ClientConnectionFailed(object sender, MqttManagedProcessFailedEventArgs e);
 
public event ClientConnectionFailed OnClientConnectionFailed;
 
public delegate void ClientUnsubscribed(object sender, MqttClientUnsubscribedTopicEventArgs e);
 
public event ClientUnsubscribed OnClientUnsubscribed;
 
public delegate void ClientSubscribed(object sender, MqttClientSubscribedTopicEventArgs e);
 
public event ClientSubscribed OnClientSubscribed;
 
public delegate void ServerClientDisconnected(object sender, MQTTnet.Server.MqttClientDisconnectedEventArgs e);
 
public event ServerClientDisconnected OnServerClientDisconnected;
 
public delegate void ServerClientConnected(object sender, MQTTnet.Server.MqttClientConnectedEventArgs e);
 
public event ServerClientConnected OnServerClientConnected;
 
public delegate void ServerStarted(object sender, EventArgs e);
 
public event ServerStarted OnServerStarted;
 
public delegate void ServerStopped(object sender, EventArgs e);
 
public event ServerStopped OnServerStopped;
 
public async Task Start(MQTTCommunicationType type, IPAddress ipAddress, int port, string nick)
{
Type = type;
IPAddress = ipAddress;
Port = port;
Nick = nick;
 
switch (type)
{
case MQTTCommunicationType.Client:
await StartClient().ConfigureAwait(false);
break;
case MQTTCommunicationType.Server:
await StartServer().ConfigureAwait(false);
break;
}
}
 
private async Task StartClient()
{
var clientOptions = new MqttClientOptionsBuilder()
.WithTcpServer(IPAddress.ToString(), Port);
 
// Setup and start a managed MQTT client.
var options = new ManagedMqttClientOptionsBuilder()
.WithAutoReconnectDelay(TimeSpan.FromSeconds(5))
.WithClientOptions(clientOptions.Build())
.Build();
 
BindClientHandlers();
 
await Client.SubscribeAsync(
new TopicFilterBuilder()
.WithTopic("lobby")
.Build()
).ConfigureAwait(false);
 
await Client.SubscribeAsync(
new TopicFilterBuilder()
.WithTopic("exchange")
.Build()
).ConfigureAwait(false);
 
await Client.StartAsync(options).ConfigureAwait(false);
 
Running = true;
}
 
private async Task StopClient()
{
UnbindClientHandlers();
 
await Client.StopAsync().ConfigureAwait(false);
}
 
public void BindClientHandlers()
{
Client.Connected += ClientOnConnected;
Client.Disconnected += ClientOnDisconnected;
Client.ConnectingFailed += ClientOnConnectingFailed;
Client.ApplicationMessageReceived += ClientOnApplicationMessageReceived;
}
 
public void UnbindClientHandlers()
{
Client.Connected -= ClientOnConnected;
Client.Disconnected -= ClientOnDisconnected;
Client.ConnectingFailed -= ClientOnConnectingFailed;
Client.ApplicationMessageReceived -= ClientOnApplicationMessageReceived;
}
 
private void ClientOnApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
{
OnMessageReceived?.Invoke(sender, e);
}
 
private void ClientOnConnectingFailed(object sender, MqttManagedProcessFailedEventArgs e)
{
OnClientConnectionFailed?.Invoke(sender, e);
}
 
private void ClientOnDisconnected(object sender, MqttClientDisconnectedEventArgs e)
{
OnClientDisconnected?.Invoke(sender, e);
}
 
private void ClientOnConnected(object sender, MqttClientConnectedEventArgs e)
{
OnClientConnected?.Invoke(sender, e);
}
 
private async Task StartServer()
{
var optionsBuilder = new MqttServerOptionsBuilder()
.WithDefaultEndpointBoundIPAddress(IPAddress)
.WithSubscriptionInterceptor(MQTTSubscriptionIntercept)
.WithDefaultEndpointPort(Port);
 
BindServerHandlers();
 
await Server.StartAsync(optionsBuilder.Build()).ConfigureAwait(false);
 
Running = true;
}
 
private async Task StopServer()
{
UnbindServerHandlers();
 
await Server.StopAsync().ConfigureAwait(false);
}
 
private void MQTTSubscriptionIntercept(MqttSubscriptionInterceptorContext context)
{
if (context.TopicFilter.Topic != "lobby" &&
context.TopicFilter.Topic != "exchange")
{
context.AcceptSubscription = false;
context.CloseConnection = true;
return;
}
 
context.AcceptSubscription = true;
context.CloseConnection = false;
}
 
private void BindServerHandlers()
{
Server.Started += ServerOnStarted;
Server.Stopped += ServerOnStopped;
Server.ClientConnected += ServerOnClientConnected;
Server.ClientDisconnected += ServerOnClientDisconnected;
Server.ClientSubscribedTopic += ServerOnClientSubscribedTopic;
Server.ClientUnsubscribedTopic += ServerOnClientUnsubscribedTopic;
Server.ApplicationMessageReceived += ServerOnApplicationMessageReceived;
}
 
private void UnbindServerHandlers()
{
Server.Started -= ServerOnStarted;
Server.Stopped -= ServerOnStopped;
Server.ClientConnected -= ServerOnClientConnected;
Server.ClientDisconnected -= ServerOnClientDisconnected;
Server.ClientSubscribedTopic -= ServerOnClientSubscribedTopic;
Server.ClientUnsubscribedTopic -= ServerOnClientUnsubscribedTopic;
Server.ApplicationMessageReceived -= ServerOnApplicationMessageReceived;
}
 
private void ServerOnApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
{
OnMessageReceived?.Invoke(sender, e);
}
 
private void ServerOnClientUnsubscribedTopic(object sender, MqttClientUnsubscribedTopicEventArgs e)
{
OnClientUnsubscribed?.Invoke(sender, e);
}
 
private void ServerOnClientSubscribedTopic(object sender, MqttClientSubscribedTopicEventArgs e)
{
OnClientSubscribed?.Invoke(sender, e);
}
 
private void ServerOnClientDisconnected(object sender, MQTTnet.Server.MqttClientDisconnectedEventArgs e)
{
OnServerClientDisconnected?.Invoke(sender, e);
}
 
private void ServerOnClientConnected(object sender, MQTTnet.Server.MqttClientConnectedEventArgs e)
{
OnServerClientConnected?.Invoke(sender, e);
}
 
private void ServerOnStopped(object sender, EventArgs e)
{
OnServerStopped?.Invoke(sender, e);
}
 
private void ServerOnStarted(object sender, EventArgs e)
{
OnServerStarted?.Invoke(sender, e);
}
 
public async Task Stop()
{
switch (Type)
{
case MQTTCommunicationType.Server:
await StopServer().ConfigureAwait(false);
break;
case MQTTCommunicationType.Client:
await StopClient().ConfigureAwait(false);
break;
}
 
Running = false;
}
 
public async Task Broadcast(string topic, byte[] payload)
{
switch (Type)
{
case MQTTCommunicationType.Client:
await Client.PublishAsync(new ManagedMqttApplicationMessage
{
ApplicationMessage = new MqttApplicationMessage { Topic = topic, Payload = payload }
}).ConfigureAwait(false);
break;
case MQTTCommunicationType.Server:
await Server.PublishAsync(new MqttApplicationMessage {Topic = topic, Payload = payload}).ConfigureAwait(false);
break;
}
}
}
}
/trunk/WingMan/Communication/MQTTCommunicationType.cs
@@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace WingMan
{
public enum MQTTCommunicationType
{
Server,
Client
}
}
/trunk/WingMan/Lobby/LobbyMessage.cs
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
 
namespace WingMan
{
public class LobbyMessage
{
public string Message { get; set; }
public string Nick { get; set; }
 
[XmlIgnore] public static XmlSerializer XmlSerializer = new XmlSerializer(typeof(LobbyMessage));
}
}
/trunk/WingMan/Lobby/LobbyMessageReceivedEventArgs.cs
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace WingMan
{
public class LobbyMessageReceivedEventArgs : EventArgs
{
public string Nick { get; set; }
 
public string Message { get; set; }
 
public LobbyMessageReceivedEventArgs(string nick, string message)
{
Nick = nick;
Message = message;
}
}
}
/trunk/WingMan/Lobby/LobbyMessageSynchronizer.cs
@@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using MQTTnet;
using WingMan.Communication;
 
namespace WingMan
{
public class LobbyMessageSynchronizer : IDisposable
{
public delegate void LobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e);
 
public event LobbyMessageReceived OnLobbyMessageReceived;
private MQTTCommunication MQTTCommunication { get; set; }
public LobbyMessageSynchronizer(MQTTCommunication MQTTCommunication)
{
this.MQTTCommunication = MQTTCommunication;
 
MQTTCommunication.OnMessageReceived += MqttCommunicationOnOnMessageReceived;
}
 
private void MqttCommunicationOnOnMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
{
if(e.ApplicationMessage.Topic != "lobby")
return;
 
using (var memoryStream = new MemoryStream(e.ApplicationMessage.Payload))
{
var lobbyMessage = (LobbyMessage)LobbyMessage.XmlSerializer.Deserialize(memoryStream);
 
OnLobbyMessageReceived?.Invoke(sender, new LobbyMessageReceivedEventArgs(lobbyMessage.Nick, lobbyMessage.Message));
}
}
 
public async Task Broadcast(string message)
{
using (var memoryStream = new MemoryStream())
{
LobbyMessage.XmlSerializer.Serialize(memoryStream, new LobbyMessage
{
Nick = MQTTCommunication.Nick,
Message = message
});
 
memoryStream.Position = 0L;
 
await MQTTCommunication.Broadcast("lobby", memoryStream.ToArray()).ConfigureAwait(false);
}
}
 
public void Dispose()
{
MQTTCommunication.OnMessageReceived -= MqttCommunicationOnOnMessageReceived;
}
}
}
/trunk/WingMan/MouseKey/MouseKeyBinding.cs
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace WingMan
{
public class MouseKeyBinding
{
public MouseKeyBinding()
{
 
}
public MouseKeyBinding(string name, List<string> keys) :this()
{
Name = name;
Keys = keys;
}
 
public string DisplayName => $"{Name} ({string.Join(" + ", Keys.ToArray())})";
 
public string Name { get; set; } = string.Empty;
 
public List<string> Keys { get; set; } = new List<string>();
}
}
/trunk/WingMan/MouseKey/MouseKeyBindingExchange.cs
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace WingMan.MouseKey
{
public class MouseKeyBindingExchange
{
public string Nick { get; set; }
 
public List<string> Names { get; set; }
}
}
/trunk/WingMan/MouseKey/MouseKeyBindings.cs
@@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
 
namespace WingMan
{
public class MouseKeyBindings
{
public MouseKeyBindings()
{
 
}
public MouseKeyBindings(List<MouseKeyBinding> bindings) : this()
{
Bindings = bindings;
}
 
public List<MouseKeyBinding> Bindings { get; set; }
}
}
/trunk/WingMan/MouseKey/MouseKeyBindingsExchange.cs
@@ -0,0 +1,31 @@
using System.Collections.Generic;
using System.Linq;
using System.Xml.Serialization;
using WingMan.MouseKey;
 
namespace WingMan
{
public class MouseKeyBindingsExchange
{
[XmlIgnore] public static readonly XmlSerializer XmlSerializer =
new XmlSerializer(typeof(MouseKeyBindingsExchange));
 
public MouseKeyBindingsExchange()
{
}
 
public MouseKeyBindingsExchange(string nick, MouseKeyBindings mouseKeyBindings) : this()
{
Nick = nick;
ExchangeBindings.Add(new MouseKeyBindingExchange
{
Nick = Nick,
Names = mouseKeyBindings.Bindings.Select(binding => binding.Name).ToList()
});
}
 
public string Nick { get; set; } = string.Empty;
 
public List<MouseKeyBindingExchange> ExchangeBindings { get; set; } = new List<MouseKeyBindingExchange>();
}
}
/trunk/WingMan/MouseKey/MouseKeyBindingsSynchronizedEventArgs.cs
@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace WingMan.MouseKey
{
public class MouseKeyBindingsSynchronizedEventArgs : EventArgs
{
public List<MouseKeyBindingExchange> ExchangeBindings { get; set; }
 
public MouseKeyBindingsSynchronizedEventArgs(List<MouseKeyBindingExchange> mouseKeyExchangeBindings)
{
ExchangeBindings = mouseKeyExchangeBindings;
}
}
}
/trunk/WingMan/MouseKey/MouseKeyBindingsSynchronizer.cs
@@ -0,0 +1,88 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet;
using MQTTnet.Extensions.ManagedClient;
using WingMan.Communication;
 
namespace WingMan.MouseKey
{
public class MouseKeyBindingsSynchronizer
{
public delegate void MouseKeyBindingsSynchronized(object sender, MouseKeyBindingsSynchronizedEventArgs e);
public event MouseKeyBindingsSynchronized OnMouseKeyBindingsSynchronized;
 
private MouseKeyBindings MouseKeyBindings { get; set; }
 
private ConcurrentDictionary<string, List<MouseKeyBindingExchange>> SynchronizedMouseKeyBindings { get; set; }
 
private MQTTCommunication MQTTCommunication { get; set; }
 
private CancellationTokenSource SynchronizationCancellationTokenSource { get; set; }
 
public MouseKeyBindingsSynchronizer(MouseKeyBindings mouseKeyBindings, MQTTCommunication MQTTCommunication)
{
MouseKeyBindings = mouseKeyBindings;
this.MQTTCommunication = MQTTCommunication;
 
SynchronizedMouseKeyBindings = new ConcurrentDictionary<string, List<MouseKeyBindingExchange>>();
 
MQTTCommunication.OnMessageReceived += MqttCommunicationOnOnMessageReceived;
 
SynchronizationCancellationTokenSource = new CancellationTokenSource();
 
Task.Run(Synchronize, SynchronizationCancellationTokenSource.Token);
}
 
private void MqttCommunicationOnOnMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
{
if (e.ApplicationMessage.Topic != "exchange")
return;
 
using (var memoryStream = new MemoryStream(e.ApplicationMessage.Payload))
{
memoryStream.Position = 0L;
 
var mouseKeyBindingsExchange = (MouseKeyBindingsExchange)MouseKeyBindingsExchange.XmlSerializer.Deserialize(memoryStream);
 
if (SynchronizedMouseKeyBindings.TryGetValue(mouseKeyBindingsExchange.Nick, out var mouseKeyBinding) &&
mouseKeyBinding.SequenceEqual(mouseKeyBindingsExchange.ExchangeBindings))
return;
 
// Nick does not exist so the bindings will be added.
SynchronizedMouseKeyBindings.AddOrUpdate(mouseKeyBindingsExchange.Nick,
mouseKeyBindingsExchange.ExchangeBindings, (s, list) => mouseKeyBindingsExchange.ExchangeBindings);
 
OnMouseKeyBindingsSynchronized?.Invoke(sender,
new MouseKeyBindingsSynchronizedEventArgs(
mouseKeyBindingsExchange.ExchangeBindings));
}
}
 
private async Task Synchronize()
{
do
{
await Task.Delay(1000).ConfigureAwait(false);
 
if (!MouseKeyBindings.Bindings.Any())
continue;
 
using (var memoryStream = new MemoryStream())
{
MouseKeyBindingsExchange.XmlSerializer.Serialize(memoryStream, new MouseKeyBindingsExchange(MQTTCommunication.Nick, MouseKeyBindings));
 
memoryStream.Position = 0L;
 
await MQTTCommunication.Broadcast("exchange", memoryStream.ToArray()).ConfigureAwait(false);
}
 
} while (!SynchronizationCancellationTokenSource.Token.IsCancellationRequested);
}
}
}
/trunk/WingMan/Properties/Strings.Designer.cs
@@ -133,6 +133,15 @@
}
/// <summary>
/// Looks up a localized string similar to Matched helm key binding.
/// </summary>
internal static string Matched_helm_key_binding {
get {
return ResourceManager.GetString("Matched_helm_key_binding", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Server started.
/// </summary>
internal static string Server_started {
@@ -149,5 +158,14 @@
return ResourceManager.GetString("Server_stopped", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Synchronized bindings with client.
/// </summary>
internal static string Synchronized_bindings_with_client {
get {
return ResourceManager.GetString("Synchronized_bindings_with_client", resourceCulture);
}
}
}
}
/trunk/WingMan/Properties/Strings.resx
@@ -141,6 +141,9 @@
<data name="Disconnect" xml:space="preserve">
<value>Disconnect</value>
</data>
<data name="Matched_helm_key_binding" xml:space="preserve">
<value>Matched helm key binding</value>
</data>
<data name="Server_started" xml:space="preserve">
<value>Server started</value>
</data>
@@ -147,4 +150,7 @@
<data name="Server_stopped" xml:space="preserve">
<value>Server stopped</value>
</data>
<data name="Synchronized_bindings_with_client" xml:space="preserve">
<value>Synchronized bindings with client</value>
</data>
</root>
/trunk/WingMan/Utilities.cs
@@ -0,0 +1,429 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
 
namespace WingMan
{
public static class Utilities
{
public static string ToDisplayName(this MouseButtons button)
{
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;
}
 
return mouseButton;
}
 
public static string ToDisplayName(this Keys keys)
{
var keyString = string.Empty;
switch ((int)keys)
{
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;
}
 
return keyString;
}
}
}
/trunk/WingMan/WingMan.csproj
@@ -52,6 +52,9 @@
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Threading.Tasks.Dataflow, Version=4.5.24.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Tpl.Dataflow.4.5.24\lib\portable-net45+win8+wpa81\System.Threading.Tasks.Dataflow.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
@@ -63,10 +66,18 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Communication\MQTTClient.cs" />
<Compile Include="HelmBinding.cs" />
<Compile Include="HelmBindings.cs" />
<Compile Include="LobbyMessage.cs" />
<Compile Include="Lobby\LobbyMessageReceivedEventArgs.cs" />
<Compile Include="Lobby\LobbyMessageSynchronizer.cs" />
<Compile Include="MouseKey\MouseKeyBindingExchange.cs" />
<Compile Include="MouseKey\MouseKeyBindingsSynchronizedEventArgs.cs" />
<Compile Include="MouseKey\MouseKeyBindingsSynchronizer.cs" />
<Compile Include="Communication\MQTTCommunication.cs" />
<Compile Include="MouseKey\MouseKeyBinding.cs" />
<Compile Include="MouseKey\MouseKeyBindings.cs" />
<Compile Include="MouseKey\MouseKeyBindingsExchange.cs" />
<Compile Include="Lobby\LobbyMessage.cs" />
<Compile Include="Communication\MQTTCommunicationType.cs" />
<Compile Include="Utilities.cs" />
<Compile Include="WingManForm.cs">
<SubType>Form</SubType>
</Compile>
@@ -73,7 +84,6 @@
<Compile Include="WingManForm.Designer.cs">
<DependentUpon>WingManForm.cs</DependentUpon>
</Compile>
<Compile Include="Communication\MQTTServer.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Strings.Designer.cs">
/trunk/WingMan/WingManForm.Designer.cs
@@ -29,12 +29,12 @@
private void InitializeComponent()
{
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.comboBox1 = new System.Windows.Forms.ComboBox();
this.WingBindingsComboBox = new System.Windows.Forms.ComboBox();
this.button2 = new System.Windows.Forms.Button();
this.button1 = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.textBox1 = new System.Windows.Forms.TextBox();
this.listBox1 = new System.Windows.Forms.ListBox();
this.WingBindingsListBox = new System.Windows.Forms.ListBox();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.button5 = new System.Windows.Forms.Button();
this.LobbySayTextBox = new System.Windows.Forms.TextBox();
@@ -80,12 +80,12 @@
//
// groupBox1
//
this.groupBox1.Controls.Add(this.comboBox1);
this.groupBox1.Controls.Add(this.WingBindingsComboBox);
this.groupBox1.Controls.Add(this.button2);
this.groupBox1.Controls.Add(this.button1);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Controls.Add(this.textBox1);
this.groupBox1.Controls.Add(this.listBox1);
this.groupBox1.Controls.Add(this.WingBindingsListBox);
this.groupBox1.Location = new System.Drawing.Point(8, 10);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(248, 296);
@@ -93,13 +93,14 @@
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Wing (Them)";
//
// comboBox1
// WingBindingsComboBox
//
this.comboBox1.FormattingEnabled = true;
this.comboBox1.Location = new System.Drawing.Point(8, 24);
this.comboBox1.Name = "comboBox1";
this.comboBox1.Size = new System.Drawing.Size(232, 21);
this.comboBox1.TabIndex = 5;
this.WingBindingsComboBox.FormattingEnabled = true;
this.WingBindingsComboBox.Location = new System.Drawing.Point(8, 24);
this.WingBindingsComboBox.Name = "WingBindingsComboBox";
this.WingBindingsComboBox.Size = new System.Drawing.Size(232, 21);
this.WingBindingsComboBox.TabIndex = 5;
this.WingBindingsComboBox.SelectedIndexChanged += new System.EventHandler(this.WingBindingsComboBoxIndexChanged);
//
// button2
//
@@ -139,14 +140,14 @@
this.textBox1.Size = new System.Drawing.Size(168, 20);
this.textBox1.TabIndex = 1;
//
// listBox1
// WingBindingsListBox
//
this.listBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.listBox1.FormattingEnabled = true;
this.listBox1.Location = new System.Drawing.Point(8, 56);
this.listBox1.Name = "listBox1";
this.listBox1.Size = new System.Drawing.Size(232, 158);
this.listBox1.TabIndex = 0;
this.WingBindingsListBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.WingBindingsListBox.FormattingEnabled = true;
this.WingBindingsListBox.Location = new System.Drawing.Point(8, 56);
this.WingBindingsListBox.Name = "WingBindingsListBox";
this.WingBindingsListBox.Size = new System.Drawing.Size(232, 158);
this.WingBindingsListBox.TabIndex = 0;
//
// groupBox2
//
@@ -169,6 +170,7 @@
this.button5.Size = new System.Drawing.Size(40, 20);
this.button5.TabIndex = 2;
this.button5.UseVisualStyleBackColor = true;
this.button5.Click += new System.EventHandler(this.LobbySayButtonClick);
//
// LobbySayTextBox
//
@@ -493,7 +495,7 @@
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.GroupBox groupBox3;
private System.Windows.Forms.ListBox listBox1;
private System.Windows.Forms.ListBox WingBindingsListBox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.TextBox LobbySayTextBox;
@@ -514,7 +516,7 @@
private System.Windows.Forms.TextBox Address;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel;
private System.Windows.Forms.ComboBox comboBox1;
private System.Windows.Forms.ComboBox WingBindingsComboBox;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.TextBox Nick;
private System.Windows.Forms.TabControl tabControl1;
/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());
}
}
}
/trunk/WingMan/packages.config
@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Tpl.Dataflow" version="4.5.24" targetFramework="net452" />
<package id="MouseKeyHook" version="5.6.0" targetFramework="net452" />
<package id="MQTTnet" version="2.8.4" targetFramework="net452" />
<package id="MQTTnet.Extensions.ManagedClient" version="2.8.4" targetFramework="net452" />