Korero – Diff between revs 1 and 2
?pathlinks?
Rev 1 | Rev 2 | |||
---|---|---|---|---|
1 | using System; |
1 | using System; |
|
2 | using System.Collections.Generic; |
2 | using System.Collections.Generic; |
|
3 | using System.Linq; |
3 | using System.Linq; |
|
4 | using System.Threading; |
4 | using System.Threading; |
|
5 | using System.Threading.Tasks; |
5 | using System.Threading.Tasks; |
|
6 | using System.Windows.Forms; |
6 | using System.Windows.Forms; |
|
7 | using Korero.Communication; |
7 | using Korero.Communication; |
|
8 | using Korero.Properties; |
8 | using Korero.Properties; |
|
9 | using Korero.Serialization; |
9 | using Korero.Serialization; |
|
10 | using Korero.Utilities; |
10 | using Korero.Utilities; |
|
11 | using Serilog; |
11 | using Serilog; |
|
12 | |
12 | |
|
13 | namespace Korero.Teleport |
13 | namespace Korero.Teleport |
|
14 | { |
14 | { |
|
15 | public partial class TeleportForm : Form |
15 | public partial class TeleportForm : Form |
|
16 | { |
16 | { |
|
17 | #region Private Delegates, Events, Enums, Properties, Indexers and Fields |
17 | #region Private Delegates, Events, Enums, Properties, Indexers and Fields |
|
18 | |
18 | |
|
19 | private readonly CancellationToken _cancellationToken; |
19 | private readonly CancellationToken _cancellationToken; |
|
20 | |
20 | |
|
21 | private readonly CancellationTokenSource _cancellationTokenSource; |
21 | private readonly CancellationTokenSource _cancellationTokenSource; |
|
22 | |
22 | |
|
23 | private readonly Task _loadInventoryLandmarksTask; |
23 | private readonly Task _loadInventoryLandmarksTask; |
|
24 | |
24 | |
|
25 | private readonly MainForm _mainForm; |
25 | private readonly MainForm _mainForm; |
|
26 | |
26 | |
|
27 | private readonly MqttCommunication _mqttCommunication; |
27 | private readonly MqttCommunication _mqttCommunication; |
|
28 | |
28 | |
|
29 | #endregion |
29 | #endregion |
|
30 | |
30 | |
|
31 | #region Constructors, Destructors and Finalizers |
31 | #region Constructors, Destructors and Finalizers |
|
32 | |
32 | |
|
33 | public TeleportForm() |
33 | public TeleportForm() |
|
34 | { |
34 | { |
|
35 | InitializeComponent(); |
35 | InitializeComponent(); |
|
36 | Utilities.WindowState.FormTracker.Track(this); |
- | ||
37 | |
36 | |
|
38 | _cancellationTokenSource = new CancellationTokenSource(); |
37 | _cancellationTokenSource = new CancellationTokenSource(); |
|
39 | _cancellationToken = _cancellationTokenSource.Token; |
38 | _cancellationToken = _cancellationTokenSource.Token; |
|
40 | } |
39 | } |
|
41 | |
40 | |
|
42 | public TeleportForm(MainForm mainForm, MqttCommunication mqttCommunication) : this() |
41 | public TeleportForm(MainForm mainForm, MqttCommunication mqttCommunication) : this() |
|
43 | { |
42 | { |
|
44 | _mainForm = mainForm; |
43 | _mainForm = mainForm; |
|
45 | _mqttCommunication = mqttCommunication; |
44 | _mqttCommunication = mqttCommunication; |
|
46 | |
45 | |
|
47 | _loadInventoryLandmarksTask = LoadInventoryLandmarks(_cancellationToken); |
46 | _loadInventoryLandmarksTask = LoadInventoryLandmarks(_cancellationToken); |
|
48 | _mqttCommunication.NotificationReceived += MqttCommunication_NotificationReceived; |
47 | _mqttCommunication.NotificationReceived += MqttCommunication_NotificationReceived; |
|
49 | } |
48 | } |
|
50 | |
49 | |
|
51 | /// <summary> |
50 | /// <summary> |
|
52 | /// Clean up any resources being used. |
51 | /// Clean up any resources being used. |
|
53 | /// </summary> |
52 | /// </summary> |
|
54 | /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> |
53 | /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param> |
|
55 | protected override void Dispose(bool disposing) |
54 | protected override void Dispose(bool disposing) |
|
56 | { |
55 | { |
|
57 | if (disposing && components != null) |
56 | if (disposing && components != null) |
|
58 | { |
57 | { |
|
59 | components.Dispose(); |
58 | components.Dispose(); |
|
60 | } |
59 | } |
|
61 | |
60 | |
|
62 | _mqttCommunication.NotificationReceived -= MqttCommunication_NotificationReceived; |
61 | _mqttCommunication.NotificationReceived -= MqttCommunication_NotificationReceived; |
|
63 | base.Dispose(disposing); |
62 | base.Dispose(disposing); |
|
64 | } |
63 | } |
|
65 | |
64 | |
|
66 | #endregion |
65 | #endregion |
|
67 | |
66 | |
|
68 | #region Event Handlers |
67 | #region Event Handlers |
|
- | 68 | |
||
- | 69 | private void TeleportForm_Load(object sender, EventArgs e) |
||
- | 70 | { |
||
- | 71 | Utilities.WindowState.FormTracker.Track(this); |
||
- | 72 | } |
||
69 | |
73 | |
|
70 | private void MqttCommunication_NotificationReceived(object sender, MqttNotificationEventArgs e) |
74 | private void MqttCommunication_NotificationReceived(object sender, MqttNotificationEventArgs e) |
|
71 | { |
75 | { |
|
72 | switch (e.Notification["notification"]) |
76 | switch (e.Notification["notification"]) |
|
73 | { |
77 | { |
|
74 | case "teleport": |
78 | case "teleport": |
|
75 | toolStripStatusLabel1.Text = $"Teleport status: {e.Notification["status"]}"; |
79 | toolStripStatusLabel1.Text = $"Teleport status: {e.Notification["status"]}"; |
|
76 | break; |
80 | break; |
|
77 | } |
81 | } |
|
78 | } |
82 | } |
|
79 | |
83 | |
|
80 | private async void Button1_Click(object sender, EventArgs e) |
84 | private async void Button1_Click(object sender, EventArgs e) |
|
81 | { |
85 | { |
|
82 | if (!await CheckTeleportRegion(textBox1.Text)) |
86 | if (!await CheckTeleportRegion(textBox1.Text)) |
|
83 | { |
87 | { |
|
84 | return; |
88 | return; |
|
85 | } |
89 | } |
|
86 | |
90 | |
|
87 | if (!int.TryParse(textBox2.Text, out var x)) |
91 | if (!int.TryParse(textBox2.Text, out var x)) |
|
88 | { |
92 | { |
|
89 | x = 128; |
93 | x = 128; |
|
90 | } |
94 | } |
|
91 | |
95 | |
|
92 | if (!int.TryParse(textBox3.Text, out var y)) |
96 | if (!int.TryParse(textBox3.Text, out var y)) |
|
93 | { |
97 | { |
|
94 | y = 128; |
98 | y = 128; |
|
95 | } |
99 | } |
|
96 | |
100 | |
|
97 | if (!int.TryParse(textBox4.Text, out var z)) |
101 | if (!int.TryParse(textBox4.Text, out var z)) |
|
98 | { |
102 | { |
|
99 | z = 25; |
103 | z = 25; |
|
100 | } |
104 | } |
|
101 | |
105 | |
|
102 | await TeleportManual(textBox1.Text, x, y, z); |
106 | await TeleportManual(textBox1.Text, x, y, z); |
|
103 | } |
107 | } |
|
104 | |
108 | |
|
105 | private async void TextBox1_KeyPress(object sender, KeyPressEventArgs e) |
109 | private async void TextBox1_KeyPress(object sender, KeyPressEventArgs e) |
|
106 | { |
110 | { |
|
107 | if (e.KeyChar != (char) Keys.Enter) |
111 | if (e.KeyChar != (char) Keys.Enter) |
|
108 | { |
112 | { |
|
109 | return; |
113 | return; |
|
110 | } |
114 | } |
|
111 | |
115 | |
|
112 | if (!await CheckTeleportRegion(textBox1.Text)) |
116 | if (!await CheckTeleportRegion(textBox1.Text)) |
|
113 | { |
117 | { |
|
114 | return; |
118 | return; |
|
115 | } |
119 | } |
|
116 | |
120 | |
|
117 | if (!int.TryParse(textBox2.Text, out var x)) |
121 | if (!int.TryParse(textBox2.Text, out var x)) |
|
118 | { |
122 | { |
|
119 | x = 128; |
123 | x = 128; |
|
120 | } |
124 | } |
|
121 | |
125 | |
|
122 | if (!int.TryParse(textBox3.Text, out var y)) |
126 | if (!int.TryParse(textBox3.Text, out var y)) |
|
123 | { |
127 | { |
|
124 | y = 128; |
128 | y = 128; |
|
125 | } |
129 | } |
|
126 | |
130 | |
|
127 | if (!int.TryParse(textBox4.Text, out var z)) |
131 | if (!int.TryParse(textBox4.Text, out var z)) |
|
128 | { |
132 | { |
|
129 | z = 25; |
133 | z = 25; |
|
130 | } |
134 | } |
|
131 | |
135 | |
|
132 | await TeleportManual(textBox1.Text, x, y, z); |
136 | await TeleportManual(textBox1.Text, x, y, z); |
|
133 | } |
137 | } |
|
134 | |
138 | |
|
135 | private async void Button2_Click(object sender, EventArgs e) |
139 | private async void Button2_Click(object sender, EventArgs e) |
|
136 | { |
140 | { |
|
137 | var index = comboBox1.SelectedIndex; |
141 | var index = comboBox1.SelectedIndex; |
|
138 | if (index == -1) |
142 | if (index == -1) |
|
139 | { |
143 | { |
|
140 | return; |
144 | return; |
|
141 | } |
145 | } |
|
142 | |
146 | |
|
143 | var item = (LandmarkComboBoxItem) comboBox1.SelectedItem; |
147 | var item = (LandmarkComboBoxItem) comboBox1.SelectedItem; |
|
144 | |
148 | |
|
145 | toolStripStatusLabel1.Text = string.Empty; |
149 | toolStripStatusLabel1.Text = string.Empty; |
|
146 | |
150 | |
|
147 | await TeleportLandmark(item.Id); |
151 | await TeleportLandmark(item.Id); |
|
148 | } |
152 | } |
|
149 | |
153 | |
|
150 | private async void Button3_Click(object sender, EventArgs e) |
154 | private async void Button3_Click(object sender, EventArgs e) |
|
151 | { |
155 | { |
|
152 | var data = new Dictionary<string, string> |
156 | var data = new Dictionary<string, string> |
|
153 | { |
157 | { |
|
154 | {"command", "gohome"}, |
158 | {"command", "gohome"}, |
|
155 | {"group", Settings.Default.Group}, |
159 | {"group", Settings.Default.Group}, |
|
156 | {"password", Settings.Default.Password} |
160 | {"password", Settings.Default.Password} |
|
157 | }; |
161 | }; |
|
158 | |
162 | |
|
159 | var callback = await _mqttCommunication.SendCommand(new Command(data), _cancellationToken); |
163 | var callback = await _mqttCommunication.SendCommand(new Command(data), _cancellationToken); |
|
160 | |
164 | |
|
161 | if (callback == null || !callback.Success) |
165 | if (callback == null || !callback.Success) |
|
162 | { |
166 | { |
|
163 | if (callback != null) |
167 | if (callback != null) |
|
164 | { |
168 | { |
|
165 | Log.Warning("Command {Command} has failed with {Error}.", |
169 | Log.Warning("Command {Command} has failed with {Error}.", |
|
166 | callback.Command, callback.Error); |
170 | callback.Command, callback.Error); |
|
167 | } |
171 | } |
|
168 | |
172 | |
|
169 | toolStripStatusLabel1.Text = "Could not teleport home."; |
173 | toolStripStatusLabel1.Text = "Could not teleport home."; |
|
170 | |
174 | |
|
171 | return; |
175 | return; |
|
172 | } |
176 | } |
|
173 | |
177 | |
|
174 | toolStripStatusLabel1.Text = "Teleported home."; |
178 | toolStripStatusLabel1.Text = "Teleported home."; |
|
175 | } |
179 | } |
|
176 | |
180 | |
|
177 | private void TeleportForm_FormClosing(object sender, FormClosingEventArgs e) |
181 | private void TeleportForm_FormClosing(object sender, FormClosingEventArgs e) |
|
178 | { |
182 | { |
|
179 | _cancellationTokenSource.Cancel(); |
183 | _cancellationTokenSource.Cancel(); |
|
180 | } |
184 | } |
|
181 | |
185 | |
|
182 | #endregion |
186 | #endregion |
|
183 | |
187 | |
|
184 | #region Private Methods |
188 | #region Private Methods |
|
185 | |
189 | |
|
186 | private async Task LoadInventoryLandmarks(CancellationToken cancellationToken) |
190 | private async Task LoadInventoryLandmarks(CancellationToken cancellationToken) |
|
187 | { |
191 | { |
|
188 | var data = new Dictionary<string, string> |
192 | var data = new Dictionary<string, string> |
|
189 | { |
193 | { |
|
190 | {"command", "inventory"}, |
194 | {"command", "inventory"}, |
|
191 | {"group", Settings.Default.Group}, |
195 | {"group", Settings.Default.Group}, |
|
192 | {"password", Settings.Default.Password}, |
196 | {"password", Settings.Default.Password}, |
|
193 | {"action", "ls"}, |
197 | {"action", "ls"}, |
|
194 | {"path", "/My Inventory/Landmarks"} |
198 | {"path", "/My Inventory/Landmarks"} |
|
195 | }; |
199 | }; |
|
196 | |
200 | |
|
197 | var callback = await _mqttCommunication.SendCommand(new Command(data), cancellationToken); |
201 | var callback = await _mqttCommunication.SendCommand(new Command(data), cancellationToken); |
|
198 | |
202 | |
|
199 | if (callback == null || !callback.Success) |
203 | if (callback == null || !callback.Success) |
|
200 | { |
204 | { |
|
201 | if (callback != null) |
205 | if (callback != null) |
|
202 | { |
206 | { |
|
203 | Log.Warning("Command {Command} has failed with {Error}.", |
207 | Log.Warning("Command {Command} has failed with {Error}.", |
|
204 | callback.Command, callback.Error); |
208 | callback.Command, callback.Error); |
|
205 | } |
209 | } |
|
206 | |
210 | |
|
207 | return; |
211 | return; |
|
208 | } |
212 | } |
|
209 | |
213 | |
|
210 | comboBox1.InvokeIfRequired(comboBox => { comboBox.Items.Clear(); }); |
214 | comboBox1.InvokeIfRequired(comboBox => { comboBox.Items.Clear(); }); |
|
211 | |
215 | |
|
212 | foreach (var landmark in CsvStride(callback.Data, 10)) |
216 | foreach (var landmark in CsvStride(callback.Data, 10)) |
|
213 | { |
217 | { |
|
214 | var index = Array.IndexOf(landmark, "name"); |
218 | var index = Array.IndexOf(landmark, "name"); |
|
215 | var name = landmark[index + 1]; |
219 | var name = landmark[index + 1]; |
|
216 | index = Array.IndexOf(landmark, "type"); |
220 | index = Array.IndexOf(landmark, "type"); |
|
217 | var type = landmark[index + 1]; |
221 | var type = landmark[index + 1]; |
|
218 | |
222 | |
|
219 | if (type != "Landmark") |
223 | if (type != "Landmark") |
|
220 | { |
224 | { |
|
221 | continue; |
225 | continue; |
|
222 | } |
226 | } |
|
223 | |
227 | |
|
224 | index = Array.IndexOf(landmark, "item"); |
228 | index = Array.IndexOf(landmark, "item"); |
|
225 | |
229 | |
|
226 | var item = landmark[index + 1]; |
230 | var item = landmark[index + 1]; |
|
227 | |
231 | |
|
228 | if (!Guid.TryParse(item, out var id)) |
232 | if (!Guid.TryParse(item, out var id)) |
|
229 | { |
233 | { |
|
230 | continue; |
234 | continue; |
|
231 | } |
235 | } |
|
232 | |
236 | |
|
233 | var landmarkComboBoxItem = new LandmarkComboBoxItem(name, id); |
237 | var landmarkComboBoxItem = new LandmarkComboBoxItem(name, id); |
|
234 | |
238 | |
|
235 | comboBox1.InvokeIfRequired(comboBox => { comboBox.Items.Add(landmarkComboBoxItem); }); |
239 | comboBox1.InvokeIfRequired(comboBox => { comboBox.Items.Add(landmarkComboBoxItem); }); |
|
236 | } |
240 | } |
|
237 | } |
241 | } |
|
238 | |
242 | |
|
239 | private async Task TeleportManual(string region, int x, int y, int z) |
243 | private async Task TeleportManual(string region, int x, int y, int z) |
|
240 | { |
244 | { |
|
241 | var data = new Dictionary<string, string> |
245 | var data = new Dictionary<string, string> |
|
242 | { |
246 | { |
|
243 | {"command", "teleport"}, |
247 | {"command", "teleport"}, |
|
244 | {"group", Settings.Default.Group}, |
248 | {"group", Settings.Default.Group}, |
|
245 | {"password", Settings.Default.Password}, |
249 | {"password", Settings.Default.Password}, |
|
246 | {"entity", "region"}, |
250 | {"entity", "region"}, |
|
247 | {"region", region}, |
251 | {"region", region}, |
|
248 | {"position", $"<{x}, {y}, {z}>"} |
252 | {"position", $"<{x}, {y}, {z}>"} |
|
249 | }; |
253 | }; |
|
250 | |
254 | |
|
251 | var callback = await _mqttCommunication.SendCommand(new Command(data), _cancellationToken); |
255 | var callback = await _mqttCommunication.SendCommand(new Command(data), _cancellationToken); |
|
252 | |
256 | |
|
253 | if (callback == null || !callback.Success) |
257 | if (callback == null || !callback.Success) |
|
254 | { |
258 | { |
|
255 | if (callback != null) |
259 | if (callback != null) |
|
256 | { |
260 | { |
|
257 | Log.Warning("Command {Command} has failed with {Error}.", |
261 | Log.Warning("Command {Command} has failed with {Error}.", |
|
258 | callback.Command, callback.Error); |
262 | callback.Command, callback.Error); |
|
259 | } |
263 | } |
|
260 | } |
264 | } |
|
261 | } |
265 | } |
|
262 | |
266 | |
|
263 | private async Task<bool> CheckTeleportRegion(string name) |
267 | private async Task<bool> CheckTeleportRegion(string name) |
|
264 | { |
268 | { |
|
265 | // Check for region name roundtrip. |
269 | // Check for region name roundtrip. |
|
266 | var data = new Dictionary<string, string> |
270 | var data = new Dictionary<string, string> |
|
267 | { |
271 | { |
|
268 | {"command", "getgridregiondata"}, |
272 | {"command", "getgridregiondata"}, |
|
269 | {"group", Settings.Default.Group}, |
273 | {"group", Settings.Default.Group}, |
|
270 | {"password", Settings.Default.Password}, |
274 | {"password", Settings.Default.Password}, |
|
271 | {"entity", "region"}, |
275 | {"entity", "region"}, |
|
272 | {"region", textBox1.Text}, |
276 | {"region", textBox1.Text}, |
|
273 | {"data", "Name"} |
277 | {"data", "Name"} |
|
274 | }; |
278 | }; |
|
275 | |
279 | |
|
276 | var callback = await _mqttCommunication.SendCommand(new Command(data), _cancellationToken); |
280 | var callback = await _mqttCommunication.SendCommand(new Command(data), _cancellationToken); |
|
277 | |
281 | |
|
278 | if (callback == null || !callback.Success) |
282 | if (callback == null || !callback.Success) |
|
279 | { |
283 | { |
|
280 | if (callback != null) |
284 | if (callback != null) |
|
281 | { |
285 | { |
|
282 | Log.Warning("Command {Command} has failed with {Error}.", |
286 | Log.Warning("Command {Command} has failed with {Error}.", |
|
283 | callback.Command, callback.Error); |
287 | callback.Command, callback.Error); |
|
284 | } |
288 | } |
|
285 | |
289 | |
|
286 | return false; |
290 | return false; |
|
287 | } |
291 | } |
|
288 | |
292 | |
|
289 | if (!string.Equals(name, callback["Name"].FirstOrDefault(), StringComparison.OrdinalIgnoreCase)) |
293 | if (!string.Equals(name, callback["Name"].FirstOrDefault(), StringComparison.OrdinalIgnoreCase)) |
|
290 | { |
294 | { |
|
291 | return false; |
295 | return false; |
|
292 | } |
296 | } |
|
293 | |
297 | |
|
294 | return true; |
298 | return true; |
|
295 | } |
299 | } |
|
296 | |
300 | |
|
297 | private static IEnumerable<string[]> CsvStride(string input, int stride) |
301 | private static IEnumerable<string[]> CsvStride(string input, int stride) |
|
298 | { |
302 | { |
|
299 | var i = 0; |
303 | var i = 0; |
|
300 | return new CSV(input).Select(s => new {s, num = i++}) |
304 | return new CSV(input).Select(s => new {s, num = i++}) |
|
301 | .GroupBy(t => t.num / stride, t => t.s) |
305 | .GroupBy(t => t.num / stride, t => t.s) |
|
302 | .Select(g => g.ToArray()); |
306 | .Select(g => g.ToArray()); |
|
303 | } |
307 | } |
|
304 | |
308 | |
|
305 | private async Task TeleportLandmark(Guid id) |
309 | private async Task TeleportLandmark(Guid id) |
|
306 | { |
310 | { |
|
307 | var data = new Dictionary<string, string> |
311 | var data = new Dictionary<string, string> |
|
308 | { |
312 | { |
|
309 | {"command", "teleport"}, |
313 | {"command", "teleport"}, |
|
310 | {"group", Settings.Default.Group}, |
314 | {"group", Settings.Default.Group}, |
|
311 | {"password", Settings.Default.Password}, |
315 | {"password", Settings.Default.Password}, |
|
312 | {"entity", "landmark"}, |
316 | {"entity", "landmark"}, |
|
313 | {"item", $"{id.ToString()}"} |
317 | {"item", $"{id.ToString()}"} |
|
314 | }; |
318 | }; |
|
315 | |
319 | |
|
316 | var callback = await _mqttCommunication.SendCommand(new Command(data), _cancellationToken); |
320 | var callback = await _mqttCommunication.SendCommand(new Command(data), _cancellationToken); |
|
317 | |
321 | |
|
318 | if (callback == null || !callback.Success) |
322 | if (callback == null || !callback.Success) |
|
319 | { |
323 | { |
|
320 | if (callback != null) |
324 | if (callback != null) |
|
321 | { |
325 | { |
|
322 | Log.Warning("Command {Command} has failed with {Error}.", |
326 | Log.Warning("Command {Command} has failed with {Error}.", |
|
323 | callback.Command, callback.Error); |
327 | callback.Command, callback.Error); |
|
324 | } |
328 | } |
|
325 | } |
329 | } |
|
326 | } |
330 | } |
|
327 | |
331 | |
|
328 | #endregion |
332 | #endregion |
|
- | 333 | |
||
- | 334 | |
||
329 | } |
335 | } |
|
330 | } |
336 | } |
|
331 | |
337 | |
|
332 |
|
338 |
|
|
333 | |
339 | |
|
334 | |
340 | |
|
335 | |
341 | |