WingMan – Diff between revs 36 and 37

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 36 Rev 37
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.Reflection;
9 using System.Threading; 10 using System.Threading;
10 using System.Threading.Tasks; 11 using System.Threading.Tasks;
11 using System.Windows.Forms; 12 using System.Windows.Forms;
12 using Gma.System.MouseKeyHook; 13 using Gma.System.MouseKeyHook;
-   14 using Microsoft.Win32;
13 using MQTTnet.Extensions.ManagedClient; 15 using MQTTnet.Extensions.ManagedClient;
14 using MQTTnet.Server; 16 using MQTTnet.Server;
15 using WingMan.AutoCompletion; 17 using WingMan.AutoCompletion;
16 using WingMan.Bindings; 18 using WingMan.Bindings;
17 using WingMan.Communication; 19 using WingMan.Communication;
18 using WingMan.Discovery; 20 using WingMan.Discovery;
19 using WingMan.Lobby; 21 using WingMan.Lobby;
20 using WingMan.Properties; 22 using WingMan.Properties;
21 using WingMan.Utilities; 23 using WingMan.Utilities;
22   24  
23 namespace WingMan 25 namespace WingMan
24 { 26 {
25 public partial class WingManForm : Form 27 public partial class WingManForm : Form
26 { 28 {
27 private const int TabControlDetachPixelOffset = 20; 29 private const int TabControlDetachPixelOffset = 20;
28   30  
29 public WingManForm() 31 public WingManForm()
30 { 32 {
31 InitializeComponent(); 33 InitializeComponent();
32   34  
33 FormTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); 35 FormTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
34 FormCancellationTokenSource = new CancellationTokenSource(); 36 FormCancellationTokenSource = new CancellationTokenSource();
35   37  
36 // Set up discovery. 38 // Set up discovery.
37 Discovery = new Discovery.Discovery(FormCancellationTokenSource, FormTaskScheduler); 39 Discovery = new Discovery.Discovery(FormCancellationTokenSource, FormTaskScheduler);
38 Discovery.OnPortMapFailed += OnDiscoveryPortMapFailed; 40 Discovery.OnPortMapFailed += OnDiscoveryPortMapFailed;
39   41  
40 // Set up autocompletion. 42 // Set up autocompletion.
41 AutoCompletion = new AutoCompletion.AutoCompletion(FormTaskScheduler, FormCancellationTokenSource.Token); 43 AutoCompletion = new AutoCompletion.AutoCompletion(FormTaskScheduler, FormCancellationTokenSource.Token);
42 AutoCompletion.OnSaveFailed += AutoCompletionOnSaveFailed; 44 AutoCompletion.OnSaveFailed += AutoCompletionOnSaveFailed;
43 AutoCompletion.OnLoadFailed += AutoCompletionOnLoadFailed; 45 AutoCompletion.OnLoadFailed += AutoCompletionOnLoadFailed;
44   46  
45 Task.Run(() => AutoCompletion.Load(Address.Name, Address.AutoCompleteCustomSource)); 47 Task.Run(() => AutoCompletion.Load(Address.Name, Address.AutoCompleteCustomSource));
46 Task.Run(() => AutoCompletion.Load(Port.Name, Address.AutoCompleteCustomSource)); 48 Task.Run(() => AutoCompletion.Load(Port.Name, Address.AutoCompleteCustomSource));
47 Task.Run(() => AutoCompletion.Load(Nick.Name, Nick.AutoCompleteCustomSource)); 49 Task.Run(() => AutoCompletion.Load(Nick.Name, Nick.AutoCompleteCustomSource));
48 Task.Run(() => AutoCompletion.Load(LocalNameTextBox.Name, LocalNameTextBox.AutoCompleteCustomSource)); 50 Task.Run(() => AutoCompletion.Load(LocalNameTextBox.Name, LocalNameTextBox.AutoCompleteCustomSource));
49   51  
50 MqttCommunication = new MqttCommunication(FormTaskScheduler, FormCancellationTokenSource.Token); 52 MqttCommunication = new MqttCommunication(FormTaskScheduler, FormCancellationTokenSource.Token);
51 MqttCommunication.OnClientAuthenticationFailed += OnMqttClientAuthenticationFailed; 53 MqttCommunication.OnClientAuthenticationFailed += OnMqttClientAuthenticationFailed;
52 MqttCommunication.OnClientConnectionFailed += OnMqttClientConnectionFailed; 54 MqttCommunication.OnClientConnectionFailed += OnMqttClientConnectionFailed;
53 MqttCommunication.OnClientDisconnected += OnMqttClientDisconnected; 55 MqttCommunication.OnClientDisconnected += OnMqttClientDisconnected;
54 MqttCommunication.OnClientConnected += OnMqttClientConnected; 56 MqttCommunication.OnClientConnected += OnMqttClientConnected;
55 MqttCommunication.OnServerAuthenticationFailed += OnMqttServerAuthenticationFailed; 57 MqttCommunication.OnServerAuthenticationFailed += OnMqttServerAuthenticationFailed;
56 MqttCommunication.OnServerStopped += OnMqttServerStopped; 58 MqttCommunication.OnServerStopped += OnMqttServerStopped;
57 MqttCommunication.OnServerStarted += OnMqttServerStarted; 59 MqttCommunication.OnServerStarted += OnMqttServerStarted;
58 MqttCommunication.OnServerClientConnected += OnMqttServerClientConnected; 60 MqttCommunication.OnServerClientConnected += OnMqttServerClientConnected;
59 MqttCommunication.OnServerClientDisconnected += OnMqttServerClientDisconnected; 61 MqttCommunication.OnServerClientDisconnected += OnMqttServerClientDisconnected;
60   62  
61 LocalKeyBindings = new LocalKeyBindings(new List<KeyBinding>()); 63 LocalKeyBindings = new LocalKeyBindings(new List<KeyBinding>());
62 RemoteKeyBindings = new RemoteKeyBindings(new ObservableCollection<RemoteKeyBinding>()); 64 RemoteKeyBindings = new RemoteKeyBindings(new ObservableCollection<RemoteKeyBinding>());
63   65  
64 LocalCheckedListBoxBindingSource = new BindingSource 66 LocalCheckedListBoxBindingSource = new BindingSource
65 { 67 {
66 DataSource = LocalKeyBindings.Bindings 68 DataSource = LocalKeyBindings.Bindings
67 }; 69 };
68 LocalCheckedListBoxBindingSource.ListChanged += LocalCheckedListBoxBindingSourceOnListChanged; 70 LocalCheckedListBoxBindingSource.ListChanged += LocalCheckedListBoxBindingSourceOnListChanged;
69   71  
70 LocalBindingsCheckedListBox.DisplayMember = "DisplayName"; 72 LocalBindingsCheckedListBox.DisplayMember = "DisplayName";
71 LocalBindingsCheckedListBox.ValueMember = "Keys"; 73 LocalBindingsCheckedListBox.ValueMember = "Keys";
72 LocalBindingsCheckedListBox.DataSource = LocalCheckedListBoxBindingSource; 74 LocalBindingsCheckedListBox.DataSource = LocalCheckedListBoxBindingSource;
73   75  
74 KeyBindingsExchange = new KeyBindingsExchange 76 KeyBindingsExchange = new KeyBindingsExchange
75 { 77 {
76 ExchangeBindings = new List<KeyBindingExchange>() 78 ExchangeBindings = new List<KeyBindingExchange>()
77 }; 79 };
78   80  
79 RemoteBindingsComboBoxSource = new BindingSource 81 RemoteBindingsComboBoxSource = new BindingSource
80 { 82 {
81 DataSource = KeyBindingsExchange.ExchangeBindings 83 DataSource = KeyBindingsExchange.ExchangeBindings
82 }; 84 };
83 RemoteBindingsComboBoxSource.ListChanged += RemoteBindingsComboBoxSourceOnListChanged; 85 RemoteBindingsComboBoxSource.ListChanged += RemoteBindingsComboBoxSourceOnListChanged;
84   86  
85 RemoteBindingsComboBox.DisplayMember = "Nick"; 87 RemoteBindingsComboBox.DisplayMember = "Nick";
86 RemoteBindingsComboBox.ValueMember = "KeyBindings"; 88 RemoteBindingsComboBox.ValueMember = "KeyBindings";
87 RemoteBindingsComboBox.DataSource = RemoteBindingsComboBoxSource; 89 RemoteBindingsComboBox.DataSource = RemoteBindingsComboBoxSource;
88   90  
89   91  
90 // Start lobby message synchronizer. 92 // Start lobby message synchronizer.
91 LobbyMessageSynchronizer = new LobbyMessageSynchronizer(MqttCommunication, FormTaskScheduler, 93 LobbyMessageSynchronizer = new LobbyMessageSynchronizer(MqttCommunication, FormTaskScheduler,
92 FormCancellationTokenSource.Token); 94 FormCancellationTokenSource.Token);
93 LobbyMessageSynchronizer.OnLobbyMessageReceived += OnLobbyMessageReceived; 95 LobbyMessageSynchronizer.OnLobbyMessageReceived += OnLobbyMessageReceived;
94   96  
95 // Start mouse key bindings synchronizer. 97 // Start mouse key bindings synchronizer.
96 KeyBindingsSynchronizer = new KeyBindingsSynchronizer(LocalKeyBindings, MqttCommunication, 98 KeyBindingsSynchronizer = new KeyBindingsSynchronizer(LocalKeyBindings, MqttCommunication,
97 FormTaskScheduler, FormCancellationTokenSource.Token); 99 FormTaskScheduler, FormCancellationTokenSource.Token);
98 KeyBindingsSynchronizer.OnMouseKeyBindingsSynchronized += OnMouseKeyBindingsSynchronized; 100 KeyBindingsSynchronizer.OnMouseKeyBindingsSynchronized += OnMouseKeyBindingsSynchronized;
99   101  
100 // Start mouse key interceptor. 102 // Start mouse key interceptor.
101 KeyInterceptor = new KeyInterceptor(RemoteKeyBindings, MqttCommunication, FormTaskScheduler, 103 KeyInterceptor = new KeyInterceptor(RemoteKeyBindings, MqttCommunication, FormTaskScheduler,
102 FormCancellationTokenSource.Token); 104 FormCancellationTokenSource.Token);
103 KeyInterceptor.OnMouseKeyBindingMatched += OnMouseKeyBindingMatched; 105 KeyInterceptor.OnMouseKeyBindingMatched += OnMouseKeyBindingMatched;
104   106  
105 // Start mouse key simulator. 107 // Start mouse key simulator.
106 KeySimulator = new KeySimulator(LocalKeyBindings, MqttCommunication, FormTaskScheduler, 108 KeySimulator = new KeySimulator(LocalKeyBindings, MqttCommunication, FormTaskScheduler,
107 FormCancellationTokenSource.Token); 109 FormCancellationTokenSource.Token);
108 KeySimulator.OnMouseKeyBindingExecuting += OnMouseKeyBindingExecuting; 110 KeySimulator.OnMouseKeyBindingExecuting += OnMouseKeyBindingExecuting;
109 } 111 }
110   112  
111 private static Discovery.Discovery Discovery { get; set; } 113 private static Discovery.Discovery Discovery { get; set; }
112 private static AutoCompletion.AutoCompletion AutoCompletion { get; set; } 114 private static AutoCompletion.AutoCompletion AutoCompletion { get; set; }
113 private static CancellationTokenSource FormCancellationTokenSource { get; set; } 115 private static CancellationTokenSource FormCancellationTokenSource { get; set; }
114   116  
115 private static TaskScheduler FormTaskScheduler { get; set; } 117 private static TaskScheduler FormTaskScheduler { get; set; }
116   118  
117 private static IKeyboardMouseEvents MouseKeyApplicationHook { get; set; } 119 private static IKeyboardMouseEvents MouseKeyApplicationHook { get; set; }
118   120  
119 private List<string> MouseKeyCombo { get; set; } 121 private List<string> MouseKeyCombo { get; set; }
120   122  
121 public LocalKeyBindings LocalKeyBindings { get; set; } 123 public LocalKeyBindings LocalKeyBindings { get; set; }
122   124  
123 private RemoteKeyBindings RemoteKeyBindings { get; } 125 private RemoteKeyBindings RemoteKeyBindings { get; }
124   126  
125 private BindingSource LocalCheckedListBoxBindingSource { get; } 127 private BindingSource LocalCheckedListBoxBindingSource { get; }
126   128  
127 private BindingSource RemoteBindingsComboBoxSource { get; } 129 private BindingSource RemoteBindingsComboBoxSource { get; }
128   130  
129 private KeyBindingsExchange KeyBindingsExchange { get; } 131 private KeyBindingsExchange KeyBindingsExchange { get; }
130   132  
131 public MqttCommunication MqttCommunication { get; set; } 133 public MqttCommunication MqttCommunication { get; set; }
132   134  
133 public LobbyMessageSynchronizer LobbyMessageSynchronizer { get; set; } 135 public LobbyMessageSynchronizer LobbyMessageSynchronizer { get; set; }
134   136  
135 public KeyBindingsSynchronizer KeyBindingsSynchronizer { get; set; } 137 public KeyBindingsSynchronizer KeyBindingsSynchronizer { get; set; }
136   138  
137 public KeyInterceptor KeyInterceptor { get; set; } 139 public KeyInterceptor KeyInterceptor { get; set; }
138   140  
139 public KeySimulator KeySimulator { get; set; } 141 public KeySimulator KeySimulator { get; set; }
140   142  
141 private static Point TabControlClickStartPosition { get; set; } 143 private static Point TabControlClickStartPosition { get; set; }
142 private static TabControl DetachedTabControl { get; set; } 144 private static TabControl DetachedTabControl { get; set; }
143 private static Form DetachedForm { get; set; } 145 private static Form DetachedForm { get; set; }
-   146  
-   147 /// <inheritdoc />
-   148 /// <summary>
-   149 /// Clean up any resources being used.
-   150 /// </summary>
-   151 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
-   152 protected override void Dispose(bool disposing)
-   153 {
-   154 FormCancellationTokenSource?.Dispose();
-   155 FormCancellationTokenSource = null;
-   156  
-   157 if (disposing && components != null)
-   158 {
-   159 components.Dispose();
-   160 components = null;
-   161 }
-   162  
-   163 base.Dispose(disposing);
-   164 }
144   165  
145 private void RemoteBindingsComboBoxSourceOnListChanged(object sender, ListChangedEventArgs e) 166 private void RemoteBindingsComboBoxSourceOnListChanged(object sender, ListChangedEventArgs e)
146 { 167 {
147 UpdateRemoteBindingsListBox(); 168 UpdateRemoteBindingsListBox();
148 } 169 }
149   170  
150 public void OnDiscoveryPortMapFailed(object sender, DiscoveryFailedEventArgs args) 171 public void OnDiscoveryPortMapFailed(object sender, DiscoveryFailedEventArgs args)
151 { 172 {
152 switch (args.Type) 173 switch (args.Type)
153 { 174 {
154 case DiscoveryType.Upnp: 175 case DiscoveryType.Upnp:
155 ActivityTextBox.AppendText( 176 ActivityTextBox.AppendText(
156 $"{Strings.Failed_to_create_UPnP_port_mapping}{Environment.NewLine}"); 177 $"{Strings.Failed_to_create_UPnP_port_mapping}{Environment.NewLine}");
157 break; 178 break;
158 case DiscoveryType.Pmp: 179 case DiscoveryType.Pmp:
159 ActivityTextBox.AppendText( 180 ActivityTextBox.AppendText(
160 $"{Strings.Failed_to_create_PMP_port_mapping}{Environment.NewLine}"); 181 $"{Strings.Failed_to_create_PMP_port_mapping}{Environment.NewLine}");
161 break; 182 break;
162 } 183 }
163 } 184 }
164   185  
165 private void LocalCheckedListBoxBindingSourceOnListChanged(object sender, ListChangedEventArgs e) 186 private void LocalCheckedListBoxBindingSourceOnListChanged(object sender, ListChangedEventArgs e)
166 { 187 {
167 // Check items 188 // Check items
168 LocalBindingsCheckedListBox.ItemCheck -= LocalBindingsCheckedListBoxItemCheck; 189 LocalBindingsCheckedListBox.ItemCheck -= LocalBindingsCheckedListBoxItemCheck;
169   190  
170 for (var i = 0; i < LocalKeyBindings.Bindings.Count; ++i) 191 for (var i = 0; i < LocalKeyBindings.Bindings.Count; ++i)
171 switch (LocalKeyBindings.Bindings[i].Enabled) 192 switch (LocalKeyBindings.Bindings[i].Enabled)
172 { 193 {
173 case true: 194 case true:
174 LocalBindingsCheckedListBox.SetItemCheckState(i, CheckState.Checked); 195 LocalBindingsCheckedListBox.SetItemCheckState(i, CheckState.Checked);
175 break; 196 break;
176 default: 197 default:
177 LocalBindingsCheckedListBox.SetItemCheckState(i, CheckState.Unchecked); 198 LocalBindingsCheckedListBox.SetItemCheckState(i, CheckState.Unchecked);
178 break; 199 break;
179 } 200 }
180   201  
181 LocalBindingsCheckedListBox.ItemCheck += LocalBindingsCheckedListBoxItemCheck; 202 LocalBindingsCheckedListBox.ItemCheck += LocalBindingsCheckedListBoxItemCheck;
182 } 203 }
183   204  
184 private void AutoCompletionOnLoadFailed(object sender, AutoCompletionFailedEventArgs args) 205 private void AutoCompletionOnLoadFailed(object sender, AutoCompletionFailedEventArgs args)
185 { 206 {
186 ActivityTextBox.AppendText( 207 ActivityTextBox.AppendText(
187 $"{Strings.Failed_loading_autocomplete_source} : {args.Name} : {args.Exception.Message}{Environment.NewLine}"); 208 $"{Strings.Failed_loading_autocomplete_source} : {args.Name} : {args.Exception.Message}{Environment.NewLine}");
188 } 209 }
189   210  
190 private void AutoCompletionOnSaveFailed(object sender, AutoCompletionFailedEventArgs args) 211 private void AutoCompletionOnSaveFailed(object sender, AutoCompletionFailedEventArgs args)
191 { 212 {
192 ActivityTextBox.AppendText( 213 ActivityTextBox.AppendText(
193 $"{Strings.Failed_saving_autocomplete_source} : {args.Name} : {args.Exception.Message}{Environment.NewLine}"); 214 $"{Strings.Failed_saving_autocomplete_source} : {args.Name} : {args.Exception.Message}{Environment.NewLine}");
194 } 215 }
195   -  
196 /// <inheritdoc /> -  
197 /// <summary> -  
198 /// Clean up any resources being used. -  
199 /// </summary> -  
200 /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> -  
201 protected override void Dispose(bool disposing) -  
202 { -  
203 FormCancellationTokenSource?.Dispose(); -  
204 FormCancellationTokenSource = null; -  
205   -  
206 if (disposing && components != null) -  
207 { -  
208 components.Dispose(); -  
209 components = null; -  
210 } -  
211   -  
212 base.Dispose(disposing); -  
213 } -  
214   216  
215 private void OnMouseKeyBindingExecuting(object sender, KeyBindingExecutingEventArgs args) 217 private void OnMouseKeyBindingExecuting(object sender, KeyBindingExecutingEventArgs args)
216 { 218 {
217 ActivityTextBox.AppendText( 219 ActivityTextBox.AppendText(
218 $"{Strings.Executing_binding_from_remote_client} : {args.Nick} : {args.Name}{Environment.NewLine}"); 220 $"{Strings.Executing_binding_from_remote_client} : {args.Nick} : {args.Name}{Environment.NewLine}");
219 } 221 }
220   222  
221 private void OnMouseKeyBindingMatched(object sender, KeyBindingMatchedEventArgs args) 223 private void OnMouseKeyBindingMatched(object sender, KeyBindingMatchedEventArgs args)
222 { 224 {
223 ActivityTextBox.AppendText( 225 ActivityTextBox.AppendText(
224 $"{Strings.Matched_remote_key_binding} : {args.Nick} : {args.Name} : {string.Join(" + ", args.KeyCombo)}{Environment.NewLine}"); 226 $"{Strings.Matched_remote_key_binding} : {args.Nick} : {args.Name} : {string.Join(" + ", args.KeyCombo)}{Environment.NewLine}");
225 } 227 }
226   228  
227 private void OnMqttServerClientDisconnected(object sender, MqttClientDisconnectedEventArgs e) 229 private void OnMqttServerClientDisconnected(object sender, MqttClientDisconnectedEventArgs e)
228 { 230 {
229 ActivityTextBox.AppendText( 231 ActivityTextBox.AppendText(
230 $"{Strings.Client_disconnected}{Environment.NewLine}"); 232 $"{Strings.Client_disconnected}{Environment.NewLine}");
231 } 233 }
232   234  
233 private void OnMqttServerClientConnected(object sender, MqttClientConnectedEventArgs e) 235 private void OnMqttServerClientConnected(object sender, MqttClientConnectedEventArgs e)
234 { 236 {
235 ActivityTextBox.AppendText( 237 ActivityTextBox.AppendText(
236 $"{Strings.Client_connected}{Environment.NewLine}"); 238 $"{Strings.Client_connected}{Environment.NewLine}");
237 } 239 }
238   240  
239 private void OnMqttServerStarted(object sender, EventArgs e) 241 private void OnMqttServerStarted(object sender, EventArgs e)
240 { 242 {
241 ActivityTextBox.AppendText( 243 ActivityTextBox.AppendText(
242 $"{Strings.Server_started}{Environment.NewLine}"); 244 $"{Strings.Server_started}{Environment.NewLine}");
243 } 245 }
244   246  
245 private void OnMqttServerStopped(object sender, EventArgs e) 247 private void OnMqttServerStopped(object sender, EventArgs e)
246 { 248 {
247 ActivityTextBox.AppendText( 249 ActivityTextBox.AppendText(
248 $"{Strings.Server_stopped}{Environment.NewLine}"); 250 $"{Strings.Server_stopped}{Environment.NewLine}");
249 } 251 }
250   252  
251 private void OnMqttClientConnected(object sender, MQTTnet.Client.MqttClientConnectedEventArgs e) 253 private void OnMqttClientConnected(object sender, MQTTnet.Client.MqttClientConnectedEventArgs e)
252 { 254 {
253 ActivityTextBox.AppendText( 255 ActivityTextBox.AppendText(
254 $"{Strings.Client_connected}{Environment.NewLine}"); 256 $"{Strings.Client_connected}{Environment.NewLine}");
255 } 257 }
256   258  
257 private void OnMqttClientDisconnected(object sender, MQTTnet.Client.MqttClientDisconnectedEventArgs e) 259 private void OnMqttClientDisconnected(object sender, MQTTnet.Client.MqttClientDisconnectedEventArgs e)
258 { 260 {
259 ActivityTextBox.AppendText( 261 ActivityTextBox.AppendText(
260 $"{Strings.Client_disconnected}{Environment.NewLine}"); 262 $"{Strings.Client_disconnected}{Environment.NewLine}");
261 } 263 }
262   264  
263 private void OnMqttClientConnectionFailed(object sender, MqttManagedProcessFailedEventArgs e) 265 private void OnMqttClientConnectionFailed(object sender, MqttManagedProcessFailedEventArgs e)
264 { 266 {
265 ActivityTextBox.AppendText( 267 ActivityTextBox.AppendText(
266 $"{Strings.Client_connection_failed}{Environment.NewLine}"); 268 $"{Strings.Client_connection_failed}{Environment.NewLine}");
267 } 269 }
268   270  
269 private void OnMqttServerAuthenticationFailed(object sender, MqttAuthenticationFailureEventArgs e) 271 private void OnMqttServerAuthenticationFailed(object sender, MqttAuthenticationFailureEventArgs e)
270 { 272 {
271 ActivityTextBox.AppendText( 273 ActivityTextBox.AppendText(
272 $"{Strings.Failed_to_authenticate_client} : {e.Exception}{Environment.NewLine}"); 274 $"{Strings.Failed_to_authenticate_client} : {e.Exception}{Environment.NewLine}");
273 } 275 }
274   276  
275 private void OnMqttClientAuthenticationFailed(object sender, MqttAuthenticationFailureEventArgs e) 277 private void OnMqttClientAuthenticationFailed(object sender, MqttAuthenticationFailureEventArgs e)
276 { 278 {
277 ActivityTextBox.AppendText( 279 ActivityTextBox.AppendText(
278 $"{Strings.Failed_to_authenticate_with_server} : {e.Exception}{Environment.NewLine}"); 280 $"{Strings.Failed_to_authenticate_with_server} : {e.Exception}{Environment.NewLine}");
279 } 281 }
280   282  
281 private void OnMouseKeyBindingsSynchronized(object sender, KeyBindingsSynchronizerEventArgs e) 283 private void OnMouseKeyBindingsSynchronized(object sender, KeyBindingsSynchronizerEventArgs e)
282 { 284 {
283 ActivityTextBox.AppendText( 285 ActivityTextBox.AppendText(
284 $"{Strings.Synchronized_bindings_with_client} : {e.Bindings.Nick} : {e.Bindings.KeyBindings.Count}{Environment.NewLine}"); 286 $"{Strings.Synchronized_bindings_with_client} : {e.Bindings.Nick} : {e.Bindings.KeyBindings.Count}{Environment.NewLine}");
285   287  
286 var exchangeBindings = KeyBindingsExchange.ExchangeBindings.FirstOrDefault(exchangeBinding => 288 var exchangeBindings = KeyBindingsExchange.ExchangeBindings.FirstOrDefault(exchangeBinding =>
287 string.Equals(exchangeBinding.Nick, e.Bindings.Nick, StringComparison.Ordinal)); 289 string.Equals(exchangeBinding.Nick, e.Bindings.Nick, StringComparison.Ordinal));
288   290  
289 // If the nick does not exist then add it. 291 // If the nick does not exist then add it.
290 if (exchangeBindings == null) 292 if (exchangeBindings == null)
291 { 293 {
292 KeyBindingsExchange.ExchangeBindings.Add(e.Bindings); 294 KeyBindingsExchange.ExchangeBindings.Add(e.Bindings);
293 RemoteBindingsComboBoxSource.ResetBindings(false); 295 RemoteBindingsComboBoxSource.ResetBindings(false);
294 return; 296 return;
295 } 297 }
296   298  
297 // If the bindings for the nick have not changed then do not update. 299 // If the bindings for the nick have not changed then do not update.
298 if (e.Bindings.KeyBindings.Count == exchangeBindings.KeyBindings.Count && 300 if (e.Bindings.KeyBindings.Count == exchangeBindings.KeyBindings.Count &&
299 e.Bindings.KeyBindings.All(exchangeBindings.KeyBindings.Contains)) 301 e.Bindings.KeyBindings.All(exchangeBindings.KeyBindings.Contains))
300 { 302 {
301 RemoteBindingsComboBoxSource.ResetBindings(false); 303 RemoteBindingsComboBoxSource.ResetBindings(false);
302 return; 304 return;
303 } 305 }
304   306  
305 // Update the bindings. 307 // Update the bindings.
306 exchangeBindings.KeyBindings.RemoveAll(binding => !e.Bindings.KeyBindings.Contains(binding)); 308 exchangeBindings.KeyBindings.RemoveAll(binding => !e.Bindings.KeyBindings.Contains(binding));
307 exchangeBindings.KeyBindings.AddRange( 309 exchangeBindings.KeyBindings.AddRange(
308 e.Bindings.KeyBindings.Where(binding => !exchangeBindings.KeyBindings.Contains(binding))); 310 e.Bindings.KeyBindings.Where(binding => !exchangeBindings.KeyBindings.Contains(binding)));
309 RemoteBindingsComboBoxSource.ResetBindings(false); 311 RemoteBindingsComboBoxSource.ResetBindings(false);
310 } 312 }
311   313  
312 private void UpdateRemoteBindingsListBox() 314 private void UpdateRemoteBindingsListBox()
313 { 315 {
314 var keyBindingExchange = (KeyBindingExchange) RemoteBindingsComboBox.SelectedItem; 316 var keyBindingExchange = (KeyBindingExchange) RemoteBindingsComboBox.SelectedItem;
315 if (keyBindingExchange == null) 317 if (keyBindingExchange == null)
316 return; 318 return;
317   319  
318 RemoteBindingsListBox.Items.Clear(); 320 RemoteBindingsListBox.Items.Clear();
319 var bindings = KeyBindingsExchange.ExchangeBindings 321 var bindings = KeyBindingsExchange.ExchangeBindings
320 .Where(binding => binding.Nick == keyBindingExchange.Nick) 322 .Where(binding => binding.Nick == keyBindingExchange.Nick)
321 .SelectMany(binding => binding.KeyBindings.Select(keyBinding => keyBinding)) 323 .SelectMany(binding => binding.KeyBindings.Select(keyBinding => keyBinding))
322 .Select(binding => (object) binding).ToArray(); 324 .Select(binding => (object) binding).ToArray();
323   325  
324 if (bindings.Length == 0) 326 if (bindings.Length == 0)
325 return; 327 return;
326   328  
327 RemoteBindingsListBox.Items.AddRange(bindings); 329 RemoteBindingsListBox.Items.AddRange(bindings);
328 } 330 }
329   331  
330 private void OnLobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e) 332 private void OnLobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e)
331 { 333 {
332 WingManNotifyIcon.BalloonTipTitle = Strings.Lobby_message; 334 WingManNotifyIcon.BalloonTipTitle = Strings.Lobby_message;
333 WingManNotifyIcon.BalloonTipText = $"{e.Nick} : {e.Message}{Environment.NewLine}"; 335 WingManNotifyIcon.BalloonTipText = $"{e.Nick} : {e.Message}{Environment.NewLine}";
334 WingManNotifyIcon.ShowBalloonTip(1000); 336 WingManNotifyIcon.ShowBalloonTip(1000);
335   337  
336 LobbyTextBox.AppendText($"{e.Nick} : {e.Message}{Environment.NewLine}"); 338 LobbyTextBox.AppendText($"{e.Nick} : {e.Message}{Environment.NewLine}");
337 } 339 }
338   340  
339 private void AddressTextBoxClick(object sender, EventArgs e) 341 private void AddressTextBoxClick(object sender, EventArgs e)
340 { 342 {
341 Address.BackColor = Color.Empty; 343 Address.BackColor = Color.Empty;
342 } 344 }
343   345  
344 private void PortTextBoxClick(object sender, EventArgs e) 346 private void PortTextBoxClick(object sender, EventArgs e)
345 { 347 {
346 Port.BackColor = Color.Empty; 348 Port.BackColor = Color.Empty;
347 } 349 }
348   350  
349 private async void HostButtonClickAsync(object sender, EventArgs e) 351 private async void HostButtonClickAsync(object sender, EventArgs e)
350 { 352 {
351 // Stop the MQTT server if it is running. 353 // Stop the MQTT server if it is running.
352 if (MqttCommunication.Running) 354 if (MqttCommunication.Running)
353 { 355 {
354 // Remote UPnP and Pmp mappings. 356 // Remote UPnP and Pmp mappings.
355 await Task.Delay(0, FormCancellationTokenSource.Token).ContinueWith(async _ => 357 await Task.Delay(0, FormCancellationTokenSource.Token).ContinueWith(async _ =>
356 { 358 {
357 await Discovery.DeleteMapping(DiscoveryType.Upnp, MqttCommunication.Port); 359 await Discovery.DeleteMapping(DiscoveryType.Upnp, MqttCommunication.Port);
358 await Discovery.DeleteMapping(DiscoveryType.Pmp, MqttCommunication.Port); 360 await Discovery.DeleteMapping(DiscoveryType.Pmp, MqttCommunication.Port);
359 }, 361 },
360 FormCancellationTokenSource.Token, TaskContinuationOptions.LongRunning, FormTaskScheduler); 362 FormCancellationTokenSource.Token, TaskContinuationOptions.LongRunning, FormTaskScheduler);
361   363  
362 await MqttCommunication.Stop(); 364 await MqttCommunication.Stop();
363   365  
364 HostButton.BackColor = Color.Empty; 366 HostButton.BackColor = Color.Empty;
365   367  
366 // Enable controls. 368 // Enable controls.
367 ConnectButton.Enabled = true; 369 ConnectButton.Enabled = true;
368 Address.Enabled = true; 370 Address.Enabled = true;
369 Port.Enabled = true; 371 Port.Enabled = true;
370 Nick.Enabled = true; 372 Nick.Enabled = true;
371 Password.Enabled = true; 373 Password.Enabled = true;
372 return; 374 return;
373 } 375 }
374   376  
375 if (!ValidateConnectionParameters(out var ipAddress, out var port, out var nick, out var password)) 377 if (!ValidateConnectionParameters(out var ipAddress, out var port, out var nick, out var password))
376 return; 378 return;
377   379  
378 StoreConnectionAutocomplete(); 380 StoreConnectionAutocomplete();
379   381  
380 // Try to reserve port: try UPnP followed by PMP. 382 // Try to reserve port: try UPnP followed by PMP.
381 await Task.Delay(0, FormCancellationTokenSource.Token).ContinueWith(async _ => 383 await Task.Delay(0, FormCancellationTokenSource.Token).ContinueWith(async _ =>
382 { 384 {
383 if (!await Discovery.CreateMapping(DiscoveryType.Upnp, port) && 385 if (!await Discovery.CreateMapping(DiscoveryType.Upnp, port) &&
384 !await Discovery.CreateMapping(DiscoveryType.Pmp, port)) 386 !await Discovery.CreateMapping(DiscoveryType.Pmp, port))
385 ActivityTextBox.AppendText( 387 ActivityTextBox.AppendText(
386 $"{Strings.Failed_creating_automatic_port_mapping_please_make_sure_the_port_is_routed_properly}{Environment.NewLine}"); 388 $"{Strings.Failed_creating_automatic_port_mapping_please_make_sure_the_port_is_routed_properly}{Environment.NewLine}");
387 }, 389 },
388 FormCancellationTokenSource.Token, TaskContinuationOptions.LongRunning, FormTaskScheduler); 390 FormCancellationTokenSource.Token, TaskContinuationOptions.LongRunning, FormTaskScheduler);
389   391  
390 // Start the MQTT server. 392 // Start the MQTT server.
391 if (!await MqttCommunication 393 if (!await MqttCommunication
392 .Start(MqttCommunicationType.Server, ipAddress, port, nick, password)) 394 .Start(MqttCommunicationType.Server, ipAddress, port, nick, password))
393 { 395 {
394 ActivityTextBox.AppendText( 396 ActivityTextBox.AppendText(
395 $"{Strings.Failed_starting_server}{Environment.NewLine}"); 397 $"{Strings.Failed_starting_server}{Environment.NewLine}");
396 return; 398 return;
397 } 399 }
398   400  
399 HostButton.BackColor = Color.Aquamarine; 401 HostButton.BackColor = Color.Aquamarine;
400   402  
401 // Disable controls 403 // Disable controls
402 ConnectButton.Enabled = false; 404 ConnectButton.Enabled = false;
403 Address.Enabled = false; 405 Address.Enabled = false;
404 Port.Enabled = false; 406 Port.Enabled = false;
405 Nick.Enabled = false; 407 Nick.Enabled = false;
406 Password.Enabled = false; 408 Password.Enabled = false;
407 } 409 }
408   410  
409 private async void StoreConnectionAutocomplete() 411 private async void StoreConnectionAutocomplete()
410 { 412 {
411 Address.AutoCompleteCustomSource.Add(Address.Text); 413 Address.AutoCompleteCustomSource.Add(Address.Text);
412   414  
413 await AutoCompletion.Save(Address.Name, Address.AutoCompleteCustomSource); 415 await AutoCompletion.Save(Address.Name, Address.AutoCompleteCustomSource);
414   416  
415 Port.AutoCompleteCustomSource.Add(Port.Text); 417 Port.AutoCompleteCustomSource.Add(Port.Text);
416   418  
417 await AutoCompletion.Save(Port.Name, Port.AutoCompleteCustomSource); 419 await AutoCompletion.Save(Port.Name, Port.AutoCompleteCustomSource);
418   420  
419 Nick.AutoCompleteCustomSource.Add(Nick.Text); 421 Nick.AutoCompleteCustomSource.Add(Nick.Text);
420   422  
421 await AutoCompletion.Save(Nick.Name, Nick.AutoCompleteCustomSource); 423 await AutoCompletion.Save(Nick.Name, Nick.AutoCompleteCustomSource);
422 } 424 }
423   425  
424 private bool ValidateConnectionParameters( 426 private bool ValidateConnectionParameters(
425 out IPAddress address, 427 out IPAddress address,
426 out int port, 428 out int port,
427 out string nick, 429 out string nick,
428 out string password) 430 out string password)
429 { 431 {
430 address = IPAddress.Any; 432 address = IPAddress.Any;
431 port = 0; 433 port = 0;
432 nick = string.Empty; 434 nick = string.Empty;
433 password = string.Empty; 435 password = string.Empty;
434   436  
435 if (string.IsNullOrEmpty(Address.Text) && 437 if (string.IsNullOrEmpty(Address.Text) &&
436 string.IsNullOrEmpty(Port.Text) && 438 string.IsNullOrEmpty(Port.Text) &&
437 string.IsNullOrEmpty(Nick.Text) && 439 string.IsNullOrEmpty(Nick.Text) &&
438 string.IsNullOrEmpty(Password.Text)) 440 string.IsNullOrEmpty(Password.Text))
439 { 441 {
440 Address.BackColor = Color.LightPink; 442 Address.BackColor = Color.LightPink;
441 Port.BackColor = Color.LightPink; 443 Port.BackColor = Color.LightPink;
442 Nick.BackColor = Color.LightPink; 444 Nick.BackColor = Color.LightPink;
443 Password.BackColor = Color.LightPink; 445 Password.BackColor = Color.LightPink;
444 return false; 446 return false;
445 } 447 }
446   448  
447 if (!IPAddress.TryParse(Address.Text, out address)) 449 if (!IPAddress.TryParse(Address.Text, out address))
448 try 450 try
449 { 451 {
450 address = Dns.GetHostAddresses(Address.Text).FirstOrDefault(); 452 address = Dns.GetHostAddresses(Address.Text).FirstOrDefault();
451 } 453 }
452 catch (Exception ex) 454 catch (Exception ex)
453 { 455 {
454 ActivityTextBox.AppendText( 456 ActivityTextBox.AppendText(
455 $"{Strings.Could_not_resolve_hostname} : {ex.Message}{Environment.NewLine}"); 457 $"{Strings.Could_not_resolve_hostname} : {ex.Message}{Environment.NewLine}");
456   458  
457 Address.BackColor = Color.LightPink; 459 Address.BackColor = Color.LightPink;
458 return false; 460 return false;
459 } 461 }
460   462  
461 if (!uint.TryParse(Port.Text, out var uPort)) 463 if (!uint.TryParse(Port.Text, out var uPort))
462 { 464 {
463 Port.BackColor = Color.LightPink; 465 Port.BackColor = Color.LightPink;
464 return false; 466 return false;
465 } 467 }
466   468  
467 port = (int) uPort; 469 port = (int) uPort;
468   470  
469 if (string.IsNullOrEmpty(Nick.Text)) 471 if (string.IsNullOrEmpty(Nick.Text))
470 { 472 {
471 Nick.BackColor = Color.LightPink; 473 Nick.BackColor = Color.LightPink;
472 return false; 474 return false;
473 } 475 }
474   476  
475 nick = Nick.Text; 477 nick = Nick.Text;
476   478  
477 if (string.IsNullOrEmpty(Password.Text)) 479 if (string.IsNullOrEmpty(Password.Text))
478 { 480 {
479 Password.BackColor = Color.LightPink; 481 Password.BackColor = Color.LightPink;
480 return false; 482 return false;
481 } 483 }
482   484  
483 password = Aes.ExpandKey(Password.Text); 485 password = Aes.ExpandKey(Password.Text);
484   486  
485 Address.BackColor = Color.Empty; 487 Address.BackColor = Color.Empty;
486 Port.BackColor = Color.Empty; 488 Port.BackColor = Color.Empty;
487 Nick.BackColor = Color.Empty; 489 Nick.BackColor = Color.Empty;
488 Password.BackColor = Color.Empty; 490 Password.BackColor = Color.Empty;
489   491  
490 return true; 492 return true;
491 } 493 }
492   494  
493 private async void ConnectButtonClickAsync(object sender, EventArgs e) 495 private async void ConnectButtonClickAsync(object sender, EventArgs e)
494 { 496 {
495 if (MqttCommunication.Running) 497 if (MqttCommunication.Running)
496 { 498 {
497 await MqttCommunication.Stop(); 499 await MqttCommunication.Stop();
498 ConnectButton.Text = Strings.Connect; 500 ConnectButton.Text = Strings.Connect;
499 ConnectButton.BackColor = Color.Empty; 501 ConnectButton.BackColor = Color.Empty;
500   502  
501 Address.Enabled = true; 503 Address.Enabled = true;
502 Port.Enabled = true; 504 Port.Enabled = true;
503 Nick.Enabled = true; 505 Nick.Enabled = true;
504 Password.Enabled = true; 506 Password.Enabled = true;
505 HostButton.Enabled = true; 507 HostButton.Enabled = true;
506 return; 508 return;
507 } 509 }
508   510  
509 if (!ValidateConnectionParameters(out var ipAddress, out var port, out var nick, out var password)) 511 if (!ValidateConnectionParameters(out var ipAddress, out var port, out var nick, out var password))
510 return; 512 return;
511   513  
512 StoreConnectionAutocomplete(); 514 StoreConnectionAutocomplete();
513   515  
514 if (!await MqttCommunication 516 if (!await MqttCommunication
515 .Start(MqttCommunicationType.Client, ipAddress, port, nick, password)) 517 .Start(MqttCommunicationType.Client, ipAddress, port, nick, password))
516 { 518 {
517 ActivityTextBox.AppendText( 519 ActivityTextBox.AppendText(
518 $"{Strings.Failed_starting_client}{Environment.NewLine}"); 520 $"{Strings.Failed_starting_client}{Environment.NewLine}");
519 return; 521 return;
520 } 522 }
521   523  
522 ConnectButton.Text = Strings.Disconnect; 524 ConnectButton.Text = Strings.Disconnect;
523 ConnectButton.BackColor = Color.Aquamarine; 525 ConnectButton.BackColor = Color.Aquamarine;
524   526  
525 HostButton.Enabled = false; 527 HostButton.Enabled = false;
526 Address.Enabled = false; 528 Address.Enabled = false;
527 Port.Enabled = false; 529 Port.Enabled = false;
528 Nick.Enabled = false; 530 Nick.Enabled = false;
529 Password.Enabled = false; 531 Password.Enabled = false;
530 } 532 }
531   533  
532 private async void LobbySayTextBoxKeyDown(object sender, KeyEventArgs e) 534 private async void LobbySayTextBoxKeyDown(object sender, KeyEventArgs e)
533 { 535 {
534 // Do not send messages if the communication is not running. 536 // Do not send messages if the communication is not running.
535 if (!MqttCommunication.Running) 537 if (!MqttCommunication.Running)
536 return; 538 return;
537   539  
538 if (e.KeyCode != Keys.Enter) 540 if (e.KeyCode != Keys.Enter)
539 return; 541 return;
540   542  
541 await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text); 543 await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text);
542   544  
543 LobbySayTextBox.Text = string.Empty; 545 LobbySayTextBox.Text = string.Empty;
544 } 546 }
545   547  
546 private async void LocalAddBindingButtonClick(object sender, EventArgs e) 548 private async void LocalAddBindingButtonClick(object sender, EventArgs e)
547 { 549 {
548 if (string.IsNullOrEmpty(LocalNameTextBox.Text)) 550 if (string.IsNullOrEmpty(LocalNameTextBox.Text))
549 { 551 {
550 LocalNameTextBox.BackColor = Color.LightPink; 552 LocalNameTextBox.BackColor = Color.LightPink;
551 return; 553 return;
552 } 554 }
553   555  
554 // Only unique names allowed. 556 // Only unique names allowed.
555 if (LocalKeyBindings.Bindings.Any(binding => 557 if (LocalKeyBindings.Bindings.Any(binding =>
556 string.Equals(binding.Name, LocalNameTextBox.Text, StringComparison.Ordinal))) 558 string.Equals(binding.Name, LocalNameTextBox.Text, StringComparison.Ordinal)))
557 { 559 {
558 LocalNameTextBox.BackColor = Color.LightPink; 560 LocalNameTextBox.BackColor = Color.LightPink;
559 LocalBindingsCheckedListBox.BackColor = Color.LightPink; 561 LocalBindingsCheckedListBox.BackColor = Color.LightPink;
560 return; 562 return;
561 } 563 }
562   564  
563 LocalNameTextBox.BackColor = Color.Empty; 565 LocalNameTextBox.BackColor = Color.Empty;
564 LocalBindingsCheckedListBox.BackColor = Color.Empty; 566 LocalBindingsCheckedListBox.BackColor = Color.Empty;
565   567  
566 LocalNameTextBox.AutoCompleteCustomSource.Add(LocalNameTextBox.Text); 568 LocalNameTextBox.AutoCompleteCustomSource.Add(LocalNameTextBox.Text);
567   569  
568 await AutoCompletion.Save(LocalNameTextBox.Name, LocalNameTextBox.AutoCompleteCustomSource); 570 await AutoCompletion.Save(LocalNameTextBox.Name, LocalNameTextBox.AutoCompleteCustomSource);
569   571  
570 ShowOverlayPanel(); 572 ShowOverlayPanel();
571   573  
572 MouseKeyCombo = new List<string>(); 574 MouseKeyCombo = new List<string>();
573   575  
574 MouseKeyApplicationHook = Hook.GlobalEvents(); 576 MouseKeyApplicationHook = Hook.GlobalEvents();
575 MouseKeyApplicationHook.KeyUp += LocalMouseKeyHookOnKeyUp; 577 MouseKeyApplicationHook.KeyUp += LocalMouseKeyHookOnKeyUp;
576 MouseKeyApplicationHook.KeyDown += LocalMouseKeyHookOnKeyDown; 578 MouseKeyApplicationHook.KeyDown += LocalMouseKeyHookOnKeyDown;
577 } 579 }
578   580  
579 private void ShowOverlayPanel() 581 private void ShowOverlayPanel()
580 { 582 {
581 OverlayPanel.BringToFront(); 583 OverlayPanel.BringToFront();
582 OverlayPanel.Visible = true; 584 OverlayPanel.Visible = true;
583 OverlayPanel.Invalidate(); 585 OverlayPanel.Invalidate();
584 } 586 }
585   587  
586 private async void LocalMouseKeyHookOnKeyUp(object sender, KeyEventArgs e) 588 private async void LocalMouseKeyHookOnKeyUp(object sender, KeyEventArgs e)
587 { 589 {
588 LocalKeyBindings.Bindings.Add(new KeyBinding(LocalNameTextBox.Text, MouseKeyCombo)); 590 LocalKeyBindings.Bindings.Add(new KeyBinding(LocalNameTextBox.Text, MouseKeyCombo));
589   591  
590 LocalCheckedListBoxBindingSource.ResetBindings(false); 592 LocalCheckedListBoxBindingSource.ResetBindings(false);
591   593  
592 MouseKeyApplicationHook.KeyDown -= LocalMouseKeyHookOnKeyDown; 594 MouseKeyApplicationHook.KeyDown -= LocalMouseKeyHookOnKeyDown;
593 MouseKeyApplicationHook.KeyUp -= LocalMouseKeyHookOnKeyUp; 595 MouseKeyApplicationHook.KeyUp -= LocalMouseKeyHookOnKeyUp;
594   596  
595 MouseKeyApplicationHook.Dispose(); 597 MouseKeyApplicationHook.Dispose();
596   598  
597 LocalNameTextBox.Text = string.Empty; 599 LocalNameTextBox.Text = string.Empty;
598 HideOverlayPanel(); 600 HideOverlayPanel();
599   601  
600 await SaveLocalMouseKeyBindings(); 602 await SaveLocalMouseKeyBindings();
601 } 603 }
602   604  
603 private void HideOverlayPanel() 605 private void HideOverlayPanel()
604 { 606 {
605 OverlayPanel.SendToBack(); 607 OverlayPanel.SendToBack();
606 OverlayPanel.Visible = false; 608 OverlayPanel.Visible = false;
607 OverlayPanel.Invalidate(); 609 OverlayPanel.Invalidate();
608 } 610 }
609   611  
610 private void LocalMouseKeyHookOnKeyDown(object sender, KeyEventArgs e) 612 private void LocalMouseKeyHookOnKeyDown(object sender, KeyEventArgs e)
611 { 613 {
612 e.SuppressKeyPress = true; 614 e.SuppressKeyPress = true;
613   615  
614 KeyConversion.KeysToString.TryGetValue((byte) e.KeyCode, out var key); 616 KeyConversion.KeysToString.TryGetValue((byte) e.KeyCode, out var key);
615   617  
616 MouseKeyCombo.Add(key); 618 MouseKeyCombo.Add(key);
617 } 619 }
618   620  
619 private void LocalNameTextBoxClick(object sender, EventArgs e) 621 private void LocalNameTextBoxClick(object sender, EventArgs e)
620 { 622 {
621 LocalNameTextBox.BackColor = Color.Empty; 623 LocalNameTextBox.BackColor = Color.Empty;
622 } 624 }
623   625  
624 private async void LocalBindingsRemoveButtonClick(object sender, EventArgs e) 626 private async void LocalBindingsRemoveButtonClick(object sender, EventArgs e)
625 { 627 {
626 var localBinding = (KeyBinding) LocalBindingsCheckedListBox.SelectedItem; 628 var localBinding = (KeyBinding) LocalBindingsCheckedListBox.SelectedItem;
627 if (localBinding == null) 629 if (localBinding == null)
628 return; 630 return;
629   631  
630 LocalKeyBindings.Bindings.Remove(localBinding); 632 LocalKeyBindings.Bindings.Remove(localBinding);
631 LocalCheckedListBoxBindingSource.ResetBindings(false); 633 LocalCheckedListBoxBindingSource.ResetBindings(false);
632   634  
633 await SaveLocalMouseKeyBindings(); 635 await SaveLocalMouseKeyBindings();
634 } 636 }
635   637  
636 private async void LobbySayButtonClick(object sender, EventArgs e) 638 private async void LobbySayButtonClick(object sender, EventArgs e)
637 { 639 {
638 // Do not send messages if the communication is not running. 640 // Do not send messages if the communication is not running.
639 if (!MqttCommunication.Running) 641 if (!MqttCommunication.Running)
640 return; 642 return;
641   643  
642 await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text); 644 await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text);
643   645  
644 LobbySayTextBox.Text = string.Empty; 646 LobbySayTextBox.Text = string.Empty;
645 } 647 }
646   648  
647 private void RemoteBindingsComboBoxSelectionChangeCompleted(object sender, EventArgs e) 649 private void RemoteBindingsComboBoxSelectionChangeCompleted(object sender, EventArgs e)
648 { 650 {
649 UpdateRemoteBindingsListBox(); 651 UpdateRemoteBindingsListBox();
650 } 652 }
651   653  
652 private async void WingManFormOnLoad(object sender, EventArgs e) 654 private async void WingManFormOnLoad(object sender, EventArgs e)
653 { 655 {
-   656 using (var key = Registry.CurrentUser.OpenSubKey
-   657 ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
-   658 {
-   659 switch (key.GetValue(Name) == null)
-   660 {
-   661 case true:
-   662 windowsStartupCheckBox.Checked = false;
-   663 break;
-   664 default:
-   665 windowsStartupCheckBox.Checked = true;
-   666 break;
-   667 }
-   668 }
-   669  
654 await LoadLocalMouseKeyBindings(); 670 await LoadLocalKeyBindings();
-   671  
-   672 await LoadRemoteKeyBindings();
-   673 }
655   674  
-   675 private void WingManFormOnClosing(object sender, FormClosingEventArgs e)
656 await LoadRemoteMouseKeyBindings(); 676 {
657 } 677 }
658   678  
659 private void RemoteBindingsBindButtonClicked(object sender, EventArgs e) 679 private void RemoteBindingsBindButtonClicked(object sender, EventArgs e)
660 { 680 {
661 if (string.IsNullOrEmpty((string) RemoteBindingsListBox.SelectedItem)) 681 if (string.IsNullOrEmpty((string) RemoteBindingsListBox.SelectedItem))
662 { 682 {
663 RemoteBindingsListBox.BackColor = Color.LightPink; 683 RemoteBindingsListBox.BackColor = Color.LightPink;
664 return; 684 return;
665 } 685 }
666   686  
667 RemoteBindingsListBox.BackColor = Color.Empty; 687 RemoteBindingsListBox.BackColor = Color.Empty;
668   688  
669 ShowOverlayPanel(); 689 ShowOverlayPanel();
670   690  
671 MouseKeyCombo = new List<string>(); 691 MouseKeyCombo = new List<string>();
672   692  
673 MouseKeyApplicationHook = Hook.GlobalEvents(); 693 MouseKeyApplicationHook = Hook.GlobalEvents();
674 MouseKeyApplicationHook.KeyUp += RemoteKeyHookOnKeyUp; 694 MouseKeyApplicationHook.KeyUp += RemoteKeyHookOnKeyUp;
675 MouseKeyApplicationHook.KeyDown += RemoteKeyHookOnKeyDown; 695 MouseKeyApplicationHook.KeyDown += RemoteKeyHookOnKeyDown;
676 } 696 }
677   697  
678 private void RemoteBindingsUnbindButtonClicked(object sender, EventArgs e) 698 private void RemoteBindingsUnbindButtonClicked(object sender, EventArgs e)
679 { 699 {
680 var item = (string) RemoteBindingsListBox.SelectedItem; 700 var item = (string) RemoteBindingsListBox.SelectedItem;
681 if (string.IsNullOrEmpty(item)) 701 if (string.IsNullOrEmpty(item))
682 { 702 {
683 RemoteBindingsListBox.BackColor = Color.LightPink; 703 RemoteBindingsListBox.BackColor = Color.LightPink;
684 return; 704 return;
685 } 705 }
686   706  
687 RemoteBindingsListBox.BackColor = Color.Empty; 707 RemoteBindingsListBox.BackColor = Color.Empty;
688   708  
689 var remoteKeyBinding = RemoteKeyBindings.Bindings.FirstOrDefault(binding => 709 var remoteKeyBinding = RemoteKeyBindings.Bindings.FirstOrDefault(binding =>
690 string.Equals(binding.Name, item, StringComparison.Ordinal)); 710 string.Equals(binding.Name, item, StringComparison.Ordinal));
691   711  
692 if (remoteKeyBinding == null) 712 if (remoteKeyBinding == null)
693 return; 713 return;
694   714  
695 RemoteKeyBindings.Bindings.Remove(remoteKeyBinding); 715 RemoteKeyBindings.Bindings.Remove(remoteKeyBinding);
696 RemoteBindingsBindToBox.Text = string.Empty; 716 RemoteBindingsBindToBox.Text = string.Empty;
697 } 717 }
698   718  
699 private void RemoteKeyHookOnKeyDown(object sender, KeyEventArgs e) 719 private void RemoteKeyHookOnKeyDown(object sender, KeyEventArgs e)
700 { 720 {
701 e.SuppressKeyPress = true; 721 e.SuppressKeyPress = true;
702   722  
703 if (!KeyConversion.KeysToString.TryGetValue((byte) e.KeyCode, out var key)) 723 if (!KeyConversion.KeysToString.TryGetValue((byte) e.KeyCode, out var key))
704 return; 724 return;
705   725  
706 MouseKeyCombo.Add(key); 726 MouseKeyCombo.Add(key);
707 } 727 }
708   728  
709 private async void RemoteKeyHookOnKeyUp(object sender, KeyEventArgs e) 729 private async void RemoteKeyHookOnKeyUp(object sender, KeyEventArgs e)
710 { 730 {
711 RemoteKeyBindings.Bindings.Add(new RemoteKeyBinding(RemoteBindingsComboBox.Text, 731 RemoteKeyBindings.Bindings.Add(new RemoteKeyBinding(RemoteBindingsComboBox.Text,
712 (string) RemoteBindingsListBox.SelectedItem, MouseKeyCombo)); 732 (string) RemoteBindingsListBox.SelectedItem, MouseKeyCombo));
713   733  
714 MouseKeyApplicationHook.KeyDown -= RemoteKeyHookOnKeyDown; 734 MouseKeyApplicationHook.KeyDown -= RemoteKeyHookOnKeyDown;
715 MouseKeyApplicationHook.KeyUp -= RemoteKeyHookOnKeyUp; 735 MouseKeyApplicationHook.KeyUp -= RemoteKeyHookOnKeyUp;
716   736  
717 MouseKeyApplicationHook.Dispose(); 737 MouseKeyApplicationHook.Dispose();
718   738  
719 RemoteBindingsBindToBox.Text = string.Join(" + ", MouseKeyCombo); 739 RemoteBindingsBindToBox.Text = string.Join(" + ", MouseKeyCombo);
720 HideOverlayPanel(); 740 HideOverlayPanel();
721   741  
722 await SaveRemoteMouseKeyBindings(); 742 await SaveRemoteMouseKeyBindings();
723 } 743 }
724   744  
725 private void RemoteBindingsListBoxSelectedValueChanged(object sender, EventArgs e) 745 private void RemoteBindingsListBoxSelectedValueChanged(object sender, EventArgs e)
726 { 746 {
727 RemoteBindingsBindToBox.Text = ""; 747 RemoteBindingsBindToBox.Text = "";
728   748  
729 var name = (string) RemoteBindingsListBox.SelectedItem; 749 var name = (string) RemoteBindingsListBox.SelectedItem;
730 if (string.IsNullOrEmpty(name)) 750 if (string.IsNullOrEmpty(name))
731 return; 751 return;
732   752  
733 var nick = RemoteBindingsComboBox.Text; 753 var nick = RemoteBindingsComboBox.Text;
734 if (string.IsNullOrEmpty(nick)) 754 if (string.IsNullOrEmpty(nick))
735 return; 755 return;
736   756  
737 foreach (var binding in RemoteKeyBindings.Bindings) 757 foreach (var binding in RemoteKeyBindings.Bindings)
738 { 758 {
739 if (!string.Equals(binding.Nick, nick) || !string.Equals(binding.Name, name)) 759 if (!string.Equals(binding.Nick, nick) || !string.Equals(binding.Name, name))
740 continue; 760 continue;
741   761  
742 RemoteBindingsBindToBox.Text = string.Join(" + ", binding.Keys); 762 RemoteBindingsBindToBox.Text = string.Join(" + ", binding.Keys);
743 break; 763 break;
744 } 764 }
745 } 765 }
746   766  
747 private void WingManFormResized(object sender, EventArgs e) 767 private void WingManFormResized(object sender, EventArgs e)
748 { 768 {
749 if (WindowState == FormWindowState.Minimized) Hide(); 769 if (WindowState == FormWindowState.Minimized) Hide();
750 } 770 }
751   771  
752 private void NotifyIconDoubleClick(object sender, EventArgs e) 772 private void NotifyIconDoubleClick(object sender, EventArgs e)
753 { 773 {
754 Show(); 774 Show();
755 WindowState = FormWindowState.Normal; 775 WindowState = FormWindowState.Normal;
756 } 776 }
757   777  
758 private async void LocalBindingsCheckedListBoxItemCheck(object sender, ItemCheckEventArgs e) 778 private async void LocalBindingsCheckedListBoxItemCheck(object sender, ItemCheckEventArgs e)
759 { 779 {
760 var helmBinding = (KeyBinding) LocalBindingsCheckedListBox.Items[e.Index]; 780 var helmBinding = (KeyBinding) LocalBindingsCheckedListBox.Items[e.Index];
761 if (helmBinding == null) 781 if (helmBinding == null)
762 return; 782 return;
763   783  
764 switch (e.NewValue) 784 switch (e.NewValue)
765 { 785 {
766 case CheckState.Checked: 786 case CheckState.Checked:
767 helmBinding.Enabled = true; 787 helmBinding.Enabled = true;
768 break; 788 break;
769 case CheckState.Unchecked: 789 case CheckState.Unchecked:
770 helmBinding.Enabled = false; 790 helmBinding.Enabled = false;
771 break; 791 break;
772 } 792 }
773   793  
774 await SaveLocalMouseKeyBindings(); 794 await SaveLocalMouseKeyBindings();
775 } 795 }
776   796  
777 private void WingManTabControlMouseDown(object sender, MouseEventArgs e) 797 private void WingManTabControlMouseDown(object sender, MouseEventArgs e)
778 { 798 {
779 if (e.Button != MouseButtons.Left) return; 799 if (e.Button != MouseButtons.Left) return;
780   800  
781 TabControlClickStartPosition = e.Location; 801 TabControlClickStartPosition = e.Location;
782 } 802 }
783   803  
784 private void WingManTabControlMouseMove(object sender, MouseEventArgs e) 804 private void WingManTabControlMouseMove(object sender, MouseEventArgs e)
785 { 805 {
786 if (e.Button == MouseButtons.Left) 806 if (e.Button == MouseButtons.Left)
787 { 807 {
788 var mouseOffsetX = TabControlClickStartPosition.X - e.X; 808 var mouseOffsetX = TabControlClickStartPosition.X - e.X;
789 var mouseOffsetY = TabControlClickStartPosition.Y - e.Y; 809 var mouseOffsetY = TabControlClickStartPosition.Y - e.Y;
790   810  
791 if (mouseOffsetX <= TabControlDetachPixelOffset && mouseOffsetY <= TabControlDetachPixelOffset) 811 if (mouseOffsetX <= TabControlDetachPixelOffset && mouseOffsetY <= TabControlDetachPixelOffset)
792 return; 812 return;
793   813  
794 tabControl1.DoDragDrop(tabControl1.SelectedTab, DragDropEffects.Move); 814 tabControl1.DoDragDrop(tabControl1.SelectedTab, DragDropEffects.Move);
795 TabControlClickStartPosition = new Point(); 815 TabControlClickStartPosition = new Point();
796   816  
797 return; 817 return;
798 } 818 }
799   819  
800 TabControlClickStartPosition = new Point(); 820 TabControlClickStartPosition = new Point();
801 } 821 }
802   822  
803 private void WingManTabControlGiveFeedback(object sender, GiveFeedbackEventArgs e) 823 private void WingManTabControlGiveFeedback(object sender, GiveFeedbackEventArgs e)
804 { 824 {
805 e.UseDefaultCursors = false; 825 e.UseDefaultCursors = false;
806 } 826 }
807   827  
808 private void WingManTabControlQueryContinueDrag(object sender, QueryContinueDragEventArgs e) 828 private void WingManTabControlQueryContinueDrag(object sender, QueryContinueDragEventArgs e)
809 { 829 {
810 if (MouseButtons != MouseButtons.Left) 830 if (MouseButtons != MouseButtons.Left)
811 { 831 {
812 e.Action = DragAction.Cancel; 832 e.Action = DragAction.Cancel;
813   833  
814 DetachedForm = new Form 834 DetachedForm = new Form
815 { 835 {
816 Size = new Size( 836 Size = new Size(
817 // Width = tab control width + tab control left and right margins + x-padding 837 // Width = tab control width + tab control left and right margins + x-padding
818 tabControl1.Width + 838 tabControl1.Width +
819 tabControl1.Margin.Right + 839 tabControl1.Margin.Right +
820 tabControl1.Margin.Left + 840 tabControl1.Margin.Left +
821 tabControl1.Padding.X, 841 tabControl1.Padding.X,
822 // Tab Height = tab control height - tab control tab page height 842 // Tab Height = tab control height - tab control tab page height
823 // Height = tab control height + Tab Height + top and bottom margin + x-padding 843 // Height = tab control height + Tab Height + top and bottom margin + x-padding
824 2 * tabControl1.Height - 844 2 * tabControl1.Height -
825 tabControl1.SelectedTab.Height + 845 tabControl1.SelectedTab.Height +
826 tabControl1.Margin.Top + 846 tabControl1.Margin.Top +
827 tabControl1.Margin.Bottom + 847 tabControl1.Margin.Bottom +
828 tabControl1.Padding.Y), 848 tabControl1.Padding.Y),
829 StartPosition = FormStartPosition.Manual, 849 StartPosition = FormStartPosition.Manual,
830 Location = MousePosition, 850 Location = MousePosition,
831 MaximizeBox = false, 851 MaximizeBox = false,
832 SizeGripStyle = SizeGripStyle.Hide, 852 SizeGripStyle = SizeGripStyle.Hide,
833 FormBorderStyle = FormBorderStyle.FixedSingle, 853 FormBorderStyle = FormBorderStyle.FixedSingle,
834 Name = Name, 854 Name = Name,
835 Text = Text, 855 Text = Text,
836 Icon = Icon 856 Icon = Icon
837 }; 857 };
838   858  
839 DetachedTabControl = new TabControl 859 DetachedTabControl = new TabControl
840 { 860 {
841 Dock = DockStyle.Fill, 861 Dock = DockStyle.Fill,
842 SizeMode = TabSizeMode.Fixed 862 SizeMode = TabSizeMode.Fixed
843 }; 863 };
844 DetachedTabControl.TabPages.Add(tabControl1.SelectedTab); 864 DetachedTabControl.TabPages.Add(tabControl1.SelectedTab);
845 DetachedForm.Controls.Add(DetachedTabControl); 865 DetachedForm.Controls.Add(DetachedTabControl);
846 DetachedForm.FormClosing += DetachedFormOnFormClosing; 866 DetachedForm.FormClosing += DetachedFormOnFormClosing;
847 DetachedForm.Show(); 867 DetachedForm.Show();
848 Cursor = Cursors.Default; 868 Cursor = Cursors.Default;
849 return; 869 return;
850 } 870 }
851   871  
852 e.Action = DragAction.Continue; 872 e.Action = DragAction.Continue;
853 Cursor = Cursors.SizeAll; 873 Cursor = Cursors.SizeAll;
854 } 874 }
855   875  
856 private void DetachedFormOnFormClosing(object sender, FormClosingEventArgs e) 876 private void DetachedFormOnFormClosing(object sender, FormClosingEventArgs e)
857 { 877 {
858 tabControl1.TabPages.Insert(DetachedTabControl.SelectedTab.TabIndex, DetachedTabControl.SelectedTab); 878 tabControl1.TabPages.Insert(DetachedTabControl.SelectedTab.TabIndex, DetachedTabControl.SelectedTab);
859 DetachedForm.FormClosing -= DetachedFormOnFormClosing; 879 DetachedForm.FormClosing -= DetachedFormOnFormClosing;
860 } 880 }
-   881  
-   882 private void LocalBindingsLoadButtonClicked(object sender, EventArgs e)
-   883 {
-   884 loadLocalBindingsDialog.ShowDialog();
-   885 }
-   886  
-   887 private void LocalBindingsSaveButtonClicked(object sender, EventArgs e)
-   888 {
-   889 saveLocalBindingsDialog.ShowDialog();
-   890 }
-   891  
-   892 private async void SaveLocalBindingsDialogOk(object sender, CancelEventArgs e)
-   893 {
-   894 using (var localBindingsStream = saveLocalBindingsDialog.OpenFile())
-   895 {
-   896 using (var memoryStream = new MemoryStream())
-   897 {
-   898 LocalKeyBindings.XmlSerializer.Serialize(memoryStream, LocalKeyBindings);
-   899  
-   900 memoryStream.Position = 0L;
-   901  
-   902 await memoryStream.CopyToAsync(localBindingsStream);
-   903 }
-   904 }
-   905 }
-   906  
-   907 private async void LoadLocalBindingsDialogOk(object sender, CancelEventArgs e)
-   908 {
-   909 using (var localBindingsStream = loadLocalBindingsDialog.OpenFile())
-   910 {
-   911 var loadedBindings = (LocalKeyBindings) LocalKeyBindings.XmlSerializer.Deserialize(localBindingsStream);
-   912  
-   913 LocalKeyBindings.Bindings.Clear();
-   914  
-   915 foreach (var binding in loadedBindings.Bindings)
-   916 LocalKeyBindings.Bindings.Add(binding);
-   917  
-   918 LocalCheckedListBoxBindingSource.ResetBindings(false);
-   919 }
-   920  
-   921 await SaveLocalMouseKeyBindings();
-   922 }
-   923  
-   924 private void SettingsWindowsStartupCheckboxCheckedChanged(object sender, EventArgs e)
-   925 {
-   926 try
-   927 {
-   928 switch (((CheckBox) sender).Checked)
-   929 {
-   930 case true:
-   931 using (var key = Registry.CurrentUser.OpenSubKey
-   932 ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
-   933 {
-   934 key.SetValue(Name, Assembly.GetEntryAssembly().Location);
-   935 }
-   936  
-   937 break;
-   938 default:
-   939 using (var key = Registry.CurrentUser.OpenSubKey
-   940 ("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
-   941 {
-   942 key.DeleteValue(Name, false);
-   943 }
-   944  
-   945 break;
-   946 }
-   947  
-   948 ActivityTextBox.AppendText(
-   949 $"{Strings.Application_Windows_startup_changed}{Environment.NewLine}");
-   950 }
-   951 catch
-   952 {
-   953 ActivityTextBox.AppendText(
-   954 $"{Strings.Could_not_change_Windows_startup}{Environment.NewLine}");
-   955 }
-   956 }
861   957  
862 #region Saving and loading 958 #region Saving and loading
863   959  
864 private async Task SaveLocalMouseKeyBindings() 960 private async Task SaveLocalMouseKeyBindings()
865 { 961 {
866 try 962 try
867 { 963 {
868 using (var memoryStream = new MemoryStream()) 964 using (var memoryStream = new MemoryStream())
869 { 965 {
870 LocalKeyBindings.XmlSerializer.Serialize(memoryStream, LocalKeyBindings); 966 LocalKeyBindings.XmlSerializer.Serialize(memoryStream, LocalKeyBindings);
871   967  
872 memoryStream.Position = 0L; 968 memoryStream.Position = 0L;
873   969  
874 using (var fileStream = new FileStream("LocalKeyBindings.xml", FileMode.Create)) 970 using (var fileStream = new FileStream("LocalKeyBindings.xml", FileMode.Create))
875 { 971 {
876 await memoryStream.CopyToAsync(fileStream); 972 await memoryStream.CopyToAsync(fileStream);
877 } 973 }
878 } 974 }
879 } 975 }
880 catch (Exception) 976 catch (Exception)
881 { 977 {
882 ActivityTextBox.AppendText( 978 ActivityTextBox.AppendText(
883 $"{Strings.Failed_saving_local_bindings}{Environment.NewLine}"); 979 $"{Strings.Failed_saving_local_bindings}{Environment.NewLine}");
884 } 980 }
885 } 981 }
886   982  
887 private async Task LoadLocalMouseKeyBindings() 983 private async Task LoadLocalKeyBindings()
888 { 984 {
889 try 985 try
890 { 986 {
891 using (var fileStream = new FileStream("LocalKeyBindings.xml", FileMode.Open)) 987 using (var fileStream = new FileStream("LocalKeyBindings.xml", FileMode.Open))
892 { 988 {
893 using (var memoryStream = new MemoryStream()) 989 using (var memoryStream = new MemoryStream())
894 { 990 {
895 await fileStream.CopyToAsync(memoryStream); 991 await fileStream.CopyToAsync(memoryStream);
896   992  
897 memoryStream.Position = 0L; 993 memoryStream.Position = 0L;
898   994  
899 var loadedBindings = 995 var loadedBindings =
900 (LocalKeyBindings) LocalKeyBindings.XmlSerializer.Deserialize(memoryStream); 996 (LocalKeyBindings) LocalKeyBindings.XmlSerializer.Deserialize(memoryStream);
901   997  
902 foreach (var binding in loadedBindings.Bindings) 998 foreach (var binding in loadedBindings.Bindings)
903 LocalKeyBindings.Bindings.Add(binding); 999 LocalKeyBindings.Bindings.Add(binding);
904   -  
905   1000  
906 LocalCheckedListBoxBindingSource.ResetBindings(false); 1001 LocalCheckedListBoxBindingSource.ResetBindings(false);
907 } 1002 }
908 } 1003 }
909 } 1004 }
910 catch (Exception) 1005 catch (Exception)
911 { 1006 {
912 ActivityTextBox.AppendText( 1007 ActivityTextBox.AppendText(
913 $"{Strings.Failed_loading_local_bindings}{Environment.NewLine}"); 1008 $"{Strings.Failed_loading_local_bindings}{Environment.NewLine}");
914 } 1009 }
915 } 1010 }
916   1011  
917 private async Task SaveRemoteMouseKeyBindings() 1012 private async Task SaveRemoteMouseKeyBindings()
918 { 1013 {
919 try 1014 try
920 { 1015 {
921 using (var memoryStream = new MemoryStream()) 1016 using (var memoryStream = new MemoryStream())
922 { 1017 {
923 RemoteKeyBindings.XmlSerializer.Serialize(memoryStream, RemoteKeyBindings); 1018 RemoteKeyBindings.XmlSerializer.Serialize(memoryStream, RemoteKeyBindings);
924   1019  
925 memoryStream.Position = 0L; 1020 memoryStream.Position = 0L;
926   1021  
927 using (var fileStream = new FileStream("RemoteKeyBindings.xml", FileMode.Create)) 1022 using (var fileStream = new FileStream("RemoteKeyBindings.xml", FileMode.Create))
928 { 1023 {
929 await memoryStream.CopyToAsync(fileStream); 1024 await memoryStream.CopyToAsync(fileStream);
930 } 1025 }
931 } 1026 }
932 } 1027 }
933 catch (Exception) 1028 catch (Exception)
934 { 1029 {
935 ActivityTextBox.AppendText( 1030 ActivityTextBox.AppendText(
936 $"{Strings.Failed_saving_remote_bindings}{Environment.NewLine}"); 1031 $"{Strings.Failed_saving_remote_bindings}{Environment.NewLine}");
937 } 1032 }
938 } 1033 }
939   1034  
940 private async Task LoadRemoteMouseKeyBindings() 1035 private async Task LoadRemoteKeyBindings()
941 { 1036 {
942 try 1037 try
943 { 1038 {
944 using (var fileStream = new FileStream("RemoteKeyBindings.xml", FileMode.Open)) 1039 using (var fileStream = new FileStream("RemoteKeyBindings.xml", FileMode.Open))
945 { 1040 {
946 using (var memoryStream = new MemoryStream()) 1041 using (var memoryStream = new MemoryStream())
947 { 1042 {
948 await fileStream.CopyToAsync(memoryStream); 1043 await fileStream.CopyToAsync(memoryStream);
949   1044  
950 memoryStream.Position = 0L; 1045 memoryStream.Position = 0L;
951   1046  
952 var loadedBindings = 1047 var loadedBindings =
953 (RemoteKeyBindings) RemoteKeyBindings.XmlSerializer.Deserialize(memoryStream); 1048 (RemoteKeyBindings) RemoteKeyBindings.XmlSerializer.Deserialize(memoryStream);
954   1049  
955 foreach (var binding in loadedBindings.Bindings) 1050 foreach (var binding in loadedBindings.Bindings)
956 RemoteKeyBindings.Bindings.Add(binding); 1051 RemoteKeyBindings.Bindings.Add(binding);
957 } 1052 }
958 } 1053 }
959 } 1054 }
960 catch (Exception) 1055 catch (Exception)
961 { 1056 {
962 ActivityTextBox.AppendText( 1057 ActivityTextBox.AppendText(
963 $"{Strings.Failed_loading_remote_bindings}{Environment.NewLine}"); 1058 $"{Strings.Failed_loading_remote_bindings}{Environment.NewLine}");
964 } 1059 }
965 } 1060 }
966   1061  
967 #endregion 1062 #endregion
968 } 1063 }
969 } 1064 }
970   1065