WingMan

Subversion Repositories:
Compare Path: Rev
With Path: Rev
?path1? @ 2  →  ?path2? @ 1
File deleted
/trunk/WingMan/WingManForm.Designer.cs
File deleted
/trunk/WingMan/LobbyMessage.cs
File deleted
\ No newline at end of file
/trunk/WingMan/WingManForm.resx
File deleted
/trunk/WingMan/WingManForm.cs
/trunk/WingMan/Communication/MQTTClient.cs
@@ -1,13 +1,9 @@
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;
@@ -16,49 +12,32 @@
{
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()
public async Task Start(IPAddress ipAddress, int port)
{
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())
.WithClientOptions(new MqttClientOptionsBuilder()
.WithTcpServer(ipAddress.ToString(), port)
.WithTls().Build())
.Build();
 
BindHandlers();
 
await Client.SubscribeAsync(
new TopicFilterBuilder()
.WithTopic("lobby")
.WithTopic("exchange")
.Build()
);
 
await Client.SubscribeAsync(
new TopicFilterBuilder()
.WithTopic("exchange")
.Build()
);
 
await Client.StartAsync(options);
 
ClientRunning = true;
@@ -66,52 +45,14 @@
 
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();
@@ -133,8 +74,6 @@
public void BindHandlers()
{
Client.Connected += ClientOnConnected;
Client.Disconnected += ClientOnDisconnected;
Client.ConnectingFailed += ClientOnConnectingFailed;
Client.ApplicationMessageReceived += ClientOnApplicationMessageReceived;
}
 
@@ -141,33 +80,7 @@
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
@@ -1,11 +1,9 @@
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;
 
@@ -13,10 +11,8 @@
{
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()
{
@@ -23,147 +19,22 @@
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)
public async Task Start(IPAddress ipAddress, int port)
{
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/Form1.Designer.cs
@@ -0,0 +1,375 @@
namespace WingMan
{
partial class Form1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
 
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
 
#region Windows Form Designer generated code
 
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.groupBox1 = new System.Windows.Forms.GroupBox();
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.groupBox2 = new System.Windows.Forms.GroupBox();
this.button5 = new System.Windows.Forms.Button();
this.textBox4 = new System.Windows.Forms.TextBox();
this.textBox3 = new System.Windows.Forms.TextBox();
this.groupBox3 = new System.Windows.Forms.GroupBox();
this.button3 = new System.Windows.Forms.Button();
this.button4 = new System.Windows.Forms.Button();
this.label2 = new System.Windows.Forms.Label();
this.textBox2 = new System.Windows.Forms.TextBox();
this.listBox2 = new System.Windows.Forms.ListBox();
this.groupBox4 = new System.Windows.Forms.GroupBox();
this.HostButton = new System.Windows.Forms.Button();
this.label4 = new System.Windows.Forms.Label();
this.ConnectButton = new System.Windows.Forms.Button();
this.Port = new System.Windows.Forms.TextBox();
this.label3 = new System.Windows.Forms.Label();
this.Address = new System.Windows.Forms.TextBox();
this.statusStrip = new System.Windows.Forms.StatusStrip();
this.toolStripStatusLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.groupBox3.SuspendLayout();
this.groupBox4.SuspendLayout();
this.statusStrip.SuspendLayout();
this.SuspendLayout();
//
// groupBox1
//
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.Location = new System.Drawing.Point(8, 128);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(256, 296);
this.groupBox1.TabIndex = 0;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Wing (Them)";
//
// button2
//
this.button2.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.button2.Location = new System.Drawing.Point(168, 264);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(75, 23);
this.button2.TabIndex = 4;
this.button2.Text = "Unbind";
this.button2.UseVisualStyleBackColor = true;
//
// button1
//
this.button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.button1.Location = new System.Drawing.Point(88, 264);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 3;
this.button1.Text = "Bind";
this.button1.UseVisualStyleBackColor = true;
//
// label1
//
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(8, 232);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(54, 13);
this.label1.TabIndex = 2;
this.label1.Text = "Bound To";
//
// textBox1
//
this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.textBox1.Location = new System.Drawing.Point(72, 228);
this.textBox1.Name = "textBox1";
this.textBox1.ReadOnly = true;
this.textBox1.Size = new System.Drawing.Size(172, 20);
this.textBox1.TabIndex = 1;
//
// listBox1
//
this.listBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.listBox1.FormattingEnabled = true;
this.listBox1.Location = new System.Drawing.Point(8, 16);
this.listBox1.Name = "listBox1";
this.listBox1.Size = new System.Drawing.Size(240, 184);
this.listBox1.TabIndex = 0;
//
// groupBox2
//
this.groupBox2.Controls.Add(this.button5);
this.groupBox2.Controls.Add(this.textBox4);
this.groupBox2.Controls.Add(this.textBox3);
this.groupBox2.Location = new System.Drawing.Point(272, 128);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(256, 296);
this.groupBox2.TabIndex = 1;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "Lobby";
//
// button5
//
this.button5.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.button5.Location = new System.Drawing.Point(208, 264);
this.button5.Name = "button5";
this.button5.Size = new System.Drawing.Size(40, 20);
this.button5.TabIndex = 2;
this.button5.UseVisualStyleBackColor = true;
//
// textBox4
//
this.textBox4.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.textBox4.Location = new System.Drawing.Point(8, 264);
this.textBox4.Name = "textBox4";
this.textBox4.Size = new System.Drawing.Size(192, 20);
this.textBox4.TabIndex = 1;
//
// textBox3
//
this.textBox3.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.textBox3.Location = new System.Drawing.Point(8, 16);
this.textBox3.Multiline = true;
this.textBox3.Name = "textBox3";
this.textBox3.ReadOnly = true;
this.textBox3.Size = new System.Drawing.Size(240, 240);
this.textBox3.TabIndex = 0;
//
// groupBox3
//
this.groupBox3.Controls.Add(this.button3);
this.groupBox3.Controls.Add(this.button4);
this.groupBox3.Controls.Add(this.label2);
this.groupBox3.Controls.Add(this.textBox2);
this.groupBox3.Controls.Add(this.listBox2);
this.groupBox3.Location = new System.Drawing.Point(536, 128);
this.groupBox3.Name = "groupBox3";
this.groupBox3.Size = new System.Drawing.Size(256, 296);
this.groupBox3.TabIndex = 2;
this.groupBox3.TabStop = false;
this.groupBox3.Text = "Helm (You)";
//
// button3
//
this.button3.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.button3.Location = new System.Drawing.Point(168, 264);
this.button3.Name = "button3";
this.button3.Size = new System.Drawing.Size(75, 23);
this.button3.TabIndex = 6;
this.button3.Text = "Remove";
this.button3.UseVisualStyleBackColor = true;
//
// button4
//
this.button4.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.button4.Location = new System.Drawing.Point(88, 264);
this.button4.Name = "button4";
this.button4.Size = new System.Drawing.Size(75, 23);
this.button4.TabIndex = 5;
this.button4.Text = "Add";
this.button4.UseVisualStyleBackColor = true;
//
// label2
//
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(24, 232);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(35, 13);
this.label2.TabIndex = 4;
this.label2.Text = "Name";
//
// textBox2
//
this.textBox2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.textBox2.Location = new System.Drawing.Point(72, 228);
this.textBox2.Name = "textBox2";
this.textBox2.Size = new System.Drawing.Size(172, 20);
this.textBox2.TabIndex = 3;
//
// listBox2
//
this.listBox2.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.listBox2.FormattingEnabled = true;
this.listBox2.Location = new System.Drawing.Point(8, 16);
this.listBox2.Name = "listBox2";
this.listBox2.Size = new System.Drawing.Size(240, 184);
this.listBox2.TabIndex = 1;
//
// groupBox4
//
this.groupBox4.Controls.Add(this.HostButton);
this.groupBox4.Controls.Add(this.label4);
this.groupBox4.Controls.Add(this.ConnectButton);
this.groupBox4.Controls.Add(this.Port);
this.groupBox4.Controls.Add(this.label3);
this.groupBox4.Controls.Add(this.Address);
this.groupBox4.Location = new System.Drawing.Point(16, 8);
this.groupBox4.Name = "groupBox4";
this.groupBox4.Size = new System.Drawing.Size(248, 112);
this.groupBox4.TabIndex = 3;
this.groupBox4.TabStop = false;
this.groupBox4.Text = "Connection";
//
// HostButton
//
this.HostButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.HostButton.Location = new System.Drawing.Point(96, 80);
this.HostButton.Name = "HostButton";
this.HostButton.Size = new System.Drawing.Size(75, 23);
this.HostButton.TabIndex = 6;
this.HostButton.Text = "Host";
this.HostButton.UseVisualStyleBackColor = true;
this.HostButton.Click += new System.EventHandler(this.HostButtonClickAsync);
//
// label4
//
this.label4.AutoSize = true;
this.label4.Location = new System.Drawing.Point(24, 52);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(26, 13);
this.label4.TabIndex = 3;
this.label4.Text = "Port";
//
// ConnectButton
//
this.ConnectButton.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.ConnectButton.Location = new System.Drawing.Point(16, 80);
this.ConnectButton.Name = "ConnectButton";
this.ConnectButton.Size = new System.Drawing.Size(75, 23);
this.ConnectButton.TabIndex = 5;
this.ConnectButton.Text = "Connect";
this.ConnectButton.UseVisualStyleBackColor = true;
this.ConnectButton.Click += new System.EventHandler(this.ConnectButtonClickAsync);
//
// Port
//
this.Port.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.Port.Location = new System.Drawing.Point(56, 48);
this.Port.Name = "Port";
this.Port.Size = new System.Drawing.Size(60, 20);
this.Port.TabIndex = 2;
this.Port.Text = "43335";
this.Port.Click += new System.EventHandler(this.PortTextBoxClick);
//
// label3
//
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(8, 24);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(45, 13);
this.label3.TabIndex = 1;
this.label3.Text = "Address";
//
// Address
//
this.Address.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.Address.Location = new System.Drawing.Point(56, 20);
this.Address.Name = "Address";
this.Address.Size = new System.Drawing.Size(180, 20);
this.Address.TabIndex = 0;
this.Address.Text = "0.0.0.0";
this.Address.Click += new System.EventHandler(this.AddressTextBoxClick);
//
// statusStrip
//
this.statusStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripStatusLabel});
this.statusStrip.Location = new System.Drawing.Point(0, 428);
this.statusStrip.Name = "statusStrip";
this.statusStrip.Size = new System.Drawing.Size(800, 22);
this.statusStrip.TabIndex = 4;
this.statusStrip.Text = "statusStrip1";
//
// toolStripStatusLabel
//
this.toolStripStatusLabel.Name = "toolStripStatusLabel";
this.toolStripStatusLabel.Size = new System.Drawing.Size(0, 17);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Controls.Add(this.statusStrip);
this.Controls.Add(this.groupBox4);
this.Controls.Add(this.groupBox3);
this.Controls.Add(this.groupBox2);
this.Controls.Add(this.groupBox1);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.MaximizeBox = false;
this.MaximumSize = new System.Drawing.Size(816, 488);
this.MinimizeBox = false;
this.MinimumSize = new System.Drawing.Size(816, 488);
this.Name = "Form1";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.Text = "Form1";
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.groupBox2.ResumeLayout(false);
this.groupBox2.PerformLayout();
this.groupBox3.ResumeLayout(false);
this.groupBox3.PerformLayout();
this.groupBox4.ResumeLayout(false);
this.groupBox4.PerformLayout();
this.statusStrip.ResumeLayout(false);
this.statusStrip.PerformLayout();
this.ResumeLayout(false);
this.PerformLayout();
 
}
 
#endregion
 
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 listBox2;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.TextBox textBox4;
private System.Windows.Forms.TextBox textBox3;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.Button button3;
private System.Windows.Forms.Button button4;
private System.Windows.Forms.Button button5;
private System.Windows.Forms.GroupBox groupBox4;
private System.Windows.Forms.Button HostButton;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Button ConnectButton;
private System.Windows.Forms.TextBox Port;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.TextBox Address;
private System.Windows.Forms.StatusStrip statusStrip;
private System.Windows.Forms.ToolStripStatusLabel toolStripStatusLabel;
}
}
 
/trunk/WingMan/Form1.cs
@@ -0,0 +1,176 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using WingMan.Communication;
using WingMan.Host;
 
namespace WingMan
{
public partial class Form1 : Form
{
private MQTTServer MQTTServer { get; set; } = new MQTTServer();
 
private MQTTClient MQTTClient { get; set; } = new MQTTClient();
 
private SemaphoreSlim MQTTServerSemaphore {get; set;} = new SemaphoreSlim(1, 1);
 
private SemaphoreSlim MQTTClientSemaphore { get; set; } = new SemaphoreSlim(1, 1);
 
public Form1()
{
InitializeComponent();
}
 
private void AddressTextBoxClick(object sender, EventArgs e)
{
Address.BackColor = Color.Empty;
}
 
private void PortTextBoxClick(object sender, EventArgs e)
{
Port.BackColor = Color.Empty;
}
 
private async void HostButtonClickAsync(object sender, EventArgs e)
{
// Stop the MQTT server if it is running.
if (MQTTServer.ServerRunning)
{
await StopServer();
toolStripStatusLabel.Text = Properties.Strings.Server_stopped;
HostButton.BackColor = Color.Empty;
 
ConnectButton.Enabled = true;
return;
}
 
if (!ValidateAddressPort(out var ipAddress, out var port))
return;
 
// Start the MQTT server.
await StartServer(ipAddress, port);
toolStripStatusLabel.Text = Properties.Strings.Server_started;
HostButton.BackColor = Color.Aquamarine;
 
ConnectButton.Enabled = false;
}
 
private bool ValidateAddressPort(out IPAddress address, out int port)
{
address = IPAddress.Any;
port = 0;
 
if (string.IsNullOrEmpty(Address.Text) &&
string.IsNullOrEmpty(Port.Text))
{
Address.BackColor = Color.LightPink;
Port.BackColor = Color.LightPink;
return false;
}
 
if (!IPAddress.TryParse(Address.Text, out address))
{
Address.BackColor = Color.LightPink;
return false;
}
 
if (!uint.TryParse(Port.Text, out var uPort))
{
Port.BackColor = Color.LightPink;
return false;
}
 
port = (int) uPort;
 
Address.BackColor = Color.Empty;
Port.BackColor = Color.Empty;
 
return true;
}
 
private async Task StartServer(IPAddress ipAddress, int port)
{
await MQTTServerSemaphore.WaitAsync();
try
{
await MQTTServer.Start(ipAddress, port);
}
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)
{
await StopClient();
ConnectButton.Text = Properties.Strings.Connect;
ConnectButton.BackColor = Color.Empty;
 
HostButton.Enabled = true;
return;
}
 
if (!ValidateAddressPort(out var ipAddress, out var port))
return;
 
await StartClient(ipAddress, port);
 
toolStripStatusLabel.Text = Properties.Strings.Client_started;
ConnectButton.Text = Properties.Strings.Disconnect;
ConnectButton.BackColor = Color.Aquamarine;
 
HostButton.Enabled = false;
}
 
private async Task StopClient()
{
await MQTTClientSemaphore.WaitAsync();
try
{
await MQTTClient.Stop();
}
finally
{
MQTTClientSemaphore.Release();
}
}
 
private async Task StartClient(IPAddress ipAddress, int port)
{
await MQTTClientSemaphore.WaitAsync();
try
{
await MQTTClient.Start(ipAddress, port);
}
finally
{
MQTTClientSemaphore.Release();
}
}
}
}
/trunk/WingMan/Form1.resx
@@ -0,0 +1,123 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
 
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="statusStrip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>
/trunk/WingMan/Program.cs
@@ -16,7 +16,7 @@
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new WingManForm());
Application.Run(new Form1());
}
}
}
/trunk/WingMan/Properties/Strings.Designer.cs
@@ -61,33 +61,6 @@
}
/// <summary>
/// Looks up a localized string similar to Client connected.
/// </summary>
internal static string Client_connected {
get {
return ResourceManager.GetString("Client_connected", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Client connection failed.
/// </summary>
internal static string Client_connection_failed {
get {
return ResourceManager.GetString("Client_connection_failed", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Client disconnected.
/// </summary>
internal static string Client_disconnected {
get {
return ResourceManager.GetString("Client_disconnected", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Client started.
/// </summary>
internal static string Client_started {
@@ -97,24 +70,6 @@
}
/// <summary>
/// Looks up a localized string similar to Client subscribed to topic.
/// </summary>
internal static string Client_subscribed_to_topic {
get {
return ResourceManager.GetString("Client_subscribed_to_topic", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Client unsubscribed from topic.
/// </summary>
internal static string Client_unsubscribed_from_topic {
get {
return ResourceManager.GetString("Client_unsubscribed_from_topic", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Connect.
/// </summary>
internal static string Connect {
/trunk/WingMan/Properties/Strings.resx
@@ -117,24 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Client_connected" xml:space="preserve">
<value>Client connected</value>
</data>
<data name="Client_connection_failed" xml:space="preserve">
<value>Client connection failed</value>
</data>
<data name="Client_disconnected" xml:space="preserve">
<value>Client disconnected</value>
</data>
<data name="Client_started" xml:space="preserve">
<value>Client started</value>
</data>
<data name="Client_subscribed_to_topic" xml:space="preserve">
<value>Client subscribed to topic</value>
</data>
<data name="Client_unsubscribed_from_topic" xml:space="preserve">
<value>Client unsubscribed from topic</value>
</data>
<data name="Connect" xml:space="preserve">
<value>Connect</value>
</data>
/trunk/WingMan/WingMan.csproj
@@ -41,9 +41,6 @@
<Reference Include="MQTTnet.Extensions.ManagedClient, Version=2.8.4.0, Culture=neutral, PublicKeyToken=b69712f52770c0a7, processorArchitecture=MSIL">
<HintPath>..\packages\MQTTnet.Extensions.ManagedClient.2.8.4\lib\net452\MQTTnet.Extensions.ManagedClient.dll</HintPath>
</Reference>
<Reference Include="Open.Nat, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f22a6a4582336c76, processorArchitecture=MSIL">
<HintPath>..\packages\Open.NAT.2.1.0.0\lib\net45\Open.Nat.dll</HintPath>
</Reference>
<Reference Include="SimWinKeyboard, Version=1.0.2.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\SimWinKeyboard.1.0.2\lib\net20\SimWinKeyboard.dll</HintPath>
</Reference>
@@ -64,12 +61,11 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Communication\MQTTClient.cs" />
<Compile Include="LobbyMessage.cs" />
<Compile Include="WingManForm.cs">
<Compile Include="Form1.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="WingManForm.Designer.cs">
<DependentUpon>WingManForm.cs</DependentUpon>
<Compile Include="Form1.Designer.cs">
<DependentUpon>Form1.cs</DependentUpon>
</Compile>
<Compile Include="Communication\MQTTServer.cs" />
<Compile Include="Program.cs" />
@@ -79,8 +75,8 @@
<DesignTime>True</DesignTime>
<DependentUpon>Strings.resx</DependentUpon>
</Compile>
<EmbeddedResource Include="WingManForm.resx">
<DependentUpon>WingManForm.cs</DependentUpon>
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
/trunk/WingMan/packages.config
@@ -3,7 +3,6 @@
<package id="MonoGame.EasyInput" version="1.0.0" targetFramework="net452" />
<package id="MQTTnet" version="2.8.4" targetFramework="net452" />
<package id="MQTTnet.Extensions.ManagedClient" version="2.8.4" targetFramework="net452" />
<package id="Open.NAT" version="2.1.0.0" targetFramework="net452" />
<package id="SimWinKeyboard" version="1.0.2" targetFramework="net452" />
<package id="SimWinMouse" version="1.0.2" targetFramework="net452" />
</packages>