corrade-vassal – Diff between revs 7 and 8

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