Hush – Diff between revs 2 and 3
?pathlinks?
Rev 2 | Rev 3 | |||
---|---|---|---|---|
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.Chat; |
|
13 | using Hush.Communication; |
12 | using Hush.Communication; |
|
14 | using Hush.Discovery; |
13 | using Hush.Discovery; |
|
15 | using Hush.Properties; |
14 | using Hush.Properties; |
|
16 | using Hush.Utilities; |
15 | using Hush.Utilities; |
|
- | 16 | using MQTTnet.Extensions.ManagedClient; |
||
- | 17 | using MQTTnet.Server; |
||
17 | using WingMan.Communication; |
18 | using WingMan.Communication; |
|
18 | using Message = System.Windows.Forms.Message; |
- | ||
Line 19... | Line 19... | |||
19 | |
19 | |
|
20 | namespace Hush |
20 | namespace Hush |
|
21 | { |
21 | { |
|
22 | public partial class Hush : Form |
22 | public partial class Hush : Form |
|
- | 23 | { |
||
- | 24 | private static TaskScheduler FormTaskScheduler { get; set; } |
||
- | 25 | private static CancellationTokenSource FormCancellationTokenSource { get; set; } |
||
- | 26 | private static MqttCommunication MqttCommunication { get; set; } |
||
- | 27 | private static ChatMessageSynchronizer ChatMessageSynchronizer { get; set; } |
||
- | 28 | private static Discovery.Discovery Discovery { get; set; } |
||
23 | { |
29 | |
|
24 | public Hush() |
30 | public Hush() |
|
25 | { |
31 | { |
|
Line 26... | Line 32... | |||
26 | InitializeComponent(); |
32 | InitializeComponent(); |
|
27 | |
33 | |
|
Line 28... | Line -... | |||
28 | FormTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); |
- | ||
29 | FormCancellationTokenSource = new CancellationTokenSource(); |
- | ||
30 | |
- | ||
31 | // Initialize a message buffer. |
34 | FormTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); |
|
32 | Messages = new List<string>(); |
35 | FormCancellationTokenSource = new CancellationTokenSource(); |
|
33 | |
36 | |
|
34 | // Bind to settings changed event. |
37 | // Bind to settings changed event. |
|
Line 35... | Line -... | |||
35 | Settings.Default.SettingsLoaded += DefaultOnSettingsLoaded; |
- | ||
36 | Settings.Default.SettingsSaving += DefaultOnSettingsSaving; |
- | ||
37 | Settings.Default.PropertyChanged += DefaultOnPropertyChanged; |
- | ||
38 | |
- | ||
39 | // Set up keyboard hook. |
38 | Settings.Default.SettingsLoaded += DefaultOnSettingsLoaded; |
|
40 | MouseKeyGlobalHook = Hook.GlobalEvents(); |
39 | Settings.Default.SettingsSaving += DefaultOnSettingsSaving; |
|
41 | MouseKeyGlobalHook.KeyDown += MouseKeyGlobalHookOnKeyDown; |
40 | Settings.Default.PropertyChanged += DefaultOnPropertyChanged; |
|
42 | |
41 | |
|
Line 43... | Line 42... | |||
43 | // Set up discovery. |
42 | // Set up discovery. |
|
44 | Discovery = new Discovery.Discovery(Constants.AssemblyName, FormCancellationTokenSource.Token, |
43 | Discovery = new Discovery.Discovery(Constants.AssemblyName, FormCancellationTokenSource.Token, |
|
- | 44 | FormTaskScheduler); |
||
- | 45 | Discovery.OnPortMapFailed += OnDiscoveryPortMapFailed; |
||
45 | FormTaskScheduler); |
46 | |
|
46 | Discovery.OnPortMapFailed += OnDiscoveryPortMapFailed; |
47 | // Bind to MQTT events. |
|
- | 48 | MqttCommunication = new MqttCommunication(FormTaskScheduler, FormCancellationTokenSource.Token); |
||
- | 49 | MqttCommunication.OnClientConnectionFailed += MqttOnClientConnectionFailed; |
||
Line 47... | Line 50... | |||
47 | |
50 | MqttCommunication.OnClientAuthenticationFailed += MqttOnClientAuthenticationFailed; |
|
48 | // Bind to MQTT events. |
51 | MqttCommunication.OnClientConnected += MqttOnClientConnected; |
|
- | 52 | MqttCommunication.OnClientDisconnected += MqttOnClientDisconnected; |
||
49 | MqttCommunication = new MqttCommunication(FormTaskScheduler, FormCancellationTokenSource.Token); |
53 | MqttCommunication.OnServerClientConnected += MqttCommunicationOnOnServerClientConnected; |
|
50 | // TODO implement events. |
54 | MqttCommunication.OnServerClientDisconnected += MqttOnServerClientDisconnected; |
|
51 | //MqttCommunication. |
55 | |
|
Line 52... | Line -... | |||
52 | |
- | ||
53 | // Start message synchronizer. |
- | ||
54 | ChatMessageSynchronizer = new ChatMessageSynchronizer(Constants.MqttTopic, MqttCommunication, FormTaskScheduler, |
- | ||
55 | FormCancellationTokenSource.Token); |
- | ||
56 | ChatMessageSynchronizer.OnMessageReceived += OnMessageReceived; |
- | ||
57 | } |
- | ||
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 |
- | ||
70 | if (!keyEventArgs.Control || keyEventArgs.KeyCode != Keys.C) |
- | ||
71 | return; |
- | ||
72 | |
- | ||
73 | ActiveControl = messageTextBox; |
- | ||
74 | messageTextBox.Focus(); |
- | ||
75 | } |
- | ||
76 | |
- | ||
77 | private void OnDiscoveryPortMapFailed(object sender, DiscoveryFailedEventArgs args) |
- | ||
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); |
- | ||
90 | |
- | ||
91 | // Keep the content of the text box limited to the size of the displayed text. |
- | ||
92 | var lineHeight = TextRenderer.MeasureText(message, chatTextBox.Font).Height; |
- | ||
93 | var linesPerPage = (int) Math.Ceiling(1.0f * chatTextBox.ClientSize.Height / lineHeight); |
- | ||
94 | |
- | ||
95 | if (Messages.Count > linesPerPage) |
- | ||
96 | Messages.RemoveRange(0, Messages.Count - 1 - linesPerPage); |
- | ||
97 | |
- | ||
98 | chatTextBox.Text = string.Join(Environment.NewLine, Messages); |
- | ||
99 | } |
- | ||
100 | |
- | ||
101 | private async void DefaultOnPropertyChanged(object sender, PropertyChangedEventArgs e) |
- | ||
102 | { |
- | ||
103 | if (string.Equals(e.PropertyName, "LaunchOnBoot")) |
- | ||
104 | LaunchOnBoot.Set(Settings.Default.LaunchOnBoot); |
- | ||
105 | |
- | ||
106 | if (string.Equals(e.PropertyName, "Start")) |
- | ||
107 | await ToggleStart(); |
- | ||
108 | } |
- | ||
109 | |
- | ||
110 | private async Task ToggleStart() |
- | ||
111 | { |
- | ||
112 | switch (Settings.Default.Mode) |
- | ||
113 | { |
- | ||
114 | case "Server": |
- | ||
115 | await StopServer(); |
- | ||
116 | |
- | ||
117 | if (!Settings.Default.Start) |
- | ||
118 | break; |
- | ||
119 | |
- | ||
120 | try |
- | ||
121 | { |
- | ||
122 | await StartServer(); |
- | ||
123 | } |
- | ||
124 | catch (ToolTippedException ex) |
- | ||
125 | { |
- | ||
126 | notifyIcon1.BalloonTipIcon = ex.Icon; |
- | ||
127 | notifyIcon1.BalloonTipTitle = ex.Title; |
- | ||
128 | notifyIcon1.BalloonTipText = ex.Body; |
- | ||
129 | notifyIcon1.ShowBalloonTip(1000); |
- | ||
130 | } |
- | ||
131 | |
- | ||
132 | break; |
- | ||
133 | case "Client": |
- | ||
134 | await StopClient(); |
- | ||
135 | |
- | ||
136 | if (!Settings.Default.Start) |
- | ||
137 | break; |
- | ||
138 | |
- | ||
139 | try |
- | ||
140 | { |
- | ||
141 | await StartClient(); |
- | ||
142 | } |
- | ||
143 | catch (ToolTippedException ex) |
- | ||
144 | { |
- | ||
145 | notifyIcon1.BalloonTipIcon = ex.Icon; |
- | ||
146 | notifyIcon1.BalloonTipTitle = ex.Title; |
- | ||
147 | notifyIcon1.BalloonTipText = ex.Body; |
- | ||
148 | notifyIcon1.ShowBalloonTip(1000); |
- | ||
149 | } |
- | ||
150 | |
- | ||
151 | break; |
- | ||
152 | } |
- | ||
153 | |
- | ||
154 | startToolStripMenuItem.Checked = Settings.Default.Start; |
- | ||
155 | } |
- | ||
156 | |
- | ||
157 | private async Task StopClient() |
- | ||
158 | { |
- | ||
159 | // Stop the client if it is already started. |
- | ||
160 | await MqttCommunication.Stop(); |
- | ||
161 | } |
- | ||
162 | |
- | ||
163 | private async Task StopServer() |
- | ||
164 | { |
- | ||
165 | // Remove UPnP and Pmp mappings. |
- | ||
166 | await Task.Delay(0, FormCancellationTokenSource.Token).ContinueWith(async _ => |
- | ||
167 | { |
- | ||
168 | await Discovery.DeleteMapping(DiscoveryType.Upnp, MqttCommunication.Port); |
- | ||
169 | await Discovery.DeleteMapping(DiscoveryType.Pmp, MqttCommunication.Port); |
- | ||
170 | }, |
- | ||
171 | FormCancellationTokenSource.Token, TaskContinuationOptions.LongRunning, FormTaskScheduler); |
- | ||
172 | |
- | ||
173 | // Stop the MQTT server if it is running. |
- | ||
174 | await MqttCommunication.Stop(); |
- | ||
175 | } |
- | ||
176 | |
- | ||
177 | private async Task StartClient() |
- | ||
178 | { |
- | ||
179 | if (!IPAddress.TryParse(Settings.Default.Address, out var address)) |
- | ||
180 | try |
- | ||
181 | { |
- | ||
182 | var getHostAddresses = await Dns.GetHostAddressesAsync(Settings.Default.Address); |
- | ||
183 | if (!getHostAddresses.Any()) |
- | ||
184 | throw new Exception(); |
- | ||
185 | |
- | ||
186 | address = getHostAddresses.FirstOrDefault(); |
- | ||
187 | } |
- | ||
188 | catch |
- | ||
189 | { |
- | ||
190 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, |
- | ||
191 | $"{Strings.Unable_to_determine_address} {Settings.Default.Address}"); |
- | ||
192 | } |
- | ||
193 | |
- | ||
194 | if (!uint.TryParse(Settings.Default.Port, out var port)) |
- | ||
195 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, |
- | ||
196 | $"{Strings.Unable_to_determine_port} {Settings.Default.Port}"); |
- | ||
197 | |
- | ||
198 | |
- | ||
199 | if (string.IsNullOrEmpty(Settings.Default.Nick)) |
- | ||
200 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.No_nickname_set); |
- | ||
201 | |
- | ||
202 | if (string.IsNullOrEmpty(Settings.Default.Password)) |
- | ||
203 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.No_password_set); |
- | ||
204 | |
- | ||
205 | if (!await MqttCommunication |
- | ||
206 | .Start(MqttCommunicationType.Client, address, (int) port, Settings.Default.Nick, |
- | ||
207 | Settings.Default.Password, |
- | ||
208 | new[] {Constants.MqttTopic})) |
- | ||
209 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.Unable_to_start_client); |
- | ||
210 | } |
- | ||
211 | |
- | ||
212 | private async Task StartServer() |
- | ||
213 | { |
- | ||
214 | if (!IPAddress.TryParse(Settings.Default.Address, out var address)) |
- | ||
215 | try |
- | ||
216 | { |
- | ||
217 | address = Dns.GetHostAddresses(Settings.Default.Address).FirstOrDefault(); |
- | ||
218 | } |
- | ||
219 | catch |
- | ||
220 | { |
- | ||
221 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, |
- | ||
222 | $"{Strings.Unable_to_determine_address} {Settings.Default.Address}"); |
- | ||
223 | } |
- | ||
224 | |
- | ||
225 | if (!uint.TryParse(Settings.Default.Port, out var port)) |
- | ||
226 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, |
- | ||
227 | $"{Strings.Unable_to_determine_port} {Settings.Default.Port}"); |
- | ||
228 | |
- | ||
229 | |
- | ||
230 | if (string.IsNullOrEmpty(Settings.Default.Nick)) |
- | ||
231 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.No_nickname_set); |
- | ||
232 | |
- | ||
233 | if (string.IsNullOrEmpty(Settings.Default.Password)) |
- | ||
234 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.No_password_set); |
- | ||
235 | |
- | ||
236 | // Try to reserve port: try UPnP followed by PMP. |
- | ||
237 | await Task.Delay(0, FormCancellationTokenSource.Token).ContinueWith(async _ => |
- | ||
238 | { |
- | ||
239 | if (!await Discovery.CreateMapping(DiscoveryType.Upnp, (int) port)) |
- | ||
240 | await Discovery.CreateMapping(DiscoveryType.Pmp, (int) port); |
- | ||
241 | }, |
- | ||
242 | FormCancellationTokenSource.Token, TaskContinuationOptions.LongRunning, FormTaskScheduler); |
- | ||
243 | |
- | ||
244 | // Start the MQTT server. |
- | ||
245 | if (!await MqttCommunication |
- | ||
246 | .Start(MqttCommunicationType.Server, address, (int) port, Settings.Default.Nick, |
- | ||
247 | Settings.Default.Password, new[] {Constants.MqttTopic})) |
- | ||
248 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.Unable_to_start_server); |
- | ||
249 | } |
- | ||
250 | |
- | ||
251 | private void DefaultOnSettingsSaving(object sender, CancelEventArgs e) |
- | ||
Line 252... | Line 56... | |||
252 | { |
56 | // Start message synchronizer. |
|
253 | } |
57 | ChatMessageSynchronizer = new ChatMessageSynchronizer(Constants.MqttTopic, MqttCommunication, |
|
254 | |
58 | FormTaskScheduler, |
|
255 | private void DefaultOnSettingsLoaded(object sender, SettingsLoadedEventArgs e) |
59 | FormCancellationTokenSource.Token); |
|
256 | { |
60 | ChatMessageSynchronizer.OnMessageReceived += OnMessageReceived; |
|
257 | LaunchOnBoot.Set(Settings.Default.LaunchOnBoot); |
61 | } |
|
258 | } |
- | ||
259 | |
- | ||
260 | /// <summary> |
- | ||
261 | /// Clean up any resources being used. |
62 | |
|
262 | /// </summary> |
63 | |
|
Line 263... | Line 64... | |||
263 | /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> |
64 | /// <summary> |
|
264 | protected override void Dispose(bool disposing) |
65 | /// Clean up any resources being used. |
|
Line 276... | Line 77... | |||
276 | |
77 | |
|
277 | if (disposing && components != null) components.Dispose(); |
78 | if (disposing && components != null) components.Dispose(); |
|
278 | base.Dispose(disposing); |
79 | base.Dispose(disposing); |
|
Line 279... | Line -... | |||
279 | } |
- | ||
280 | |
- | ||
281 | private void OnMouseDown(object sender, MouseEventArgs e) |
- | ||
282 | { |
80 | } |
|
283 | if (e.Button == MouseButtons.Left) |
- | ||
284 | { |
- | ||
285 | DllImports.ReleaseCapture(); |
- | ||
286 | DllImports.SendMessage(Handle, DllImports.WM_NCLBUTTONDOWN, DllImports.HT_CAPTION, 0); |
- | ||
Line 287... | Line 81... | |||
287 | } |
81 | |
|
288 | } |
82 | #region Overrides |
|
289 | |
83 | |
|
290 | protected override void OnPaintBackground(PaintEventArgs e) |
84 | protected override void OnPaintBackground(PaintEventArgs e) |
|
Line 368... | Line 162... | |||
368 | |
162 | |
|
369 | if (!handled) |
163 | if (!handled) |
|
370 | base.WndProc(ref m); |
164 | base.WndProc(ref m); |
|
Line -... | Line 165... | |||
- | 165 | } |
||
- | 166 | |
||
- | 167 | #endregion |
||
- | 168 | |
||
- | 169 | #region Event Handlers |
||
- | 170 | |
||
- | 171 | private void MqttOnServerClientDisconnected(object sender, |
||
- | 172 | MqttClientDisconnectedEventArgs mqttClientDisconnectedEventArgs) |
||
- | 173 | { |
||
- | 174 | notifyIcon1.BalloonTipIcon = ToolTipIcon.Warning; |
||
- | 175 | notifyIcon1.BalloonTipTitle = Strings.Network_warning; |
||
- | 176 | notifyIcon1.BalloonTipText = $"{Strings.Client_disconnected}"; |
||
- | 177 | notifyIcon1.ShowBalloonTip(1000); |
||
- | 178 | } |
||
- | 179 | |
||
- | 180 | |
||
- | 181 | private void MqttCommunicationOnOnServerClientConnected(object sender, |
||
- | 182 | MqttClientConnectedEventArgs mqttClientConnectedEventArgs) |
||
- | 183 | { |
||
- | 184 | notifyIcon1.BalloonTipIcon = ToolTipIcon.Warning; |
||
- | 185 | notifyIcon1.BalloonTipTitle = Strings.Network_warning; |
||
- | 186 | notifyIcon1.BalloonTipText = $"{Strings.Client_connected}"; |
||
- | 187 | notifyIcon1.ShowBalloonTip(1000); |
||
- | 188 | } |
||
- | 189 | |
||
- | 190 | private void MqttOnClientDisconnected(object sender, |
||
- | 191 | MQTTnet.Client.MqttClientDisconnectedEventArgs mqttClientDisconnectedEventArgs) |
||
- | 192 | { |
||
- | 193 | notifyIcon1.BalloonTipIcon = ToolTipIcon.Warning; |
||
- | 194 | notifyIcon1.BalloonTipTitle = Strings.Network_warning; |
||
- | 195 | notifyIcon1.BalloonTipText = $"{Strings.Client_disconnected}"; |
||
- | 196 | notifyIcon1.ShowBalloonTip(1000); |
||
- | 197 | } |
||
- | 198 | |
||
- | 199 | private void MqttOnClientConnected(object sender, |
||
- | 200 | MQTTnet.Client.MqttClientConnectedEventArgs mqttClientConnectedEventArgs) |
||
- | 201 | { |
||
- | 202 | notifyIcon1.BalloonTipIcon = ToolTipIcon.Warning; |
||
- | 203 | notifyIcon1.BalloonTipTitle = Strings.Network_warning; |
||
- | 204 | notifyIcon1.BalloonTipText = $"{Strings.Client_connected}"; |
||
- | 205 | notifyIcon1.ShowBalloonTip(1000); |
||
- | 206 | } |
||
- | 207 | |
||
- | 208 | private void MqttOnClientAuthenticationFailed(object sender, |
||
- | 209 | MqttAuthenticationFailureEventArgs mqttAuthenticationFailureEventArgs) |
||
- | 210 | { |
||
- | 211 | notifyIcon1.BalloonTipIcon = ToolTipIcon.Warning; |
||
- | 212 | notifyIcon1.BalloonTipTitle = Strings.Network_warning; |
||
- | 213 | notifyIcon1.BalloonTipText = $"{Strings.Failed_to_authenticate_to_server}"; |
||
- | 214 | notifyIcon1.ShowBalloonTip(1000); |
||
- | 215 | } |
||
- | 216 | |
||
- | 217 | private void MqttOnClientConnectionFailed(object sender, |
||
- | 218 | MqttManagedProcessFailedEventArgs mqttManagedProcessFailedEventArgs) |
||
- | 219 | { |
||
- | 220 | notifyIcon1.BalloonTipIcon = ToolTipIcon.Warning; |
||
- | 221 | notifyIcon1.BalloonTipTitle = Strings.Network_warning; |
||
- | 222 | notifyIcon1.BalloonTipText = |
||
- | 223 | $"{Strings.Failed_to_connect_to_server} {mqttManagedProcessFailedEventArgs.Exception.Message}"; |
||
- | 224 | notifyIcon1.ShowBalloonTip(1000); |
||
- | 225 | } |
||
- | 226 | |
||
- | 227 | private void OnDiscoveryPortMapFailed(object sender, DiscoveryFailedEventArgs args) |
||
- | 228 | { |
||
- | 229 | notifyIcon1.BalloonTipIcon = ToolTipIcon.Warning; |
||
- | 230 | notifyIcon1.BalloonTipTitle = Strings.Network_warning; |
||
- | 231 | notifyIcon1.BalloonTipText = Strings.Failed_to_create_automatic_NAT_port_mapping; |
||
- | 232 | notifyIcon1.ShowBalloonTip(1000); |
||
- | 233 | } |
||
- | 234 | |
||
- | 235 | private void OnMessageReceived(object sender, ChatMessageReceivedEventArgs e) |
||
- | 236 | { |
||
- | 237 | var message = $"{e.Nick} : {e.Message}{Environment.NewLine}"; |
||
- | 238 | chatTextBox.AppendText(message); |
||
- | 239 | } |
||
- | 240 | |
||
- | 241 | private async void DefaultOnPropertyChanged(object sender, PropertyChangedEventArgs e) |
||
- | 242 | { |
||
- | 243 | LaunchOnBoot.Set(Settings.Default.LaunchOnBoot); |
||
- | 244 | await ToggleStart(); |
||
- | 245 | } |
||
- | 246 | |
||
- | 247 | private void DefaultOnSettingsSaving(object sender, CancelEventArgs e) |
||
- | 248 | { |
||
- | 249 | } |
||
- | 250 | |
||
- | 251 | private void DefaultOnSettingsLoaded(object sender, SettingsLoadedEventArgs e) |
||
- | 252 | { |
||
- | 253 | LaunchOnBoot.Set(Settings.Default.LaunchOnBoot); |
||
- | 254 | } |
||
- | 255 | |
||
- | 256 | private void OnMouseDown(object sender, MouseEventArgs e) |
||
- | 257 | { |
||
- | 258 | if (e.Button == MouseButtons.Left) |
||
- | 259 | { |
||
- | 260 | DllImports.ReleaseCapture(); |
||
- | 261 | DllImports.SendMessage(Handle, DllImports.WM_NCLBUTTONDOWN, DllImports.HT_CAPTION, 0); |
||
- | 262 | } |
||
371 | } |
263 | } |
|
372 | |
264 | |
|
373 | private void HushFocus(object sender, EventArgs e) |
265 | private void HushFocus(object sender, EventArgs e) |
|
374 | { |
266 | { |
|
Line 454... | Line 346... | |||
454 | var toolStripMenuItem = (ToolStripTextBox) sender; |
346 | var toolStripMenuItem = (ToolStripTextBox) sender; |
|
Line 455... | Line 347... | |||
455 | |
347 | |
|
456 | Settings.Default.Port = toolStripMenuItem.Text; |
348 | Settings.Default.Port = toolStripMenuItem.Text; |
|
Line -... | Line 349... | |||
- | 349 | } |
||
- | 350 | |
||
457 | } |
351 | #endregion |
|
458 | |
352 | |
|
- | 353 | private async Task ToggleStart() |
||
- | 354 | { |
||
- | 355 | switch (Settings.Default.Mode) |
||
459 | private void ChatTextBox_TextChanged(object sender, EventArgs e) |
356 | { |
|
- | 357 | case "Server": |
||
- | 358 | await StopServer(); |
||
- | 359 | |
||
Line -... | Line 360... | |||
- | 360 | if (!Settings.Default.Start) |
||
- | 361 | break; |
||
- | 362 | |
||
- | 363 | try |
||
- | 364 | { |
||
- | 365 | await StartServer(); |
||
- | 366 | } |
||
- | 367 | catch (ToolTippedException ex) |
||
- | 368 | { |
||
- | 369 | notifyIcon1.BalloonTipIcon = ex.Icon; |
||
- | 370 | notifyIcon1.BalloonTipTitle = ex.Title; |
||
- | 371 | notifyIcon1.BalloonTipText = ex.Body; |
||
- | 372 | notifyIcon1.ShowBalloonTip(1000); |
||
- | 373 | } |
||
460 | { |
374 | |
|
- | 375 | break; |
||
- | 376 | case "Client": |
||
- | 377 | await StopClient(); |
||
- | 378 | |
||
- | 379 | if (!Settings.Default.Start) |
||
- | 380 | break; |
||
- | 381 | |
||
- | 382 | try |
||
- | 383 | { |
||
- | 384 | await StartClient(); |
||
- | 385 | } |
||
- | 386 | catch (ToolTippedException ex) |
||
- | 387 | { |
||
- | 388 | notifyIcon1.BalloonTipIcon = ex.Icon; |
||
- | 389 | notifyIcon1.BalloonTipTitle = ex.Title; |
||
- | 390 | notifyIcon1.BalloonTipText = ex.Body; |
||
- | 391 | notifyIcon1.ShowBalloonTip(1000); |
||
- | 392 | } |
||
- | 393 | |
||
- | 394 | break; |
||
- | 395 | } |
||
- | 396 | |
||
- | 397 | startToolStripMenuItem.Checked = Settings.Default.Start; |
||
- | 398 | } |
||
- | 399 | |
||
- | 400 | private async Task StopClient() |
||
- | 401 | { |
||
- | 402 | // Stop the client if it is already started. |
||
- | 403 | await MqttCommunication.Stop(); |
||
- | 404 | } |
||
- | 405 | |
||
- | 406 | private async Task StopServer() |
||
- | 407 | { |
||
- | 408 | // Remove UPnP and Pmp mappings. |
||
- | 409 | await Task.Delay(0, FormCancellationTokenSource.Token).ContinueWith(async _ => |
||
- | 410 | { |
||
- | 411 | await Discovery.DeleteMapping(DiscoveryType.Upnp, MqttCommunication.Port); |
||
- | 412 | await Discovery.DeleteMapping(DiscoveryType.Pmp, MqttCommunication.Port); |
||
- | 413 | }, |
||
- | 414 | FormCancellationTokenSource.Token, TaskContinuationOptions.LongRunning, FormTaskScheduler); |
||
- | 415 | |
||
- | 416 | // Stop the MQTT server if it is running. |
||
- | 417 | await MqttCommunication.Stop(); |
||
- | 418 | } |
||
- | 419 | |
||
- | 420 | private async Task StartClient() |
||
- | 421 | { |
||
- | 422 | if (!IPAddress.TryParse(Settings.Default.Address, out var address)) |
||
- | 423 | try |
||
- | 424 | { |
||
- | 425 | var getHostAddresses = await Dns.GetHostAddressesAsync(Settings.Default.Address); |
||
- | 426 | if (!getHostAddresses.Any()) |
||
- | 427 | throw new Exception(); |
||
- | 428 | |
||
- | 429 | address = getHostAddresses.FirstOrDefault(); |
||
- | 430 | } |
||
- | 431 | catch |
||
- | 432 | { |
||
- | 433 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, |
||
- | 434 | $"{Strings.Unable_to_determine_address} {Settings.Default.Address}"); |
||
- | 435 | } |
||
- | 436 | |
||
- | 437 | if (!uint.TryParse(Settings.Default.Port, out var port)) |
||
- | 438 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, |
||
- | 439 | $"{Strings.Unable_to_determine_port} {Settings.Default.Port}"); |
||
- | 440 | |
||
- | 441 | |
||
- | 442 | if (string.IsNullOrEmpty(Settings.Default.Nick)) |
||
- | 443 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.No_nickname_set); |
||
- | 444 | |
||
- | 445 | if (string.IsNullOrEmpty(Settings.Default.Password)) |
||
- | 446 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.No_password_set); |
||
- | 447 | |
||
- | 448 | if (!await MqttCommunication |
||
- | 449 | .Start(MqttCommunicationType.Client, address, (int) port, Settings.Default.Nick, |
||
- | 450 | Settings.Default.Password, |
||
- | 451 | new[] {Constants.MqttTopic})) |
||
- | 452 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.Unable_to_start_client); |
||
- | 453 | } |
||
- | 454 | |
||
- | 455 | private async Task StartServer() |
||
- | 456 | { |
||
- | 457 | if (!IPAddress.TryParse(Settings.Default.Address, out var address)) |
||
- | 458 | try |
||
- | 459 | { |
||
- | 460 | address = Dns.GetHostAddresses(Settings.Default.Address).FirstOrDefault(); |
||
- | 461 | } |
||
- | 462 | catch |
||
- | 463 | { |
||
- | 464 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, |
||
- | 465 | $"{Strings.Unable_to_determine_address} {Settings.Default.Address}"); |
||
- | 466 | } |
||
- | 467 | |
||
- | 468 | if (!uint.TryParse(Settings.Default.Port, out var port)) |
||
- | 469 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, |
||
- | 470 | $"{Strings.Unable_to_determine_port} {Settings.Default.Port}"); |
||
- | 471 | |
||
- | 472 | |
||
- | 473 | if (string.IsNullOrEmpty(Settings.Default.Nick)) |
||
- | 474 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.No_nickname_set); |
||
- | 475 | |
||
- | 476 | if (string.IsNullOrEmpty(Settings.Default.Password)) |
||
- | 477 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.No_password_set); |
||
- | 478 | |
||
- | 479 | // Try to reserve port: try UPnP followed by PMP. |
||
- | 480 | await Task.Delay(0, FormCancellationTokenSource.Token).ContinueWith(async _ => |
||
- | 481 | { |
||
- | 482 | if (!await Discovery.CreateMapping(DiscoveryType.Upnp, (int) port)) |
||
- | 483 | await Discovery.CreateMapping(DiscoveryType.Pmp, (int) port); |
||
- | 484 | }, |
||
- | 485 | FormCancellationTokenSource.Token, TaskContinuationOptions.LongRunning, FormTaskScheduler); |
||
- | 486 | |
||
- | 487 | // Start the MQTT server. |
||
- | 488 | if (!await MqttCommunication |
||
461 | var textBox = (TextBox) sender; |
489 | .Start(MqttCommunicationType.Server, address, (int) port, Settings.Default.Nick, |
|
462 | |
490 | Settings.Default.Password, new[] {Constants.MqttTopic})) |
|
463 | textBox.ScrollToCaret(); |
491 | throw new ToolTippedException(ToolTipIcon.Error, Strings.Network_error, Strings.Unable_to_start_server); |
|
464 | } |
492 | } |