WingMan – Diff between revs 21 and 22

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 21 Rev 22
1 using System; 1 using System;
2 using System.Collections.Generic; 2 using System.Collections.Generic;
3 using System.Collections.ObjectModel; 3 using System.Collections.ObjectModel;
4 using System.Drawing; 4 using System.Drawing;
5 using System.IO; 5 using System.IO;
6 using System.Linq; 6 using System.Linq;
7 using System.Net; 7 using System.Net;
8 using System.Threading; 8 using System.Threading;
9 using System.Threading.Tasks; 9 using System.Threading.Tasks;
10 using System.Windows.Forms; 10 using System.Windows.Forms;
11 using Gma.System.MouseKeyHook; 11 using Gma.System.MouseKeyHook;
12 using MQTTnet.Extensions.ManagedClient; 12 using MQTTnet.Extensions.ManagedClient;
13 using MQTTnet.Server; 13 using MQTTnet.Server;
14 using WingMan.Bindings; 14 using WingMan.Bindings;
15 using WingMan.Communication; 15 using WingMan.Communication;
16 using WingMan.Lobby; 16 using WingMan.Lobby;
17 using WingMan.Properties; 17 using WingMan.Properties;
18 using WingMan.Utilities; 18 using WingMan.Utilities;
19   19  
20 namespace WingMan 20 namespace WingMan
21 { 21 {
22 public partial class WingManForm : Form 22 public partial class WingManForm : Form
23 { 23 {
24 public WingManForm() 24 public WingManForm()
25 { 25 {
26 InitializeComponent(); 26 InitializeComponent();
27   27  
28 FormTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 28 FormTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
29 FormCancellationTokenSource = new CancellationTokenSource(); 29 FormCancellationTokenSource = new CancellationTokenSource();
30   30  
31 MqttCommunication = new MqttCommunication(FormTaskScheduler, FormCancellationTokenSource.Token); 31 MqttCommunication = new MqttCommunication(FormTaskScheduler, FormCancellationTokenSource.Token);
32 MqttCommunication.OnClientAuthenticationFailed += OnMqttClientAuthenticationFailed; 32 MqttCommunication.OnClientAuthenticationFailed += OnMqttClientAuthenticationFailed;
33 MqttCommunication.OnClientConnectionFailed += OnMqttClientConnectionFailed; 33 MqttCommunication.OnClientConnectionFailed += OnMqttClientConnectionFailed;
34 MqttCommunication.OnClientDisconnected += OnMqttClientDisconnected; 34 MqttCommunication.OnClientDisconnected += OnMqttClientDisconnected;
35 MqttCommunication.OnClientConnected += OnMqttClientConnected; 35 MqttCommunication.OnClientConnected += OnMqttClientConnected;
36 MqttCommunication.OnServerAuthenticationFailed += OnMqttServerAuthenticationFailed; 36 MqttCommunication.OnServerAuthenticationFailed += OnMqttServerAuthenticationFailed;
37 MqttCommunication.OnServerStopped += OnMqttServerStopped; 37 MqttCommunication.OnServerStopped += OnMqttServerStopped;
38 MqttCommunication.OnServerStarted += OnMqttServerStarted; 38 MqttCommunication.OnServerStarted += OnMqttServerStarted;
39 MqttCommunication.OnServerClientConnected += OnMqttServerClientConnected; 39 MqttCommunication.OnServerClientConnected += OnMqttServerClientConnected;
40 MqttCommunication.OnServerClientDisconnected += OnMqttServerClientDisconnected; 40 MqttCommunication.OnServerClientDisconnected += OnMqttServerClientDisconnected;
41   41  
42 LocalKeyBindings = new LocalKeyBindings(new List<KeyBinding>()); 42 LocalKeyBindings = new LocalKeyBindings(new List<KeyBinding>());
43 RemoteKeyBindings = new RemoteKeyBindings(new ObservableCollection<RemoteKeyBinding>()); 43 RemoteKeyBindings = new RemoteKeyBindings(new ObservableCollection<RemoteKeyBinding>());
44   44  
45 LocalListBoxBindingSource = new BindingSource 45 LocalListBoxBindingSource = new BindingSource
46 { 46 {
47 DataSource = LocalKeyBindings.Bindings 47 DataSource = LocalKeyBindings.Bindings
48 }; 48 };
49 LocalBindingsListBox.DisplayMember = "DisplayName"; 49 LocalBindingsListBox.DisplayMember = "DisplayName";
50 LocalBindingsListBox.ValueMember = "Keys"; 50 LocalBindingsListBox.ValueMember = "Keys";
51 LocalBindingsListBox.DataSource = LocalListBoxBindingSource; 51 LocalBindingsListBox.DataSource = LocalListBoxBindingSource;
52   52  
53 KeyBindingsExchange = new KeyBindingsExchange 53 KeyBindingsExchange = new KeyBindingsExchange
54 { 54 {
55 ExchangeBindings = new List<KeyBindingExchange>() 55 ExchangeBindings = new List<KeyBindingExchange>()
56 }; 56 };
57   57  
58 RemoteBindingsComboBoxSource = new BindingSource 58 RemoteBindingsComboBoxSource = new BindingSource
59 { 59 {
60 DataSource = KeyBindingsExchange.ExchangeBindings 60 DataSource = KeyBindingsExchange.ExchangeBindings
61 }; 61 };
62 RemoteBindingsComboBox.DisplayMember = "Nick"; 62 RemoteBindingsComboBox.DisplayMember = "Nick";
63 RemoteBindingsComboBox.ValueMember = "KeyBindings"; 63 RemoteBindingsComboBox.ValueMember = "KeyBindings";
64 RemoteBindingsComboBox.DataSource = RemoteBindingsComboBoxSource; 64 RemoteBindingsComboBox.DataSource = RemoteBindingsComboBoxSource;
65   65  
66 // Start lobby message synchronizer. 66 // Start lobby message synchronizer.
67 LobbyMessageSynchronizer = new LobbyMessageSynchronizer(MqttCommunication, FormTaskScheduler, 67 LobbyMessageSynchronizer = new LobbyMessageSynchronizer(MqttCommunication, FormTaskScheduler,
68 FormCancellationTokenSource.Token); 68 FormCancellationTokenSource.Token);
69 LobbyMessageSynchronizer.OnLobbyMessageReceived += OnLobbyMessageReceived; 69 LobbyMessageSynchronizer.OnLobbyMessageReceived += OnLobbyMessageReceived;
70   70  
71 // Start mouse key bindings synchronizer. 71 // Start mouse key bindings synchronizer.
72 KeyBindingsSynchronizer = new KeyBindingsSynchronizer(LocalKeyBindings, MqttCommunication, 72 KeyBindingsSynchronizer = new KeyBindingsSynchronizer(LocalKeyBindings, MqttCommunication,
73 FormTaskScheduler, FormCancellationTokenSource.Token); 73 FormTaskScheduler, FormCancellationTokenSource.Token);
74 KeyBindingsSynchronizer.OnMouseKeyBindingsSynchronized += OnMouseKeyBindingsSynchronized; 74 KeyBindingsSynchronizer.OnMouseKeyBindingsSynchronized += OnMouseKeyBindingsSynchronized;
75   75  
76 // Start mouse key interceptor. 76 // Start mouse key interceptor.
77 KeyInterceptor = new KeyInterceptor(RemoteKeyBindings, MqttCommunication, FormTaskScheduler, 77 KeyInterceptor = new KeyInterceptor(RemoteKeyBindings, MqttCommunication, FormTaskScheduler,
78 FormCancellationTokenSource.Token); 78 FormCancellationTokenSource.Token);
79 KeyInterceptor.OnMouseKeyBindingMatched += OnMouseKeyBindingMatched; 79 KeyInterceptor.OnMouseKeyBindingMatched += OnMouseKeyBindingMatched;
80   80  
81 // Start mouse key simulator. 81 // Start mouse key simulator.
82 KeySimulator = new KeySimulator(LocalKeyBindings, MqttCommunication, FormTaskScheduler, 82 KeySimulator = new KeySimulator(LocalKeyBindings, MqttCommunication, FormTaskScheduler,
83 FormCancellationTokenSource.Token); 83 FormCancellationTokenSource.Token);
84 KeySimulator.OnMouseKeyBindingExecuting += OnMouseKeyBindingExecuting; 84 KeySimulator.OnMouseKeyBindingExecuting += OnMouseKeyBindingExecuting;
85 } 85 }
86   86  
87 private static CancellationTokenSource FormCancellationTokenSource { get; set; } 87 private static CancellationTokenSource FormCancellationTokenSource { get; set; }
88   88  
89 private static TaskScheduler FormTaskScheduler { get; set; } 89 private static TaskScheduler FormTaskScheduler { get; set; }
90   90  
91 private static IKeyboardMouseEvents MouseKeyApplicationHook { get; set; } 91 private static IKeyboardMouseEvents MouseKeyApplicationHook { get; set; }
92   92  
93 private List<string> MouseKeyCombo { get; set; } 93 private List<string> MouseKeyCombo { get; set; }
94   94  
95 private LocalKeyBindings LocalKeyBindings { get; } 95 private LocalKeyBindings LocalKeyBindings { get; }
96   96  
97 private RemoteKeyBindings RemoteKeyBindings { get; } 97 private RemoteKeyBindings RemoteKeyBindings { get; }
98   98  
99 private BindingSource LocalListBoxBindingSource { get; } 99 private BindingSource LocalListBoxBindingSource { get; }
100   100  
101 private BindingSource RemoteBindingsComboBoxSource { get; } 101 private BindingSource RemoteBindingsComboBoxSource { get; }
102   102  
103 private KeyBindingsExchange KeyBindingsExchange { get; } 103 private KeyBindingsExchange KeyBindingsExchange { get; }
104   104  
105 public MqttCommunication MqttCommunication { get; set; } 105 public MqttCommunication MqttCommunication { get; set; }
106   106  
107 public LobbyMessageSynchronizer LobbyMessageSynchronizer { get; set; } 107 public LobbyMessageSynchronizer LobbyMessageSynchronizer { get; set; }
108   108  
109 public KeyBindingsSynchronizer KeyBindingsSynchronizer { get; set; } 109 public KeyBindingsSynchronizer KeyBindingsSynchronizer { get; set; }
110   110  
111 public KeyInterceptor KeyInterceptor { get; set; } 111 public KeyInterceptor KeyInterceptor { get; set; }
112   112  
113 public KeySimulator KeySimulator { get; set; } 113 public KeySimulator KeySimulator { get; set; }
114   114  
115 /// <inheritdoc /> 115 /// <inheritdoc />
116 /// <summary> 116 /// <summary>
117 /// Clean up any resources being used. 117 /// Clean up any resources being used.
118 /// </summary> 118 /// </summary>
119 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> 119 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
120 protected override void Dispose(bool disposing) 120 protected override void Dispose(bool disposing)
121 { 121 {
122 FormCancellationTokenSource?.Dispose(); 122 FormCancellationTokenSource?.Dispose();
123 FormCancellationTokenSource = null; 123 FormCancellationTokenSource = null;
124   124  
125 if (disposing && components != null) 125 if (disposing && components != null)
126 { 126 {
127 components.Dispose(); 127 components.Dispose();
128 components = null; 128 components = null;
129 } 129 }
130   130  
131 base.Dispose(disposing); 131 base.Dispose(disposing);
132 } 132 }
133   133  
134 private void OnMouseKeyBindingExecuting(object sender, KeyBindingExecutingEventArgs args) 134 private void OnMouseKeyBindingExecuting(object sender, KeyBindingExecutingEventArgs args)
135 { 135 {
136 ActivityTextBox.AppendText( 136 ActivityTextBox.AppendText(
137 $"{Strings.Executing_binding_from_remote_client} : {args.Nick} : {args.Name}{Environment.NewLine}"); 137 $"{Strings.Executing_binding_from_remote_client} : {args.Nick} : {args.Name}{Environment.NewLine}");
138 } 138 }
139   139  
140 private void OnMouseKeyBindingMatched(object sender, KeyBindingMatchedEventArgs args) 140 private void OnMouseKeyBindingMatched(object sender, KeyBindingMatchedEventArgs args)
141 { 141 {
142 ActivityTextBox.AppendText( 142 ActivityTextBox.AppendText(
143 $"{Strings.Matched_remote_key_binding} : {args.Nick} : {args.Name} : {string.Join(" + ", args.KeyCombo)}{Environment.NewLine}"); 143 $"{Strings.Matched_remote_key_binding} : {args.Nick} : {args.Name} : {string.Join(" + ", args.KeyCombo)}{Environment.NewLine}");
144 } 144 }
145   145  
146 private void OnMqttServerClientDisconnected(object sender, MqttClientDisconnectedEventArgs e) 146 private void OnMqttServerClientDisconnected(object sender, MqttClientDisconnectedEventArgs e)
147 { 147 {
148 ActivityTextBox.AppendText( 148 ActivityTextBox.AppendText(
149 $"{Strings.Client_disconnected}{Environment.NewLine}"); 149 $"{Strings.Client_disconnected}{Environment.NewLine}");
150 } 150 }
151   151  
152 private void OnMqttServerClientConnected(object sender, MqttClientConnectedEventArgs e) 152 private void OnMqttServerClientConnected(object sender, MqttClientConnectedEventArgs e)
153 { 153 {
154 ActivityTextBox.AppendText( 154 ActivityTextBox.AppendText(
155 $"{Strings.Client_connected}{Environment.NewLine}"); 155 $"{Strings.Client_connected}{Environment.NewLine}");
156 } 156 }
157   157  
158 private void OnMqttServerStarted(object sender, EventArgs e) 158 private void OnMqttServerStarted(object sender, EventArgs e)
159 { 159 {
160 ActivityTextBox.AppendText( 160 ActivityTextBox.AppendText(
161 $"{Strings.Server_started}{Environment.NewLine}"); 161 $"{Strings.Server_started}{Environment.NewLine}");
162 } 162 }
163   163  
164 private void OnMqttServerStopped(object sender, EventArgs e) 164 private void OnMqttServerStopped(object sender, EventArgs e)
165 { 165 {
166 ActivityTextBox.AppendText( 166 ActivityTextBox.AppendText(
167 $"{Strings.Server_stopped}{Environment.NewLine}"); 167 $"{Strings.Server_stopped}{Environment.NewLine}");
168 } 168 }
169   169  
170 private void OnMqttClientConnected(object sender, MQTTnet.Client.MqttClientConnectedEventArgs e) 170 private void OnMqttClientConnected(object sender, MQTTnet.Client.MqttClientConnectedEventArgs e)
171 { 171 {
172 ActivityTextBox.AppendText( 172 ActivityTextBox.AppendText(
173 $"{Strings.Client_connected}{Environment.NewLine}"); 173 $"{Strings.Client_connected}{Environment.NewLine}");
174 } 174 }
175   175  
176 private void OnMqttClientDisconnected(object sender, MQTTnet.Client.MqttClientDisconnectedEventArgs e) 176 private void OnMqttClientDisconnected(object sender, MQTTnet.Client.MqttClientDisconnectedEventArgs e)
177 { 177 {
178 ActivityTextBox.AppendText( 178 ActivityTextBox.AppendText(
179 $"{Strings.Client_disconnected}{Environment.NewLine}"); 179 $"{Strings.Client_disconnected}{Environment.NewLine}");
180 } 180 }
181   181  
182 private void OnMqttClientConnectionFailed(object sender, MqttManagedProcessFailedEventArgs e) 182 private void OnMqttClientConnectionFailed(object sender, MqttManagedProcessFailedEventArgs e)
183 { 183 {
184 ActivityTextBox.AppendText( 184 ActivityTextBox.AppendText(
185 $"{Strings.Client_connection_failed}{Environment.NewLine}"); 185 $"{Strings.Client_connection_failed}{Environment.NewLine}");
186 } 186 }
187   187  
188 private void OnMqttServerAuthenticationFailed(object sender, MqttAuthenticationFailureEventArgs e) 188 private void OnMqttServerAuthenticationFailed(object sender, MqttAuthenticationFailureEventArgs e)
189 { 189 {
190 ActivityTextBox.AppendText( 190 ActivityTextBox.AppendText(
191 $"{Strings.Failed_to_authenticate_client} : {e.Exception}{Environment.NewLine}"); 191 $"{Strings.Failed_to_authenticate_client} : {e.Exception}{Environment.NewLine}");
192 } 192 }
193   193  
194 private void OnMqttClientAuthenticationFailed(object sender, MqttAuthenticationFailureEventArgs e) 194 private void OnMqttClientAuthenticationFailed(object sender, MqttAuthenticationFailureEventArgs e)
195 { 195 {
196 ActivityTextBox.AppendText( 196 ActivityTextBox.AppendText(
197 $"{Strings.Failed_to_authenticate_with_server} : {e.Exception}{Environment.NewLine}"); 197 $"{Strings.Failed_to_authenticate_with_server} : {e.Exception}{Environment.NewLine}");
198 } 198 }
199   199  
200 private void OnMouseKeyBindingsSynchronized(object sender, KeyBindingsSynchronizerEventArgs e) 200 private void OnMouseKeyBindingsSynchronized(object sender, KeyBindingsSynchronizerEventArgs e)
201 { 201 {
202 ActivityTextBox.AppendText( 202 ActivityTextBox.AppendText(
203 $"{Strings.Synchronized_bindings_with_client} : {e.Bindings.Nick} : {e.Bindings.KeyBindings.Count}{Environment.NewLine}"); 203 $"{Strings.Synchronized_bindings_with_client} : {e.Bindings.Nick} : {e.Bindings.KeyBindings.Count}{Environment.NewLine}");
204   204  
205 var exchangeBindings = KeyBindingsExchange.ExchangeBindings.FirstOrDefault(exchangeBinding => 205 var exchangeBindings = KeyBindingsExchange.ExchangeBindings.FirstOrDefault(exchangeBinding =>
206 string.Equals(exchangeBinding.Nick, e.Bindings.Nick, StringComparison.Ordinal)); 206 string.Equals(exchangeBinding.Nick, e.Bindings.Nick, StringComparison.Ordinal));
207   207  
208 // If the nick does not exist then add it. 208 // If the nick does not exist then add it.
209 if (exchangeBindings == null) 209 if (exchangeBindings == null)
210 { 210 {
211 KeyBindingsExchange.ExchangeBindings.Add(e.Bindings); 211 KeyBindingsExchange.ExchangeBindings.Add(e.Bindings);
212 RemoteBindingsComboBoxSource.ResetBindings(false); 212 RemoteBindingsComboBoxSource.ResetBindings(false);
213 UpdateRemoteItems(); 213 UpdateRemoteItems();
214 return; 214 return;
215 } 215 }
216   216  
217 // If the bindings for the nick have not changed then do not update. 217 // If the bindings for the nick have not changed then do not update.
218 if (exchangeBindings.KeyBindings.SequenceEqual(e.Bindings.KeyBindings)) 218 if (exchangeBindings.KeyBindings.SequenceEqual(e.Bindings.KeyBindings))
219 { 219 {
220 RemoteBindingsComboBoxSource.ResetBindings(false); 220 RemoteBindingsComboBoxSource.ResetBindings(false);
221 UpdateRemoteItems(); 221 UpdateRemoteItems();
222 return; 222 return;
223 } 223 }
224   224  
225 // Update the bindings. 225 // Update the bindings.
226 exchangeBindings.KeyBindings = e.Bindings.KeyBindings; 226 exchangeBindings.KeyBindings = e.Bindings.KeyBindings;
227 RemoteBindingsComboBoxSource.ResetBindings(false); 227 RemoteBindingsComboBoxSource.ResetBindings(false);
228 UpdateRemoteItems(); 228 UpdateRemoteItems();
229 } 229 }
230   230  
231 private void UpdateRemoteItems() 231 private void UpdateRemoteItems()
232 { 232 {
233 var exchangeBindings = (List<KeyBinding>) RemoteBindingsComboBox.SelectedValue; 233 var exchangeBindings = (List<KeyBinding>) RemoteBindingsComboBox.SelectedValue;
234 if (exchangeBindings == null) 234 if (exchangeBindings == null)
235 return; 235 return;
236   236  
237 var replaceMouseBindings = new ObservableCollection<RemoteKeyBinding>(); 237 var replaceMouseBindings = new ObservableCollection<RemoteKeyBinding>();
238 foreach (var remoteBinding in RemoteKeyBindings.Bindings) 238 foreach (var remoteBinding in RemoteKeyBindings.Bindings)
239 { 239 {
240 if (!exchangeBindings.Any(binding => 240 if (!exchangeBindings.Any(binding =>
241 string.Equals(binding.Name, remoteBinding.Name, StringComparison.Ordinal))) 241 string.Equals(binding.Name, remoteBinding.Name, StringComparison.Ordinal)))
242 continue; 242 continue;
243   243  
244 replaceMouseBindings.Add(remoteBinding); 244 replaceMouseBindings.Add(remoteBinding);
245 } 245 }
246   246  
247 RemoteKeyBindings.Bindings.Clear(); 247 RemoteKeyBindings.Bindings.Clear();
248 foreach (var binding in replaceMouseBindings) RemoteKeyBindings.Bindings.Add(binding); 248 foreach (var binding in replaceMouseBindings) RemoteKeyBindings.Bindings.Add(binding);
249   249  
250 RemoteBindingsListBox.Items.Clear(); 250 RemoteBindingsListBox.Items.Clear();
251 RemoteBindingsListBox.DisplayMember = "Name"; 251 RemoteBindingsListBox.DisplayMember = "Name";
252 RemoteBindingsListBox.ValueMember = "Name"; 252 RemoteBindingsListBox.ValueMember = "Name";
253 var bindings = exchangeBindings.Select(binding => (object) binding.Name).ToArray(); 253 var bindings = exchangeBindings.Select(binding => (object) binding.Name).ToArray();
254 if (bindings.Length == 0) 254 if (bindings.Length == 0)
255 return; 255 return;
256   256  
257 RemoteBindingsListBox.Items.AddRange(bindings); 257 RemoteBindingsListBox.Items.AddRange(bindings);
258 } 258 }
259   259  
260 private void OnLobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e) 260 private void OnLobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e)
261 { 261 {
262 LobbyTextBox.AppendText($"{e.Nick} : {e.Message}{Environment.NewLine}"); 262 LobbyTextBox.AppendText($"{e.Nick} : {e.Message}{Environment.NewLine}");
263 } 263 }
264   264  
265 private void AddressTextBoxClick(object sender, EventArgs e) 265 private void AddressTextBoxClick(object sender, EventArgs e)
266 { 266 {
267 Address.BackColor = Color.Empty; 267 Address.BackColor = Color.Empty;
268 } 268 }
269   269  
270 private void PortTextBoxClick(object sender, EventArgs e) 270 private void PortTextBoxClick(object sender, EventArgs e)
271 { 271 {
272 Port.BackColor = Color.Empty; 272 Port.BackColor = Color.Empty;
273 } 273 }
274   274  
275 private async void HostButtonClickAsync(object sender, EventArgs e) 275 private async void HostButtonClickAsync(object sender, EventArgs e)
276 { 276 {
277 // Stop the MQTT server if it is running. 277 // Stop the MQTT server if it is running.
278 if (MqttCommunication.Running) 278 if (MqttCommunication.Running)
279 { 279 {
280 await MqttCommunication.Stop(); 280 await MqttCommunication.Stop();
281 HostButton.BackColor = Color.Empty; 281 HostButton.BackColor = Color.Empty;
282   282  
283 // Enable controls. 283 // Enable controls.
284 ConnectButton.Enabled = true; 284 ConnectButton.Enabled = true;
285 Address.Enabled = true; 285 Address.Enabled = true;
286 Port.Enabled = true; 286 Port.Enabled = true;
287 Nick.Enabled = true; 287 Nick.Enabled = true;
288 Password.Enabled = true; 288 Password.Enabled = true;
289 return; 289 return;
290 } 290 }
291   291  
292 if (!ValidateConnectionParameters(out var ipAddress, out var port, out var nick, out var password)) 292 if (!ValidateConnectionParameters(out var ipAddress, out var port, out var nick, out var password))
293 return; 293 return;
294   294  
295 // Start the MQTT server. 295 // Start the MQTT server.
296 if (!await MqttCommunication 296 if (!await MqttCommunication
297 .Start(MqttCommunicationType.Server, ipAddress, port, nick, password)) 297 .Start(MqttCommunicationType.Server, ipAddress, port, nick, password))
298 { 298 {
299 ActivityTextBox.AppendText( 299 ActivityTextBox.AppendText(
300 $"{Strings.Failed_starting_server}{Environment.NewLine}"); 300 $"{Strings.Failed_starting_server}{Environment.NewLine}");
301 return; 301 return;
302 } 302 }
303   303  
304 HostButton.BackColor = Color.Aquamarine; 304 HostButton.BackColor = Color.Aquamarine;
305   305  
306 // Disable controls 306 // Disable controls
307 ConnectButton.Enabled = false; 307 ConnectButton.Enabled = false;
308 Address.Enabled = false; 308 Address.Enabled = false;
309 Port.Enabled = false; 309 Port.Enabled = false;
310 Nick.Enabled = false; 310 Nick.Enabled = false;
311 Password.Enabled = false; 311 Password.Enabled = false;
312 } 312 }
313   313  
314 private bool ValidateConnectionParameters( 314 private bool ValidateConnectionParameters(
315 out IPAddress address, 315 out IPAddress address,
316 out int port, 316 out int port,
317 out string nick, 317 out string nick,
318 out string password) 318 out string password)
319 { 319 {
320 address = IPAddress.Any; 320 address = IPAddress.Any;
321 port = 0; 321 port = 0;
322 nick = string.Empty; 322 nick = string.Empty;
323 password = string.Empty; 323 password = string.Empty;
324   324  
325 if (string.IsNullOrEmpty(Address.Text) && 325 if (string.IsNullOrEmpty(Address.Text) &&
326 string.IsNullOrEmpty(Port.Text) && 326 string.IsNullOrEmpty(Port.Text) &&
327 string.IsNullOrEmpty(Nick.Text) && 327 string.IsNullOrEmpty(Nick.Text) &&
328 string.IsNullOrEmpty(Password.Text)) 328 string.IsNullOrEmpty(Password.Text))
329 { 329 {
330 Address.BackColor = Color.LightPink; 330 Address.BackColor = Color.LightPink;
331 Port.BackColor = Color.LightPink; 331 Port.BackColor = Color.LightPink;
332 Nick.BackColor = Color.LightPink; 332 Nick.BackColor = Color.LightPink;
333 Password.BackColor = Color.LightPink; 333 Password.BackColor = Color.LightPink;
334 return false; 334 return false;
335 } 335 }
336   336  
337 if (!IPAddress.TryParse(Address.Text, out address)) 337 if (!IPAddress.TryParse(Address.Text, out address))
338 try 338 try
339 { 339 {
340 address = Dns.GetHostAddresses(Address.Text).FirstOrDefault(); 340 address = Dns.GetHostAddresses(Address.Text).FirstOrDefault();
341 } 341 }
342 catch (Exception ex) 342 catch (Exception ex)
343 { 343 {
344 ActivityTextBox.AppendText( 344 ActivityTextBox.AppendText(
345 $"{Strings.Could_not_resolve_hostname} : {ex.Message}{Environment.NewLine}"); 345 $"{Strings.Could_not_resolve_hostname} : {ex.Message}{Environment.NewLine}");
346   346  
347 Address.BackColor = Color.LightPink; 347 Address.BackColor = Color.LightPink;
348 return false; 348 return false;
349 } 349 }
350   350  
351 if (!uint.TryParse(Port.Text, out var uPort)) 351 if (!uint.TryParse(Port.Text, out var uPort))
352 { 352 {
353 Port.BackColor = Color.LightPink; 353 Port.BackColor = Color.LightPink;
354 return false; 354 return false;
355 } 355 }
356   356  
357 port = (int) uPort; 357 port = (int) uPort;
358   358  
359 if (string.IsNullOrEmpty(Nick.Text)) 359 if (string.IsNullOrEmpty(Nick.Text))
360 { 360 {
361 Nick.BackColor = Color.LightPink; 361 Nick.BackColor = Color.LightPink;
362 return false; 362 return false;
363 } 363 }
364   364  
365 nick = Nick.Text; 365 nick = Nick.Text;
366   366  
367 if (string.IsNullOrEmpty(Password.Text)) 367 if (string.IsNullOrEmpty(Password.Text))
368 { 368 {
369 Password.BackColor = Color.LightPink; 369 Password.BackColor = Color.LightPink;
370 return false; 370 return false;
371 } 371 }
372   372  
373 password = AES.ExpandKey(Password.Text); 373 password = AES.ExpandKey(Password.Text);
374   374  
375 Address.BackColor = Color.Empty; 375 Address.BackColor = Color.Empty;
376 Port.BackColor = Color.Empty; 376 Port.BackColor = Color.Empty;
377 Nick.BackColor = Color.Empty; 377 Nick.BackColor = Color.Empty;
378 Password.BackColor = Color.Empty; 378 Password.BackColor = Color.Empty;
379   379  
380 return true; 380 return true;
381 } 381 }
382   382  
383 private async void ConnectButtonClickAsync(object sender, EventArgs e) 383 private async void ConnectButtonClickAsync(object sender, EventArgs e)
384 { 384 {
385 if (MqttCommunication.Running) 385 if (MqttCommunication.Running)
386 { 386 {
387 await MqttCommunication.Stop(); 387 await MqttCommunication.Stop();
388 ConnectButton.Text = Strings.Connect; 388 ConnectButton.Text = Strings.Connect;
389 ConnectButton.BackColor = Color.Empty; 389 ConnectButton.BackColor = Color.Empty;
390   390  
391 Address.Enabled = true; 391 Address.Enabled = true;
392 Port.Enabled = true; 392 Port.Enabled = true;
393 Nick.Enabled = true; 393 Nick.Enabled = true;
394 Password.Enabled = true; 394 Password.Enabled = true;
395 HostButton.Enabled = true; 395 HostButton.Enabled = true;
396 return; 396 return;
397 } 397 }
398   398  
399 if (!ValidateConnectionParameters(out var ipAddress, out var port, out var nick, out var password)) 399 if (!ValidateConnectionParameters(out var ipAddress, out var port, out var nick, out var password))
400 return; 400 return;
401   401  
402 if (!await MqttCommunication 402 if (!await MqttCommunication
403 .Start(MqttCommunicationType.Client, ipAddress, port, nick, password)) 403 .Start(MqttCommunicationType.Client, ipAddress, port, nick, password))
404 { 404 {
405 ActivityTextBox.AppendText( 405 ActivityTextBox.AppendText(
406 $"{Strings.Failed_starting_client}{Environment.NewLine}"); 406 $"{Strings.Failed_starting_client}{Environment.NewLine}");
407 return; 407 return;
408 } 408 }
409   409  
410 ConnectButton.Text = Strings.Disconnect; 410 ConnectButton.Text = Strings.Disconnect;
411 ConnectButton.BackColor = Color.Aquamarine; 411 ConnectButton.BackColor = Color.Aquamarine;
412   412  
413 HostButton.Enabled = false; 413 HostButton.Enabled = false;
414 Address.Enabled = false; 414 Address.Enabled = false;
415 Port.Enabled = false; 415 Port.Enabled = false;
416 Nick.Enabled = false; 416 Nick.Enabled = false;
417 Password.Enabled = false; 417 Password.Enabled = false;
418 } 418 }
419   419  
420 private async void LobbySayTextBoxKeyDown(object sender, KeyEventArgs e) 420 private async void LobbySayTextBoxKeyDown(object sender, KeyEventArgs e)
421 { 421 {
422 if (e.KeyCode != Keys.Enter) 422 if (e.KeyCode != Keys.Enter)
423 return; 423 return;
424   424  
425 await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text); 425 await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text);
426   426  
427 LobbySayTextBox.Text = string.Empty; 427 LobbySayTextBox.Text = string.Empty;
428 } 428 }
429   429  
430 private void LocalAddBindingButtonClick(object sender, EventArgs e) 430 private void LocalAddBindingButtonClick(object sender, EventArgs e)
431 { 431 {
432 if (string.IsNullOrEmpty(LocalNameTextBox.Text)) 432 if (string.IsNullOrEmpty(LocalNameTextBox.Text))
433 { 433 {
434 LocalNameTextBox.BackColor = Color.LightPink; 434 LocalNameTextBox.BackColor = Color.LightPink;
435 return; 435 return;
436 } 436 }
437   437  
438 // Only unique names allowed. 438 // Only unique names allowed.
439 if (LocalKeyBindings.Bindings.Any(binding => 439 if (LocalKeyBindings.Bindings.Any(binding =>
440 string.Equals(binding.Name, LocalNameTextBox.Text, StringComparison.Ordinal))) 440 string.Equals(binding.Name, LocalNameTextBox.Text, StringComparison.Ordinal)))
441 { 441 {
442 LocalNameTextBox.BackColor = Color.LightPink; 442 LocalNameTextBox.BackColor = Color.LightPink;
443 LocalBindingsListBox.BackColor = Color.LightPink; 443 LocalBindingsListBox.BackColor = Color.LightPink;
444 return; 444 return;
445 } 445 }
446   446  
447 LocalNameTextBox.BackColor = Color.Empty; 447 LocalNameTextBox.BackColor = Color.Empty;
448 LocalBindingsListBox.BackColor = Color.Empty; 448 LocalBindingsListBox.BackColor = Color.Empty;
449   449  
450 ShowOverlayPanel(); 450 ShowOverlayPanel();
451   451  
452 MouseKeyCombo = new List<string>(); 452 MouseKeyCombo = new List<string>();
453   453  
454 MouseKeyApplicationHook = Hook.GlobalEvents(); 454 MouseKeyApplicationHook = Hook.GlobalEvents();
455 MouseKeyApplicationHook.KeyUp += LocalMouseKeyHookOnKeyUp; 455 MouseKeyApplicationHook.KeyUp += LocalMouseKeyHookOnKeyUp;
456 MouseKeyApplicationHook.KeyDown += LocalMouseKeyHookOnKeyDown; 456 MouseKeyApplicationHook.KeyDown += LocalMouseKeyHookOnKeyDown;
457 } 457 }
458   458  
459 private void ShowOverlayPanel() 459 private void ShowOverlayPanel()
460 { 460 {
461 OverlayPanel.BringToFront(); 461 OverlayPanel.BringToFront();
462 OverlayPanel.Visible = true; 462 OverlayPanel.Visible = true;
463 OverlayPanel.Invalidate(); 463 OverlayPanel.Invalidate();
464 } 464 }
465   465  
466 private async void LocalMouseKeyHookOnKeyUp(object sender, KeyEventArgs e) 466 private async void LocalMouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
467 { 467 {
468 LocalKeyBindings.Bindings.Add(new KeyBinding(LocalNameTextBox.Text, MouseKeyCombo)); 468 LocalKeyBindings.Bindings.Add(new KeyBinding(LocalNameTextBox.Text, MouseKeyCombo));
469   469  
470 LocalListBoxBindingSource.ResetBindings(false); 470 LocalListBoxBindingSource.ResetBindings(false);
471   471  
472 MouseKeyApplicationHook.KeyDown -= LocalMouseKeyHookOnKeyDown; 472 MouseKeyApplicationHook.KeyDown -= LocalMouseKeyHookOnKeyDown;
473 MouseKeyApplicationHook.KeyUp -= LocalMouseKeyHookOnKeyUp; 473 MouseKeyApplicationHook.KeyUp -= LocalMouseKeyHookOnKeyUp;
474   474  
475 MouseKeyApplicationHook.Dispose(); 475 MouseKeyApplicationHook.Dispose();
476   476  
477 LocalNameTextBox.Text = string.Empty; 477 LocalNameTextBox.Text = string.Empty;
478 HideOverlayPanel(); 478 HideOverlayPanel();
479   479  
480 await SaveLocalMouseKeyBindings(); 480 await SaveLocalMouseKeyBindings();
481 } 481 }
482   482  
483 private void HideOverlayPanel() 483 private void HideOverlayPanel()
484 { 484 {
485 OverlayPanel.SendToBack(); 485 OverlayPanel.SendToBack();
486 OverlayPanel.Visible = false; 486 OverlayPanel.Visible = false;
487 OverlayPanel.Invalidate(); 487 OverlayPanel.Invalidate();
488 } 488 }
489   489  
490 private void LocalMouseKeyHookOnKeyDown(object sender, KeyEventArgs e) 490 private void LocalMouseKeyHookOnKeyDown(object sender, KeyEventArgs e)
491 { 491 {
492 e.SuppressKeyPress = true; 492 e.SuppressKeyPress = true;
493   493  
494 KeyConversion.KeysToString.TryGetValue((byte) e.KeyCode, out var key); 494 KeyConversion.KeysToString.TryGetValue((byte) e.KeyCode, out var key);
495   495  
496 MouseKeyCombo.Add(key); 496 MouseKeyCombo.Add(key);
497 } 497 }
498   498  
499 private void LocalNameTextBoxClick(object sender, EventArgs e) 499 private void LocalNameTextBoxClick(object sender, EventArgs e)
500 { 500 {
501 LocalNameTextBox.BackColor = Color.Empty; 501 LocalNameTextBox.BackColor = Color.Empty;
502 } 502 }
503   503  
504 private async void LocalBindingsRemoveButtonClick(object sender, EventArgs e) 504 private async void LocalBindingsRemoveButtonClick(object sender, EventArgs e)
505 { 505 {
506 var helmBinding = (KeyBinding) LocalBindingsListBox.SelectedItem; 506 var helmBinding = (KeyBinding) LocalBindingsListBox.SelectedItem;
507 if (helmBinding == null) 507 if (helmBinding == null)
508 return; 508 return;
509   509  
510 LocalKeyBindings.Bindings.Remove(helmBinding); 510 LocalKeyBindings.Bindings.Remove(helmBinding);
511 LocalListBoxBindingSource.ResetBindings(false); 511 LocalListBoxBindingSource.ResetBindings(false);
512   512  
513 await SaveLocalMouseKeyBindings(); 513 await SaveLocalMouseKeyBindings();
514 } 514 }
515   515  
516 private async void LobbySayButtonClick(object sender, EventArgs e) 516 private async void LobbySayButtonClick(object sender, EventArgs e)
517 { 517 {
518 await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text); 518 await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text);
519   519  
520 LobbySayTextBox.Text = string.Empty; 520 LobbySayTextBox.Text = string.Empty;
521 } 521 }
522   522  
523 private void RemoteBindingsComboBoxSelectionChangeCompleted(object sender, EventArgs e) 523 private void RemoteBindingsComboBoxSelectionChangeCompleted(object sender, EventArgs e)
524 { 524 {
525 UpdateRemoteItems(); 525 UpdateRemoteItems();
526 } 526 }
527   527  
528 private async void WingManFormOnLoad(object sender, EventArgs e) 528 private async void WingManFormOnLoad(object sender, EventArgs e)
529 { 529 {
530 await LoadLocalMouseKeyBindings(); 530 await LoadLocalMouseKeyBindings();
531   531  
532 await LoadRemoteMouseKeyBindings(); 532 await LoadRemoteMouseKeyBindings();
533 } 533 }
534   534  
535 private void RemoteBindingsBindButtonClicked(object sender, EventArgs e) 535 private void RemoteBindingsBindButtonClicked(object sender, EventArgs e)
536 { 536 {
537 if (string.IsNullOrEmpty((string) RemoteBindingsListBox.SelectedItem)) 537 if (string.IsNullOrEmpty((string) RemoteBindingsListBox.SelectedItem))
538 { 538 {
539 RemoteBindingsListBox.BackColor = Color.LightPink; 539 RemoteBindingsListBox.BackColor = Color.LightPink;
540 return; 540 return;
541 } 541 }
542   542  
543 RemoteBindingsListBox.BackColor = Color.Empty; 543 RemoteBindingsListBox.BackColor = Color.Empty;
544   544  
545 ShowOverlayPanel(); 545 ShowOverlayPanel();
546   546  
547 MouseKeyCombo = new List<string>(); 547 MouseKeyCombo = new List<string>();
548   548  
549 MouseKeyApplicationHook = Hook.GlobalEvents(); 549 MouseKeyApplicationHook = Hook.GlobalEvents();
550 MouseKeyApplicationHook.KeyUp += RemoteKeyHookOnKeyUp; 550 MouseKeyApplicationHook.KeyUp += RemoteKeyHookOnKeyUp;
551 MouseKeyApplicationHook.KeyDown += RemoteKeyHookOnKeyDown; 551 MouseKeyApplicationHook.KeyDown += RemoteKeyHookOnKeyDown;
552 } 552 }
553   553  
554 private void RemoteBindingsUnbindButtonClicked(object sender, EventArgs e) 554 private void RemoteBindingsUnbindButtonClicked(object sender, EventArgs e)
555 { 555 {
556 var item = (string) RemoteBindingsListBox.SelectedItem; 556 var item = (string) RemoteBindingsListBox.SelectedItem;
557 if (string.IsNullOrEmpty(item)) 557 if (string.IsNullOrEmpty(item))
558 { 558 {
559 RemoteBindingsListBox.BackColor = Color.LightPink; 559 RemoteBindingsListBox.BackColor = Color.LightPink;
560 return; 560 return;
561 } 561 }
562   562  
563 RemoteBindingsListBox.BackColor = Color.Empty; 563 RemoteBindingsListBox.BackColor = Color.Empty;
564   564  
565 var remoteKeyBinding = RemoteKeyBindings.Bindings.FirstOrDefault(binding => 565 var remoteKeyBinding = RemoteKeyBindings.Bindings.FirstOrDefault(binding =>
566 string.Equals(binding.Name, item, StringComparison.Ordinal)); 566 string.Equals(binding.Name, item, StringComparison.Ordinal));
567   567  
568 if (remoteKeyBinding == null) 568 if (remoteKeyBinding == null)
569 return; 569 return;
570   570  
571 RemoteKeyBindings.Bindings.Remove(remoteKeyBinding); 571 RemoteKeyBindings.Bindings.Remove(remoteKeyBinding);
572 RemoteBindingsBindToBox.Text = string.Empty; 572 RemoteBindingsBindToBox.Text = string.Empty;
573 } 573 }
574   574  
575 private void RemoteKeyHookOnKeyDown(object sender, KeyEventArgs e) 575 private void RemoteKeyHookOnKeyDown(object sender, KeyEventArgs e)
576 { 576 {
577 e.SuppressKeyPress = true; 577 e.SuppressKeyPress = true;
578   578  
579 if (!KeyConversion.KeysToString.TryGetValue((byte) e.KeyCode, out var key)) 579 if (!KeyConversion.KeysToString.TryGetValue((byte) e.KeyCode, out var key))
580 return; 580 return;
581   581  
582 MouseKeyCombo.Add(key); 582 MouseKeyCombo.Add(key);
583 } 583 }
584   584  
585 private async void RemoteKeyHookOnKeyUp(object sender, KeyEventArgs e) 585 private async void RemoteKeyHookOnKeyUp(object sender, KeyEventArgs e)
586 { 586 {
587 RemoteKeyBindings.Bindings.Add(new RemoteKeyBinding(RemoteBindingsComboBox.Text, 587 RemoteKeyBindings.Bindings.Add(new RemoteKeyBinding(RemoteBindingsComboBox.Text,
588 (string) RemoteBindingsListBox.SelectedItem, MouseKeyCombo)); 588 (string) RemoteBindingsListBox.SelectedItem, MouseKeyCombo));
589   589  
590 MouseKeyApplicationHook.KeyDown -= RemoteKeyHookOnKeyDown; 590 MouseKeyApplicationHook.KeyDown -= RemoteKeyHookOnKeyDown;
591 MouseKeyApplicationHook.KeyUp -= RemoteKeyHookOnKeyUp; 591 MouseKeyApplicationHook.KeyUp -= RemoteKeyHookOnKeyUp;
592   592  
593 MouseKeyApplicationHook.Dispose(); 593 MouseKeyApplicationHook.Dispose();
594   594  
595 RemoteBindingsBindToBox.Text = string.Join(" + ", MouseKeyCombo); 595 RemoteBindingsBindToBox.Text = string.Join(" + ", MouseKeyCombo);
596 HideOverlayPanel(); 596 HideOverlayPanel();
597   597  
598 await SaveRemoteMouseKeyBindings(); 598 await SaveRemoteMouseKeyBindings();
599 } 599 }
600   600  
601 private void RemoteBindingsListBoxSelectedValueChanged(object sender, EventArgs e) 601 private void RemoteBindingsListBoxSelectedValueChanged(object sender, EventArgs e)
602 { 602 {
603 RemoteBindingsBindToBox.Text = ""; 603 RemoteBindingsBindToBox.Text = "";
604   604  
605 var name = (string) RemoteBindingsListBox.SelectedItem; 605 var name = (string) RemoteBindingsListBox.SelectedItem;
606 if (string.IsNullOrEmpty(name)) 606 if (string.IsNullOrEmpty(name))
607 return; 607 return;
608   608  
609 var nick = RemoteBindingsComboBox.Text; 609 var nick = RemoteBindingsComboBox.Text;
610 if (string.IsNullOrEmpty(nick)) 610 if (string.IsNullOrEmpty(nick))
611 return; 611 return;
612   612  
613 foreach (var binding in RemoteKeyBindings.Bindings) 613 foreach (var binding in RemoteKeyBindings.Bindings)
614 { 614 {
615 if (!string.Equals(binding.Nick, nick) || !string.Equals(binding.Name, name)) 615 if (!string.Equals(binding.Nick, nick) || !string.Equals(binding.Name, name))
616 continue; 616 continue;
617   617  
618 RemoteBindingsBindToBox.Text = string.Join(" + ", binding.Keys); 618 RemoteBindingsBindToBox.Text = string.Join(" + ", binding.Keys);
619 break; 619 break;
620 } 620 }
621 } 621 }
622   622  
623 #region Saving and loading 623 #region Saving and loading
624   624  
625 private async Task SaveLocalMouseKeyBindings() 625 private async Task SaveLocalMouseKeyBindings()
626 { 626 {
627 try 627 try
628 { 628 {
629 using (var memoryStream = new MemoryStream()) 629 using (var memoryStream = new MemoryStream())
630 { 630 {
631 LocalKeyBindings.XmlSerializer.Serialize(memoryStream, LocalKeyBindings); 631 LocalKeyBindings.XmlSerializer.Serialize(memoryStream, LocalKeyBindings);
632   632  
633 memoryStream.Position = 0L; 633 memoryStream.Position = 0L;
634   634  
635 using (var fileStream = new FileStream("LocalKeyBindings.xml", FileMode.Create)) 635 using (var fileStream = new FileStream("LocalKeyBindings.xml", FileMode.Create))
636 { 636 {
637 await memoryStream.CopyToAsync(fileStream); 637 await memoryStream.CopyToAsync(fileStream);
638 } 638 }
639 } 639 }
640 } 640 }
641 catch (Exception) 641 catch (Exception)
642 { 642 {
643 ActivityTextBox.AppendText( 643 ActivityTextBox.AppendText(
644 $"{Strings.Failed_saving_local_bindings}{Environment.NewLine}"); 644 $"{Strings.Failed_saving_local_bindings}{Environment.NewLine}");
645 } 645 }
646 } 646 }
647   647  
648 private async Task LoadLocalMouseKeyBindings() 648 private async Task LoadLocalMouseKeyBindings()
649 { 649 {
650 try 650 try
651 { 651 {
652 using (var fileStream = new FileStream("LocalKeyBindings.xml", FileMode.Open)) 652 using (var fileStream = new FileStream("LocalKeyBindings.xml", FileMode.Open))
653 { 653 {
654 using (var memoryStream = new MemoryStream()) 654 using (var memoryStream = new MemoryStream())
655 { 655 {
656 await fileStream.CopyToAsync(memoryStream); 656 await fileStream.CopyToAsync(memoryStream);
657   657  
658 memoryStream.Position = 0L; 658 memoryStream.Position = 0L;
659   659  
660 var loadedBindings = 660 var loadedBindings =
661 (LocalKeyBindings) LocalKeyBindings.XmlSerializer.Deserialize(memoryStream); 661 (LocalKeyBindings) LocalKeyBindings.XmlSerializer.Deserialize(memoryStream);
662   662  
663 foreach (var binding in loadedBindings.Bindings) 663 foreach (var binding in loadedBindings.Bindings)
664 LocalKeyBindings.Bindings.Add(binding); 664 LocalKeyBindings.Bindings.Add(binding);
665   665  
666 LocalListBoxBindingSource.ResetBindings(false); 666 LocalListBoxBindingSource.ResetBindings(false);
667 } 667 }
668 } 668 }
669 } 669 }
670 catch (Exception) 670 catch (Exception)
671 { 671 {
672 ActivityTextBox.AppendText( 672 ActivityTextBox.AppendText(
673 $"{Strings.Failed_loading_local_bindings}{Environment.NewLine}"); 673 $"{Strings.Failed_loading_local_bindings}{Environment.NewLine}");
674 } 674 }
675 } 675 }
676   676  
677 private async Task SaveRemoteMouseKeyBindings() 677 private async Task SaveRemoteMouseKeyBindings()
678 { 678 {
679 try 679 try
680 { 680 {
681 using (var memoryStream = new MemoryStream()) 681 using (var memoryStream = new MemoryStream())
682 { 682 {
683 RemoteKeyBindings.XmlSerializer.Serialize(memoryStream, RemoteKeyBindings); 683 RemoteKeyBindings.XmlSerializer.Serialize(memoryStream, RemoteKeyBindings);
684   684  
685 memoryStream.Position = 0L; 685 memoryStream.Position = 0L;
686   686  
687 using (var fileStream = new FileStream("RemoteKeyBindings.xml", FileMode.Create)) 687 using (var fileStream = new FileStream("RemoteKeyBindings.xml", FileMode.Create))
688 { 688 {
689 await memoryStream.CopyToAsync(fileStream); 689 await memoryStream.CopyToAsync(fileStream);
690 } 690 }
691 } 691 }
692 } 692 }
693 catch (Exception) 693 catch (Exception)
694 { 694 {
695 ActivityTextBox.AppendText( 695 ActivityTextBox.AppendText(
696 $"{Strings.Failed_saving_remote_bindings}{Environment.NewLine}"); 696 $"{Strings.Failed_saving_remote_bindings}{Environment.NewLine}");
697 } 697 }
698 } 698 }
699   699  
700 private async Task LoadRemoteMouseKeyBindings() 700 private async Task LoadRemoteMouseKeyBindings()
701 { 701 {
702 try 702 try
703 { 703 {
704 using (var fileStream = new FileStream("RemoteKeyBindings.xml", FileMode.Open)) 704 using (var fileStream = new FileStream("RemoteKeyBindings.xml", FileMode.Open))
705 { 705 {
706 using (var memoryStream = new MemoryStream()) 706 using (var memoryStream = new MemoryStream())
707 { 707 {
708 await fileStream.CopyToAsync(memoryStream); 708 await fileStream.CopyToAsync(memoryStream);
709   709  
710 memoryStream.Position = 0L; 710 memoryStream.Position = 0L;
711   711  
712 var loadedBindings = 712 var loadedBindings =
713 (RemoteKeyBindings) RemoteKeyBindings.XmlSerializer.Deserialize(memoryStream); 713 (RemoteKeyBindings) RemoteKeyBindings.XmlSerializer.Deserialize(memoryStream);
714   714  
715 foreach (var binding in loadedBindings.Bindings) 715 foreach (var binding in loadedBindings.Bindings)
716 RemoteKeyBindings.Bindings.Add(binding); 716 RemoteKeyBindings.Bindings.Add(binding);
717 } 717 }
718 } 718 }
719 } 719 }
720 catch (Exception) 720 catch (Exception)
721 { 721 {
722 ActivityTextBox.AppendText( 722 ActivityTextBox.AppendText(
723 $"{Strings.Failed_loading_remote_bindings}{Environment.NewLine}"); 723 $"{Strings.Failed_loading_remote_bindings}{Environment.NewLine}");
724 } 724 }
725 } 725 }
726   726  
727 #endregion 727 #endregion
-   728  
-   729 private void WingManFormResized(object sender, EventArgs e)
-   730 {
-   731 if (WindowState == FormWindowState.Minimized)
-   732 {
-   733 Hide();
-   734 notifyIcon1.Visible = true;
-   735 }
-   736 }
-   737  
-   738 private void NotifyIconDoubleClick(object sender, EventArgs e)
-   739 {
-   740 Show();
-   741 WindowState = FormWindowState.Normal;
-   742 notifyIcon1.Visible = false;
-   743 }
728 } 744 }
729 } 745 }
730   746