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