WingMan – Blame information for rev 7
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | using System; |
2 | using System.Collections.Generic; |
||
3 | using System.Drawing; |
||
4 | using System.Linq; |
||
5 | using System.Net; |
||
7 | office | 6 | using System.Threading; |
6 | office | 7 | using System.Threading.Tasks; |
1 | office | 8 | using System.Windows.Forms; |
4 | office | 9 | using Gma.System.MouseKeyHook; |
1 | office | 10 | using WingMan.Communication; |
7 | office | 11 | using WingMan.Lobby; |
5 | office | 12 | using WingMan.MouseKey; |
13 | using WingMan.Properties; |
||
1 | office | 14 | |
15 | namespace WingMan |
||
16 | { |
||
2 | office | 17 | public partial class WingManForm : Form |
1 | office | 18 | { |
5 | office | 19 | public WingManForm() |
20 | { |
||
21 | InitializeComponent(); |
||
1 | office | 22 | |
6 | office | 23 | FormTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); |
7 | office | 24 | FormCancellationTokenSource = new CancellationTokenSource(); |
1 | office | 25 | |
7 | office | 26 | MQTTCommunication = new MQTTCommunication(FormTaskScheduler, FormCancellationTokenSource.Token); |
6 | office | 27 | |
5 | office | 28 | MouseKeyBindings = new MouseKeyBindings(new List<MouseKeyBinding>()); |
1 | office | 29 | |
7 | office | 30 | HelmListBoxBindingSource = new BindingSource |
5 | office | 31 | { |
32 | DataSource = MouseKeyBindings.Bindings |
||
33 | }; |
||
34 | HelmBindingsListBox.DisplayMember = "DisplayName"; |
||
35 | HelmBindingsListBox.ValueMember = "Keys"; |
||
7 | office | 36 | HelmBindingsListBox.DataSource = HelmListBoxBindingSource; |
1 | office | 37 | |
7 | office | 38 | MouseKeyBindingsExchange = new MouseKeyBindingsExchange |
5 | office | 39 | { |
7 | office | 40 | ExchangeBindings = new List<MouseKeyBindingExchange>() |
41 | }; |
||
42 | |||
43 | WingBindingsComboBoxSource = new BindingSource |
||
44 | { |
||
5 | office | 45 | DataSource = MouseKeyBindingsExchange.ExchangeBindings |
46 | }; |
||
47 | WingBindingsComboBox.DisplayMember = "Nick"; |
||
7 | office | 48 | WingBindingsComboBox.ValueMember = "MouseKeyBindings"; |
49 | WingBindingsComboBox.DataSource = WingBindingsComboBoxSource; |
||
4 | office | 50 | |
5 | office | 51 | // Start lobby message synchronizer. |
7 | office | 52 | LobbyMessageSynchronizer = new LobbyMessageSynchronizer(MQTTCommunication, FormTaskScheduler, |
53 | FormCancellationTokenSource.Token); |
||
5 | office | 54 | LobbyMessageSynchronizer.OnLobbyMessageReceived += OnLobbyMessageReceived; |
4 | office | 55 | |
5 | office | 56 | // Start mouse key bindings synchronizer. |
7 | office | 57 | MouseKeyBindingsSynchronizer = new MouseKeyBindingsSynchronizer(MouseKeyBindings, MQTTCommunication, |
58 | FormTaskScheduler, FormCancellationTokenSource.Token); |
||
5 | office | 59 | MouseKeyBindingsSynchronizer.OnMouseKeyBindingsSynchronized += OnMouseKeyBindingsSynchronized; |
60 | } |
||
4 | office | 61 | |
7 | office | 62 | private static CancellationTokenSource FormCancellationTokenSource { get; set; } |
4 | office | 63 | |
7 | office | 64 | private static TaskScheduler FormTaskScheduler { get; set; } |
4 | office | 65 | |
7 | office | 66 | private static IKeyboardMouseEvents MouseKeyApplicationHook { get; set; } |
4 | office | 67 | |
7 | office | 68 | private List<string> MouseKeyCombo { get; set; } |
2 | office | 69 | |
7 | office | 70 | private MouseKeyBindings MouseKeyBindings { get; } |
4 | office | 71 | |
7 | office | 72 | private BindingSource HelmListBoxBindingSource { get; } |
4 | office | 73 | |
7 | office | 74 | private BindingSource WingBindingsComboBoxSource { get; } |
4 | office | 75 | |
7 | office | 76 | private MouseKeyBindingsExchange MouseKeyBindingsExchange { get; } |
77 | |||
78 | public MQTTCommunication MQTTCommunication { get; set; } |
||
79 | |||
80 | public LobbyMessageSynchronizer LobbyMessageSynchronizer { get; set; } |
||
81 | |||
82 | public MouseKeyBindingsSynchronizer MouseKeyBindingsSynchronizer { get; set; } |
||
83 | |||
84 | /// <summary> |
||
85 | /// Clean up any resources being used. |
||
86 | /// </summary> |
||
87 | /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> |
||
88 | protected override void Dispose(bool disposing) |
||
89 | { |
||
90 | if (disposing && components != null) |
||
91 | { |
||
92 | FormCancellationTokenSource.Dispose(); |
||
93 | FormCancellationTokenSource = null; |
||
94 | |||
95 | components.Dispose(); |
||
6 | office | 96 | } |
4 | office | 97 | |
7 | office | 98 | base.Dispose(disposing); |
1 | office | 99 | } |
100 | |||
7 | office | 101 | private void OnMouseKeyBindingsSynchronized(object sender, MouseKeyBindingsSynchronizedEventArgs e) |
102 | { |
||
103 | ActivityTextBox.AppendText( |
||
104 | $"{Strings.Synchronized_bindings_with_client} : {e.Bindings.Nick} : {e.Bindings.MouseKeyBindings.Count}{Environment.NewLine}"); |
||
6 | office | 105 | |
7 | office | 106 | var exchangeBindings = MouseKeyBindingsExchange.ExchangeBindings.FirstOrDefault(exchangeBinding => |
107 | string.Equals(exchangeBinding.Nick, e.Bindings.Nick, StringComparison.Ordinal)); |
||
5 | office | 108 | |
7 | office | 109 | // If the nick does not exist then add it. |
110 | if (exchangeBindings == null) |
||
111 | { |
||
112 | MouseKeyBindingsExchange.ExchangeBindings.Add(e.Bindings); |
||
113 | WingBindingsComboBoxSource.ResetBindings(false); |
||
114 | UpdateWingListBoxItems(); |
||
115 | return; |
||
116 | } |
||
5 | office | 117 | |
7 | office | 118 | // If the bindings for the nick have not changed then do not update. |
119 | if (exchangeBindings.MouseKeyBindings.SequenceEqual(e.Bindings.MouseKeyBindings)) |
||
120 | { |
||
121 | WingBindingsComboBoxSource.ResetBindings(false); |
||
122 | UpdateWingListBoxItems(); |
||
123 | return; |
||
124 | } |
||
5 | office | 125 | |
7 | office | 126 | // Update the bindings. |
127 | exchangeBindings.MouseKeyBindings = e.Bindings.MouseKeyBindings; |
||
128 | WingBindingsComboBoxSource.ResetBindings(false); |
||
129 | UpdateWingListBoxItems(); |
||
130 | } |
||
5 | office | 131 | |
7 | office | 132 | private void UpdateWingListBoxItems() |
133 | { |
||
134 | var exchangeBinding = (List<MouseKeyBinding>) WingBindingsComboBox.SelectedValue; |
||
135 | if (exchangeBinding == null) |
||
136 | return; |
||
5 | office | 137 | |
7 | office | 138 | WingBindingsListBox.Items.Clear(); |
139 | WingBindingsListBox.DisplayMember = "Name"; |
||
140 | WingBindingsListBox.ValueMember = "Name"; |
||
141 | var i = exchangeBinding.Select(binding => (object) binding.Name).ToArray(); |
||
142 | if (i.Length == 0) |
||
143 | return; |
||
5 | office | 144 | |
7 | office | 145 | WingBindingsListBox.Items.AddRange(i); |
146 | } |
||
5 | office | 147 | |
148 | private void OnLobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e) |
||
149 | { |
||
150 | LobbyTextBox.Invoke((MethodInvoker) delegate |
||
151 | { |
||
152 | LobbyTextBox.AppendText($"{e.Nick} : {e.Message}{Environment.NewLine}"); |
||
153 | }); |
||
154 | } |
||
155 | |||
1 | office | 156 | private void AddressTextBoxClick(object sender, EventArgs e) |
157 | { |
||
158 | Address.BackColor = Color.Empty; |
||
159 | } |
||
160 | |||
161 | private void PortTextBoxClick(object sender, EventArgs e) |
||
162 | { |
||
163 | Port.BackColor = Color.Empty; |
||
164 | } |
||
165 | |||
166 | private async void HostButtonClickAsync(object sender, EventArgs e) |
||
167 | { |
||
168 | // Stop the MQTT server if it is running. |
||
5 | office | 169 | if (MQTTCommunication.Running) |
1 | office | 170 | { |
5 | office | 171 | await MQTTCommunication.Stop().ConfigureAwait(false); |
172 | toolStripStatusLabel.Text = Strings.Server_stopped; |
||
1 | office | 173 | HostButton.BackColor = Color.Empty; |
174 | |||
3 | office | 175 | // Enable controls. |
1 | office | 176 | ConnectButton.Enabled = true; |
5 | office | 177 | Address.Enabled = true; |
178 | Port.Enabled = true; |
||
179 | Nick.Enabled = true; |
||
180 | |||
1 | office | 181 | return; |
182 | } |
||
183 | |||
2 | office | 184 | if (!ValidateAddressPort(out var ipAddress, out var port, out var nick)) |
1 | office | 185 | return; |
186 | |||
187 | // Start the MQTT server. |
||
5 | office | 188 | await MQTTCommunication.Start(MQTTCommunicationType.Server, ipAddress, port, nick).ConfigureAwait(false); |
189 | toolStripStatusLabel.Text = Strings.Server_started; |
||
1 | office | 190 | HostButton.BackColor = Color.Aquamarine; |
191 | |||
3 | office | 192 | // Disable controls |
1 | office | 193 | ConnectButton.Enabled = false; |
3 | office | 194 | Address.Enabled = false; |
195 | Port.Enabled = false; |
||
196 | Nick.Enabled = false; |
||
197 | } |
||
198 | |||
2 | office | 199 | private bool ValidateAddressPort(out IPAddress address, out int port, out string nick) |
1 | office | 200 | { |
201 | address = IPAddress.Any; |
||
202 | port = 0; |
||
2 | office | 203 | nick = string.Empty; |
1 | office | 204 | |
205 | if (string.IsNullOrEmpty(Address.Text) && |
||
2 | office | 206 | string.IsNullOrEmpty(Port.Text) && |
207 | string.IsNullOrEmpty(Nick.Text)) |
||
1 | office | 208 | { |
209 | Address.BackColor = Color.LightPink; |
||
210 | Port.BackColor = Color.LightPink; |
||
2 | office | 211 | Nick.BackColor = Color.LightPink; |
1 | office | 212 | return false; |
213 | } |
||
214 | |||
215 | if (!IPAddress.TryParse(Address.Text, out address)) |
||
216 | { |
||
217 | Address.BackColor = Color.LightPink; |
||
218 | return false; |
||
219 | } |
||
220 | |||
221 | if (!uint.TryParse(Port.Text, out var uPort)) |
||
222 | { |
||
223 | Port.BackColor = Color.LightPink; |
||
224 | return false; |
||
225 | } |
||
226 | |||
227 | port = (int) uPort; |
||
228 | |||
2 | office | 229 | if (string.IsNullOrEmpty(Nick.Text)) |
230 | { |
||
231 | Nick.BackColor = Color.LightPink; |
||
232 | return false; |
||
233 | } |
||
234 | |||
235 | nick = Nick.Text; |
||
236 | |||
1 | office | 237 | Address.BackColor = Color.Empty; |
238 | Port.BackColor = Color.Empty; |
||
2 | office | 239 | Nick.BackColor = Color.Empty; |
1 | office | 240 | |
241 | return true; |
||
242 | } |
||
243 | |||
244 | private async void ConnectButtonClickAsync(object sender, EventArgs e) |
||
245 | { |
||
5 | office | 246 | if (MQTTCommunication.Running) |
1 | office | 247 | { |
5 | office | 248 | await MQTTCommunication.Stop().ConfigureAwait(false); |
249 | ConnectButton.Text = Strings.Connect; |
||
1 | office | 250 | ConnectButton.BackColor = Color.Empty; |
251 | |||
5 | office | 252 | Address.Enabled = true; |
253 | Port.Enabled = true; |
||
254 | Nick.Enabled = true; |
||
1 | office | 255 | HostButton.Enabled = true; |
256 | return; |
||
257 | } |
||
258 | |||
2 | office | 259 | if (!ValidateAddressPort(out var ipAddress, out var port, out var nick)) |
1 | office | 260 | return; |
261 | |||
5 | office | 262 | await MQTTCommunication.Start(MQTTCommunicationType.Client, ipAddress, port, nick).ConfigureAwait(false); |
1 | office | 263 | |
5 | office | 264 | toolStripStatusLabel.Text = Strings.Client_started; |
265 | ConnectButton.Text = Strings.Disconnect; |
||
1 | office | 266 | ConnectButton.BackColor = Color.Aquamarine; |
267 | |||
268 | HostButton.Enabled = false; |
||
5 | office | 269 | Address.Enabled = false; |
270 | Port.Enabled = false; |
||
271 | Nick.Enabled = false; |
||
1 | office | 272 | } |
273 | |||
2 | office | 274 | private async void LobbySayTextBoxKeyDown(object sender, KeyEventArgs e) |
275 | { |
||
276 | if (e.KeyCode != Keys.Enter) |
||
277 | return; |
||
278 | |||
5 | office | 279 | await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text).ConfigureAwait(false); |
2 | office | 280 | |
5 | office | 281 | LobbySayTextBox.Text = string.Empty; |
2 | office | 282 | } |
4 | office | 283 | |
284 | private void HelmAddButtonClick(object sender, EventArgs e) |
||
285 | { |
||
286 | if (string.IsNullOrEmpty(HelmNameTextBox.Text)) |
||
287 | { |
||
288 | HelmNameTextBox.BackColor = Color.LightPink; |
||
289 | return; |
||
290 | } |
||
291 | |||
292 | HelmAddButton.Enabled = false; |
||
293 | |||
294 | MouseKeyCombo = new List<string>(); |
||
295 | |||
296 | MouseKeyApplicationHook = Hook.AppEvents(); |
||
297 | MouseKeyApplicationHook.MouseDown += MouseKeyHookOnMouseDown; |
||
298 | MouseKeyApplicationHook.KeyUp += MouseKeyHookOnKeyUp; |
||
299 | MouseKeyApplicationHook.KeyDown += MouseKeyHookOnKeyDown; |
||
300 | MouseKeyApplicationHook.MouseUp += MouseKeyHookOnMouseUp; |
||
301 | } |
||
302 | |||
303 | private void MouseKeyHookOnKeyUp(object sender, KeyEventArgs e) |
||
304 | { |
||
5 | office | 305 | MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo)); |
4 | office | 306 | |
7 | office | 307 | HelmListBoxBindingSource.ResetBindings(false); |
4 | office | 308 | |
309 | MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown; |
||
310 | MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp; |
||
5 | office | 311 | MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown; |
312 | MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp; |
||
4 | office | 313 | |
314 | MouseKeyApplicationHook.Dispose(); |
||
315 | |||
316 | HelmNameTextBox.Text = string.Empty; |
||
317 | HelmAddButton.Enabled = true; |
||
318 | } |
||
319 | |||
320 | private void MouseKeyHookOnMouseUp(object sender, MouseEventArgs e) |
||
321 | { |
||
5 | office | 322 | MouseKeyBindings.Bindings.Add(new MouseKeyBinding(HelmNameTextBox.Text, MouseKeyCombo)); |
4 | office | 323 | |
7 | office | 324 | HelmListBoxBindingSource.ResetBindings(false); |
4 | office | 325 | |
326 | MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown; |
||
327 | MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp; |
||
5 | office | 328 | MouseKeyApplicationHook.KeyDown -= MouseKeyHookOnKeyDown; |
329 | MouseKeyApplicationHook.KeyUp -= MouseKeyHookOnKeyUp; |
||
4 | office | 330 | |
331 | MouseKeyApplicationHook.Dispose(); |
||
332 | |||
333 | HelmNameTextBox.Text = string.Empty; |
||
334 | HelmAddButton.Enabled = true; |
||
335 | } |
||
336 | |||
337 | |||
338 | private void MouseKeyHookOnMouseDown(object sender, MouseEventArgs e) |
||
339 | { |
||
5 | office | 340 | MouseKeyCombo.Add(e.Button.ToDisplayName()); |
4 | office | 341 | } |
342 | |||
343 | private void MouseKeyHookOnKeyDown(object sender, KeyEventArgs e) |
||
344 | { |
||
345 | e.SuppressKeyPress = true; |
||
346 | |||
5 | office | 347 | MouseKeyCombo.Add(e.KeyCode.ToDisplayName()); |
4 | office | 348 | } |
349 | |||
350 | private void HelmNameTextBoxClick(object sender, EventArgs e) |
||
351 | { |
||
352 | HelmNameTextBox.BackColor = Color.Empty; |
||
353 | } |
||
354 | |||
5 | office | 355 | private void HelmRemoveButtonClick(object sender, EventArgs e) |
4 | office | 356 | { |
5 | office | 357 | var helmBinding = (MouseKeyBinding) HelmBindingsListBox.SelectedItem; |
358 | if (helmBinding == null) |
||
359 | return; |
||
4 | office | 360 | |
5 | office | 361 | MouseKeyBindings.Bindings.Remove(helmBinding); |
7 | office | 362 | HelmListBoxBindingSource.ResetBindings(false); |
4 | office | 363 | } |
364 | |||
5 | office | 365 | private async void LobbySayButtonClick(object sender, EventArgs e) |
4 | office | 366 | { |
5 | office | 367 | await LobbyMessageSynchronizer.Broadcast(LobbySayTextBox.Text).ConfigureAwait(false); |
4 | office | 368 | |
5 | office | 369 | LobbySayTextBox.Text = string.Empty; |
4 | office | 370 | } |
371 | |||
6 | office | 372 | private void WingBindingsComboBoxSelectionChangeCompleted(object sender, EventArgs e) |
4 | office | 373 | { |
7 | office | 374 | UpdateWingListBoxItems(); |
4 | office | 375 | } |
1 | office | 376 | } |
377 | } |