WingMan

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 9  →  ?path2? @ 8
/trunk/WingMan/Communication/MQTTCommunication.cs
@@ -0,0 +1,396 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Threading;
using System.Threading.Tasks;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Protocol;
using MQTTnet.Server;
using WingMan.Utilities;
using MqttClientConnectedEventArgs = MQTTnet.Client.MqttClientConnectedEventArgs;
using MqttClientDisconnectedEventArgs = MQTTnet.Client.MqttClientDisconnectedEventArgs;
 
namespace WingMan.Communication
{
public class MQTTCommunication : IDisposable
{
public delegate void ClientAuthenticationFailed(object sender, EventArgs e);
 
public delegate void ClientConnected(object sender, MqttClientConnectedEventArgs e);
 
public delegate void ClientConnectionFailed(object sender, MqttManagedProcessFailedEventArgs e);
 
public delegate void ClientDisconnected(object sender, MqttClientDisconnectedEventArgs e);
 
public delegate void ClientSubscribed(object sender, MqttClientSubscribedTopicEventArgs e);
 
public delegate void ClientUnsubscribed(object sender, MqttClientUnsubscribedTopicEventArgs e);
 
public delegate void MessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e);
 
public delegate void ServerAuthenticationFailed(object sender, EventArgs e);
 
public delegate void ServerClientConnected(object sender, MQTTnet.Server.MqttClientConnectedEventArgs e);
 
public delegate void ServerClientDisconnected(object sender, MQTTnet.Server.MqttClientDisconnectedEventArgs e);
 
public delegate void ServerStarted(object sender, EventArgs e);
 
public delegate void ServerStopped(object sender, EventArgs e);
 
public MQTTCommunication(TaskScheduler taskScheduler, CancellationToken cancellationToken)
{
TaskScheduler = taskScheduler;
CancellationToken = cancellationToken;
 
TrackedClients = new TrackedClients {Clients = new List<TrackedClient>()};
 
Client = new MqttFactory().CreateManagedMqttClient();
Server = new MqttFactory().CreateMqttServer();
}
 
private TrackedClients TrackedClients { get; }
 
private TaskScheduler TaskScheduler { get; }
 
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; }
 
private string Password { get; set; }
 
private CancellationToken CancellationToken { get; }
 
public MQTTCommunicationType Type { get; set; }
 
public async void Dispose()
{
await Stop();
}
 
public event ClientAuthenticationFailed OnClientAuthenticationFailed;
 
public event ServerAuthenticationFailed OnServerAuthenticationFailed;
 
public event MessageReceived OnMessageReceived;
 
public event ClientConnected OnClientConnected;
 
public event ClientDisconnected OnClientDisconnected;
 
public event ClientConnectionFailed OnClientConnectionFailed;
 
public event ClientUnsubscribed OnClientUnsubscribed;
 
public event ClientSubscribed OnClientSubscribed;
 
public event ServerClientDisconnected OnServerClientDisconnected;
 
public event ServerClientConnected OnServerClientConnected;
 
public event ServerStarted OnServerStarted;
 
public event ServerStopped OnServerStopped;
 
public async Task Start(MQTTCommunicationType type, IPAddress ipAddress, int port, string nick, string password)
{
Type = type;
IPAddress = ipAddress;
Port = port;
Nick = nick;
Password = password;
 
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 async void ClientOnApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
{
try
{
e.ApplicationMessage.Payload = await AES.Decrypt(e.ApplicationMessage.Payload, Password);
}
catch (Exception)
{
await Task.Delay(0).ContinueWith(_ => OnClientAuthenticationFailed?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler);
 
return;
}
 
await Task.Delay(0).ContinueWith(_ => OnMessageReceived?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler);
}
 
private async void ClientOnConnectingFailed(object sender, MqttManagedProcessFailedEventArgs e)
{
await Task.Delay(0).ContinueWith(_ => OnClientConnectionFailed?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler).ConfigureAwait(false);
}
 
private async void ClientOnDisconnected(object sender, MqttClientDisconnectedEventArgs e)
{
await Task.Delay(0).ContinueWith(_ => OnClientDisconnected?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler).ConfigureAwait(false);
}
 
private async void ClientOnConnected(object sender, MqttClientConnectedEventArgs e)
{
await Task.Delay(0).ContinueWith(_ => OnClientConnected?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler).ConfigureAwait(false);
}
 
private async Task StartServer()
{
var optionsBuilder = new MqttServerOptionsBuilder()
.WithDefaultEndpointBoundIPAddress(IPAddress)
.WithSubscriptionInterceptor(MQTTSubscriptionIntercept)
.WithConnectionValidator(MQTTConnectionValidator)
.WithDefaultEndpointPort(Port);
 
BindServerHandlers();
 
await Server.StartAsync(optionsBuilder.Build()).ConfigureAwait(false);
 
Running = true;
}
 
private void MQTTConnectionValidator(MqttConnectionValidatorContext context)
{
// Do not accept connections from banned clients.
if (TrackedClients.Clients.Any(client =>
(string.Equals(client.EndPoint, context.Endpoint, StringComparison.OrdinalIgnoreCase) ||
string.Equals(client.ClientId, context.ClientId, StringComparison.Ordinal)) &&
client.Banned))
{
context.ReturnCode = MqttConnectReturnCode.ConnectionRefusedNotAuthorized;
return;
}
 
TrackedClients.Clients.Add(new TrackedClient {ClientId = context.ClientId, EndPoint = context.Endpoint});
 
context.ReturnCode = MqttConnectReturnCode.ConnectionAccepted;
}
 
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 async void ServerOnApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
{
try
{
e.ApplicationMessage.Payload = await AES.Decrypt(e.ApplicationMessage.Payload, Password);
}
catch (Exception)
{
// Decryption failed, assume a rogue client and ban the client.
foreach (var client in TrackedClients.Clients)
{
if (!string.Equals(client.ClientId, e.ClientId, StringComparison.Ordinal))
continue;
 
client.Banned = true;
 
foreach (var clientSessionStatus in await Server.GetClientSessionsStatusAsync())
{
if (!string.Equals(clientSessionStatus.ClientId, e.ClientId, StringComparison.Ordinal) &&
!string.Equals(clientSessionStatus.Endpoint, client.EndPoint, StringComparison.Ordinal))
continue;
 
await clientSessionStatus.ClearPendingApplicationMessagesAsync();
await clientSessionStatus.DisconnectAsync();
}
}
 
await Task.Delay(0).ContinueWith(_ => OnServerAuthenticationFailed?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler);
 
return;
}
 
await Task.Delay(0).ContinueWith(_ => OnMessageReceived?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler).ConfigureAwait(false);
}
 
private async void ServerOnClientUnsubscribedTopic(object sender, MqttClientUnsubscribedTopicEventArgs e)
{
await Task.Delay(0).ContinueWith(_ => OnClientUnsubscribed?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler).ConfigureAwait(false);
}
 
private async void ServerOnClientSubscribedTopic(object sender, MqttClientSubscribedTopicEventArgs e)
{
await Task.Delay(0).ContinueWith(_ => OnClientSubscribed?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler).ConfigureAwait(false);
}
 
private async void ServerOnClientDisconnected(object sender, MQTTnet.Server.MqttClientDisconnectedEventArgs e)
{
await Task.Delay(0).ContinueWith(_ => OnServerClientDisconnected?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler).ConfigureAwait(false);
}
 
private async void ServerOnClientConnected(object sender, MQTTnet.Server.MqttClientConnectedEventArgs e)
{
await Task.Delay(0).ContinueWith(_ => OnServerClientConnected?.Invoke(sender, e),
CancellationToken, TaskContinuationOptions.None, TaskScheduler).ConfigureAwait(false);
}
 
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)
{
// Encrypt the payload.
var encryptedPayload = await AES.Encrypt(payload, Password);
 
switch (Type)
{
case MQTTCommunicationType.Client:
 
await Client.PublishAsync(new ManagedMqttApplicationMessage
{
ApplicationMessage = new MqttApplicationMessage {Topic = topic, Payload = encryptedPayload}
}).ConfigureAwait(false);
break;
case MQTTCommunicationType.Server:
await Server.PublishAsync(new MqttApplicationMessage {Topic = topic, Payload = encryptedPayload})
.ConfigureAwait(false);
break;
}
}
}
}
/trunk/WingMan/Communication/MQTTCommunicationType.cs
@@ -0,0 +1,8 @@
namespace WingMan.Communication
{
public enum MQTTCommunicationType
{
Server,
Client
}
}
/trunk/WingMan/Lobby/LobbyMessageSynchronizer.cs
@@ -11,17 +11,17 @@
{
public delegate void LobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e);
 
public LobbyMessageSynchronizer(MqttCommunication mqttCommunication, TaskScheduler taskScheduler,
public LobbyMessageSynchronizer(MQTTCommunication MQTTCommunication, TaskScheduler taskScheduler,
CancellationToken cancellationToken)
{
MqttCommunication = mqttCommunication;
this.MQTTCommunication = MQTTCommunication;
CancellationToken = cancellationToken;
TaskScheduler = taskScheduler;
 
mqttCommunication.OnMessageReceived += MqttCommunicationOnOnMessageReceived;
MQTTCommunication.OnMessageReceived += MqttCommunicationOnOnMessageReceived;
}
 
private MqttCommunication MqttCommunication { get; }
private MQTTCommunication MQTTCommunication { get; }
 
private CancellationToken CancellationToken { get; }
private TaskScheduler TaskScheduler { get; }
@@ -28,7 +28,7 @@
 
public void Dispose()
{
MqttCommunication.OnMessageReceived -= MqttCommunicationOnOnMessageReceived;
MQTTCommunication.OnMessageReceived -= MqttCommunicationOnOnMessageReceived;
}
 
public event LobbyMessageReceived OnLobbyMessageReceived;
@@ -57,13 +57,13 @@
{
LobbyMessage.XmlSerializer.Serialize(memoryStream, new LobbyMessage
{
Nick = MqttCommunication.Nick,
Nick = MQTTCommunication.Nick,
Message = message
});
 
memoryStream.Position = 0L;
 
await MqttCommunication.Broadcast("lobby", memoryStream.ToArray()).ConfigureAwait(false);
await MQTTCommunication.Broadcast("lobby", memoryStream.ToArray()).ConfigureAwait(false);
}
}
}
File deleted
/trunk/WingMan/MouseKey/RemoteMouseKeyBindings.cs
File deleted
/trunk/WingMan/MouseKey/RemoteMouseKeyBinding.cs
/trunk/WingMan/MouseKey/MouseKeyBindings.cs
@@ -1,12 +1,9 @@
using System.Collections.Generic;
using System.Xml.Serialization;
 
namespace WingMan.MouseKey
{
public class MouseKeyBindings
{
[XmlIgnore] public static readonly XmlSerializer XmlSerializer = new XmlSerializer(typeof(MouseKeyBindings));
 
public MouseKeyBindings()
{
}
/trunk/WingMan/MouseKey/MouseKeyBindingsSynchronizer.cs
@@ -13,17 +13,17 @@
{
public delegate void MouseKeyBindingsSynchronized(object sender, MouseKeyBindingsSynchronizedEventArgs e);
 
public MouseKeyBindingsSynchronizer(MouseKeyBindings mouseKeyBindings, MqttCommunication mqttCommunication,
public MouseKeyBindingsSynchronizer(MouseKeyBindings mouseKeyBindings, MQTTCommunication MQTTCommunication,
TaskScheduler taskScheduler, CancellationToken cancellationToken)
{
MouseKeyBindings = mouseKeyBindings;
MqttCommunication = mqttCommunication;
this.MQTTCommunication = MQTTCommunication;
CancellationToken = cancellationToken;
TaskScheduler = taskScheduler;
 
SynchronizedMouseKeyBindings = new ConcurrentDictionary<string, List<MouseKeyBinding>>();
 
mqttCommunication.OnMessageReceived += MqttCommunicationOnOnMessageReceived;
MQTTCommunication.OnMessageReceived += MqttCommunicationOnOnMessageReceived;
 
Task.Run(Synchronize, CancellationToken);
}
@@ -32,7 +32,7 @@
 
private ConcurrentDictionary<string, List<MouseKeyBinding>> SynchronizedMouseKeyBindings { get; }
 
private MqttCommunication MqttCommunication { get; }
private MQTTCommunication MQTTCommunication { get; }
 
private CancellationToken CancellationToken { get; }
private TaskScheduler TaskScheduler { get; }
@@ -74,17 +74,17 @@
{
await Task.Delay(1000, CancellationToken).ConfigureAwait(false);
 
if (!MqttCommunication.Running)
if (!MQTTCommunication.Running)
continue;
 
using (var memoryStream = new MemoryStream())
{
MouseKeyBindingExchange.XmlSerializer.Serialize(memoryStream,
new MouseKeyBindingExchange(MqttCommunication.Nick, MouseKeyBindings.Bindings));
new MouseKeyBindingExchange(MQTTCommunication.Nick, MouseKeyBindings.Bindings));
 
memoryStream.Position = 0L;
 
await MqttCommunication.Broadcast("exchange", memoryStream.ToArray()).ConfigureAwait(false);
await MQTTCommunication.Broadcast("exchange", memoryStream.ToArray()).ConfigureAwait(false);
}
} while (!CancellationToken.IsCancellationRequested);
}
/trunk/WingMan/Properties/Strings.Designer.cs
@@ -133,60 +133,6 @@
}
/// <summary>
/// Looks up a localized string similar to Failed loading local bindings.
/// </summary>
internal static string Failed_loading_local_bindings {
get {
return ResourceManager.GetString("Failed_loading_local_bindings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed loading remote bindings.
/// </summary>
internal static string Failed_loading_remote_bindings {
get {
return ResourceManager.GetString("Failed_loading_remote_bindings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed saving local bindings.
/// </summary>
internal static string Failed_saving_local_bindings {
get {
return ResourceManager.GetString("Failed_saving_local_bindings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed saving remote bindings.
/// </summary>
internal static string Failed_saving_remote_bindings {
get {
return ResourceManager.GetString("Failed_saving_remote_bindings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed starting client.
/// </summary>
internal static string Failed_starting_client {
get {
return ResourceManager.GetString("Failed_starting_client", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed starting server.
/// </summary>
internal static string Failed_starting_server {
get {
return ResourceManager.GetString("Failed_starting_server", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Failed to authenticate client.
/// </summary>
internal static string Failed_to_authenticate_client {
/trunk/WingMan/Properties/Strings.resx
@@ -141,24 +141,6 @@
<data name="Disconnect" xml:space="preserve">
<value>Disconnect</value>
</data>
<data name="Failed_loading_local_bindings" xml:space="preserve">
<value>Failed loading local bindings</value>
</data>
<data name="Failed_loading_remote_bindings" xml:space="preserve">
<value>Failed loading remote bindings</value>
</data>
<data name="Failed_saving_local_bindings" xml:space="preserve">
<value>Failed saving local bindings</value>
</data>
<data name="Failed_saving_remote_bindings" xml:space="preserve">
<value>Failed saving remote bindings</value>
</data>
<data name="Failed_starting_client" xml:space="preserve">
<value>Failed starting client</value>
</data>
<data name="Failed_starting_server" xml:space="preserve">
<value>Failed starting server</value>
</data>
<data name="Failed_to_authenticate_client" xml:space="preserve">
<value>Failed to authenticate client</value>
</data>
/trunk/WingMan/WingMan.csproj
@@ -78,14 +78,12 @@
<Compile Include="MouseKey\MouseKeyBindingExchange.cs" />
<Compile Include="MouseKey\MouseKeyBindingsSynchronizedEventArgs.cs" />
<Compile Include="MouseKey\MouseKeyBindingsSynchronizer.cs" />
<Compile Include="Communication\MqttCommunication.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="MouseKey\RemoteMouseKeyBinding.cs" />
<Compile Include="MouseKey\RemoteMouseKeyBindings.cs" />
<Compile Include="Communication\MQTTCommunicationType.cs" />
<Compile Include="Utilities\AES.cs" />
<Compile Include="Utilities\KeyConversion.cs" />
<Compile Include="WingManForm.cs">
/trunk/WingMan/WingManForm.Designer.cs
@@ -17,22 +17,22 @@
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(WingManForm));
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.RemoteBindingsComboBox = 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.RemoteBindingsBindToBox = new System.Windows.Forms.TextBox();
this.RemoteBindingsListBox = new System.Windows.Forms.ListBox();
this.WingBindingsBindToBox = new System.Windows.Forms.TextBox();
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();
this.LobbyTextBox = new System.Windows.Forms.TextBox();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this.LocalBindingsListBox = new System.Windows.Forms.ListBox();
this.HelmBindingsListBox = new System.Windows.Forms.ListBox();
this.button3 = new System.Windows.Forms.Button();
this.HelmAddButton = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.LocalNameTextBox = new System.Windows.Forms.TextBox();
this.HelmNameTextBox = new System.Windows.Forms.TextBox();
this.groupBox4 = new System.Windows.Forms.GroupBox();
this.label6 = new System.Windows.Forms.Label();
this.Password = new System.Windows.Forms.TextBox();
@@ -73,27 +73,27 @@
//
// groupBox1
//
this.groupBox1.Controls.Add(this.RemoteBindingsComboBox);
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.RemoteBindingsBindToBox);
this.groupBox1.Controls.Add(this.RemoteBindingsListBox);
this.groupBox1.Controls.Add(this.WingBindingsBindToBox);
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);
this.groupBox1.TabIndex = 0;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Remote (Them)";
this.groupBox1.Text = "Wing (Them)";
//
// RemoteBindingsComboBox
// WingBindingsComboBox
//
this.RemoteBindingsComboBox.FormattingEnabled = true;
this.RemoteBindingsComboBox.Location = new System.Drawing.Point(8, 24);
this.RemoteBindingsComboBox.Name = "RemoteBindingsComboBox";
this.RemoteBindingsComboBox.Size = new System.Drawing.Size(232, 21);
this.RemoteBindingsComboBox.TabIndex = 5;
this.RemoteBindingsComboBox.SelectionChangeCommitted += new System.EventHandler(this.RemoteBindingsComboBoxSelectionChangeCompleted);
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.SelectionChangeCommitted += new System.EventHandler(this.WingBindingsComboBoxSelectionChangeCompleted);
//
// button2
//
@@ -114,7 +114,7 @@
this.button1.TabIndex = 3;
this.button1.Text = "Bind";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.RemoteBindingsBindButtonClicked);
this.button1.Click += new System.EventHandler(this.WingBindingsBindButtonClicked);
//
// label1
//
@@ -125,23 +125,23 @@
this.label1.TabIndex = 2;
this.label1.Text = "Bound To";
//
// RemoteBindingsBindToBox
// WingBindingsBindToBox
//
this.RemoteBindingsBindToBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.RemoteBindingsBindToBox.Location = new System.Drawing.Point(72, 232);
this.RemoteBindingsBindToBox.Name = "RemoteBindingsBindToBox";
this.RemoteBindingsBindToBox.ReadOnly = true;
this.RemoteBindingsBindToBox.Size = new System.Drawing.Size(168, 20);
this.RemoteBindingsBindToBox.TabIndex = 1;
this.WingBindingsBindToBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.WingBindingsBindToBox.Location = new System.Drawing.Point(72, 232);
this.WingBindingsBindToBox.Name = "WingBindingsBindToBox";
this.WingBindingsBindToBox.ReadOnly = true;
this.WingBindingsBindToBox.Size = new System.Drawing.Size(168, 20);
this.WingBindingsBindToBox.TabIndex = 1;
//
// RemoteBindingsListBox
// WingBindingsListBox
//
this.RemoteBindingsListBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.RemoteBindingsListBox.FormattingEnabled = true;
this.RemoteBindingsListBox.Location = new System.Drawing.Point(8, 56);
this.RemoteBindingsListBox.Name = "RemoteBindingsListBox";
this.RemoteBindingsListBox.Size = new System.Drawing.Size(232, 158);
this.RemoteBindingsListBox.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
//
@@ -187,26 +187,26 @@
//
// groupBox3
//
this.groupBox3.Controls.Add(this.LocalBindingsListBox);
this.groupBox3.Controls.Add(this.HelmBindingsListBox);
this.groupBox3.Controls.Add(this.button3);
this.groupBox3.Controls.Add(this.HelmAddButton);
this.groupBox3.Controls.Add(this.label2);
this.groupBox3.Controls.Add(this.LocalNameTextBox);
this.groupBox3.Controls.Add(this.HelmNameTextBox);
this.groupBox3.Location = new System.Drawing.Point(272, 8);
this.groupBox3.Name = "groupBox3";
this.groupBox3.Size = new System.Drawing.Size(248, 296);
this.groupBox3.TabIndex = 2;
this.groupBox3.TabStop = false;
this.groupBox3.Text = "Local (You)";
this.groupBox3.Text = "Helm (You)";
//
// LocalBindingsListBox
// HelmBindingsListBox
//
this.LocalBindingsListBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.LocalBindingsListBox.FormattingEnabled = true;
this.LocalBindingsListBox.Location = new System.Drawing.Point(8, 16);
this.LocalBindingsListBox.Name = "LocalBindingsListBox";
this.LocalBindingsListBox.Size = new System.Drawing.Size(232, 197);
this.LocalBindingsListBox.TabIndex = 7;
this.HelmBindingsListBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.HelmBindingsListBox.FormattingEnabled = true;
this.HelmBindingsListBox.Location = new System.Drawing.Point(8, 16);
this.HelmBindingsListBox.Name = "HelmBindingsListBox";
this.HelmBindingsListBox.Size = new System.Drawing.Size(232, 197);
this.HelmBindingsListBox.TabIndex = 7;
//
// button3
//
@@ -239,14 +239,14 @@
this.label2.TabIndex = 4;
this.label2.Text = "Name";
//
// LocalNameTextBox
// HelmNameTextBox
//
this.LocalNameTextBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.LocalNameTextBox.Location = new System.Drawing.Point(72, 232);
this.LocalNameTextBox.Name = "LocalNameTextBox";
this.LocalNameTextBox.Size = new System.Drawing.Size(172, 20);
this.LocalNameTextBox.TabIndex = 3;
this.LocalNameTextBox.Click += new System.EventHandler(this.HelmNameTextBoxClick);
this.HelmNameTextBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.HelmNameTextBox.Location = new System.Drawing.Point(72, 232);
this.HelmNameTextBox.Name = "HelmNameTextBox";
this.HelmNameTextBox.Size = new System.Drawing.Size(172, 20);
this.HelmNameTextBox.TabIndex = 3;
this.HelmNameTextBox.Click += new System.EventHandler(this.HelmNameTextBoxClick);
//
// groupBox4
//
@@ -504,7 +504,6 @@
this.Name = "WingManForm";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.Text = "WingMan © 2018 Wizardry and Steamworks";
this.Load += new System.EventHandler(this.WingManFormOnLoad);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupBox2.ResumeLayout(false);
@@ -535,13 +534,13 @@
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.GroupBox groupBox3;
private System.Windows.Forms.ListBox RemoteBindingsListBox;
private System.Windows.Forms.ListBox WingBindingsListBox;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox RemoteBindingsBindToBox;
private System.Windows.Forms.TextBox WingBindingsBindToBox;
private System.Windows.Forms.TextBox LobbySayTextBox;
public System.Windows.Forms.TextBox LobbyTextBox;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox LocalNameTextBox;
private System.Windows.Forms.TextBox HelmNameTextBox;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button3;
@@ -556,7 +555,7 @@
private System.Windows.Forms.TextBox Address;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel;
private System.Windows.Forms.ComboBox RemoteBindingsComboBox;
private System.Windows.Forms.ComboBox WingBindingsComboBox;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.TextBox Nick;
private System.Windows.Forms.TabControl tabControl1;
@@ -567,7 +566,7 @@
private System.Windows.Forms.TabPage tabPage3;
private System.Windows.Forms.PictureBox pictureBox1;
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
private System.Windows.Forms.ListBox LocalBindingsListBox;
private System.Windows.Forms.ListBox HelmBindingsListBox;
private System.Windows.Forms.Panel OverlayPanel;
private System.Windows.Forms.Label OverlayPanelLabel;
private System.Windows.Forms.Label label6;
/trunk/WingMan/WingManForm.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
@@ -8,8 +7,6 @@
using System.Threading.Tasks;
using System.Windows.Forms;
using Gma.System.MouseKeyHook;
using MQTTnet.Extensions.ManagedClient;
using MQTTnet.Server;
using WingMan.Communication;
using WingMan.Lobby;
using WingMan.MouseKey;
@@ -27,27 +24,19 @@
FormTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
FormCancellationTokenSource = new CancellationTokenSource();
 
MqttCommunication = new MqttCommunication(FormTaskScheduler, FormCancellationTokenSource.Token);
MqttCommunication.OnClientAuthenticationFailed += OnMqttClientAuthenticationFailed;
MqttCommunication.OnClientConnectionFailed += OnMqttClientConnectionFailed;
MqttCommunication.OnClientDisconnected += OnMqttClientDisconnected;
MqttCommunication.OnClientConnected += OnMqttClientConnected;
MqttCommunication.OnServerAuthenticationFailed += OnMqttServerAuthenticationFailed;
MqttCommunication.OnServerStopped += OnMqttServerStopped;
MqttCommunication.OnServerStarted += OnMqttServerStarted;
MqttCommunication.OnServerClientConnected += OnMqttServerClientConnected;
MqttCommunication.OnServerClientDisconnected += OnMqttServerClientDisconnected;
MQTTCommunication = new MQTTCommunication(FormTaskScheduler, FormCancellationTokenSource.Token);
MQTTCommunication.OnClientAuthenticationFailed += OnMQTTClientAuthenticationFailed;
MQTTCommunication.OnServerAuthenticationFailed += OnMQTTServerAuthenticationFailed;
 
LocalMouseKeyBindings = new MouseKeyBindings(new List<MouseKeyBinding>());
RemoteMouseKeyBindings = new RemoteMouseKeyBindings(new List<RemoteMouseKeyBinding>());
MouseKeyBindings = new MouseKeyBindings(new List<MouseKeyBinding>());
 
LocalListBoxBindingSource = new BindingSource
HelmListBoxBindingSource = new BindingSource
{
DataSource = LocalMouseKeyBindings.Bindings
DataSource = MouseKeyBindings.Bindings
};
LocalBindingsListBox.DisplayMember = "DisplayName";
LocalBindingsListBox.ValueMember = "Keys";
LocalBindingsListBox.DataSource = LocalListBoxBindingSource;
HelmBindingsListBox.DisplayMember = "DisplayName";
HelmBindingsListBox.ValueMember = "Keys";
HelmBindingsListBox.DataSource = HelmListBoxBindingSource;
 
MouseKeyBindingsExchange = new MouseKeyBindingsExchange
{
@@ -54,25 +43,23 @@
ExchangeBindings = new List<MouseKeyBindingExchange>()
};
 
RemoteBindingsComboBoxSource = new BindingSource
WingBindingsComboBoxSource = new BindingSource
{
DataSource = MouseKeyBindingsExchange.ExchangeBindings
};
RemoteBindingsComboBox.DisplayMember = "Nick";
RemoteBindingsComboBox.ValueMember = "MouseKeyBindings";
RemoteBindingsComboBox.DataSource = RemoteBindingsComboBoxSource;
WingBindingsComboBox.DisplayMember = "Nick";
WingBindingsComboBox.ValueMember = "MouseKeyBindings";
WingBindingsComboBox.DataSource = WingBindingsComboBoxSource;
 
// Start lobby message synchronizer.
LobbyMessageSynchronizer = new LobbyMessageSynchronizer(MqttCommunication, FormTaskScheduler,
LobbyMessageSynchronizer = new LobbyMessageSynchronizer(MQTTCommunication, FormTaskScheduler,
FormCancellationTokenSource.Token);
LobbyMessageSynchronizer.OnLobbyMessageReceived += OnLobbyMessageReceived;
 
// Start mouse key bindings synchronizer.
MouseKeyBindingsSynchronizer = new MouseKeyBindingsSynchronizer(LocalMouseKeyBindings, MqttCommunication,
MouseKeyBindingsSynchronizer = new MouseKeyBindingsSynchronizer(MouseKeyBindings, MQTTCommunication,
FormTaskScheduler, FormCancellationTokenSource.Token);
MouseKeyBindingsSynchronizer.OnMouseKeyBindingsSynchronized += OnMouseKeyBindingsSynchronized;
 
// Start key binding simulator.
}
 
private static CancellationTokenSource FormCancellationTokenSource { get; set; }
@@ -83,94 +70,27 @@
 
private List<string> MouseKeyCombo { get; set; }
 
private MouseKeyBindings LocalMouseKeyBindings { get; }
private MouseKeyBindings MouseKeyBindings { get; }
 
private RemoteMouseKeyBindings RemoteMouseKeyBindings { get; }
private BindingSource HelmListBoxBindingSource { get; }
 
private BindingSource LocalListBoxBindingSource { get; }
private BindingSource WingBindingsComboBoxSource { get; }
 
private BindingSource RemoteBindingsComboBoxSource { get; }
 
private MouseKeyBindingsExchange MouseKeyBindingsExchange { get; }
 
public MqttCommunication MqttCommunication { get; set; }
public MQTTCommunication MQTTCommunication { get; set; }
 
public LobbyMessageSynchronizer LobbyMessageSynchronizer { get; set; }
 
public MouseKeyBindingsSynchronizer MouseKeyBindingsSynchronizer { get; set; }
 
private async Task SaveLocalMouseKeyBindings()
private void OnMQTTServerAuthenticationFailed(object sender, EventArgs e)
{
try
{
using (var memoryStream = new MemoryStream())
{
MouseKeyBindings.XmlSerializer.Serialize(memoryStream, LocalMouseKeyBindings);
 
memoryStream.Position = 0L;
 
using (var fileStream = new FileStream("LocalMouseKeyBindings.xml", FileMode.Create))
{
await memoryStream.CopyToAsync(fileStream).ConfigureAwait(false);
}
}
}
catch (Exception)
{
ActivityTextBox.AppendText(
$"{Strings.Failed_saving_local_bindings}{Environment.NewLine}");
}
}
 
private void OnMqttServerClientDisconnected(object sender, MqttClientDisconnectedEventArgs e)
{
ActivityTextBox.AppendText(
$"{Strings.Client_disconnected}{Environment.NewLine}");
}
 
private void OnMqttServerClientConnected(object sender, MqttClientConnectedEventArgs e)
{
ActivityTextBox.AppendText(
$"{Strings.Client_connected}{Environment.NewLine}");
}
 
private void OnMqttServerStarted(object sender, EventArgs e)
{
ActivityTextBox.AppendText(
$"{Strings.Server_started}{Environment.NewLine}");
}
 
private void OnMqttServerStopped(object sender, EventArgs e)
{
ActivityTextBox.AppendText(
$"{Strings.Server_stopped}{Environment.NewLine}");
}
 
private void OnMqttClientConnected(object sender, MQTTnet.Client.MqttClientConnectedEventArgs e)
{
ActivityTextBox.AppendText(
$"{Strings.Client_connected}{Environment.NewLine}");
}
 
private void OnMqttClientDisconnected(object sender, MQTTnet.Client.MqttClientDisconnectedEventArgs e)
{
ActivityTextBox.AppendText(
$"{Strings.Client_disconnected}{Environment.NewLine}");
}
 
private void OnMqttClientConnectionFailed(object sender, MqttManagedProcessFailedEventArgs e)
{
ActivityTextBox.AppendText(
$"{Strings.Client_connection_failed}{Environment.NewLine}");
}
 
private void OnMqttServerAuthenticationFailed(object sender, EventArgs e)
{
ActivityTextBox.AppendText(
$"{Strings.Failed_to_authenticate_client}{Environment.NewLine}");
}
 
private void OnMqttClientAuthenticationFailed(object sender, EventArgs e)
private void OnMQTTClientAuthenticationFailed(object sender, EventArgs e)
{
ActivityTextBox.AppendText(
$"{Strings.Server_authentication_failed}{Environment.NewLine}");
@@ -205,8 +125,8 @@
if (exchangeBindings == null)
{
MouseKeyBindingsExchange.ExchangeBindings.Add(e.Bindings);
RemoteBindingsComboBoxSource.ResetBindings(false);
UpdateRemoteListBoxItems();
WingBindingsComboBoxSource.ResetBindings(false);
UpdateWingListBoxItems();
return;
}
 
@@ -213,36 +133,39 @@
// If the bindings for the nick have not changed then do not update.
if (exchangeBindings.MouseKeyBindings.SequenceEqual(e.Bindings.MouseKeyBindings))
{
RemoteBindingsComboBoxSource.ResetBindings(false);
UpdateRemoteListBoxItems();
WingBindingsComboBoxSource.ResetBindings(false);
UpdateWingListBoxItems();
return;
}
 
// Update the bindings.
exchangeBindings.MouseKeyBindings = e.Bindings.MouseKeyBindings;
RemoteBindingsComboBoxSource.ResetBindings(false);
UpdateRemoteListBoxItems();
WingBindingsComboBoxSource.ResetBindings(false);
UpdateWingListBoxItems();
}
 
private void UpdateRemoteListBoxItems()
private void UpdateWingListBoxItems()
{
var exchangeBinding = (List<MouseKeyBinding>) RemoteBindingsComboBox.SelectedValue;
var exchangeBinding = (List<MouseKeyBinding>) WingBindingsComboBox.SelectedValue;
if (exchangeBinding == null)
return;
 
RemoteBindingsListBox.Items.Clear();
RemoteBindingsListBox.DisplayMember = "Name";
RemoteBindingsListBox.ValueMember = "Name";
WingBindingsListBox.Items.Clear();
WingBindingsListBox.DisplayMember = "Name";
WingBindingsListBox.ValueMember = "Name";
var i = exchangeBinding.Select(binding => (object) binding.Name).ToArray();
if (i.Length == 0)
return;
 
RemoteBindingsListBox.Items.AddRange(i);
WingBindingsListBox.Items.AddRange(i);
}
 
private void OnLobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e)
{
LobbyTextBox.AppendText($"{e.Nick} : {e.Message}{Environment.NewLine}");
LobbyTextBox.Invoke((MethodInvoker) delegate
{
LobbyTextBox.AppendText($"{e.Nick} : {e.Message}{Environment.NewLine}");
});
}
 
private void AddressTextBoxClick(object sender, EventArgs e)
@@ -258,9 +181,10 @@
private async void HostButtonClickAsync(object sender, EventArgs e)
{
// Stop the MQTT server if it is running.
if (MqttCommunication.Running)
if (MQTTCommunication.Running)
{
await MqttCommunication.Stop().ConfigureAwait(false);
await MQTTCommunication.Stop().ConfigureAwait(false);
toolStripStatusLabel.Text = Strings.Server_stopped;
HostButton.BackColor = Color.Empty;
 
// Enable controls.
@@ -276,14 +200,9 @@
return;
 
// Start the MQTT server.
if (!await MqttCommunication.Start(MqttCommunicationType.Server, ipAddress, port, nick, password)
.ConfigureAwait(false))
{
ActivityTextBox.AppendText(
$"{Strings.Failed_starting_server}{Environment.NewLine}");
return;
}
 
await MQTTCommunication.Start(MQTTCommunicationType.Server, ipAddress, port, nick, password)
.ConfigureAwait(false);
toolStripStatusLabel.Text = Strings.Server_started;
HostButton.BackColor = Color.Aquamarine;
 
// Disable controls
@@ -352,9 +271,9 @@
 
private async void ConnectButtonClickAsync(object sender, EventArgs e)
{
if (MqttCommunication.Running)
if (MQTTCommunication.Running)
{
await MqttCommunication.Stop().ConfigureAwait(false);
await MQTTCommunication.Stop().ConfigureAwait(false);
ConnectButton.Text = Strings.Connect;
ConnectButton.BackColor = Color.Empty;
 
@@ -368,14 +287,10 @@
if (!ValidateAddressPort(out var ipAddress, out var port, out var nick, out var password))
return;
 
if (!await MqttCommunication.Start(MqttCommunicationType.Client, ipAddress, port, nick, password)
.ConfigureAwait(false))
{
ActivityTextBox.AppendText(
$"{Strings.Failed_starting_client}{Environment.NewLine}");
return;
}
await MQTTCommunication.Start(MQTTCommunicationType.Client, ipAddress, port, nick, password)
.ConfigureAwait(false);
 
toolStripStatusLabel.Text = Strings.Client_started;
ConnectButton.Text = Strings.Disconnect;
ConnectButton.BackColor = Color.Aquamarine;
 
@@ -397,9 +312,9 @@
 
private void HelmAddButtonClick(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(LocalNameTextBox.Text))
if (string.IsNullOrEmpty(HelmNameTextBox.Text))
{
LocalNameTextBox.BackColor = Color.LightPink;
HelmNameTextBox.BackColor = Color.LightPink;
return;
}
 
@@ -408,10 +323,10 @@
MouseKeyCombo = new List<string>();
 
MouseKeyApplicationHook = Hook.AppEvents();
MouseKeyApplicationHook.MouseDown += LocalMouseKeyHookOnMouseDown;
MouseKeyApplicationHook.KeyUp += LocalMouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown += LocalMouseKeyHookOnKeyDown;
MouseKeyApplicationHook.MouseUp += LocalMouseKeyHookOnMouseUp;
MouseKeyApplicationHook.MouseDown += MouseKeyHookOnMouseDown;
MouseKeyApplicationHook.KeyUp += MouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown += MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.MouseUp += MouseKeyHookOnMouseUp;
}
 
private void ShowOverlayPanel()
@@ -421,23 +336,21 @@
OverlayPanel.Invalidate();
}
 
private async void LocalMouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
private void MouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
{
LocalMouseKeyBindings.Bindings.Add(new MouseKeyBinding(LocalNameTextBox.Text, MouseKeyCombo));
MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo));
 
LocalListBoxBindingSource.ResetBindings(false);
HelmListBoxBindingSource.ResetBindings(false);
 
MouseKeyApplicationHook.KeyDown -= LocalMouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= LocalMouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= LocalMouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= LocalMouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
 
MouseKeyApplicationHook.Dispose();
 
LocalNameTextBox.Text = string.Empty;
HelmNameTextBox.Text = string.Empty;
HideOverlayPanel();
 
await SaveLocalMouseKeyBindings().ConfigureAwait(false);
}
 
private void HideOverlayPanel()
@@ -447,32 +360,30 @@
OverlayPanel.Invalidate();
}
 
private async void LocalMouseKeyHookOnMouseUp(object sender, MouseEventArgs e)
private void MouseKeyHookOnMouseUp(object sender, MouseEventArgs e)
{
LocalMouseKeyBindings.Bindings.Add(new MouseKeyBinding(LocalNameTextBox.Text, MouseKeyCombo));
MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo));
 
LocalListBoxBindingSource.ResetBindings(false);
HelmListBoxBindingSource.ResetBindings(false);
 
MouseKeyApplicationHook.KeyDown -= LocalMouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= LocalMouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= LocalMouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= LocalMouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
 
MouseKeyApplicationHook.Dispose();
 
LocalNameTextBox.Text = string.Empty;
HelmNameTextBox.Text = string.Empty;
HideOverlayPanel();
 
await SaveLocalMouseKeyBindings().ConfigureAwait(false);
}
 
 
private void LocalMouseKeyHookOnMouseDown(object sender, MouseEventArgs e)
private void MouseKeyHookOnMouseDown(object sender, MouseEventArgs e)
{
MouseKeyCombo.Add(e.Button.ToDisplayName());
}
 
private void LocalMouseKeyHookOnKeyDown(object sender, KeyEventArgs e)
private void MouseKeyHookOnKeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = true;
 
@@ -481,19 +392,17 @@
 
private void HelmNameTextBoxClick(object sender, EventArgs e)
{
LocalNameTextBox.BackColor = Color.Empty;
HelmNameTextBox.BackColor = Color.Empty;
}
 
private async void HelmRemoveButtonClick(object sender, EventArgs e)
private void HelmRemoveButtonClick(object sender, EventArgs e)
{
var helmBinding = (MouseKeyBinding) LocalBindingsListBox.SelectedItem;
var helmBinding = (MouseKeyBinding) HelmBindingsListBox.SelectedItem;
if (helmBinding == null)
return;
 
LocalMouseKeyBindings.Bindings.Remove(helmBinding);
LocalListBoxBindingSource.ResetBindings(false);
 
await SaveLocalMouseKeyBindings().ConfigureAwait(false);
MouseKeyBindings.Bindings.Remove(helmBinding);
HelmListBoxBindingSource.ResetBindings(false);
}
 
private async void LobbySayButtonClick(object sender, EventArgs e)
@@ -503,153 +412,13 @@
LobbySayTextBox.Text = string.Empty;
}
 
private void RemoteBindingsComboBoxSelectionChangeCompleted(object sender, EventArgs e)
private void WingBindingsComboBoxSelectionChangeCompleted(object sender, EventArgs e)
{
UpdateRemoteListBoxItems();
UpdateWingListBoxItems();
}
 
private async void WingManFormOnLoad(object sender, EventArgs e)
private void WingBindingsBindButtonClicked(object sender, EventArgs e)
{
await LoadLocalMouseKeyBindings();
await LoadRemoteMouseKeyBindings();
}
 
private async Task LoadLocalMouseKeyBindings()
{
try
{
using (var fileStream = new FileStream("LocalMouseKeyBindings.xml", FileMode.Open))
{
using (var memoryStream = new MemoryStream())
{
await fileStream.CopyToAsync(memoryStream).ConfigureAwait(false);
 
memoryStream.Position = 0L;
 
var loadedBindings =
(MouseKeyBindings) MouseKeyBindings.XmlSerializer.Deserialize(memoryStream);
 
foreach (var binding in loadedBindings.Bindings) LocalMouseKeyBindings.Bindings.Add(binding);
 
LocalListBoxBindingSource.ResetBindings(false);
}
}
}
catch (Exception)
{
ActivityTextBox.AppendText(
$"{Strings.Failed_loading_local_bindings}{Environment.NewLine}");
}
}
 
private void RemoteBindingsBindButtonClicked(object sender, EventArgs e)
{
ShowOverlayPanel();
 
MouseKeyCombo = new List<string>();
 
MouseKeyApplicationHook = Hook.AppEvents();
MouseKeyApplicationHook.MouseDown += RemoteMouseKeyHookOnMouseDown;
MouseKeyApplicationHook.KeyUp += RemoteMouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown += RemoteMouseKeyHookOnKeyDown;
MouseKeyApplicationHook.MouseUp += RemoteMouseKeyHookOnMouseUp;
}
 
private void RemoteMouseKeyHookOnKeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = true;
 
MouseKeyCombo.Add(e.KeyCode.ToDisplayName());
}
 
private void RemoteMouseKeyHookOnMouseDown(object sender, MouseEventArgs e)
{
MouseKeyCombo.Add(e.Button.ToDisplayName());
}
 
private async void RemoteMouseKeyHookOnMouseUp(object sender, MouseEventArgs e)
{
RemoteMouseKeyBindings.Bindings.Add(new RemoteMouseKeyBinding(RemoteBindingsComboBox.Text,
(string) RemoteBindingsListBox.SelectedItem, MouseKeyCombo));
 
MouseKeyApplicationHook.KeyDown -= RemoteMouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= RemoteMouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= RemoteMouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= RemoteMouseKeyHookOnKeyUp;
 
MouseKeyApplicationHook.Dispose();
 
RemoteBindingsBindToBox.Text = string.Join(" + ", MouseKeyCombo);
HideOverlayPanel();
 
await SaveRemoteMouseKeyBindings().ConfigureAwait(false);
}
 
private async void RemoteMouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
{
RemoteMouseKeyBindings.Bindings.Add(new RemoteMouseKeyBinding(RemoteBindingsComboBox.Text,
(string) RemoteBindingsListBox.SelectedItem, MouseKeyCombo));
 
MouseKeyApplicationHook.KeyDown -= RemoteMouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= RemoteMouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= RemoteMouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= RemoteMouseKeyHookOnKeyUp;
 
MouseKeyApplicationHook.Dispose();
 
RemoteBindingsBindToBox.Text = string.Join(" + ", MouseKeyCombo);
HideOverlayPanel();
 
await SaveRemoteMouseKeyBindings().ConfigureAwait(false);
}
 
private async Task SaveRemoteMouseKeyBindings()
{
try
{
using (var memoryStream = new MemoryStream())
{
RemoteMouseKeyBindings.XmlSerializer.Serialize(memoryStream, RemoteMouseKeyBindings);
 
memoryStream.Position = 0L;
 
using (var fileStream = new FileStream("RemoteMouseKeyBindings.xml", FileMode.Create))
{
await memoryStream.CopyToAsync(fileStream).ConfigureAwait(false);
}
}
}
catch (Exception)
{
ActivityTextBox.AppendText(
$"{Strings.Failed_saving_remote_bindings}{Environment.NewLine}");
}
}
 
private async Task LoadRemoteMouseKeyBindings()
{
try
{
using (var fileStream = new FileStream("RemoteMouseKeyBindings.xml", FileMode.Open))
{
using (var memoryStream = new MemoryStream())
{
await fileStream.CopyToAsync(memoryStream).ConfigureAwait(false);
 
memoryStream.Position = 0L;
 
var loadedBindings =
(RemoteMouseKeyBindings) RemoteMouseKeyBindings.XmlSerializer.Deserialize(memoryStream);
 
foreach (var binding in loadedBindings.Bindings) RemoteMouseKeyBindings.Bindings.Add(binding);
}
}
}
catch (Exception)
{
ActivityTextBox.AppendText(
$"{Strings.Failed_loading_remote_bindings}{Environment.NewLine}");
}
}
}
}