WingMan – Blame information for rev 7

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Collections.Generic;
3 using System.Drawing;
4 using System.Linq;
5 using System.Net;
7 office 6 using System.Threading;
6 office 7 using System.Threading.Tasks;
1 office 8 using System.Windows.Forms;
4 office 9 using Gma.System.MouseKeyHook;
1 office 10 using WingMan.Communication;
7 office 11 using WingMan.Lobby;
5 office 12 using WingMan.MouseKey;
13 using WingMan.Properties;
1 office 14  
15 namespace WingMan
16 {
2 office 17 public partial class WingManForm : Form
1 office 18 {
5 office 19 public WingManForm()
20 {
21 InitializeComponent();
1 office 22  
6 office 23 FormTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
7 office 24 FormCancellationTokenSource = new CancellationTokenSource();
1 office 25  
7 office 26 MQTTCommunication = new MQTTCommunication(FormTaskScheduler, FormCancellationTokenSource.Token);
6 office 27  
5 office 28 MouseKeyBindings = new MouseKeyBindings(new List<MouseKeyBinding>());
1 office 29  
7 office 30 HelmListBoxBindingSource = new BindingSource
5 office 31 {
32 DataSource = MouseKeyBindings.Bindings
33 };
34 HelmBindingsListBox.DisplayMember = "DisplayName";
35 HelmBindingsListBox.ValueMember = "Keys";
7 office 36 HelmBindingsListBox.DataSource = HelmListBoxBindingSource;
1 office 37  
7 office 38 MouseKeyBindingsExchange = new MouseKeyBindingsExchange
5 office 39 {
7 office 40 ExchangeBindings = new List<MouseKeyBindingExchange>()
41 };
42  
43 WingBindingsComboBoxSource = new BindingSource
44 {
5 office 45 DataSource = MouseKeyBindingsExchange.ExchangeBindings
46 };
47 WingBindingsComboBox.DisplayMember = "Nick";
7 office 48 WingBindingsComboBox.ValueMember = "MouseKeyBindings";
49 WingBindingsComboBox.DataSource = WingBindingsComboBoxSource;
4 office 50  
5 office 51 // Start lobby message synchronizer.
7 office 52 LobbyMessageSynchronizer = new LobbyMessageSynchronizer(MQTTCommunication, FormTaskScheduler,
53 FormCancellationTokenSource.Token);
5 office 54 LobbyMessageSynchronizer.OnLobbyMessageReceived += OnLobbyMessageReceived;
4 office 55  
5 office 56 // Start mouse key bindings synchronizer.
7 office 57 MouseKeyBindingsSynchronizer = new MouseKeyBindingsSynchronizer(MouseKeyBindings, MQTTCommunication,
58 FormTaskScheduler, FormCancellationTokenSource.Token);
5 office 59 MouseKeyBindingsSynchronizer.OnMouseKeyBindingsSynchronized += OnMouseKeyBindingsSynchronized;
60 }
4 office 61  
7 office 62 private static CancellationTokenSource FormCancellationTokenSource { get; set; }
4 office 63  
7 office 64 private static TaskScheduler FormTaskScheduler { get; set; }
4 office 65  
7 office 66 private static IKeyboardMouseEvents MouseKeyApplicationHook { get; set; }
4 office 67  
7 office 68 private List<string> MouseKeyCombo { get; set; }
2 office 69  
7 office 70 private MouseKeyBindings MouseKeyBindings { get; }
4 office 71  
7 office 72 private BindingSource HelmListBoxBindingSource { get; }
4 office 73  
7 office 74 private BindingSource WingBindingsComboBoxSource { get; }
4 office 75  
7 office 76 private MouseKeyBindingsExchange MouseKeyBindingsExchange { get; }
77  
78 public MQTTCommunication MQTTCommunication { get; set; }
79  
80 public LobbyMessageSynchronizer LobbyMessageSynchronizer { get; set; }
81  
82 public MouseKeyBindingsSynchronizer MouseKeyBindingsSynchronizer { get; set; }
83  
84 /// <summary>
85 /// Clean up any resources being used.
86 /// </summary>
87 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
88 protected override void Dispose(bool disposing)
89 {
90 if (disposing && components != null)
91 {
92 FormCancellationTokenSource.Dispose();
93 FormCancellationTokenSource = null;
94  
95 components.Dispose();
6 office 96 }
4 office 97  
7 office 98 base.Dispose(disposing);
1 office 99 }
100  
7 office 101 private void OnMouseKeyBindingsSynchronized(object sender, MouseKeyBindingsSynchronizedEventArgs e)
102 {
103 ActivityTextBox.AppendText(
104 $"{Strings.Synchronized_bindings_with_client} : {e.Bindings.Nick} : {e.Bindings.MouseKeyBindings.Count}{Environment.NewLine}");
6 office 105  
7 office 106 var exchangeBindings = MouseKeyBindingsExchange.ExchangeBindings.FirstOrDefault(exchangeBinding =>
107 string.Equals(exchangeBinding.Nick, e.Bindings.Nick, StringComparison.Ordinal));
5 office 108  
7 office 109 // If the nick does not exist then add it.
110 if (exchangeBindings == null)
111 {
112 MouseKeyBindingsExchange.ExchangeBindings.Add(e.Bindings);
113 WingBindingsComboBoxSource.ResetBindings(false);
114 UpdateWingListBoxItems();
115 return;
116 }
5 office 117  
7 office 118 // If the bindings for the nick have not changed then do not update.
119 if (exchangeBindings.MouseKeyBindings.SequenceEqual(e.Bindings.MouseKeyBindings))
120 {
121 WingBindingsComboBoxSource.ResetBindings(false);
122 UpdateWingListBoxItems();
123 return;
124 }
5 office 125  
7 office 126 // Update the bindings.
127 exchangeBindings.MouseKeyBindings = e.Bindings.MouseKeyBindings;
128 WingBindingsComboBoxSource.ResetBindings(false);
129 UpdateWingListBoxItems();
130 }
5 office 131  
7 office 132 private void UpdateWingListBoxItems()
133 {
134 var exchangeBinding = (List<MouseKeyBinding>) WingBindingsComboBox.SelectedValue;
135 if (exchangeBinding == null)
136 return;
5 office 137  
7 office 138 WingBindingsListBox.Items.Clear();
139 WingBindingsListBox.DisplayMember = "Name";
140 WingBindingsListBox.ValueMember = "Name";
141 var i = exchangeBinding.Select(binding => (object) binding.Name).ToArray();
142 if (i.Length == 0)
143 return;
5 office 144  
7 office 145 WingBindingsListBox.Items.AddRange(i);
146 }
5 office 147  
148 private void OnLobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e)
149 {
150 LobbyTextBox.Invoke((MethodInvoker) delegate
151 {
152 LobbyTextBox.AppendText($"{e.Nick} : {e.Message}{Environment.NewLine}");
153 });
154 }
155  
1 office 156 private void AddressTextBoxClick(object sender, EventArgs e)
157 {
158 Address.BackColor = Color.Empty;
159 }
160  
161 private void PortTextBoxClick(object sender, EventArgs e)
162 {
163 Port.BackColor = Color.Empty;
164 }
165  
166 private async void HostButtonClickAsync(object sender, EventArgs e)
167 {
168 // Stop the MQTT server if it is running.
5 office 169 if (MQTTCommunication.Running)
1 office 170 {
5 office 171 await MQTTCommunication.Stop().ConfigureAwait(false);
172 toolStripStatusLabel.Text = Strings.Server_stopped;
1 office 173 HostButton.BackColor = Color.Empty;
174  
3 office 175 // Enable controls.
1 office 176 ConnectButton.Enabled = true;
5 office 177 Address.Enabled = true;
178 Port.Enabled = true;
179 Nick.Enabled = true;
180  
1 office 181 return;
182 }
183  
2 office 184 if (!ValidateAddressPort(out var ipAddress, out var port, out var nick))
1 office 185 return;
186  
187 // Start the MQTT server.
5 office 188 await MQTTCommunication.Start(MQTTCommunicationType.Server, ipAddress, port, nick).ConfigureAwait(false);
189 toolStripStatusLabel.Text = Strings.Server_started;
1 office 190 HostButton.BackColor = Color.Aquamarine;
191  
3 office 192 // Disable controls
1 office 193 ConnectButton.Enabled = false;
3 office 194 Address.Enabled = false;
195 Port.Enabled = false;
196 Nick.Enabled = false;
197 }
198  
2 office 199 private bool ValidateAddressPort(out IPAddress address, out int port, out string nick)
1 office 200 {
201 address = IPAddress.Any;
202 port = 0;
2 office 203 nick = string.Empty;
1 office 204  
205 if (string.IsNullOrEmpty(Address.Text) &&
2 office 206 string.IsNullOrEmpty(Port.Text) &&
207 string.IsNullOrEmpty(Nick.Text))
1 office 208 {
209 Address.BackColor = Color.LightPink;
210 Port.BackColor = Color.LightPink;
2 office 211 Nick.BackColor = Color.LightPink;
1 office 212 return false;
213 }
214  
215 if (!IPAddress.TryParse(Address.Text, out address))
216 {
217 Address.BackColor = Color.LightPink;
218 return false;
219 }
220  
221 if (!uint.TryParse(Port.Text, out var uPort))
222 {
223 Port.BackColor = Color.LightPink;
224 return false;
225 }
226  
227 port = (int) uPort;
228  
2 office 229 if (string.IsNullOrEmpty(Nick.Text))
230 {
231 Nick.BackColor = Color.LightPink;
232 return false;
233 }
234  
235 nick = Nick.Text;
236  
1 office 237 Address.BackColor = Color.Empty;
238 Port.BackColor = Color.Empty;
2 office 239 Nick.BackColor = Color.Empty;
1 office 240  
241 return true;
242 }
243  
244 private async void ConnectButtonClickAsync(object sender, EventArgs e)
245 {
5 office 246 if (MQTTCommunication.Running)
1 office 247 {
5 office 248 await MQTTCommunication.Stop().ConfigureAwait(false);
249 ConnectButton.Text = Strings.Connect;
1 office 250 ConnectButton.BackColor = Color.Empty;
251  
5 office 252 Address.Enabled = true;
253 Port.Enabled = true;
254 Nick.Enabled = true;
1 office 255 HostButton.Enabled = true;
256 return;
257 }
258  
2 office 259 if (!ValidateAddressPort(out var ipAddress, out var port, out var nick))
1 office 260 return;
261  
5 office 262 await MQTTCommunication.Start(MQTTCommunicationType.Client, ipAddress, port, nick).ConfigureAwait(false);
1 office 263  
5 office 264 toolStripStatusLabel.Text = Strings.Client_started;
265 ConnectButton.Text = Strings.Disconnect;
1 office 266 ConnectButton.BackColor = Color.Aquamarine;
267  
268 HostButton.Enabled = false;
5 office 269 Address.Enabled = false;
270 Port.Enabled = false;
271 Nick.Enabled = false;
1 office 272 }
273  
2 office 274 private async void LobbySayTextBoxKeyDown(object sender, KeyEventArgs e)
275 {
276 if (e.KeyCode != Keys.Enter)
277 return;
278  
5 office 279 await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text).ConfigureAwait(false);
2 office 280  
5 office 281 LobbySayTextBox.Text = string.Empty;
2 office 282 }
4 office 283  
284 private void HelmAddButtonClick(object sender, EventArgs e)
285 {
286 if (string.IsNullOrEmpty(HelmNameTextBox.Text))
287 {
288 HelmNameTextBox.BackColor = Color.LightPink;
289 return;
290 }
291  
292 HelmAddButton.Enabled = false;
293  
294 MouseKeyCombo = new List<string>();
295  
296 MouseKeyApplicationHook = Hook.AppEvents();
297 MouseKeyApplicationHook.MouseDown += MouseKeyHookOnMouseDown;
298 MouseKeyApplicationHook.KeyUp += MouseKeyHookOnKeyUp;
299 MouseKeyApplicationHook.KeyDown += MouseKeyHookOnKeyDown;
300 MouseKeyApplicationHook.MouseUp += MouseKeyHookOnMouseUp;
301 }
302  
303 private void MouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
304 {
5 office 305 MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo));
4 office 306  
7 office 307 HelmListBoxBindingSource.ResetBindings(false);
4 office 308  
309 MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
310 MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
5 office 311 MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
312 MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
4 office 313  
314 MouseKeyApplicationHook.Dispose();
315  
316 HelmNameTextBox.Text = string.Empty;
317 HelmAddButton.Enabled = true;
318 }
319  
320 private void MouseKeyHookOnMouseUp(object sender, MouseEventArgs e)
321 {
5 office 322 MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo));
4 office 323  
7 office 324 HelmListBoxBindingSource.ResetBindings(false);
4 office 325  
326 MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
327 MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
5 office 328 MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
329 MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
4 office 330  
331 MouseKeyApplicationHook.Dispose();
332  
333 HelmNameTextBox.Text = string.Empty;
334 HelmAddButton.Enabled = true;
335 }
336  
337  
338 private void MouseKeyHookOnMouseDown(object sender, MouseEventArgs e)
339 {
5 office 340 MouseKeyCombo.Add(e.Button.ToDisplayName());
4 office 341 }
342  
343 private void MouseKeyHookOnKeyDown(object sender, KeyEventArgs e)
344 {
345 e.SuppressKeyPress = true;
346  
5 office 347 MouseKeyCombo.Add(e.KeyCode.ToDisplayName());
4 office 348 }
349  
350 private void HelmNameTextBoxClick(object sender, EventArgs e)
351 {
352 HelmNameTextBox.BackColor = Color.Empty;
353 }
354  
5 office 355 private void HelmRemoveButtonClick(object sender, EventArgs e)
4 office 356 {
5 office 357 var helmBinding = (MouseKeyBinding) HelmBindingsListBox.SelectedItem;
358 if (helmBinding == null)
359 return;
4 office 360  
5 office 361 MouseKeyBindings.Bindings.Remove(helmBinding);
7 office 362 HelmListBoxBindingSource.ResetBindings(false);
4 office 363 }
364  
5 office 365 private async void LobbySayButtonClick(object sender, EventArgs e)
4 office 366 {
5 office 367 await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text).ConfigureAwait(false);
4 office 368  
5 office 369 LobbySayTextBox.Text = string.Empty;
4 office 370 }
371  
6 office 372 private void WingBindingsComboBoxSelectionChangeCompleted(object sender, EventArgs e)
4 office 373 {
7 office 374 UpdateWingListBoxItems();
4 office 375 }
1 office 376 }
377 }