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