WingMan

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 8  →  ?path2? @ 9
/trunk/WingMan/WingManForm.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading;
@@ -7,6 +8,8 @@
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;
@@ -24,19 +27,27 @@
FormTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
FormCancellationTokenSource = new CancellationTokenSource();
 
MQTTCommunication = new MQTTCommunication(FormTaskScheduler, FormCancellationTokenSource.Token);
MQTTCommunication.OnClientAuthenticationFailed += OnMQTTClientAuthenticationFailed;
MQTTCommunication.OnServerAuthenticationFailed += OnMQTTServerAuthenticationFailed;
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;
 
MouseKeyBindings = new MouseKeyBindings(new List<MouseKeyBinding>());
LocalMouseKeyBindings = new MouseKeyBindings(new List<MouseKeyBinding>());
RemoteMouseKeyBindings = new RemoteMouseKeyBindings(new List<RemoteMouseKeyBinding>());
 
HelmListBoxBindingSource = new BindingSource
LocalListBoxBindingSource = new BindingSource
{
DataSource = MouseKeyBindings.Bindings
DataSource = LocalMouseKeyBindings.Bindings
};
HelmBindingsListBox.DisplayMember = "DisplayName";
HelmBindingsListBox.ValueMember = "Keys";
HelmBindingsListBox.DataSource = HelmListBoxBindingSource;
LocalBindingsListBox.DisplayMember = "DisplayName";
LocalBindingsListBox.ValueMember = "Keys";
LocalBindingsListBox.DataSource = LocalListBoxBindingSource;
 
MouseKeyBindingsExchange = new MouseKeyBindingsExchange
{
@@ -43,23 +54,25 @@
ExchangeBindings = new List<MouseKeyBindingExchange>()
};
 
WingBindingsComboBoxSource = new BindingSource
RemoteBindingsComboBoxSource = new BindingSource
{
DataSource = MouseKeyBindingsExchange.ExchangeBindings
};
WingBindingsComboBox.DisplayMember = "Nick";
WingBindingsComboBox.ValueMember = "MouseKeyBindings";
WingBindingsComboBox.DataSource = WingBindingsComboBoxSource;
RemoteBindingsComboBox.DisplayMember = "Nick";
RemoteBindingsComboBox.ValueMember = "MouseKeyBindings";
RemoteBindingsComboBox.DataSource = RemoteBindingsComboBoxSource;
 
// 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(MouseKeyBindings, MQTTCommunication,
MouseKeyBindingsSynchronizer = new MouseKeyBindingsSynchronizer(LocalMouseKeyBindings, MqttCommunication,
FormTaskScheduler, FormCancellationTokenSource.Token);
MouseKeyBindingsSynchronizer.OnMouseKeyBindingsSynchronized += OnMouseKeyBindingsSynchronized;
 
// Start key binding simulator.
}
 
private static CancellationTokenSource FormCancellationTokenSource { get; set; }
@@ -70,27 +83,94 @@
 
private List<string> MouseKeyCombo { get; set; }
 
private MouseKeyBindings MouseKeyBindings { get; }
private MouseKeyBindings LocalMouseKeyBindings { get; }
 
private BindingSource HelmListBoxBindingSource { get; }
private RemoteMouseKeyBindings RemoteMouseKeyBindings { get; }
 
private BindingSource WingBindingsComboBoxSource { get; }
private BindingSource LocalListBoxBindingSource { 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 void OnMQTTServerAuthenticationFailed(object sender, EventArgs e)
private async Task SaveLocalMouseKeyBindings()
{
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}");
@@ -125,8 +205,8 @@
if (exchangeBindings == null)
{
MouseKeyBindingsExchange.ExchangeBindings.Add(e.Bindings);
WingBindingsComboBoxSource.ResetBindings(false);
UpdateWingListBoxItems();
RemoteBindingsComboBoxSource.ResetBindings(false);
UpdateRemoteListBoxItems();
return;
}
 
@@ -133,39 +213,36 @@
// If the bindings for the nick have not changed then do not update.
if (exchangeBindings.MouseKeyBindings.SequenceEqual(e.Bindings.MouseKeyBindings))
{
WingBindingsComboBoxSource.ResetBindings(false);
UpdateWingListBoxItems();
RemoteBindingsComboBoxSource.ResetBindings(false);
UpdateRemoteListBoxItems();
return;
}
 
// Update the bindings.
exchangeBindings.MouseKeyBindings = e.Bindings.MouseKeyBindings;
WingBindingsComboBoxSource.ResetBindings(false);
UpdateWingListBoxItems();
RemoteBindingsComboBoxSource.ResetBindings(false);
UpdateRemoteListBoxItems();
}
 
private void UpdateWingListBoxItems()
private void UpdateRemoteListBoxItems()
{
var exchangeBinding = (List<MouseKeyBinding>) WingBindingsComboBox.SelectedValue;
var exchangeBinding = (List<MouseKeyBinding>) RemoteBindingsComboBox.SelectedValue;
if (exchangeBinding == null)
return;
 
WingBindingsListBox.Items.Clear();
WingBindingsListBox.DisplayMember = "Name";
WingBindingsListBox.ValueMember = "Name";
RemoteBindingsListBox.Items.Clear();
RemoteBindingsListBox.DisplayMember = "Name";
RemoteBindingsListBox.ValueMember = "Name";
var i = exchangeBinding.Select(binding => (object) binding.Name).ToArray();
if (i.Length == 0)
return;
 
WingBindingsListBox.Items.AddRange(i);
RemoteBindingsListBox.Items.AddRange(i);
}
 
private void OnLobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e)
{
LobbyTextBox.Invoke((MethodInvoker) delegate
{
LobbyTextBox.AppendText($"{e.Nick} : {e.Message}{Environment.NewLine}");
});
LobbyTextBox.AppendText($"{e.Nick} : {e.Message}{Environment.NewLine}");
}
 
private void AddressTextBoxClick(object sender, EventArgs e)
@@ -181,10 +258,9 @@
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);
toolStripStatusLabel.Text = Strings.Server_stopped;
await MqttCommunication.Stop().ConfigureAwait(false);
HostButton.BackColor = Color.Empty;
 
// Enable controls.
@@ -200,9 +276,14 @@
return;
 
// Start the MQTT server.
await MQTTCommunication.Start(MQTTCommunicationType.Server, ipAddress, port, nick, password)
.ConfigureAwait(false);
toolStripStatusLabel.Text = Strings.Server_started;
if (!await MqttCommunication.Start(MqttCommunicationType.Server, ipAddress, port, nick, password)
.ConfigureAwait(false))
{
ActivityTextBox.AppendText(
$"{Strings.Failed_starting_server}{Environment.NewLine}");
return;
}
 
HostButton.BackColor = Color.Aquamarine;
 
// Disable controls
@@ -271,9 +352,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;
 
@@ -287,10 +368,14 @@
if (!ValidateAddressPort(out var ipAddress, out var port, out var nick, out var password))
return;
 
await MQTTCommunication.Start(MQTTCommunicationType.Client, ipAddress, port, nick, password)
.ConfigureAwait(false);
if (!await MqttCommunication.Start(MqttCommunicationType.Client, ipAddress, port, nick, password)
.ConfigureAwait(false))
{
ActivityTextBox.AppendText(
$"{Strings.Failed_starting_client}{Environment.NewLine}");
return;
}
 
toolStripStatusLabel.Text = Strings.Client_started;
ConnectButton.Text = Strings.Disconnect;
ConnectButton.BackColor = Color.Aquamarine;
 
@@ -312,9 +397,9 @@
 
private void HelmAddButtonClick(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(HelmNameTextBox.Text))
if (string.IsNullOrEmpty(LocalNameTextBox.Text))
{
HelmNameTextBox.BackColor = Color.LightPink;
LocalNameTextBox.BackColor = Color.LightPink;
return;
}
 
@@ -323,10 +408,10 @@
MouseKeyCombo = new List<string>();
 
MouseKeyApplicationHook = Hook.AppEvents();
MouseKeyApplicationHook.MouseDown += MouseKeyHookOnMouseDown;
MouseKeyApplicationHook.KeyUp += MouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown += MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.MouseUp += MouseKeyHookOnMouseUp;
MouseKeyApplicationHook.MouseDown += LocalMouseKeyHookOnMouseDown;
MouseKeyApplicationHook.KeyUp += LocalMouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown += LocalMouseKeyHookOnKeyDown;
MouseKeyApplicationHook.MouseUp += LocalMouseKeyHookOnMouseUp;
}
 
private void ShowOverlayPanel()
@@ -336,21 +421,23 @@
OverlayPanel.Invalidate();
}
 
private void MouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
private async void LocalMouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
{
MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo));
LocalMouseKeyBindings.Bindings.Add(new MouseKeyBinding(LocalNameTextBox.Text, MouseKeyCombo));
 
HelmListBoxBindingSource.ResetBindings(false);
LocalListBoxBindingSource.ResetBindings(false);
 
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= LocalMouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= LocalMouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= LocalMouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= LocalMouseKeyHookOnKeyUp;
 
MouseKeyApplicationHook.Dispose();
 
HelmNameTextBox.Text = string.Empty;
LocalNameTextBox.Text = string.Empty;
HideOverlayPanel();
 
await SaveLocalMouseKeyBindings().ConfigureAwait(false);
}
 
private void HideOverlayPanel()
@@ -360,30 +447,32 @@
OverlayPanel.Invalidate();
}
 
private void MouseKeyHookOnMouseUp(object sender, MouseEventArgs e)
private async void LocalMouseKeyHookOnMouseUp(object sender, MouseEventArgs e)
{
MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo));
LocalMouseKeyBindings.Bindings.Add(new MouseKeyBinding(LocalNameTextBox.Text, MouseKeyCombo));
 
HelmListBoxBindingSource.ResetBindings(false);
LocalListBoxBindingSource.ResetBindings(false);
 
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= LocalMouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= LocalMouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= LocalMouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= LocalMouseKeyHookOnKeyUp;
 
MouseKeyApplicationHook.Dispose();
 
HelmNameTextBox.Text = string.Empty;
LocalNameTextBox.Text = string.Empty;
HideOverlayPanel();
 
await SaveLocalMouseKeyBindings().ConfigureAwait(false);
}
 
 
private void MouseKeyHookOnMouseDown(object sender, MouseEventArgs e)
private void LocalMouseKeyHookOnMouseDown(object sender, MouseEventArgs e)
{
MouseKeyCombo.Add(e.Button.ToDisplayName());
}
 
private void MouseKeyHookOnKeyDown(object sender, KeyEventArgs e)
private void LocalMouseKeyHookOnKeyDown(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = true;
 
@@ -392,17 +481,19 @@
 
private void HelmNameTextBoxClick(object sender, EventArgs e)
{
HelmNameTextBox.BackColor = Color.Empty;
LocalNameTextBox.BackColor = Color.Empty;
}
 
private void HelmRemoveButtonClick(object sender, EventArgs e)
private async void HelmRemoveButtonClick(object sender, EventArgs e)
{
var helmBinding = (MouseKeyBinding) HelmBindingsListBox.SelectedItem;
var helmBinding = (MouseKeyBinding) LocalBindingsListBox.SelectedItem;
if (helmBinding == null)
return;
 
MouseKeyBindings.Bindings.Remove(helmBinding);
HelmListBoxBindingSource.ResetBindings(false);
LocalMouseKeyBindings.Bindings.Remove(helmBinding);
LocalListBoxBindingSource.ResetBindings(false);
 
await SaveLocalMouseKeyBindings().ConfigureAwait(false);
}
 
private async void LobbySayButtonClick(object sender, EventArgs e)
@@ -412,13 +503,153 @@
LobbySayTextBox.Text = string.Empty;
}
 
private void WingBindingsComboBoxSelectionChangeCompleted(object sender, EventArgs e)
private void RemoteBindingsComboBoxSelectionChangeCompleted(object sender, EventArgs e)
{
UpdateWingListBoxItems();
UpdateRemoteListBoxItems();
}
 
private void WingBindingsBindButtonClicked(object sender, EventArgs e)
private async void WingManFormOnLoad(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}");
}
}
}
}