/trunk/WingMan/Communication/MQTTCommunication.cs |
@@ -0,0 +1,296 @@ |
using System; |
using System.Net; |
using System.Threading.Tasks; |
using MQTTnet; |
using MQTTnet.Client; |
using MQTTnet.Extensions.ManagedClient; |
using MQTTnet.Server; |
using MqttClientConnectedEventArgs = MQTTnet.Client.MqttClientConnectedEventArgs; |
using MqttClientDisconnectedEventArgs = MQTTnet.Client.MqttClientDisconnectedEventArgs; |
|
namespace WingMan.Communication |
{ |
public class MQTTCommunication |
{ |
public MQTTCommunication(IPAddress ipAddress, int port, string nick) :this() |
{ |
IPAddress = ipAddress; |
Port = port; |
Nick = nick; |
} |
|
public MQTTCommunication() |
{ |
Client = new MqttFactory().CreateManagedMqttClient(); |
Server = new MqttFactory().CreateMqttServer(); |
} |
|
private IManagedMqttClient Client { get; } |
|
private IMqttServer Server { get; } |
|
public bool Running { get; set; } |
|
public string Nick { get; set; } |
|
private IPAddress IPAddress { get; set; } |
|
private int Port { get; set; } |
|
public MQTTCommunicationType Type { get; set; } |
|
public delegate void MessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e); |
|
public event MessageReceived OnMessageReceived; |
|
public delegate void ClientConnected(object sender, MqttClientConnectedEventArgs e); |
|
public event ClientConnected OnClientConnected; |
|
public delegate void ClientDisconnected(object sender, MqttClientDisconnectedEventArgs e); |
|
public event ClientDisconnected OnClientDisconnected; |
|
public delegate void ClientConnectionFailed(object sender, MqttManagedProcessFailedEventArgs e); |
|
public event ClientConnectionFailed OnClientConnectionFailed; |
|
public delegate void ClientUnsubscribed(object sender, MqttClientUnsubscribedTopicEventArgs e); |
|
public event ClientUnsubscribed OnClientUnsubscribed; |
|
public delegate void ClientSubscribed(object sender, MqttClientSubscribedTopicEventArgs e); |
|
public event ClientSubscribed OnClientSubscribed; |
|
public delegate void ServerClientDisconnected(object sender, MQTTnet.Server.MqttClientDisconnectedEventArgs e); |
|
public event ServerClientDisconnected OnServerClientDisconnected; |
|
public delegate void ServerClientConnected(object sender, MQTTnet.Server.MqttClientConnectedEventArgs e); |
|
public event ServerClientConnected OnServerClientConnected; |
|
public delegate void ServerStarted(object sender, EventArgs e); |
|
public event ServerStarted OnServerStarted; |
|
public delegate void ServerStopped(object sender, EventArgs e); |
|
public event ServerStopped OnServerStopped; |
|
public async Task Start(MQTTCommunicationType type, IPAddress ipAddress, int port, string nick) |
{ |
Type = type; |
IPAddress = ipAddress; |
Port = port; |
Nick = nick; |
|
switch (type) |
{ |
case MQTTCommunicationType.Client: |
await StartClient().ConfigureAwait(false); |
break; |
case MQTTCommunicationType.Server: |
await StartServer().ConfigureAwait(false); |
break; |
} |
} |
|
private async Task StartClient() |
{ |
var clientOptions = new MqttClientOptionsBuilder() |
.WithTcpServer(IPAddress.ToString(), Port); |
|
// Setup and start a managed MQTT client. |
var options = new ManagedMqttClientOptionsBuilder() |
.WithAutoReconnectDelay(TimeSpan.FromSeconds(5)) |
.WithClientOptions(clientOptions.Build()) |
.Build(); |
|
BindClientHandlers(); |
|
await Client.SubscribeAsync( |
new TopicFilterBuilder() |
.WithTopic("lobby") |
.Build() |
).ConfigureAwait(false); |
|
await Client.SubscribeAsync( |
new TopicFilterBuilder() |
.WithTopic("exchange") |
.Build() |
).ConfigureAwait(false); |
|
await Client.StartAsync(options).ConfigureAwait(false); |
|
Running = true; |
} |
|
private async Task StopClient() |
{ |
UnbindClientHandlers(); |
|
await Client.StopAsync().ConfigureAwait(false); |
} |
|
public void BindClientHandlers() |
{ |
Client.Connected += ClientOnConnected; |
Client.Disconnected += ClientOnDisconnected; |
Client.ConnectingFailed += ClientOnConnectingFailed; |
Client.ApplicationMessageReceived += ClientOnApplicationMessageReceived; |
} |
|
public void UnbindClientHandlers() |
{ |
Client.Connected -= ClientOnConnected; |
Client.Disconnected -= ClientOnDisconnected; |
Client.ConnectingFailed -= ClientOnConnectingFailed; |
Client.ApplicationMessageReceived -= ClientOnApplicationMessageReceived; |
} |
|
private void ClientOnApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e) |
{ |
OnMessageReceived?.Invoke(sender, e); |
} |
|
private void ClientOnConnectingFailed(object sender, MqttManagedProcessFailedEventArgs e) |
{ |
OnClientConnectionFailed?.Invoke(sender, e); |
} |
|
private void ClientOnDisconnected(object sender, MqttClientDisconnectedEventArgs e) |
{ |
OnClientDisconnected?.Invoke(sender, e); |
} |
|
private void ClientOnConnected(object sender, MqttClientConnectedEventArgs e) |
{ |
OnClientConnected?.Invoke(sender, e); |
} |
|
private async Task StartServer() |
{ |
var optionsBuilder = new MqttServerOptionsBuilder() |
.WithDefaultEndpointBoundIPAddress(IPAddress) |
.WithSubscriptionInterceptor(MQTTSubscriptionIntercept) |
.WithDefaultEndpointPort(Port); |
|
BindServerHandlers(); |
|
await Server.StartAsync(optionsBuilder.Build()).ConfigureAwait(false); |
|
Running = true; |
} |
|
private async Task StopServer() |
{ |
UnbindServerHandlers(); |
|
await Server.StopAsync().ConfigureAwait(false); |
} |
|
private void MQTTSubscriptionIntercept(MqttSubscriptionInterceptorContext context) |
{ |
if (context.TopicFilter.Topic != "lobby" && |
context.TopicFilter.Topic != "exchange") |
{ |
context.AcceptSubscription = false; |
context.CloseConnection = true; |
return; |
} |
|
context.AcceptSubscription = true; |
context.CloseConnection = false; |
} |
|
private void BindServerHandlers() |
{ |
Server.Started += ServerOnStarted; |
Server.Stopped += ServerOnStopped; |
Server.ClientConnected += ServerOnClientConnected; |
Server.ClientDisconnected += ServerOnClientDisconnected; |
Server.ClientSubscribedTopic += ServerOnClientSubscribedTopic; |
Server.ClientUnsubscribedTopic += ServerOnClientUnsubscribedTopic; |
Server.ApplicationMessageReceived += ServerOnApplicationMessageReceived; |
} |
|
private void UnbindServerHandlers() |
{ |
Server.Started -= ServerOnStarted; |
Server.Stopped -= ServerOnStopped; |
Server.ClientConnected -= ServerOnClientConnected; |
Server.ClientDisconnected -= ServerOnClientDisconnected; |
Server.ClientSubscribedTopic -= ServerOnClientSubscribedTopic; |
Server.ClientUnsubscribedTopic -= ServerOnClientUnsubscribedTopic; |
Server.ApplicationMessageReceived -= ServerOnApplicationMessageReceived; |
} |
|
private void ServerOnApplicationMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e) |
{ |
OnMessageReceived?.Invoke(sender, e); |
} |
|
private void ServerOnClientUnsubscribedTopic(object sender, MqttClientUnsubscribedTopicEventArgs e) |
{ |
OnClientUnsubscribed?.Invoke(sender, e); |
} |
|
private void ServerOnClientSubscribedTopic(object sender, MqttClientSubscribedTopicEventArgs e) |
{ |
OnClientSubscribed?.Invoke(sender, e); |
} |
|
private void ServerOnClientDisconnected(object sender, MQTTnet.Server.MqttClientDisconnectedEventArgs e) |
{ |
OnServerClientDisconnected?.Invoke(sender, e); |
} |
|
private void ServerOnClientConnected(object sender, MQTTnet.Server.MqttClientConnectedEventArgs e) |
{ |
OnServerClientConnected?.Invoke(sender, e); |
} |
|
private void ServerOnStopped(object sender, EventArgs e) |
{ |
OnServerStopped?.Invoke(sender, e); |
} |
|
private void ServerOnStarted(object sender, EventArgs e) |
{ |
OnServerStarted?.Invoke(sender, e); |
} |
|
public async Task Stop() |
{ |
switch (Type) |
{ |
case MQTTCommunicationType.Server: |
await StopServer().ConfigureAwait(false); |
break; |
case MQTTCommunicationType.Client: |
await StopClient().ConfigureAwait(false); |
break; |
} |
|
Running = false; |
} |
|
public async Task Broadcast(string topic, byte[] payload) |
{ |
switch (Type) |
{ |
case MQTTCommunicationType.Client: |
await Client.PublishAsync(new ManagedMqttApplicationMessage |
{ |
ApplicationMessage = new MqttApplicationMessage { Topic = topic, Payload = payload } |
}).ConfigureAwait(false); |
break; |
case MQTTCommunicationType.Server: |
await Server.PublishAsync(new MqttApplicationMessage {Topic = topic, Payload = payload}).ConfigureAwait(false); |
break; |
} |
} |
} |
} |
/trunk/WingMan/MouseKey/MouseKeyBindingsSynchronizer.cs |
@@ -0,0 +1,88 @@ |
using System; |
using System.Collections.Concurrent; |
using System.Collections.Generic; |
using System.IO; |
using System.Linq; |
using System.Text; |
using System.Threading; |
using System.Threading.Tasks; |
using MQTTnet; |
using MQTTnet.Extensions.ManagedClient; |
using WingMan.Communication; |
|
namespace WingMan.MouseKey |
{ |
public class MouseKeyBindingsSynchronizer |
{ |
public delegate void MouseKeyBindingsSynchronized(object sender, MouseKeyBindingsSynchronizedEventArgs e); |
public event MouseKeyBindingsSynchronized OnMouseKeyBindingsSynchronized; |
|
private MouseKeyBindings MouseKeyBindings { get; set; } |
|
private ConcurrentDictionary<string, List<MouseKeyBindingExchange>> SynchronizedMouseKeyBindings { get; set; } |
|
private MQTTCommunication MQTTCommunication { get; set; } |
|
private CancellationTokenSource SynchronizationCancellationTokenSource { get; set; } |
|
public MouseKeyBindingsSynchronizer(MouseKeyBindings mouseKeyBindings, MQTTCommunication MQTTCommunication) |
{ |
MouseKeyBindings = mouseKeyBindings; |
this.MQTTCommunication = MQTTCommunication; |
|
SynchronizedMouseKeyBindings = new ConcurrentDictionary<string, List<MouseKeyBindingExchange>>(); |
|
MQTTCommunication.OnMessageReceived += MqttCommunicationOnOnMessageReceived; |
|
SynchronizationCancellationTokenSource = new CancellationTokenSource(); |
|
Task.Run(Synchronize, SynchronizationCancellationTokenSource.Token); |
} |
|
private void MqttCommunicationOnOnMessageReceived(object sender, MqttApplicationMessageReceivedEventArgs e) |
{ |
if (e.ApplicationMessage.Topic != "exchange") |
return; |
|
using (var memoryStream = new MemoryStream(e.ApplicationMessage.Payload)) |
{ |
memoryStream.Position = 0L; |
|
var mouseKeyBindingsExchange = (MouseKeyBindingsExchange)MouseKeyBindingsExchange.XmlSerializer.Deserialize(memoryStream); |
|
if (SynchronizedMouseKeyBindings.TryGetValue(mouseKeyBindingsExchange.Nick, out var mouseKeyBinding) && |
mouseKeyBinding.SequenceEqual(mouseKeyBindingsExchange.ExchangeBindings)) |
return; |
|
// Nick does not exist so the bindings will be added. |
SynchronizedMouseKeyBindings.AddOrUpdate(mouseKeyBindingsExchange.Nick, |
mouseKeyBindingsExchange.ExchangeBindings, (s, list) => mouseKeyBindingsExchange.ExchangeBindings); |
|
OnMouseKeyBindingsSynchronized?.Invoke(sender, |
new MouseKeyBindingsSynchronizedEventArgs( |
mouseKeyBindingsExchange.ExchangeBindings)); |
} |
} |
|
private async Task Synchronize() |
{ |
do |
{ |
await Task.Delay(1000).ConfigureAwait(false); |
|
if (!MouseKeyBindings.Bindings.Any()) |
continue; |
|
using (var memoryStream = new MemoryStream()) |
{ |
MouseKeyBindingsExchange.XmlSerializer.Serialize(memoryStream, new MouseKeyBindingsExchange(MQTTCommunication.Nick, MouseKeyBindings)); |
|
memoryStream.Position = 0L; |
|
await MQTTCommunication.Broadcast("exchange", memoryStream.ToArray()).ConfigureAwait(false); |
} |
|
} while (!SynchronizationCancellationTokenSource.Token.IsCancellationRequested); |
} |
} |
} |
/trunk/WingMan/WingManForm.Designer.cs |
@@ -29,12 +29,12 @@ |
private void InitializeComponent() |
{ |
this.groupBox1 = new System.Windows.Forms.GroupBox(); |
this.comboBox1 = new System.Windows.Forms.ComboBox(); |
this.WingBindingsComboBox = new System.Windows.Forms.ComboBox(); |
this.button2 = new System.Windows.Forms.Button(); |
this.button1 = new System.Windows.Forms.Button(); |
this.label1 = new System.Windows.Forms.Label(); |
this.textBox1 = new System.Windows.Forms.TextBox(); |
this.listBox1 = new System.Windows.Forms.ListBox(); |
this.WingBindingsListBox = new System.Windows.Forms.ListBox(); |
this.groupBox2 = new System.Windows.Forms.GroupBox(); |
this.button5 = new System.Windows.Forms.Button(); |
this.LobbySayTextBox = new System.Windows.Forms.TextBox(); |
@@ -80,12 +80,12 @@ |
// |
// groupBox1 |
// |
this.groupBox1.Controls.Add(this.comboBox1); |
this.groupBox1.Controls.Add(this.WingBindingsComboBox); |
this.groupBox1.Controls.Add(this.button2); |
this.groupBox1.Controls.Add(this.button1); |
this.groupBox1.Controls.Add(this.label1); |
this.groupBox1.Controls.Add(this.textBox1); |
this.groupBox1.Controls.Add(this.listBox1); |
this.groupBox1.Controls.Add(this.WingBindingsListBox); |
this.groupBox1.Location = new System.Drawing.Point(8, 10); |
this.groupBox1.Name = "groupBox1"; |
this.groupBox1.Size = new System.Drawing.Size(248, 296); |
@@ -93,13 +93,14 @@ |
this.groupBox1.TabStop = false; |
this.groupBox1.Text = "Wing (Them)"; |
// |
// comboBox1 |
// WingBindingsComboBox |
// |
this.comboBox1.FormattingEnabled = true; |
this.comboBox1.Location = new System.Drawing.Point(8, 24); |
this.comboBox1.Name = "comboBox1"; |
this.comboBox1.Size = new System.Drawing.Size(232, 21); |
this.comboBox1.TabIndex = 5; |
this.WingBindingsComboBox.FormattingEnabled = true; |
this.WingBindingsComboBox.Location = new System.Drawing.Point(8, 24); |
this.WingBindingsComboBox.Name = "WingBindingsComboBox"; |
this.WingBindingsComboBox.Size = new System.Drawing.Size(232, 21); |
this.WingBindingsComboBox.TabIndex = 5; |
this.WingBindingsComboBox.SelectedIndexChanged += new System.EventHandler(this.WingBindingsComboBoxIndexChanged); |
// |
// button2 |
// |
@@ -139,14 +140,14 @@ |
this.textBox1.Size = new System.Drawing.Size(168, 20); |
this.textBox1.TabIndex = 1; |
// |
// listBox1 |
// WingBindingsListBox |
// |
this.listBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; |
this.listBox1.FormattingEnabled = true; |
this.listBox1.Location = new System.Drawing.Point(8, 56); |
this.listBox1.Name = "listBox1"; |
this.listBox1.Size = new System.Drawing.Size(232, 158); |
this.listBox1.TabIndex = 0; |
this.WingBindingsListBox.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle; |
this.WingBindingsListBox.FormattingEnabled = true; |
this.WingBindingsListBox.Location = new System.Drawing.Point(8, 56); |
this.WingBindingsListBox.Name = "WingBindingsListBox"; |
this.WingBindingsListBox.Size = new System.Drawing.Size(232, 158); |
this.WingBindingsListBox.TabIndex = 0; |
// |
// groupBox2 |
// |
@@ -169,6 +170,7 @@ |
this.button5.Size = new System.Drawing.Size(40, 20); |
this.button5.TabIndex = 2; |
this.button5.UseVisualStyleBackColor = true; |
this.button5.Click += new System.EventHandler(this.LobbySayButtonClick); |
// |
// LobbySayTextBox |
// |
@@ -493,7 +495,7 @@ |
private System.Windows.Forms.GroupBox groupBox1; |
private System.Windows.Forms.GroupBox groupBox2; |
private System.Windows.Forms.GroupBox groupBox3; |
private System.Windows.Forms.ListBox listBox1; |
private System.Windows.Forms.ListBox WingBindingsListBox; |
private System.Windows.Forms.Label label1; |
private System.Windows.Forms.TextBox textBox1; |
private System.Windows.Forms.TextBox LobbySayTextBox; |
@@ -514,7 +516,7 @@ |
private System.Windows.Forms.TextBox Address; |
private System.Windows.Forms.StatusStrip statusStrip; |
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel; |
private System.Windows.Forms.ComboBox comboBox1; |
private System.Windows.Forms.ComboBox WingBindingsComboBox; |
private System.Windows.Forms.Label label5; |
private System.Windows.Forms.TextBox Nick; |
private System.Windows.Forms.TabControl tabControl1; |
/trunk/WingMan/WingManForm.cs |
@@ -1,67 +1,118 @@ |
using System; |
using System.Collections.Concurrent; |
using System.Collections.Generic; |
using System.ComponentModel; |
using System.Data; |
using System.Drawing; |
using System.Globalization; |
using System.Linq; |
using System.Net; |
using System.Resources; |
using System.Text; |
using System.Threading; |
using System.Threading.Tasks; |
using System.Windows.Forms; |
using Gma.System.MouseKeyHook; |
using WingMan.Communication; |
using WingMan.Host; |
using WingMan.MouseKey; |
using WingMan.Properties; |
|
namespace WingMan |
{ |
public partial class WingManForm : Form |
{ |
private MQTTServer MQTTServer { get; set; } |
public WingManForm() |
{ |
InitializeComponent(); |
|
private MQTTClient MQTTClient { get; set; } |
MQTTCommunication = new MQTTCommunication(); |
|
private SemaphoreSlim MQTTServerSemaphore {get; set;} = new SemaphoreSlim(1, 1); |
MouseKeyBindings = new MouseKeyBindings(new List<MouseKeyBinding>()); |
|
private SemaphoreSlim MQTTClientSemaphore { get; set; } = new SemaphoreSlim(1, 1); |
HelmBindingSource = new BindingSource |
{ |
DataSource = MouseKeyBindings.Bindings |
}; |
HelmBindingsListBox.DisplayMember = "DisplayName"; |
HelmBindingsListBox.ValueMember = "Keys"; |
HelmBindingsListBox.DataSource = HelmBindingSource; |
|
private static IKeyboardMouseEvents MouseKeyApplicationHook { get; set; } |
MouseKeyBindingsExchange = new MouseKeyBindingsExchange(); |
WingBindingSource = new BindingSource |
{ |
DataSource = MouseKeyBindingsExchange.ExchangeBindings |
}; |
WingBindingsComboBox.DisplayMember = "Nick"; |
WingBindingsComboBox.ValueMember = "Names"; |
WingBindingsComboBox.DataSource = WingBindingSource; |
|
private static IKeyboardMouseEvents MouseKeyGlobalHook { get; set; } |
// Start lobby message synchronizer. |
LobbyMessageSynchronizer = new LobbyMessageSynchronizer(MQTTCommunication); |
LobbyMessageSynchronizer.OnLobbyMessageReceived += OnLobbyMessageReceived; |
|
private List<string> MouseKeyCombo { get; set; } |
// Start mouse key bindings synchronizer. |
MouseKeyBindingsSynchronizer = new MouseKeyBindingsSynchronizer(MouseKeyBindings, MQTTCommunication); |
MouseKeyBindingsSynchronizer.OnMouseKeyBindingsSynchronized += OnMouseKeyBindingsSynchronized; |
} |
|
private HelmBindings HelmBindings { get; set; } |
private void OnMouseKeyBindingsSynchronized(object sender, MouseKeyBindingsSynchronizedEventArgs e) |
{ |
this.Invoke((MethodInvoker) delegate |
{ |
foreach (var binding in e.ExchangeBindings) |
{ |
ActivityTextBox.AppendText( |
$"{Strings.Synchronized_bindings_with_client} : {binding.Nick} : {binding.Names.Count}{Environment.NewLine}"); |
|
private BindingSource HelmBindingSource { get; set; } |
|
public ConcurrentDictionary<string, HelmBindings> WingBindings { get; set; } |
var exchangeBindings = MouseKeyBindingsExchange.ExchangeBindings.FirstOrDefault(exchangeBinding => |
string.Equals(exchangeBinding.Nick, binding.Nick, StringComparison.Ordinal)); |
|
public WingManForm() |
{ |
InitializeComponent(); |
// If the nick has not been registered add it. |
if (exchangeBindings == null) |
{ |
MouseKeyBindingsExchange.ExchangeBindings.Add(binding); |
continue; |
} |
|
MouseKeyGlobalHook = Hook.GlobalEvents(); |
// If the nick has been added, then update the binding names. |
exchangeBindings.Names = binding.Names; |
|
MQTTClient = new MQTTClient(this); |
MQTTServer = new MQTTServer(this); |
// Update wing list box. |
var selectedExchangeBinding = (MouseKeyBindingExchange)WingBindingsComboBox.SelectedItem; |
if (selectedExchangeBinding == null || !string.Equals(selectedExchangeBinding.Nick, binding.Nick)) |
continue; |
|
HelmBindings = new HelmBindings(); |
HelmBindings.Bindings = new List<HelmBinding>(); |
WingBindingsListBox.Items.Clear(); |
WingBindingsListBox.DisplayMember = "Name"; |
WingBindingsListBox.ValueMember = "Name"; |
WingBindingsListBox.Items.AddRange(exchangeBindings.Names.Select(name => (object)name).ToArray()); |
|
HelmBindingSource = new BindingSource(); |
HelmBindingSource.DataSource = HelmBindings.Bindings; |
} |
|
HelmBindingsListBox.DisplayMember = "DisplayName"; |
HelmBindingsListBox.ValueMember = "Keys"; |
HelmBindingsListBox.DataSource = HelmBindingSource; |
WingBindingSource.ResetBindings(false); |
|
WingBindings = new ConcurrentDictionary<string, HelmBindings>(); |
}); |
} |
|
private static IKeyboardMouseEvents MouseKeyApplicationHook { get; set; } |
|
private List<string> MouseKeyCombo { get; set; } |
|
private MouseKeyBindings MouseKeyBindings { get; } |
|
private BindingSource HelmBindingSource { get; } |
|
private BindingSource WingBindingSource { get; set; } |
|
private MouseKeyBindingsExchange MouseKeyBindingsExchange { get; set; } |
|
public MQTTCommunication MQTTCommunication { get; set; } |
|
public LobbyMessageSynchronizer LobbyMessageSynchronizer { get; set; } |
|
public MouseKeyBindingsSynchronizer MouseKeyBindingsSynchronizer { get; set; } |
|
private void OnLobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e) |
{ |
LobbyTextBox.Invoke((MethodInvoker) delegate |
{ |
LobbyTextBox.AppendText($"{e.Nick} : {e.Message}{Environment.NewLine}"); |
}); |
} |
|
private void AddressTextBoxClick(object sender, EventArgs e) |
{ |
Address.BackColor = Color.Empty; |
@@ -75,15 +126,18 @@ |
private async void HostButtonClickAsync(object sender, EventArgs e) |
{ |
// Stop the MQTT server if it is running. |
if (MQTTServer.ServerRunning) |
if (MQTTCommunication.Running) |
{ |
await StopServer(); |
toolStripStatusLabel.Text = Properties.Strings.Server_stopped; |
await MQTTCommunication.Stop().ConfigureAwait(false); |
toolStripStatusLabel.Text = Strings.Server_stopped; |
HostButton.BackColor = Color.Empty; |
|
// Enable controls. |
ConnectButton.Enabled = true; |
EnableConnectionControls(); |
Address.Enabled = true; |
Port.Enabled = true; |
Nick.Enabled = true; |
|
return; |
} |
|
@@ -91,29 +145,17 @@ |
return; |
|
// Start the MQTT server. |
await StartServer(ipAddress, port, nick); |
toolStripStatusLabel.Text = Properties.Strings.Server_started; |
await MQTTCommunication.Start(MQTTCommunicationType.Server, ipAddress, port, nick).ConfigureAwait(false); |
toolStripStatusLabel.Text = Strings.Server_started; |
HostButton.BackColor = Color.Aquamarine; |
|
// Disable controls |
ConnectButton.Enabled = false; |
DisableConnectionControls(); |
} |
|
private void DisableConnectionControls() |
{ |
Address.Enabled = false; |
Port.Enabled = false; |
Nick.Enabled = false; |
} |
|
private void EnableConnectionControls() |
{ |
Address.Enabled = true; |
Port.Enabled = true; |
Nick.Enabled = true; |
} |
|
private bool ValidateAddressPort(out IPAddress address, out int port, out string nick) |
{ |
address = IPAddress.Any; |
@@ -159,41 +201,17 @@ |
return true; |
} |
|
private async Task StartServer(IPAddress ipAddress, int port, string nick) |
{ |
await MQTTServerSemaphore.WaitAsync(); |
try |
{ |
await MQTTServer.Start(ipAddress, port, nick); |
} |
finally |
{ |
MQTTServerSemaphore.Release(); |
} |
} |
|
private async Task StopServer() |
{ |
await MQTTServerSemaphore.WaitAsync(); |
try |
{ |
await MQTTServer.Stop(); |
} |
finally |
{ |
MQTTServerSemaphore.Release(); |
} |
} |
|
private async void ConnectButtonClickAsync(object sender, EventArgs e) |
{ |
if (MQTTClient.ClientRunning) |
if (MQTTCommunication.Running) |
{ |
await StopClient(); |
ConnectButton.Text = Properties.Strings.Connect; |
await MQTTCommunication.Stop().ConfigureAwait(false); |
ConnectButton.Text = Strings.Connect; |
ConnectButton.BackColor = Color.Empty; |
|
EnableConnectionControls(); |
Address.Enabled = true; |
Port.Enabled = true; |
Nick.Enabled = true; |
HostButton.Enabled = true; |
return; |
} |
@@ -201,57 +219,26 @@ |
if (!ValidateAddressPort(out var ipAddress, out var port, out var nick)) |
return; |
|
await StartClient(ipAddress, port, nick); |
await MQTTCommunication.Start(MQTTCommunicationType.Client, ipAddress, port, nick).ConfigureAwait(false); |
|
toolStripStatusLabel.Text = Properties.Strings.Client_started; |
ConnectButton.Text = Properties.Strings.Disconnect; |
toolStripStatusLabel.Text = Strings.Client_started; |
ConnectButton.Text = Strings.Disconnect; |
ConnectButton.BackColor = Color.Aquamarine; |
|
HostButton.Enabled = false; |
DisableConnectionControls(); |
Address.Enabled = false; |
Port.Enabled = false; |
Nick.Enabled = false; |
} |
|
private async Task StopClient() |
{ |
await MQTTClientSemaphore.WaitAsync(); |
try |
{ |
await MQTTClient.Stop(); |
} |
finally |
{ |
MQTTClientSemaphore.Release(); |
} |
} |
|
private async Task StartClient(IPAddress ipAddress, int port, string nick) |
{ |
await MQTTClientSemaphore.WaitAsync(); |
try |
{ |
await MQTTClient.Start(ipAddress, port, nick); |
} |
finally |
{ |
MQTTClientSemaphore.Release(); |
} |
} |
|
private async void LobbySayTextBoxKeyDown(object sender, KeyEventArgs e) |
{ |
if (e.KeyCode != Keys.Enter) |
return; |
|
if (MQTTServer.ServerRunning) |
{ |
await MQTTServer.BroadcastLobbyMessage(LobbySayTextBox.Text); |
} |
await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text).ConfigureAwait(false); |
|
if (MQTTClient.ClientRunning) |
{ |
await MQTTClient.BroadcastLobbyMessage(LobbySayTextBox.Text); |
} |
|
LobbySayTextBox.Text = string.Empty; |
} |
|
private void HelmAddButtonClick(object sender, EventArgs e) |
@@ -271,21 +258,18 @@ |
MouseKeyApplicationHook.KeyUp += MouseKeyHookOnKeyUp; |
MouseKeyApplicationHook.KeyDown += MouseKeyHookOnKeyDown; |
MouseKeyApplicationHook.MouseUp += MouseKeyHookOnMouseUp; |
|
} |
|
private void MouseKeyHookOnKeyUp(object sender, KeyEventArgs e) |
{ |
HelmBindings.Bindings.Add(new HelmBinding |
{ |
Keys = MouseKeyCombo, |
Name = HelmNameTextBox.Text |
}); |
MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo)); |
|
HelmBindingSource.ResetBindings(false); |
|
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown; |
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp; |
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown; |
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp; |
|
MouseKeyApplicationHook.Dispose(); |
|
@@ -295,16 +279,14 @@ |
|
private void MouseKeyHookOnMouseUp(object sender, MouseEventArgs e) |
{ |
HelmBindings.Bindings.Add(new HelmBinding |
{ |
Keys = MouseKeyCombo, |
Name = HelmNameTextBox.Text |
}); |
MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo)); |
|
HelmBindingSource.ResetBindings(false); |
|
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown; |
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp; |
MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown; |
MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp; |
|
MouseKeyApplicationHook.Dispose(); |
|
@@ -315,7 +297,7 @@ |
|
private void MouseKeyHookOnMouseDown(object sender, MouseEventArgs e) |
{ |
MouseKeyCombo.Add(MouseButtonToName(e.Button)); |
MouseKeyCombo.Add(e.Button.ToDisplayName()); |
} |
|
private void MouseKeyHookOnKeyDown(object sender, KeyEventArgs e) |
@@ -322,7 +304,7 @@ |
{ |
e.SuppressKeyPress = true; |
|
MouseKeyCombo.Add(KeyCodeToName((int) e.KeyCode)); |
MouseKeyCombo.Add(e.KeyCode.ToDisplayName()); |
} |
|
private void HelmNameTextBoxClick(object sender, EventArgs e) |
@@ -330,431 +312,33 @@ |
HelmNameTextBox.BackColor = Color.Empty; |
} |
|
private string MouseButtonToName(MouseButtons button) |
private void HelmRemoveButtonClick(object sender, EventArgs e) |
{ |
var mouseButton = string.Empty; |
switch (button) |
{ |
case MouseButtons.Left: |
mouseButton = "Left Mouse Button"; |
break; |
case MouseButtons.Middle: |
mouseButton = "Middle Mouse Button"; |
break; |
case MouseButtons.Right: |
mouseButton = "Right Mouse Button"; |
break; |
} |
var helmBinding = (MouseKeyBinding) HelmBindingsListBox.SelectedItem; |
if (helmBinding == null) |
return; |
|
return mouseButton; |
MouseKeyBindings.Bindings.Remove(helmBinding); |
HelmBindingSource.ResetBindings(false); |
} |
|
private string KeyCodeToName(int code) |
private async void LobbySayButtonClick(object sender, EventArgs e) |
{ |
var keyString = string.Empty; |
switch (code) |
{ |
case 0: |
break; |
case 1: |
keyString = "Mouse Left"; |
break; |
case 2: |
keyString = "Mouse Right"; |
break; |
case 3: |
keyString = "Cancel"; |
break; |
case 4: |
keyString = "Mouse Middle"; |
break; |
case 5: |
keyString = "Special 1"; |
break; |
case 6: |
keyString = "Special 2"; |
break; |
case 8: |
keyString = "Back"; |
break; |
case 9: |
keyString = "TAB"; |
break; |
case 12: |
keyString = "Clear"; |
break; |
case 13: |
keyString = "Enter"; |
break; |
case 16: |
keyString = "Shift"; |
break; |
case 17: |
keyString = "Ctrl"; |
break; |
case 18: |
keyString = "Menu"; |
break; |
case 19: |
keyString = "Pause"; |
break; |
case 20: |
keyString = "Caps Lock"; |
break; |
case 21: |
keyString = "Kana/Hangul"; |
break; |
case 23: |
keyString = "Junja"; |
break; |
case 24: |
keyString = "Final"; |
break; |
case 25: |
keyString = "Hanja/Kanji"; |
break; |
case 27: |
keyString = "Esc"; |
break; |
case 28: |
keyString = "Convert"; |
break; |
case 29: |
keyString = "NonConvert"; |
break; |
case 30: |
keyString = "Accept"; |
break; |
case 31: |
keyString = "Mode"; |
break; |
case 32: |
keyString = "Space"; |
break; |
case 33: |
keyString = "Page Up"; |
break; |
case 34: |
keyString = "Page Down"; |
break; |
case 35: |
keyString = "End"; |
break; |
case 36: |
keyString = "Home"; |
break; |
case 37: |
keyString = "Left"; |
break; |
case 38: |
keyString = "Up"; |
break; |
case 39: |
keyString = "Right"; |
break; |
case 40: |
keyString = "Down"; |
break; |
case 41: |
keyString = "Select"; |
break; |
case 42: |
keyString = "Print"; |
break; |
case 43: |
keyString = "Execute"; |
break; |
case 44: |
keyString = "Snapshot"; |
break; |
case 45: |
keyString = "Insert"; |
break; |
case 46: |
keyString = "Delete"; |
break; |
case 47: |
keyString = "Help"; |
break; |
case 48: |
keyString = "Num 0"; |
break; |
case 49: |
keyString = "Num 1"; |
break; |
case 50: |
keyString = "Num 2"; |
break; |
case 51: |
keyString = "Num 3"; |
break; |
case 52: |
keyString = "Num 4"; |
break; |
case 53: |
keyString = "Num 5"; |
break; |
case 54: |
keyString = "Num 6"; |
break; |
case 55: |
keyString = "Num 7"; |
break; |
case 56: |
keyString = "Num 8"; |
break; |
case 57: |
keyString = "Num 9"; |
break; |
case 65: |
keyString = "A"; |
break; |
case 66: |
keyString = "B"; |
break; |
case 67: |
keyString = "C"; |
break; |
case 68: |
keyString = "D"; |
break; |
case 69: |
keyString = "E"; |
break; |
case 70: |
keyString = "F"; |
break; |
case 71: |
keyString = "G"; |
break; |
case 72: |
keyString = "H"; |
break; |
case 73: |
keyString = "I"; |
break; |
case 74: |
keyString = "J"; |
break; |
case 75: |
keyString = "K"; |
break; |
case 76: |
keyString = "L"; |
break; |
case 77: |
keyString = "M"; |
break; |
case 78: |
keyString = "N"; |
break; |
case 79: |
keyString = "O"; |
break; |
case 80: |
keyString = "P"; |
break; |
case 81: |
keyString = "Q"; |
break; |
case 82: |
keyString = "R"; |
break; |
case 83: |
keyString = "S"; |
break; |
case 84: |
keyString = "T"; |
break; |
case 85: |
keyString = "U"; |
break; |
case 86: |
keyString = "V"; |
break; |
case 87: |
keyString = "W"; |
break; |
case 88: |
keyString = "X"; |
break; |
case 89: |
keyString = "Y"; |
break; |
case 90: |
keyString = "Z"; |
break; |
case 91: |
keyString = "Windows Left"; |
break; |
case 92: |
keyString = "Windows Right"; |
break; |
case 93: |
keyString = "Application"; |
break; |
case 95: |
keyString = "Sleep"; |
break; |
case 96: |
keyString = "NumPad 0"; |
break; |
case 97: |
keyString = "NumPad 1"; |
break; |
case 98: |
keyString = "NumPad 2"; |
break; |
case 99: |
keyString = "NumPad 3"; |
break; |
case 100: |
keyString = "NumPad 4"; |
break; |
case 101: |
keyString = "NumPad 5"; |
break; |
case 102: |
keyString = "NumPad 6"; |
break; |
case 103: |
keyString = "NumPad 7"; |
break; |
case 104: |
keyString = "NumPad 8"; |
break; |
case 105: |
keyString = "NumPad 9"; |
break; |
case 106: |
keyString = "NumPad *"; |
break; |
case 107: |
keyString = "NumPad +"; |
break; |
case 108: |
keyString = "NumPad ."; |
break; |
case 109: |
keyString = "NumPad -"; |
break; |
case 110: |
keyString = "NumPad ,"; |
break; |
case 111: |
keyString = "NumPad /"; |
break; |
case 112: |
keyString = "F1"; |
break; |
case 113: |
keyString = "F2"; |
break; |
case 114: |
keyString = "F3"; |
break; |
case 115: |
keyString = "F4"; |
break; |
case 116: |
keyString = "F5"; |
break; |
case 117: |
keyString = "F6"; |
break; |
case 118: |
keyString = "F7"; |
break; |
case 119: |
keyString = "F8"; |
break; |
case 120: |
keyString = "F9"; |
break; |
case 121: |
keyString = "F10"; |
break; |
case 122: |
keyString = "F11"; |
break; |
case 123: |
keyString = "F12"; |
break; |
case 124: |
keyString = "F13"; |
break; |
case 125: |
keyString = "F14"; |
break; |
case 126: |
keyString = "F15"; |
break; |
case 127: |
keyString = "F16"; |
break; |
case 128: |
keyString = "F17"; |
break; |
case 129: |
keyString = "F18"; |
break; |
case 130: |
keyString = "F19"; |
break; |
case 131: |
keyString = "F20"; |
break; |
case 132: |
keyString = "F21"; |
break; |
case 133: |
keyString = "F22"; |
break; |
case 134: |
keyString = "F23"; |
break; |
case 135: |
keyString = "F24"; |
break; |
case 144: |
keyString = "Num lock"; |
break; |
case 145: |
keyString = "Scroll"; |
break; |
case 160: |
keyString = "Shift Left"; |
break; |
case 161: |
keyString = "Shift Right"; |
break; |
case 162: |
keyString = "Ctrl Left"; |
break; |
case 163: |
keyString = "Ctrl Right"; |
break; |
case 164: |
keyString = "Menu Left"; |
break; |
case 165: |
keyString = "Menu Right"; |
break; |
default: |
break; |
} |
await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text).ConfigureAwait(false); |
|
return keyString; |
LobbySayTextBox.Text = string.Empty; |
} |
|
private void HelmRemoveButtonClick(object sender, EventArgs e) |
private void WingBindingsComboBoxIndexChanged(object sender, EventArgs e) |
{ |
var helmBinding = (HelmBinding)HelmBindingsListBox.SelectedItem; |
if (helmBinding == null) |
var exchangeBinding = (MouseKeyBindingExchange) WingBindingsComboBox.SelectedItem; |
if (exchangeBinding == null) |
return; |
|
HelmBindings.Bindings.Remove(helmBinding); |
HelmBindingSource.ResetBindings(false); |
WingBindingsListBox.Items.Clear(); |
WingBindingsListBox.DisplayMember = "Name"; |
WingBindingsListBox.ValueMember = "Name"; |
WingBindingsListBox.Items.AddRange(exchangeBinding.Names.Select(name => (object)name).ToArray()); |
} |
} |
} |