/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/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); |
} |
} |
} |