WingMan

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 5  →  ?path2? @ 4
File deleted
/trunk/WingMan/Lobby/LobbyMessageSynchronizer.cs
File deleted
/trunk/WingMan/Lobby/LobbyMessage.cs
File deleted
/trunk/WingMan/Lobby/LobbyMessageReceivedEventArgs.cs
File deleted
/trunk/WingMan/Utilities.cs
File deleted
/trunk/WingMan/MouseKey/MouseKeyBindingsSynchronizedEventArgs.cs
File deleted
/trunk/WingMan/MouseKey/MouseKeyBindingExchange.cs
File deleted
/trunk/WingMan/MouseKey/MouseKeyBindings.cs
File deleted
/trunk/WingMan/MouseKey/MouseKeyBindingsExchange.cs
File deleted
/trunk/WingMan/MouseKey/MouseKeyBinding.cs
File deleted
/trunk/WingMan/MouseKey/MouseKeyBindingsSynchronizer.cs
File deleted
/trunk/WingMan/Communication/MQTTCommunication.cs
File deleted
/trunk/WingMan/Communication/MQTTCommunicationType.cs
/trunk/WingMan/Communication/MQTTClient.cs
@@ -0,0 +1,173 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml.Serialization;
using MQTTnet;
using MQTTnet.Client;
using MQTTnet.Extensions.ManagedClient;
 
namespace WingMan.Communication
{
public class MQTTClient : IDisposable
{
private WingManForm WingManForm { get; set; }
private IManagedMqttClient Client { get; set; }
public bool ClientRunning { get; set; }
 
public string Nick { get; set; }
 
public MQTTClient()
{
Client = new MqttFactory().CreateManagedMqttClient();
}
 
public MQTTClient(WingManForm wingManForm) : this()
{
WingManForm = wingManForm;
}
 
public async Task Start(IPAddress ipAddress, int port, string nick)
{
Nick = nick;
 
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();
 
BindHandlers();
 
await Client.SubscribeAsync(
new TopicFilterBuilder()
.WithTopic("lobby")
.Build()
);
 
await Client.SubscribeAsync(
new TopicFilterBuilder()
.WithTopic("exchange")
.Build()
);
 
await Client.StartAsync(options);
 
ClientRunning = true;
}
 
private void ClientOnApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e)
{
if (e.ApplicationMessage.Topic == "lobby")
{
using (var memoryStream = new MemoryStream(e.ApplicationMessage.Payload))
{
memoryStream.Position = 0L;
 
var lobbyMessage = (LobbyMessage)LobbyMessage.XmlSerializer.Deserialize(memoryStream);
 
UpdateLobbyMessage(lobbyMessage.Nick, lobbyMessage.Message);
}
return;
}
}
 
private void ClientOnConnected(object sender, MqttClientConnectedEventArgs e)
{
LogActivity(Properties.Strings.Client_connected);
}
 
private void ClientOnDisconnected(object sender, MqttClientDisconnectedEventArgs e)
{
LogActivity(Properties.Strings.Client_disconnected, e.Exception.Message);
}
 
private void ClientOnConnectingFailed(object sender, MqttManagedProcessFailedEventArgs e)
{
LogActivity(Properties.Strings.Client_connection_failed, e.Exception.Message);
}
 
private void UpdateLobbyMessage(string client, string message)
{
WingManForm.LobbyTextBox.Invoke((MethodInvoker)delegate
{
WingManForm.LobbyTextBox.AppendText($"{client} : {message}" + Environment.NewLine);
});
}
 
private void LogActivity(params string[] messages)
{
WingManForm.ActivityTextBox.Invoke((MethodInvoker) delegate
{
WingManForm.ActivityTextBox.Text =
string.Join(" : ", messages) + Environment.NewLine + WingManForm.ActivityTextBox.Text;
});
}
 
public async Task Stop()
{
UnbindHandlers();
 
await Client.StopAsync();
 
ClientRunning = false;
}
 
public void Dispose()
{
UnbindHandlers();
 
Client.StopAsync().Wait();
 
Client?.Dispose();
}
 
public void BindHandlers()
{
Client.Connected += ClientOnConnected;
Client.Disconnected += ClientOnDisconnected;
Client.ConnectingFailed += ClientOnConnectingFailed;
Client.ApplicationMessageReceived += ClientOnApplicationMessageReceived;
}
 
public void UnbindHandlers()
{
Client.Connected -= ClientOnConnected;
Client.Disconnected -= ClientOnDisconnected;
Client.ConnectingFailed -= ClientOnConnectingFailed;
Client.ApplicationMessageReceived -= ClientOnApplicationMessageReceived;
}
 
public async Task BroadcastLobbyMessage(string text)
{
using (var memoryStream = new MemoryStream())
{
LobbyMessage.XmlSerializer.Serialize(memoryStream, new LobbyMessage()
{
Message = text,
Nick = Nick
});
 
memoryStream.Position = 0L;
 
await Client.PublishAsync(new ManagedMqttApplicationMessage
{
ApplicationMessage = new MqttApplicationMessage
{
Payload = memoryStream.ToArray(),
Topic = "lobby"
}
});
 
}
}
}
}
/trunk/WingMan/Communication/MQTTServer.cs
@@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MQTTnet;
using MQTTnet.Server;
 
namespace WingMan.Host
{
public class MQTTServer
{
private WingManForm WingManForm { get; set; }
private IMqttServer Server { get; set; }
public bool ServerRunning { get; set; }
public string Nick { get; set; }
 
public MQTTServer()
{
Server = new MqttFactory().CreateMqttServer();
}
 
public MQTTServer(WingManForm wingManForm) : this()
{
WingManForm = wingManForm;
}
 
public async Task Stop()
{
UnbindHandlers();
 
await Server.StopAsync().ConfigureAwait(false);
 
ServerRunning = false;
}
 
public async Task Start(IPAddress ipAddress, int port, string nick)
{
Nick = nick;
 
var optionsBuilder = new MqttServerOptionsBuilder()
.WithDefaultEndpointBoundIPAddress(ipAddress)
.WithSubscriptionInterceptor(MQTTSubscriptionIntercept)
.WithDefaultEndpointPort(port);
 
BindHandlers();
 
await Server.StartAsync(optionsBuilder.Build()).ConfigureAwait(false);
 
ServerRunning = true;
}
 
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 ServerOnClientUnsubscribedTopic(object sender, MqttClientUnsubscribedTopicEventArgs e)
{
LogActivity(Properties.Strings.Client_unsubscribed_from_topic, e.ClientId, e.TopicFilter);
}
 
private void ServerOnClientSubscribedTopic(object sender, MqttClientSubscribedTopicEventArgs e)
{
LogActivity(Properties.Strings.Client_subscribed_to_topic, e.ClientId, e.TopicFilter.Topic);
}
 
private void ServerOnClientDisconnected(object sender, MqttClientDisconnectedEventArgs e)
{
LogActivity(Properties.Strings.Client_disconnected, e.ClientId);
}
 
private void ServerOnClientConnected(object sender, MqttClientConnectedEventArgs e)
{
LogActivity(Properties.Strings.Client_connected, e.ClientId);
}
 
private void ServerOnStopped(object sender, EventArgs e)
{
LogActivity(Properties.Strings.Server_stopped);
}
 
private void ServerOnStarted(object sender, EventArgs e)
{
LogActivity(Properties.Strings.Server_started);
}
 
private void BindHandlers()
{
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)
{
using (var memoryStream = new MemoryStream(e.ApplicationMessage.Payload))
{
memoryStream.Position = 0L;
 
var lobbyMessage = (LobbyMessage)LobbyMessage.XmlSerializer.Deserialize(memoryStream);
 
UpdateLobbyMessage(lobbyMessage.Nick, lobbyMessage.Message);
}
}
 
private void UnbindHandlers()
{
Server.Started -= ServerOnStarted;
Server.Stopped -= ServerOnStopped;
Server.ClientConnected -= ServerOnClientConnected;
Server.ClientDisconnected -= ServerOnClientDisconnected;
Server.ClientSubscribedTopic -= ServerOnClientSubscribedTopic;
Server.ClientUnsubscribedTopic -= ServerOnClientUnsubscribedTopic;
Server.ApplicationMessageReceived -= ServerOnApplicationMessageReceived;
}
 
private void UpdateLobbyMessage(string client, string message)
{
WingManForm.LobbyTextBox.Invoke((MethodInvoker)delegate
{
WingManForm.LobbyTextBox.AppendText($"{client} : {message}" + Environment.NewLine);
});
}
 
private void LogActivity(params string[] messages)
{
WingManForm.ActivityTextBox.Invoke((MethodInvoker) delegate
{
WingManForm.ActivityTextBox.Text =
string.Join(" : ", messages) + Environment.NewLine + WingManForm.ActivityTextBox.Text;
});
}
 
public async Task BroadcastLobbyMessage(string text)
{
using (var memoryStream = new MemoryStream())
{
LobbyMessage.XmlSerializer.Serialize(memoryStream, new LobbyMessage()
{
Message = text,
Nick = Nick
});
 
memoryStream.Position = 0L;
 
await Server.PublishAsync(
new MqttApplicationMessage { Payload = memoryStream.ToArray(), Topic = "lobby" });
 
}
}
}
}
/trunk/WingMan/HelmBinding.cs
@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace WingMan
{
public class HelmBinding
{
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/HelmBindings.cs
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace WingMan
{
public class HelmBindings
{
public List<HelmBinding> Bindings { get; set; }
}
}
/trunk/WingMan/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/Properties/Strings.Designer.cs
@@ -133,15 +133,6 @@
}
/// <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 {
@@ -158,14 +149,5 @@
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,9 +141,6 @@
<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>
@@ -150,7 +147,4 @@
<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/WingMan.csproj
@@ -52,9 +52,6 @@
</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" />
@@ -66,18 +63,10 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<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="Communication\MQTTClient.cs" />
<Compile Include="HelmBinding.cs" />
<Compile Include="HelmBindings.cs" />
<Compile Include="LobbyMessage.cs" />
<Compile Include="WingManForm.cs">
<SubType>Form</SubType>
</Compile>
@@ -84,6 +73,7 @@
<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.WingBindingsComboBox = new System.Windows.Forms.ComboBox();
this.comboBox1 = 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.WingBindingsListBox = new System.Windows.Forms.ListBox();
this.listBox1 = 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.WingBindingsComboBox);
this.groupBox1.Controls.Add(this.comboBox1);
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.WingBindingsListBox);
this.groupBox1.Controls.Add(this.listBox1);
this.groupBox1.Location = new System.Drawing.Point(8, 10);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(248, 296);
@@ -93,14 +93,13 @@
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Wing (Them)";
//
// WingBindingsComboBox
// comboBox1
//
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);
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;
//
// button2
//
@@ -140,14 +139,14 @@
this.textBox1.Size = new System.Drawing.Size(168, 20);
this.textBox1.TabIndex = 1;
//
// WingBindingsListBox
// listBox1
//
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;
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;
//
// groupBox2
//
@@ -170,7 +169,6 @@
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
//
@@ -495,7 +493,7 @@
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.GroupBox groupBox3;
private System.Windows.Forms.ListBox WingBindingsListBox;
private System.Windows.Forms.ListBox listBox1;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.TextBox LobbySayTextBox;
@@ -516,7 +514,7 @@
private System.Windows.Forms.TextBox Address;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel;
private System.Windows.Forms.ComboBox WingBindingsComboBox;
private System.Windows.Forms.ComboBox comboBox1;
private System.Windows.Forms.Label label5;
private System.Windows.Forms.TextBox Nick;
private System.Windows.Forms.TabControl tabControl1;
/trunk/WingMan/WingManForm.cs
@@ -1,118 +1,67 @@
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.MouseKey;
using WingMan.Properties;
using WingMan.Host;
 
namespace WingMan
{
public partial class WingManForm : Form
{
public WingManForm()
{
InitializeComponent();
private MQTTServer MQTTServer { get; set; }
 
MQTTCommunication = new MQTTCommunication();
private MQTTClient MQTTClient { get; set; }
 
MouseKeyBindings = new MouseKeyBindings(new List<MouseKeyBinding>());
private SemaphoreSlim MQTTServerSemaphore {get; set;} = new SemaphoreSlim(1, 1);
 
HelmBindingSource = new BindingSource
{
DataSource = MouseKeyBindings.Bindings
};
HelmBindingsListBox.DisplayMember = "DisplayName";
HelmBindingsListBox.ValueMember = "Keys";
HelmBindingsListBox.DataSource = HelmBindingSource;
private SemaphoreSlim MQTTClientSemaphore { get; set; } = new SemaphoreSlim(1, 1);
 
MouseKeyBindingsExchange = new MouseKeyBindingsExchange();
WingBindingSource = new BindingSource
{
DataSource = MouseKeyBindingsExchange.ExchangeBindings
};
WingBindingsComboBox.DisplayMember = "Nick";
WingBindingsComboBox.ValueMember = "Names";
WingBindingsComboBox.DataSource = WingBindingSource;
private static IKeyboardMouseEvents MouseKeyApplicationHook { get; set; }
 
// Start lobby message synchronizer.
LobbyMessageSynchronizer = new LobbyMessageSynchronizer(MQTTCommunication);
LobbyMessageSynchronizer.OnLobbyMessageReceived += OnLobbyMessageReceived;
private static IKeyboardMouseEvents MouseKeyGlobalHook { get; set; }
 
// Start mouse key bindings synchronizer.
MouseKeyBindingsSynchronizer = new MouseKeyBindingsSynchronizer(MouseKeyBindings, MQTTCommunication);
MouseKeyBindingsSynchronizer.OnMouseKeyBindingsSynchronized += OnMouseKeyBindingsSynchronized;
}
private List<string> MouseKeyCombo { 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 HelmBindings HelmBindings { get; set; }
 
private BindingSource HelmBindingSource { get; set; }
 
var exchangeBindings = MouseKeyBindingsExchange.ExchangeBindings.FirstOrDefault(exchangeBinding =>
string.Equals(exchangeBinding.Nick, binding.Nick, StringComparison.Ordinal));
public ConcurrentDictionary<string, HelmBindings> WingBindings { get; set; }
 
// If the nick has not been registered add it.
if (exchangeBindings == null)
{
MouseKeyBindingsExchange.ExchangeBindings.Add(binding);
continue;
}
public WingManForm()
{
InitializeComponent();
 
// If the nick has been added, then update the binding names.
exchangeBindings.Names = binding.Names;
MouseKeyGlobalHook = Hook.GlobalEvents();
 
// Update wing list box.
var selectedExchangeBinding = (MouseKeyBindingExchange)WingBindingsComboBox.SelectedItem;
if (selectedExchangeBinding == null || !string.Equals(selectedExchangeBinding.Nick, binding.Nick))
continue;
MQTTClient = new MQTTClient(this);
MQTTServer = new MQTTServer(this);
 
WingBindingsListBox.Items.Clear();
WingBindingsListBox.DisplayMember = "Name";
WingBindingsListBox.ValueMember = "Name";
WingBindingsListBox.Items.AddRange(exchangeBindings.Names.Select(name => (object)name).ToArray());
HelmBindings = new HelmBindings();
HelmBindings.Bindings = new List<HelmBinding>();
 
}
HelmBindingSource = new BindingSource();
HelmBindingSource.DataSource = HelmBindings.Bindings;
 
WingBindingSource.ResetBindings(false);
HelmBindingsListBox.DisplayMember = "DisplayName";
HelmBindingsListBox.ValueMember = "Keys";
HelmBindingsListBox.DataSource = HelmBindingSource;
 
});
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;
@@ -126,18 +75,15 @@
private async void HostButtonClickAsync(object sender, EventArgs e)
{
// Stop the MQTT server if it is running.
if (MQTTCommunication.Running)
if (MQTTServer.ServerRunning)
{
await MQTTCommunication.Stop().ConfigureAwait(false);
toolStripStatusLabel.Text = Strings.Server_stopped;
await StopServer();
toolStripStatusLabel.Text = Properties.Strings.Server_stopped;
HostButton.BackColor = Color.Empty;
 
// Enable controls.
ConnectButton.Enabled = true;
Address.Enabled = true;
Port.Enabled = true;
Nick.Enabled = true;
 
EnableConnectionControls();
return;
}
 
@@ -145,17 +91,29 @@
return;
 
// Start the MQTT server.
await MQTTCommunication.Start(MQTTCommunicationType.Server, ipAddress, port, nick).ConfigureAwait(false);
toolStripStatusLabel.Text = Strings.Server_started;
await StartServer(ipAddress, port, nick);
toolStripStatusLabel.Text = Properties.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;
@@ -201,17 +159,41 @@
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 (MQTTCommunication.Running)
if (MQTTClient.ClientRunning)
{
await MQTTCommunication.Stop().ConfigureAwait(false);
ConnectButton.Text = Strings.Connect;
await StopClient();
ConnectButton.Text = Properties.Strings.Connect;
ConnectButton.BackColor = Color.Empty;
 
Address.Enabled = true;
Port.Enabled = true;
Nick.Enabled = true;
EnableConnectionControls();
HostButton.Enabled = true;
return;
}
@@ -219,26 +201,57 @@
if (!ValidateAddressPort(out var ipAddress, out var port, out var nick))
return;
 
await MQTTCommunication.Start(MQTTCommunicationType.Client, ipAddress, port, nick).ConfigureAwait(false);
await StartClient(ipAddress, port, nick);
 
toolStripStatusLabel.Text = Strings.Client_started;
ConnectButton.Text = Strings.Disconnect;
toolStripStatusLabel.Text = Properties.Strings.Client_started;
ConnectButton.Text = Properties.Strings.Disconnect;
ConnectButton.BackColor = Color.Aquamarine;
 
HostButton.Enabled = false;
Address.Enabled = false;
Port.Enabled = false;
Nick.Enabled = false;
DisableConnectionControls();
}
 
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;
 
await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text).ConfigureAwait(false);
if (MQTTServer.ServerRunning)
{
await MQTTServer.BroadcastLobbyMessage(LobbySayTextBox.Text);
}
 
LobbySayTextBox.Text = string.Empty;
if (MQTTClient.ClientRunning)
{
await MQTTClient.BroadcastLobbyMessage(LobbySayTextBox.Text);
}
 
}
 
private void HelmAddButtonClick(object sender, EventArgs e)
@@ -258,18 +271,21 @@
MouseKeyApplicationHook.KeyUp += MouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown += MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.MouseUp += MouseKeyHookOnMouseUp;
 
}
 
private void MouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
{
MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo));
HelmBindings.Bindings.Add(new HelmBinding
{
Keys = MouseKeyCombo,
Name = HelmNameTextBox.Text
});
 
HelmBindingSource.ResetBindings(false);
 
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
 
MouseKeyApplicationHook.Dispose();
 
@@ -279,14 +295,16 @@
 
private void MouseKeyHookOnMouseUp(object sender, MouseEventArgs e)
{
MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo));
HelmBindings.Bindings.Add(new HelmBinding
{
Keys = MouseKeyCombo,
Name = HelmNameTextBox.Text
});
 
HelmBindingSource.ResetBindings(false);
 
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
 
MouseKeyApplicationHook.Dispose();
 
@@ -297,7 +315,7 @@
 
private void MouseKeyHookOnMouseDown(object sender, MouseEventArgs e)
{
MouseKeyCombo.Add(e.Button.ToDisplayName());
MouseKeyCombo.Add(MouseButtonToName(e.Button));
}
 
private void MouseKeyHookOnKeyDown(object sender, KeyEventArgs e)
@@ -304,7 +322,7 @@
{
e.SuppressKeyPress = true;
 
MouseKeyCombo.Add(e.KeyCode.ToDisplayName());
MouseKeyCombo.Add(KeyCodeToName((int) e.KeyCode));
}
 
private void HelmNameTextBoxClick(object sender, EventArgs e)
@@ -312,33 +330,431 @@
HelmNameTextBox.BackColor = Color.Empty;
}
 
private void HelmRemoveButtonClick(object sender, EventArgs e)
private string MouseButtonToName(MouseButtons button)
{
var helmBinding = (MouseKeyBinding) HelmBindingsListBox.SelectedItem;
if (helmBinding == null)
return;
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;
}
 
MouseKeyBindings.Bindings.Remove(helmBinding);
HelmBindingSource.ResetBindings(false);
return mouseButton;
}
 
private async void LobbySayButtonClick(object sender, EventArgs e)
private string KeyCodeToName(int code)
{
await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text).ConfigureAwait(false);
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;
}
 
LobbySayTextBox.Text = string.Empty;
return keyString;
}
 
private void WingBindingsComboBoxIndexChanged(object sender, EventArgs e)
private void HelmRemoveButtonClick(object sender, EventArgs e)
{
var exchangeBinding = (MouseKeyBindingExchange) WingBindingsComboBox.SelectedItem;
if (exchangeBinding == null)
var helmBinding = (HelmBinding)HelmBindingsListBox.SelectedItem;
if (helmBinding == null)
return;
 
WingBindingsListBox.Items.Clear();
WingBindingsListBox.DisplayMember = "Name";
WingBindingsListBox.ValueMember = "Name";
WingBindingsListBox.Items.AddRange(exchangeBinding.Names.Select(name => (object)name).ToArray());
HelmBindings.Bindings.Remove(helmBinding);
HelmBindingSource.ResetBindings(false);
}
}
}
/trunk/WingMan/packages.config
@@ -1,6 +1,5 @@
<?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" />