Hush – Diff between revs 1 and 2
?pathlinks?
Rev 1 | Rev 2 | |||
---|---|---|---|---|
Line 6... | Line 6... | |||
6 | using System.Linq; |
6 | using System.Linq; |
|
7 | using System.Net; |
7 | using System.Net; |
|
8 | using System.Threading; |
8 | using System.Threading; |
|
9 | using System.Threading.Tasks; |
9 | using System.Threading.Tasks; |
|
10 | using System.Windows.Forms; |
10 | using System.Windows.Forms; |
|
- | 11 | using Gma.System.MouseKeyHook; |
||
- | 12 | using Hush.Chat; |
||
11 | using Hush.Communication; |
13 | using Hush.Communication; |
|
12 | using Hush.Discovery; |
14 | using Hush.Discovery; |
|
13 | using Hush.Lobby; |
- | ||
14 | using Hush.Properties; |
15 | using Hush.Properties; |
|
15 | using Hush.Utilities; |
16 | using Hush.Utilities; |
|
16 | using WingMan.Communication; |
17 | using WingMan.Communication; |
|
- | 18 | using Message = System.Windows.Forms.Message; |
||
Line 17... | Line 19... | |||
17 | |
19 | |
|
18 | namespace Hush |
20 | namespace Hush |
|
19 | { |
21 | { |
|
20 | public partial class Hush : Form |
22 | public partial class Hush : Form |
|
Line 24... | Line 26... | |||
24 | InitializeComponent(); |
26 | InitializeComponent(); |
|
Line 25... | Line 27... | |||
25 | |
27 | |
|
26 | FormTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); |
28 | FormTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); |
|
Line -... | Line 29... | |||
- | 29 | FormCancellationTokenSource = new CancellationTokenSource(); |
||
- | 30 | |
||
- | 31 | // Initialize a message buffer. |
||
27 | FormCancellationTokenSource = new CancellationTokenSource(); |
32 | Messages = new List<string>(); |
|
28 | |
33 | |
|
29 | // Bind to settings changed event. |
34 | // Bind to settings changed event. |
|
30 | Settings.Default.SettingsLoaded += DefaultOnSettingsLoaded; |
35 | Settings.Default.SettingsLoaded += DefaultOnSettingsLoaded; |
|
Line -... | Line 36... | |||
- | 36 | Settings.Default.SettingsSaving += DefaultOnSettingsSaving; |
||
- | 37 | Settings.Default.PropertyChanged += DefaultOnPropertyChanged; |
||
- | 38 | |
||
- | 39 | // Set up keyboard hook. |
||
31 | Settings.Default.SettingsSaving += DefaultOnSettingsSaving; |
40 | MouseKeyGlobalHook = Hook.GlobalEvents(); |
|
32 | Settings.Default.PropertyChanged += DefaultOnPropertyChanged; |
41 | MouseKeyGlobalHook.KeyDown += MouseKeyGlobalHookOnKeyDown; |
|
33 | |
42 | |
|
34 | // Set up discovery. |
43 | // Set up discovery. |
|
Line 35... | Line 44... | |||
35 | Discovery = new Discovery.Discovery(Constants.ASSEMBLY_NAME, FormCancellationTokenSource, |
44 | Discovery = new Discovery.Discovery(Constants.AssemblyName, FormCancellationTokenSource.Token, |
|
36 | FormTaskScheduler); |
45 | FormTaskScheduler); |
|
- | 46 | Discovery.OnPortMapFailed += OnDiscoveryPortMapFailed; |
||
37 | Discovery.OnPortMapFailed += OnDiscoveryPortMapFailed; |
47 | |
|
Line 38... | Line 48... | |||
38 | |
48 | // Bind to MQTT events. |
|
39 | // Bind to MQTT events. |
49 | MqttCommunication = new MqttCommunication(FormTaskScheduler, FormCancellationTokenSource.Token); |
|
40 | MqttCommunication = new MqttCommunication(FormTaskScheduler, FormCancellationTokenSource.Token); |
50 | // TODO implement events. |
|
41 | //mqttCommunication. |
51 | //MqttCommunication. |
|
42 | |
52 | |
|
Line -... | Line 53... | |||
- | 53 | // Start message synchronizer. |
||
43 | // Start lobby message synchronizer. |
54 | ChatMessageSynchronizer = new ChatMessageSynchronizer(Constants.MqttTopic, MqttCommunication, FormTaskScheduler, |
|
44 | LobbyMessageSynchronizer = new LobbyMessageSynchronizer(MqttCommunication, FormTaskScheduler, |
55 | FormCancellationTokenSource.Token); |
|
45 | FormCancellationTokenSource.Token); |
56 | ChatMessageSynchronizer.OnMessageReceived += OnMessageReceived; |
|
46 | LobbyMessageSynchronizer.OnLobbyMessageReceived += OnLobbyMessageReceived; |
57 | } |
|
47 | } |
58 | |
|
- | 59 | private static IKeyboardMouseEvents MouseKeyGlobalHook { get; set; } |
||
- | 60 | private static TaskScheduler FormTaskScheduler { get; set; } |
||
- | 61 | private static CancellationTokenSource FormCancellationTokenSource { get; set; } |
||
- | 62 | private static MqttCommunication MqttCommunication { get; set; } |
||
- | 63 | private static ChatMessageSynchronizer ChatMessageSynchronizer { get; set; } |
||
- | 64 | private static Discovery.Discovery Discovery { get; set; } |
||
- | 65 | private static List<string> Messages { get; set; } |
||
- | 66 | |
||
- | 67 | private void MouseKeyGlobalHookOnKeyDown(object sender, KeyEventArgs keyEventArgs) |
||
- | 68 | { |
||
- | 69 | // Bind to CTRL+C |
||
Line 48... | Line 70... | |||
48 | |
70 | if (!keyEventArgs.Control || keyEventArgs.KeyCode != Keys.C) |
|
49 | private static TaskScheduler FormTaskScheduler { get; set; } |
71 | return; |
|
50 | private static CancellationTokenSource FormCancellationTokenSource { get; set; } |
72 | |
|
51 | private static MqttCommunication MqttCommunication { get; set; } |
73 | ActiveControl = messageTextBox; |
|
52 | private static LobbyMessageSynchronizer LobbyMessageSynchronizer { get; set; } |
74 | messageTextBox.Focus(); |
|
53 | private static Discovery.Discovery Discovery { get; set; } |
75 | } |
|
54 | |
76 | |
|
Line 55... | Line 77... | |||
55 | private void OnDiscoveryPortMapFailed(object sender, DiscoveryFailedEventArgs args) |
77 | private void OnDiscoveryPortMapFailed(object sender, DiscoveryFailedEventArgs args) |
|
56 | { |
78 | { |
|
- | 79 | notifyIcon1.BalloonTipIcon = ToolTipIcon.Warning; |
||
- | 80 | notifyIcon1.BalloonTipTitle = Strings.Network_warning; |
||
- | 81 | notifyIcon1.BalloonTipText = Strings.Failed_to_create_automatic_NAT_port_mapping; |
||
- | 82 | notifyIcon1.ShowBalloonTip(1000); |
||
- | 83 | } |
||
- | 84 | |
||
- | 85 | private void OnMessageReceived(object sender, ChatMessageReceivedEventArgs e) |
||
- | 86 | { |
||
- | 87 | var message = $"{e.Nick} : {e.Message}"; |
||
- | 88 | |
||
- | 89 | Messages.Add(message); |
||
57 | notifyIcon1.BalloonTipIcon = ToolTipIcon.Warning; |
90 | |
|
58 | notifyIcon1.BalloonTipTitle = Strings.Network_warning; |
91 | // Keep the content of the text box limited to the size of the displayed text. |
|
Line 59... | Line 92... | |||
59 | notifyIcon1.BalloonTipText = Strings.Failed_to_create_automatic_NAT_port_mapping; |
92 | var lineHeight = TextRenderer.MeasureText(message, chatTextBox.Font).Height; |
|
60 | notifyIcon1.ShowBalloonTip(1000); |
93 | var linesPerPage = (int) Math.Ceiling(1.0f * chatTextBox.ClientSize.Height / lineHeight); |
|
61 | } |
94 | |
|
62 | |
95 | if (Messages.Count > linesPerPage) |
|
Line 63... | Line 96... | |||
63 | private void OnLobbyMessageReceived(object sender, LobbyMessageReceivedEventArgs e) |
96 | Messages.RemoveRange(0, Messages.Count - 1 - linesPerPage); |
|
64 | { |
97 | |
|
65 | LobbyTextBox.AppendText($"{e.Nick} : {e.Message}{Environment.NewLine}"); |
98 | chatTextBox.Text = string.Join(Environment.NewLine, Messages); |
|
Line 66... | Line 99... | |||
66 | } |
99 | } |
|
67 | |
100 | |
|
Line 144... | Line 177... | |||
144 | private async Task StartClient() |
177 | private async Task StartClient() |
|
145 | { |
178 | { |
|
146 | if (!IPAddress.TryParse(Settings.Default.Address, out var address)) |
179 | if (!IPAddress.TryParse(Settings.Default.Address, out var address)) |
|
147 | try |
180 | try |
|
148 | { |
181 | { |
|
- | 182 | var getHostAddresses = await Dns.GetHostAddressesAsync(Settings.Default.Address); |
||
- | 183 | if (!getHostAddresses.Any()) |
||
- | 184 | throw new Exception(); |
||
- | 185 | |
||
149 | address = Dns.GetHostAddresses(Settings.Default.Address).FirstOrDefault(); |
186 | address = getHostAddresses.FirstOrDefault(); |
|
150 | } |
187 | } |
|
151 | catch |
188 | catch |
|
152 | { |
189 | { |
|
153 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, |
190 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, |
|
154 | $"{Strings.Unable_to_determine_address} {Settings.Default.Address}"); |
191 | $"{Strings.Unable_to_determine_address} {Settings.Default.Address}"); |
|
Line 166... | Line 203... | |||
166 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.No_password_set); |
203 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.No_password_set); |
|
Line 167... | Line 204... | |||
167 | |
204 | |
|
168 | if (!await MqttCommunication |
205 | if (!await MqttCommunication |
|
169 | .Start(MqttCommunicationType.Client, address, (int) port, Settings.Default.Nick, |
206 | .Start(MqttCommunicationType.Client, address, (int) port, Settings.Default.Nick, |
|
170 | Settings.Default.Password, |
207 | Settings.Default.Password, |
|
171 | new[] {"lobby"})) |
208 | new[] {Constants.MqttTopic})) |
|
172 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.Unable_to_start_client); |
209 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.Unable_to_start_client); |
|
Line 173... | Line 210... | |||
173 | } |
210 | } |
|
174 | |
211 | |
|
Line 205... | Line 242... | |||
205 | FormCancellationTokenSource.Token, TaskContinuationOptions.LongRunning, FormTaskScheduler); |
242 | FormCancellationTokenSource.Token, TaskContinuationOptions.LongRunning, FormTaskScheduler); |
|
Line 206... | Line 243... | |||
206 | |
243 | |
|
207 | // Start the MQTT server. |
244 | // Start the MQTT server. |
|
208 | if (!await MqttCommunication |
245 | if (!await MqttCommunication |
|
209 | .Start(MqttCommunicationType.Server, address, (int) port, Settings.Default.Nick, |
246 | .Start(MqttCommunicationType.Server, address, (int) port, Settings.Default.Nick, |
|
210 | Settings.Default.Password, new[] {"lobby"})) |
247 | Settings.Default.Password, new[] {Constants.MqttTopic})) |
|
211 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.Unable_to_start_server); |
248 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.Unable_to_start_server); |
|
Line 212... | Line 249... | |||
212 | } |
249 | } |
|
213 | |
250 | |
|
Line 224... | Line 261... | |||
224 | /// Clean up any resources being used. |
261 | /// Clean up any resources being used. |
|
225 | /// </summary> |
262 | /// </summary> |
|
226 | /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> |
263 | /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> |
|
227 | protected override void Dispose(bool disposing) |
264 | protected override void Dispose(bool disposing) |
|
228 | { |
265 | { |
|
- | 266 | // Unbind global key hook. |
||
- | 267 | MouseKeyGlobalHook.KeyDown -= MouseKeyGlobalHookOnKeyDown; |
||
- | 268 | |
||
- | 269 | // Unbind message synchronizer. |
||
- | 270 | ChatMessageSynchronizer.OnMessageReceived -= OnMessageReceived; |
||
- | 271 | |
||
229 | // Unbind settings handlers. |
272 | // Unbind settings handlers. |
|
230 | Settings.Default.SettingsLoaded -= DefaultOnSettingsLoaded; |
273 | Settings.Default.SettingsLoaded -= DefaultOnSettingsLoaded; |
|
231 | Settings.Default.SettingsSaving -= DefaultOnSettingsSaving; |
274 | Settings.Default.SettingsSaving -= DefaultOnSettingsSaving; |
|
232 | Settings.Default.PropertyChanged -= DefaultOnPropertyChanged; |
275 | Settings.Default.PropertyChanged -= DefaultOnPropertyChanged; |
|
Line 237... | Line 280... | |||
237 | |
280 | |
|
238 | private void OnMouseDown(object sender, MouseEventArgs e) |
281 | private void OnMouseDown(object sender, MouseEventArgs e) |
|
239 | { |
282 | { |
|
240 | if (e.Button == MouseButtons.Left) |
283 | if (e.Button == MouseButtons.Left) |
|
241 | { |
284 | { |
|
242 | Natives.ReleaseCapture(); |
285 | DllImports.ReleaseCapture(); |
|
243 | Natives.SendMessage(Handle, Natives.WM_NCLBUTTONDOWN, Natives.HT_CAPTION, 0); |
286 | DllImports.SendMessage(Handle, DllImports.WM_NCLBUTTONDOWN, DllImports.HT_CAPTION, 0); |
|
244 | } |
287 | } |
|
Line 245... | Line 288... | |||
245 | } |
288 | } |
|
246 | |
289 | |
|
Line 325... | Line 368... | |||
325 | |
368 | |
|
326 | if (!handled) |
369 | if (!handled) |
|
327 | base.WndProc(ref m); |
370 | base.WndProc(ref m); |
|
Line 328... | Line 371... | |||
328 | } |
371 | } |
|
329 | |
372 | |
|
330 | private void OnMouseEnter(object sender, EventArgs e) |
373 | private void HushFocus(object sender, EventArgs e) |
|
331 | { |
374 | { |
|
Line 332... | Line 375... | |||
332 | Opacity = .75; |
375 | Opacity = .75; |
|
333 | } |
376 | } |
|
334 | |
377 | |
|
335 | private void OnMouseLeave(object sender, EventArgs e) |
378 | private void HushUnfocus(object sender, EventArgs e) |
|
Line 336... | Line 379... | |||
336 | { |
379 | { |
|
Line 347... | Line 390... | |||
347 | Application.Exit(); |
390 | Application.Exit(); |
|
348 | } |
391 | } |
|
Line 349... | Line 392... | |||
349 | |
392 | |
|
350 | private async void MessageTextBoxOnKeyDown(object sender, KeyEventArgs e) |
393 | private async void MessageTextBoxOnKeyDown(object sender, KeyEventArgs e) |
|
351 | { |
394 | { |
|
352 | // Do not send messages if the communication is not running. |
395 | // Prevent the enter key to be passed to the text box or we get a nasty ding. |
|
353 | if (!MqttCommunication.Running) |
396 | if (e.KeyCode == Keys.Enter) |
|
Line 354... | Line 397... | |||
354 | return; |
397 | e.SuppressKeyPress = true; |
|
355 | |
398 | |
|
Line -... | Line 399... | |||
- | 399 | if (e.KeyCode != Keys.Enter) |
||
- | 400 | return; |
||
- | 401 | |
||
- | 402 | // Do not send messages if the communication is not running. |
||
356 | if (e.KeyCode != Keys.Enter) |
403 | if (!MqttCommunication.Running) |
|
357 | return; |
404 | return; |
|
Line 358... | Line 405... | |||
358 | |
405 | |
|
359 | if (string.IsNullOrEmpty(messageTextBox.Text)) |
406 | if (string.IsNullOrEmpty(messageTextBox.Text)) |
|
Line 360... | Line 407... | |||
360 | return; |
407 | return; |
|
361 | |
408 | |
|
Line 362... | Line 409... | |||
362 | // Send the message |
409 | // Send the message |
|
Line 406... | Line 453... | |||
406 | { |
453 | { |
|
407 | var toolStripMenuItem = (ToolStripTextBox) sender; |
454 | var toolStripMenuItem = (ToolStripTextBox) sender; |
|
Line 408... | Line 455... | |||
408 | |
455 | |
|
409 | Settings.Default.Port = toolStripMenuItem.Text; |
456 | Settings.Default.Port = toolStripMenuItem.Text; |
|
- | 457 | } |
||
- | 458 | |
||
- | 459 | private void ChatTextBox_TextChanged(object sender, EventArgs e) |
||
- | 460 | { |
||
- | 461 | var textBox = (TextBox) sender; |
||
- | 462 | |
||
- | 463 | textBox.ScrollToCaret(); |
||
410 | } |
464 | } |
|
411 | } |
465 | } |
|
412 | } |
466 | } |