corrade-vassal – Diff between revs 13 and 16

Subversion Repositories:
Rev:
Only display areas with differencesIgnore whitespace
Rev 13 Rev 16
1 /////////////////////////////////////////////////////////////////////////// 1 ///////////////////////////////////////////////////////////////////////////
2 // Copyright (C) Wizardry and Steamworks 2015 - License: GNU GPLv3 // 2 // Copyright (C) Wizardry and Steamworks 2015 - License: GNU GPLv3 //
3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, // 3 // Please see: http://www.gnu.org/licenses/gpl.html for legal details, //
4 // rights of fair usage, the disclaimer and warranty conditions. // 4 // rights of fair usage, the disclaimer and warranty conditions. //
5 /////////////////////////////////////////////////////////////////////////// 5 ///////////////////////////////////////////////////////////////////////////
6   6  
7 using System; 7 using System;
8 using System.Collections.Generic; 8 using System.Collections.Generic;
9 using System.Diagnostics; 9 using System.Diagnostics;
10 using System.Drawing; 10 using System.Drawing;
11 using System.Drawing.Imaging; 11 using System.Drawing.Imaging;
12 using System.IO; 12 using System.IO;
13 using System.Linq; 13 using System.Linq;
14 using System.Net; 14 using System.Net;
-   15 using System.Net.Http.Headers;
15 using System.Net.Sockets; 16 using System.Net.Sockets;
16 using System.Reflection; 17 using System.Reflection;
17 using System.Text; 18 using System.Text;
18 using System.Text.RegularExpressions; 19 using System.Text.RegularExpressions;
19 using System.Threading; 20 using System.Threading;
20 using System.Windows.Forms; 21 using System.Windows.Forms;
21 using OpenMetaverse; 22 using OpenMetaverse;
22 using wasSharp; 23 using wasSharp;
23 using Parallel = System.Threading.Tasks.Parallel; 24 using Parallel = System.Threading.Tasks.Parallel;
24 using Timer = System.Timers.Timer; 25 using Timer = System.Timers.Timer;
25   26  
26 namespace Vassal 27 namespace Vassal
27 { 28 {
28 public partial class Vassal : Form 29 public partial class Vassal : Form
29 { 30 {
30 public static Timer vassalTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); 31 public static Timer vassalTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds);
31 public static Timer overviewTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); 32 public static Timer overviewTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds);
32 public static Timer residentListTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); 33 public static Timer residentListTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds);
33 public static Timer estateTopTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); 34 public static Timer estateTopTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds);
34 public static Timer regionsStateTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); 35 public static Timer regionsStateTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds);
35 public static Timer estateTexturesTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); 36 public static Timer estateTexturesTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds);
36 public static Image[] groundTextureImages = new Image[4]; 37 public static Image[] groundTextureImages = new Image[4];
37 public static volatile int regionsStateCheckIndex; 38 public static volatile int regionsStateCheckIndex;
38 public static VassalConfiguration vassalConfiguration = new VassalConfiguration(); 39 public static VassalConfiguration vassalConfiguration = new VassalConfiguration();
39 public static Vassal vassalForm; 40 public static Vassal vassalForm;
40 public static readonly object ClientInstanceTeleportLock = new object(); 41 public static readonly object ClientInstanceTeleportLock = new object();
41 public static readonly object RegionsStateCheckLock = new object(); 42 public static readonly object RegionsStateCheckLock = new object();
-   43 public static Web.wasHTTPClient HTTPClient;
-   44  
-   45 /// <summary>
-   46 /// Corrade version.
-   47 /// </summary>
-   48 public static readonly string VASSAL_VERSION = Assembly.GetEntryAssembly().GetName().Version.ToString();
42   49  
43 /// <summary> 50 /// <summary>
44 /// Corrade's input filter function. 51 /// Corrade's input filter function.
45 /// </summary> 52 /// </summary>
46 private static readonly Func<string, string> wasInput = o => 53 private static readonly Func<string, string> wasInput = o =>
47 { 54 {
48 if (string.IsNullOrEmpty(o)) return string.Empty; 55 if (string.IsNullOrEmpty(o)) return string.Empty;
49   56  
50 foreach (Filter filter in vassalConfiguration.InputFilters) 57 foreach (var filter in vassalConfiguration.InputFilters)
51 { 58 {
52 switch (filter) 59 switch (filter)
53 { 60 {
54 case Filter.RFC1738: 61 case Filter.RFC1738:
55 o = Web.URLUnescapeDataString(o); 62 o = Web.URLUnescapeDataString(o);
56 break; 63 break;
57 case Filter.RFC3986: 64 case Filter.RFC3986:
58 o = Web.URIUnescapeDataString(o); 65 o = Web.URIUnescapeDataString(o);
59 break; 66 break;
60 case Filter.ENIGMA: 67 case Filter.ENIGMA:
61 o = Cryptography.ENIGMA(o, vassalConfiguration.ENIGMA.rotors.ToArray(), 68 o = Cryptography.ENIGMA(o, vassalConfiguration.ENIGMA.rotors.ToArray(),
62 vassalConfiguration.ENIGMA.plugs.ToArray(), 69 vassalConfiguration.ENIGMA.plugs.ToArray(),
63 vassalConfiguration.ENIGMA.reflector); 70 vassalConfiguration.ENIGMA.reflector);
64 break; 71 break;
65 case Filter.VIGENERE: 72 case Filter.VIGENERE:
66 o = Cryptography.DecryptVIGENERE(o, vassalConfiguration.VIGENERESecret); 73 o = Cryptography.DecryptVIGENERE(o, vassalConfiguration.VIGENERESecret);
67 break; 74 break;
68 case Filter.ATBASH: 75 case Filter.ATBASH:
69 o = Cryptography.ATBASH(o); 76 o = Cryptography.ATBASH(o);
70 break; 77 break;
71 case Filter.BASE64: 78 case Filter.BASE64:
72 o = Encoding.UTF8.GetString(Convert.FromBase64String(o)); 79 o = Encoding.UTF8.GetString(Convert.FromBase64String(o));
73 break; 80 break;
74 } 81 }
75 } 82 }
76 return o; 83 return o;
77 }; 84 };
78   85  
79 /// <summary> 86 /// <summary>
80 /// Corrade's output filter function. 87 /// Corrade's output filter function.
81 /// </summary> 88 /// </summary>
82 private static readonly Func<string, string> wasOutput = o => 89 private static readonly Func<string, string> wasOutput = o =>
83 { 90 {
84 if (string.IsNullOrEmpty(o)) return string.Empty; 91 if (string.IsNullOrEmpty(o)) return string.Empty;
85   92  
86 foreach (Filter filter in vassalConfiguration.OutputFilters) 93 foreach (var filter in vassalConfiguration.OutputFilters)
87 { 94 {
88 switch (filter) 95 switch (filter)
89 { 96 {
90 case Filter.RFC1738: 97 case Filter.RFC1738:
91 o = Web.URLEscapeDataString(o); 98 o = Web.URLEscapeDataString(o);
92 break; 99 break;
93 case Filter.RFC3986: 100 case Filter.RFC3986:
94 o = Web.URIEscapeDataString(o); 101 o = Web.URIEscapeDataString(o);
95 break; 102 break;
96 case Filter.ENIGMA: 103 case Filter.ENIGMA:
97 o = Cryptography.ENIGMA(o, vassalConfiguration.ENIGMA.rotors.ToArray(), 104 o = Cryptography.ENIGMA(o, vassalConfiguration.ENIGMA.rotors.ToArray(),
98 vassalConfiguration.ENIGMA.plugs.ToArray(), 105 vassalConfiguration.ENIGMA.plugs.ToArray(),
99 vassalConfiguration.ENIGMA.reflector); 106 vassalConfiguration.ENIGMA.reflector);
100 break; 107 break;
101 case Filter.VIGENERE: 108 case Filter.VIGENERE:
102 o = Cryptography.EncryptVIGENERE(o, vassalConfiguration.VIGENERESecret); 109 o = Cryptography.EncryptVIGENERE(o, vassalConfiguration.VIGENERESecret);
103 break; 110 break;
104 case Filter.ATBASH: 111 case Filter.ATBASH:
105 o = Cryptography.ATBASH(o); 112 o = Cryptography.ATBASH(o);
106 break; 113 break;
107 case Filter.BASE64: 114 case Filter.BASE64:
108 o = Convert.ToBase64String(Encoding.UTF8.GetBytes(o)); 115 o = Convert.ToBase64String(Encoding.UTF8.GetBytes(o));
109 break; 116 break;
110 } 117 }
111 } 118 }
112 return o; 119 return o;
113 }; 120 };
114   121  
115 private static readonly Action updateCurrentRegionName = () => 122 private static readonly Action updateCurrentRegionName = () =>
116 { 123 {
117 try 124 try
118 { 125 {
119 string result = wasPOST(vassalConfiguration.HTTPServerURL, 126 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
120 KeyValue.Escape(new Dictionary<string, string> 127 KeyValue.Escape(new Dictionary<string, string>
121 { 128 {
122 {"command", "getregiondata"}, 129 {"command", "getregiondata"},
123 {"group", vassalConfiguration.Group}, 130 {"group", vassalConfiguration.Group},
124 {"password", vassalConfiguration.Password}, 131 {"password", vassalConfiguration.Password},
125 {"data", "Name"} 132 {"data", "Name"}
126 }, wasOutput), 60000); 133 }, wasOutput)).Result);
127 bool success; 134 bool success;
128 if (string.IsNullOrEmpty(result) || 135 if (string.IsNullOrEmpty(result) ||
129 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 136 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
130 { 137 {
131 vassalForm.BeginInvoke( 138 vassalForm.BeginInvoke(
132 (MethodInvoker) 139 (MethodInvoker)
133 (() => { vassalForm.StatusText.Text = @"Failed to query Corrade for current region."; })); 140 (() => { vassalForm.StatusText.Text = @"Failed to query Corrade for current region."; }));
134 return; 141 return;
135 } 142 }
136 switch (success) 143 switch (success)
137 { 144 {
138 case true: 145 case true:
139 vassalForm.BeginInvoke((MethodInvoker) (() => 146 vassalForm.BeginInvoke((MethodInvoker) (() =>
140 { 147 {
141 vassalForm.CurrentRegionAt.Visible = true; 148 vassalForm.CurrentRegionAt.Visible = true;
142 vassalForm.CurrentRegionName.Visible = true; 149 vassalForm.CurrentRegionName.Visible = true;
143 vassalForm.CurrentRegionName.Text = 150 vassalForm.CurrentRegionName.Text =
144 CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))).Last(); 151 CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))).Last();
145 })); 152 }));
146 break; 153 break;
147 default: 154 default:
148 vassalForm.BeginInvoke((MethodInvoker) (() => 155 vassalForm.BeginInvoke((MethodInvoker) (() =>
149 { 156 {
150 vassalForm.CurrentRegionAt.Visible = false; 157 vassalForm.CurrentRegionAt.Visible = false;
151 vassalForm.CurrentRegionName.Visible = false; 158 vassalForm.CurrentRegionName.Visible = false;
152 vassalForm.StatusText.Text = @"Error getting current region: " + 159 vassalForm.StatusText.Text = @"Error getting current region: " +
153 wasInput(KeyValue.Get("error", result)); 160 wasInput(KeyValue.Get("error", result));
154 })); 161 }));
155 break; 162 break;
156 } 163 }
157 } 164 }
158 catch (Exception ex) 165 catch (Exception ex)
159 { 166 {
160 vassalForm.BeginInvoke((MethodInvoker) (() => 167 vassalForm.BeginInvoke((MethodInvoker) (() =>
161 { 168 {
162 vassalForm.StatusText.Text = 169 vassalForm.StatusText.Text =
163 @"Error getting current region: " + 170 @"Error getting current region: " +
164 ex.Message; 171 ex.Message;
165 })); 172 }));
166 } 173 }
167 }; 174 };
168   175  
169 public Vassal() 176 public Vassal()
170 { 177 {
171 InitializeComponent(); 178 InitializeComponent();
172 vassalForm = this; 179 vassalForm = this;
173 } 180 }
174   -  
175 /////////////////////////////////////////////////////////////////////////// -  
176 // Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // -  
177 /////////////////////////////////////////////////////////////////////////// -  
178 /// <summary> -  
179 /// Sends a post request to an URL with set key-value pairs. -  
180 /// </summary> 181  
181 /// <param name="URL">the url to send the message to</param> -  
182 /// <param name="message">key-value pairs to send</param> -  
183 /// <param name="millisecondsTimeout">the time in milliseconds for the request to timeout</param> -  
184 private static string wasPOST(string URL, Dictionary<string, string> message, uint millisecondsTimeout) 182 private void ShowToolTip(object sender, EventArgs e)
185 { -  
186 try -  
187 { -  
188 HttpWebRequest request = (HttpWebRequest) WebRequest.Create(URL); -  
189 request.UserAgent = VASSAL_CONSTANTS.USER_AGENT; -  
190 request.Proxy = WebRequest.DefaultWebProxy; 183 {
191 request.Pipelined = true; -  
192 request.KeepAlive = true; -  
193 request.Timeout = (int) millisecondsTimeout; -  
194 request.ReadWriteTimeout = (int) millisecondsTimeout; -  
195 request.AllowAutoRedirect = true; -  
196 request.AllowWriteStreamBuffering = true; -  
197 request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; -  
198 request.Method = WebRequestMethods.Http.Post; -  
199 // set the content type based on chosen output filers -  
200 switch (vassalConfiguration.OutputFilters.Last()) -  
201 { -  
202 case Filter.RFC1738: -  
203 request.ContentType = VASSAL_CONSTANTS.CONTENT_TYPE.WWW_FORM_URLENCODED; -  
204 break; -  
205 default: -  
206 request.ContentType = VASSAL_CONSTANTS.CONTENT_TYPE.TEXT_PLAIN; 184 vassalForm.BeginInvoke(
207 break; -  
208 } -  
209 // send request -  
210 using (Stream requestStream = request.GetRequestStream()) -  
211 { -  
212 using (StreamWriter dataStream = new StreamWriter(requestStream)) -  
213 { -  
214 dataStream.Write(KeyValue.Encode(message)); -  
215 } -  
216 } -  
217 // read response -  
218 using (HttpWebResponse response = (HttpWebResponse) request.GetResponse()) 185 (Action)(() =>
219 { 186 {
-   187 PictureBox pictureBox = sender as PictureBox;
220 using (Stream responseStream = response.GetResponseStream()) 188 if (pictureBox != null)
221 { -  
222 if (responseStream != null) -  
223 { -  
224 using ( 189 {
225 StreamReader streamReader = new StreamReader(responseStream)) -  
226 { -  
227 return streamReader.ReadToEnd(); -  
228 } -  
229 } 190 toolTip1.Show(toolTip1.GetToolTip(pictureBox), pictureBox);
230 } 191 }
231 } -  
232 } -  
233 catch (Exception) -  
234 { -  
235 } -  
236   -  
237 return null; 192 }));
238 } 193 }
239   194  
240 private void RegionSelected(object sender, EventArgs e) 195 private void RegionSelected(object sender, EventArgs e)
241 { 196 {
242 new Thread(() => 197 new Thread(() =>
243 { 198 {
244 try 199 try
245 { 200 {
246 // Stop timers. 201 // Stop timers.
247 vassalTimer.Stop(); 202 vassalTimer.Stop();
248 overviewTabTimer.Stop(); 203 overviewTabTimer.Stop();
249 regionsStateTabTimer.Stop(); 204 regionsStateTabTimer.Stop();
250 residentListTabTimer.Stop(); 205 residentListTabTimer.Stop();
251 estateTopTabTimer.Stop(); 206 estateTopTabTimer.Stop();
252 estateTexturesTabTimer.Stop(); 207 estateTexturesTabTimer.Stop();
253   208  
254 Monitor.Enter(ClientInstanceTeleportLock); 209 Monitor.Enter(ClientInstanceTeleportLock);
255   210  
256 string selectedRegionName = string.Empty; 211 var selectedRegionName = string.Empty;
257 Vector3 selectedRegionPosition = Vector3.Zero; 212 var selectedRegionPosition = Vector3.Zero;
258 bool startTeleport = false; 213 var startTeleport = false;
259 vassalForm.Invoke((MethodInvoker) (() => 214 vassalForm.Invoke((MethodInvoker) (() =>
260 { 215 {
261 ListViewItem listViewItem = LoadedRegionsBox.SelectedItem as ListViewItem; 216 var listViewItem = LoadedRegionsBox.SelectedItem as ListViewItem;
262 switch (listViewItem != null && LoadedRegionsBox.SelectedIndex != -1) 217 switch (listViewItem != null && LoadedRegionsBox.SelectedIndex != -1)
263 { 218 {
264 case true: 219 case true:
265 selectedRegionName = listViewItem.Text; 220 selectedRegionName = listViewItem.Text;
266 selectedRegionPosition = (Vector3) listViewItem.Tag; 221 selectedRegionPosition = (Vector3) listViewItem.Tag;
267 startTeleport = true; 222 startTeleport = true;
268 break; 223 break;
269 default: 224 default:
270 startTeleport = false; 225 startTeleport = false;
271 break; 226 break;
272 } 227 }
273 })); 228 }));
274   229  
275 if (!startTeleport) throw new Exception(); 230 if (!startTeleport) throw new Exception();
276   231  
277 // Announce teleport. 232 // Announce teleport.
278 vassalForm.Invoke((MethodInvoker) (() => 233 vassalForm.Invoke((MethodInvoker) (() =>
279 { 234 {
280 vassalForm.RegionTeleportGroup.Enabled = false; 235 vassalForm.RegionTeleportGroup.Enabled = false;
281 vassalForm.StatusProgress.Value = 0; 236 vassalForm.StatusProgress.Value = 0;
282 vassalForm.StatusText.Text = @"Teleporting to " + selectedRegionName; 237 vassalForm.StatusText.Text = @"Teleporting to " + selectedRegionName;
283 })); 238 }));
284   239  
285 // Pause for teleport (10 teleports / 15s allowed). 240 // Pause for teleport (10 teleports / 15s allowed).
286 Thread.Sleep(700); 241 Thread.Sleep(700);
287   242  
288 int elapsedSeconds = 0; 243 var elapsedSeconds = 0;
289 Timer teleportTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); 244 var teleportTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds);
290 teleportTimer.Elapsed += (o, p) => 245 teleportTimer.Elapsed += (o, p) =>
291 { 246 {
292 vassalForm.Invoke((MethodInvoker) (() => 247 vassalForm.Invoke((MethodInvoker) (() =>
293 { 248 {
294 vassalForm.StatusProgress.Value = 249 vassalForm.StatusProgress.Value =
295 Math.Min( 250 Math.Min(
296 (int) 251 (int)
297 (100d* 252 (100d*
298 (TimeSpan.FromSeconds(++elapsedSeconds).TotalMilliseconds/ 253 (TimeSpan.FromSeconds(++elapsedSeconds).TotalMilliseconds/
299 vassalConfiguration.TeleportTimeout)), 100); 254 vassalConfiguration.TeleportTimeout)), 100);
300 })); 255 }));
301 }; 256 };
302 teleportTimer.Start(); 257 teleportTimer.Start();
303 string result = null; 258 string result = null;
304 ManualResetEvent receivedPOST = new ManualResetEvent(false); 259 var receivedPOST = new ManualResetEvent(false);
305 new Thread(() => 260 new Thread(() =>
306 { 261 {
307 result = wasInput(wasPOST(vassalConfiguration.HTTPServerURL, 262 result = wasInput(Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
308 KeyValue.Escape(new Dictionary<string, string> 263 KeyValue.Escape(new Dictionary<string, string>
309 { 264 {
310 {"command", "teleport"}, 265 {"command", "teleport"},
311 {"group", vassalConfiguration.Group}, 266 {"group", vassalConfiguration.Group},
312 {"password", vassalConfiguration.Password}, 267 {"password", vassalConfiguration.Password},
313 {"region", selectedRegionName}, 268 {"region", selectedRegionName},
314 {"position", selectedRegionPosition.ToString()}, 269 {"position", selectedRegionPosition.ToString()},
315 {"fly", "True"} 270 {"fly", "True"}
316 }, wasOutput), vassalConfiguration.TeleportTimeout)); 271 }, wasOutput)).Result));
317 receivedPOST.Set(); 272 receivedPOST.Set();
318 }) {IsBackground = true}.Start(); 273 }) {IsBackground = true}.Start();
319 receivedPOST.WaitOne((int) vassalConfiguration.TeleportTimeout, false); 274 receivedPOST.WaitOne((int) vassalConfiguration.TeleportTimeout, false);
320 teleportTimer.Stop(); 275 teleportTimer.Stop();
321 switch (!string.IsNullOrEmpty(result) && KeyValue.Get("success", result) == "True") 276 switch (!string.IsNullOrEmpty(result) && KeyValue.Get("success", result) == "True")
322 { 277 {
323 case true: 278 case true:
324 vassalForm.Invoke((MethodInvoker) (() => 279 vassalForm.Invoke((MethodInvoker) (() =>
325 { 280 {
326 vassalForm.StatusText.Text = @"Now at " + selectedRegionName; 281 vassalForm.StatusText.Text = @"Now at " + selectedRegionName;
327 vassalForm.CurrentRegionName.Text = selectedRegionName; 282 vassalForm.CurrentRegionName.Text = selectedRegionName;
328 })); 283 }));
329 break; 284 break;
330 default: 285 default:
331 switch (!string.IsNullOrEmpty(result)) 286 switch (!string.IsNullOrEmpty(result))
332 { 287 {
333 case true: 288 case true:
334 vassalForm.Invoke((MethodInvoker) (() => 289 vassalForm.Invoke((MethodInvoker) (() =>
335 { 290 {
336 vassalForm.StatusText.Text = @"Failed teleporting to " + selectedRegionName + 291 vassalForm.StatusText.Text = @"Failed teleporting to " + selectedRegionName +
337 @": " + 292 @": " +
338 KeyValue.Get("error", result); 293 KeyValue.Get("error", result);
339 })); 294 }));
340 break; 295 break;
341 default: 296 default:
342 vassalForm.Invoke( 297 vassalForm.Invoke(
343 (MethodInvoker) 298 (MethodInvoker)
344 (() => 299 (() =>
345 { 300 {
346 vassalForm.StatusText.Text = @"Failed teleporting to " + 301 vassalForm.StatusText.Text = @"Failed teleporting to " +
347 selectedRegionName; 302 selectedRegionName;
348 })); 303 }));
349 break; 304 break;
350 } 305 }
351 break; 306 break;
352 } 307 }
353 } 308 }
354 catch (Exception ex) 309 catch (Exception ex)
355 { 310 {
356 vassalForm.Invoke( 311 vassalForm.Invoke(
357 (MethodInvoker) 312 (MethodInvoker)
358 (() => { vassalForm.StatusText.Text = @"Error communicating with Corrade: " + ex.Message; })); 313 (() => { vassalForm.StatusText.Text = @"Error communicating with Corrade: " + ex.Message; }));
359 } 314 }
360 finally 315 finally
361 { 316 {
362 vassalForm.BeginInvoke((MethodInvoker) (() => 317 vassalForm.BeginInvoke((MethodInvoker) (() =>
363 { 318 {
364 vassalForm.StatusProgress.Value = 100; 319 vassalForm.StatusProgress.Value = 100;
365 vassalForm.RegionTeleportGroup.Enabled = true; 320 vassalForm.RegionTeleportGroup.Enabled = true;
366 // Set the map image to the loading spinner. 321 // Set the map image to the loading spinner.
367 Assembly thisAssembly = Assembly.GetExecutingAssembly(); 322 var thisAssembly = Assembly.GetExecutingAssembly();
368 Stream file = 323 var file =
369 thisAssembly.GetManifestResourceStream("Vassal.img.loading.gif"); 324 thisAssembly.GetManifestResourceStream("Vassal.img.loading.gif");
370 switch (file != null) 325 switch (file != null)
371 { 326 {
372 case true: 327 case true:
373 vassalForm.Invoke((MethodInvoker) (() => 328 vassalForm.Invoke((MethodInvoker) (() =>
374 { 329 {
375 RegionAvatarsMap.SizeMode = PictureBoxSizeMode.CenterImage; 330 RegionAvatarsMap.SizeMode = PictureBoxSizeMode.CenterImage;
376 RegionAvatarsMap.Image = Image.FromStream(file); 331 RegionAvatarsMap.Image = Image.FromStream(file);
377 RegionAvatarsMap.Refresh(); 332 RegionAvatarsMap.Refresh();
378 })); 333 }));
379 break; 334 break;
380 } 335 }
381 // Clear the resident list table. 336 // Clear the resident list table.
382 ResidentListGridView.Rows.Clear(); 337 ResidentListGridView.Rows.Clear();
383 // Clear the top scripts table. 338 // Clear the top scripts table.
384 TopScriptsGridView.Rows.Clear(); 339 TopScriptsGridView.Rows.Clear();
385 // Clear the top colliders table. 340 // Clear the top colliders table.
386 TopCollidersGridView.Rows.Clear(); 341 TopCollidersGridView.Rows.Clear();
387 // Clear the estate list table. 342 // Clear the estate list table.
388 EstateListGridView.Rows.Clear(); 343 EstateListGridView.Rows.Clear();
389 // Clear the estate list selection box. 344 // Clear the estate list selection box.
390 EstateListSelectBox.SelectedIndex = -1; 345 EstateListSelectBox.SelectedIndex = -1;
391 // Invalidate data for overview tab. 346 // Invalidate data for overview tab.
392 vassalForm.CurrentRegionAt.Visible = false; 347 vassalForm.CurrentRegionAt.Visible = false;
393 vassalForm.CurrentRegionName.Visible = false; 348 vassalForm.CurrentRegionName.Visible = false;
394 Agents.Text = string.Empty; 349 Agents.Text = string.Empty;
395 Agents.Enabled = false; 350 Agents.Enabled = false;
396 LastLag.Text = string.Empty; 351 LastLag.Text = string.Empty;
397 LastLag.Enabled = false; 352 LastLag.Enabled = false;
398 Dilation.Text = string.Empty; 353 Dilation.Text = string.Empty;
399 Dilation.Enabled = false; 354 Dilation.Enabled = false;
400 FPS.Text = string.Empty; 355 FPS.Text = string.Empty;
401 FPS.Enabled = false; 356 FPS.Enabled = false;
402 PhysicsFPS.Text = string.Empty; 357 PhysicsFPS.Text = string.Empty;
403 PhysicsFPS.Enabled = false; 358 PhysicsFPS.Enabled = false;
404 ActiveScripts.Text = string.Empty; 359 ActiveScripts.Text = string.Empty;
405 ActiveScripts.Enabled = false; 360 ActiveScripts.Enabled = false;
406 ScriptTime.Text = string.Empty; 361 ScriptTime.Text = string.Empty;
407 ScriptTime.Enabled = false; 362 ScriptTime.Enabled = false;
408 FrameTime.Text = string.Empty; 363 FrameTime.Text = string.Empty;
409 FrameTime.Enabled = false; 364 FrameTime.Enabled = false;
410 ScriptedObjects.Text = string.Empty; 365 ScriptedObjects.Text = string.Empty;
411 ScriptedObjects.Enabled = false; 366 ScriptedObjects.Enabled = false;
412 PhysicsTime.Text = string.Empty; 367 PhysicsTime.Text = string.Empty;
413 PhysicsTime.Enabled = false; 368 PhysicsTime.Enabled = false;
414 NetTime.Text = string.Empty; 369 NetTime.Text = string.Empty;
415 NetTime.Enabled = false; 370 NetTime.Enabled = false;
416 Objects.Text = string.Empty; 371 Objects.Text = string.Empty;
417 Objects.Enabled = false; 372 Objects.Enabled = false;
418 })); 373 }));
419   374  
420 Monitor.Exit(ClientInstanceTeleportLock); 375 Monitor.Exit(ClientInstanceTeleportLock);
421   376  
422 // start timers 377 // start timers
423 vassalTimer.Start(); 378 vassalTimer.Start();
424 overviewTabTimer.Start(); 379 overviewTabTimer.Start();
425 regionsStateTabTimer.Start(); 380 regionsStateTabTimer.Start();
426 residentListTabTimer.Start(); 381 residentListTabTimer.Start();
427 estateTopTabTimer.Start(); 382 estateTopTabTimer.Start();
428 estateTexturesTabTimer.Start(); 383 estateTexturesTabTimer.Start();
429 } 384 }
430 }) 385 })
431 {IsBackground = true}.Start(); 386 {IsBackground = true}.Start();
432 } 387 }
433   388  
434 private void SettingsRequested(object sender, EventArgs e) 389 private void SettingsRequested(object sender, EventArgs e)
435 { 390 {
436 vassalForm.BeginInvoke((MethodInvoker) (() => { VassalStatusGroup.Enabled = false; })); 391 vassalForm.BeginInvoke((MethodInvoker) (() => { VassalStatusGroup.Enabled = false; }));
437 SettingsForm settingsForm = new SettingsForm {TopMost = true}; 392 var settingsForm = new SettingsForm {TopMost = true};
438 settingsForm.Show(); 393 settingsForm.Show();
439 } 394 }
440   395  
441 private void VassalShown(object sender, EventArgs e) 396 private void VassalShown(object sender, EventArgs e)
442 { 397 {
443 // Set the version 398 // Set the version
444 vassalForm.Version.Text = @"v" + VASSAL_CONSTANTS.VASSAL_VERSION; 399 vassalForm.Version.Text = @"v" + VASSAL_CONSTANTS.VASSAL_VERSION;
445   400  
446 // Disable estate manager tabs since we will enable these dynamically. 401 // Disable estate manager tabs since we will enable these dynamically.
447 EstateTopTab.Enabled = false; 402 EstateTopTab.Enabled = false;
448 EstateListsTab.Enabled = false; 403 EstateListsTab.Enabled = false;
449 ResidentListBanGroup.Enabled = false; 404 ResidentListBanGroup.Enabled = false;
450 ResidentListTeleportHomeGroup.Enabled = false; 405 ResidentListTeleportHomeGroup.Enabled = false;
451 EstateTerrainDownloadUploadGroup.Enabled = false; 406 EstateTerrainDownloadUploadGroup.Enabled = false;
452 EstateVariablesGroup.Enabled = false; 407 EstateVariablesGroup.Enabled = false;
453 // Estate textures 408 // Estate textures
454 RegionTexturesLowUUIDApplyBox.Enabled = false; 409 RegionTexturesLowUUIDApplyBox.Enabled = false;
455 RegionTexturesLowUUIDApplyButton.Enabled = false; 410 RegionTexturesLowUUIDApplyButton.Enabled = false;
456 RegionTexturesMiddleLowUUIDApplyBox.Enabled = false; 411 RegionTexturesMiddleLowUUIDApplyBox.Enabled = false;
457 RegionTexturesMiddleLowUUIDApplyButton.Enabled = false; 412 RegionTexturesMiddleLowUUIDApplyButton.Enabled = false;
458 RegionTexturesMiddleHighUUIDApplyBox.Enabled = false; 413 RegionTexturesMiddleHighUUIDApplyBox.Enabled = false;
459 RegionTexturesMiddleHighUUIDApplyButton.Enabled = false; 414 RegionTexturesMiddleHighUUIDApplyButton.Enabled = false;
460 RegionTexturesHighUUIDApplyBox.Enabled = false; 415 RegionTexturesHighUUIDApplyBox.Enabled = false;
461 RegionTexturesHighUUIDApplyButton.Enabled = false; 416 RegionTexturesHighUUIDApplyButton.Enabled = false;
462   417  
463 // Get the configuration file settings if it exists. 418 // Get the configuration file settings if it exists.
464 if (File.Exists(VASSAL_CONSTANTS.VASSAL_CONFIGURATION_FILE)) 419 if (File.Exists(VASSAL_CONSTANTS.VASSAL_CONFIGURATION_FILE))
465 { 420 {
466 // Load the configuration. 421 // Load the configuration.
467 VassalConfiguration.Load(VASSAL_CONSTANTS.VASSAL_CONFIGURATION_FILE, ref vassalConfiguration); 422 VassalConfiguration.Load(VASSAL_CONSTANTS.VASSAL_CONFIGURATION_FILE, ref vassalConfiguration);
468 // Apply settings 423 // Apply settings
469 RegionRestartDelayBox.Text = vassalConfiguration.RegionRestartDelay.ToString(Utils.EnUsCulture); 424 RegionRestartDelayBox.Text = vassalConfiguration.RegionRestartDelay.ToString(Utils.EnUsCulture);
-   425 // HTTP
-   426 string mediaType;
-   427 switch (vassalConfiguration.InputFilters.LastOrDefault())
-   428 {
-   429 case Filter.RFC1738:
-   430 mediaType = @"application/x-www-form-urlencoded";
-   431 break;
-   432 default:
-   433 mediaType = @"text/plain";
-   434 break;
-   435 }
-   436 // Create HTTP Client
-   437 Vassal.HTTPClient = new Web.wasHTTPClient(new ProductInfoHeaderValue(@"Vassal",
-   438 Vassal.VASSAL_VERSION), new CookieContainer(), mediaType, vassalConfiguration.ServicesTimeout);
470 } 439 }
471   440  
472 // Get all the regions if they exist. 441 // Get all the regions if they exist.
473 if (File.Exists(VASSAL_CONSTANTS.VASSAL_REGIONS)) 442 if (File.Exists(VASSAL_CONSTANTS.VASSAL_REGIONS))
474 { 443 {
475 Vector3 localPosition; 444 Vector3 localPosition;
476 List<KeyValuePair<string, Vector3>> ConfiguredRegions = new List<KeyValuePair<string, Vector3>>( 445 var ConfiguredRegions = new List<KeyValuePair<string, Vector3>>(
477 File.ReadAllLines(VASSAL_CONSTANTS.VASSAL_REGIONS) 446 File.ReadAllLines(VASSAL_CONSTANTS.VASSAL_REGIONS)
478 .Select(o => new List<string>(CSV.ToEnumerable(o))) 447 .Select(o => new List<string>(CSV.ToEnumerable(o)))
479 .Where(o => o.Count == 2) 448 .Where(o => o.Count == 2)
480 .ToDictionary(o => o.First(), 449 .ToDictionary(o => o.First(),
481 p => 450 p =>
482 Vector3.TryParse(p.Last(), out localPosition) 451 Vector3.TryParse(p.Last(), out localPosition)
483 ? localPosition 452 ? localPosition
484 : Vector3.Zero).OrderBy(o => o.Key).ToDictionary(o => o.Key, o => o.Value)); 453 : Vector3.Zero).OrderBy(o => o.Key).ToDictionary(o => o.Key, o => o.Value));
485 // Populate the loaded regions. 454 // Populate the loaded regions.
486 LoadedRegionsBox.Items.Clear(); 455 LoadedRegionsBox.Items.Clear();
487 LoadedRegionsBox.Items.AddRange( 456 LoadedRegionsBox.Items.AddRange(
488 ConfiguredRegions.Select(o => (object) new ListViewItem {Text = o.Key, Tag = o.Value}) 457 ConfiguredRegions.Select(o => (object) new ListViewItem {Text = o.Key, Tag = o.Value})
489 .ToArray()); 458 .ToArray());
490 // Populate the batch restart grid view. 459 // Populate the batch restart grid view.
491 BatchRestartGridView.Rows.Clear(); 460 BatchRestartGridView.Rows.Clear();
492 foreach (KeyValuePair<string, Vector3> data in ConfiguredRegions) 461 foreach (var data in ConfiguredRegions)
493 { 462 {
494 BatchRestartGridView.Rows.Add(data.Key, data.Value.ToString()); 463 BatchRestartGridView.Rows.Add(data.Key, data.Value.ToString());
495 } 464 }
-   465 // Populate the batch covenant grid view.
-   466 BatchSetCovenantGridView.Rows.Clear();
-   467 foreach (var data in ConfiguredRegions)
-   468 {
-   469 BatchSetCovenantGridView.Rows.Add(data.Key, data.Value.ToString());
-   470 }
496 // Populate the regions state grid view. 471 // Populate the regions state grid view.
497 foreach (KeyValuePair<string, Vector3> data in ConfiguredRegions) 472 foreach (var data in ConfiguredRegions)
498 { 473 {
499 RegionsStateGridView.Rows.Add(data.Key, "Check pening..."); 474 RegionsStateGridView.Rows.Add(data.Key, "Check pening...");
500 } 475 }
501 } 476 }
502   477  
503 // Start the vassal timer. 478 // Start the vassal timer.
504 vassalTimer.Elapsed += (o, p) => 479 vassalTimer.Elapsed += (o, p) =>
505 { 480 {
506 if (!Monitor.TryEnter(ClientInstanceTeleportLock)) 481 if (!Monitor.TryEnter(ClientInstanceTeleportLock))
507 return; 482 return;
508 try 483 try
509 { 484 {
510 // Check Corrade connection status. 485 // Check Corrade connection status.
511 TcpClient tcpClient = new TcpClient(); 486 var tcpClient = new TcpClient();
512 Uri uri = new Uri(vassalConfiguration.HTTPServerURL); 487 var uri = new Uri(vassalConfiguration.HTTPServerURL);
513 tcpClient.Connect(uri.Host, uri.Port); 488 tcpClient.Connect(uri.Host, uri.Port);
514 // port open 489 // port open
515 vassalForm.BeginInvoke((MethodInvoker) (() => 490 vassalForm.BeginInvoke((MethodInvoker) (() =>
516 { 491 {
517 vassalForm.CurrentRegionAt.Visible = true; 492 vassalForm.CurrentRegionAt.Visible = true;
518 vassalForm.CurrentRegionName.Visible = true; 493 vassalForm.CurrentRegionName.Visible = true;
519 Assembly thisAssembly = Assembly.GetExecutingAssembly(); 494 var thisAssembly = Assembly.GetExecutingAssembly();
520 Stream file = 495 var file =
521 thisAssembly.GetManifestResourceStream("Vassal.img.online.png"); 496 thisAssembly.GetManifestResourceStream("Vassal.img.online.png");
522 switch (file != null) 497 switch (file != null)
523 { 498 {
524 case true: 499 case true:
525 vassalForm.BeginInvoke((MethodInvoker) (() => 500 vassalForm.BeginInvoke((MethodInvoker) (() =>
526 { 501 {
527 ConnectionStatusPictureBox.Image = Image.FromStream(file); 502 ConnectionStatusPictureBox.Image = Image.FromStream(file);
528 ConnectionStatusPictureBox.Refresh(); 503 ConnectionStatusPictureBox.Refresh();
529 })); 504 }));
530 break; 505 break;
531 } 506 }
532 Tabs.Enabled = true; 507 Tabs.Enabled = true;
533 RegionTeleportGroup.Enabled = true; 508 RegionTeleportGroup.Enabled = true;
534 })); 509 }));
535 } 510 }
536 catch (Exception) 511 catch (Exception)
537 { 512 {
538 // port closed 513 // port closed
539 vassalForm.BeginInvoke((MethodInvoker) (() => 514 vassalForm.BeginInvoke((MethodInvoker) (() =>
540 { 515 {
541 vassalForm.CurrentRegionAt.Visible = false; 516 vassalForm.CurrentRegionAt.Visible = false;
542 vassalForm.CurrentRegionName.Visible = false; 517 vassalForm.CurrentRegionName.Visible = false;
543 Assembly thisAssembly = Assembly.GetExecutingAssembly(); 518 var thisAssembly = Assembly.GetExecutingAssembly();
544 Stream file = 519 var file =
545 thisAssembly.GetManifestResourceStream("Vassal.img.offline.png"); 520 thisAssembly.GetManifestResourceStream("Vassal.img.offline.png");
546 switch (file != null) 521 switch (file != null)
547 { 522 {
548 case true: 523 case true:
549 vassalForm.BeginInvoke((MethodInvoker) (() => 524 vassalForm.BeginInvoke((MethodInvoker) (() =>
550 { 525 {
551 ConnectionStatusPictureBox.Image = Image.FromStream(file); 526 ConnectionStatusPictureBox.Image = Image.FromStream(file);
552 ConnectionStatusPictureBox.Refresh(); 527 ConnectionStatusPictureBox.Refresh();
553 })); 528 }));
554 break; 529 break;
555 } 530 }
556 Tabs.Enabled = false; 531 Tabs.Enabled = false;
557 RegionTeleportGroup.Enabled = false; 532 RegionTeleportGroup.Enabled = false;
558 })); 533 }));
559 } 534 }
560   535  
561 try 536 try
562 { 537 {
563 // Get the simulator name and if we are an estate manager. 538 // Get the simulator name and if we are an estate manager.
564 string result = wasPOST(vassalConfiguration.HTTPServerURL, 539 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
565 KeyValue.Escape(new Dictionary<string, string> 540 KeyValue.Escape(new Dictionary<string, string>
566 { 541 {
567 {"command", "getregiondata"}, 542 {"command", "getregiondata"},
568 {"group", vassalConfiguration.Group}, 543 {"group", vassalConfiguration.Group},
569 {"password", vassalConfiguration.Password}, 544 {"password", vassalConfiguration.Password},
570 { 545 {
571 "data", CSV.FromEnumerable(new[] 546 "data", CSV.FromEnumerable(new[]
572 { 547 {
573 "Name", 548 "Name",
574 "IsEstateManager" 549 "IsEstateManager"
575 }) 550 })
576 } 551 }
577 }, wasOutput), vassalConfiguration.DataTimeout); 552 }, wasOutput)).Result);
578   553  
579 bool success; 554 bool success;
580 if (string.IsNullOrEmpty(result) || 555 if (string.IsNullOrEmpty(result) ||
581 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 556 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
582 throw new Exception(); 557 throw new Exception();
583   558  
584 List<string> data = CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))).ToList(); 559 var data = CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))).ToList();
585 if (data.Count.Equals(0)) 560 if (data.Count.Equals(0))
586 throw new Exception(); 561 throw new Exception();
587   562  
588 vassalForm.BeginInvoke((MethodInvoker) (() => 563 vassalForm.BeginInvoke((MethodInvoker) (() =>
589 { 564 {
590 // Drop access to features if we are not estate managers. 565 // Drop access to features if we are not estate managers.
591 bool isEstateManager; 566 bool isEstateManager;
592 switch ( 567 switch (
593 bool.TryParse(data[data.IndexOf("IsEstateManager") + 1], out isEstateManager) && 568 bool.TryParse(data[data.IndexOf("IsEstateManager") + 1], out isEstateManager) &&
594 isEstateManager) 569 isEstateManager)
595 { 570 {
596 case true: // we are an estate manager 571 case true: // we are an estate manager
597 EstateTopTab.Enabled = true; 572 EstateTopTab.Enabled = true;
598 EstateListsTab.Enabled = true; 573 EstateListsTab.Enabled = true;
599 ResidentListBanGroup.Enabled = true; 574 ResidentListBanGroup.Enabled = true;
600 ResidentListTeleportHomeGroup.Enabled = true; 575 ResidentListTeleportHomeGroup.Enabled = true;
601 EstateTerrainDownloadUploadGroup.Enabled = true; 576 EstateTerrainDownloadUploadGroup.Enabled = true;
602 EstateVariablesGroup.Enabled = true; 577 EstateVariablesGroup.Enabled = true;
603 RegionToolsRegionDebugGroup.Enabled = true; 578 RegionToolsRegionDebugGroup.Enabled = true;
604 RegionToolsRegionInfoGroup.Enabled = true; 579 RegionToolsRegionInfoGroup.Enabled = true;
605 // Estate textures 580 // Estate textures
606 RegionTexturesLowUUIDApplyBox.Enabled = true; 581 RegionTexturesLowUUIDApplyBox.Enabled = true;
607 RegionTexturesLowUUIDApplyButton.Enabled = true; 582 RegionTexturesLowUUIDApplyButton.Enabled = true;
608 RegionTexturesMiddleLowUUIDApplyBox.Enabled = true; 583 RegionTexturesMiddleLowUUIDApplyBox.Enabled = true;
609 RegionTexturesMiddleLowUUIDApplyButton.Enabled = true; 584 RegionTexturesMiddleLowUUIDApplyButton.Enabled = true;
610 RegionTexturesMiddleHighUUIDApplyBox.Enabled = true; 585 RegionTexturesMiddleHighUUIDApplyBox.Enabled = true;
611 RegionTexturesMiddleHighUUIDApplyButton.Enabled = true; 586 RegionTexturesMiddleHighUUIDApplyButton.Enabled = true;
612 RegionTexturesHighUUIDApplyBox.Enabled = true; 587 RegionTexturesHighUUIDApplyBox.Enabled = true;
613 RegionTexturesHighUUIDApplyButton.Enabled = true; 588 RegionTexturesHighUUIDApplyButton.Enabled = true;
614 break; 589 break;
615 default: 590 default:
616 EstateTopTab.Enabled = false; 591 EstateTopTab.Enabled = false;
617 EstateListsTab.Enabled = false; 592 EstateListsTab.Enabled = false;
618 ResidentListBanGroup.Enabled = false; 593 ResidentListBanGroup.Enabled = false;
619 ResidentListTeleportHomeGroup.Enabled = false; 594 ResidentListTeleportHomeGroup.Enabled = false;
620 EstateTerrainDownloadUploadGroup.Enabled = false; 595 EstateTerrainDownloadUploadGroup.Enabled = false;
621 EstateVariablesGroup.Enabled = false; 596 EstateVariablesGroup.Enabled = false;
622 RegionToolsRegionDebugGroup.Enabled = false; 597 RegionToolsRegionDebugGroup.Enabled = false;
623 RegionToolsRegionInfoGroup.Enabled = false; 598 RegionToolsRegionInfoGroup.Enabled = false;
624 // Estate textures 599 // Estate textures
625 RegionTexturesLowUUIDApplyBox.Enabled = false; 600 RegionTexturesLowUUIDApplyBox.Enabled = false;
626 RegionTexturesLowUUIDApplyButton.Enabled = false; 601 RegionTexturesLowUUIDApplyButton.Enabled = false;
627 RegionTexturesMiddleLowUUIDApplyBox.Enabled = false; 602 RegionTexturesMiddleLowUUIDApplyBox.Enabled = false;
628 RegionTexturesMiddleLowUUIDApplyButton.Enabled = false; 603 RegionTexturesMiddleLowUUIDApplyButton.Enabled = false;
629 RegionTexturesMiddleHighUUIDApplyBox.Enabled = false; 604 RegionTexturesMiddleHighUUIDApplyBox.Enabled = false;
630 RegionTexturesMiddleHighUUIDApplyButton.Enabled = false; 605 RegionTexturesMiddleHighUUIDApplyButton.Enabled = false;
631 RegionTexturesHighUUIDApplyBox.Enabled = false; 606 RegionTexturesHighUUIDApplyBox.Enabled = false;
632 RegionTexturesHighUUIDApplyButton.Enabled = false; 607 RegionTexturesHighUUIDApplyButton.Enabled = false;
633 break; 608 break;
634 } 609 }
635   610  
636 // Show the region name. 611 // Show the region name.
637 vassalForm.CurrentRegionName.Text = data[data.IndexOf("Name") + 1]; 612 vassalForm.CurrentRegionName.Text = data[data.IndexOf("Name") + 1];
638 vassalForm.CurrentRegionAt.Visible = true; 613 vassalForm.CurrentRegionAt.Visible = true;
639 vassalForm.CurrentRegionName.Visible = true; 614 vassalForm.CurrentRegionName.Visible = true;
640 })); 615 }));
641 } 616 }
642 catch (Exception) 617 catch (Exception)
643 { 618 {
644 } 619 }
645   620  
646 Monitor.Exit(ClientInstanceTeleportLock); 621 Monitor.Exit(ClientInstanceTeleportLock);
647 }; 622 };
648 vassalTimer.Start(); 623 vassalTimer.Start();
649   624  
650 // Start the overview timer. 625 // Start the overview timer.
651 overviewTabTimer.Elapsed += (o, p) => 626 overviewTabTimer.Elapsed += (o, p) =>
652 { 627 {
653 // Do not do anything in case the tab is not selected. 628 // Do not do anything in case the tab is not selected.
654 bool run = false; 629 var run = false;
655 vassalForm.Invoke((MethodInvoker) (() => { run = Tabs.SelectedTab.Equals(OverviewTab); })); 630 vassalForm.Invoke((MethodInvoker) (() => { run = Tabs.SelectedTab.Equals(OverviewTab); }));
656   631  
657 if (!run) 632 if (!run)
658 { 633 {
659 overviewTabTimer.Stop(); 634 overviewTabTimer.Stop();
660 return; 635 return;
661 } 636 }
662   637  
663 overviewTabTimer.Stop(); 638 overviewTabTimer.Stop();
664   639  
665 try 640 try
666 { 641 {
667 // Start measuring the lag to Corrade. 642 // Start measuring the lag to Corrade.
668 Stopwatch stopWatch = new Stopwatch(); 643 var stopWatch = new Stopwatch();
669 stopWatch.Start(); 644 stopWatch.Start();
670 // Get the statistics. 645 // Get the statistics.
671 string result = wasPOST(vassalConfiguration.HTTPServerURL, 646 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
672 KeyValue.Escape(new Dictionary<string, string> 647 KeyValue.Escape(new Dictionary<string, string>
673 { 648 {
674 {"command", "getregiondata"}, 649 {"command", "getregiondata"},
675 {"group", vassalConfiguration.Group}, 650 {"group", vassalConfiguration.Group},
676 {"password", vassalConfiguration.Password}, 651 {"password", vassalConfiguration.Password},
677 { 652 {
678 "data", CSV.FromEnumerable(new[] 653 "data", CSV.FromEnumerable(new[]
679 { 654 {
680 "Agents", 655 "Agents",
681 "LastLag", 656 "LastLag",
682 "Dilation", 657 "Dilation",
683 "FPS", 658 "FPS",
684 "PhysicsFPS", 659 "PhysicsFPS",
685 "ActiveScripts", 660 "ActiveScripts",
686 "ScriptTime", 661 "ScriptTime",
687 "Objects", 662 "Objects",
688 "FrameTime", 663 "FrameTime",
689 "ScriptedObjects", 664 "ScriptedObjects",
690 "PhysicsTime", 665 "PhysicsTime",
691 "NetTime", 666 "NetTime",
692 "AvatarPositions" 667 "AvatarPositions"
693 }) 668 })
694 } 669 }
695 }, wasOutput), vassalConfiguration.DataTimeout); 670 }, wasOutput)).Result);
696 stopWatch.Stop(); 671 stopWatch.Stop();
697   672  
698 bool success; 673 bool success;
699 if (string.IsNullOrEmpty(result) || 674 if (string.IsNullOrEmpty(result) ||
700 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 675 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
701 throw new Exception(); 676 throw new Exception();
702   677  
703 List<string> data = CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))).ToList(); 678 var data = CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))).ToList();
704 if (data.Count.Equals(0)) 679 if (data.Count.Equals(0))
705 throw new Exception(); 680 throw new Exception();
706   681  
707 vassalForm.BeginInvoke((MethodInvoker) (() => 682 vassalForm.BeginInvoke((MethodInvoker) (() =>
708 { 683 {
709 // Populate the overview tab. 684 // Populate the overview tab.
710 Agents.Text = data[data.IndexOf("Agents") + 1]; 685 Agents.Text = data[data.IndexOf("Agents") + 1];
711 Agents.Enabled = true; 686 Agents.Enabled = true;
712 LastLag.Text = data[data.IndexOf("LastLag") + 1]; 687 LastLag.Text = data[data.IndexOf("LastLag") + 1];
713 LastLag.Enabled = true; 688 LastLag.Enabled = true;
714 Dilation.Text = data[data.IndexOf("Dilation") + 1]; 689 Dilation.Text = data[data.IndexOf("Dilation") + 1];
715 Dilation.Enabled = true; 690 Dilation.Enabled = true;
716 FPS.Text = data[data.IndexOf("FPS") + 1]; 691 FPS.Text = data[data.IndexOf("FPS") + 1];
717 FPS.Enabled = true; 692 FPS.Enabled = true;
718 PhysicsFPS.Text = data[data.IndexOf("PhysicsFPS") + 1]; 693 PhysicsFPS.Text = data[data.IndexOf("PhysicsFPS") + 1];
719 PhysicsFPS.Enabled = true; 694 PhysicsFPS.Enabled = true;
720 ActiveScripts.Text = data[data.IndexOf("ActiveScripts") + 1]; 695 ActiveScripts.Text = data[data.IndexOf("ActiveScripts") + 1];
721 ActiveScripts.Enabled = true; 696 ActiveScripts.Enabled = true;
722 ScriptTime.Text = data[data.IndexOf("ScriptTime") + 1]; 697 ScriptTime.Text = data[data.IndexOf("ScriptTime") + 1];
723 ScriptTime.Enabled = true; 698 ScriptTime.Enabled = true;
724 FrameTime.Text = data[data.IndexOf("FrameTime") + 1]; 699 FrameTime.Text = data[data.IndexOf("FrameTime") + 1];
725 FrameTime.Enabled = true; 700 FrameTime.Enabled = true;
726 ScriptedObjects.Text = data[data.IndexOf("ScriptedObjects") + 1]; 701 ScriptedObjects.Text = data[data.IndexOf("ScriptedObjects") + 1];
727 ScriptedObjects.Enabled = true; 702 ScriptedObjects.Enabled = true;
728 PhysicsTime.Text = data[data.IndexOf("PhysicsTime") + 1]; 703 PhysicsTime.Text = data[data.IndexOf("PhysicsTime") + 1];
729 PhysicsTime.Enabled = true; 704 PhysicsTime.Enabled = true;
730 NetTime.Text = data[data.IndexOf("NetTime") + 1]; 705 NetTime.Text = data[data.IndexOf("NetTime") + 1];
731 NetTime.Enabled = true; 706 NetTime.Enabled = true;
732 Objects.Text = data[data.IndexOf("Objects") + 1]; 707 Objects.Text = data[data.IndexOf("Objects") + 1];
733 Objects.Enabled = true; 708 Objects.Enabled = true;
734   709  
735 // Show the overview lag time. 710 // Show the overview lag time.
736 CorradePollTimeDial.Value = 711 CorradePollTimeDial.Value =
737 (float) Math.Min(TimeSpan.FromMilliseconds(stopWatch.ElapsedMilliseconds).TotalSeconds, 712 (float) Math.Min(TimeSpan.FromMilliseconds(stopWatch.ElapsedMilliseconds).TotalSeconds,
738 CorradePollTimeDial.MaxValue); 713 CorradePollTimeDial.MaxValue);
739 })); 714 }));
740   715  
741 // Get avatar positions. 716 // Get avatar positions.
742 // Pattern: [...], X, 10, Y, 63, Z, 200, [...], X, 52, Y, 73, Z, 55, [...[...]] 717 // Pattern: [...], X, 10, Y, 63, Z, 200, [...], X, 52, Y, 73, Z, 55, [...[...]]
743 float X = 0, Y = 0, Z = 0; 718 float X = 0, Y = 0, Z = 0;
744 List<Vector3> positions = data.Select((x, i) => new {Item = x, Index = i}) 719 var positions = data.Select((x, i) => new {Item = x, Index = i})
745 .Where(x => x.Item.Equals("X") || x.Item.Equals("Y") || x.Item.Equals("Z")) 720 .Where(x => x.Item.Equals("X") || x.Item.Equals("Y") || x.Item.Equals("Z"))
746 .Select(z => data[z.Index + 1]).Select((x, i) => new {Value = x, Index = i}) 721 .Select(z => data[z.Index + 1]).Select((x, i) => new {Value = x, Index = i})
747 .GroupBy(x => x.Index/3) 722 .GroupBy(x => x.Index/3)
748 .Select(x => x.Select(v => v.Value).ToList()) 723 .Select(x => x.Select(v => v.Value).ToList())
749 .Where( 724 .Where(
750 x => 725 x =>
751 float.TryParse(x[0], out X) && float.TryParse(x[1], out Y) && 726 float.TryParse(x[0], out X) && float.TryParse(x[1], out Y) &&
752 float.TryParse(x[2], out Z)) 727 float.TryParse(x[2], out Z))
753 .Select(x => new Vector3(X, Y, Z)) 728 .Select(x => new Vector3(X, Y, Z))
754 .ToList(); 729 .ToList();
755   730  
756 // Get the map image. 731 // Get the map image.
757 result = wasPOST(vassalConfiguration.HTTPServerURL, 732 result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
758 KeyValue.Escape(new Dictionary<string, string> 733 KeyValue.Escape(new Dictionary<string, string>
759 { 734 {
760 {"command", "getgridregiondata"}, 735 {"command", "getgridregiondata"},
761 {"group", vassalConfiguration.Group}, 736 {"group", vassalConfiguration.Group},
762 {"password", vassalConfiguration.Password}, 737 {"password", vassalConfiguration.Password},
763 {"data", "MapImageID"} 738 {"data", "MapImageID"}
764 }, wasOutput), vassalConfiguration.DataTimeout); 739 }, wasOutput)).Result);
765   740  
766 if (string.IsNullOrEmpty(result) || 741 if (string.IsNullOrEmpty(result) ||
767 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 742 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
768 throw new Exception(); 743 throw new Exception();
769   744  
770 data = CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))).ToList(); 745 data = CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))).ToList();
771 if (!data.Count.Equals(2)) 746 if (!data.Count.Equals(2))
772 throw new Exception(); 747 throw new Exception();
773 result = wasPOST(vassalConfiguration.HTTPServerURL, 748 result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
774 KeyValue.Escape(new Dictionary<string, string> 749 KeyValue.Escape(new Dictionary<string, string>
775 { 750 {
776 {"command", "download"}, 751 {"command", "download"},
777 {"group", vassalConfiguration.Group}, 752 {"group", vassalConfiguration.Group},
778 {"password", vassalConfiguration.Password}, 753 {"password", vassalConfiguration.Password},
779 {"item", data.Last()}, 754 {"item", data.Last()},
780 {"type", "Texture"}, 755 {"type", "Texture"},
781 {"format", "Jpeg"} 756 {"format", "Jpeg"}
782 }, wasOutput), vassalConfiguration.DataTimeout); 757 }, wasOutput)).Result);
783 if (string.IsNullOrEmpty(result) || 758 if (string.IsNullOrEmpty(result) ||
784 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 759 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
785 throw new Exception(); 760 throw new Exception();
786 byte[] mapImageBytes = Convert.FromBase64String(wasInput(KeyValue.Get("data", result))); 761 var mapImageBytes = Convert.FromBase64String(wasInput(KeyValue.Get("data", result)));
787 Image mapImage; 762 Image mapImage;
788 using (MemoryStream memoryStream = new MemoryStream(mapImageBytes, 0, mapImageBytes.Length)) 763 using (var memoryStream = new MemoryStream(mapImageBytes, 0, mapImageBytes.Length))
789 { 764 {
790 mapImage = Image.FromStream(memoryStream); 765 mapImage = Image.FromStream(memoryStream);
791 } 766 }
792   767  
793 // Draw the avatars onto the map. 768 // Draw the avatars onto the map.
794 Graphics mapGraphics = Graphics.FromImage(mapImage); 769 var mapGraphics = Graphics.FromImage(mapImage);
795 foreach (Vector3 position in positions) 770 foreach (var position in positions)
796 { 771 {
797 mapGraphics.FillEllipse(Brushes.Chartreuse, 772 mapGraphics.FillEllipse(Brushes.Chartreuse,
798 new Rectangle((int) position.X, (int) position.Y, 4, 4)); 773 new Rectangle((int) position.X, (int) position.Y, 4, 4));
799 } 774 }
800 mapGraphics.DrawImage(mapImage, new Point(0, 0)); 775 mapGraphics.DrawImage(mapImage, new Point(0, 0));
801   776  
802 vassalForm.BeginInvoke((MethodInvoker) (() => 777 vassalForm.BeginInvoke((MethodInvoker) (() =>
803 { 778 {
804 RegionAvatarsMap.SizeMode = PictureBoxSizeMode.StretchImage; 779 RegionAvatarsMap.SizeMode = PictureBoxSizeMode.StretchImage;
805 RegionAvatarsMap.Image = mapImage; 780 RegionAvatarsMap.Image = mapImage;
806 RegionAvatarsMap.Refresh(); 781 RegionAvatarsMap.Refresh();
807 })); 782 }));
808 } 783 }
809 catch (Exception) 784 catch (Exception)
810 { 785 {
811 } 786 }
812   787  
813 overviewTabTimer.Start(); 788 overviewTabTimer.Start();
814 }; 789 };
815 overviewTabTimer.Start(); 790 overviewTabTimer.Start();
816   791  
817 regionsStateTabTimer.Elapsed += (o, p) => 792 regionsStateTabTimer.Elapsed += (o, p) =>
818 { 793 {
819 // Do not do anything in case the tab is not selected. 794 // Do not do anything in case the tab is not selected.
820 bool run = false; 795 var run = false;
821 vassalForm.Invoke((MethodInvoker) (() => { run = Tabs.SelectedTab.Equals(RegionsStateTab); })); 796 vassalForm.Invoke((MethodInvoker) (() => { run = Tabs.SelectedTab.Equals(RegionsStateTab); }));
822   797  
823 if (!run) 798 if (!run)
824 { 799 {
825 regionsStateTabTimer.Stop(); 800 regionsStateTabTimer.Stop();
826 return; 801 return;
827 } 802 }
828   803  
829 regionsStateTabTimer.Stop(); 804 regionsStateTabTimer.Stop();
830   805  
831 try 806 try
832 { 807 {
833 string regionName = string.Empty; 808 var regionName = string.Empty;
834 vassalForm.Invoke((MethodInvoker) (() => 809 vassalForm.Invoke((MethodInvoker) (() =>
835 { 810 {
836 regionName = 811 regionName =
837 RegionsStateGridView.Rows[regionsStateCheckIndex].Cells["RegionsStateRegionName"].Value 812 RegionsStateGridView.Rows[regionsStateCheckIndex].Cells["RegionsStateRegionName"].Value
838 .ToString(); 813 .ToString();
839 RegionsStateGridView.Rows[regionsStateCheckIndex].DefaultCellStyle.BackColor = 814 RegionsStateGridView.Rows[regionsStateCheckIndex].DefaultCellStyle.BackColor =
840 Color.Gold; 815 Color.Gold;
841 })); 816 }));
842   817  
843 if (string.IsNullOrEmpty(regionName)) 818 if (string.IsNullOrEmpty(regionName))
844 throw new Exception(); 819 throw new Exception();
845   820  
846 // Get the region status. 821 // Get the region status.
847 string result = wasPOST(vassalConfiguration.HTTPServerURL, 822 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
848 KeyValue.Escape(new Dictionary<string, string> 823 KeyValue.Escape(new Dictionary<string, string>
849 { 824 {
850 {"command", "getgridregiondata"}, 825 {"command", "getgridregiondata"},
851 {"group", vassalConfiguration.Group}, 826 {"group", vassalConfiguration.Group},
852 {"password", vassalConfiguration.Password}, 827 {"password", vassalConfiguration.Password},
853 {"region", regionName}, 828 {"region", regionName},
854 {"data", "Access"} 829 {"data", "Access"}
855 }, wasOutput), vassalConfiguration.DataTimeout); 830 }, wasOutput)).Result);
856   831  
857 bool success; 832 bool success;
858 if (string.IsNullOrEmpty(result) || 833 if (string.IsNullOrEmpty(result) ||
859 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 834 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
860 throw new Exception(); 835 throw new Exception();
861   836  
862 List<string> data = CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))).ToList(); 837 var data = CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))).ToList();
863 if (!data.Count.Equals(2)) 838 if (!data.Count.Equals(2))
864 throw new Exception(); 839 throw new Exception();
865   840  
866 string status = data.Last(); 841 var status = data.Last();
867 vassalForm.Invoke((MethodInvoker) (() => 842 vassalForm.Invoke((MethodInvoker) (() =>
868 { 843 {
869 switch (status) 844 switch (status)
870 { 845 {
871 case "Unknown": 846 case "Unknown":
872 case "Down": 847 case "Down":
873 case "NonExistent": 848 case "NonExistent":
874 RegionsStateGridView.Rows[regionsStateCheckIndex].DefaultCellStyle.BackColor = 849 RegionsStateGridView.Rows[regionsStateCheckIndex].DefaultCellStyle.BackColor =
875 Color.LightPink; 850 Color.LightPink;
876 RegionsStateGridView.Rows[regionsStateCheckIndex].Cells["RegionsStateLastState"].Value = 851 RegionsStateGridView.Rows[regionsStateCheckIndex].Cells["RegionsStateLastState"].Value =
877 status; 852 status;
878 break; 853 break;
879 default: 854 default:
880 RegionsStateGridView.Rows[regionsStateCheckIndex].DefaultCellStyle.BackColor = 855 RegionsStateGridView.Rows[regionsStateCheckIndex].DefaultCellStyle.BackColor =
881 Color.LightGreen; 856 Color.LightGreen;
882 RegionsStateGridView.Rows[regionsStateCheckIndex].Cells["RegionsStateLastState"].Value = 857 RegionsStateGridView.Rows[regionsStateCheckIndex].Cells["RegionsStateLastState"].Value =
883 "Up"; 858 "Up";
884 break; 859 break;
885 } 860 }
886 RegionsStateGridView.Rows[regionsStateCheckIndex].Cells["RegionsStateLastCheck"].Value = DateTime 861 RegionsStateGridView.Rows[regionsStateCheckIndex].Cells["RegionsStateLastCheck"].Value = DateTime
887 .Now.ToUniversalTime() 862 .Now.ToUniversalTime()
888 .ToString(LINDEN_CONSTANTS.LSL.DATE_TIME_STAMP); 863 .ToString(LINDEN_CONSTANTS.LSL.DATE_TIME_STAMP);
889 })); 864 }));
890 } 865 }
891 catch (Exception) 866 catch (Exception)
892 { 867 {
893 } 868 }
894 finally 869 finally
895 { 870 {
896 ++regionsStateCheckIndex; 871 ++regionsStateCheckIndex;
897 vassalForm.Invoke((MethodInvoker) (() => 872 vassalForm.Invoke((MethodInvoker) (() =>
898 { 873 {
899 if (regionsStateCheckIndex >= RegionsStateGridView.Rows.Count) 874 if (regionsStateCheckIndex >= RegionsStateGridView.Rows.Count)
900 { 875 {
901 regionsStateCheckIndex = 0; 876 regionsStateCheckIndex = 0;
902 } 877 }
903 })); 878 }));
904 } 879 }
905   880  
906 regionsStateTabTimer.Start(); 881 regionsStateTabTimer.Start();
907 }; 882 };
908 regionsStateTabTimer.Start(); 883 regionsStateTabTimer.Start();
909   884  
910 // Start the top scores timer. 885 // Start the top scores timer.
911 estateTopTabTimer.Elapsed += (o, p) => 886 estateTopTabTimer.Elapsed += (o, p) =>
912 { 887 {
913 // Do not do anything in case the tab is not selected. 888 // Do not do anything in case the tab is not selected.
914 bool run = false; 889 var run = false;
915 vassalForm.Invoke((MethodInvoker) (() => { run = Tabs.SelectedTab.Equals(EstateTopTab); })); 890 vassalForm.Invoke((MethodInvoker) (() => { run = Tabs.SelectedTab.Equals(EstateTopTab); }));
916   891  
917 if (!run) 892 if (!run)
918 { 893 {
919 estateTopTabTimer.Stop(); 894 estateTopTabTimer.Stop();
920 return; 895 return;
921 } 896 }
922   897  
923 estateTopTabTimer.Stop(); 898 estateTopTabTimer.Stop();
924   899  
925 try 900 try
926 { 901 {
927 // Get the top scripts. 902 // Get the top scripts.
928 string result = wasPOST(vassalConfiguration.HTTPServerURL, 903 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
929 KeyValue.Escape(new Dictionary<string, string> 904 KeyValue.Escape(new Dictionary<string, string>
930 { 905 {
931 {"command", "getregiontop"}, 906 {"command", "getregiontop"},
932 {"group", vassalConfiguration.Group}, 907 {"group", vassalConfiguration.Group},
933 {"password", vassalConfiguration.Password}, 908 {"password", vassalConfiguration.Password},
934 {"type", "scripts"} 909 {"type", "scripts"}
935 }, wasOutput), vassalConfiguration.DataTimeout); 910 }, wasOutput)).Result);
936   911  
937 bool success; 912 bool success;
938 if (string.IsNullOrEmpty(result) || 913 if (string.IsNullOrEmpty(result) ||
939 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 914 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
940 throw new Exception(); 915 throw new Exception();
941   916  
942 HashSet<List<string>> data = 917 var data =
943 new HashSet<List<string>>(CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))) 918 new HashSet<List<string>>(CSV.ToEnumerable(wasInput(KeyValue.Get("data", result)))
944 .Select((x, i) => new {Index = i, Value = x}) 919 .Select((x, i) => new {Index = i, Value = x})
945 .GroupBy(x => x.Index/5) 920 .GroupBy(x => x.Index/5)
946 .Select(x => x.Select(v => v.Value).ToList())); 921 .Select(x => x.Select(v => v.Value).ToList()));
947 if (data.Count.Equals(0)) 922 if (data.Count.Equals(0))
948 throw new Exception(); 923 throw new Exception();
949   924  
950 vassalForm.Invoke((MethodInvoker) (() => 925 vassalForm.Invoke((MethodInvoker) (() =>
951 { 926 {
952 // Remove rows that are not in the data update. 927 // Remove rows that are not in the data update.
953 foreach ( 928 foreach (
954 int index in 929 var index in
955 TopScriptsGridView.Rows.AsParallel().Cast<DataGridViewRow>() 930 TopScriptsGridView.Rows.AsParallel().Cast<DataGridViewRow>()
956 .Where( 931 .Where(
957 topScriptsRow => 932 topScriptsRow =>
958 !data.Any(q => q[2].Equals(topScriptsRow.Cells["TopScriptsUUID"].Value))) 933 !data.Any(q => q[2].Equals(topScriptsRow.Cells["TopScriptsUUID"].Value)))
959 .Select(q => q.Index)) 934 .Select(q => q.Index))
960 { 935 {
961 TopScriptsGridView.Rows.RemoveAt(index); 936 TopScriptsGridView.Rows.RemoveAt(index);
962 } 937 }
963 // Now update or add new data. 938 // Now update or add new data.
964 foreach (List<string> dataComponents in data.Where(q => q.Count.Equals(5))) 939 foreach (var dataComponents in data.Where(q => q.Count.Equals(5)))
965 { 940 {
966 DataGridViewRow row = 941 var row =
967 TopScriptsGridView.Rows.AsParallel() 942 TopScriptsGridView.Rows.AsParallel()
968 .Cast<DataGridViewRow>() 943 .Cast<DataGridViewRow>()
969 .FirstOrDefault(q => q.Cells["TopScriptsUUID"].Value.Equals(dataComponents[2])); 944 .FirstOrDefault(q => q.Cells["TopScriptsUUID"].Value.Equals(dataComponents[2]));
970 switch (row != null) 945 switch (row != null)
971 { 946 {
972 case true: // the row exists, so update it. 947 case true: // the row exists, so update it.
973 row.Cells["TopScriptsScore"].Value = dataComponents[0]; 948 row.Cells["TopScriptsScore"].Value = dataComponents[0];
974 row.Cells["TopScriptsTaskName"].Value = dataComponents[1]; 949 row.Cells["TopScriptsTaskName"].Value = dataComponents[1];
975 row.Cells["TopScriptsUUID"].Value = dataComponents[2]; 950 row.Cells["TopScriptsUUID"].Value = dataComponents[2];
976 row.Cells["TopScriptsOwner"].Value = dataComponents[3]; 951 row.Cells["TopScriptsOwner"].Value = dataComponents[3];
977 row.Cells["TopScriptsPosition"].Value = dataComponents[4]; 952 row.Cells["TopScriptsPosition"].Value = dataComponents[4];
978 break; 953 break;
979 case false: // the row dosn't exist, so add it. 954 case false: // the row dosn't exist, so add it.
980 TopScriptsGridView.Rows.Add(dataComponents[0], dataComponents[1], dataComponents[2], 955 TopScriptsGridView.Rows.Add(dataComponents[0], dataComponents[1], dataComponents[2],
981 dataComponents[3], dataComponents[4]); 956 dataComponents[3], dataComponents[4]);
982 break; 957 break;
983 } 958 }
984 } 959 }
985 })); 960 }));
986   961  
987 // Get the top colliders. 962 // Get the top colliders.
988 result = wasPOST(vassalConfiguration.HTTPServerURL, 963 result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
989 KeyValue.Escape(new Dictionary<string, string> 964 KeyValue.Escape(new Dictionary<string, string>
990 { 965 {
991 {"command", "getregiontop"}, 966 {"command", "getregiontop"},
992 {"group", vassalConfiguration.Group}, 967 {"group", vassalConfiguration.Group},
993 {"password", vassalConfiguration.Password}, 968 {"password", vassalConfiguration.Password},
994 {"type", "colliders"} 969 {"type", "colliders"}
995 }, wasOutput), vassalConfiguration.DataTimeout); 970 }, wasOutput)).Result);
996   971  
997 if (string.IsNullOrEmpty(result) || 972 if (string.IsNullOrEmpty(result) ||
998 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 973 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
999 throw new Exception(); 974 throw new Exception();
1000   975  
1001 data = new HashSet<List<string>>(CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))) 976 data = new HashSet<List<string>>(CSV.ToEnumerable(wasInput(KeyValue.Get("data", result)))
1002 .Select((x, i) => new {Index = i, Value = x}) 977 .Select((x, i) => new {Index = i, Value = x})
1003 .GroupBy(x => x.Index/5) 978 .GroupBy(x => x.Index/5)
1004 .Select(x => x.Select(v => v.Value).ToList())); 979 .Select(x => x.Select(v => v.Value).ToList()));
1005 if (data.Count.Equals(0)) 980 if (data.Count.Equals(0))
1006 throw new Exception(); 981 throw new Exception();
1007   982  
1008 vassalForm.Invoke((MethodInvoker) (() => 983 vassalForm.Invoke((MethodInvoker) (() =>
1009 { 984 {
1010 // Remove rows that are not in the data update. 985 // Remove rows that are not in the data update.
1011 foreach ( 986 foreach (
1012 int index in 987 var index in
1013 TopCollidersGridView.Rows.AsParallel().Cast<DataGridViewRow>() 988 TopCollidersGridView.Rows.AsParallel().Cast<DataGridViewRow>()
1014 .Where( 989 .Where(
1015 topCollidersRow => 990 topCollidersRow =>
1016 !data.Any(q => q[2].Equals(topCollidersRow.Cells["TopCollidersUUID"].Value))) 991 !data.Any(q => q[2].Equals(topCollidersRow.Cells["TopCollidersUUID"].Value)))
1017 .Select(q => q.Index)) 992 .Select(q => q.Index))
1018 { 993 {
1019 TopCollidersGridView.Rows.RemoveAt(index); 994 TopCollidersGridView.Rows.RemoveAt(index);
1020 } 995 }
1021 // Now update or add new data. 996 // Now update or add new data.
1022 foreach (List<string> dataComponents in data.Where(q => q.Count.Equals(5))) 997 foreach (var dataComponents in data.Where(q => q.Count.Equals(5)))
1023 { 998 {
1024 DataGridViewRow row = 999 var row =
1025 TopCollidersGridView.Rows.AsParallel() 1000 TopCollidersGridView.Rows.AsParallel()
1026 .Cast<DataGridViewRow>() 1001 .Cast<DataGridViewRow>()
1027 .FirstOrDefault(q => q.Cells["TopCollidersUUID"].Value.Equals(dataComponents[2])); 1002 .FirstOrDefault(q => q.Cells["TopCollidersUUID"].Value.Equals(dataComponents[2]));
1028 switch (row != null) 1003 switch (row != null)
1029 { 1004 {
1030 case true: // the row exists, so update it. 1005 case true: // the row exists, so update it.
1031 row.Cells["TopCollidersScore"].Value = dataComponents[0]; 1006 row.Cells["TopCollidersScore"].Value = dataComponents[0];
1032 row.Cells["TopSCollidersTaskName"].Value = dataComponents[1]; 1007 row.Cells["TopSCollidersTaskName"].Value = dataComponents[1];
1033 row.Cells["TopCollidersUUID"].Value = dataComponents[2]; 1008 row.Cells["TopCollidersUUID"].Value = dataComponents[2];
1034 row.Cells["TopCollidersOwner"].Value = dataComponents[3]; 1009 row.Cells["TopCollidersOwner"].Value = dataComponents[3];
1035 row.Cells["TopCollidersPosition"].Value = dataComponents[4]; 1010 row.Cells["TopCollidersPosition"].Value = dataComponents[4];
1036 break; 1011 break;
1037 case false: // the row dosn't exist, so add it. 1012 case false: // the row dosn't exist, so add it.
1038 TopCollidersGridView.Rows.Add(dataComponents[0], dataComponents[1], 1013 TopCollidersGridView.Rows.Add(dataComponents[0], dataComponents[1],
1039 dataComponents[2], 1014 dataComponents[2],
1040 dataComponents[3], dataComponents[4]); 1015 dataComponents[3], dataComponents[4]);
1041 break; 1016 break;
1042 } 1017 }
1043 } 1018 }
1044 })); 1019 }));
1045 } 1020 }
1046 catch (Exception) 1021 catch (Exception)
1047 { 1022 {
1048 } 1023 }
1049   1024  
1050 estateTopTabTimer.Start(); 1025 estateTopTabTimer.Start();
1051 }; 1026 };
1052 estateTopTabTimer.Start(); 1027 estateTopTabTimer.Start();
1053   1028  
1054 // Start the resident list timer. 1029 // Start the resident list timer.
1055 residentListTabTimer.Elapsed += (o, p) => 1030 residentListTabTimer.Elapsed += (o, p) =>
1056 { 1031 {
1057 // Do not do anything in case the tab is not selected. 1032 // Do not do anything in case the tab is not selected.
1058 bool run = false; 1033 var run = false;
1059 vassalForm.Invoke((MethodInvoker) (() => { run = Tabs.SelectedTab.Equals(ResidentListTab); })); 1034 vassalForm.Invoke((MethodInvoker) (() => { run = Tabs.SelectedTab.Equals(ResidentListTab); }));
1060   1035  
1061 if (!run) 1036 if (!run)
1062 { 1037 {
1063 residentListTabTimer.Stop(); 1038 residentListTabTimer.Stop();
1064 return; 1039 return;
1065 } 1040 }
1066   1041  
1067 residentListTabTimer.Stop(); 1042 residentListTabTimer.Stop();
1068   1043  
1069 try 1044 try
1070 { 1045 {
1071 // Get the avatar positions. 1046 // Get the avatar positions.
1072 string result = wasPOST(vassalConfiguration.HTTPServerURL, 1047 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
1073 KeyValue.Escape(new Dictionary<string, string> 1048 KeyValue.Escape(new Dictionary<string, string>
1074 { 1049 {
1075 {"command", "getavatarpositions"}, 1050 {"command", "getavatarpositions"},
1076 {"group", vassalConfiguration.Group}, 1051 {"group", vassalConfiguration.Group},
1077 {"password", vassalConfiguration.Password}, 1052 {"password", vassalConfiguration.Password},
1078 {"entity", "region"} 1053 {"entity", "region"}
1079 }, wasOutput), vassalConfiguration.DataTimeout); 1054 }, wasOutput)).Result);
1080   1055  
1081 bool success; 1056 bool success;
1082 if (string.IsNullOrEmpty(result) || 1057 if (string.IsNullOrEmpty(result) ||
1083 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 1058 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
1084 throw new Exception(); 1059 throw new Exception();
1085   1060  
1086 HashSet<List<string>> data = 1061 var data =
1087 new HashSet<List<string>>(CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))) 1062 new HashSet<List<string>>(CSV.ToEnumerable(wasInput(KeyValue.Get("data", result)))
1088 .Select((x, i) => new {Index = i, Value = x}) 1063 .Select((x, i) => new {Index = i, Value = x})
1089 .GroupBy(x => x.Index/3) 1064 .GroupBy(x => x.Index/3)
1090 .Select(x => x.Select(v => v.Value).ToList())); 1065 .Select(x => x.Select(v => v.Value).ToList()));
1091 if (data.Count.Equals(0)) 1066 if (data.Count.Equals(0))
1092 throw new Exception(); 1067 throw new Exception();
1093   1068  
1094 vassalForm.Invoke((MethodInvoker) (() => 1069 vassalForm.Invoke((MethodInvoker) (() =>
1095 { 1070 {
1096 // Remove rows that are not in the data update. 1071 // Remove rows that are not in the data update.
1097 foreach ( 1072 foreach (
1098 int index in 1073 var index in
1099 ResidentListGridView.Rows.AsParallel().Cast<DataGridViewRow>() 1074 ResidentListGridView.Rows.AsParallel().Cast<DataGridViewRow>()
1100 .Where( 1075 .Where(
1101 residentListRow => 1076 residentListRow =>
1102 !data.Any(q => q[1].Equals(residentListRow.Cells["ResidentListUUID"].Value))) 1077 !data.Any(q => q[1].Equals(residentListRow.Cells["ResidentListUUID"].Value)))
1103 .Select(q => q.Index)) 1078 .Select(q => q.Index))
1104 { 1079 {
1105 ResidentListGridView.Rows.RemoveAt(index); 1080 ResidentListGridView.Rows.RemoveAt(index);
1106 } 1081 }
1107 // Now update or add new data. 1082 // Now update or add new data.
1108 foreach (List<string> dataComponents in data.Where(q => q.Count.Equals(3))) 1083 foreach (var dataComponents in data.Where(q => q.Count.Equals(3)))
1109 { 1084 {
1110 DataGridViewRow row = 1085 var row =
1111 ResidentListGridView.Rows.AsParallel() 1086 ResidentListGridView.Rows.AsParallel()
1112 .Cast<DataGridViewRow>() 1087 .Cast<DataGridViewRow>()
1113 .FirstOrDefault(q => q.Cells["ResidentListUUID"].Value.Equals(dataComponents[1])); 1088 .FirstOrDefault(q => q.Cells["ResidentListUUID"].Value.Equals(dataComponents[1]));
1114 switch (row != null) 1089 switch (row != null)
1115 { 1090 {
1116 case true: // the row exists, so update it. 1091 case true: // the row exists, so update it.
1117 row.Cells["ResidentListName"].Value = dataComponents[0]; 1092 row.Cells["ResidentListName"].Value = dataComponents[0];
1118 row.Cells["ResidentListUUID"].Value = dataComponents[1]; 1093 row.Cells["ResidentListUUID"].Value = dataComponents[1];
1119 row.Cells["ResidentListPosition"].Value = dataComponents[2]; 1094 row.Cells["ResidentListPosition"].Value = dataComponents[2];
1120 break; 1095 break;
1121 case false: // the row dosn't exist, so add it. 1096 case false: // the row dosn't exist, so add it.
1122 ResidentListGridView.Rows.Add(dataComponents[0], dataComponents[1], 1097 ResidentListGridView.Rows.Add(dataComponents[0], dataComponents[1],
1123 dataComponents[2]); 1098 dataComponents[2]);
1124 break; 1099 break;
1125 } 1100 }
1126 } 1101 }
1127 })); 1102 }));
1128 } 1103 }
1129 catch (Exception) 1104 catch (Exception)
1130 { 1105 {
1131 } 1106 }
1132   1107  
1133 residentListTabTimer.Start(); 1108 residentListTabTimer.Start();
1134 }; 1109 };
1135 residentListTabTimer.Start(); 1110 residentListTabTimer.Start();
1136   1111  
1137 estateTexturesTabTimer.Elapsed += (o, p) => 1112 estateTexturesTabTimer.Elapsed += (o, p) =>
1138 { 1113 {
1139 // Do not do anything in case the tab is not selected. 1114 // Do not do anything in case the tab is not selected.
1140 bool run = false; 1115 var run = false;
1141 vassalForm.Invoke((MethodInvoker) (() => { run = Tabs.SelectedTab.Equals(EstateTexturesTab); })); 1116 vassalForm.Invoke((MethodInvoker) (() => { run = Tabs.SelectedTab.Equals(EstateTexturesTab); }));
1142   1117  
1143 if (!run) 1118 if (!run)
1144 { 1119 {
1145 estateTexturesTabTimer.Stop(); 1120 estateTexturesTabTimer.Stop();
1146 return; 1121 return;
1147 } 1122 }
1148   1123  
1149 estateTexturesTabTimer.Stop(); 1124 estateTexturesTabTimer.Stop();
1150   1125  
1151 try 1126 try
1152 { 1127 {
1153 // Get the region terrain texture UUIDs. 1128 // Get the region terrain texture UUIDs.
1154 string result = wasPOST(vassalConfiguration.HTTPServerURL, 1129 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
1155 KeyValue.Escape(new Dictionary<string, string> 1130 KeyValue.Escape(new Dictionary<string, string>
1156 { 1131 {
1157 {"command", "getregionterraintextures"}, 1132 {"command", "getregionterraintextures"},
1158 {"group", vassalConfiguration.Group}, 1133 {"group", vassalConfiguration.Group},
1159 {"password", vassalConfiguration.Password} 1134 {"password", vassalConfiguration.Password}
1160 }, wasOutput), vassalConfiguration.DataTimeout); 1135 }, wasOutput)).Result);
1161   1136  
1162 bool success; 1137 bool success;
1163 if (string.IsNullOrEmpty(result) || 1138 if (string.IsNullOrEmpty(result) ||
1164 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 1139 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
1165 throw new Exception(); 1140 throw new Exception();
1166   1141  
1167 List<string> data = CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))).ToList(); 1142 var data = CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))).ToList();
1168 if (!data.Count.Equals(4)) 1143 if (!data.Count.Equals(4))
1169 throw new Exception(); 1144 throw new Exception();
1170   1145  
1171 vassalForm.Invoke((MethodInvoker) (() => 1146 vassalForm.Invoke((MethodInvoker) (() =>
1172 { 1147 {
1173 RegionTexturesLowUUIDBox.Text = data[0]; 1148 RegionTexturesLowUUIDBox.Text = data[0];
1174 if (string.IsNullOrEmpty(RegionTexturesLowUUIDApplyBox.Text)) 1149 if (string.IsNullOrEmpty(RegionTexturesLowUUIDApplyBox.Text))
1175 { 1150 {
1176 RegionTexturesLowUUIDApplyBox.Text = data[0]; 1151 RegionTexturesLowUUIDApplyBox.Text = data[0];
1177 } 1152 }
1178 RegionTexturesMiddleLowUUIDBox.Text = data[1]; 1153 RegionTexturesMiddleLowUUIDBox.Text = data[1];
1179 if (string.IsNullOrEmpty(RegionTexturesMiddleLowUUIDApplyBox.Text)) 1154 if (string.IsNullOrEmpty(RegionTexturesMiddleLowUUIDApplyBox.Text))
1180 { 1155 {
1181 RegionTexturesMiddleLowUUIDApplyBox.Text = data[1]; 1156 RegionTexturesMiddleLowUUIDApplyBox.Text = data[1];
1182 } 1157 }
1183 RegionTexturesMiddleHighUUIDBox.Text = data[2]; 1158 RegionTexturesMiddleHighUUIDBox.Text = data[2];
1184 if (string.IsNullOrEmpty(RegionTexturesMiddleHighUUIDApplyBox.Text)) 1159 if (string.IsNullOrEmpty(RegionTexturesMiddleHighUUIDApplyBox.Text))
1185 { 1160 {
1186 RegionTexturesMiddleHighUUIDApplyBox.Text = data[2]; 1161 RegionTexturesMiddleHighUUIDApplyBox.Text = data[2];
1187 } 1162 }
1188 RegionTexturesHighUUIDBox.Text = data[3]; 1163 RegionTexturesHighUUIDBox.Text = data[3];
1189 if (string.IsNullOrEmpty(RegionTexturesHighUUIDApplyBox.Text)) 1164 if (string.IsNullOrEmpty(RegionTexturesHighUUIDApplyBox.Text))
1190 { 1165 {
1191 RegionTexturesHighUUIDApplyBox.Text = data[1]; 1166 RegionTexturesHighUUIDApplyBox.Text = data[1];
1192 } 1167 }
1193 })); 1168 }));
1194   1169  
1195 Parallel.ForEach(Enumerable.Range(0, 4), i => 1170 Parallel.ForEach(Enumerable.Range(0, 4), i =>
1196 { 1171 {
1197 result = wasPOST(vassalConfiguration.HTTPServerURL, 1172 result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
1198 KeyValue.Escape(new Dictionary<string, string> 1173 KeyValue.Escape(new Dictionary<string, string>
1199 { 1174 {
1200 {"command", "download"}, 1175 {"command", "download"},
1201 {"group", vassalConfiguration.Group}, 1176 {"group", vassalConfiguration.Group},
1202 {"password", vassalConfiguration.Password}, 1177 {"password", vassalConfiguration.Password},
1203 {"item", data[i]}, 1178 {"item", data[i]},
1204 {"type", "Texture"}, 1179 {"type", "Texture"},
1205 {"format", "Jpeg"} 1180 {"format", "Jpeg"}
1206 }, wasOutput), vassalConfiguration.DataTimeout); 1181 }, wasOutput)).Result);
1207   1182  
1208 if (string.IsNullOrEmpty(result) || 1183 if (string.IsNullOrEmpty(result) ||
1209 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 1184 !bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
1210 return; 1185 return;
1211   1186  
1212 byte[] mapImageBytes = Convert.FromBase64String(wasInput(KeyValue.Get("data", result))); 1187 var mapImageBytes = Convert.FromBase64String(wasInput(KeyValue.Get("data", result)));
1213 using (MemoryStream memoryStream = new MemoryStream(mapImageBytes, 0, mapImageBytes.Length)) 1188 using (var memoryStream = new MemoryStream(mapImageBytes, 0, mapImageBytes.Length))
1214 { 1189 {
1215 groundTextureImages[i] = Image.FromStream(memoryStream); 1190 groundTextureImages[i] = Image.FromStream(memoryStream);
1216 } 1191 }
1217   1192  
1218 switch (i) 1193 switch (i)
1219 { 1194 {
1220 case 0: 1195 case 0:
1221 vassalForm.BeginInvoke( 1196 vassalForm.BeginInvoke(
1222 (MethodInvoker) 1197 (MethodInvoker)
1223 (() => { RegionTexturesLowPictureBox.Image = groundTextureImages[0]; })); 1198 (() => { RegionTexturesLowPictureBox.Image = groundTextureImages[0]; }));
1224   1199  
1225 break; 1200 break;
1226 case 1: 1201 case 1:
1227 vassalForm.BeginInvoke( 1202 vassalForm.BeginInvoke(
1228 (MethodInvoker) 1203 (MethodInvoker)
1229 (() => { RegionTexturesMiddleLowPictureBox.Image = groundTextureImages[1]; })); 1204 (() => { RegionTexturesMiddleLowPictureBox.Image = groundTextureImages[1]; }));
1230   1205  
1231 break; 1206 break;
1232 case 2: 1207 case 2:
1233 vassalForm.BeginInvoke( 1208 vassalForm.BeginInvoke(
1234 (MethodInvoker) 1209 (MethodInvoker)
1235 (() => { RegionTexturesMiddleHighPictureBox.Image = groundTextureImages[2]; })); 1210 (() => { RegionTexturesMiddleHighPictureBox.Image = groundTextureImages[2]; }));
1236 break; 1211 break;
1237 case 3: 1212 case 3:
1238 vassalForm.BeginInvoke( 1213 vassalForm.BeginInvoke(
1239 (MethodInvoker) 1214 (MethodInvoker)
1240 (() => { RegionTexturesHighPictureBox.Image = groundTextureImages[3]; })); 1215 (() => { RegionTexturesHighPictureBox.Image = groundTextureImages[3]; }));
1241 break; 1216 break;
1242 } 1217 }
1243 }); 1218 });
1244 } 1219 }
1245 catch (Exception) 1220 catch (Exception)
1246 { 1221 {
1247 } 1222 }
1248   1223  
1249 estateTexturesTabTimer.Start(); 1224 estateTexturesTabTimer.Start();
1250 }; 1225 };
1251 estateTexturesTabTimer.Start(); 1226 estateTexturesTabTimer.Start();
1252 } 1227 }
1253   1228  
1254 private void RequestedEditRegions(object sender, EventArgs e) 1229 private void RequestedEditRegions(object sender, EventArgs e)
1255 { 1230 {
1256 // Clear any selection. 1231 // Clear any selection.
1257 LoadedRegionsBox.SelectedIndex = -1; 1232 LoadedRegionsBox.SelectedIndex = -1;
1258 RegionEditForm regionEditForm = new RegionEditForm {TopMost = true}; 1233 var regionEditForm = new RegionEditForm {TopMost = true};
1259 regionEditForm.Show(); 1234 regionEditForm.Show();
1260 } 1235 }
1261   1236  
1262 private void RequestSelecting(object sender, TabControlCancelEventArgs e) 1237 private void RequestSelecting(object sender, TabControlCancelEventArgs e)
1263 { 1238 {
1264 e.Cancel = !e.TabPage.Enabled; 1239 e.Cancel = !e.TabPage.Enabled;
1265 } 1240 }
1266   1241  
1267 private void RequestExportTopScripts(object sender, EventArgs e) 1242 private void RequestExportTopScripts(object sender, EventArgs e)
1268 { 1243 {
1269 vassalForm.BeginInvoke((MethodInvoker) (() => 1244 vassalForm.BeginInvoke((MethodInvoker) (() =>
1270 { 1245 {
1271 switch (vassalForm.ExportCSVDialog.ShowDialog()) 1246 switch (vassalForm.ExportCSVDialog.ShowDialog())
1272 { 1247 {
1273 case DialogResult.OK: 1248 case DialogResult.OK:
1274 string file = vassalForm.ExportCSVDialog.FileName; 1249 var file = vassalForm.ExportCSVDialog.FileName;
1275 new Thread(() => 1250 new Thread(() =>
1276 { 1251 {
1277 vassalForm.BeginInvoke((MethodInvoker) (() => 1252 vassalForm.BeginInvoke((MethodInvoker) (() =>
1278 { 1253 {
1279 try 1254 try
1280 { 1255 {
1281 vassalForm.StatusText.Text = @"exporting..."; 1256 vassalForm.StatusText.Text = @"exporting...";
1282 vassalForm.StatusProgress.Value = 0; 1257 vassalForm.StatusProgress.Value = 0;
1283   1258  
1284 using (StreamWriter streamWriter = new StreamWriter(file, false, Encoding.UTF8)) 1259 using (var streamWriter = new StreamWriter(file, false, Encoding.UTF8))
1285 { 1260 {
1286 foreach (DataGridViewRow topScriptsRow in TopScriptsGridView.Rows) 1261 foreach (DataGridViewRow topScriptsRow in TopScriptsGridView.Rows)
1287 { 1262 {
1288 streamWriter.WriteLine(CSV.FromEnumerable(new[] 1263 streamWriter.WriteLine(CSV.FromEnumerable(new[]
1289 { 1264 {
1290 topScriptsRow.Cells["TopScriptsScore"].Value.ToString(), 1265 topScriptsRow.Cells["TopScriptsScore"].Value.ToString(),
1291 topScriptsRow.Cells["TopScriptsTaskName"].Value.ToString(), 1266 topScriptsRow.Cells["TopScriptsTaskName"].Value.ToString(),
1292 topScriptsRow.Cells["TopScriptsUUID"].Value.ToString(), 1267 topScriptsRow.Cells["TopScriptsUUID"].Value.ToString(),
1293 topScriptsRow.Cells["TopScriptsOwner"].Value.ToString(), 1268 topScriptsRow.Cells["TopScriptsOwner"].Value.ToString(),
1294 topScriptsRow.Cells["TopScriptsPosition"].Value.ToString() 1269 topScriptsRow.Cells["TopScriptsPosition"].Value.ToString()
1295 })); 1270 }));
1296 } 1271 }
1297 } 1272 }
1298   1273  
1299 vassalForm.StatusText.Text = @"exported"; 1274 vassalForm.StatusText.Text = @"exported";
1300 vassalForm.StatusProgress.Value = 100; 1275 vassalForm.StatusProgress.Value = 100;
1301 } 1276 }
1302 catch (Exception ex) 1277 catch (Exception ex)
1303 { 1278 {
1304 vassalForm.StatusText.Text = ex.Message; 1279 vassalForm.StatusText.Text = ex.Message;
1305 } 1280 }
1306 })); 1281 }));
1307 }) 1282 })
1308 {IsBackground = true}.Start(); 1283 {IsBackground = true}.Start();
1309 break; 1284 break;
1310 } 1285 }
1311 })); 1286 }));
1312 } 1287 }
1313   1288  
1314 private void RequestExportTopColliders(object sender, EventArgs e) 1289 private void RequestExportTopColliders(object sender, EventArgs e)
1315 { 1290 {
1316 vassalForm.BeginInvoke((MethodInvoker) (() => 1291 vassalForm.BeginInvoke((MethodInvoker) (() =>
1317 { 1292 {
1318 switch (vassalForm.ExportCSVDialog.ShowDialog()) 1293 switch (vassalForm.ExportCSVDialog.ShowDialog())
1319 { 1294 {
1320 case DialogResult.OK: 1295 case DialogResult.OK:
1321 string file = vassalForm.ExportCSVDialog.FileName; 1296 var file = vassalForm.ExportCSVDialog.FileName;
1322 new Thread(() => 1297 new Thread(() =>
1323 { 1298 {
1324 vassalForm.BeginInvoke((MethodInvoker) (() => 1299 vassalForm.BeginInvoke((MethodInvoker) (() =>
1325 { 1300 {
1326 try 1301 try
1327 { 1302 {
1328 vassalForm.StatusText.Text = @"exporting..."; 1303 vassalForm.StatusText.Text = @"exporting...";
1329 vassalForm.StatusProgress.Value = 0; 1304 vassalForm.StatusProgress.Value = 0;
1330   1305  
1331 using (StreamWriter streamWriter = new StreamWriter(file, false, Encoding.UTF8)) 1306 using (var streamWriter = new StreamWriter(file, false, Encoding.UTF8))
1332 { 1307 {
1333 foreach (DataGridViewRow topCollidersRow in TopCollidersGridView.Rows) 1308 foreach (DataGridViewRow topCollidersRow in TopCollidersGridView.Rows)
1334 { 1309 {
1335 streamWriter.WriteLine(CSV.FromEnumerable(new[] 1310 streamWriter.WriteLine(CSV.FromEnumerable(new[]
1336 { 1311 {
1337 topCollidersRow.Cells["TopCollidersScore"].Value.ToString(), 1312 topCollidersRow.Cells["TopCollidersScore"].Value.ToString(),
1338 topCollidersRow.Cells["TopCollidersTaskName"].Value.ToString(), 1313 topCollidersRow.Cells["TopCollidersTaskName"].Value.ToString(),
1339 topCollidersRow.Cells["TopCollidersUUID"].Value.ToString(), 1314 topCollidersRow.Cells["TopCollidersUUID"].Value.ToString(),
1340 topCollidersRow.Cells["TopCollidersOwner"].Value.ToString(), 1315 topCollidersRow.Cells["TopCollidersOwner"].Value.ToString(),
1341 topCollidersRow.Cells["TopCollidersPosition"].Value.ToString() 1316 topCollidersRow.Cells["TopCollidersPosition"].Value.ToString()
1342 })); 1317 }));
1343 } 1318 }
1344 } 1319 }
1345   1320  
1346 vassalForm.StatusText.Text = @"exported"; 1321 vassalForm.StatusText.Text = @"exported";
1347 vassalForm.StatusProgress.Value = 100; 1322 vassalForm.StatusProgress.Value = 100;
1348 } 1323 }
1349 catch (Exception ex) 1324 catch (Exception ex)
1350 { 1325 {
1351 vassalForm.StatusText.Text = ex.Message; 1326 vassalForm.StatusText.Text = ex.Message;
1352 } 1327 }
1353 })); 1328 }));
1354 }) 1329 })
1355 {IsBackground = true}.Start(); 1330 {IsBackground = true}.Start();
1356 break; 1331 break;
1357 } 1332 }
1358 })); 1333 }));
1359 } 1334 }
1360   1335  
1361 private void RequestFilterTopScripts(object sender, EventArgs e) 1336 private void RequestFilterTopScripts(object sender, EventArgs e)
1362 { 1337 {
1363 vassalForm.BeginInvoke((MethodInvoker) (() => 1338 vassalForm.BeginInvoke((MethodInvoker) (() =>
1364 { 1339 {
1365 Regex topScriptsRowRegex; 1340 Regex topScriptsRowRegex;
1366 switch (!string.IsNullOrEmpty(TopScriptsFilter.Text)) 1341 switch (!string.IsNullOrEmpty(TopScriptsFilter.Text))
1367 { 1342 {
1368 case true: 1343 case true:
1369 topScriptsRowRegex = new Regex(TopScriptsFilter.Text, RegexOptions.Compiled); 1344 topScriptsRowRegex = new Regex(TopScriptsFilter.Text, RegexOptions.Compiled);
1370 break; 1345 break;
1371 default: 1346 default:
1372 topScriptsRowRegex = new Regex(@".+?", RegexOptions.Compiled); 1347 topScriptsRowRegex = new Regex(@".+?", RegexOptions.Compiled);
1373 break; 1348 break;
1374 } 1349 }
1375 foreach (DataGridViewRow topScriptsRow in TopScriptsGridView.Rows.AsParallel().Cast<DataGridViewRow>()) 1350 foreach (var topScriptsRow in TopScriptsGridView.Rows.AsParallel().Cast<DataGridViewRow>())
1376 { 1351 {
1377 topScriptsRow.Visible = 1352 topScriptsRow.Visible =
1378 topScriptsRowRegex.IsMatch(topScriptsRow.Cells["TopScriptsScore"].Value.ToString()) || 1353 topScriptsRowRegex.IsMatch(topScriptsRow.Cells["TopScriptsScore"].Value.ToString()) ||
1379 topScriptsRowRegex.IsMatch( 1354 topScriptsRowRegex.IsMatch(
1380 topScriptsRow.Cells["TopScriptsTaskName"].Value.ToString()) || 1355 topScriptsRow.Cells["TopScriptsTaskName"].Value.ToString()) ||
1381 topScriptsRowRegex.IsMatch(topScriptsRow.Cells["TopScriptsUUID"].Value.ToString()) || 1356 topScriptsRowRegex.IsMatch(topScriptsRow.Cells["TopScriptsUUID"].Value.ToString()) ||
1382 topScriptsRowRegex.IsMatch(topScriptsRow.Cells["TopScriptsOwner"].Value.ToString()) || 1357 topScriptsRowRegex.IsMatch(topScriptsRow.Cells["TopScriptsOwner"].Value.ToString()) ||
1383 topScriptsRowRegex.IsMatch( 1358 topScriptsRowRegex.IsMatch(
1384 topScriptsRow.Cells["TopScriptsPosition"].Value.ToString()); 1359 topScriptsRow.Cells["TopScriptsPosition"].Value.ToString());
1385 } 1360 }
1386 })); 1361 }));
1387 } 1362 }
1388   1363  
1389 private void RequestFilterTopColliders(object sender, EventArgs e) 1364 private void RequestFilterTopColliders(object sender, EventArgs e)
1390 { 1365 {
1391 vassalForm.BeginInvoke((MethodInvoker) (() => 1366 vassalForm.BeginInvoke((MethodInvoker) (() =>
1392 { 1367 {
1393 Regex topCollidersRowRegex; 1368 Regex topCollidersRowRegex;
1394 switch (!string.IsNullOrEmpty(TopScriptsFilter.Text)) 1369 switch (!string.IsNullOrEmpty(TopScriptsFilter.Text))
1395 { 1370 {
1396 case true: 1371 case true:
1397 topCollidersRowRegex = new Regex(TopScriptsFilter.Text, RegexOptions.Compiled); 1372 topCollidersRowRegex = new Regex(TopScriptsFilter.Text, RegexOptions.Compiled);
1398 break; 1373 break;
1399 default: 1374 default:
1400 topCollidersRowRegex = new Regex(@".+?", RegexOptions.Compiled); 1375 topCollidersRowRegex = new Regex(@".+?", RegexOptions.Compiled);
1401 break; 1376 break;
1402 } 1377 }
1403 foreach ( 1378 foreach (
1404 DataGridViewRow topCollidersRow in TopCollidersGridView.Rows.AsParallel().Cast<DataGridViewRow>()) 1379 var topCollidersRow in TopCollidersGridView.Rows.AsParallel().Cast<DataGridViewRow>())
1405 { 1380 {
1406 topCollidersRow.Visible = 1381 topCollidersRow.Visible =
1407 topCollidersRowRegex.IsMatch(topCollidersRow.Cells["TopCollidersScore"].Value.ToString()) || 1382 topCollidersRowRegex.IsMatch(topCollidersRow.Cells["TopCollidersScore"].Value.ToString()) ||
1408 topCollidersRowRegex.IsMatch( 1383 topCollidersRowRegex.IsMatch(
1409 topCollidersRow.Cells["TopCollidersTaskName"].Value.ToString()) || 1384 topCollidersRow.Cells["TopCollidersTaskName"].Value.ToString()) ||
1410 topCollidersRowRegex.IsMatch(topCollidersRow.Cells["TopCollidersUUID"].Value.ToString()) || 1385 topCollidersRowRegex.IsMatch(topCollidersRow.Cells["TopCollidersUUID"].Value.ToString()) ||
1411 topCollidersRowRegex.IsMatch(topCollidersRow.Cells["TopCollidersOwner"].Value.ToString()) || 1386 topCollidersRowRegex.IsMatch(topCollidersRow.Cells["TopCollidersOwner"].Value.ToString()) ||
1412 topCollidersRowRegex.IsMatch( 1387 topCollidersRowRegex.IsMatch(
1413 topCollidersRow.Cells["TopCollidersPosition"].Value.ToString()); 1388 topCollidersRow.Cells["TopCollidersPosition"].Value.ToString());
1414 } 1389 }
1415 })); 1390 }));
1416 } 1391 }
1417   1392  
1418 private void RequestReturnTopScriptsObjects(object sender, EventArgs e) 1393 private void RequestReturnTopScriptsObjects(object sender, EventArgs e)
1419 { 1394 {
1420 // Block teleports and disable button. 1395 // Block teleports and disable button.
1421 vassalForm.Invoke((MethodInvoker) (() => 1396 vassalForm.Invoke((MethodInvoker) (() =>
1422 { 1397 {
1423 vassalForm.ReturnTopScriptsButton.Enabled = false; 1398 vassalForm.ReturnTopScriptsButton.Enabled = false;
1424 RegionTeleportGroup.Enabled = false; 1399 RegionTeleportGroup.Enabled = false;
1425 })); 1400 }));
1426   1401  
1427 // Enqueue all the UUIDs to return. 1402 // Enqueue all the UUIDs to return.
1428 Queue<KeyValuePair<UUID, Vector3>> returnUUIDs = new Queue<KeyValuePair<UUID, Vector3>>(); 1403 var returnUUIDs = new Queue<KeyValuePair<UUID, Vector3>>();
1429 vassalForm.Invoke((MethodInvoker) (() => 1404 vassalForm.Invoke((MethodInvoker) (() =>
1430 { 1405 {
1431 foreach ( 1406 foreach (
1432 DataGridViewRow topScriptsRow in 1407 var topScriptsRow in
1433 TopScriptsGridView.Rows.AsParallel() 1408 TopScriptsGridView.Rows.AsParallel()
1434 .Cast<DataGridViewRow>() 1409 .Cast<DataGridViewRow>()
1435 .Where(o => o.Selected || o.Cells.Cast<DataGridViewCell>().Any(p => p.Selected))) 1410 .Where(o => o.Selected || o.Cells.Cast<DataGridViewCell>().Any(p => p.Selected)))
1436 { 1411 {
1437 Vector3 objectPosition; 1412 Vector3 objectPosition;
1438 UUID returnUUID; 1413 UUID returnUUID;
1439 if (!UUID.TryParse(topScriptsRow.Cells["TopScriptsUUID"].Value.ToString(), out returnUUID) || 1414 if (!UUID.TryParse(topScriptsRow.Cells["TopScriptsUUID"].Value.ToString(), out returnUUID) ||
1440 !Vector3.TryParse(topScriptsRow.Cells["TopScriptsPosition"].Value.ToString(), out objectPosition)) 1415 !Vector3.TryParse(topScriptsRow.Cells["TopScriptsPosition"].Value.ToString(), out objectPosition))
1441 continue; 1416 continue;
1442 returnUUIDs.Enqueue(new KeyValuePair<UUID, Vector3>(returnUUID, objectPosition)); 1417 returnUUIDs.Enqueue(new KeyValuePair<UUID, Vector3>(returnUUID, objectPosition));
1443 } 1418 }
1444 })); 1419 }));
1445   1420  
1446 // If no rows were selected, enable teleports, the return button and return. 1421 // If no rows were selected, enable teleports, the return button and return.
1447 if (returnUUIDs.Count.Equals(0)) 1422 if (returnUUIDs.Count.Equals(0))
1448 { 1423 {
1449 vassalForm.Invoke((MethodInvoker) (() => 1424 vassalForm.Invoke((MethodInvoker) (() =>
1450 { 1425 {
1451 vassalForm.ReturnTopScriptsButton.Enabled = true; 1426 vassalForm.ReturnTopScriptsButton.Enabled = true;
1452 RegionTeleportGroup.Enabled = true; 1427 RegionTeleportGroup.Enabled = true;
1453 })); 1428 }));
1454 return; 1429 return;
1455 } 1430 }
1456   1431  
1457 new Thread(() => 1432 new Thread(() =>
1458 { 1433 {
1459 Monitor.Enter(ClientInstanceTeleportLock); 1434 Monitor.Enter(ClientInstanceTeleportLock);
1460   1435  
1461 try 1436 try
1462 { 1437 {
1463 vassalForm.Invoke((MethodInvoker) (() => { vassalForm.StatusProgress.Value = 0; })); 1438 vassalForm.Invoke((MethodInvoker) (() => { vassalForm.StatusProgress.Value = 0; }));
1464 int totalObjects = returnUUIDs.Count; 1439 var totalObjects = returnUUIDs.Count;
1465 do 1440 do
1466 { 1441 {
1467 // Dequeue the first object. 1442 // Dequeue the first object.
1468 KeyValuePair<UUID, Vector3> objectData = returnUUIDs.Dequeue(); 1443 var objectData = returnUUIDs.Dequeue();
1469   1444  
1470 vassalForm.Invoke( 1445 vassalForm.Invoke(
1471 (MethodInvoker) 1446 (MethodInvoker)
1472 (() => { vassalForm.StatusText.Text = @"Returning object UUID: " + objectData.Key; })); 1447 (() => { vassalForm.StatusText.Text = @"Returning object UUID: " + objectData.Key; }));
1473   1448  
1474 string currentRegionName = string.Empty; 1449 var currentRegionName = string.Empty;
1475 vassalForm.Invoke((MethodInvoker) (() => { currentRegionName = CurrentRegionName.Text; })); 1450 vassalForm.Invoke((MethodInvoker) (() => { currentRegionName = CurrentRegionName.Text; }));
1476   1451  
1477 // Teleport to the object. 1452 // Teleport to the object.
1478 string result = wasPOST(vassalConfiguration.HTTPServerURL, 1453 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
1479 KeyValue.Escape(new Dictionary<string, string> 1454 KeyValue.Escape(new Dictionary<string, string>
1480 { 1455 {
1481 {"command", "teleport"}, 1456 {"command", "teleport"},
1482 {"group", vassalConfiguration.Group}, 1457 {"group", vassalConfiguration.Group},
1483 {"password", vassalConfiguration.Password}, 1458 {"password", vassalConfiguration.Password},
1484 {"position", objectData.Value.ToString()}, 1459 {"position", objectData.Value.ToString()},
1485 {"region", currentRegionName}, 1460 {"region", currentRegionName},
1486 {"fly", "True"} 1461 {"fly", "True"}
1487 }, wasOutput), vassalConfiguration.TeleportTimeout); 1462 }, wasOutput)).Result);
1488   1463  
1489 if (string.IsNullOrEmpty(result)) 1464 if (string.IsNullOrEmpty(result))
1490 { 1465 {
1491 vassalForm.Invoke( 1466 vassalForm.Invoke(
1492 (MethodInvoker) 1467 (MethodInvoker)
1493 (() => { vassalForm.StatusText.Text = @"Error communicating with Corrade."; })); 1468 (() => { vassalForm.StatusText.Text = @"Error communicating with Corrade."; }));
1494 continue; 1469 continue;
1495 } 1470 }
1496   1471  
1497 // Return the object. 1472 // Return the object.
1498 result = wasPOST(vassalConfiguration.HTTPServerURL, 1473 result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
1499 KeyValue.Escape(new Dictionary<string, string> 1474 KeyValue.Escape(new Dictionary<string, string>
1500 { 1475 {
1501 {"command", "derez"}, 1476 {"command", "derez"},
1502 {"group", vassalConfiguration.Group}, 1477 {"group", vassalConfiguration.Group},
1503 {"password", vassalConfiguration.Password}, 1478 {"password", vassalConfiguration.Password},
1504 {"item", objectData.Key.ToString()}, 1479 {"item", objectData.Key.ToString()},
1505 {"range", "32"}, // maximal prim size = 64 - middle bounding box at half 1480 {"range", "32"}, // maximal prim size = 64 - middle bounding box at half
1506 {"type", "ReturnToOwner"} 1481 {"type", "ReturnToOwner"}
1507 }, wasOutput), vassalConfiguration.DataTimeout); 1482 }, wasOutput)).Result);
1508   1483  
1509 if (string.IsNullOrEmpty(result)) 1484 if (string.IsNullOrEmpty(result))
1510 { 1485 {
1511 vassalForm.Invoke( 1486 vassalForm.Invoke(
1512 (MethodInvoker) 1487 (MethodInvoker)
1513 (() => { vassalForm.StatusText.Text = @"Error communicating with Corrade."; })); 1488 (() => { vassalForm.StatusText.Text = @"Error communicating with Corrade."; }));
1514 continue; 1489 continue;
1515 } 1490 }
1516   1491  
1517 bool success; 1492 bool success;
1518 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 1493 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
1519 { 1494 {
1520 vassalForm.Invoke( 1495 vassalForm.Invoke(
1521 (MethodInvoker) 1496 (MethodInvoker)
1522 (() => { vassalForm.StatusText.Text = @"No success status could be retrieved. "; })); 1497 (() => { vassalForm.StatusText.Text = @"No success status could be retrieved. "; }));
1523 continue; 1498 continue;
1524 } 1499 }
1525   1500  
1526 switch (success) 1501 switch (success)
1527 { 1502 {
1528 case true: 1503 case true:
1529 vassalForm.Invoke((MethodInvoker) (() => 1504 vassalForm.Invoke((MethodInvoker) (() =>
1530 { 1505 {
1531 vassalForm.StatusText.Text = @"Returned object: " + objectData.Key; 1506 vassalForm.StatusText.Text = @"Returned object: " + objectData.Key;
1532 // Remove the row from the grid view. 1507 // Remove the row from the grid view.
1533 DataGridViewRow row = 1508 var row =
1534 TopScriptsGridView.Rows.AsParallel() 1509 TopScriptsGridView.Rows.AsParallel()
1535 .Cast<DataGridViewRow>() 1510 .Cast<DataGridViewRow>()
1536 .FirstOrDefault( 1511 .FirstOrDefault(
1537 o => o.Cells["TopScriptsUUID"].Value.Equals(objectData.Key.ToString())); 1512 o => o.Cells["TopScriptsUUID"].Value.Equals(objectData.Key.ToString()));
1538 if (row == null) return; 1513 if (row == null) return;
1539 int i = row.Index; 1514 var i = row.Index;
1540 TopScriptsGridView.Rows.RemoveAt(i); 1515 TopScriptsGridView.Rows.RemoveAt(i);
1541 })); 1516 }));
1542 break; 1517 break;
1543 case false: 1518 case false:
1544 vassalForm.Invoke((MethodInvoker) (() => 1519 vassalForm.Invoke((MethodInvoker) (() =>
1545 { 1520 {
1546 vassalForm.StatusText.Text = @"Could not return object " + objectData.Key + 1521 vassalForm.StatusText.Text = @"Could not return object " + objectData.Key +
1547 @": " + 1522 @": " +
1548 wasInput(KeyValue.Get("error", result)); 1523 wasInput(KeyValue.Get("error", result));
1549 })); 1524 }));
1550 break; 1525 break;
1551 } 1526 }
1552 vassalForm.Invoke((MethodInvoker) (() => 1527 vassalForm.Invoke((MethodInvoker) (() =>
1553 { 1528 {
1554 vassalForm.StatusProgress.Value = 1529 vassalForm.StatusProgress.Value =
1555 Math.Min((int) (100d*Math.Abs(returnUUIDs.Count - totalObjects)/totalObjects), 100); 1530 Math.Min((int) (100d*Math.Abs(returnUUIDs.Count - totalObjects)/totalObjects), 100);
1556 })); 1531 }));
1557 } while (!returnUUIDs.Count.Equals(0)); 1532 } while (!returnUUIDs.Count.Equals(0));
1558 vassalForm.Invoke((MethodInvoker) (() => { vassalForm.StatusProgress.Value = 100; })); 1533 vassalForm.Invoke((MethodInvoker) (() => { vassalForm.StatusProgress.Value = 100; }));
1559 } 1534 }
1560 catch (Exception ex) 1535 catch (Exception ex)
1561 { 1536 {
1562 vassalForm.Invoke( 1537 vassalForm.Invoke(
1563 (MethodInvoker) (() => { vassalForm.StatusText.Text = @"Unexpected error: " + ex.Message; })); 1538 (MethodInvoker) (() => { vassalForm.StatusText.Text = @"Unexpected error: " + ex.Message; }));
1564 } 1539 }
1565 finally 1540 finally
1566 { 1541 {
1567 Monitor.Exit(ClientInstanceTeleportLock); 1542 Monitor.Exit(ClientInstanceTeleportLock);
1568 // Allow teleports and enable button. 1543 // Allow teleports and enable button.
1569 vassalForm.BeginInvoke((MethodInvoker) (() => 1544 vassalForm.BeginInvoke((MethodInvoker) (() =>
1570 { 1545 {
1571 vassalForm.ReturnTopScriptsButton.Enabled = true; 1546 vassalForm.ReturnTopScriptsButton.Enabled = true;
1572 RegionTeleportGroup.Enabled = true; 1547 RegionTeleportGroup.Enabled = true;
1573 })); 1548 }));
1574 } 1549 }
1575 }) 1550 })
1576 {IsBackground = true}.Start(); 1551 {IsBackground = true}.Start();
1577 } 1552 }
1578   1553  
1579 private void RequestReturnTopCollidersObjects(object sender, EventArgs e) 1554 private void RequestReturnTopCollidersObjects(object sender, EventArgs e)
1580 { 1555 {
1581 // Block teleports and disable button. 1556 // Block teleports and disable button.
1582 vassalForm.Invoke((MethodInvoker) (() => 1557 vassalForm.Invoke((MethodInvoker) (() =>
1583 { 1558 {
1584 vassalForm.ReturnTopCollidersButton.Enabled = false; 1559 vassalForm.ReturnTopCollidersButton.Enabled = false;
1585 RegionTeleportGroup.Enabled = false; 1560 RegionTeleportGroup.Enabled = false;
1586 })); 1561 }));
1587   1562  
1588 // Enqueue all the UUIDs to return. 1563 // Enqueue all the UUIDs to return.
1589 Queue<KeyValuePair<UUID, Vector3>> returnObjectUUIDQueue = new Queue<KeyValuePair<UUID, Vector3>>(); 1564 var returnObjectUUIDQueue = new Queue<KeyValuePair<UUID, Vector3>>();
1590 vassalForm.Invoke((MethodInvoker) (() => 1565 vassalForm.Invoke((MethodInvoker) (() =>
1591 { 1566 {
1592 foreach ( 1567 foreach (
1593 DataGridViewRow topCollidersRow in 1568 var topCollidersRow in
1594 TopCollidersGridView.Rows.AsParallel() 1569 TopCollidersGridView.Rows.AsParallel()
1595 .Cast<DataGridViewRow>() 1570 .Cast<DataGridViewRow>()
1596 .Where(o => o.Selected || o.Cells.Cast<DataGridViewCell>().Any(p => p.Selected))) 1571 .Where(o => o.Selected || o.Cells.Cast<DataGridViewCell>().Any(p => p.Selected)))
1597 { 1572 {
1598 Vector3 objectPosition; 1573 Vector3 objectPosition;
1599 UUID returnUUID; 1574 UUID returnUUID;
1600 if (!UUID.TryParse(topCollidersRow.Cells["TopCollidersUUID"].Value.ToString(), out returnUUID) || 1575 if (!UUID.TryParse(topCollidersRow.Cells["TopCollidersUUID"].Value.ToString(), out returnUUID) ||
1601 !Vector3.TryParse(topCollidersRow.Cells["TopCollidersPosition"].Value.ToString(), 1576 !Vector3.TryParse(topCollidersRow.Cells["TopCollidersPosition"].Value.ToString(),
1602 out objectPosition)) 1577 out objectPosition))
1603 continue; 1578 continue;
1604 returnObjectUUIDQueue.Enqueue(new KeyValuePair<UUID, Vector3>(returnUUID, objectPosition)); 1579 returnObjectUUIDQueue.Enqueue(new KeyValuePair<UUID, Vector3>(returnUUID, objectPosition));
1605 } 1580 }
1606 })); 1581 }));
1607   1582  
1608 // If no rows were selected, enable teleports, the return button and return. 1583 // If no rows were selected, enable teleports, the return button and return.
1609 if (returnObjectUUIDQueue.Count.Equals(0)) 1584 if (returnObjectUUIDQueue.Count.Equals(0))
1610 { 1585 {
1611 vassalForm.Invoke((MethodInvoker) (() => 1586 vassalForm.Invoke((MethodInvoker) (() =>
1612 { 1587 {
1613 vassalForm.ReturnTopCollidersButton.Enabled = true; 1588 vassalForm.ReturnTopCollidersButton.Enabled = true;
1614 RegionTeleportGroup.Enabled = true; 1589 RegionTeleportGroup.Enabled = true;
1615 })); 1590 }));
1616 return; 1591 return;
1617 } 1592 }
1618   1593  
1619 new Thread(() => 1594 new Thread(() =>
1620 { 1595 {
1621 Monitor.Enter(ClientInstanceTeleportLock); 1596 Monitor.Enter(ClientInstanceTeleportLock);
1622   1597  
1623 try 1598 try
1624 { 1599 {
1625 vassalForm.Invoke((MethodInvoker) (() => { vassalForm.StatusProgress.Value = 0; })); 1600 vassalForm.Invoke((MethodInvoker) (() => { vassalForm.StatusProgress.Value = 0; }));
1626 int totalObjects = returnObjectUUIDQueue.Count; 1601 var totalObjects = returnObjectUUIDQueue.Count;
1627 do 1602 do
1628 { 1603 {
1629 // Dequeue the first object. 1604 // Dequeue the first object.
1630 KeyValuePair<UUID, Vector3> objectData = returnObjectUUIDQueue.Dequeue(); 1605 var objectData = returnObjectUUIDQueue.Dequeue();
1631   1606  
1632 vassalForm.Invoke( 1607 vassalForm.Invoke(
1633 (MethodInvoker) 1608 (MethodInvoker)
1634 (() => { vassalForm.StatusText.Text = @"Returning UUID: " + objectData.Key; })); 1609 (() => { vassalForm.StatusText.Text = @"Returning UUID: " + objectData.Key; }));
1635   1610  
1636 string currentRegionName = string.Empty; 1611 var currentRegionName = string.Empty;
1637 vassalForm.Invoke((MethodInvoker) (() => { currentRegionName = CurrentRegionName.Text; })); 1612 vassalForm.Invoke((MethodInvoker) (() => { currentRegionName = CurrentRegionName.Text; }));
1638   1613  
1639 // Teleport to the object. 1614 // Teleport to the object.
1640 string result = wasPOST(vassalConfiguration.HTTPServerURL, 1615 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
1641 KeyValue.Escape(new Dictionary<string, string> 1616 KeyValue.Escape(new Dictionary<string, string>
1642 { 1617 {
1643 {"command", "teleport"}, 1618 {"command", "teleport"},
1644 {"group", vassalConfiguration.Group}, 1619 {"group", vassalConfiguration.Group},
1645 {"password", vassalConfiguration.Password}, 1620 {"password", vassalConfiguration.Password},
1646 {"position", objectData.Value.ToString()}, 1621 {"position", objectData.Value.ToString()},
1647 {"region", currentRegionName}, 1622 {"region", currentRegionName},
1648 {"fly", "True"} 1623 {"fly", "True"}
1649 }, wasOutput), vassalConfiguration.DataTimeout); 1624 }, wasOutput)).Result);
1650   1625  
1651 if (string.IsNullOrEmpty(result)) 1626 if (string.IsNullOrEmpty(result))
1652 { 1627 {
1653 vassalForm.Invoke( 1628 vassalForm.Invoke(
1654 (MethodInvoker) 1629 (MethodInvoker)
1655 (() => { vassalForm.StatusText.Text = @"Error communicating with Corrade."; })); 1630 (() => { vassalForm.StatusText.Text = @"Error communicating with Corrade."; }));
1656 continue; 1631 continue;
1657 } 1632 }
1658   1633  
1659 // Return the object. 1634 // Return the object.
1660 result = wasPOST(vassalConfiguration.HTTPServerURL, 1635 result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
1661 KeyValue.Escape(new Dictionary<string, string> 1636 KeyValue.Escape(new Dictionary<string, string>
1662 { 1637 {
1663 {"command", "derez"}, 1638 {"command", "derez"},
1664 {"group", vassalConfiguration.Group}, 1639 {"group", vassalConfiguration.Group},
1665 {"password", vassalConfiguration.Password}, 1640 {"password", vassalConfiguration.Password},
1666 {"item", objectData.Key.ToString()}, 1641 {"item", objectData.Key.ToString()},
1667 {"range", "32"}, // maximal prim size = 64 - middle bounding box at half 1642 {"range", "32"}, // maximal prim size = 64 - middle bounding box at half
1668 {"type", "ReturnToOwner"} 1643 {"type", "ReturnToOwner"}
1669 }, wasOutput), vassalConfiguration.DataTimeout); 1644 }, wasOutput)).Result);
1670   1645  
1671 if (string.IsNullOrEmpty(result)) 1646 if (string.IsNullOrEmpty(result))
1672 { 1647 {
1673 vassalForm.Invoke( 1648 vassalForm.Invoke(
1674 (MethodInvoker) 1649 (MethodInvoker)
1675 (() => { vassalForm.StatusText.Text = @"Error communicating with Corrade."; })); 1650 (() => { vassalForm.StatusText.Text = @"Error communicating with Corrade."; }));
1676 continue; 1651 continue;
1677 } 1652 }
1678   1653  
1679 bool success; 1654 bool success;
1680 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 1655 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
1681 { 1656 {
1682 vassalForm.Invoke( 1657 vassalForm.Invoke(
1683 (MethodInvoker) 1658 (MethodInvoker)
1684 (() => { vassalForm.StatusText.Text = @"No success status could be retrieved. "; })); 1659 (() => { vassalForm.StatusText.Text = @"No success status could be retrieved. "; }));
1685 continue; 1660 continue;
1686 } 1661 }
1687   1662  
1688 switch (success) 1663 switch (success)
1689 { 1664 {
1690 case true: 1665 case true:
1691 vassalForm.Invoke((MethodInvoker) (() => 1666 vassalForm.Invoke((MethodInvoker) (() =>
1692 { 1667 {
1693 vassalForm.StatusText.Text = @"Returned object: " + objectData.Key; 1668 vassalForm.StatusText.Text = @"Returned object: " + objectData.Key;
1694 // Remove the row from the grid view. 1669 // Remove the row from the grid view.
1695 DataGridViewRow row = 1670 var row =
1696 TopCollidersGridView.Rows.AsParallel() 1671 TopCollidersGridView.Rows.AsParallel()
1697 .Cast<DataGridViewRow>() 1672 .Cast<DataGridViewRow>()
1698 .FirstOrDefault( 1673 .FirstOrDefault(
1699 o => o.Cells["TopCollidersUUID"].Value.Equals(objectData.Key.ToString())); 1674 o => o.Cells["TopCollidersUUID"].Value.Equals(objectData.Key.ToString()));
1700 if (row == null) return; 1675 if (row == null) return;
1701 int i = row.Index; 1676 var i = row.Index;
1702 TopCollidersGridView.Rows.RemoveAt(i); 1677 TopCollidersGridView.Rows.RemoveAt(i);
1703 })); 1678 }));
1704 break; 1679 break;
1705 case false: 1680 case false:
1706 vassalForm.Invoke((MethodInvoker) (() => 1681 vassalForm.Invoke((MethodInvoker) (() =>
1707 { 1682 {
1708 vassalForm.StatusText.Text = @"Could not return object " + objectData.Key + 1683 vassalForm.StatusText.Text = @"Could not return object " + objectData.Key +
1709 @": " + 1684 @": " +
1710 wasInput(KeyValue.Get("error", result)); 1685 wasInput(KeyValue.Get("error", result));
1711 })); 1686 }));
1712 break; 1687 break;
1713 } 1688 }
1714 vassalForm.Invoke((MethodInvoker) (() => 1689 vassalForm.Invoke((MethodInvoker) (() =>
1715 { 1690 {
1716 vassalForm.StatusProgress.Value = 1691 vassalForm.StatusProgress.Value =
1717 Math.Min( 1692 Math.Min(
1718 (int) (100d*Math.Abs(returnObjectUUIDQueue.Count - totalObjects)/totalObjects), 100); 1693 (int) (100d*Math.Abs(returnObjectUUIDQueue.Count - totalObjects)/totalObjects), 100);
1719 })); 1694 }));
1720 } while (!returnObjectUUIDQueue.Count.Equals(0)); 1695 } while (!returnObjectUUIDQueue.Count.Equals(0));
1721 vassalForm.Invoke((MethodInvoker) (() => { vassalForm.StatusProgress.Value = 100; })); 1696 vassalForm.Invoke((MethodInvoker) (() => { vassalForm.StatusProgress.Value = 100; }));
1722 } 1697 }
1723 catch (Exception ex) 1698 catch (Exception ex)
1724 { 1699 {
1725 vassalForm.Invoke( 1700 vassalForm.Invoke(
1726 (MethodInvoker) (() => { vassalForm.StatusText.Text = @"Unexpected error: " + ex.Message; })); 1701 (MethodInvoker) (() => { vassalForm.StatusText.Text = @"Unexpected error: " + ex.Message; }));
1727 } 1702 }
1728 finally 1703 finally
1729 { 1704 {
1730 Monitor.Exit(ClientInstanceTeleportLock); 1705 Monitor.Exit(ClientInstanceTeleportLock);
1731 // Allow teleports and enable button. 1706 // Allow teleports and enable button.
1732 vassalForm.BeginInvoke((MethodInvoker) (() => 1707 vassalForm.BeginInvoke((MethodInvoker) (() =>
1733 { 1708 {
1734 vassalForm.ReturnTopScriptsButton.Enabled = true; 1709 vassalForm.ReturnTopScriptsButton.Enabled = true;
1735 RegionTeleportGroup.Enabled = true; 1710 RegionTeleportGroup.Enabled = true;
1736 })); 1711 }));
1737 } 1712 }
1738 }) 1713 })
1739 {IsBackground = true}.Start(); 1714 {IsBackground = true}.Start();
1740 } 1715 }
1741   1716  
1742 private void RequestBatchRestart(object sender, EventArgs e) 1717 private void RequestBatchRestart(object sender, EventArgs e)
1743 { 1718 {
1744 // Block teleports and disable button. 1719 // Block teleports and disable button.
1745 vassalForm.Invoke((MethodInvoker) (() => 1720 vassalForm.Invoke((MethodInvoker) (() =>
1746 { 1721 {
1747 vassalForm.BatchRestartButton.Enabled = false; 1722 vassalForm.BatchRestartButton.Enabled = false;
-   1723 vassalForm.RegionRestartDelayBox.Enabled = false;
1748 RegionTeleportGroup.Enabled = false; 1724 RegionTeleportGroup.Enabled = false;
1749 })); 1725 }));
1750   1726  
1751 // Enqueue all the regions to restart. 1727 // Enqueue all the regions to restart.
1752 Queue<KeyValuePair<string, Vector3>> restartRegionQueue = new Queue<KeyValuePair<string, Vector3>>(); 1728 var restartRegionQueue = new Queue<KeyValuePair<string, Vector3>>();
1753 vassalForm.Invoke((MethodInvoker) (() => 1729 vassalForm.Invoke((MethodInvoker) (() =>
1754 { 1730 {
1755 foreach ( 1731 foreach (
1756 DataGridViewRow topCollidersRow in 1732 var topCollidersRow in
1757 BatchRestartGridView.Rows.AsParallel() 1733 BatchRestartGridView.Rows.AsParallel()
1758 .Cast<DataGridViewRow>() 1734 .Cast<DataGridViewRow>()
1759 .Where(o => o.Selected || o.Cells.Cast<DataGridViewCell>().Any(p => p.Selected))) 1735 .Where(o => o.Selected || o.Cells.Cast<DataGridViewCell>().Any(p => p.Selected)))
1760 { 1736 {
1761 Vector3 objectPosition; 1737 Vector3 objectPosition;
1762 string regionName = topCollidersRow.Cells["BatchRestartRegionName"].Value.ToString(); 1738 var regionName = topCollidersRow.Cells["BatchRestartRegionName"].Value.ToString();
1763 if (string.IsNullOrEmpty(regionName) || 1739 if (string.IsNullOrEmpty(regionName) ||
1764 !Vector3.TryParse(topCollidersRow.Cells["BatchRestartPosition"].Value.ToString(), 1740 !Vector3.TryParse(topCollidersRow.Cells["BatchRestartPosition"].Value.ToString(),
1765 out objectPosition)) 1741 out objectPosition))
1766 continue; 1742 continue;
1767 restartRegionQueue.Enqueue(new KeyValuePair<string, Vector3>(regionName, objectPosition)); 1743 restartRegionQueue.Enqueue(new KeyValuePair<string, Vector3>(regionName, objectPosition));
1768 } 1744 }
1769 })); 1745 }));
1770   1746  
1771 // If no rows were selected, enable teleports, the return button and return. 1747 // If no rows were selected, enable teleports, the return button and return.
1772 if (restartRegionQueue.Count.Equals(0)) 1748 if (restartRegionQueue.Count.Equals(0))
1773 { 1749 {
1774 vassalForm.Invoke((MethodInvoker) (() => 1750 vassalForm.Invoke((MethodInvoker) (() =>
1775 { 1751 {
1776 vassalForm.BatchRestartButton.Enabled = true; 1752 vassalForm.BatchRestartButton.Enabled = true;
-   1753 vassalForm.RegionRestartDelayBox.Enabled = true;
1777 RegionTeleportGroup.Enabled = true; 1754 RegionTeleportGroup.Enabled = true;
1778 })); 1755 }));
1779 return; 1756 return;
1780 } 1757 }
1781   1758  
1782 new Thread(() => 1759 new Thread(() =>
1783 { 1760 {
1784 Monitor.Enter(ClientInstanceTeleportLock); 1761 Monitor.Enter(ClientInstanceTeleportLock);
1785   1762  
1786 try 1763 try
1787 { 1764 {
1788 do 1765 do
1789 { 1766 {
1790 // Dequeue the first object. 1767 // Dequeue the first object.
1791 KeyValuePair<string, Vector3> restartRegionData = restartRegionQueue.Dequeue(); 1768 var restartRegionData = restartRegionQueue.Dequeue();
1792 DataGridViewRow currentDataGridViewRow = null; 1769 DataGridViewRow currentDataGridViewRow = null;
1793 vassalForm.Invoke((MethodInvoker) (() => 1770 vassalForm.Invoke((MethodInvoker) (() =>
1794 { 1771 {
1795 currentDataGridViewRow = vassalForm.BatchRestartGridView.Rows.AsParallel() 1772 currentDataGridViewRow = vassalForm.BatchRestartGridView.Rows.AsParallel()
1796 .Cast<DataGridViewRow>() 1773 .Cast<DataGridViewRow>()
1797 .FirstOrDefault( 1774 .FirstOrDefault(
1798 o => 1775 o =>
1799 o.Cells["BatchRestartRegionName"].Value.ToString() 1776 o.Cells["BatchRestartRegionName"].Value.ToString()
1800 .Equals(restartRegionData.Key, StringComparison.OrdinalIgnoreCase) && 1777 .Equals(restartRegionData.Key, StringComparison.OrdinalIgnoreCase) &&
1801 o.Cells["BatchRestartPosition"].Value.ToString() 1778 o.Cells["BatchRestartPosition"].Value.ToString()
1802 .Equals(restartRegionData.Value.ToString(), 1779 .Equals(restartRegionData.Value.ToString(),
1803 StringComparison.OrdinalIgnoreCase)); 1780 StringComparison.OrdinalIgnoreCase));
1804 })); 1781 }));
1805   1782  
1806 if (currentDataGridViewRow == null) continue; 1783 if (currentDataGridViewRow == null) continue;
1807   1784  
1808 try 1785 try
1809 { 1786 {
1810 bool success = false; 1787 var success = false;
1811 string result; 1788 string result;
1812   1789  
1813 // Retry to teleport to each region a few times. 1790 // Retry to teleport to each region a few times.
1814 int teleportRetries = 3; 1791 var teleportRetries = 3;
1815 do 1792 do
1816 { 1793 {
1817 vassalForm.Invoke((MethodInvoker) (() => 1794 vassalForm.Invoke((MethodInvoker) (() =>
1818 { 1795 {
1819 vassalForm.StatusText.Text = @"Attempting to teleport to " + restartRegionData.Key + 1796 vassalForm.StatusText.Text = @"Attempting to teleport to " + restartRegionData.Key +
1820 @" " + @"(" + 1797 @" " + @"(" +
1821 teleportRetries.ToString(Utils.EnUsCulture) + 1798 teleportRetries.ToString(Utils.EnUsCulture) +
1822 @")"; 1799 @")";
1823 })); 1800 }));
1824   1801  
1825 // Teleport to the region. 1802 // Teleport to the region.
1826 result = wasPOST(vassalConfiguration.HTTPServerURL, 1803 result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
1827 KeyValue.Escape(new Dictionary<string, string> 1804 KeyValue.Escape(new Dictionary<string, string>
1828 { 1805 {
1829 {"command", "teleport"}, 1806 {"command", "teleport"},
1830 {"group", vassalConfiguration.Group}, 1807 {"group", vassalConfiguration.Group},
1831 {"password", vassalConfiguration.Password}, 1808 {"password", vassalConfiguration.Password},
1832 {"position", restartRegionData.Value.ToString()}, 1809 {"position", restartRegionData.Value.ToString()},
1833 {"region", restartRegionData.Key}, 1810 {"region", restartRegionData.Key},
1834 {"fly", "True"} 1811 {"fly", "True"}
1835 }, wasOutput), vassalConfiguration.DataTimeout); 1812 }, wasOutput)).Result);
1836   1813  
1837 if (string.IsNullOrEmpty(result)) 1814 if (string.IsNullOrEmpty(result))
1838 { 1815 {
1839 vassalForm.Invoke( 1816 vassalForm.Invoke(
1840 (MethodInvoker) 1817 (MethodInvoker)
1841 (() => 1818 (() =>
1842 { 1819 {
1843 vassalForm.StatusText.Text = @"Error communicating with Corrade."; 1820 vassalForm.StatusText.Text = @"Error communicating with Corrade.";
1844 })); 1821 }));
1845 continue; 1822 continue;
1846 } 1823 }
1847 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 1824 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
1848 { 1825 {
1849 vassalForm.Invoke( 1826 vassalForm.Invoke(
1850 (MethodInvoker) 1827 (MethodInvoker)
1851 (() => 1828 (() =>
1852 { 1829 {
1853 vassalForm.StatusText.Text = @"No success status could be retrieved. "; 1830 vassalForm.StatusText.Text = @"No success status could be retrieved. ";
1854 })); 1831 }));
1855 continue; 1832 continue;
1856 } 1833 }
1857 switch (success) 1834 switch (success)
1858 { 1835 {
1859 case true: 1836 case true:
1860 vassalForm.Invoke( 1837 vassalForm.Invoke(
1861 (MethodInvoker) 1838 (MethodInvoker)
1862 (() => { vassalForm.StatusText.Text = @"Teleport succeeded."; })); 1839 (() => { vassalForm.StatusText.Text = @"Teleport succeeded."; }));
1863 break; 1840 break;
1864 default: 1841 default:
1865 // In case the destination is to close (Corrade status code 37559), 1842 // In case the destination is to close (Corrade status code 37559),
1866 // then we are on the same region so no need to retry. 1843 // then we are on the same region so no need to retry.
1867 uint status; //37559 1844 uint status; //37559
1868 switch ( 1845 switch (
1869 uint.TryParse(wasInput(KeyValue.Get("status", result)), out status) && 1846 uint.TryParse(wasInput(KeyValue.Get("status", result)), out status) &&
1870 status.Equals(37559)) 1847 status.Equals(37559))
1871 { 1848 {
1872 case true: // We are on the region already! 1849 case true: // We are on the region already!
1873 success = true; 1850 success = true;
1874 break; 1851 break;
1875 default: 1852 default:
1876 vassalForm.Invoke( 1853 vassalForm.Invoke(
1877 (MethodInvoker) 1854 (MethodInvoker)
1878 (() => { vassalForm.StatusText.Text = @"Teleport failed."; })); 1855 (() => { vassalForm.StatusText.Text = @"Teleport failed."; }));
1879 break; 1856 break;
1880 } 1857 }
1881 break; 1858 break;
1882 } 1859 }
1883   1860  
1884 // Pause for teleport (10 teleports / 15s allowed). 1861 // Pause for teleport (10 teleports / 15s allowed).
1885 Thread.Sleep(700); 1862 Thread.Sleep(700);
1886 } while (!success && !(--teleportRetries).Equals(0)); 1863 } while (!success && !(--teleportRetries).Equals(0));
1887   1864  
1888 if (!success) 1865 if (!success)
1889 throw new Exception("Failed to teleport to region."); 1866 throw new Exception("Failed to teleport to region.");
1890   1867  
1891 result = wasPOST(vassalConfiguration.HTTPServerURL, 1868 result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
1892 KeyValue.Escape(new Dictionary<string, string> 1869 KeyValue.Escape(new Dictionary<string, string>
1893 { 1870 {
1894 {"command", "getregiondata"}, 1871 {"command", "getregiondata"},
1895 {"group", vassalConfiguration.Group}, 1872 {"group", vassalConfiguration.Group},
1896 {"password", vassalConfiguration.Password}, 1873 {"password", vassalConfiguration.Password},
1897 {"data", "IsEstateManager"} 1874 {"data", "IsEstateManager"}
1898 }, wasOutput), vassalConfiguration.DataTimeout); 1875 }, wasOutput)).Result);
1899   1876  
1900 if (string.IsNullOrEmpty(result)) 1877 if (string.IsNullOrEmpty(result))
1901 throw new Exception("Error communicating with Corrade."); 1878 throw new Exception("Error communicating with Corrade.");
1902   1879  
1903 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 1880 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
1904 throw new Exception("No success status could be retrieved."); 1881 throw new Exception("No success status could be retrieved.");
1905   1882  
1906 if (!success) 1883 if (!success)
1907 throw new Exception("Could not retrieve estate rights."); 1884 throw new Exception("Could not retrieve estate rights.");
1908   1885  
1909 List<string> data = CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))).ToList(); 1886 var data = CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))).ToList();
1910 if (!data.Count.Equals(2)) 1887 if (!data.Count.Equals(2))
1911 throw new Exception("Could not retrieve estate rights."); 1888 throw new Exception("Could not retrieve estate rights.");
1912   1889  
1913 bool isEstateManager; 1890 bool isEstateManager;
1914 switch ( 1891 switch (
1915 bool.TryParse(data[data.IndexOf("IsEstateManager") + 1], out isEstateManager) && 1892 bool.TryParse(data[data.IndexOf("IsEstateManager") + 1], out isEstateManager) &&
1916 isEstateManager) 1893 isEstateManager)
1917 { 1894 {
1918 case true: // we are an estate manager 1895 case true: // we are an estate manager
1919 result = wasPOST(vassalConfiguration.HTTPServerURL, 1896 result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
1920 KeyValue.Escape(new Dictionary<string, string> 1897 KeyValue.Escape(new Dictionary<string, string>
1921 { 1898 {
1922 {"command", "restartregion"}, 1899 {"command", "restartregion"},
1923 {"group", vassalConfiguration.Group}, 1900 {"group", vassalConfiguration.Group},
1924 {"password", vassalConfiguration.Password}, 1901 {"password", vassalConfiguration.Password},
1925 {"action", "restart"}, 1902 {"action", "restart"},
1926 { 1903 {
1927 "delay", 1904 "delay",
1928 vassalConfiguration.RegionRestartDelay.ToString(Utils.EnUsCulture) 1905 vassalForm.RegionRestartDelayBox.Text
1929 } 1906 }
1930 }, wasOutput), vassalConfiguration.DataTimeout); 1907 }, wasOutput)).Result);
1931   1908  
1932 if (string.IsNullOrEmpty(result)) 1909 if (string.IsNullOrEmpty(result))
1933 throw new Exception("Error communicating with Corrade."); 1910 throw new Exception("Error communicating with Corrade.");
1934   1911  
1935 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 1912 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
1936 throw new Exception("No success status could be retrieved."); 1913 throw new Exception("No success status could be retrieved.");
1937   1914  
1938 if (!success) 1915 if (!success)
1939 throw new Exception("Could not schedule a region restart."); 1916 throw new Exception("Could not schedule a region restart.");
1940   1917  
1941 vassalForm.Invoke((MethodInvoker) (() => 1918 vassalForm.Invoke((MethodInvoker) (() =>
1942 { 1919 {
1943 vassalForm.StatusText.Text = @"Region scheduled for restart."; 1920 vassalForm.StatusText.Text = @"Region scheduled for restart.";
1944 currentDataGridViewRow.Selected = false; 1921 currentDataGridViewRow.Selected = false;
1945 currentDataGridViewRow.DefaultCellStyle.BackColor = Color.LightGreen; 1922 currentDataGridViewRow.DefaultCellStyle.BackColor = Color.LightGreen;
1946 foreach ( 1923 foreach (
1947 DataGridViewCell cell in 1924 var cell in
1948 currentDataGridViewRow.Cells.AsParallel().Cast<DataGridViewCell>()) 1925 currentDataGridViewRow.Cells.AsParallel().Cast<DataGridViewCell>())
1949 { 1926 {
1950 cell.ToolTipText = @"Region scheduled for restart."; 1927 cell.ToolTipText = @"Region scheduled for restart.";
1951 } 1928 }
1952 })); 1929 }));
1953 break; 1930 break;
1954 default: 1931 default:
1955 throw new Exception("No estate manager rights for region restart."); 1932 throw new Exception("No estate manager rights for region restart.");
1956 } 1933 }
1957 } 1934 }
1958 catch (Exception ex) 1935 catch (Exception ex)
1959 { 1936 {
1960 vassalForm.Invoke((MethodInvoker) (() => 1937 vassalForm.Invoke((MethodInvoker) (() =>
1961 { 1938 {
1962 vassalForm.StatusText.Text = ex.Message; 1939 vassalForm.StatusText.Text = ex.Message;
1963 currentDataGridViewRow.Selected = false; 1940 currentDataGridViewRow.Selected = false;
1964 currentDataGridViewRow.DefaultCellStyle.BackColor = Color.LightPink; 1941 currentDataGridViewRow.DefaultCellStyle.BackColor = Color.LightPink;
1965 foreach ( 1942 foreach (
1966 DataGridViewCell cell in 1943 var cell in
1967 currentDataGridViewRow.Cells.AsParallel().Cast<DataGridViewCell>()) 1944 currentDataGridViewRow.Cells.AsParallel().Cast<DataGridViewCell>())
1968 { 1945 {
1969 cell.ToolTipText = ex.Message; 1946 cell.ToolTipText = ex.Message;
1970 } 1947 }
1971 })); 1948 }));
1972 } 1949 }
1973 finally 1950 finally
1974 { 1951 {
1975 // Pause for teleport (10 teleports / 15s allowed). 1952 // Pause for teleport (10 teleports / 15s allowed).
1976 Thread.Sleep(700); 1953 Thread.Sleep(700);
1977 } 1954 }
1978 } while (!restartRegionQueue.Count.Equals(0)); 1955 } while (!restartRegionQueue.Count.Equals(0));
1979 } 1956 }
1980 catch (Exception) 1957 catch (Exception)
1981 { 1958 {
1982 } 1959 }
1983 finally 1960 finally
1984 { 1961 {
1985 Monitor.Exit(ClientInstanceTeleportLock); 1962 Monitor.Exit(ClientInstanceTeleportLock);
1986 // Allow teleports and enable button. 1963 // Allow teleports and enable button.
1987 vassalForm.BeginInvoke((MethodInvoker) (() => 1964 vassalForm.BeginInvoke((MethodInvoker) (() =>
1988 { 1965 {
1989 vassalForm.BatchRestartButton.Enabled = true; 1966 vassalForm.BatchRestartButton.Enabled = true;
-   1967 vassalForm.RegionRestartDelayBox.Enabled = true;
1990 RegionTeleportGroup.Enabled = true; 1968 RegionTeleportGroup.Enabled = true;
1991 })); 1969 }));
1992 } 1970 }
1993 }) 1971 })
1994 {IsBackground = true}.Start(); 1972 {IsBackground = true}.Start();
1995 } 1973 }
1996   1974  
1997 private void RequestFilterResidentList(object sender, EventArgs e) 1975 private void RequestFilterResidentList(object sender, EventArgs e)
1998 { 1976 {
1999 vassalForm.BeginInvoke((MethodInvoker) (() => 1977 vassalForm.BeginInvoke((MethodInvoker) (() =>
2000 { 1978 {
2001 Regex residentListRowRegex; 1979 Regex residentListRowRegex;
2002 switch (!string.IsNullOrEmpty(ResidentListFilter.Text)) 1980 switch (!string.IsNullOrEmpty(ResidentListFilter.Text))
2003 { 1981 {
2004 case true: 1982 case true:
2005 residentListRowRegex = new Regex(ResidentListFilter.Text, RegexOptions.Compiled); 1983 residentListRowRegex = new Regex(ResidentListFilter.Text, RegexOptions.Compiled);
2006 break; 1984 break;
2007 default: 1985 default:
2008 residentListRowRegex = new Regex(@".+?", RegexOptions.Compiled); 1986 residentListRowRegex = new Regex(@".+?", RegexOptions.Compiled);
2009 break; 1987 break;
2010 } 1988 }
2011 foreach ( 1989 foreach (
2012 DataGridViewRow residentListRow in ResidentListGridView.Rows.AsParallel().Cast<DataGridViewRow>()) 1990 var residentListRow in ResidentListGridView.Rows.AsParallel().Cast<DataGridViewRow>())
2013 { 1991 {
2014 residentListRow.Visible = 1992 residentListRow.Visible =
2015 residentListRowRegex.IsMatch(residentListRow.Cells["ResidentListName"].Value.ToString()) || 1993 residentListRowRegex.IsMatch(residentListRow.Cells["ResidentListName"].Value.ToString()) ||
2016 residentListRowRegex.IsMatch( 1994 residentListRowRegex.IsMatch(
2017 residentListRow.Cells["ResidentListUUID"].Value.ToString()) || 1995 residentListRow.Cells["ResidentListUUID"].Value.ToString()) ||
2018 residentListRowRegex.IsMatch(residentListRow.Cells["ResidentListPosition"].Value.ToString()); 1996 residentListRowRegex.IsMatch(residentListRow.Cells["ResidentListPosition"].Value.ToString());
2019 } 1997 }
2020 })); 1998 }));
2021 } 1999 }
2022   2000  
2023 private void RequestBanAgents(object sender, EventArgs e) 2001 private void RequestBanAgents(object sender, EventArgs e)
2024 { 2002 {
2025 // Block teleports and disable button. 2003 // Block teleports and disable button.
2026 vassalForm.Invoke((MethodInvoker) (() => 2004 vassalForm.Invoke((MethodInvoker) (() =>
2027 { 2005 {
2028 ResidentListTeleportHomeGroup.Enabled = false; 2006 ResidentListTeleportHomeGroup.Enabled = false;
2029 ResidentListBanGroup.Enabled = false; 2007 ResidentListBanGroup.Enabled = false;
2030 RegionTeleportGroup.Enabled = false; 2008 RegionTeleportGroup.Enabled = false;
2031 })); 2009 }));
2032   2010  
2033 // Enqueue all the agents to ban. 2011 // Enqueue all the agents to ban.
2034 Queue<UUID> agentsQueue = new Queue<UUID>(); 2012 var agentsQueue = new Queue<UUID>();
2035 vassalForm.Invoke((MethodInvoker) (() => 2013 vassalForm.Invoke((MethodInvoker) (() =>
2036 { 2014 {
2037 foreach ( 2015 foreach (
2038 DataGridViewRow residentListRow in 2016 var residentListRow in
2039 ResidentListGridView.Rows.AsParallel() 2017 ResidentListGridView.Rows.AsParallel()
2040 .Cast<DataGridViewRow>() 2018 .Cast<DataGridViewRow>()
2041 .Where(o => o.Selected || o.Cells.Cast<DataGridViewCell>().Any(p => p.Selected))) 2019 .Where(o => o.Selected || o.Cells.Cast<DataGridViewCell>().Any(p => p.Selected)))
2042 { 2020 {
2043 UUID agentUUID; 2021 UUID agentUUID;
2044 if (!UUID.TryParse(residentListRow.Cells["ResidentListUUID"].Value.ToString(), out agentUUID)) 2022 if (!UUID.TryParse(residentListRow.Cells["ResidentListUUID"].Value.ToString(), out agentUUID))
2045 continue; 2023 continue;
2046 agentsQueue.Enqueue(agentUUID); 2024 agentsQueue.Enqueue(agentUUID);
2047 } 2025 }
2048 })); 2026 }));
2049   2027  
2050 // If no rows were selected, enable teleports, the return button and return. 2028 // If no rows were selected, enable teleports, the return button and return.
2051 if (agentsQueue.Count.Equals(0)) 2029 if (agentsQueue.Count.Equals(0))
2052 { 2030 {
2053 vassalForm.Invoke((MethodInvoker) (() => 2031 vassalForm.Invoke((MethodInvoker) (() =>
2054 { 2032 {
2055 ResidentListBanGroup.Enabled = true; 2033 ResidentListBanGroup.Enabled = true;
2056 RegionTeleportGroup.Enabled = true; 2034 RegionTeleportGroup.Enabled = true;
2057 })); 2035 }));
2058 return; 2036 return;
2059 } 2037 }
2060   2038  
2061 new Thread(() => 2039 new Thread(() =>
2062 { 2040 {
2063 Monitor.Enter(ClientInstanceTeleportLock); 2041 Monitor.Enter(ClientInstanceTeleportLock);
2064 try 2042 try
2065 { 2043 {
2066 do 2044 do
2067 { 2045 {
2068 // Dequeue the first object. 2046 // Dequeue the first object.
2069 UUID agentUUID = agentsQueue.Dequeue(); 2047 var agentUUID = agentsQueue.Dequeue();
2070 DataGridViewRow currentDataGridViewRow = null; 2048 DataGridViewRow currentDataGridViewRow = null;
2071 vassalForm.Invoke((MethodInvoker) (() => 2049 vassalForm.Invoke((MethodInvoker) (() =>
2072 { 2050 {
2073 currentDataGridViewRow = vassalForm.ResidentListGridView.Rows.AsParallel() 2051 currentDataGridViewRow = vassalForm.ResidentListGridView.Rows.AsParallel()
2074 .Cast<DataGridViewRow>() 2052 .Cast<DataGridViewRow>()
2075 .FirstOrDefault( 2053 .FirstOrDefault(
2076 o => 2054 o =>
2077 o.Cells["ResidentListUUID"].Value.ToString() 2055 o.Cells["ResidentListUUID"].Value.ToString()
2078 .Equals(agentUUID.ToString(), StringComparison.OrdinalIgnoreCase)); 2056 .Equals(agentUUID.ToString(), StringComparison.OrdinalIgnoreCase));
2079 })); 2057 }));
2080   2058  
2081 if (currentDataGridViewRow == null) continue; 2059 if (currentDataGridViewRow == null) continue;
2082   2060  
2083 try 2061 try
2084 { 2062 {
2085 bool alsoBan = false; 2063 var alsoBan = false;
2086 vassalForm.Invoke( 2064 vassalForm.Invoke(
2087 (MethodInvoker) (() => { alsoBan = vassalForm.ResidentBanAllEstatesBox.Checked; })); 2065 (MethodInvoker) (() => { alsoBan = vassalForm.ResidentBanAllEstatesBox.Checked; }));
2088   2066  
2089 // Ban the resident. 2067 // Ban the resident.
2090 string result = wasPOST(vassalConfiguration.HTTPServerURL, 2068 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
2091 KeyValue.Escape(new Dictionary<string, string> 2069 KeyValue.Escape(new Dictionary<string, string>
2092 { 2070 {
2093 {"command", "setestatelist"}, 2071 {"command", "setestatelist"},
2094 {"group", vassalConfiguration.Group}, 2072 {"group", vassalConfiguration.Group},
2095 {"password", vassalConfiguration.Password}, 2073 {"password", vassalConfiguration.Password},
2096 {"type", "ban"}, 2074 {"type", "ban"},
2097 {"action", "add"}, 2075 {"action", "add"},
2098 {"agent", agentUUID.ToString()}, 2076 {"agent", agentUUID.ToString()},
2099 {"all", alsoBan.ToString()} 2077 {"all", alsoBan.ToString()}
2100 }, wasOutput), vassalConfiguration.DataTimeout); 2078 }, wasOutput)).Result);
2101   2079  
2102 if (string.IsNullOrEmpty(result)) 2080 if (string.IsNullOrEmpty(result))
2103 throw new Exception("Error communicating with Corrade."); 2081 throw new Exception("Error communicating with Corrade.");
2104   2082  
2105 bool success; 2083 bool success;
2106 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 2084 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
2107 throw new Exception("No success status could be retrieved."); 2085 throw new Exception("No success status could be retrieved.");
2108   2086  
2109 switch (success) 2087 switch (success)
2110 { 2088 {
2111 case true: 2089 case true:
2112 vassalForm.Invoke((MethodInvoker) (() => 2090 vassalForm.Invoke((MethodInvoker) (() =>
2113 { 2091 {
2114 vassalForm.StatusText.Text = @"Resident banned."; 2092 vassalForm.StatusText.Text = @"Resident banned.";
2115 currentDataGridViewRow.Selected = false; 2093 currentDataGridViewRow.Selected = false;
2116 currentDataGridViewRow.DefaultCellStyle.BackColor = Color.LightGreen; 2094 currentDataGridViewRow.DefaultCellStyle.BackColor = Color.LightGreen;
2117 foreach ( 2095 foreach (
2118 DataGridViewCell cell in 2096 var cell in
2119 currentDataGridViewRow.Cells.AsParallel().Cast<DataGridViewCell>()) 2097 currentDataGridViewRow.Cells.AsParallel().Cast<DataGridViewCell>())
2120 { 2098 {
2121 cell.ToolTipText = @"Resident banned."; 2099 cell.ToolTipText = @"Resident banned.";
2122 } 2100 }
2123 })); 2101 }));
2124 break; 2102 break;
2125 default: 2103 default:
2126 throw new Exception("Unable to ban resident."); 2104 throw new Exception("Unable to ban resident.");
2127 } 2105 }
2128 } 2106 }
2129 catch (Exception ex) 2107 catch (Exception ex)
2130 { 2108 {
2131 vassalForm.Invoke((MethodInvoker) (() => 2109 vassalForm.Invoke((MethodInvoker) (() =>
2132 { 2110 {
2133 vassalForm.StatusText.Text = ex.Message; 2111 vassalForm.StatusText.Text = ex.Message;
2134 currentDataGridViewRow.Selected = false; 2112 currentDataGridViewRow.Selected = false;
2135 currentDataGridViewRow.DefaultCellStyle.BackColor = Color.LightPink; 2113 currentDataGridViewRow.DefaultCellStyle.BackColor = Color.LightPink;
2136 foreach ( 2114 foreach (
2137 DataGridViewCell cell in 2115 var cell in
2138 currentDataGridViewRow.Cells.AsParallel().Cast<DataGridViewCell>()) 2116 currentDataGridViewRow.Cells.AsParallel().Cast<DataGridViewCell>())
2139 { 2117 {
2140 cell.ToolTipText = ex.Message; 2118 cell.ToolTipText = ex.Message;
2141 } 2119 }
2142 })); 2120 }));
2143 } 2121 }
2144 } while (agentsQueue.Count.Equals(0)); 2122 } while (agentsQueue.Count.Equals(0));
2145 } 2123 }
2146 catch (Exception) 2124 catch (Exception)
2147 { 2125 {
2148 } 2126 }
2149 finally 2127 finally
2150 { 2128 {
2151 Monitor.Exit(ClientInstanceTeleportLock); 2129 Monitor.Exit(ClientInstanceTeleportLock);
2152 // Allow teleports and enable button. 2130 // Allow teleports and enable button.
2153 vassalForm.BeginInvoke((MethodInvoker) (() => 2131 vassalForm.BeginInvoke((MethodInvoker) (() =>
2154 { 2132 {
2155 ResidentListTeleportHomeGroup.Enabled = true; 2133 ResidentListTeleportHomeGroup.Enabled = true;
2156 ResidentListBanGroup.Enabled = true; 2134 ResidentListBanGroup.Enabled = true;
2157 RegionTeleportGroup.Enabled = true; 2135 RegionTeleportGroup.Enabled = true;
2158 })); 2136 }));
2159 } 2137 }
2160 }) 2138 })
2161 {IsBackground = true}.Start(); 2139 {IsBackground = true}.Start();
2162 } 2140 }
2163   2141  
2164 private void RequestRipTerrain(object sender, EventArgs e) 2142 private void RequestRipTerrain(object sender, EventArgs e)
2165 { 2143 {
2166 // Block teleports and disable button. 2144 // Block teleports and disable button.
2167 vassalForm.Invoke((MethodInvoker) (() => 2145 vassalForm.Invoke((MethodInvoker) (() =>
2168 { 2146 {
2169 RegionTeleportGroup.Enabled = false; 2147 RegionTeleportGroup.Enabled = false;
2170 RipTerrainButton.Enabled = false; 2148 RipTerrainButton.Enabled = false;
2171 })); 2149 }));
2172   2150  
2173 new Thread(() => 2151 new Thread(() =>
2174 { 2152 {
2175 Monitor.Enter(ClientInstanceTeleportLock); 2153 Monitor.Enter(ClientInstanceTeleportLock);
2176   2154  
2177 try 2155 try
2178 { 2156 {
2179 // Get the map heights. 2157 // Get the map heights.
2180 string result = wasPOST(vassalConfiguration.HTTPServerURL, 2158 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
2181 KeyValue.Escape(new Dictionary<string, string> 2159 KeyValue.Escape(new Dictionary<string, string>
2182 { 2160 {
2183 {"command", "getterrainheight"}, 2161 {"command", "getterrainheight"},
2184 {"group", vassalConfiguration.Group}, 2162 {"group", vassalConfiguration.Group},
2185 {"password", vassalConfiguration.Password}, 2163 {"password", vassalConfiguration.Password},
2186 {"entity", "region"} 2164 {"entity", "region"}
2187 }, wasOutput), vassalConfiguration.DataTimeout); 2165 }, wasOutput)).Result);
2188   2166  
2189 if (string.IsNullOrEmpty(result)) 2167 if (string.IsNullOrEmpty(result))
2190 throw new Exception("Error communicating with Corrade."); 2168 throw new Exception("Error communicating with Corrade.");
2191   2169  
2192 bool success; 2170 bool success;
2193 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 2171 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
2194 throw new Exception("No success status could be retrieved."); 2172 throw new Exception("No success status could be retrieved.");
2195   2173  
2196 if (!success) 2174 if (!success)
2197 throw new Exception("Could not get terrain heights."); 2175 throw new Exception("Could not get terrain heights.");
2198   2176  
2199 List<double> heights = new List<double>(); 2177 var heights = new List<double>();
2200 foreach (string map in CSV.ToEnumerable(wasInput(KeyValue.Get("data", result)))) 2178 foreach (var map in CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))))
2201 { 2179 {
2202 double height; 2180 double height;
2203 if (!double.TryParse(map, out height)) 2181 if (!double.TryParse(map, out height))
2204 continue; 2182 continue;
2205 heights.Add(height); 2183 heights.Add(height);
2206 } 2184 }
2207 if (heights.Count.Equals(0)) 2185 if (heights.Count.Equals(0))
2208 throw new Exception("Could not get terrain heights."); 2186 throw new Exception("Could not get terrain heights.");
2209   2187  
2210 double maxHeight = heights.Max(); 2188 var maxHeight = heights.Max();
2211 using (Bitmap bitmap = new Bitmap(256, 256)) 2189 using (var bitmap = new Bitmap(256, 256))
2212 { 2190 {
2213 foreach (int x in Enumerable.Range(1, 255)) 2191 foreach (var x in Enumerable.Range(1, 255))
2214 { 2192 {
2215 foreach (int y in Enumerable.Range(1, 255)) 2193 foreach (var y in Enumerable.Range(1, 255))
2216 { 2194 {
2217 bitmap.SetPixel(x, 256 - y, 2195 bitmap.SetPixel(x, 256 - y,
2218 Color.FromArgb( 2196 Color.FromArgb(
2219 Math.Max( 2197 Math.Max(
2220 (int) Numerics.MapValueToRange(heights[256*x + y], 0, maxHeight, 0, 255), 0), 2198 (int) Numerics.MapValueToRange(heights[256*x + y], 0, maxHeight, 0, 255), 0),
2221 0, 0)); 2199 0, 0));
2222 } 2200 }
2223 } 2201 }
2224 Bitmap closureBitmap = (Bitmap) bitmap.Clone(); 2202 var closureBitmap = (Bitmap) bitmap.Clone();
2225 vassalForm.BeginInvoke((MethodInvoker) (() => 2203 vassalForm.BeginInvoke((MethodInvoker) (() =>
2226 { 2204 {
2227 switch (vassalForm.SavePNGFileDialog.ShowDialog()) 2205 switch (vassalForm.SavePNGFileDialog.ShowDialog())
2228 { 2206 {
2229 case DialogResult.OK: 2207 case DialogResult.OK:
2230 string file = vassalForm.SavePNGFileDialog.FileName; 2208 var file = vassalForm.SavePNGFileDialog.FileName;
2231 new Thread(() => 2209 new Thread(() =>
2232 { 2210 {
2233 vassalForm.BeginInvoke((MethodInvoker) (() => 2211 vassalForm.BeginInvoke((MethodInvoker) (() =>
2234 { 2212 {
2235 try 2213 try
2236 { 2214 {
2237 vassalForm.StatusText.Text = @"saving terrain..."; 2215 vassalForm.StatusText.Text = @"saving terrain...";
2238 vassalForm.StatusProgress.Value = 0; 2216 vassalForm.StatusProgress.Value = 0;
2239   2217  
2240 closureBitmap.Save(file, ImageFormat.Png); 2218 closureBitmap.Save(file, ImageFormat.Png);
2241   2219  
2242 vassalForm.StatusText.Text = @"terrain saved"; 2220 vassalForm.StatusText.Text = @"terrain saved";
2243 vassalForm.StatusProgress.Value = 100; 2221 vassalForm.StatusProgress.Value = 100;
2244 } 2222 }
2245 catch (Exception ex) 2223 catch (Exception ex)
2246 { 2224 {
2247 vassalForm.StatusText.Text = ex.Message; 2225 vassalForm.StatusText.Text = ex.Message;
2248 } 2226 }
2249 finally 2227 finally
2250 { 2228 {
2251 closureBitmap.Dispose(); 2229 closureBitmap.Dispose();
2252 } 2230 }
2253 })); 2231 }));
2254 }) 2232 })
2255 {IsBackground = true}.Start(); 2233 {IsBackground = true}.Start();
2256 break; 2234 break;
2257 } 2235 }
2258 })); 2236 }));
2259 } 2237 }
2260 } 2238 }
2261 catch (Exception ex) 2239 catch (Exception ex)
2262 { 2240 {
2263 vassalForm.BeginInvoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); 2241 vassalForm.BeginInvoke((MethodInvoker) (() => { StatusText.Text = ex.Message; }));
2264 } 2242 }
2265 finally 2243 finally
2266 { 2244 {
2267 Monitor.Exit(ClientInstanceTeleportLock); 2245 Monitor.Exit(ClientInstanceTeleportLock);
2268 vassalForm.BeginInvoke((MethodInvoker) (() => 2246 vassalForm.BeginInvoke((MethodInvoker) (() =>
2269 { 2247 {
2270 RegionTeleportGroup.Enabled = true; 2248 RegionTeleportGroup.Enabled = true;
2271 RipTerrainButton.Enabled = true; 2249 RipTerrainButton.Enabled = true;
2272 })); 2250 }));
2273 } 2251 }
2274 }) {IsBackground = true}.Start(); 2252 }) {IsBackground = true}.Start();
2275 } 2253 }
2276   2254  
2277 private void RequestDownloadTerrain(object sender, EventArgs e) 2255 private void RequestDownloadTerrain(object sender, EventArgs e)
2278 { 2256 {
2279 // Block teleports and disable button. 2257 // Block teleports and disable button.
2280 vassalForm.Invoke((MethodInvoker) (() => 2258 vassalForm.Invoke((MethodInvoker) (() =>
2281 { 2259 {
2282 RegionTeleportGroup.Enabled = false; 2260 RegionTeleportGroup.Enabled = false;
2283 DownloadTerrainButton.Enabled = false; 2261 DownloadTerrainButton.Enabled = false;
2284 })); 2262 }));
2285   2263  
2286 new Thread(() => 2264 new Thread(() =>
2287 { 2265 {
2288 Monitor.Enter(ClientInstanceTeleportLock); 2266 Monitor.Enter(ClientInstanceTeleportLock);
2289   2267  
2290 try 2268 try
2291 { 2269 {
2292 // Download the terrain. 2270 // Download the terrain.
2293 string result = wasPOST(vassalConfiguration.HTTPServerURL, 2271 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
2294 KeyValue.Escape(new Dictionary<string, string> 2272 KeyValue.Escape(new Dictionary<string, string>
2295 { 2273 {
2296 {"command", "terrain"}, 2274 {"command", "terrain"},
2297 {"group", vassalConfiguration.Group}, 2275 {"group", vassalConfiguration.Group},
2298 {"password", vassalConfiguration.Password}, 2276 {"password", vassalConfiguration.Password},
2299 {"action", "get"} 2277 {"action", "get"}
2300 }, wasOutput), vassalConfiguration.DataTimeout); 2278 }, wasOutput)).Result);
2301   2279  
2302 if (string.IsNullOrEmpty(result)) 2280 if (string.IsNullOrEmpty(result))
2303 throw new Exception("Error communicating with Corrade."); 2281 throw new Exception("Error communicating with Corrade.");
2304   2282  
2305 bool success; 2283 bool success;
2306 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 2284 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
2307 throw new Exception("No success status could be retrieved."); 2285 throw new Exception("No success status could be retrieved.");
2308   2286  
2309 if (!success) 2287 if (!success)
2310 throw new Exception("Could not download terrain."); 2288 throw new Exception("Could not download terrain.");
2311   2289  
2312 byte[] data = Convert.FromBase64String(wasInput(KeyValue.Get("data", result))); 2290 var data = Convert.FromBase64String(wasInput(KeyValue.Get("data", result)));
2313   2291  
2314 vassalForm.BeginInvoke((MethodInvoker) (() => 2292 vassalForm.BeginInvoke((MethodInvoker) (() =>
2315 { 2293 {
2316 switch (vassalForm.SaveRawFileDialog.ShowDialog()) 2294 switch (vassalForm.SaveRawFileDialog.ShowDialog())
2317 { 2295 {
2318 case DialogResult.OK: 2296 case DialogResult.OK:
2319 string file = vassalForm.SaveRawFileDialog.FileName; 2297 var file = vassalForm.SaveRawFileDialog.FileName;
2320 new Thread(() => 2298 new Thread(() =>
2321 { 2299 {
2322 vassalForm.BeginInvoke((MethodInvoker) (() => 2300 vassalForm.BeginInvoke((MethodInvoker) (() =>
2323 { 2301 {
2324 try 2302 try
2325 { 2303 {
2326 vassalForm.StatusText.Text = @"saving terrain..."; 2304 vassalForm.StatusText.Text = @"saving terrain...";
2327 vassalForm.StatusProgress.Value = 0; 2305 vassalForm.StatusProgress.Value = 0;
2328   2306  
2329 File.WriteAllBytes(file, data); 2307 File.WriteAllBytes(file, data);
2330   2308  
2331 vassalForm.StatusText.Text = @"terrain saved"; 2309 vassalForm.StatusText.Text = @"terrain saved";
2332 vassalForm.StatusProgress.Value = 100; 2310 vassalForm.StatusProgress.Value = 100;
2333 } 2311 }
2334 catch (Exception ex) 2312 catch (Exception ex)
2335 { 2313 {
2336 vassalForm.StatusText.Text = ex.Message; 2314 vassalForm.StatusText.Text = ex.Message;
2337 } 2315 }
2338 })); 2316 }));
2339 }) 2317 })
2340 {IsBackground = true}.Start(); 2318 {IsBackground = true}.Start();
2341 break; 2319 break;
2342 } 2320 }
2343 })); 2321 }));
2344 } 2322 }
2345 catch (Exception ex) 2323 catch (Exception ex)
2346 { 2324 {
2347 vassalForm.BeginInvoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); 2325 vassalForm.BeginInvoke((MethodInvoker) (() => { StatusText.Text = ex.Message; }));
2348 } 2326 }
2349 finally 2327 finally
2350 { 2328 {
2351 Monitor.Exit(ClientInstanceTeleportLock); 2329 Monitor.Exit(ClientInstanceTeleportLock);
2352 vassalForm.BeginInvoke((MethodInvoker) (() => 2330 vassalForm.BeginInvoke((MethodInvoker) (() =>
2353 { 2331 {
2354 DownloadTerrainButton.Enabled = true; 2332 DownloadTerrainButton.Enabled = true;
2355 RegionTeleportGroup.Enabled = true; 2333 RegionTeleportGroup.Enabled = true;
2356 })); 2334 }));
2357 } 2335 }
2358 }) 2336 })
2359 {IsBackground = true}.Start(); 2337 {IsBackground = true}.Start();
2360 } 2338 }
2361   2339  
2362 private void RequestUploadTerrain(object sender, EventArgs e) 2340 private void RequestUploadTerrain(object sender, EventArgs e)
2363 { 2341 {
2364 // Block teleports and disable button. 2342 // Block teleports and disable button.
2365 vassalForm.Invoke((MethodInvoker) (() => 2343 vassalForm.Invoke((MethodInvoker) (() =>
2366 { 2344 {
2367 RegionTeleportGroup.Enabled = false; 2345 RegionTeleportGroup.Enabled = false;
2368 UploadTerrainButton.Enabled = false; 2346 UploadTerrainButton.Enabled = false;
2369 })); 2347 }));
2370   2348  
2371 new Thread(() => 2349 new Thread(() =>
2372 { 2350 {
2373 Monitor.Enter(ClientInstanceTeleportLock); 2351 Monitor.Enter(ClientInstanceTeleportLock);
2374   2352  
2375 try 2353 try
2376 { 2354 {
2377 byte[] data = null; 2355 byte[] data = null;
2378 vassalForm.Invoke((MethodInvoker) (() => 2356 vassalForm.Invoke((MethodInvoker) (() =>
2379 { 2357 {
2380 switch (vassalForm.LoadRawFileDialog.ShowDialog()) 2358 switch (vassalForm.LoadRawFileDialog.ShowDialog())
2381 { 2359 {
2382 case DialogResult.OK: 2360 case DialogResult.OK:
2383 string file = vassalForm.LoadRawFileDialog.FileName; 2361 var file = vassalForm.LoadRawFileDialog.FileName;
2384 vassalForm.StatusText.Text = @"loading terrain..."; 2362 vassalForm.StatusText.Text = @"loading terrain...";
2385 vassalForm.StatusProgress.Value = 0; 2363 vassalForm.StatusProgress.Value = 0;
2386   2364  
2387 data = File.ReadAllBytes(file); 2365 data = File.ReadAllBytes(file);
2388   2366  
2389 vassalForm.StatusText.Text = @"terrain loaded"; 2367 vassalForm.StatusText.Text = @"terrain loaded";
2390 vassalForm.StatusProgress.Value = 100; 2368 vassalForm.StatusProgress.Value = 100;
2391 break; 2369 break;
2392 } 2370 }
2393 })); 2371 }));
2394   2372  
2395 // Upload the terrain. 2373 // Upload the terrain.
2396 string result = wasPOST(vassalConfiguration.HTTPServerURL, 2374 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
2397 KeyValue.Escape(new Dictionary<string, string> 2375 KeyValue.Escape(new Dictionary<string, string>
2398 { 2376 {
2399 {"command", "terrain"}, 2377 {"command", "terrain"},
2400 {"group", vassalConfiguration.Group}, 2378 {"group", vassalConfiguration.Group},
2401 {"password", vassalConfiguration.Password}, 2379 {"password", vassalConfiguration.Password},
2402 {"action", "set"}, 2380 {"action", "set"},
2403 {"data", Convert.ToBase64String(data)} 2381 {"data", Convert.ToBase64String(data)}
2404 }, wasOutput), vassalConfiguration.DataTimeout); 2382 }, wasOutput)).Result);
2405   2383  
2406 if (string.IsNullOrEmpty(result)) 2384 if (string.IsNullOrEmpty(result))
2407 throw new Exception("Error communicating with Corrade."); 2385 throw new Exception("Error communicating with Corrade.");
2408   2386  
2409 bool success; 2387 bool success;
2410 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 2388 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
2411 throw new Exception("No success status could be retrieved."); 2389 throw new Exception("No success status could be retrieved.");
2412   2390  
2413 if (!success) 2391 if (!success)
2414 throw new Exception("Could not upload terrain."); 2392 throw new Exception("Could not upload terrain.");
2415 } 2393 }
2416 catch (Exception ex) 2394 catch (Exception ex)
2417 { 2395 {
2418 vassalForm.BeginInvoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); 2396 vassalForm.BeginInvoke((MethodInvoker) (() => { StatusText.Text = ex.Message; }));
2419 } 2397 }
2420 finally 2398 finally
2421 { 2399 {
2422 Monitor.Exit(ClientInstanceTeleportLock); 2400 Monitor.Exit(ClientInstanceTeleportLock);
2423 vassalForm.BeginInvoke((MethodInvoker) (() => 2401 vassalForm.BeginInvoke((MethodInvoker) (() =>
2424 { 2402 {
2425 UploadTerrainButton.Enabled = true; 2403 UploadTerrainButton.Enabled = true;
2426 RegionTeleportGroup.Enabled = true; 2404 RegionTeleportGroup.Enabled = true;
2427 })); 2405 }));
2428 } 2406 }
2429 }) 2407 })
2430 {IsBackground = true}.Start(); 2408 {IsBackground = true}.Start();
2431 } 2409 }
2432   2410  
2433 private void RequestTabsChanged(object sender, EventArgs e) 2411 private void RequestTabsChanged(object sender, EventArgs e)
2434 { 2412 {
2435 vassalForm.BeginInvoke((MethodInvoker) (() => 2413 vassalForm.BeginInvoke((MethodInvoker) (() =>
2436 { 2414 {
2437 overviewTabTimer.Stop(); 2415 overviewTabTimer.Stop();
2438 regionsStateTabTimer.Stop(); 2416 regionsStateTabTimer.Stop();
2439 residentListTabTimer.Stop(); 2417 residentListTabTimer.Stop();
2440 estateTopTabTimer.Stop(); 2418 estateTopTabTimer.Stop();
2441   2419  
2442 if (Tabs.SelectedTab.Equals(OverviewTab)) 2420 if (Tabs.SelectedTab.Equals(OverviewTab))
2443 { 2421 {
2444 overviewTabTimer.Start(); 2422 overviewTabTimer.Start();
2445 return; 2423 return;
2446 } 2424 }
2447 if (Tabs.SelectedTab.Equals(RegionsStateTab)) 2425 if (Tabs.SelectedTab.Equals(RegionsStateTab))
2448 { 2426 {
2449 regionsStateTabTimer.Start(); 2427 regionsStateTabTimer.Start();
2450 return; 2428 return;
2451 } 2429 }
2452 if (Tabs.SelectedTab.Equals(ResidentListTab)) 2430 if (Tabs.SelectedTab.Equals(ResidentListTab))
2453 { 2431 {
2454 residentListTabTimer.Start(); 2432 residentListTabTimer.Start();
2455 return; 2433 return;
2456 } 2434 }
2457 if (Tabs.SelectedTab.Equals(EstateTopTab)) 2435 if (Tabs.SelectedTab.Equals(EstateTopTab))
2458 { 2436 {
2459 estateTopTabTimer.Start(); 2437 estateTopTabTimer.Start();
2460 return; 2438 return;
2461 } 2439 }
2462 if (Tabs.SelectedTab.Equals(EstateTexturesTab)) 2440 if (Tabs.SelectedTab.Equals(EstateTexturesTab))
2463 { 2441 {
2464 estateTexturesTabTimer.Start(); 2442 estateTexturesTabTimer.Start();
2465 } 2443 }
2466 })); 2444 }));
2467 } 2445 }
2468   2446  
2469 private void RequestFilterEstateList(object sender, EventArgs e) 2447 private void RequestFilterEstateList(object sender, EventArgs e)
2470 { 2448 {
2471 vassalForm.BeginInvoke((MethodInvoker) (() => 2449 vassalForm.BeginInvoke((MethodInvoker) (() =>
2472 { 2450 {
2473 Regex estateListRowRegex; 2451 Regex estateListRowRegex;
2474 switch (!string.IsNullOrEmpty(EstateListFilter.Text)) 2452 switch (!string.IsNullOrEmpty(EstateListFilter.Text))
2475 { 2453 {
2476 case true: 2454 case true:
2477 estateListRowRegex = new Regex(EstateListFilter.Text, RegexOptions.Compiled); 2455 estateListRowRegex = new Regex(EstateListFilter.Text, RegexOptions.Compiled);
2478 break; 2456 break;
2479 default: 2457 default:
2480 estateListRowRegex = new Regex(@".+?", RegexOptions.Compiled); 2458 estateListRowRegex = new Regex(@".+?", RegexOptions.Compiled);
2481 break; 2459 break;
2482 } 2460 }
2483 foreach (DataGridViewRow estateListRow in EstateListGridView.Rows.AsParallel().Cast<DataGridViewRow>()) 2461 foreach (var estateListRow in EstateListGridView.Rows.AsParallel().Cast<DataGridViewRow>())
2484 { 2462 {
2485 estateListRow.Visible = 2463 estateListRow.Visible =
2486 estateListRowRegex.IsMatch(estateListRow.Cells["EstateListName"].Value.ToString()); 2464 estateListRowRegex.IsMatch(estateListRow.Cells["EstateListName"].Value.ToString());
2487 } 2465 }
2488 })); 2466 }));
2489 } 2467 }
2490   2468  
2491 private void EstateListSelected(object sender, EventArgs e) 2469 private void EstateListSelected(object sender, EventArgs e)
2492 { 2470 {
2493 string selectedEstateListType = string.Empty; 2471 var selectedEstateListType = string.Empty;
2494 bool queryEstateList = false; 2472 var queryEstateList = false;
2495 vassalForm.Invoke((MethodInvoker) (() => 2473 vassalForm.Invoke((MethodInvoker) (() =>
2496 { 2474 {
2497 if (vassalForm.EstateListSelectBox.SelectedItem == null) return; 2475 if (vassalForm.EstateListSelectBox.SelectedItem == null) return;
2498 selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString(); 2476 selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString();
2499 switch ( 2477 switch (
2500 !string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1) 2478 !string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1)
2501 { 2479 {
2502 case true: 2480 case true:
2503 queryEstateList = true; 2481 queryEstateList = true;
2504 break; 2482 break;
2505 default: 2483 default:
2506 EstateListsResidentsGroup.Enabled = false; 2484 EstateListsResidentsGroup.Enabled = false;
2507 EstateListsGroupsGroup.Enabled = false; 2485 EstateListsGroupsGroup.Enabled = false;
2508 queryEstateList = false; 2486 queryEstateList = false;
2509 break; 2487 break;
2510 } 2488 }
2511 })); 2489 }));
2512   2490  
2513 if (!queryEstateList) return; 2491 if (!queryEstateList) return;
2514   2492  
2515 new Thread(() => 2493 new Thread(() =>
2516 { 2494 {
2517 try 2495 try
2518 { 2496 {
2519 Monitor.Enter(ClientInstanceTeleportLock); 2497 Monitor.Enter(ClientInstanceTeleportLock);
2520   2498  
2521 // Disable controls. 2499 // Disable controls.
2522 vassalForm.Invoke((MethodInvoker) (() => 2500 vassalForm.Invoke((MethodInvoker) (() =>
2523 { 2501 {
2524 RegionTeleportGroup.Enabled = false; 2502 RegionTeleportGroup.Enabled = false;
2525 EstateListsResidentsGroup.Enabled = false; 2503 EstateListsResidentsGroup.Enabled = false;
2526 EstateListsGroupsGroup.Enabled = false; 2504 EstateListsGroupsGroup.Enabled = false;
2527 })); 2505 }));
2528   2506  
2529 // Get the selected estate list. 2507 // Get the selected estate list.
2530 string result = wasPOST(vassalConfiguration.HTTPServerURL, 2508 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
2531 KeyValue.Escape(new Dictionary<string, string> 2509 KeyValue.Escape(new Dictionary<string, string>
2532 { 2510 {
2533 {"command", "getestatelist"}, 2511 {"command", "getestatelist"},
2534 {"group", vassalConfiguration.Group}, 2512 {"group", vassalConfiguration.Group},
2535 {"password", vassalConfiguration.Password}, 2513 {"password", vassalConfiguration.Password},
2536 {"type", selectedEstateListType} 2514 {"type", selectedEstateListType}
2537 }, wasOutput), vassalConfiguration.DataTimeout); 2515 }, wasOutput)).Result);
2538   2516  
2539 if (string.IsNullOrEmpty(result)) 2517 if (string.IsNullOrEmpty(result))
2540 throw new Exception("Error communicating with Corrade."); 2518 throw new Exception("Error communicating with Corrade.");
2541   2519  
2542 bool success; 2520 bool success;
2543 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 2521 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
2544 throw new Exception("No success status could be retrieved."); 2522 throw new Exception("No success status could be retrieved.");
2545   2523  
2546 if (!success) 2524 if (!success)
2547 throw new Exception("Could not retrieve estate list."); 2525 throw new Exception("Could not retrieve estate list.");
2548   2526  
2549 vassalForm.Invoke((MethodInvoker) (() => { EstateListGridView.Rows.Clear(); })); 2527 vassalForm.Invoke((MethodInvoker) (() => { EstateListGridView.Rows.Clear(); }));
2550 foreach (List<string> data in CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))) 2528 foreach (var data in CSV.ToEnumerable(wasInput(KeyValue.Get("data", result)))
2551 .Where(x => !string.IsNullOrEmpty(x)) 2529 .Where(x => !string.IsNullOrEmpty(x))
2552 .Select((x, i) => new {Index = i, Value = x}) 2530 .Select((x, i) => new {Index = i, Value = x})
2553 .GroupBy(x => x.Index/2) 2531 .GroupBy(x => x.Index/2)
2554 .Select(x => x.Select(v => v.Value).ToList()).Where(x => x.Count.Equals(2))) 2532 .Select(x => x.Select(v => v.Value).ToList()).Where(x => x.Count.Equals(2)))
2555 { 2533 {
2556 vassalForm.Invoke( 2534 vassalForm.Invoke(
2557 (MethodInvoker) (() => { EstateListGridView.Rows.Add(data.First(), data.Last()); })); 2535 (MethodInvoker) (() => { EstateListGridView.Rows.Add(data.First(), data.Last()); }));
2558 } 2536 }
2559 } 2537 }
2560 catch (Exception ex) 2538 catch (Exception ex)
2561 { 2539 {
2562 vassalForm.Invoke((MethodInvoker) (() => { vassalForm.StatusText.Text = ex.Message; })); 2540 vassalForm.Invoke((MethodInvoker) (() => { vassalForm.StatusText.Text = ex.Message; }));
2563 } 2541 }
2564 finally 2542 finally
2565 { 2543 {
2566 Monitor.Exit(ClientInstanceTeleportLock); 2544 Monitor.Exit(ClientInstanceTeleportLock);
2567 // Enable controls 2545 // Enable controls
2568 vassalForm.Invoke((MethodInvoker) (() => 2546 vassalForm.Invoke((MethodInvoker) (() =>
2569 { 2547 {
2570 vassalForm.RegionTeleportGroup.Enabled = true; 2548 vassalForm.RegionTeleportGroup.Enabled = true;
2571   2549  
2572 switch (selectedEstateListType) 2550 switch (selectedEstateListType)
2573 { 2551 {
2574 case "ban": 2552 case "ban":
2575 case "manager": 2553 case "manager":
2576 case "user": 2554 case "user":
2577 EstateListsResidentsGroup.Enabled = true; 2555 EstateListsResidentsGroup.Enabled = true;
2578 EstateListsGroupsGroup.Enabled = false; 2556 EstateListsGroupsGroup.Enabled = false;
2579 break; 2557 break;
2580 case "group": 2558 case "group":
2581 EstateListsResidentsGroup.Enabled = false; 2559 EstateListsResidentsGroup.Enabled = false;
2582 EstateListsGroupsGroup.Enabled = true; 2560 EstateListsGroupsGroup.Enabled = true;
2583 break; 2561 break;
2584 } 2562 }
2585 })); 2563 }));
2586 } 2564 }
2587 }) 2565 })
2588 {IsBackground = true}.Start(); 2566 {IsBackground = true}.Start();
2589 } 2567 }
2590   2568  
2591 private void RequestRemoveEstateListMember(object sender, EventArgs e) 2569 private void RequestRemoveEstateListMember(object sender, EventArgs e)
2592 { 2570 {
2593 // Get the estate list type. 2571 // Get the estate list type.
2594 string selectedEstateListType = string.Empty; 2572 var selectedEstateListType = string.Empty;
2595 bool queryEstateList = false; 2573 var queryEstateList = false;
2596 vassalForm.Invoke((MethodInvoker) (() => 2574 vassalForm.Invoke((MethodInvoker) (() =>
2597 { 2575 {
2598 if (vassalForm.EstateListSelectBox.SelectedItem == null) 2576 if (vassalForm.EstateListSelectBox.SelectedItem == null)
2599 { 2577 {
2600 queryEstateList = false; 2578 queryEstateList = false;
2601 return; 2579 return;
2602 } 2580 }
2603 selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString(); 2581 selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString();
2604 switch ( 2582 switch (
2605 !string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1) 2583 !string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1)
2606 { 2584 {
2607 case true: 2585 case true:
2608 queryEstateList = true; 2586 queryEstateList = true;
2609 break; 2587 break;
2610 default: 2588 default:
2611 queryEstateList = false; 2589 queryEstateList = false;
2612 break; 2590 break;
2613 } 2591 }
2614 })); 2592 }));
2615   2593  
2616 // If not estate list type is selected then return. 2594 // If not estate list type is selected then return.
2617 if (!queryEstateList) return; 2595 if (!queryEstateList) return;
2618   2596  
2619 // Enqueue all the regions to restart. 2597 // Enqueue all the regions to restart.
2620 Queue<UUID> estateListMembersQueue = new Queue<UUID>(); 2598 var estateListMembersQueue = new Queue<UUID>();
2621 vassalForm.Invoke((MethodInvoker) (() => 2599 vassalForm.Invoke((MethodInvoker) (() =>
2622 { 2600 {
2623 foreach ( 2601 foreach (
2624 DataGridViewRow estateListRow in 2602 var estateListRow in
2625 EstateListGridView.Rows.AsParallel() 2603 EstateListGridView.Rows.AsParallel()
2626 .Cast<DataGridViewRow>() 2604 .Cast<DataGridViewRow>()
2627 .Where(o => o.Selected || o.Cells.Cast<DataGridViewCell>().Any(p => p.Selected))) 2605 .Where(o => o.Selected || o.Cells.Cast<DataGridViewCell>().Any(p => p.Selected)))
2628 { 2606 {
2629 UUID estateListMemberUUID; 2607 UUID estateListMemberUUID;
2630 if (!UUID.TryParse(estateListRow.Cells["EstateListUUID"].Value.ToString(), 2608 if (!UUID.TryParse(estateListRow.Cells["EstateListUUID"].Value.ToString(),
2631 out estateListMemberUUID)) 2609 out estateListMemberUUID))
2632 continue; 2610 continue;
2633 estateListMembersQueue.Enqueue(estateListMemberUUID); 2611 estateListMembersQueue.Enqueue(estateListMemberUUID);
2634 } 2612 }
2635 })); 2613 }));
2636   2614  
2637 // If no rows were selected, enable teleports, the return button and return. 2615 // If no rows were selected, enable teleports, the return button and return.
2638 if (estateListMembersQueue.Count.Equals(0)) return; 2616 if (estateListMembersQueue.Count.Equals(0)) return;
2639   2617  
2640 // Block teleports and disable button. 2618 // Block teleports and disable button.
2641 vassalForm.Invoke((MethodInvoker) (() => 2619 vassalForm.Invoke((MethodInvoker) (() =>
2642 { 2620 {
2643 RegionTeleportGroup.Enabled = false; 2621 RegionTeleportGroup.Enabled = false;
2644 RemoveEstateListMemberButton.Enabled = false; 2622 RemoveEstateListMemberButton.Enabled = false;
2645 })); 2623 }));
2646   2624  
2647 new Thread(() => 2625 new Thread(() =>
2648 { 2626 {
2649 try 2627 try
2650 { 2628 {
2651 Monitor.Enter(ClientInstanceTeleportLock); 2629 Monitor.Enter(ClientInstanceTeleportLock);
2652 UUID memberUUID = UUID.Zero; 2630 var memberUUID = UUID.Zero;
2653 do 2631 do
2654 { 2632 {
2655 try 2633 try
2656 { 2634 {
2657 memberUUID = estateListMembersQueue.Dequeue(); 2635 memberUUID = estateListMembersQueue.Dequeue();
2658   2636  
2659 // Remove the agent or group from the list. 2637 // Remove the agent or group from the list.
2660 string result = wasPOST(vassalConfiguration.HTTPServerURL, 2638 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
2661 KeyValue.Escape(new Dictionary<string, string> 2639 KeyValue.Escape(new Dictionary<string, string>
2662 { 2640 {
2663 {"command", "setestatelist"}, 2641 {"command", "setestatelist"},
2664 {"group", vassalConfiguration.Group}, 2642 {"group", vassalConfiguration.Group},
2665 {"password", vassalConfiguration.Password}, 2643 {"password", vassalConfiguration.Password},
2666 {"type", selectedEstateListType}, 2644 {"type", selectedEstateListType},
2667 {"action", "remove"}, 2645 {"action", "remove"},
2668 {selectedEstateListType.Equals("group") ? "target" : "agent", memberUUID.ToString()} 2646 {selectedEstateListType.Equals("group") ? "target" : "agent", memberUUID.ToString()}
2669 }, wasOutput), vassalConfiguration.DataTimeout); 2647 }, wasOutput)).Result);
2670   2648  
2671 if (string.IsNullOrEmpty(result)) 2649 if (string.IsNullOrEmpty(result))
2672 throw new Exception("Error communicating with Corrade"); 2650 throw new Exception("Error communicating with Corrade");
2673   2651  
2674 bool success; 2652 bool success;
2675 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 2653 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
2676 throw new Exception("No success status could be retrieved"); 2654 throw new Exception("No success status could be retrieved");
2677   2655  
2678 if (!success) 2656 if (!success)
2679 throw new Exception("Unable to remove member"); 2657 throw new Exception("Unable to remove member");
2680   2658  
2681 vassalForm.Invoke((MethodInvoker) (() => 2659 vassalForm.Invoke((MethodInvoker) (() =>
2682 { 2660 {
2683 foreach ( 2661 foreach (
2684 int i in 2662 var i in
2685 EstateListGridView.Rows.AsParallel() 2663 EstateListGridView.Rows.AsParallel()
2686 .Cast<DataGridViewRow>() 2664 .Cast<DataGridViewRow>()
2687 .Where( 2665 .Where(
2688 o => 2666 o =>
2689 o.Cells["EstateListUUID"].Value.ToString() 2667 o.Cells["EstateListUUID"].Value.ToString()
2690 .Equals(memberUUID.ToString(), 2668 .Equals(memberUUID.ToString(),
2691 StringComparison.OrdinalIgnoreCase)).Select(o => o.Index) 2669 StringComparison.OrdinalIgnoreCase)).Select(o => o.Index)
2692 ) 2670 )
2693 { 2671 {
2694 EstateListGridView.Rows.RemoveAt(i); 2672 EstateListGridView.Rows.RemoveAt(i);
2695 } 2673 }
2696 })); 2674 }));
2697 } 2675 }
2698 catch (Exception ex) 2676 catch (Exception ex)
2699 { 2677 {
2700 vassalForm.Invoke( 2678 vassalForm.Invoke(
2701 (MethodInvoker) (() => { StatusText.Text = ex.Message + @": " + memberUUID; })); 2679 (MethodInvoker) (() => { StatusText.Text = ex.Message + @": " + memberUUID; }));
2702 } 2680 }
2703 } while (!estateListMembersQueue.Count.Equals(0)); 2681 } while (!estateListMembersQueue.Count.Equals(0));
2704 } 2682 }
2705 catch (Exception) 2683 catch (Exception)
2706 { 2684 {
2707 } 2685 }
2708 finally 2686 finally
2709 { 2687 {
2710 Monitor.Exit(ClientInstanceTeleportLock); 2688 Monitor.Exit(ClientInstanceTeleportLock);
2711 // Enable teleports and enable button. 2689 // Enable teleports and enable button.
2712 vassalForm.Invoke((MethodInvoker) (() => 2690 vassalForm.Invoke((MethodInvoker) (() =>
2713 { 2691 {
2714 RegionTeleportGroup.Enabled = true; 2692 RegionTeleportGroup.Enabled = true;
2715 RemoveEstateListMemberButton.Enabled = true; 2693 RemoveEstateListMemberButton.Enabled = true;
2716 })); 2694 }));
2717 } 2695 }
2718 }) 2696 })
2719 {IsBackground = true}.Start(); 2697 {IsBackground = true}.Start();
2720 } 2698 }
2721   2699  
2722 private void RequestEstateListsAddResident(object sender, EventArgs e) 2700 private void RequestEstateListsAddResident(object sender, EventArgs e)
2723 { 2701 {
2724 // Get the estate list type. 2702 // Get the estate list type.
2725 string selectedEstateListType = string.Empty; 2703 var selectedEstateListType = string.Empty;
2726 bool queryEstateList = false; 2704 var queryEstateList = false;
2727 vassalForm.Invoke((MethodInvoker) (() => 2705 vassalForm.Invoke((MethodInvoker) (() =>
2728 { 2706 {
2729 selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString(); 2707 selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString();
2730 switch ( 2708 switch (
2731 !string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1) 2709 !string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1)
2732 { 2710 {
2733 case true: 2711 case true:
2734 queryEstateList = true; 2712 queryEstateList = true;
2735 break; 2713 break;
2736 default: 2714 default:
2737 queryEstateList = false; 2715 queryEstateList = false;
2738 break; 2716 break;
2739 } 2717 }
2740 })); 2718 }));
2741   2719  
2742 // If not estate list type is selected then return. 2720 // If not estate list type is selected then return.
2743 if (!queryEstateList) return; 2721 if (!queryEstateList) return;
2744   2722  
2745 string firstName = string.Empty; 2723 var firstName = string.Empty;
2746 string lastName = string.Empty; 2724 var lastName = string.Empty;
2747   2725  
2748 vassalForm.Invoke((MethodInvoker) (() => 2726 vassalForm.Invoke((MethodInvoker) (() =>
2749 { 2727 {
2750 switch (string.IsNullOrEmpty(EstateListsResidentFirstName.Text)) 2728 switch (string.IsNullOrEmpty(EstateListsResidentFirstName.Text))
2751 { 2729 {
2752 case true: 2730 case true:
2753 EstateListsResidentFirstName.BackColor = Color.MistyRose; 2731 EstateListsResidentFirstName.BackColor = Color.MistyRose;
2754 return; 2732 return;
2755 default: 2733 default:
2756 EstateListsResidentFirstName.BackColor = Color.Empty; 2734 EstateListsResidentFirstName.BackColor = Color.Empty;
2757 break; 2735 break;
2758 } 2736 }
2759 firstName = EstateListsResidentFirstName.Text; 2737 firstName = EstateListsResidentFirstName.Text;
2760 switch (string.IsNullOrEmpty(EstateListsResidentLastName.Text)) 2738 switch (string.IsNullOrEmpty(EstateListsResidentLastName.Text))
2761 { 2739 {
2762 case true: 2740 case true:
2763 EstateListsResidentLastName.BackColor = Color.MistyRose; 2741 EstateListsResidentLastName.BackColor = Color.MistyRose;
2764 return; 2742 return;
2765 default: 2743 default:
2766 EstateListsResidentLastName.BackColor = Color.Empty; 2744 EstateListsResidentLastName.BackColor = Color.Empty;
2767 break; 2745 break;
2768 } 2746 }
2769 lastName = EstateListsResidentLastName.Text; 2747 lastName = EstateListsResidentLastName.Text;
2770 })); 2748 }));
2771   2749  
2772 if (string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty(lastName)) return; 2750 if (string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty(lastName)) return;
2773   2751  
2774 // Block teleports and disable button. 2752 // Block teleports and disable button.
2775 vassalForm.Invoke((MethodInvoker) (() => 2753 vassalForm.Invoke((MethodInvoker) (() =>
2776 { 2754 {
2777 RegionTeleportGroup.Enabled = false; 2755 RegionTeleportGroup.Enabled = false;
2778 EstateListsResidentsGroup.Enabled = false; 2756 EstateListsResidentsGroup.Enabled = false;
2779 })); 2757 }));
2780   2758  
2781 new Thread(() => 2759 new Thread(() =>
2782 { 2760 {
2783 try 2761 try
2784 { 2762 {
2785 Monitor.Enter(ClientInstanceTeleportLock); 2763 Monitor.Enter(ClientInstanceTeleportLock);
2786   2764  
2787 // Add the resident to the list. 2765 // Add the resident to the list.
2788 string result = wasPOST(vassalConfiguration.HTTPServerURL, 2766 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
2789 KeyValue.Escape(new Dictionary<string, string> 2767 KeyValue.Escape(new Dictionary<string, string>
2790 { 2768 {
2791 {"command", "setestatelist"}, 2769 {"command", "setestatelist"},
2792 {"group", vassalConfiguration.Group}, 2770 {"group", vassalConfiguration.Group},
2793 {"password", vassalConfiguration.Password}, 2771 {"password", vassalConfiguration.Password},
2794 {"type", selectedEstateListType}, 2772 {"type", selectedEstateListType},
2795 {"action", "add"}, 2773 {"action", "add"},
2796 {"firstname", firstName}, 2774 {"firstname", firstName},
2797 {"lastname", lastName} 2775 {"lastname", lastName}
2798 }, wasOutput), vassalConfiguration.DataTimeout); 2776 }, wasOutput)).Result);
2799   2777  
2800 if (string.IsNullOrEmpty(result)) 2778 if (string.IsNullOrEmpty(result))
2801 throw new Exception("Error communicating with Corrade"); 2779 throw new Exception("Error communicating with Corrade");
2802   2780  
2803 bool success; 2781 bool success;
2804 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 2782 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
2805 throw new Exception("No success status could be retrieved"); 2783 throw new Exception("No success status could be retrieved");
2806   2784  
2807 if (!success) 2785 if (!success)
2808 throw new Exception("Unable to add resident"); 2786 throw new Exception("Unable to add resident");
2809   2787  
2810 // Retrieve the estate list for updates. 2788 // Retrieve the estate list for updates.
2811 result = wasPOST(vassalConfiguration.HTTPServerURL, 2789 result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
2812 KeyValue.Escape(new Dictionary<string, string> 2790 KeyValue.Escape(new Dictionary<string, string>
2813 { 2791 {
2814 {"command", "getestatelist"}, 2792 {"command", "getestatelist"},
2815 {"group", vassalConfiguration.Group}, 2793 {"group", vassalConfiguration.Group},
2816 {"password", vassalConfiguration.Password}, 2794 {"password", vassalConfiguration.Password},
2817 {"type", selectedEstateListType} 2795 {"type", selectedEstateListType}
2818 }, wasOutput), vassalConfiguration.DataTimeout); 2796 }, wasOutput)).Result);
2819   2797  
2820 if (string.IsNullOrEmpty(result)) 2798 if (string.IsNullOrEmpty(result))
2821 throw new Exception("Error communicating with Corrade."); 2799 throw new Exception("Error communicating with Corrade.");
2822   2800  
2823 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 2801 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
2824 throw new Exception("No success status could be retrieved."); 2802 throw new Exception("No success status could be retrieved.");
2825   2803  
2826 if (!success) 2804 if (!success)
2827 throw new Exception("Could not retrieve estate list."); 2805 throw new Exception("Could not retrieve estate list.");
2828   2806  
2829 vassalForm.Invoke((MethodInvoker) (() => { EstateListGridView.Rows.Clear(); })); 2807 vassalForm.Invoke((MethodInvoker) (() => { EstateListGridView.Rows.Clear(); }));
2830 foreach (List<string> data in CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))) 2808 foreach (var data in CSV.ToEnumerable(wasInput(KeyValue.Get("data", result)))
2831 .Where(x => !string.IsNullOrEmpty(x)) 2809 .Where(x => !string.IsNullOrEmpty(x))
2832 .Select((x, i) => new {Index = i, Value = x}) 2810 .Select((x, i) => new {Index = i, Value = x})
2833 .GroupBy(x => x.Index/2) 2811 .GroupBy(x => x.Index/2)
2834 .Select(x => x.Select(v => v.Value).ToList()).Where(x => x.Count.Equals(2))) 2812 .Select(x => x.Select(v => v.Value).ToList()).Where(x => x.Count.Equals(2)))
2835 { 2813 {
2836 vassalForm.Invoke( 2814 vassalForm.Invoke(
2837 (MethodInvoker) (() => { EstateListGridView.Rows.Add(data.First(), data.Last()); })); 2815 (MethodInvoker) (() => { EstateListGridView.Rows.Add(data.First(), data.Last()); }));
2838 } 2816 }
2839 } 2817 }
2840 catch (Exception ex) 2818 catch (Exception ex)
2841 { 2819 {
2842 vassalForm.Invoke( 2820 vassalForm.Invoke(
2843 (MethodInvoker) (() => { StatusText.Text = ex.Message + @": " + firstName + @" " + lastName; })); 2821 (MethodInvoker) (() => { StatusText.Text = ex.Message + @": " + firstName + @" " + lastName; }));
2844 } 2822 }
2845 finally 2823 finally
2846 { 2824 {
2847 Monitor.Exit(ClientInstanceTeleportLock); 2825 Monitor.Exit(ClientInstanceTeleportLock);
2848 // Enable teleports and enable button. 2826 // Enable teleports and enable button.
2849 vassalForm.Invoke((MethodInvoker) (() => 2827 vassalForm.Invoke((MethodInvoker) (() =>
2850 { 2828 {
2851 RegionTeleportGroup.Enabled = true; 2829 RegionTeleportGroup.Enabled = true;
2852 EstateListsResidentsGroup.Enabled = true; 2830 EstateListsResidentsGroup.Enabled = true;
2853 })); 2831 }));
2854 } 2832 }
2855 }) 2833 })
2856 {IsBackground = true}.Start(); 2834 {IsBackground = true}.Start();
2857 } 2835 }
2858   2836  
2859 private void RequestEstateListsAddGroup(object sender, EventArgs e) 2837 private void RequestEstateListsAddGroup(object sender, EventArgs e)
2860 { 2838 {
2861 // Get the estate list type. 2839 // Get the estate list type.
2862 string selectedEstateListType = string.Empty; 2840 var selectedEstateListType = string.Empty;
2863 bool queryEstateList = false; 2841 var queryEstateList = false;
2864 vassalForm.Invoke((MethodInvoker) (() => 2842 vassalForm.Invoke((MethodInvoker) (() =>
2865 { 2843 {
2866 selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString(); 2844 selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString();
2867 switch ( 2845 switch (
2868 !string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1) 2846 !string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1)
2869 { 2847 {
2870 case true: 2848 case true:
2871 queryEstateList = true; 2849 queryEstateList = true;
2872 break; 2850 break;
2873 default: 2851 default:
2874 queryEstateList = false; 2852 queryEstateList = false;
2875 break; 2853 break;
2876 } 2854 }
2877 })); 2855 }));
2878   2856  
2879 // If not estate list type is selected then return. 2857 // If not estate list type is selected then return.
2880 if (!queryEstateList) return; 2858 if (!queryEstateList) return;
2881   2859  
2882 string target = string.Empty; 2860 var target = string.Empty;
2883   2861  
2884 vassalForm.Invoke((MethodInvoker) (() => 2862 vassalForm.Invoke((MethodInvoker) (() =>
2885 { 2863 {
2886 switch (string.IsNullOrEmpty(EstateListsAddGroupBox.Text)) 2864 switch (string.IsNullOrEmpty(EstateListsAddGroupBox.Text))
2887 { 2865 {
2888 case true: 2866 case true:
2889 EstateListsAddGroupBox.BackColor = Color.MistyRose; 2867 EstateListsAddGroupBox.BackColor = Color.MistyRose;
2890 return; 2868 return;
2891 default: 2869 default:
2892 EstateListsAddGroupBox.BackColor = Color.Empty; 2870 EstateListsAddGroupBox.BackColor = Color.Empty;
2893 break; 2871 break;
2894 } 2872 }
2895 target = EstateListsAddGroupBox.Text; 2873 target = EstateListsAddGroupBox.Text;
2896 })); 2874 }));
2897   2875  
2898 if (string.IsNullOrEmpty(target)) return; 2876 if (string.IsNullOrEmpty(target)) return;
2899   2877  
2900 // Block teleports and disable button. 2878 // Block teleports and disable button.
2901 vassalForm.Invoke((MethodInvoker) (() => 2879 vassalForm.Invoke((MethodInvoker) (() =>
2902 { 2880 {
2903 RegionTeleportGroup.Enabled = false; 2881 RegionTeleportGroup.Enabled = false;
2904 EstateListsGroupsGroup.Enabled = false; 2882 EstateListsGroupsGroup.Enabled = false;
2905 })); 2883 }));
2906   2884  
2907 new Thread(() => 2885 new Thread(() =>
2908 { 2886 {
2909 try 2887 try
2910 { 2888 {
2911 Monitor.Enter(ClientInstanceTeleportLock); 2889 Monitor.Enter(ClientInstanceTeleportLock);
2912   2890  
2913 // Add the group to the list. 2891 // Add the group to the list.
2914 string result = wasPOST(vassalConfiguration.HTTPServerURL, 2892 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
2915 KeyValue.Escape(new Dictionary<string, string> 2893 KeyValue.Escape(new Dictionary<string, string>
2916 { 2894 {
2917 {"command", "setestatelist"}, 2895 {"command", "setestatelist"},
2918 {"group", vassalConfiguration.Group}, 2896 {"group", vassalConfiguration.Group},
2919 {"password", vassalConfiguration.Password}, 2897 {"password", vassalConfiguration.Password},
2920 {"type", selectedEstateListType}, 2898 {"type", selectedEstateListType},
2921 {"action", "add"}, 2899 {"action", "add"},
2922 {"target", target} 2900 {"target", target}
2923 }, wasOutput), vassalConfiguration.DataTimeout); 2901 }, wasOutput)).Result);
2924   2902  
2925 if (string.IsNullOrEmpty(result)) 2903 if (string.IsNullOrEmpty(result))
2926 throw new Exception("Error communicating with Corrade"); 2904 throw new Exception("Error communicating with Corrade");
2927   2905  
2928 bool success; 2906 bool success;
2929 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 2907 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
2930 throw new Exception("No success status could be retrieved"); 2908 throw new Exception("No success status could be retrieved");
2931   2909  
2932 if (!success) 2910 if (!success)
2933 throw new Exception("Unable to add group"); 2911 throw new Exception("Unable to add group");
2934   2912  
2935 // Retrieve the estate list for updates. 2913 // Retrieve the estate list for updates.
2936 result = wasPOST(vassalConfiguration.HTTPServerURL, 2914 result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
2937 KeyValue.Escape(new Dictionary<string, string> 2915 KeyValue.Escape(new Dictionary<string, string>
2938 { 2916 {
2939 {"command", "getestatelist"}, 2917 {"command", "getestatelist"},
2940 {"group", vassalConfiguration.Group}, 2918 {"group", vassalConfiguration.Group},
2941 {"password", vassalConfiguration.Password}, 2919 {"password", vassalConfiguration.Password},
2942 {"type", selectedEstateListType} 2920 {"type", selectedEstateListType}
2943 }, wasOutput), vassalConfiguration.DataTimeout); 2921 }, wasOutput)).Result);
2944   2922  
2945 if (string.IsNullOrEmpty(result)) 2923 if (string.IsNullOrEmpty(result))
2946 throw new Exception("Error communicating with Corrade."); 2924 throw new Exception("Error communicating with Corrade.");
2947   2925  
2948 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 2926 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
2949 throw new Exception("No success status could be retrieved."); 2927 throw new Exception("No success status could be retrieved.");
2950   2928  
2951 if (!success) 2929 if (!success)
2952 throw new Exception("Could not retrieve estate list."); 2930 throw new Exception("Could not retrieve estate list.");
2953   2931  
2954 vassalForm.Invoke((MethodInvoker) (() => { EstateListGridView.Rows.Clear(); })); 2932 vassalForm.Invoke((MethodInvoker) (() => { EstateListGridView.Rows.Clear(); }));
2955 foreach (List<string> data in CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))) 2933 foreach (var data in CSV.ToEnumerable(wasInput(KeyValue.Get("data", result)))
2956 .Where(x => !string.IsNullOrEmpty(x)) 2934 .Where(x => !string.IsNullOrEmpty(x))
2957 .Select((x, i) => new {Index = i, Value = x}) 2935 .Select((x, i) => new {Index = i, Value = x})
2958 .GroupBy(x => x.Index/2) 2936 .GroupBy(x => x.Index/2)
2959 .Select(x => x.Select(v => v.Value).ToList()).Where(x => x.Count.Equals(2))) 2937 .Select(x => x.Select(v => v.Value).ToList()).Where(x => x.Count.Equals(2)))
2960 { 2938 {
2961 vassalForm.Invoke( 2939 vassalForm.Invoke(
2962 (MethodInvoker) (() => { EstateListGridView.Rows.Add(data.First(), data.Last()); })); 2940 (MethodInvoker) (() => { EstateListGridView.Rows.Add(data.First(), data.Last()); }));
2963 } 2941 }
2964 } 2942 }
2965 catch (Exception ex) 2943 catch (Exception ex)
2966 { 2944 {
2967 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message + @": " + target; })); 2945 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message + @": " + target; }));
2968 } 2946 }
2969 finally 2947 finally
2970 { 2948 {
2971 Monitor.Exit(ClientInstanceTeleportLock); 2949 Monitor.Exit(ClientInstanceTeleportLock);
2972 // Enable teleports and enable button. 2950 // Enable teleports and enable button.
2973 vassalForm.Invoke((MethodInvoker) (() => 2951 vassalForm.Invoke((MethodInvoker) (() =>
2974 { 2952 {
2975 RegionTeleportGroup.Enabled = true; 2953 RegionTeleportGroup.Enabled = true;
2976 EstateListsGroupsGroup.Enabled = true; 2954 EstateListsGroupsGroup.Enabled = true;
2977 })); 2955 }));
2978 } 2956 }
2979 }) 2957 })
2980 {IsBackground = true}.Start(); 2958 {IsBackground = true}.Start();
2981 } 2959 }
2982   2960  
2983 private void RequestRegionDebugApply(object sender, EventArgs e) 2961 private void RequestRegionDebugApply(object sender, EventArgs e)
2984 { 2962 {
2985 // Block teleports and disable button. 2963 // Block teleports and disable button.
2986 vassalForm.Invoke((MethodInvoker) (() => 2964 vassalForm.Invoke((MethodInvoker) (() =>
2987 { 2965 {
2988 RegionTeleportGroup.Enabled = false; 2966 RegionTeleportGroup.Enabled = false;
2989 ApplyRegionDebugButton.Enabled = false; 2967 ApplyRegionDebugButton.Enabled = false;
2990 })); 2968 }));
2991   2969  
2992 new Thread(() => 2970 new Thread(() =>
2993 { 2971 {
2994 try 2972 try
2995 { 2973 {
2996 Monitor.Enter(ClientInstanceTeleportLock); 2974 Monitor.Enter(ClientInstanceTeleportLock);
2997   2975  
2998 bool scripts = false; 2976 var scripts = false;
2999 bool collisons = false; 2977 var collisons = false;
3000 bool physics = false; 2978 var physics = false;
3001 vassalForm.Invoke((MethodInvoker) (() => 2979 vassalForm.Invoke((MethodInvoker) (() =>
3002 { 2980 {
3003 scripts = RegionDebugScriptsBox.Checked; 2981 scripts = RegionDebugScriptsBox.Checked;
3004 collisons = RegionDebugCollisionsBox.Checked; 2982 collisons = RegionDebugCollisionsBox.Checked;
3005 physics = RegionDebugPhysicsBox.Checked; 2983 physics = RegionDebugPhysicsBox.Checked;
3006 })); 2984 }));
3007   2985  
3008 // Set the debug settings. 2986 // Set the debug settings.
3009 string result = wasPOST(vassalConfiguration.HTTPServerURL, 2987 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
3010 KeyValue.Escape(new Dictionary<string, string> 2988 KeyValue.Escape(new Dictionary<string, string>
3011 { 2989 {
3012 {"command", "setregiondebug"}, 2990 {"command", "setregiondebug"},
3013 {"group", vassalConfiguration.Group}, 2991 {"group", vassalConfiguration.Group},
3014 {"password", vassalConfiguration.Password}, 2992 {"password", vassalConfiguration.Password},
3015 {"scripts", scripts.ToString()}, 2993 {"scripts", scripts.ToString()},
3016 {"collisions", collisons.ToString()}, 2994 {"collisions", collisons.ToString()},
3017 {"physics", physics.ToString()} 2995 {"physics", physics.ToString()}
3018 }, wasOutput), vassalConfiguration.DataTimeout); 2996 }, wasOutput)).Result);
3019   2997  
3020 if (string.IsNullOrEmpty(result)) 2998 if (string.IsNullOrEmpty(result))
3021 throw new Exception("Error communicating with Corrade"); 2999 throw new Exception("Error communicating with Corrade");
3022   3000  
3023 bool success; 3001 bool success;
3024 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 3002 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
3025 throw new Exception("No success status could be retrieved"); 3003 throw new Exception("No success status could be retrieved");
3026   3004  
3027 if (!success) 3005 if (!success)
3028 throw new Exception("Unable to set region debug"); 3006 throw new Exception("Unable to set region debug");
3029 } 3007 }
3030 catch (Exception ex) 3008 catch (Exception ex)
3031 { 3009 {
3032 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); 3010 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; }));
3033 } 3011 }
3034 finally 3012 finally
3035 { 3013 {
3036 Monitor.Exit(ClientInstanceTeleportLock); 3014 Monitor.Exit(ClientInstanceTeleportLock);
3037 } 3015 }
3038   3016  
3039 // Block teleports and disable button. 3017 // Block teleports and disable button.
3040 vassalForm.Invoke((MethodInvoker) (() => 3018 vassalForm.Invoke((MethodInvoker) (() =>
3041 { 3019 {
3042 RegionTeleportGroup.Enabled = true; 3020 RegionTeleportGroup.Enabled = true;
3043 ApplyRegionDebugButton.Enabled = true; 3021 ApplyRegionDebugButton.Enabled = true;
3044 })); 3022 }));
3045 }) 3023 })
3046 {IsBackground = true}.Start(); 3024 {IsBackground = true}.Start();
3047 } 3025 }
3048   3026  
3049 private void RequestApplyRegionInfo(object sender, EventArgs e) 3027 private void RequestApplyRegionInfo(object sender, EventArgs e)
3050 { 3028 {
3051 // Block teleports and disable button. 3029 // Block teleports and disable button.
3052 vassalForm.Invoke((MethodInvoker) (() => 3030 vassalForm.Invoke((MethodInvoker) (() =>
3053 { 3031 {
3054 RegionTeleportGroup.Enabled = false; 3032 RegionTeleportGroup.Enabled = false;
3055 ApplyRegionInfoButton.Enabled = false; 3033 ApplyRegionInfoButton.Enabled = false;
3056 })); 3034 }));
3057   3035  
3058 new Thread(() => 3036 new Thread(() =>
3059 { 3037 {
3060 try 3038 try
3061 { 3039 {
3062 Monitor.Enter(ClientInstanceTeleportLock); 3040 Monitor.Enter(ClientInstanceTeleportLock);
3063   3041  
3064 bool terraform = false; 3042 var terraform = false;
3065 bool fly = false; 3043 var fly = false;
3066 bool damage = false; 3044 var damage = false;
3067 bool resell = false; 3045 var resell = false;
3068 bool push = false; 3046 var push = false;
3069 bool parcel = false; 3047 var parcel = false;
3070 bool mature = false; 3048 var mature = false;
3071 uint agentLimit = 20; 3049 uint agentLimit = 20;
3072 double objectBonus = 2.0; 3050 var objectBonus = 2.0;
3073   3051  
3074 bool run = false; 3052 var run = false;
3075   3053  
3076 vassalForm.Invoke((MethodInvoker) (() => 3054 vassalForm.Invoke((MethodInvoker) (() =>
3077 { 3055 {
3078 terraform = RegionInfoTerraformBox.Checked; 3056 terraform = RegionInfoTerraformBox.Checked;
3079 fly = RegionInfoFlyBox.Checked; 3057 fly = RegionInfoFlyBox.Checked;
3080 damage = RegionInfoDamageBox.Checked; 3058 damage = RegionInfoDamageBox.Checked;
3081 resell = RegioninfoResellBox.Checked; 3059 resell = RegioninfoResellBox.Checked;
3082 push = RegionInfoPushBox.Checked; 3060 push = RegionInfoPushBox.Checked;
3083 parcel = RegionInfoParcelBox.Checked; 3061 parcel = RegionInfoParcelBox.Checked;
3084 mature = RegionInfoMatureBox.Checked; 3062 mature = RegionInfoMatureBox.Checked;
3085 switch (!uint.TryParse(RegionInfoAgentLimitBox.Text, out agentLimit)) 3063 switch (!uint.TryParse(RegionInfoAgentLimitBox.Text, out agentLimit))
3086 { 3064 {
3087 case true: 3065 case true:
3088 RegionInfoAgentLimitBox.BackColor = Color.MistyRose; 3066 RegionInfoAgentLimitBox.BackColor = Color.MistyRose;
3089 return; 3067 return;
3090 default: 3068 default:
3091 RegionInfoAgentLimitBox.BackColor = Color.Empty; 3069 RegionInfoAgentLimitBox.BackColor = Color.Empty;
3092 run = true; 3070 run = true;
3093 break; 3071 break;
3094 } 3072 }
3095 switch (!double.TryParse(RegionInfoObjectBonusBox.Text, out objectBonus)) 3073 switch (!double.TryParse(RegionInfoObjectBonusBox.Text, out objectBonus))
3096 { 3074 {
3097 case true: 3075 case true:
3098 RegionInfoObjectBonusBox.BackColor = Color.MistyRose; 3076 RegionInfoObjectBonusBox.BackColor = Color.MistyRose;
3099 return; 3077 return;
3100 default: 3078 default:
3101 RegionInfoAgentLimitBox.BackColor = Color.Empty; 3079 RegionInfoAgentLimitBox.BackColor = Color.Empty;
3102 break; 3080 break;
3103 } 3081 }
3104   3082  
3105 run = true; 3083 run = true;
3106 })); 3084 }));
3107   3085  
3108 if (!run) return; 3086 if (!run) return;
3109   3087  
3110 // Set the debug settings. 3088 // Set the debug settings.
3111 string result = wasPOST(vassalConfiguration.HTTPServerURL, 3089 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
3112 KeyValue.Escape(new Dictionary<string, string> 3090 KeyValue.Escape(new Dictionary<string, string>
3113 { 3091 {
3114 {"command", "setregioninfo"}, 3092 {"command", "setregioninfo"},
3115 {"group", vassalConfiguration.Group}, 3093 {"group", vassalConfiguration.Group},
3116 {"password", vassalConfiguration.Password}, 3094 {"password", vassalConfiguration.Password},
3117 {"terraform", terraform.ToString()}, 3095 {"terraform", terraform.ToString()},
3118 {"fly", fly.ToString()}, 3096 {"fly", fly.ToString()},
3119 {"damage", damage.ToString()}, 3097 {"damage", damage.ToString()},
3120 {"resell", resell.ToString()}, 3098 {"resell", resell.ToString()},
3121 {"push", push.ToString()}, 3099 {"push", push.ToString()},
3122 {"parcel", parcel.ToString()}, 3100 {"parcel", parcel.ToString()},
3123 {"mature", mature.ToString()}, 3101 {"mature", mature.ToString()},
3124 {"limit", agentLimit.ToString(Utils.EnUsCulture)}, 3102 {"limit", agentLimit.ToString(Utils.EnUsCulture)},
3125 {"bonus", objectBonus.ToString(Utils.EnUsCulture)} 3103 {"bonus", objectBonus.ToString(Utils.EnUsCulture)}
3126 }, wasOutput), vassalConfiguration.DataTimeout); 3104 }, wasOutput)).Result);
3127   3105  
3128 if (string.IsNullOrEmpty(result)) 3106 if (string.IsNullOrEmpty(result))
3129 throw new Exception("Error communicating with Corrade"); 3107 throw new Exception("Error communicating with Corrade");
3130   3108  
3131 bool success; 3109 bool success;
3132 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 3110 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
3133 throw new Exception("No success status could be retrieved"); 3111 throw new Exception("No success status could be retrieved");
3134   3112  
3135 if (!success) 3113 if (!success)
3136 throw new Exception("Unable to set region info"); 3114 throw new Exception("Unable to set region info");
3137 } 3115 }
3138 catch (Exception ex) 3116 catch (Exception ex)
3139 { 3117 {
3140 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); 3118 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; }));
3141 } 3119 }
3142 finally 3120 finally
3143 { 3121 {
3144 Monitor.Exit(ClientInstanceTeleportLock); 3122 Monitor.Exit(ClientInstanceTeleportLock);
3145 } 3123 }
3146   3124  
3147 // Block teleports and disable button. 3125 // Block teleports and disable button.
3148 vassalForm.Invoke((MethodInvoker) (() => 3126 vassalForm.Invoke((MethodInvoker) (() =>
3149 { 3127 {
3150 RegionTeleportGroup.Enabled = true; 3128 RegionTeleportGroup.Enabled = true;
3151 ApplyRegionInfoButton.Enabled = true; 3129 ApplyRegionInfoButton.Enabled = true;
3152 })); 3130 }));
3153 }) 3131 })
3154 {IsBackground = true}.Start(); 3132 {IsBackground = true}.Start();
3155 } 3133 }
3156   3134  
3157 private void RequestEstateTexturesApply(object sender, EventArgs e) 3135 private void RequestEstateTexturesApply(object sender, EventArgs e)
3158 { 3136 {
3159 List<UUID> groundTextureUUIDs = new List<UUID>(); 3137 var groundTextureUUIDs = new List<UUID>();
3160 vassalForm.Invoke((MethodInvoker) (() => 3138 vassalForm.Invoke((MethodInvoker) (() =>
3161 { 3139 {
3162 UUID textureUUID; 3140 UUID textureUUID;
3163 switch (!UUID.TryParse(RegionTexturesLowUUIDApplyBox.Text, out textureUUID)) 3141 switch (!UUID.TryParse(RegionTexturesLowUUIDApplyBox.Text, out textureUUID))
3164 { 3142 {
3165 case true: 3143 case true:
3166 RegionTexturesLowUUIDApplyBox.BackColor = Color.MistyRose; 3144 RegionTexturesLowUUIDApplyBox.BackColor = Color.MistyRose;
3167 return; 3145 return;
3168 default: 3146 default:
3169 RegionTexturesLowUUIDApplyBox.BackColor = Color.Empty; 3147 RegionTexturesLowUUIDApplyBox.BackColor = Color.Empty;
3170 break; 3148 break;
3171 } 3149 }
3172 groundTextureUUIDs.Add(textureUUID); 3150 groundTextureUUIDs.Add(textureUUID);
3173   3151  
3174 switch (!UUID.TryParse(RegionTexturesMiddleLowUUIDApplyBox.Text, out textureUUID)) 3152 switch (!UUID.TryParse(RegionTexturesMiddleLowUUIDApplyBox.Text, out textureUUID))
3175 { 3153 {
3176 case true: 3154 case true:
3177 RegionTexturesMiddleLowUUIDApplyBox.BackColor = Color.MistyRose; 3155 RegionTexturesMiddleLowUUIDApplyBox.BackColor = Color.MistyRose;
3178 return; 3156 return;
3179 default: 3157 default:
3180 RegionTexturesMiddleLowUUIDApplyBox.BackColor = Color.Empty; 3158 RegionTexturesMiddleLowUUIDApplyBox.BackColor = Color.Empty;
3181 break; 3159 break;
3182 } 3160 }
3183 groundTextureUUIDs.Add(textureUUID); 3161 groundTextureUUIDs.Add(textureUUID);
3184   3162  
3185 switch (!UUID.TryParse(RegionTexturesMiddleHighUUIDApplyBox.Text, out textureUUID)) 3163 switch (!UUID.TryParse(RegionTexturesMiddleHighUUIDApplyBox.Text, out textureUUID))
3186 { 3164 {
3187 case true: 3165 case true:
3188 RegionTexturesMiddleHighUUIDApplyBox.BackColor = Color.MistyRose; 3166 RegionTexturesMiddleHighUUIDApplyBox.BackColor = Color.MistyRose;
3189 return; 3167 return;
3190 default: 3168 default:
3191 RegionTexturesMiddleHighUUIDApplyBox.BackColor = Color.Empty; 3169 RegionTexturesMiddleHighUUIDApplyBox.BackColor = Color.Empty;
3192 break; 3170 break;
3193 } 3171 }
3194 groundTextureUUIDs.Add(textureUUID); 3172 groundTextureUUIDs.Add(textureUUID);
3195   3173  
3196 switch (!UUID.TryParse(RegionTexturesHighUUIDApplyBox.Text, out textureUUID)) 3174 switch (!UUID.TryParse(RegionTexturesHighUUIDApplyBox.Text, out textureUUID))
3197 { 3175 {
3198 case true: 3176 case true:
3199 RegionTexturesHighUUIDApplyBox.BackColor = Color.MistyRose; 3177 RegionTexturesHighUUIDApplyBox.BackColor = Color.MistyRose;
3200 return; 3178 return;
3201 default: 3179 default:
3202 RegionTexturesHighUUIDApplyBox.BackColor = Color.Empty; 3180 RegionTexturesHighUUIDApplyBox.BackColor = Color.Empty;
3203 break; 3181 break;
3204 } 3182 }
3205 groundTextureUUIDs.Add(textureUUID); 3183 groundTextureUUIDs.Add(textureUUID);
3206 })); 3184 }));
3207   3185  
3208 if (!groundTextureUUIDs.Count.Equals(4)) return; 3186 if (!groundTextureUUIDs.Count.Equals(4)) return;
3209   3187  
3210 // Block teleports and disable button. 3188 // Block teleports and disable button.
3211 vassalForm.Invoke((MethodInvoker) (() => 3189 vassalForm.Invoke((MethodInvoker) (() =>
3212 { 3190 {
3213 RegionTeleportGroup.Enabled = false; 3191 RegionTeleportGroup.Enabled = false;
3214 GroundTexturesGroup.Enabled = false; 3192 GroundTexturesGroup.Enabled = false;
3215 })); 3193 }));
3216   3194  
3217 new Thread(() => 3195 new Thread(() =>
3218 { 3196 {
3219 try 3197 try
3220 { 3198 {
3221 Monitor.Enter(ClientInstanceTeleportLock); 3199 Monitor.Enter(ClientInstanceTeleportLock);
3222   3200  
3223 // Set the debug settings. 3201 // Set the debug settings.
3224 string result = wasPOST(vassalConfiguration.HTTPServerURL, 3202 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
3225 KeyValue.Escape(new Dictionary<string, string> 3203 KeyValue.Escape(new Dictionary<string, string>
3226 { 3204 {
3227 {"command", "setregionterraintextures"}, 3205 {"command", "setregionterraintextures"},
3228 {"group", vassalConfiguration.Group}, 3206 {"group", vassalConfiguration.Group},
3229 {"password", vassalConfiguration.Password}, 3207 {"password", vassalConfiguration.Password},
3230 {"data", CSV.FromEnumerable(groundTextureUUIDs.Select(o => o.ToString()))} 3208 {"data", CSV.FromEnumerable(groundTextureUUIDs.Select(o => o.ToString()))}
3231 }, wasOutput), vassalConfiguration.DataTimeout); 3209 }, wasOutput)).Result);
3232   3210  
3233 if (string.IsNullOrEmpty(result)) 3211 if (string.IsNullOrEmpty(result))
3234 throw new Exception("Error communicating with Corrade"); 3212 throw new Exception("Error communicating with Corrade");
3235   3213  
3236 bool success; 3214 bool success;
3237 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 3215 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
3238 throw new Exception("No success status could be retrieved"); 3216 throw new Exception("No success status could be retrieved");
3239   3217  
3240 if (!success) 3218 if (!success)
3241 throw new Exception("Unable to apply estate ground textures"); 3219 throw new Exception("Unable to apply estate ground textures");
3242 } 3220 }
3243 catch (Exception ex) 3221 catch (Exception ex)
3244 { 3222 {
3245 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); 3223 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; }));
3246 } 3224 }
3247 finally 3225 finally
3248 { 3226 {
3249 Monitor.Exit(ClientInstanceTeleportLock); 3227 Monitor.Exit(ClientInstanceTeleportLock);
3250 } 3228 }
3251   3229  
3252 // Block teleports and disable button. 3230 // Block teleports and disable button.
3253 vassalForm.Invoke((MethodInvoker) (() => 3231 vassalForm.Invoke((MethodInvoker) (() =>
3254 { 3232 {
3255 RegionTeleportGroup.Enabled = true; 3233 RegionTeleportGroup.Enabled = true;
3256 GroundTexturesGroup.Enabled = true; 3234 GroundTexturesGroup.Enabled = true;
3257 })); 3235 }));
3258 }) 3236 })
3259 {IsBackground = true}; 3237 {IsBackground = true};
3260 } 3238 }
3261   3239  
3262 private void RequestDownloadRegionTexture(object sender, EventArgs e) 3240 private void RequestDownloadRegionTexture(object sender, EventArgs e)
3263 { 3241 {
3264 string textureName = string.Empty; 3242 var textureName = string.Empty;
3265 UUID textureUUID = UUID.Zero; 3243 var textureUUID = UUID.Zero;
3266 bool run = false; 3244 var run = false;
3267 vassalForm.Invoke((MethodInvoker) (() => 3245 vassalForm.Invoke((MethodInvoker) (() =>
3268 { 3246 {
3269 Button button = sender as Button; 3247 var button = sender as Button;
3270 if (button == null) 3248 if (button == null)
3271 { 3249 {
3272 run = false; 3250 run = false;
3273 return; 3251 return;
3274 } 3252 }
3275 textureName = button.Tag.ToString(); 3253 textureName = button.Tag.ToString();
3276 switch (textureName) 3254 switch (textureName)
3277 { 3255 {
3278 case "Low": 3256 case "Low":
3279 if (!UUID.TryParse(RegionTexturesLowUUIDBox.Text, out textureUUID)) 3257 if (!UUID.TryParse(RegionTexturesLowUUIDBox.Text, out textureUUID))
3280 { 3258 {
3281 run = false; 3259 run = false;
3282 return; 3260 return;
3283 } 3261 }
3284 goto case "MiddleLow"; 3262 goto case "MiddleLow";
3285 case "MiddleLow": 3263 case "MiddleLow":
3286 if (!UUID.TryParse(RegionTexturesMiddleLowUUIDBox.Text, out textureUUID)) 3264 if (!UUID.TryParse(RegionTexturesMiddleLowUUIDBox.Text, out textureUUID))
3287 { 3265 {
3288 run = false; 3266 run = false;
3289 return; 3267 return;
3290 } 3268 }
3291 goto case "MiddleHigh"; 3269 goto case "MiddleHigh";
3292 case "MiddleHigh": 3270 case "MiddleHigh":
3293 if (!UUID.TryParse(RegionTexturesMiddleHighUUIDBox.Text, out textureUUID)) 3271 if (!UUID.TryParse(RegionTexturesMiddleHighUUIDBox.Text, out textureUUID))
3294 { 3272 {
3295 run = false; 3273 run = false;
3296 return; 3274 return;
3297 } 3275 }
3298 goto case "High"; 3276 goto case "High";
3299 case "High": 3277 case "High":
3300 if (!UUID.TryParse(RegionTexturesHighUUIDBox.Text, out textureUUID)) 3278 if (!UUID.TryParse(RegionTexturesHighUUIDBox.Text, out textureUUID))
3301 { 3279 {
3302 run = false; 3280 run = false;
3303 return; 3281 return;
3304 } 3282 }
3305 run = true; 3283 run = true;
3306 break; 3284 break;
3307 } 3285 }
3308 })); 3286 }));
3309   3287  
3310 if (!run) return; 3288 if (!run) return;
3311   3289  
3312 // Block teleports and disable button. 3290 // Block teleports and disable button.
3313 vassalForm.Invoke((MethodInvoker) (() => 3291 vassalForm.Invoke((MethodInvoker) (() =>
3314 { 3292 {
3315 RegionTeleportGroup.Enabled = false; 3293 RegionTeleportGroup.Enabled = false;
3316 GroundTexturesGroup.Enabled = false; 3294 GroundTexturesGroup.Enabled = false;
3317 })); 3295 }));
3318   3296  
3319 new Thread(() => 3297 new Thread(() =>
3320 { 3298 {
3321 try 3299 try
3322 { 3300 {
3323 Monitor.Enter(ClientInstanceTeleportLock); 3301 Monitor.Enter(ClientInstanceTeleportLock);
3324   3302  
3325 string result = wasPOST(vassalConfiguration.HTTPServerURL, 3303 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
3326 KeyValue.Escape(new Dictionary<string, string> 3304 KeyValue.Escape(new Dictionary<string, string>
3327 { 3305 {
3328 {"command", "download"}, 3306 {"command", "download"},
3329 {"group", vassalConfiguration.Group}, 3307 {"group", vassalConfiguration.Group},
3330 {"password", vassalConfiguration.Password}, 3308 {"password", vassalConfiguration.Password},
3331 {"item", textureUUID.ToString()}, 3309 {"item", textureUUID.ToString()},
3332 {"type", "Texture"}, 3310 {"type", "Texture"},
3333 {"format", "Png"} 3311 {"format", "Png"}
3334 }, wasOutput), vassalConfiguration.DataTimeout); 3312 }, wasOutput)).Result);
3335   3313  
3336 if (string.IsNullOrEmpty(result)) 3314 if (string.IsNullOrEmpty(result))
3337 throw new Exception("Error communicating with Corrade"); 3315 throw new Exception("Error communicating with Corrade");
3338   3316  
3339 bool success; 3317 bool success;
3340 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 3318 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
3341 throw new Exception("No success status could be retrieved"); 3319 throw new Exception("No success status could be retrieved");
3342   3320  
3343 byte[] mapImageBytes = Convert.FromBase64String(wasInput(KeyValue.Get("data", result))); 3321 var mapImageBytes = Convert.FromBase64String(wasInput(KeyValue.Get("data", result)));
3344 Image mapImage; 3322 Image mapImage;
3345 using (MemoryStream memoryStream = new MemoryStream(mapImageBytes, 0, mapImageBytes.Length)) 3323 using (var memoryStream = new MemoryStream(mapImageBytes, 0, mapImageBytes.Length))
3346 { 3324 {
3347 mapImage = Image.FromStream(memoryStream); 3325 mapImage = Image.FromStream(memoryStream);
3348 } 3326 }
3349   3327  
3350 vassalForm.BeginInvoke((MethodInvoker) (() => 3328 vassalForm.BeginInvoke((MethodInvoker) (() =>
3351 { 3329 {
3352 switch (vassalForm.SavePNGFileDialog.ShowDialog()) 3330 switch (vassalForm.SavePNGFileDialog.ShowDialog())
3353 { 3331 {
3354 case DialogResult.OK: 3332 case DialogResult.OK:
3355 string file = vassalForm.SavePNGFileDialog.FileName; 3333 var file = vassalForm.SavePNGFileDialog.FileName;
3356 new Thread(() => 3334 new Thread(() =>
3357 { 3335 {
3358 vassalForm.BeginInvoke((MethodInvoker) (() => 3336 vassalForm.BeginInvoke((MethodInvoker) (() =>
3359 { 3337 {
3360 try 3338 try
3361 { 3339 {
3362 vassalForm.StatusText.Text = @"saving texture..."; 3340 vassalForm.StatusText.Text = @"saving texture...";
3363 vassalForm.StatusProgress.Value = 0; 3341 vassalForm.StatusProgress.Value = 0;
3364   3342  
3365 mapImage.Save(file, ImageFormat.Png); 3343 mapImage.Save(file, ImageFormat.Png);
3366   3344  
3367 vassalForm.StatusText.Text = @"texture saved"; 3345 vassalForm.StatusText.Text = @"texture saved";
3368 vassalForm.StatusProgress.Value = 100; 3346 vassalForm.StatusProgress.Value = 100;
3369 } 3347 }
3370 catch (Exception ex) 3348 catch (Exception ex)
3371 { 3349 {
3372 vassalForm.StatusText.Text = ex.Message; 3350 vassalForm.StatusText.Text = ex.Message;
3373 } 3351 }
3374 finally 3352 finally
3375 { 3353 {
3376 mapImage.Dispose(); 3354 mapImage.Dispose();
3377 } 3355 }
3378 })); 3356 }));
3379 }) 3357 })
3380 {IsBackground = true}.Start(); 3358 {IsBackground = true}.Start();
3381 break; 3359 break;
3382 } 3360 }
3383 })); 3361 }));
3384 } 3362 }
3385 catch (Exception ex) 3363 catch (Exception ex)
3386 { 3364 {
3387 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); 3365 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; }));
3388 } 3366 }
3389 finally 3367 finally
3390 { 3368 {
3391 Monitor.Exit(ClientInstanceTeleportLock); 3369 Monitor.Exit(ClientInstanceTeleportLock);
3392 } 3370 }
3393   3371  
3394 // Block teleports and disable button. 3372 // Block teleports and disable button.
3395 vassalForm.Invoke((MethodInvoker) (() => 3373 vassalForm.Invoke((MethodInvoker) (() =>
3396 { 3374 {
3397 RegionTeleportGroup.Enabled = true; 3375 RegionTeleportGroup.Enabled = true;
3398 GroundTexturesGroup.Enabled = true; 3376 GroundTexturesGroup.Enabled = true;
3399 })); 3377 }));
3400 }) 3378 })
3401 {IsBackground = true}.Start(); 3379 {IsBackground = true}.Start();
3402 } 3380 }
3403   3381  
3404 private void RequestEstateListsAddGroupsFromCSV(object sender, EventArgs e) 3382 private void RequestEstateListsAddGroupsFromCSV(object sender, EventArgs e)
3405 { 3383 {
3406 // Get the estate list type. 3384 // Get the estate list type.
3407 string selectedEstateListType = string.Empty; 3385 var selectedEstateListType = string.Empty;
3408 bool queryEstateList = false; 3386 var queryEstateList = false;
3409 vassalForm.Invoke((MethodInvoker) (() => 3387 vassalForm.Invoke((MethodInvoker) (() =>
3410 { 3388 {
3411 if (vassalForm.EstateListSelectBox.SelectedItem == null) return; 3389 if (vassalForm.EstateListSelectBox.SelectedItem == null) return;
3412 selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString(); 3390 selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString();
3413 switch ( 3391 switch (
3414 !string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1) 3392 !string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1)
3415 { 3393 {
3416 case true: 3394 case true:
3417 queryEstateList = true; 3395 queryEstateList = true;
3418 break; 3396 break;
3419 default: 3397 default:
3420 queryEstateList = false; 3398 queryEstateList = false;
3421 break; 3399 break;
3422 } 3400 }
3423 })); 3401 }));
3424   3402  
3425 // If not estate list type is selected then return. 3403 // If not estate list type is selected then return.
3426 if (!queryEstateList) return; 3404 if (!queryEstateList) return;
3427   3405  
3428 Queue<KeyValuePair<string, UUID>> targets = new Queue<KeyValuePair<string, UUID>>(); 3406 var targets = new Queue<KeyValuePair<string, UUID>>();
3429   3407  
3430 vassalForm.Invoke((MethodInvoker) (() => 3408 vassalForm.Invoke((MethodInvoker) (() =>
3431 { 3409 {
3432 switch (vassalForm.LoadCSVFile.ShowDialog()) 3410 switch (vassalForm.LoadCSVFile.ShowDialog())
3433 { 3411 {
3434 case DialogResult.OK: 3412 case DialogResult.OK:
3435 string file = vassalForm.LoadCSVFile.FileName; 3413 var file = vassalForm.LoadCSVFile.FileName;
3436 try 3414 try
3437 { 3415 {
3438 vassalForm.StatusText.Text = @"loading group list..."; 3416 vassalForm.StatusText.Text = @"loading group list...";
3439 vassalForm.StatusProgress.Value = 0; 3417 vassalForm.StatusProgress.Value = 0;
3440   3418  
3441 // import groups 3419 // import groups
3442 UUID targetUUID; 3420 UUID targetUUID;
3443 foreach (KeyValuePair<string, UUID> target in 3421 foreach (var target in
3444 File.ReadAllLines(file) 3422 File.ReadAllLines(file)
3445 .AsParallel() 3423 .AsParallel()
3446 .Select(o => new List<string>(CSV.ToEnumerable(o))) 3424 .Select(o => new List<string>(CSV.ToEnumerable(o)))
3447 .Where(o => o.Count == 2) 3425 .Where(o => o.Count == 2)
3448 .ToDictionary(o => o.First(), 3426 .ToDictionary(o => o.First(),
3449 p => 3427 p =>
3450 UUID.TryParse(p.Last(), out targetUUID) 3428 UUID.TryParse(p.Last(), out targetUUID)
3451 ? targetUUID 3429 ? targetUUID
3452 : UUID.Zero)) 3430 : UUID.Zero))
3453 { 3431 {
3454 targets.Enqueue(target); 3432 targets.Enqueue(target);
3455 } 3433 }
3456   3434  
3457 vassalForm.StatusText.Text = @"group list loaded"; 3435 vassalForm.StatusText.Text = @"group list loaded";
3458 vassalForm.StatusProgress.Value = 100; 3436 vassalForm.StatusProgress.Value = 100;
3459 } 3437 }
3460 catch (Exception ex) 3438 catch (Exception ex)
3461 { 3439 {
3462 vassalForm.StatusText.Text = ex.Message; 3440 vassalForm.StatusText.Text = ex.Message;
3463 } 3441 }
3464 break; 3442 break;
3465 } 3443 }
3466 })); 3444 }));
3467   3445  
3468 if (targets.Count.Equals(0)) return; 3446 if (targets.Count.Equals(0)) return;
3469 int initialQueueSize = targets.Count; 3447 var initialQueueSize = targets.Count;
3470   3448  
3471 // Block teleports and disable button. 3449 // Block teleports and disable button.
3472 vassalForm.Invoke((MethodInvoker) (() => 3450 vassalForm.Invoke((MethodInvoker) (() =>
3473 { 3451 {
3474 RegionTeleportGroup.Enabled = false; 3452 RegionTeleportGroup.Enabled = false;
3475 EstateListsGroupsGroup.Enabled = false; 3453 EstateListsGroupsGroup.Enabled = false;
3476 })); 3454 }));
3477   3455  
3478 new Thread(() => 3456 new Thread(() =>
3479 { 3457 {
3480 try 3458 try
3481 { 3459 {
3482 Monitor.Enter(ClientInstanceTeleportLock); 3460 Monitor.Enter(ClientInstanceTeleportLock);
3483   3461  
3484 do 3462 do
3485 { 3463 {
3486 KeyValuePair<string, UUID> target = targets.Dequeue(); 3464 var target = targets.Dequeue();
3487   3465  
3488 vassalForm.Invoke((MethodInvoker) (() => 3466 vassalForm.Invoke((MethodInvoker) (() =>
3489 { 3467 {
3490 StatusText.Text = @"Adding to estate list: " + target.Key; 3468 StatusText.Text = @"Adding to estate list: " + target.Key;
3491 vassalForm.StatusProgress.Value = 3469 vassalForm.StatusProgress.Value =
3492 Math.Min((int) (100d*Math.Abs(targets.Count - initialQueueSize)/initialQueueSize), 100); 3470 Math.Min((int) (100d*Math.Abs(targets.Count - initialQueueSize)/initialQueueSize), 100);
3493 })); 3471 }));
3494   3472  
3495 // Skip any items that already exist. 3473 // Skip any items that already exist.
3496 bool run = false; 3474 var run = false;
3497 vassalForm.Invoke((MethodInvoker) (() => 3475 vassalForm.Invoke((MethodInvoker) (() =>
3498 { 3476 {
3499 run = 3477 run =
3500 !EstateListGridView.Rows.AsParallel() 3478 !EstateListGridView.Rows.AsParallel()
3501 .Cast<DataGridViewRow>() 3479 .Cast<DataGridViewRow>()
3502 .Any(o => o.Cells["EstateListUUID"].Value.ToString().Equals(target.Value.ToString())); 3480 .Any(o => o.Cells["EstateListUUID"].Value.ToString().Equals(target.Value.ToString()));
3503 })); 3481 }));
3504 if (!run) continue; 3482 if (!run) continue;
3505   3483  
3506 // Skip broken UUIDs. 3484 // Skip broken UUIDs.
3507 if (target.Value.Equals(UUID.Zero)) continue; 3485 if (target.Value.Equals(UUID.Zero)) continue;
3508   3486  
3509 try 3487 try
3510 { 3488 {
3511 // Add the group to the list. 3489 // Add the group to the list.
3512 string result = wasPOST(vassalConfiguration.HTTPServerURL, 3490 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
3513 KeyValue.Escape(new Dictionary<string, string> 3491 KeyValue.Escape(new Dictionary<string, string>
3514 { 3492 {
3515 {"command", "setestatelist"}, 3493 {"command", "setestatelist"},
3516 {"group", vassalConfiguration.Group}, 3494 {"group", vassalConfiguration.Group},
3517 {"password", vassalConfiguration.Password}, 3495 {"password", vassalConfiguration.Password},
3518 {"type", selectedEstateListType}, 3496 {"type", selectedEstateListType},
3519 {"action", "add"}, 3497 {"action", "add"},
3520 {"target", target.Value.ToString()} 3498 {"target", target.Value.ToString()}
3521 }, wasOutput), vassalConfiguration.DataTimeout); 3499 }, wasOutput)).Result);
3522   3500  
3523 if (string.IsNullOrEmpty(result)) 3501 if (string.IsNullOrEmpty(result))
3524 throw new Exception("Error communicating with Corrade"); 3502 throw new Exception("Error communicating with Corrade");
3525   3503  
3526 bool success; 3504 bool success;
3527 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 3505 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
3528 throw new Exception("No success status could be retrieved"); 3506 throw new Exception("No success status could be retrieved");
3529   3507  
3530 if (!success) 3508 if (!success)
3531 throw new Exception("Unable to add group"); 3509 throw new Exception("Unable to add group");
3532 } 3510 }
3533 catch (Exception ex) 3511 catch (Exception ex)
3534 { 3512 {
3535 vassalForm.Invoke( 3513 vassalForm.Invoke(
3536 (MethodInvoker) (() => { StatusText.Text = ex.Message + @": " + target.Value; })); 3514 (MethodInvoker) (() => { StatusText.Text = ex.Message + @": " + target.Value; }));
3537 } 3515 }
3538 } while (!targets.Count.Equals(0)); 3516 } while (!targets.Count.Equals(0));
3539   3517  
3540 // Retrieve the estate list. 3518 // Retrieve the estate list.
3541 try 3519 try
3542 { 3520 {
3543 // Retrieve the estate list for updates. 3521 // Retrieve the estate list for updates.
3544 string result = wasPOST(vassalConfiguration.HTTPServerURL, 3522 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
3545 KeyValue.Escape(new Dictionary<string, string> 3523 KeyValue.Escape(new Dictionary<string, string>
3546 { 3524 {
3547 {"command", "getestatelist"}, 3525 {"command", "getestatelist"},
3548 {"group", vassalConfiguration.Group}, 3526 {"group", vassalConfiguration.Group},
3549 {"password", vassalConfiguration.Password}, 3527 {"password", vassalConfiguration.Password},
3550 {"type", selectedEstateListType} 3528 {"type", selectedEstateListType}
3551 }, wasOutput), vassalConfiguration.DataTimeout); 3529 }, wasOutput)).Result);
3552   3530  
3553 if (string.IsNullOrEmpty(result)) 3531 if (string.IsNullOrEmpty(result))
3554 throw new Exception("Error communicating with Corrade."); 3532 throw new Exception("Error communicating with Corrade.");
3555   3533  
3556 bool success; 3534 bool success;
3557 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 3535 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
3558 throw new Exception("No success status could be retrieved."); 3536 throw new Exception("No success status could be retrieved.");
3559   3537  
3560 if (!success) 3538 if (!success)
3561 throw new Exception("Could not retrieve estate list."); 3539 throw new Exception("Could not retrieve estate list.");
3562   3540  
3563 vassalForm.Invoke((MethodInvoker) (() => { EstateListGridView.Rows.Clear(); })); 3541 vassalForm.Invoke((MethodInvoker) (() => { EstateListGridView.Rows.Clear(); }));
3564 foreach (List<string> data in CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))) 3542 foreach (var data in CSV.ToEnumerable(wasInput(KeyValue.Get("data", result)))
3565 .Where(x => !string.IsNullOrEmpty(x)) 3543 .Where(x => !string.IsNullOrEmpty(x))
3566 .Select((x, i) => new {Index = i, Value = x}) 3544 .Select((x, i) => new {Index = i, Value = x})
3567 .GroupBy(x => x.Index/2) 3545 .GroupBy(x => x.Index/2)
3568 .Select(x => x.Select(v => v.Value).ToList())) 3546 .Select(x => x.Select(v => v.Value).ToList()))
3569 { 3547 {
3570 vassalForm.BeginInvoke( 3548 vassalForm.BeginInvoke(
3571 (MethodInvoker) (() => { EstateListGridView.Rows.Add(data.First(), data.Last()); })); 3549 (MethodInvoker) (() => { EstateListGridView.Rows.Add(data.First(), data.Last()); }));
3572 } 3550 }
3573 } 3551 }
3574 catch (Exception ex) 3552 catch (Exception ex)
3575 { 3553 {
3576 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); 3554 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; }));
3577 } 3555 }
3578 } 3556 }
3579 catch (Exception ex) 3557 catch (Exception ex)
3580 { 3558 {
3581 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); 3559 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; }));
3582 } 3560 }
3583 finally 3561 finally
3584 { 3562 {
3585 Monitor.Exit(ClientInstanceTeleportLock); 3563 Monitor.Exit(ClientInstanceTeleportLock);
3586 // Enable teleports and enable button. 3564 // Enable teleports and enable button.
3587 vassalForm.Invoke((MethodInvoker) (() => 3565 vassalForm.Invoke((MethodInvoker) (() =>
3588 { 3566 {
3589 RegionTeleportGroup.Enabled = true; 3567 RegionTeleportGroup.Enabled = true;
3590 EstateListsGroupsGroup.Enabled = true; 3568 EstateListsGroupsGroup.Enabled = true;
3591 })); 3569 }));
3592 } 3570 }
3593 }) 3571 })
3594 {IsBackground = true}.Start(); 3572 {IsBackground = true}.Start();
3595 } 3573 }
3596   3574  
3597 private void RequestEstateListsAddResidentsFromCSV(object sender, EventArgs e) 3575 private void RequestEstateListsAddResidentsFromCSV(object sender, EventArgs e)
3598 { 3576 {
3599 // Get the estate list type. 3577 // Get the estate list type.
3600 string selectedEstateListType = string.Empty; 3578 var selectedEstateListType = string.Empty;
3601 bool queryEstateList = false; 3579 var queryEstateList = false;
3602 vassalForm.Invoke((MethodInvoker) (() => 3580 vassalForm.Invoke((MethodInvoker) (() =>
3603 { 3581 {
3604 if (vassalForm.EstateListSelectBox.SelectedItem == null) return; 3582 if (vassalForm.EstateListSelectBox.SelectedItem == null) return;
3605 selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString(); 3583 selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString();
3606 switch ( 3584 switch (
3607 !string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1) 3585 !string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1)
3608 { 3586 {
3609 case true: 3587 case true:
3610 queryEstateList = true; 3588 queryEstateList = true;
3611 break; 3589 break;
3612 default: 3590 default:
3613 queryEstateList = false; 3591 queryEstateList = false;
3614 break; 3592 break;
3615 } 3593 }
3616 })); 3594 }));
3617   3595  
3618 // If not estate list type is selected then return. 3596 // If not estate list type is selected then return.
3619 if (!queryEstateList) return; 3597 if (!queryEstateList) return;
3620   3598  
3621 Queue<KeyValuePair<string, UUID>> targets = new Queue<KeyValuePair<string, UUID>>(); 3599 var targets = new Queue<KeyValuePair<string, UUID>>();
3622   3600  
3623 vassalForm.Invoke((MethodInvoker) (() => 3601 vassalForm.Invoke((MethodInvoker) (() =>
3624 { 3602 {
3625 switch (vassalForm.LoadCSVFile.ShowDialog()) 3603 switch (vassalForm.LoadCSVFile.ShowDialog())
3626 { 3604 {
3627 case DialogResult.OK: 3605 case DialogResult.OK:
3628 string file = vassalForm.LoadCSVFile.FileName; 3606 var file = vassalForm.LoadCSVFile.FileName;
3629 try 3607 try
3630 { 3608 {
3631 vassalForm.StatusText.Text = @"loading residents list..."; 3609 vassalForm.StatusText.Text = @"loading residents list...";
3632 vassalForm.StatusProgress.Value = 0; 3610 vassalForm.StatusProgress.Value = 0;
3633   3611  
3634 // import groups 3612 // import groups
3635 UUID targetUUID; 3613 UUID targetUUID;
3636 foreach (KeyValuePair<string, UUID> target in 3614 foreach (var target in
3637 File.ReadAllLines(file) 3615 File.ReadAllLines(file)
3638 .AsParallel() 3616 .AsParallel()
3639 .Select(o => new List<string>(CSV.ToEnumerable(o))) 3617 .Select(o => new List<string>(CSV.ToEnumerable(o)))
3640 .Where(o => o.Count == 2) 3618 .Where(o => o.Count == 2)
3641 .ToDictionary(o => o.First(), 3619 .ToDictionary(o => o.First(),
3642 p => 3620 p =>
3643 UUID.TryParse(p.Last(), out targetUUID) 3621 UUID.TryParse(p.Last(), out targetUUID)
3644 ? targetUUID 3622 ? targetUUID
3645 : UUID.Zero)) 3623 : UUID.Zero))
3646 { 3624 {
3647 targets.Enqueue(target); 3625 targets.Enqueue(target);
3648 } 3626 }
3649   3627  
3650 vassalForm.StatusText.Text = @"residents list loaded"; 3628 vassalForm.StatusText.Text = @"residents list loaded";
3651 vassalForm.StatusProgress.Value = 100; 3629 vassalForm.StatusProgress.Value = 100;
3652 } 3630 }
3653 catch (Exception ex) 3631 catch (Exception ex)
3654 { 3632 {
3655 vassalForm.StatusText.Text = ex.Message; 3633 vassalForm.StatusText.Text = ex.Message;
3656 } 3634 }
3657 break; 3635 break;
3658 } 3636 }
3659 })); 3637 }));
3660   3638  
3661 if (targets.Count.Equals(0)) return; 3639 if (targets.Count.Equals(0)) return;
3662 int initialQueueSize = targets.Count; 3640 var initialQueueSize = targets.Count;
3663   3641  
3664 // Block teleports and disable button. 3642 // Block teleports and disable button.
3665 vassalForm.Invoke((MethodInvoker) (() => 3643 vassalForm.Invoke((MethodInvoker) (() =>
3666 { 3644 {
3667 RegionTeleportGroup.Enabled = false; 3645 RegionTeleportGroup.Enabled = false;
3668 EstateListsResidentsGroup.Enabled = false; 3646 EstateListsResidentsGroup.Enabled = false;
3669 })); 3647 }));
3670   3648  
3671 new Thread(() => 3649 new Thread(() =>
3672 { 3650 {
3673 try 3651 try
3674 { 3652 {
3675 Monitor.Enter(ClientInstanceTeleportLock); 3653 Monitor.Enter(ClientInstanceTeleportLock);
3676   3654  
3677 do 3655 do
3678 { 3656 {
3679 KeyValuePair<string, UUID> target = targets.Dequeue(); 3657 var target = targets.Dequeue();
3680   3658  
3681 vassalForm.Invoke((MethodInvoker) (() => 3659 vassalForm.Invoke((MethodInvoker) (() =>
3682 { 3660 {
3683 StatusText.Text = @"Adding to estate list: " + target.Key; 3661 StatusText.Text = @"Adding to estate list: " + target.Key;
3684 vassalForm.StatusProgress.Value = 3662 vassalForm.StatusProgress.Value =
3685 Math.Min((int) (100d*Math.Abs(targets.Count - initialQueueSize)/initialQueueSize), 100); 3663 Math.Min((int) (100d*Math.Abs(targets.Count - initialQueueSize)/initialQueueSize), 100);
3686 })); 3664 }));
3687   3665  
3688 // Skip any items that already exist. 3666 // Skip any items that already exist.
3689 bool run = false; 3667 var run = false;
3690 vassalForm.Invoke((MethodInvoker) (() => 3668 vassalForm.Invoke((MethodInvoker) (() =>
3691 { 3669 {
3692 run = 3670 run =
3693 !EstateListGridView.Rows.AsParallel() 3671 !EstateListGridView.Rows.AsParallel()
3694 .Cast<DataGridViewRow>() 3672 .Cast<DataGridViewRow>()
3695 .Any(o => o.Cells["EstateListUUID"].Value.ToString().Equals(target.Value.ToString())); 3673 .Any(o => o.Cells["EstateListUUID"].Value.ToString().Equals(target.Value.ToString()));
3696 })); 3674 }));
3697 if (!run) continue; 3675 if (!run) continue;
3698   3676  
3699 // Skip broken UUIDs. 3677 // Skip broken UUIDs.
3700 if (target.Value.Equals(UUID.Zero)) continue; 3678 if (target.Value.Equals(UUID.Zero)) continue;
3701   3679  
3702 try 3680 try
3703 { 3681 {
3704 // Add the group to the list. 3682 // Add the group to the list.
3705 string result = wasPOST(vassalConfiguration.HTTPServerURL, 3683 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
3706 KeyValue.Escape(new Dictionary<string, string> 3684 KeyValue.Escape(new Dictionary<string, string>
3707 { 3685 {
3708 {"command", "setestatelist"}, 3686 {"command", "setestatelist"},
3709 {"group", vassalConfiguration.Group}, 3687 {"group", vassalConfiguration.Group},
3710 {"password", vassalConfiguration.Password}, 3688 {"password", vassalConfiguration.Password},
3711 {"type", selectedEstateListType}, 3689 {"type", selectedEstateListType},
3712 {"action", "add"}, 3690 {"action", "add"},
3713 {"agent", target.Value.ToString()} 3691 {"agent", target.Value.ToString()}
3714 }, wasOutput), vassalConfiguration.DataTimeout); 3692 }, wasOutput)).Result);
3715   3693  
3716 if (string.IsNullOrEmpty(result)) 3694 if (string.IsNullOrEmpty(result))
3717 throw new Exception("Error communicating with Corrade"); 3695 throw new Exception("Error communicating with Corrade");
3718   3696  
3719 bool success; 3697 bool success;
3720 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 3698 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
3721 throw new Exception("No success status could be retrieved"); 3699 throw new Exception("No success status could be retrieved");
3722   3700  
3723 if (!success) 3701 if (!success)
3724 throw new Exception("Unable to add resident"); 3702 throw new Exception("Unable to add resident");
3725 } 3703 }
3726 catch (Exception ex) 3704 catch (Exception ex)
3727 { 3705 {
3728 vassalForm.Invoke( 3706 vassalForm.Invoke(
3729 (MethodInvoker) (() => { StatusText.Text = ex.Message + @": " + target.Value; })); 3707 (MethodInvoker) (() => { StatusText.Text = ex.Message + @": " + target.Value; }));
3730 } 3708 }
3731 } while (!targets.Count.Equals(0)); 3709 } while (!targets.Count.Equals(0));
3732   3710  
3733 // Retrieve the estate list. 3711 // Retrieve the estate list.
3734 try 3712 try
3735 { 3713 {
3736 // Retrieve the estate list for updates. 3714 // Retrieve the estate list for updates.
3737 string result = wasPOST(vassalConfiguration.HTTPServerURL, 3715 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
3738 KeyValue.Escape(new Dictionary<string, string> 3716 KeyValue.Escape(new Dictionary<string, string>
3739 { 3717 {
3740 {"command", "getestatelist"}, 3718 {"command", "getestatelist"},
3741 {"group", vassalConfiguration.Group}, 3719 {"group", vassalConfiguration.Group},
3742 {"password", vassalConfiguration.Password}, 3720 {"password", vassalConfiguration.Password},
3743 {"type", selectedEstateListType} 3721 {"type", selectedEstateListType}
3744 }, wasOutput), vassalConfiguration.DataTimeout); 3722 }, wasOutput)).Result);
3745   3723  
3746 if (string.IsNullOrEmpty(result)) 3724 if (string.IsNullOrEmpty(result))
3747 throw new Exception("Error communicating with Corrade."); 3725 throw new Exception("Error communicating with Corrade.");
3748   3726  
3749 bool success; 3727 bool success;
3750 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 3728 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
3751 throw new Exception("No success status could be retrieved."); 3729 throw new Exception("No success status could be retrieved.");
3752   3730  
3753 if (!success) 3731 if (!success)
3754 throw new Exception("Could not retrieve estate list."); 3732 throw new Exception("Could not retrieve estate list.");
3755   3733  
3756 vassalForm.Invoke((MethodInvoker) (() => { EstateListGridView.Rows.Clear(); })); 3734 vassalForm.Invoke((MethodInvoker) (() => { EstateListGridView.Rows.Clear(); }));
3757 foreach (List<string> data in CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))) 3735 foreach (var data in CSV.ToEnumerable(wasInput(KeyValue.Get("data", result)))
3758 .Where(x => !string.IsNullOrEmpty(x)) 3736 .Where(x => !string.IsNullOrEmpty(x))
3759 .Select((x, i) => new {Index = i, Value = x}) 3737 .Select((x, i) => new {Index = i, Value = x})
3760 .GroupBy(x => x.Index/2) 3738 .GroupBy(x => x.Index/2)
3761 .Select(x => x.Select(v => v.Value).ToList())) 3739 .Select(x => x.Select(v => v.Value).ToList()))
3762 { 3740 {
3763 vassalForm.BeginInvoke( 3741 vassalForm.BeginInvoke(
3764 (MethodInvoker) (() => { EstateListGridView.Rows.Add(data.First(), data.Last()); })); 3742 (MethodInvoker) (() => { EstateListGridView.Rows.Add(data.First(), data.Last()); }));
3765 } 3743 }
3766 } 3744 }
3767 catch (Exception ex) 3745 catch (Exception ex)
3768 { 3746 {
3769 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); 3747 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; }));
3770 } 3748 }
3771 } 3749 }
3772 catch (Exception ex) 3750 catch (Exception ex)
3773 { 3751 {
3774 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); 3752 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; }));
3775 } 3753 }
3776 finally 3754 finally
3777 { 3755 {
3778 Monitor.Exit(ClientInstanceTeleportLock); 3756 Monitor.Exit(ClientInstanceTeleportLock);
3779 // Enable teleports and enable button. 3757 // Enable teleports and enable button.
3780 vassalForm.Invoke((MethodInvoker) (() => 3758 vassalForm.Invoke((MethodInvoker) (() =>
3781 { 3759 {
3782 RegionTeleportGroup.Enabled = true; 3760 RegionTeleportGroup.Enabled = true;
3783 EstateListsResidentsGroup.Enabled = true; 3761 EstateListsResidentsGroup.Enabled = true;
3784 })); 3762 }));
3785 } 3763 }
3786 }) 3764 })
3787 {IsBackground = true}.Start(); 3765 {IsBackground = true}.Start();
3788 } 3766 }
3789   3767  
3790 private void RequestExportEstateList(object sender, EventArgs e) 3768 private void RequestExportEstateList(object sender, EventArgs e)
3791 { 3769 {
3792 vassalForm.BeginInvoke((MethodInvoker) (() => 3770 vassalForm.BeginInvoke((MethodInvoker) (() =>
3793 { 3771 {
3794 switch (vassalForm.ExportCSVDialog.ShowDialog()) 3772 switch (vassalForm.ExportCSVDialog.ShowDialog())
3795 { 3773 {
3796 case DialogResult.OK: 3774 case DialogResult.OK:
3797 string file = vassalForm.ExportCSVDialog.FileName; 3775 var file = vassalForm.ExportCSVDialog.FileName;
3798 new Thread(() => 3776 new Thread(() =>
3799 { 3777 {
3800 vassalForm.BeginInvoke((MethodInvoker) (() => 3778 vassalForm.BeginInvoke((MethodInvoker) (() =>
3801 { 3779 {
3802 try 3780 try
3803 { 3781 {
3804 vassalForm.StatusText.Text = @"exporting..."; 3782 vassalForm.StatusText.Text = @"exporting...";
3805 vassalForm.StatusProgress.Value = 0; 3783 vassalForm.StatusProgress.Value = 0;
3806   3784  
3807 using (StreamWriter streamWriter = new StreamWriter(file, false, Encoding.UTF8)) 3785 using (var streamWriter = new StreamWriter(file, false, Encoding.UTF8))
3808 { 3786 {
3809 foreach (DataGridViewRow estateListRow in EstateListGridView.Rows) 3787 foreach (DataGridViewRow estateListRow in EstateListGridView.Rows)
3810 { 3788 {
3811 streamWriter.WriteLine(CSV.FromEnumerable(new[] 3789 streamWriter.WriteLine(CSV.FromEnumerable(new[]
3812 { 3790 {
3813 estateListRow.Cells["EstateListName"].Value.ToString(), 3791 estateListRow.Cells["EstateListName"].Value.ToString(),
3814 estateListRow.Cells["EstateListUUID"].Value.ToString() 3792 estateListRow.Cells["EstateListUUID"].Value.ToString()
3815 })); 3793 }));
3816 } 3794 }
3817 } 3795 }
3818   3796  
3819 vassalForm.StatusText.Text = @"exported"; 3797 vassalForm.StatusText.Text = @"exported";
3820 vassalForm.StatusProgress.Value = 100; 3798 vassalForm.StatusProgress.Value = 100;
3821 } 3799 }
3822 catch (Exception ex) 3800 catch (Exception ex)
3823 { 3801 {
3824 vassalForm.StatusText.Text = ex.Message; 3802 vassalForm.StatusText.Text = ex.Message;
3825 } 3803 }
3826 })); 3804 }));
3827 }) 3805 })
3828 {IsBackground = true}.Start(); 3806 {IsBackground = true}.Start();
3829 break; 3807 break;
3830 } 3808 }
3831 })); 3809 }));
3832 } 3810 }
3833   3811  
3834 private void RequestTeleportHome(object sender, EventArgs e) 3812 private void RequestTeleportHome(object sender, EventArgs e)
3835 { 3813 {
3836 // Block teleports and disable button. 3814 // Block teleports and disable button.
3837 vassalForm.Invoke((MethodInvoker) (() => 3815 vassalForm.Invoke((MethodInvoker) (() =>
3838 { 3816 {
3839 ResidentListTeleportHomeGroup.Enabled = false; 3817 ResidentListTeleportHomeGroup.Enabled = false;
3840 ResidentListBanGroup.Enabled = false; 3818 ResidentListBanGroup.Enabled = false;
3841 RegionTeleportGroup.Enabled = false; 3819 RegionTeleportGroup.Enabled = false;
3842 })); 3820 }));
3843   3821  
3844 // Enqueue all the agents to teleport home. 3822 // Enqueue all the agents to teleport home.
3845 Queue<UUID> agentsQueue = new Queue<UUID>(); 3823 var agentsQueue = new Queue<UUID>();
3846 vassalForm.Invoke((MethodInvoker) (() => 3824 vassalForm.Invoke((MethodInvoker) (() =>
3847 { 3825 {
3848 foreach ( 3826 foreach (
3849 DataGridViewRow residentListRow in 3827 var residentListRow in
3850 ResidentListGridView.Rows.AsParallel() 3828 ResidentListGridView.Rows.AsParallel()
3851 .Cast<DataGridViewRow>() 3829 .Cast<DataGridViewRow>()
3852 .Where(o => o.Selected || o.Cells.Cast<DataGridViewCell>().Any(p => p.Selected))) 3830 .Where(o => o.Selected || o.Cells.Cast<DataGridViewCell>().Any(p => p.Selected)))
3853 { 3831 {
3854 UUID agentUUID; 3832 UUID agentUUID;
3855 if (!UUID.TryParse(residentListRow.Cells["ResidentListUUID"].Value.ToString(), out agentUUID)) 3833 if (!UUID.TryParse(residentListRow.Cells["ResidentListUUID"].Value.ToString(), out agentUUID))
3856 continue; 3834 continue;
3857 agentsQueue.Enqueue(agentUUID); 3835 agentsQueue.Enqueue(agentUUID);
3858 } 3836 }
3859 })); 3837 }));
3860   3838  
3861 // If no rows were selected, enable teleports, the return button and return. 3839 // If no rows were selected, enable teleports, the return button and return.
3862 if (agentsQueue.Count.Equals(0)) 3840 if (agentsQueue.Count.Equals(0))
3863 { 3841 {
3864 vassalForm.Invoke((MethodInvoker) (() => 3842 vassalForm.Invoke((MethodInvoker) (() =>
3865 { 3843 {
3866 ResidentListBanGroup.Enabled = true; 3844 ResidentListBanGroup.Enabled = true;
3867 RegionTeleportGroup.Enabled = true; 3845 RegionTeleportGroup.Enabled = true;
3868 })); 3846 }));
3869 return; 3847 return;
3870 } 3848 }
3871   3849  
3872 new Thread(() => 3850 new Thread(() =>
3873 { 3851 {
3874 Monitor.Enter(ClientInstanceTeleportLock); 3852 Monitor.Enter(ClientInstanceTeleportLock);
3875 try 3853 try
3876 { 3854 {
3877 do 3855 do
3878 { 3856 {
3879 // Dequeue the first object. 3857 // Dequeue the first object.
3880 UUID agentUUID = agentsQueue.Dequeue(); 3858 var agentUUID = agentsQueue.Dequeue();
3881 DataGridViewRow currentDataGridViewRow = null; 3859 DataGridViewRow currentDataGridViewRow = null;
3882 vassalForm.Invoke((MethodInvoker) (() => 3860 vassalForm.Invoke((MethodInvoker) (() =>
3883 { 3861 {
3884 currentDataGridViewRow = vassalForm.ResidentListGridView.Rows.AsParallel() 3862 currentDataGridViewRow = vassalForm.ResidentListGridView.Rows.AsParallel()
3885 .Cast<DataGridViewRow>() 3863 .Cast<DataGridViewRow>()
3886 .FirstOrDefault( 3864 .FirstOrDefault(
3887 o => 3865 o =>
3888 o.Cells["ResidentListUUID"].Value.ToString() 3866 o.Cells["ResidentListUUID"].Value.ToString()
3889 .Equals(agentUUID.ToString(), StringComparison.OrdinalIgnoreCase)); 3867 .Equals(agentUUID.ToString(), StringComparison.OrdinalIgnoreCase));
3890 })); 3868 }));
3891   3869  
3892 if (currentDataGridViewRow == null) continue; 3870 if (currentDataGridViewRow == null) continue;
3893   3871  
3894 try 3872 try
3895 { 3873 {
3896 // Teleport the user home. 3874 // Teleport the user home.
3897 string result = wasPOST(vassalConfiguration.HTTPServerURL, 3875 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
3898 KeyValue.Escape(new Dictionary<string, string> 3876 KeyValue.Escape(new Dictionary<string, string>
3899 { 3877 {
3900 {"command", "estateteleportusershome"}, 3878 {"command", "estateteleportusershome"},
3901 {"group", vassalConfiguration.Group}, 3879 {"group", vassalConfiguration.Group},
3902 {"password", vassalConfiguration.Password}, 3880 {"password", vassalConfiguration.Password},
3903 {"avatars", agentUUID.ToString()} 3881 {"avatars", agentUUID.ToString()}
3904 }, wasOutput), vassalConfiguration.DataTimeout); 3882 }, wasOutput)).Result);
3905   3883  
3906 if (string.IsNullOrEmpty(result)) 3884 if (string.IsNullOrEmpty(result))
3907 throw new Exception("Error communicating with Corrade."); 3885 throw new Exception("Error communicating with Corrade.");
3908   3886  
3909 bool success; 3887 bool success;
3910 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 3888 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
3911 throw new Exception("No success status could be retrieved."); 3889 throw new Exception("No success status could be retrieved.");
3912   3890  
3913 switch (success) 3891 switch (success)
3914 { 3892 {
3915 case true: 3893 case true:
3916 vassalForm.Invoke((MethodInvoker) (() => 3894 vassalForm.Invoke((MethodInvoker) (() =>
3917 { 3895 {
3918 vassalForm.StatusText.Text = @"Resident teleported home."; 3896 vassalForm.StatusText.Text = @"Resident teleported home.";
3919 currentDataGridViewRow.Selected = false; 3897 currentDataGridViewRow.Selected = false;
3920 currentDataGridViewRow.DefaultCellStyle.BackColor = Color.LightGreen; 3898 currentDataGridViewRow.DefaultCellStyle.BackColor = Color.LightGreen;
3921 foreach ( 3899 foreach (
3922 DataGridViewCell cell in 3900 var cell in
3923 currentDataGridViewRow.Cells.AsParallel().Cast<DataGridViewCell>()) 3901 currentDataGridViewRow.Cells.AsParallel().Cast<DataGridViewCell>())
3924 { 3902 {
3925 cell.ToolTipText = @"Resident teleported home."; 3903 cell.ToolTipText = @"Resident teleported home.";
3926 } 3904 }
3927 })); 3905 }));
3928 break; 3906 break;
3929 default: 3907 default:
3930 throw new Exception("Unable to teleport resident home."); 3908 throw new Exception("Unable to teleport resident home.");
3931 } 3909 }
3932 } 3910 }
3933 catch (Exception ex) 3911 catch (Exception ex)
3934 { 3912 {
3935 vassalForm.Invoke((MethodInvoker) (() => 3913 vassalForm.Invoke((MethodInvoker) (() =>
3936 { 3914 {
3937 vassalForm.StatusText.Text = ex.Message; 3915 vassalForm.StatusText.Text = ex.Message;
3938 currentDataGridViewRow.Selected = false; 3916 currentDataGridViewRow.Selected = false;
3939 currentDataGridViewRow.DefaultCellStyle.BackColor = Color.LightPink; 3917 currentDataGridViewRow.DefaultCellStyle.BackColor = Color.LightPink;
3940 foreach ( 3918 foreach (
3941 DataGridViewCell cell in 3919 var cell in
3942 currentDataGridViewRow.Cells.AsParallel().Cast<DataGridViewCell>()) 3920 currentDataGridViewRow.Cells.AsParallel().Cast<DataGridViewCell>())
3943 { 3921 {
3944 cell.ToolTipText = ex.Message; 3922 cell.ToolTipText = ex.Message;
3945 } 3923 }
3946 })); 3924 }));
3947 } 3925 }
3948 } while (agentsQueue.Count.Equals(0)); 3926 } while (agentsQueue.Count.Equals(0));
3949 } 3927 }
3950 catch (Exception) 3928 catch (Exception)
3951 { 3929 {
3952 } 3930 }
3953 finally 3931 finally
3954 { 3932 {
3955 Monitor.Exit(ClientInstanceTeleportLock); 3933 Monitor.Exit(ClientInstanceTeleportLock);
3956 // Allow teleports and enable button. 3934 // Allow teleports and enable button.
3957 vassalForm.BeginInvoke((MethodInvoker) (() => 3935 vassalForm.BeginInvoke((MethodInvoker) (() =>
3958 { 3936 {
3959 ResidentListTeleportHomeGroup.Enabled = true; 3937 ResidentListTeleportHomeGroup.Enabled = true;
3960 ResidentListBanGroup.Enabled = true; 3938 ResidentListBanGroup.Enabled = true;
3961 RegionTeleportGroup.Enabled = true; 3939 RegionTeleportGroup.Enabled = true;
3962 })); 3940 }));
3963 } 3941 }
3964 }) 3942 })
3965 {IsBackground = true}.Start(); 3943 {IsBackground = true}.Start();
3966 } 3944 }
3967   3945  
3968 private void RequestSetVariables(object sender, EventArgs e) 3946 private void RequestSetVariables(object sender, EventArgs e)
3969 { 3947 {
3970 // Block teleports and disable button. 3948 // Block teleports and disable button.
3971 vassalForm.Invoke((MethodInvoker) (() => 3949 vassalForm.Invoke((MethodInvoker) (() =>
3972 { 3950 {
3973 RegionTeleportGroup.Enabled = false; 3951 RegionTeleportGroup.Enabled = false;
3974 SetTerrainVariablesButton.Enabled = false; 3952 SetTerrainVariablesButton.Enabled = false;
3975 })); 3953 }));
3976   3954  
3977 new Thread(() => 3955 new Thread(() =>
3978 { 3956 {
3979 try 3957 try
3980 { 3958 {
3981 Monitor.Enter(ClientInstanceTeleportLock); 3959 Monitor.Enter(ClientInstanceTeleportLock);
3982   3960  
3983 int waterHeight = 10; 3961 var waterHeight = 10;
3984 int terrainRaiseLimit = 100; 3962 var terrainRaiseLimit = 100;
3985 int terrainLowerLimit = -100; 3963 var terrainLowerLimit = -100;
3986 bool useEstateSun = true; 3964 var useEstateSun = true;
3987 bool fixedSun = false; 3965 var fixedSun = false;
3988 int sunPosition = 18; 3966 var sunPosition = 18;
3989   3967  
3990 bool run = false; 3968 var run = false;
3991   3969  
3992 vassalForm.Invoke((MethodInvoker) (() => 3970 vassalForm.Invoke((MethodInvoker) (() =>
3993 { 3971 {
3994 useEstateSun = TerrainToolsUseEstateSunBox.Checked; 3972 useEstateSun = TerrainToolsUseEstateSunBox.Checked;
3995 fixedSun = TerrainToolsFixedSunBox.Checked; 3973 fixedSun = TerrainToolsFixedSunBox.Checked;
3996 switch (!int.TryParse(TerrainToolsWaterHeightBox.Text, out waterHeight)) 3974 switch (!int.TryParse(TerrainToolsWaterHeightBox.Text, out waterHeight))
3997 { 3975 {
3998 case true: 3976 case true:
3999 TerrainToolsWaterHeightBox.BackColor = Color.MistyRose; 3977 TerrainToolsWaterHeightBox.BackColor = Color.MistyRose;
4000 return; 3978 return;
4001 default: 3979 default:
4002 TerrainToolsWaterHeightBox.BackColor = Color.Empty; 3980 TerrainToolsWaterHeightBox.BackColor = Color.Empty;
4003 break; 3981 break;
4004 } 3982 }
4005 switch (!int.TryParse(TerrainToolsTerrainRaiseLimitBox.Text, out terrainRaiseLimit)) 3983 switch (!int.TryParse(TerrainToolsTerrainRaiseLimitBox.Text, out terrainRaiseLimit))
4006 { 3984 {
4007 case true: 3985 case true:
4008 TerrainToolsTerrainRaiseLimitBox.BackColor = Color.MistyRose; 3986 TerrainToolsTerrainRaiseLimitBox.BackColor = Color.MistyRose;
4009 return; 3987 return;
4010 default: 3988 default:
4011 TerrainToolsTerrainRaiseLimitBox.BackColor = Color.Empty; 3989 TerrainToolsTerrainRaiseLimitBox.BackColor = Color.Empty;
4012 break; 3990 break;
4013 } 3991 }
4014 switch (!int.TryParse(TerrainToolsTerrainLowerLimitBox.Text, out terrainLowerLimit)) 3992 switch (!int.TryParse(TerrainToolsTerrainLowerLimitBox.Text, out terrainLowerLimit))
4015 { 3993 {
4016 case true: 3994 case true:
4017 TerrainToolsTerrainLowerLimitBox.BackColor = Color.MistyRose; 3995 TerrainToolsTerrainLowerLimitBox.BackColor = Color.MistyRose;
4018 return; 3996 return;
4019 default: 3997 default:
4020 TerrainToolsTerrainLowerLimitBox.BackColor = Color.Empty; 3998 TerrainToolsTerrainLowerLimitBox.BackColor = Color.Empty;
4021 break; 3999 break;
4022 } 4000 }
4023 switch (!int.TryParse(TerrainToolsSunPositionBox.Text, out sunPosition)) 4001 switch (!int.TryParse(TerrainToolsSunPositionBox.Text, out sunPosition))
4024 { 4002 {
4025 case true: 4003 case true:
4026 TerrainToolsSunPositionBox.BackColor = Color.MistyRose; 4004 TerrainToolsSunPositionBox.BackColor = Color.MistyRose;
4027 return; 4005 return;
4028 default: 4006 default:
4029 TerrainToolsSunPositionBox.BackColor = Color.Empty; 4007 TerrainToolsSunPositionBox.BackColor = Color.Empty;
4030 break; 4008 break;
4031 } 4009 }
4032   4010  
4033 run = true; 4011 run = true;
4034 })); 4012 }));
4035   4013  
4036 if (!run) return; 4014 if (!run) return;
4037   4015  
4038 // Set the terrain variables. 4016 // Set the terrain variables.
4039 string result = wasPOST(vassalConfiguration.HTTPServerURL, 4017 var result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
4040 KeyValue.Escape(new Dictionary<string, string> 4018 KeyValue.Escape(new Dictionary<string, string>
4041 { 4019 {
4042 {"command", "setregionterrainvariables"}, 4020 {"command", "setregionterrainvariables"},
4043 {"group", vassalConfiguration.Group}, 4021 {"group", vassalConfiguration.Group},
4044 {"password", vassalConfiguration.Password}, 4022 {"password", vassalConfiguration.Password},
4045 {"waterheight", waterHeight.ToString()}, 4023 {"waterheight", waterHeight.ToString()},
4046 {"terrainraiselimit", terrainRaiseLimit.ToString()}, 4024 {"terrainraiselimit", terrainRaiseLimit.ToString()},
4047 {"terrainlowerlimit", terrainLowerLimit.ToString()}, 4025 {"terrainlowerlimit", terrainLowerLimit.ToString()},
4048 {"useestatesun", useEstateSun.ToString()}, 4026 {"useestatesun", useEstateSun.ToString()},
4049 {"fixedsun", fixedSun.ToString()}, 4027 {"fixedsun", fixedSun.ToString()},
4050 {"sunposition", sunPosition.ToString()} 4028 {"sunposition", sunPosition.ToString()}
4051 }, wasOutput), vassalConfiguration.DataTimeout); 4029 }, wasOutput)).Result);
4052   4030  
4053 if (string.IsNullOrEmpty(result)) 4031 if (string.IsNullOrEmpty(result))
4054 throw new Exception("Error communicating with Corrade"); 4032 throw new Exception("Error communicating with Corrade");
4055   4033  
4056 bool success; 4034 bool success;
4057 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success)) 4035 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
4058 throw new Exception("No success status could be retrieved"); 4036 throw new Exception("No success status could be retrieved");
4059   4037  
4060 if (!success) 4038 if (!success)
4061 throw new Exception("Unable to set region variables"); 4039 throw new Exception("Unable to set region variables");
4062 } 4040 }
4063 catch (Exception ex) 4041 catch (Exception ex)
4064 { 4042 {
4065 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); 4043 vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; }));
4066 } 4044 }
4067 finally 4045 finally
4068 { 4046 {
4069 Monitor.Exit(ClientInstanceTeleportLock); 4047 Monitor.Exit(ClientInstanceTeleportLock);
4070 } 4048 }
4071   4049  
4072 // Block teleports and disable button. 4050 // Block teleports and disable button.
4073 vassalForm.Invoke((MethodInvoker) (() => 4051 vassalForm.Invoke((MethodInvoker) (() =>
4074 { 4052 {
4075 RegionTeleportGroup.Enabled = true; 4053 RegionTeleportGroup.Enabled = true;
4076 SetTerrainVariablesButton.Enabled = true; 4054 SetTerrainVariablesButton.Enabled = true;
4077 })); 4055 }));
4078 }) 4056 })
4079 {IsBackground = true}.Start(); 4057 {IsBackground = true}.Start();
4080 } 4058 }
4081   4059  
4082 private void ReconnectRequested(object sender, EventArgs e) 4060 private void ReconnectRequested(object sender, EventArgs e)
4083 { 4061 {
4084 // Spawn a thread to check Corrade's connection status. 4062 // Spawn a thread to check Corrade's connection status.
4085 new Thread(() => 4063 new Thread(() =>
4086 { 4064 {
4087 TcpClient tcpClient = new TcpClient(); 4065 var tcpClient = new TcpClient();
4088 try 4066 try
4089 { 4067 {
4090 Uri uri = new Uri(vassalConfiguration.HTTPServerURL); 4068 var uri = new Uri(vassalConfiguration.HTTPServerURL);
4091 tcpClient.Connect(uri.Host, uri.Port); 4069 tcpClient.Connect(uri.Host, uri.Port);
4092 // port open 4070 // port open
4093 vassalForm.BeginInvoke((MethodInvoker) (() => { vassalForm.Tabs.Enabled = true; })); 4071 vassalForm.BeginInvoke((MethodInvoker) (() => { vassalForm.Tabs.Enabled = true; }));
4094 // set the loading spinner 4072 // set the loading spinner
4095 if (vassalForm.RegionAvatarsMap.Image == null) 4073 if (vassalForm.RegionAvatarsMap.Image == null)
4096 { 4074 {
4097 Assembly thisAssembly = Assembly.GetExecutingAssembly(); 4075 var thisAssembly = Assembly.GetExecutingAssembly();
4098 Stream file = 4076 var file =
4099 thisAssembly.GetManifestResourceStream("Vassal.img.loading.gif"); 4077 thisAssembly.GetManifestResourceStream("Vassal.img.loading.gif");
4100 switch (file != null) 4078 switch (file != null)
4101 { 4079 {
4102 case true: 4080 case true:
4103 vassalForm.BeginInvoke((MethodInvoker) (() => 4081 vassalForm.BeginInvoke((MethodInvoker) (() =>
4104 { 4082 {
4105 vassalForm.RegionAvatarsMap.SizeMode = PictureBoxSizeMode.CenterImage; 4083 vassalForm.RegionAvatarsMap.SizeMode = PictureBoxSizeMode.CenterImage;
4106 vassalForm.RegionAvatarsMap.Image = Image.FromStream(file); 4084 vassalForm.RegionAvatarsMap.Image = Image.FromStream(file);
4107 vassalForm.RegionAvatarsMap.Refresh(); 4085 vassalForm.RegionAvatarsMap.Refresh();
4108 })); 4086 }));
4109 break; 4087 break;
4110 } 4088 }
4111 } 4089 }
4112 } 4090 }
4113 catch (Exception) 4091 catch (Exception)
4114 { 4092 {
4115 // port closed 4093 // port closed
4116 vassalForm.BeginInvoke((MethodInvoker) (() => { vassalForm.Tabs.Enabled = false; })); 4094 vassalForm.BeginInvoke((MethodInvoker) (() => { vassalForm.Tabs.Enabled = false; }));
4117 } 4095 }
4118 }) 4096 })
4119 {IsBackground = true}.Start(); 4097 {IsBackground = true}.Start();
4120 } 4098 }
4121   4099  
4122 /// <summary> 4100 /// <summary>
4123 /// Linden constants. 4101 /// Linden constants.
4124 /// </summary> 4102 /// </summary>
4125 public struct LINDEN_CONSTANTS 4103 public struct LINDEN_CONSTANTS
4126 { 4104 {
4127 public struct ALERTS 4105 public struct ALERTS
4128 { 4106 {
4129 public const string NO_ROOM_TO_SIT_HERE = @"No room to sit here, try another spot."; 4107 public const string NO_ROOM_TO_SIT_HERE = @"No room to sit here, try another spot.";
4130   4108  
4131 public const string UNABLE_TO_SET_HOME = 4109 public const string UNABLE_TO_SET_HOME =
4132 @"You can only set your 'Home Location' on your land or at a mainland Infohub."; 4110 @"You can only set your 'Home Location' on your land or at a mainland Infohub.";
4133   4111  
4134 public const string HOME_SET = @"Home position set."; 4112 public const string HOME_SET = @"Home position set.";
4135 } 4113 }
4136   4114  
4137 public struct ASSETS 4115 public struct ASSETS
4138 { 4116 {
4139 public struct NOTECARD 4117 public struct NOTECARD
4140 { 4118 {
4141 public const string NEWLINE = "\n"; 4119 public const string NEWLINE = "\n";
4142 public const uint MAXIMUM_BODY_LENTH = 65536; 4120 public const uint MAXIMUM_BODY_LENTH = 65536;
4143 } 4121 }
4144 } 4122 }
4145   4123  
4146 public struct AVATARS 4124 public struct AVATARS
4147 { 4125 {
4148 public const uint SET_DISPLAY_NAME_SUCCESS = 200; 4126 public const uint SET_DISPLAY_NAME_SUCCESS = 200;
4149 public const string LASTNAME_PLACEHOLDER = @"Resident"; 4127 public const string LASTNAME_PLACEHOLDER = @"Resident";
4150 public const uint MAXIMUM_DISPLAY_NAME_CHARACTERS = 31; 4128 public const uint MAXIMUM_DISPLAY_NAME_CHARACTERS = 31;
4151 public const uint MINIMUM_DISPLAY_NAME_CHARACTERS = 1; 4129 public const uint MINIMUM_DISPLAY_NAME_CHARACTERS = 1;
4152 public const uint MAXIMUM_NUMBER_OF_ATTACHMENTS = 38; 4130 public const uint MAXIMUM_NUMBER_OF_ATTACHMENTS = 38;
4153   4131  
4154 public struct PROFILE 4132 public struct PROFILE
4155 { 4133 {
4156 public const uint SECOND_LIFE_TEXT_SIZE = 510; 4134 public const uint SECOND_LIFE_TEXT_SIZE = 510;
4157 public const uint FIRST_LIFE_TEXT_SIZE = 253; 4135 public const uint FIRST_LIFE_TEXT_SIZE = 253;
4158 } 4136 }
4159   4137  
4160 public struct PICKS 4138 public struct PICKS
4161 { 4139 {
4162 public const uint MAXIMUM_PICKS = 10; 4140 public const uint MAXIMUM_PICKS = 10;
4163 public const uint MAXIMUM_PICK_DESCRIPTION_SIZE = 1022; 4141 public const uint MAXIMUM_PICK_DESCRIPTION_SIZE = 1022;
4164 } 4142 }
4165   4143  
4166 public struct CLASSIFIEDS 4144 public struct CLASSIFIEDS
4167 { 4145 {
4168 public const uint MAXIMUM_CLASSIFIEDS = 100; 4146 public const uint MAXIMUM_CLASSIFIEDS = 100;
4169 } 4147 }
4170 } 4148 }
4171   4149  
4172 public struct PRIMITIVES 4150 public struct PRIMITIVES
4173 { 4151 {
4174 public const uint MAXIMUM_NAME_SIZE = 63; 4152 public const uint MAXIMUM_NAME_SIZE = 63;
4175 public const uint MAXIMUM_DESCRIPTION_SIZE = 127; 4153 public const uint MAXIMUM_DESCRIPTION_SIZE = 127;
4176 public const double MAXIMUM_REZ_HEIGHT = 4096.0; 4154 public const double MAXIMUM_REZ_HEIGHT = 4096.0;
4177 public const double MINIMUM_SIZE_X = 0.01; 4155 public const double MINIMUM_SIZE_X = 0.01;
4178 public const double MINIMUM_SIZE_Y = 0.01; 4156 public const double MINIMUM_SIZE_Y = 0.01;
4179 public const double MINIMUM_SIZE_Z = 0.01; 4157 public const double MINIMUM_SIZE_Z = 0.01;
4180 public const double MAXIMUM_SIZE_X = 64.0; 4158 public const double MAXIMUM_SIZE_X = 64.0;
4181 public const double MAXIMUM_SIZE_Y = 64.0; 4159 public const double MAXIMUM_SIZE_Y = 64.0;
4182 public const double MAXIMUM_SIZE_Z = 64.0; 4160 public const double MAXIMUM_SIZE_Z = 64.0;
4183 } 4161 }
4184   4162  
4185 public struct OBJECTS 4163 public struct OBJECTS
4186 { 4164 {
4187 public const uint MAXIMUM_PRIMITIVE_COUNT = 256; 4165 public const uint MAXIMUM_PRIMITIVE_COUNT = 256;
4188 } 4166 }
4189   4167  
4190 public struct DIRECTORY 4168 public struct DIRECTORY
4191 { 4169 {
4192 public struct EVENT 4170 public struct EVENT
4193 { 4171 {
4194 public const uint SEARCH_RESULTS_COUNT = 200; 4172 public const uint SEARCH_RESULTS_COUNT = 200;
4195 } 4173 }
4196   4174  
4197 public struct GROUP 4175 public struct GROUP
4198 { 4176 {
4199 public const uint SEARCH_RESULTS_COUNT = 100; 4177 public const uint SEARCH_RESULTS_COUNT = 100;
4200 } 4178 }
4201   4179  
4202 public struct LAND 4180 public struct LAND
4203 { 4181 {
4204 public const uint SEARCH_RESULTS_COUNT = 100; 4182 public const uint SEARCH_RESULTS_COUNT = 100;
4205 } 4183 }
4206   4184  
4207 public struct PEOPLE 4185 public struct PEOPLE
4208 { 4186 {
4209 public const uint SEARCH_RESULTS_COUNT = 100; 4187 public const uint SEARCH_RESULTS_COUNT = 100;
4210 } 4188 }
4211 } 4189 }
4212   4190  
4213 public struct ESTATE 4191 public struct ESTATE
4214 { 4192 {
4215 public const uint REGION_RESTART_DELAY = 120; 4193 public const uint REGION_RESTART_DELAY = 120;
4216 public const uint MAXIMUM_BAN_LIST_LENGTH = 500; 4194 public const uint MAXIMUM_BAN_LIST_LENGTH = 500;
4217 public const uint MAXIMUM_GROUP_LIST_LENGTH = 63; 4195 public const uint MAXIMUM_GROUP_LIST_LENGTH = 63;
4218 public const uint MAXIMUM_USER_LIST_LENGTH = 500; 4196 public const uint MAXIMUM_USER_LIST_LENGTH = 500;
4219 public const uint MAXIMUM_MANAGER_LIST_LENGTH = 10; 4197 public const uint MAXIMUM_MANAGER_LIST_LENGTH = 10;
4220   4198  
4221 public struct MESSAGES 4199 public struct MESSAGES
4222 { 4200 {
4223 public const string REGION_RESTART_MESSAGE = @"restart"; 4201 public const string REGION_RESTART_MESSAGE = @"restart";
4224 } 4202 }
4225 } 4203 }
4226   4204  
4227 public struct PARCELS 4205 public struct PARCELS
4228 { 4206 {
4229 public const double MAXIMUM_AUTO_RETURN_TIME = 999999; 4207 public const double MAXIMUM_AUTO_RETURN_TIME = 999999;
4230 public const uint MINIMUM_AUTO_RETURN_TIME = 0; 4208 public const uint MINIMUM_AUTO_RETURN_TIME = 0;
4231 public const uint MAXIMUM_NAME_LENGTH = 63; 4209 public const uint MAXIMUM_NAME_LENGTH = 63;
4232 public const uint MAXIMUM_DESCRIPTION_LENGTH = 255; 4210 public const uint MAXIMUM_DESCRIPTION_LENGTH = 255;
4233 } 4211 }
4234   4212  
4235 public struct GRID 4213 public struct GRID
4236 { 4214 {
4237 public const string SECOND_LIFE = @"Second Life"; 4215 public const string SECOND_LIFE = @"Second Life";
4238 public const string TIME_ZONE = @"Pacific Standard Time"; 4216 public const string TIME_ZONE = @"Pacific Standard Time";
4239 } 4217 }
4240   4218  
4241 public struct CHAT 4219 public struct CHAT
4242 { 4220 {
4243 public const uint MAXIMUM_MESSAGE_LENGTH = 1024; 4221 public const uint MAXIMUM_MESSAGE_LENGTH = 1024;
4244 } 4222 }
4245   4223  
4246 public struct GROUPS 4224 public struct GROUPS
4247 { 4225 {
4248 public const uint MAXIMUM_NUMBER_OF_ROLES = 10; 4226 public const uint MAXIMUM_NUMBER_OF_ROLES = 10;
4249 public const string EVERYONE_ROLE_NAME = @"Everyone"; 4227 public const string EVERYONE_ROLE_NAME = @"Everyone";
4250 public const uint MAXIMUM_GROUP_NAME_LENGTH = 35; 4228 public const uint MAXIMUM_GROUP_NAME_LENGTH = 35;
4251 public const uint MAXIMUM_GROUP_TITLE_LENGTH = 20; 4229 public const uint MAXIMUM_GROUP_TITLE_LENGTH = 20;
4252 } 4230 }
4253   4231  
4254 public struct NOTICES 4232 public struct NOTICES
4255 { 4233 {
4256 public const uint MAXIMUM_NOTICE_MESSAGE_LENGTH = 512; 4234 public const uint MAXIMUM_NOTICE_MESSAGE_LENGTH = 512;
4257 } 4235 }
4258   4236  
4259 public struct LSL 4237 public struct LSL
4260 { 4238 {
4261 public const string CSV_DELIMITER = @", "; 4239 public const string CSV_DELIMITER = @", ";
4262 public const float SENSOR_RANGE = 96; 4240 public const float SENSOR_RANGE = 96;
4263 public const string DATE_TIME_STAMP = @"yyy-MM-ddTHH:mm:ss.ffffffZ"; 4241 public const string DATE_TIME_STAMP = @"yyy-MM-ddTHH:mm:ss.ffffffZ";
4264 } 4242 }
4265   4243  
4266 public struct REGION 4244 public struct REGION
4267 { 4245 {
4268 public const float TELEPORT_MINIMUM_DISTANCE = 1; 4246 public const float TELEPORT_MINIMUM_DISTANCE = 1;
4269 public const float DEFAULT_AGENT_LIMIT = 40; 4247 public const float DEFAULT_AGENT_LIMIT = 40;
4270 public const float DEFAULT_OBJECT_BONUS = 1; 4248 public const float DEFAULT_OBJECT_BONUS = 1;
4271 public const bool DEFAULT_FIXED_SUN = false; 4249 public const bool DEFAULT_FIXED_SUN = false;
4272 public const float DEFAULT_TERRAIN_LOWER_LIMIT = -4; 4250 public const float DEFAULT_TERRAIN_LOWER_LIMIT = -4;
4273 public const float DEFAULT_TERRAIN_RAISE_LIMIT = 4; 4251 public const float DEFAULT_TERRAIN_RAISE_LIMIT = 4;
4274 public const bool DEFAULT_USE_ESTATE_SUN = true; 4252 public const bool DEFAULT_USE_ESTATE_SUN = true;
4275 public const float DEFAULT_WATER_HEIGHT = 20; 4253 public const float DEFAULT_WATER_HEIGHT = 20;
4276 public const float SUNRISE = 6; 4254 public const float SUNRISE = 6;
4277 } 4255 }
4278   4256  
4279 public struct VIEWER 4257 public struct VIEWER
4280 { 4258 {
4281 public const float MAXIMUM_DRAW_DISTANCE = 4096; 4259 public const float MAXIMUM_DRAW_DISTANCE = 4096;
4282 } 4260 }
4283   4261  
4284 public struct TELEPORTS 4262 public struct TELEPORTS
4285 { 4263 {
4286 public struct THROTTLE 4264 public struct THROTTLE
4287 { 4265 {
4288 public const uint MAX_TELEPORTS = 10; 4266 public const uint MAX_TELEPORTS = 10;
4289 public const uint GRACE_SECONDS = 15; 4267 public const uint GRACE_SECONDS = 15;
4290 } 4268 }
4291 } 4269 }
4292 } 4270 }
4293   4271  
4294 /// <summary> 4272 /// <summary>
4295 /// Constants used by Corrade. 4273 /// Constants used by Corrade.
4296 /// </summary> 4274 /// </summary>
4297 public struct VASSAL_CONSTANTS 4275 public struct VASSAL_CONSTANTS
4298 { 4276 {
4299 /// <summary> 4277 /// <summary>
4300 /// Copyright. 4278 /// Copyright.
4301 /// </summary> 4279 /// </summary>
4302 public const string COPYRIGHT = @"(c) Copyright 2013 Wizardry and Steamworks"; 4280 public const string COPYRIGHT = @"(c) Copyright 2013 Wizardry and Steamworks";
4303   4281  
4304 public const string WIZARDRY_AND_STEAMWORKS = @"Wizardry and Steamworks"; 4282 public const string WIZARDRY_AND_STEAMWORKS = @"Wizardry and Steamworks";
4305 public const string VASSAL = @"Vassal"; 4283 public const string VASSAL = @"Vassal";
4306 public const string WIZARDRY_AND_STEAMWORKS_WEBSITE = @"http://grimore.org"; 4284 public const string WIZARDRY_AND_STEAMWORKS_WEBSITE = @"http://grimore.org";
4307   4285  
4308 /// <summary> 4286 /// <summary>
4309 /// Vassal version. 4287 /// Vassal version.
4310 /// </summary> 4288 /// </summary>
4311 public static readonly string VASSAL_VERSION = Assembly.GetEntryAssembly().GetName().Version.ToString(); 4289 public static readonly string VASSAL_VERSION = Assembly.GetEntryAssembly().GetName().Version.ToString();
4312   4290  
4313 /// <summary> 4291 /// <summary>
4314 /// Corrade user agent. 4292 /// Corrade user agent.
4315 /// </summary> 4293 /// </summary>
4316 public static readonly string USER_AGENT = 4294 public static readonly string USER_AGENT =
4317 $"{VASSAL}/{VASSAL_VERSION} ({WIZARDRY_AND_STEAMWORKS_WEBSITE})"; 4295 $"{VASSAL}/{VASSAL_VERSION} ({WIZARDRY_AND_STEAMWORKS_WEBSITE})";
4318   4296  
4319 /// <summary> 4297 /// <summary>
4320 /// Vassal compile date. 4298 /// Vassal compile date.
4321 /// </summary> 4299 /// </summary>
4322 public static readonly string VASSAL_COMPILE_DATE = new DateTime(2000, 1, 1).Add(new TimeSpan( 4300 public static readonly string VASSAL_COMPILE_DATE = new DateTime(2000, 1, 1).Add(new TimeSpan(
4323 TimeSpan.TicksPerDay*Assembly.GetEntryAssembly().GetName().Version.Build + // days since 1 January 2000 4301 TimeSpan.TicksPerDay*Assembly.GetEntryAssembly().GetName().Version.Build + // days since 1 January 2000
4324 TimeSpan.TicksPerSecond*2*Assembly.GetEntryAssembly().GetName().Version.Revision)).ToLongDateString(); 4302 TimeSpan.TicksPerSecond*2*Assembly.GetEntryAssembly().GetName().Version.Revision)).ToLongDateString();
4325   4303  
4326 /// <summary> 4304 /// <summary>
4327 /// Vassal configuration file. 4305 /// Vassal configuration file.
4328 /// </summary> 4306 /// </summary>
4329 public static readonly string VASSAL_CONFIGURATION_FILE = @"Vassal.ini"; 4307 public static readonly string VASSAL_CONFIGURATION_FILE = @"Vassal.ini";
4330   4308  
4331 /// <summary> 4309 /// <summary>
4332 /// Vassal regions file. 4310 /// Vassal regions file.
4333 /// </summary> 4311 /// </summary>
4334 public static readonly string VASSAL_REGIONS = @"Regions.csv"; 4312 public static readonly string VASSAL_REGIONS = @"Regions.csv";
4335   4313  
4336 /// <summary> 4314 /// <summary>
4337 /// Conten-types that Corrade can send and receive. 4315 /// Conten-types that Corrade can send and receive.
4338 /// </summary> 4316 /// </summary>
4339 public struct CONTENT_TYPE 4317 public struct CONTENT_TYPE
4340 { 4318 {
4341 public const string TEXT_PLAIN = @"text/plain"; 4319 public const string TEXT_PLAIN = @"text/plain";
4342 public const string WWW_FORM_URLENCODED = @"application/x-www-form-urlencoded"; 4320 public const string WWW_FORM_URLENCODED = @"application/x-www-form-urlencoded";
4343 } 4321 }
4344 } 4322 }
-   4323  
-   4324 private void RequestBatchSetCovenant(object sender, EventArgs e)
-   4325 {
-   4326 // Block teleports and disable button.
-   4327 vassalForm.Invoke((MethodInvoker)(() =>
-   4328 {
-   4329 vassalForm.BatchSetCovenantButton.Enabled = false;
-   4330 vassalForm.SetCovenantNotecardUUIDBox.Enabled = false;
-   4331 RegionTeleportGroup.Enabled = false;
-   4332 }));
-   4333  
-   4334 // Enqueue all the regions to set covenant.
-   4335 var batchSetCovenantQueue = new Queue<KeyValuePair<string, Vector3>>();
-   4336 vassalForm.Invoke((MethodInvoker)(() =>
-   4337 {
-   4338 foreach (
-   4339 var topCollidersRow in
-   4340 BatchSetCovenantGridView.Rows.AsParallel()
-   4341 .Cast<DataGridViewRow>()
-   4342 .Where(o => o.Selected || o.Cells.Cast<DataGridViewCell>().Any(p => p.Selected)))
-   4343 {
-   4344 Vector3 objectPosition;
-   4345 var regionName = topCollidersRow.Cells["BatchSetCovenantRegionName"].Value.ToString();
-   4346 if (string.IsNullOrEmpty(regionName) ||
-   4347 !Vector3.TryParse(topCollidersRow.Cells["BatchSetCovenantPosition"].Value.ToString(),
-   4348 out objectPosition))
-   4349 continue;
-   4350 batchSetCovenantQueue.Enqueue(new KeyValuePair<string, Vector3>(regionName, objectPosition));
-   4351 }
-   4352 }));
-   4353  
-   4354 // If no rows were selected, enable teleports, the return button and return.
-   4355 if (batchSetCovenantQueue.Count.Equals(0))
-   4356 {
-   4357 vassalForm.Invoke((MethodInvoker)(() =>
-   4358 {
-   4359 vassalForm.BatchSetCovenantButton.Enabled = true;
-   4360 vassalForm.SetCovenantNotecardUUIDBox.Enabled = true;
-   4361 RegionTeleportGroup.Enabled = true;
-   4362 }));
-   4363 return;
-   4364 }
-   4365  
-   4366 new Thread(() =>
-   4367 {
-   4368 Monitor.Enter(ClientInstanceTeleportLock);
-   4369  
-   4370 try
-   4371 {
-   4372 do
-   4373 {
-   4374 // Dequeue the first object.
-   4375 var batchSetCovenantRegionData = batchSetCovenantQueue.Dequeue();
-   4376 DataGridViewRow currentDataGridViewRow = null;
-   4377 vassalForm.Invoke((MethodInvoker)(() =>
-   4378 {
-   4379 currentDataGridViewRow = vassalForm.BatchSetCovenantGridView.Rows.AsParallel()
-   4380 .Cast<DataGridViewRow>()
-   4381 .FirstOrDefault(
-   4382 o =>
-   4383 o.Cells["BatchSetCovenantRegionName"].Value.ToString()
-   4384 .Equals(batchSetCovenantRegionData.Key, StringComparison.OrdinalIgnoreCase) &&
-   4385 o.Cells["BatchSetCovenantPosition"].Value.ToString()
-   4386 .Equals(batchSetCovenantRegionData.Value.ToString(),
4345   4387 StringComparison.OrdinalIgnoreCase));
-   4388 }));
-   4389  
-   4390 if (currentDataGridViewRow == null) continue;
-   4391  
-   4392 try
-   4393 {
-   4394 var success = false;
-   4395 string result;
-   4396  
-   4397 // Retry to teleport to each region a few times.
-   4398 var teleportRetries = 3;
-   4399 do
-   4400 {
-   4401 vassalForm.Invoke((MethodInvoker)(() =>
-   4402 {
-   4403 vassalForm.StatusText.Text = @"Attempting to teleport to " + batchSetCovenantRegionData.Key +
-   4404 @" " + @"(" +
-   4405 teleportRetries.ToString(Utils.EnUsCulture) +
-   4406 @")";
-   4407 }));
-   4408  
-   4409 // Teleport to the region.
-   4410 result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
-   4411 KeyValue.Escape(new Dictionary<string, string>
-   4412 {
-   4413 {"command", "teleport"},
-   4414 {"group", vassalConfiguration.Group},
-   4415 {"password", vassalConfiguration.Password},
-   4416 {"position", batchSetCovenantRegionData.Value.ToString()},
-   4417 {"region", batchSetCovenantRegionData.Key},
-   4418 {"fly", "True"}
-   4419 }, wasOutput)).Result);
-   4420  
-   4421 if (string.IsNullOrEmpty(result))
-   4422 {
-   4423 vassalForm.Invoke(
-   4424 (MethodInvoker)
-   4425 (() =>
-   4426 {
-   4427 vassalForm.StatusText.Text = @"Error communicating with Corrade.";
-   4428 }));
-   4429 continue;
-   4430 }
-   4431 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
-   4432 {
-   4433 vassalForm.Invoke(
-   4434 (MethodInvoker)
-   4435 (() =>
-   4436 {
-   4437 vassalForm.StatusText.Text = @"No success status could be retrieved. ";
-   4438 }));
-   4439 continue;
-   4440 }
-   4441 switch (success)
-   4442 {
-   4443 case true:
-   4444 vassalForm.Invoke(
-   4445 (MethodInvoker)
-   4446 (() => { vassalForm.StatusText.Text = @"Teleport succeeded."; }));
-   4447 break;
-   4448 default:
-   4449 // In case the destination is to close (Corrade status code 37559),
-   4450 // then we are on the same region so no need to retry.
-   4451 uint status; //37559
-   4452 switch (
-   4453 uint.TryParse(wasInput(KeyValue.Get("status", result)), out status) &&
-   4454 status.Equals(37559))
-   4455 {
-   4456 case true: // We are on the region already!
-   4457 success = true;
-   4458 break;
-   4459 default:
-   4460 vassalForm.Invoke(
-   4461 (MethodInvoker)
-   4462 (() => { vassalForm.StatusText.Text = @"Teleport failed."; }));
-   4463 break;
-   4464 }
-   4465 break;
-   4466 }
-   4467  
-   4468 // Pause for teleport (10 teleports / 15s allowed).
-   4469 Thread.Sleep(700);
-   4470 } while (!success && !(--teleportRetries).Equals(0));
-   4471  
-   4472 if (!success)
-   4473 throw new Exception("Failed to teleport to region.");
-   4474  
-   4475 result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
-   4476 KeyValue.Escape(new Dictionary<string, string>
-   4477 {
-   4478 {"command", "getregiondata"},
-   4479 {"group", vassalConfiguration.Group},
-   4480 {"password", vassalConfiguration.Password},
-   4481 {"data", "IsEstateManager"}
-   4482 }, wasOutput)).Result);
-   4483  
-   4484 if (string.IsNullOrEmpty(result))
-   4485 throw new Exception("Error communicating with Corrade.");
-   4486  
-   4487 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
-   4488 throw new Exception("No success status could be retrieved.");
-   4489  
-   4490 if (!success)
-   4491 throw new Exception("Could not retrieve estate rights.");
-   4492  
-   4493 var data = CSV.ToEnumerable(wasInput(KeyValue.Get("data", result))).ToList();
-   4494 if (!data.Count.Equals(2))
-   4495 throw new Exception("Could not retrieve estate rights.");
-   4496  
-   4497 bool isEstateManager;
-   4498 switch (
-   4499 bool.TryParse(data[data.IndexOf("IsEstateManager") + 1], out isEstateManager) &&
-   4500 isEstateManager)
-   4501 {
-   4502 case true: // we are an estate manager
-   4503 result = Encoding.UTF8.GetString(HTTPClient.POST(vassalConfiguration.HTTPServerURL,
-   4504 KeyValue.Escape(new Dictionary<string, string>
-   4505 {
-   4506 {"command", "setestatecovenant"},
-   4507 {"group", vassalConfiguration.Group},
-   4508 {"password", vassalConfiguration.Password},
-   4509 {"item", vassalForm.SetCovenantNotecardUUIDBox.Text}
-   4510 }, wasOutput)).Result);
-   4511  
-   4512 if (string.IsNullOrEmpty(result))
-   4513 throw new Exception("Error communicating with Corrade.");
-   4514  
-   4515 if (!bool.TryParse(wasInput(KeyValue.Get("success", result)), out success))
-   4516 throw new Exception("No success status could be retrieved.");
-   4517  
-   4518 if (!success)
-   4519 throw new Exception("Could not set region covenant.");
-   4520  
-   4521 vassalForm.Invoke((MethodInvoker)(() =>
-   4522 {
-   4523 vassalForm.StatusText.Text = @"Region covenant set.";
-   4524 currentDataGridViewRow.Selected = false;
-   4525 currentDataGridViewRow.DefaultCellStyle.BackColor = Color.LightGreen;
-   4526 foreach (
-   4527 var cell in
-   4528 currentDataGridViewRow.Cells.AsParallel().Cast<DataGridViewCell>())
-   4529 {
-   4530 cell.ToolTipText = @"Region covenant set.";
-   4531 }
-   4532 }));
-   4533 break;
-   4534 default:
-   4535 throw new Exception("No estate manager rights for setting covenant.");
-   4536 }
-   4537 }
-   4538 catch (Exception ex)
-   4539 {
-   4540 vassalForm.Invoke((MethodInvoker)(() =>
-   4541 {
-   4542 vassalForm.StatusText.Text = ex.Message;
-   4543 currentDataGridViewRow.Selected = false;
-   4544 currentDataGridViewRow.DefaultCellStyle.BackColor = Color.LightPink;
-   4545 foreach (
-   4546 var cell in
-   4547 currentDataGridViewRow.Cells.AsParallel().Cast<DataGridViewCell>())
-   4548 {
-   4549 cell.ToolTipText = ex.Message;
-   4550 }
-   4551 }));
-   4552 }
-   4553 finally
-   4554 {
-   4555 // Pause for teleport (10 teleports / 15s allowed).
-   4556 Thread.Sleep(700);
-   4557 }
-   4558 } while (!batchSetCovenantQueue.Count.Equals(0));
-   4559 }
-   4560 catch (Exception)
-   4561 {
-   4562 }
-   4563 finally
-   4564 {
-   4565 Monitor.Exit(ClientInstanceTeleportLock);
-   4566 // Allow teleports and enable button.
-   4567 vassalForm.BeginInvoke((MethodInvoker)(() =>
-   4568 {
-   4569 vassalForm.BatchSetCovenantButton.Enabled = true;
-   4570 vassalForm.SetCovenantNotecardUUIDBox.Enabled = true;
4346 #region CRYPTOGRAPHY 4571 RegionTeleportGroup.Enabled = true;
-   4572 }));
-   4573 }
-   4574 })
4347   4575 { IsBackground = true }.Start();
4348 #endregion 4576 }
4349 } 4577 }
4350 } 4578 }
4351   4579  
4352
Generated by GNU Enscript 1.6.5.90.
4580
Generated by GNU Enscript 1.6.5.90.
4353   4581  
4354   4582  
4355   4583