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