WingMan – Diff between revs 4 and 5

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 4 Rev 5
1 using System; 1 using System;
2 using System.Collections.Concurrent; -  
3 using System.Collections.Generic; 2 using System.Collections.Generic;
4 using System.ComponentModel; -  
5 using System.Data; -  
6 using System.Drawing; 3 using System.Drawing;
7 using System.Globalization; -  
8 using System.Linq; 4 using System.Linq;
9 using System.Net; 5 using System.Net;
10 using System.Resources; -  
11 using System.Text; -  
12 using System.Threading; -  
13 using System.Threading.Tasks; -  
14 using System.Windows.Forms; 6 using System.Windows.Forms;
15 using Gma.System.MouseKeyHook; 7 using Gma.System.MouseKeyHook;
16 using WingMan.Communication; 8 using WingMan.Communication;
17 using WingMan.Host; 9 using WingMan.MouseKey;
-   10 using WingMan.Properties;
18   11  
19 namespace WingMan 12 namespace WingMan
20 { 13 {
21 public partial class WingManForm : Form 14 public partial class WingManForm : Form
22 { 15 {
-   16 public WingManForm()
-   17 {
23 private MQTTServer MQTTServer { get; set; } 18 InitializeComponent();
24   19  
25 private MQTTClient MQTTClient { get; set; } 20 MQTTCommunication = new MQTTCommunication();
-   21  
-   22 MouseKeyBindings = new MouseKeyBindings(new List<MouseKeyBinding>());
-   23  
-   24 HelmBindingSource = new BindingSource
-   25 {
-   26 DataSource = MouseKeyBindings.Bindings
26   27 };
27 private SemaphoreSlim MQTTServerSemaphore {get; set;} = new SemaphoreSlim(1, 1); 28 HelmBindingsListBox.DisplayMember = "DisplayName";
-   29 HelmBindingsListBox.ValueMember = "Keys";
-   30 HelmBindingsListBox.DataSource = HelmBindingSource;
-   31  
-   32 MouseKeyBindingsExchange = new MouseKeyBindingsExchange();
-   33 WingBindingSource = new BindingSource
-   34 {
-   35 DataSource = MouseKeyBindingsExchange.ExchangeBindings
-   36 };
-   37 WingBindingsComboBox.DisplayMember = "Nick";
28   38 WingBindingsComboBox.ValueMember = "Names";
29 private SemaphoreSlim MQTTClientSemaphore { get; set; } = new SemaphoreSlim(1, 1); 39 WingBindingsComboBox.DataSource = WingBindingSource;
-   40  
-   41 // Start lobby message synchronizer.
-   42 LobbyMessageSynchronizer = new LobbyMessageSynchronizer(MQTTCommunication);
-   43 LobbyMessageSynchronizer.OnLobbyMessageReceived += OnLobbyMessageReceived;
-   44  
-   45 // Start mouse key bindings synchronizer.
-   46 MouseKeyBindingsSynchronizer = new MouseKeyBindingsSynchronizer(MouseKeyBindings, MQTTCommunication);
30   47 MouseKeyBindingsSynchronizer.OnMouseKeyBindingsSynchronized += OnMouseKeyBindingsSynchronized;
-   48 }
-   49  
-   50 private void OnMouseKeyBindingsSynchronized(object sender, MouseKeyBindingsSynchronizedEventArgs e)
31 private static IKeyboardMouseEvents MouseKeyApplicationHook { get; set; } -  
-   51 {
32   52 this.Invoke((MethodInvoker) delegate
-   53 {
33 private static IKeyboardMouseEvents MouseKeyGlobalHook { get; set; } 54 foreach (var binding in e.ExchangeBindings)
34   55 {
-   56 ActivityTextBox.AppendText(
35 private List<string> MouseKeyCombo { get; set; } 57 $"{Strings.Synchronized_bindings_with_client} : {binding.Nick} : {binding.Names.Count}{Environment.NewLine}");
-   58  
-   59  
36   60 var exchangeBindings = MouseKeyBindingsExchange.ExchangeBindings.FirstOrDefault(exchangeBinding =>
37 private HelmBindings HelmBindings { get; set; } 61 string.Equals(exchangeBinding.Nick, binding.Nick, StringComparison.Ordinal));
-   62  
-   63 // If the nick has not been registered add it.
38   64 if (exchangeBindings == null)
39 private BindingSource HelmBindingSource { get; set; } 65 {
40   66 MouseKeyBindingsExchange.ExchangeBindings.Add(binding);
-   67 continue;
-   68 }
41 public ConcurrentDictionary<string, HelmBindings> WingBindings { get; set; } 69  
42   -  
43 public WingManForm() 70 // If the nick has been added, then update the binding names.
-   71 exchangeBindings.Names = binding.Names;
-   72  
-   73 // Update wing list box.
-   74 var selectedExchangeBinding = (MouseKeyBindingExchange)WingBindingsComboBox.SelectedItem;
-   75 if (selectedExchangeBinding == null || !string.Equals(selectedExchangeBinding.Nick, binding.Nick))
-   76 continue;
-   77  
-   78 WingBindingsListBox.Items.Clear();
44 { 79 WingBindingsListBox.DisplayMember = "Name";
-   80 WingBindingsListBox.ValueMember = "Name";
45 InitializeComponent(); 81 WingBindingsListBox.Items.AddRange(exchangeBindings.Names.Select(name => (object)name).ToArray());
-   82  
-   83 }
-   84  
-   85 WingBindingSource.ResetBindings(false);
-   86  
-   87 });
-   88 }
-   89  
46   90 private static IKeyboardMouseEvents MouseKeyApplicationHook { get; set; }
-   91  
-   92 private List<string> MouseKeyCombo { get; set; }
-   93  
-   94 private MouseKeyBindings MouseKeyBindings { get; }
-   95  
-   96 private BindingSource HelmBindingSource { get; }
-   97  
47 MouseKeyGlobalHook = Hook.GlobalEvents(); 98 private BindingSource WingBindingSource { get; set; }
48   99  
49 MQTTClient = new MQTTClient(this); 100 private MouseKeyBindingsExchange MouseKeyBindingsExchange { get; set; }
50 MQTTServer = new MQTTServer(this); 101  
51   102 public MQTTCommunication MQTTCommunication { get; set; }
52 HelmBindings = new HelmBindings(); 103  
53 HelmBindings.Bindings = new List<HelmBinding>(); 104 public LobbyMessageSynchronizer LobbyMessageSynchronizer { get; set; }
54   105  
55 HelmBindingSource = new BindingSource(); 106 public MouseKeyBindingsSynchronizer MouseKeyBindingsSynchronizer { get; set; }
56 HelmBindingSource.DataSource = HelmBindings.Bindings; 107  
57   108 private void OnLobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e)
58 HelmBindingsListBox.DisplayMember = "DisplayName"; 109 {
59 HelmBindingsListBox.ValueMember = "Keys"; 110 LobbyTextBox.Invoke((MethodInvoker) delegate
60 HelmBindingsListBox.DataSource = HelmBindingSource; 111 {
61   112 LobbyTextBox.AppendText($"{e.Nick} : {e.Message}{Environment.NewLine}");
62 WingBindings = new ConcurrentDictionary<string, HelmBindings>(); 113 });
63 } 114 }
64   115  
65 private void AddressTextBoxClick(object sender, EventArgs e) 116 private void AddressTextBoxClick(object sender, EventArgs e)
66 { 117 {
67 Address.BackColor = Color.Empty; 118 Address.BackColor = Color.Empty;
68 } 119 }
69   120  
70 private void PortTextBoxClick(object sender, EventArgs e) 121 private void PortTextBoxClick(object sender, EventArgs e)
71 { 122 {
72 Port.BackColor = Color.Empty; 123 Port.BackColor = Color.Empty;
73 } 124 }
74   125  
75 private async void HostButtonClickAsync(object sender, EventArgs e) 126 private async void HostButtonClickAsync(object sender, EventArgs e)
76 { 127 {
77 // Stop the MQTT server if it is running. 128 // Stop the MQTT server if it is running.
78 if (MQTTServer.ServerRunning) 129 if (MQTTCommunication.Running)
79 { 130 {
80 await StopServer(); 131 await MQTTCommunication.Stop().ConfigureAwait(false);
81 toolStripStatusLabel.Text = Properties.Strings.Server_stopped; 132 toolStripStatusLabel.Text = Strings.Server_stopped;
82 HostButton.BackColor = Color.Empty; 133 HostButton.BackColor = Color.Empty;
83   134  
84 // Enable controls. 135 // Enable controls.
85 ConnectButton.Enabled = true; 136 ConnectButton.Enabled = true;
86 EnableConnectionControls(); 137 Address.Enabled = true;
-   138 Port.Enabled = true;
-   139 Nick.Enabled = true;
-   140  
87 return; 141 return;
88 } 142 }
89   143  
90 if (!ValidateAddressPort(out var ipAddress, out var port, out var nick)) 144 if (!ValidateAddressPort(out var ipAddress, out var port, out var nick))
91 return; 145 return;
92   146  
93 // Start the MQTT server. 147 // Start the MQTT server.
94 await StartServer(ipAddress, port, nick); 148 await MQTTCommunication.Start(MQTTCommunicationType.Server, ipAddress, port, nick).ConfigureAwait(false);
95 toolStripStatusLabel.Text = Properties.Strings.Server_started; 149 toolStripStatusLabel.Text = Strings.Server_started;
96 HostButton.BackColor = Color.Aquamarine; 150 HostButton.BackColor = Color.Aquamarine;
97   151  
98 // Disable controls 152 // Disable controls
99 ConnectButton.Enabled = false; 153 ConnectButton.Enabled = false;
100 DisableConnectionControls(); -  
101 } -  
102   -  
103 private void DisableConnectionControls() -  
104 { -  
105 Address.Enabled = false; 154 Address.Enabled = false;
106 Port.Enabled = false; 155 Port.Enabled = false;
107 Nick.Enabled = false; 156 Nick.Enabled = false;
108 } 157 }
109   -  
110 private void EnableConnectionControls() -  
111 { -  
112 Address.Enabled = true; -  
113 Port.Enabled = true; -  
114 Nick.Enabled = true; -  
115 } -  
116   158  
117 private bool ValidateAddressPort(out IPAddress address, out int port, out string nick) 159 private bool ValidateAddressPort(out IPAddress address, out int port, out string nick)
118 { 160 {
119 address = IPAddress.Any; 161 address = IPAddress.Any;
120 port = 0; 162 port = 0;
121 nick = string.Empty; 163 nick = string.Empty;
122   164  
123 if (string.IsNullOrEmpty(Address.Text) && 165 if (string.IsNullOrEmpty(Address.Text) &&
124 string.IsNullOrEmpty(Port.Text) && 166 string.IsNullOrEmpty(Port.Text) &&
125 string.IsNullOrEmpty(Nick.Text)) 167 string.IsNullOrEmpty(Nick.Text))
126 { 168 {
127 Address.BackColor = Color.LightPink; 169 Address.BackColor = Color.LightPink;
128 Port.BackColor = Color.LightPink; 170 Port.BackColor = Color.LightPink;
129 Nick.BackColor = Color.LightPink; 171 Nick.BackColor = Color.LightPink;
130 return false; 172 return false;
131 } 173 }
132   174  
133 if (!IPAddress.TryParse(Address.Text, out address)) 175 if (!IPAddress.TryParse(Address.Text, out address))
134 { 176 {
135 Address.BackColor = Color.LightPink; 177 Address.BackColor = Color.LightPink;
136 return false; 178 return false;
137 } 179 }
138   180  
139 if (!uint.TryParse(Port.Text, out var uPort)) 181 if (!uint.TryParse(Port.Text, out var uPort))
140 { 182 {
141 Port.BackColor = Color.LightPink; 183 Port.BackColor = Color.LightPink;
142 return false; 184 return false;
143 } 185 }
144   186  
145 port = (int) uPort; 187 port = (int) uPort;
146   188  
147 if (string.IsNullOrEmpty(Nick.Text)) 189 if (string.IsNullOrEmpty(Nick.Text))
148 { 190 {
149 Nick.BackColor = Color.LightPink; 191 Nick.BackColor = Color.LightPink;
150 return false; 192 return false;
151 } 193 }
152   194  
153 nick = Nick.Text; 195 nick = Nick.Text;
154   196  
155 Address.BackColor = Color.Empty; 197 Address.BackColor = Color.Empty;
156 Port.BackColor = Color.Empty; 198 Port.BackColor = Color.Empty;
157 Nick.BackColor = Color.Empty; 199 Nick.BackColor = Color.Empty;
158   200  
159 return true; 201 return true;
160 } 202 }
161   -  
162 private async Task StartServer(IPAddress ipAddress, int port, string nick) -  
163 { -  
164 await MQTTServerSemaphore.WaitAsync(); -  
165 try -  
166 { -  
167 await MQTTServer.Start(ipAddress, port, nick); -  
168 } -  
169 finally -  
170 { -  
171 MQTTServerSemaphore.Release(); -  
172 } -  
173 } -  
174   -  
175 private async Task StopServer() -  
176 { -  
177 await MQTTServerSemaphore.WaitAsync(); -  
178 try -  
179 { -  
180 await MQTTServer.Stop(); -  
181 } -  
182 finally -  
183 { -  
184 MQTTServerSemaphore.Release(); -  
185 } -  
186 } -  
187   203  
188 private async void ConnectButtonClickAsync(object sender, EventArgs e) 204 private async void ConnectButtonClickAsync(object sender, EventArgs e)
189 { 205 {
190 if (MQTTClient.ClientRunning) 206 if (MQTTCommunication.Running)
191 { 207 {
192 await StopClient(); 208 await MQTTCommunication.Stop().ConfigureAwait(false);
193 ConnectButton.Text = Properties.Strings.Connect; 209 ConnectButton.Text = Strings.Connect;
194 ConnectButton.BackColor = Color.Empty; 210 ConnectButton.BackColor = Color.Empty;
-   211  
-   212 Address.Enabled = true;
195   213 Port.Enabled = true;
196 EnableConnectionControls(); 214 Nick.Enabled = true;
197 HostButton.Enabled = true; 215 HostButton.Enabled = true;
198 return; 216 return;
199 } 217 }
200   218  
201 if (!ValidateAddressPort(out var ipAddress, out var port, out var nick)) 219 if (!ValidateAddressPort(out var ipAddress, out var port, out var nick))
202 return; 220 return;
203   221  
204 await StartClient(ipAddress, port, nick); 222 await MQTTCommunication.Start(MQTTCommunicationType.Client, ipAddress, port, nick).ConfigureAwait(false);
205   223  
206 toolStripStatusLabel.Text = Properties.Strings.Client_started; 224 toolStripStatusLabel.Text = Strings.Client_started;
207 ConnectButton.Text = Properties.Strings.Disconnect; 225 ConnectButton.Text = Strings.Disconnect;
208 ConnectButton.BackColor = Color.Aquamarine; 226 ConnectButton.BackColor = Color.Aquamarine;
209   227  
210 HostButton.Enabled = false; 228 HostButton.Enabled = false;
211 DisableConnectionControls(); 229 Address.Enabled = false;
212 } -  
213   -  
214 private async Task StopClient() -  
215 { -  
216 await MQTTClientSemaphore.WaitAsync(); -  
217 try -  
218 { -  
219 await MQTTClient.Stop(); -  
220 } -  
221 finally 230 Port.Enabled = false;
222 { -  
223 MQTTClientSemaphore.Release(); -  
224 } -  
225 } -  
226   -  
227 private async Task StartClient(IPAddress ipAddress, int port, string nick) -  
228 { -  
229 await MQTTClientSemaphore.WaitAsync(); -  
230 try -  
231 { -  
232 await MQTTClient.Start(ipAddress, port, nick); -  
233 } -  
234 finally 231 Nick.Enabled = false;
235 { -  
236 MQTTClientSemaphore.Release(); -  
237 } -  
238 } 232 }
239   233  
240 private async void LobbySayTextBoxKeyDown(object sender, KeyEventArgs e) 234 private async void LobbySayTextBoxKeyDown(object sender, KeyEventArgs e)
241 { 235 {
242 if (e.KeyCode != Keys.Enter) 236 if (e.KeyCode != Keys.Enter)
243 return; 237 return;
244   -  
245 if (MQTTServer.ServerRunning) -  
246 { 238  
247 await MQTTServer.BroadcastLobbyMessage(LobbySayTextBox.Text); -  
248 } -  
249   -  
250 if (MQTTClient.ClientRunning) -  
251 { -  
252 await MQTTClient.BroadcastLobbyMessage(LobbySayTextBox.Text); -  
-   239 await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text).ConfigureAwait(false);
253 } 240  
254   241 LobbySayTextBox.Text = string.Empty;
255 } 242 }
256   243  
257 private void HelmAddButtonClick(object sender, EventArgs e) 244 private void HelmAddButtonClick(object sender, EventArgs e)
258 { 245 {
259 if (string.IsNullOrEmpty(HelmNameTextBox.Text)) 246 if (string.IsNullOrEmpty(HelmNameTextBox.Text))
260 { 247 {
261 HelmNameTextBox.BackColor = Color.LightPink; 248 HelmNameTextBox.BackColor = Color.LightPink;
262 return; 249 return;
263 } 250 }
264   251  
265 HelmAddButton.Enabled = false; 252 HelmAddButton.Enabled = false;
266   253  
267 MouseKeyCombo = new List<string>(); 254 MouseKeyCombo = new List<string>();
268   255  
269 MouseKeyApplicationHook = Hook.AppEvents(); 256 MouseKeyApplicationHook = Hook.AppEvents();
270 MouseKeyApplicationHook.MouseDown += MouseKeyHookOnMouseDown; 257 MouseKeyApplicationHook.MouseDown += MouseKeyHookOnMouseDown;
271 MouseKeyApplicationHook.KeyUp += MouseKeyHookOnKeyUp; 258 MouseKeyApplicationHook.KeyUp += MouseKeyHookOnKeyUp;
272 MouseKeyApplicationHook.KeyDown += MouseKeyHookOnKeyDown; 259 MouseKeyApplicationHook.KeyDown += MouseKeyHookOnKeyDown;
273 MouseKeyApplicationHook.MouseUp += MouseKeyHookOnMouseUp; 260 MouseKeyApplicationHook.MouseUp += MouseKeyHookOnMouseUp;
274   -  
275 } 261 }
276   262  
277 private void MouseKeyHookOnKeyUp(object sender, KeyEventArgs e) 263 private void MouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
278 { 264 {
279 HelmBindings.Bindings.Add(new HelmBinding 265 MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo));
280 { -  
281 Keys = MouseKeyCombo, -  
282 Name = HelmNameTextBox.Text -  
283 }); -  
284   266  
285 HelmBindingSource.ResetBindings(false); 267 HelmBindingSource.ResetBindings(false);
286   268  
287 MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown; 269 MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
288 MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp; 270 MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
-   271 MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
-   272 MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
289   273  
290 MouseKeyApplicationHook.Dispose(); 274 MouseKeyApplicationHook.Dispose();
291   275  
292 HelmNameTextBox.Text = string.Empty; 276 HelmNameTextBox.Text = string.Empty;
293 HelmAddButton.Enabled = true; 277 HelmAddButton.Enabled = true;
294 } 278 }
295   279  
296 private void MouseKeyHookOnMouseUp(object sender, MouseEventArgs e) 280 private void MouseKeyHookOnMouseUp(object sender, MouseEventArgs e)
297 { 281 {
298 HelmBindings.Bindings.Add(new HelmBinding 282 MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo));
299 { -  
300 Keys = MouseKeyCombo, -  
301 Name = HelmNameTextBox.Text -  
302 }); -  
303   283  
304 HelmBindingSource.ResetBindings(false); 284 HelmBindingSource.ResetBindings(false);
305   285  
306 MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown; 286 MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
307 MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp; 287 MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
-   288 MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown;
-   289 MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp;
308   290  
309 MouseKeyApplicationHook.Dispose(); 291 MouseKeyApplicationHook.Dispose();
310   292  
311 HelmNameTextBox.Text = string.Empty; 293 HelmNameTextBox.Text = string.Empty;
312 HelmAddButton.Enabled = true; 294 HelmAddButton.Enabled = true;
313 } 295 }
314   296  
315   297  
316 private void MouseKeyHookOnMouseDown(object sender, MouseEventArgs e) 298 private void MouseKeyHookOnMouseDown(object sender, MouseEventArgs e)
317 { 299 {
318 MouseKeyCombo.Add(MouseButtonToName(e.Button)); 300 MouseKeyCombo.Add(e.Button.ToDisplayName());
319 } 301 }
320   302  
321 private void MouseKeyHookOnKeyDown(object sender, KeyEventArgs e) 303 private void MouseKeyHookOnKeyDown(object sender, KeyEventArgs e)
322 { 304 {
323 e.SuppressKeyPress = true; 305 e.SuppressKeyPress = true;
324   306  
325 MouseKeyCombo.Add(KeyCodeToName((int) e.KeyCode)); 307 MouseKeyCombo.Add(e.KeyCode.ToDisplayName());
326 } 308 }
327   309  
328 private void HelmNameTextBoxClick(object sender, EventArgs e) 310 private void HelmNameTextBoxClick(object sender, EventArgs e)
329 { 311 {
330 HelmNameTextBox.BackColor = Color.Empty; 312 HelmNameTextBox.BackColor = Color.Empty;
331 } 313 }
332   314  
333 private string MouseButtonToName(MouseButtons button) 315 private void HelmRemoveButtonClick(object sender, EventArgs e)
334 { -  
335 var mouseButton = string.Empty; -  
336 switch (button) -  
337 { -  
338 case MouseButtons.Left: 316 {
339 mouseButton = "Left Mouse Button"; -  
340 break; 317 var helmBinding = (MouseKeyBinding) HelmBindingsListBox.SelectedItem;
341 case MouseButtons.Middle: -  
342 mouseButton = "Middle Mouse Button"; -  
343 break; -  
344 case MouseButtons.Right: -  
345 mouseButton = "Right Mouse Button"; 318 if (helmBinding == null)
346 break; -  
-   319 return;
347 } 320  
348   321 MouseKeyBindings.Bindings.Remove(helmBinding);
349 return mouseButton; 322 HelmBindingSource.ResetBindings(false);
350 } 323 }
351   -  
352 private string KeyCodeToName(int code) -  
353 { -  
354 var keyString = string.Empty; -  
355 switch (code) -  
356 { -  
357 case 0: -  
358 break; -  
359 case 1: -  
360 keyString = "Mouse Left"; -  
361 break; -  
362 case 2: -  
363 keyString = "Mouse Right"; -  
364 break; -  
365 case 3: -  
366 keyString = "Cancel"; -  
367 break; -  
368 case 4: -  
369 keyString = "Mouse Middle"; -  
370 break; -  
371 case 5: -  
372 keyString = "Special 1"; -  
373 break; -  
374 case 6: -  
375 keyString = "Special 2"; -  
376 break; -  
377 case 8: -  
378 keyString = "Back"; -  
379 break; -  
380 case 9: -  
381 keyString = "TAB"; -  
382 break; -  
383 case 12: -  
384 keyString = "Clear"; -  
385 break; -  
386 case 13: -  
387 keyString = "Enter"; -  
388 break; -  
389 case 16: -  
390 keyString = "Shift"; -  
391 break; -  
392 case 17: -  
393 keyString = "Ctrl"; -  
394 break; -  
395 case 18: -  
396 keyString = "Menu"; -  
397 break; -  
398 case 19: -  
399 keyString = "Pause"; -  
400 break; -  
401 case 20: -  
402 keyString = "Caps Lock"; 324  
403 break; -  
404 case 21: -  
405 keyString = "Kana/Hangul"; -  
406 break; -  
407 case 23: -  
408 keyString = "Junja"; -  
409 break; -  
410 case 24: -  
411 keyString = "Final"; -  
412 break; -  
413 case 25: -  
414 keyString = "Hanja/Kanji"; -  
415 break; -  
416 case 27: -  
417 keyString = "Esc"; -  
418 break; -  
419 case 28: -  
420 keyString = "Convert"; -  
421 break; -  
422 case 29: -  
423 keyString = "NonConvert"; -  
424 break; -  
425 case 30: -  
426 keyString = "Accept"; -  
427 break; -  
428 case 31: -  
429 keyString = "Mode"; -  
430 break; -  
431 case 32: -  
432 keyString = "Space"; -  
433 break; -  
434 case 33: -  
435 keyString = "Page Up"; -  
436 break; -  
437 case 34: -  
438 keyString = "Page Down"; -  
439 break; -  
440 case 35: -  
441 keyString = "End"; -  
442 break; -  
443 case 36: -  
444 keyString = "Home"; -  
445 break; -  
446 case 37: -  
447 keyString = "Left"; -  
448 break; -  
449 case 38: -  
450 keyString = "Up"; -  
451 break; -  
452 case 39: -  
453 keyString = "Right"; -  
454 break; -  
455 case 40: -  
456 keyString = "Down"; -  
457 break; -  
458 case 41: -  
459 keyString = "Select"; -  
460 break; -  
461 case 42: -  
462 keyString = "Print"; -  
463 break; -  
464 case 43: -  
465 keyString = "Execute"; -  
466 break; -  
467 case 44: -  
468 keyString = "Snapshot"; -  
469 break; -  
470 case 45: -  
471 keyString = "Insert"; -  
472 break; -  
473 case 46: -  
474 keyString = "Delete"; -  
475 break; -  
476 case 47: -  
477 keyString = "Help"; -  
478 break; -  
479 case 48: -  
480 keyString = "Num 0"; -  
481 break; -  
482 case 49: -  
483 keyString = "Num 1"; -  
484 break; -  
485 case 50: -  
486 keyString = "Num 2"; -  
487 break; -  
488 case 51: -  
489 keyString = "Num 3"; -  
490 break; -  
491 case 52: -  
492 keyString = "Num 4"; -  
493 break; -  
494 case 53: -  
495 keyString = "Num 5"; -  
496 break; -  
497 case 54: -  
498 keyString = "Num 6"; -  
499 break; -  
500 case 55: -  
501 keyString = "Num 7"; -  
502 break; -  
503 case 56: -  
504 keyString = "Num 8"; -  
505 break; -  
506 case 57: -  
507 keyString = "Num 9"; -  
508 break; -  
509 case 65: -  
510 keyString = "A"; -  
511 break; -  
512 case 66: -  
513 keyString = "B"; -  
514 break; -  
515 case 67: -  
516 keyString = "C"; -  
517 break; -  
518 case 68: -  
519 keyString = "D"; -  
520 break; -  
521 case 69: -  
522 keyString = "E"; -  
523 break; -  
524 case 70: -  
525 keyString = "F"; -  
526 break; -  
527 case 71: -  
528 keyString = "G"; -  
529 break; -  
530 case 72: -  
531 keyString = "H"; -  
532 break; -  
533 case 73: -  
534 keyString = "I"; -  
535 break; -  
536 case 74: -  
537 keyString = "J"; -  
538 break; -  
539 case 75: -  
540 keyString = "K"; -  
541 break; -  
542 case 76: -  
543 keyString = "L"; -  
544 break; -  
545 case 77: -  
546 keyString = "M"; -  
547 break; -  
548 case 78: -  
549 keyString = "N"; -  
550 break; -  
551 case 79: -  
552 keyString = "O"; -  
553 break; -  
554 case 80: -  
555 keyString = "P"; -  
556 break; -  
557 case 81: -  
558 keyString = "Q"; -  
559 break; -  
560 case 82: -  
561 keyString = "R"; -  
562 break; -  
563 case 83: -  
564 keyString = "S"; -  
565 break; -  
566 case 84: -  
567 keyString = "T"; -  
568 break; -  
569 case 85: -  
570 keyString = "U"; -  
571 break; -  
572 case 86: -  
573 keyString = "V"; -  
574 break; -  
575 case 87: -  
576 keyString = "W"; -  
577 break; -  
578 case 88: -  
579 keyString = "X"; -  
580 break; -  
581 case 89: -  
582 keyString = "Y"; -  
583 break; -  
584 case 90: -  
585 keyString = "Z"; -  
586 break; -  
587 case 91: -  
588 keyString = "Windows Left"; -  
589 break; -  
590 case 92: -  
591 keyString = "Windows Right"; -  
592 break; -  
593 case 93: -  
594 keyString = "Application"; -  
595 break; -  
596 case 95: -  
597 keyString = "Sleep"; -  
598 break; -  
599 case 96: -  
600 keyString = "NumPad 0"; -  
601 break; -  
602 case 97: -  
603 keyString = "NumPad 1"; -  
604 break; -  
605 case 98: -  
606 keyString = "NumPad 2"; -  
607 break; -  
608 case 99: -  
609 keyString = "NumPad 3"; -  
610 break; -  
611 case 100: -  
612 keyString = "NumPad 4"; -  
613 break; -  
614 case 101: -  
615 keyString = "NumPad 5"; -  
616 break; -  
617 case 102: -  
618 keyString = "NumPad 6"; -  
619 break; -  
620 case 103: -  
621 keyString = "NumPad 7"; -  
622 break; -  
623 case 104: -  
624 keyString = "NumPad 8"; -  
625 break; -  
626 case 105: -  
627 keyString = "NumPad 9"; -  
628 break; -  
629 case 106: -  
630 keyString = "NumPad *"; -  
631 break; -  
632 case 107: -  
633 keyString = "NumPad +"; -  
634 break; -  
635 case 108: -  
636 keyString = "NumPad ."; -  
637 break; -  
638 case 109: -  
639 keyString = "NumPad -"; -  
640 break; -  
641 case 110: -  
642 keyString = "NumPad ,"; -  
643 break; -  
644 case 111: -  
645 keyString = "NumPad /"; -  
646 break; -  
647 case 112: -  
648 keyString = "F1"; -  
649 break; -  
650 case 113: -  
651 keyString = "F2"; -  
652 break; -  
653 case 114: -  
654 keyString = "F3"; -  
655 break; -  
656 case 115: -  
657 keyString = "F4"; -  
658 break; -  
659 case 116: -  
660 keyString = "F5"; -  
661 break; -  
662 case 117: -  
663 keyString = "F6"; -  
664 break; -  
665 case 118: -  
666 keyString = "F7"; -  
667 break; -  
668 case 119: -  
669 keyString = "F8"; -  
670 break; -  
671 case 120: -  
672 keyString = "F9"; -  
673 break; -  
674 case 121: -  
675 keyString = "F10"; -  
676 break; -  
677 case 122: -  
678 keyString = "F11"; -  
679 break; -  
680 case 123: -  
681 keyString = "F12"; -  
682 break; -  
683 case 124: -  
684 keyString = "F13"; -  
685 break; -  
686 case 125: -  
687 keyString = "F14"; -  
688 break; -  
689 case 126: -  
690 keyString = "F15"; -  
691 break; -  
692 case 127: -  
693 keyString = "F16"; -  
694 break; -  
695 case 128: -  
696 keyString = "F17"; -  
697 break; -  
698 case 129: -  
699 keyString = "F18"; -  
700 break; -  
701 case 130: -  
702 keyString = "F19"; -  
703 break; -  
704 case 131: -  
705 keyString = "F20"; -  
706 break; -  
707 case 132: -  
708 keyString = "F21"; -  
709 break; -  
710 case 133: -  
711 keyString = "F22"; -  
712 break; -  
713 case 134: -  
714 keyString = "F23"; -  
715 break; -  
716 case 135: -  
717 keyString = "F24"; -  
718 break; -  
719 case 144: -  
720 keyString = "Num lock"; -  
721 break; -  
722 case 145: -  
723 keyString = "Scroll"; -  
724 break; -  
725 case 160: -  
726 keyString = "Shift Left"; -  
727 break; -  
728 case 161: -  
729 keyString = "Shift Right"; -  
730 break; -  
731 case 162: -  
732 keyString = "Ctrl Left"; -  
733 break; -  
734 case 163: -  
735 keyString = "Ctrl Right"; -  
736 break; -  
737 case 164: -  
738 keyString = "Menu Left"; -  
739 break; -  
740 case 165: -  
741 keyString = "Menu Right"; -  
742 break; -  
743 default: 325 private async void LobbySayButtonClick(object sender, EventArgs e)
744 break; 326 {
745 } 327 await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text).ConfigureAwait(false);
746   328  
747 return keyString; 329 LobbySayTextBox.Text = string.Empty;
748 } 330 }
749   331  
750 private void HelmRemoveButtonClick(object sender, EventArgs e) 332 private void WingBindingsComboBoxIndexChanged(object sender, EventArgs e)
-   333 {
751 { 334 var exchangeBinding = (MouseKeyBindingExchange) WingBindingsComboBox.SelectedItem;
-   335 if (exchangeBinding == null)
752 var helmBinding = (HelmBinding)HelmBindingsListBox.SelectedItem; 336 return;
753 if (helmBinding == null) 337  
754 return; 338 WingBindingsListBox.Items.Clear();
755   339 WingBindingsListBox.DisplayMember = "Name";
756 HelmBindings.Bindings.Remove(helmBinding); 340 WingBindingsListBox.ValueMember = "Name";
757 HelmBindingSource.ResetBindings(false); 341 WingBindingsListBox.Items.AddRange(exchangeBinding.Names.Select(name => (object)name).ToArray());
758 } 342 }
759 } 343 }
760 } 344 }
761   345