WingMan – Diff between revs 27 and 32

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