/Vassal/Vassal/VassalForm.cs |
@@ -5,10 +5,7 @@ |
/////////////////////////////////////////////////////////////////////////// |
|
using System; |
using System.Collections; |
using System.Collections.Generic; |
using System.ComponentModel; |
using System.Data; |
using System.Drawing; |
using System.Drawing.Imaging; |
using System.IO; |
@@ -18,7 +15,6 @@ |
using System.Reflection; |
using System.Text; |
using System.Text.RegularExpressions; |
using System.Timers; |
using System.Threading; |
using System.Web; |
using System.Windows.Forms; |
@@ -30,12 +26,14 @@ |
{ |
public partial class Vassal : Form |
{ |
public static System.Timers.Timer overviewTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); |
public static System.Timers.Timer residentListTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); |
public static System.Timers.Timer topScriptsTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); |
public static System.Timers.Timer topCollidersTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); |
public static System.Timers.Timer regionsStateTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); |
public static volatile int regionsStateCheckIndex = 0; |
public static Timer vassalTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); |
public static Timer overviewTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); |
public static Timer residentListTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); |
public static Timer estateTopTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); |
public static Timer regionsStateTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); |
public static Timer estateTexturesTabTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); |
public static Image[] groundTextureImages = new Image[4]; |
public static volatile int regionsStateCheckIndex; |
public static VassalConfiguration vassalConfiguration = new VassalConfiguration(); |
public static Vassal vassalForm; |
public static readonly object ClientInstanceTeleportLock = new object(); |
@@ -42,175 +40,135 @@ |
public static readonly object RegionsStateCheckLock = new object(); |
|
/// <summary> |
/// Linden constants. |
/// Corrade's input filter function. |
/// </summary> |
public struct LINDEN_CONSTANTS |
private static readonly Func<string, string> wasInput = o => |
{ |
public struct ALERTS |
{ |
public const string NO_ROOM_TO_SIT_HERE = @"No room to sit here, try another spot."; |
if (string.IsNullOrEmpty(o)) return string.Empty; |
|
public const string UNABLE_TO_SET_HOME = |
@"You can only set your 'Home Location' on your land or at a mainland Infohub."; |
|
public const string HOME_SET = @"Home position set."; |
} |
|
public struct ASSETS |
foreach (Filter filter in vassalConfiguration.InputFilters) |
{ |
public struct NOTECARD |
switch (filter) |
{ |
public const string NEWLINE = "\n"; |
public const uint MAXIMUM_BODY_LENTH = 65536; |
case Filter.RFC1738: |
o = wasURLUnescapeDataString(o); |
break; |
case Filter.RFC3986: |
o = wasURIUnescapeDataString(o); |
break; |
case Filter.ENIGMA: |
o = wasEnigma(o, vassalConfiguration.ENIGMA.rotors.ToArray(), |
vassalConfiguration.ENIGMA.plugs.ToArray(), |
vassalConfiguration.ENIGMA.reflector); |
break; |
case Filter.VIGENERE: |
o = wasDecryptVIGENERE(o, vassalConfiguration.VIGENERESecret); |
break; |
case Filter.ATBASH: |
o = wasATBASH(o); |
break; |
case Filter.BASE64: |
o = Encoding.UTF8.GetString(Convert.FromBase64String(o)); |
break; |
} |
} |
return o; |
}; |
|
public struct AVATARS |
/// <summary> |
/// Corrade's output filter function. |
/// </summary> |
private static readonly Func<string, string> wasOutput = o => |
{ |
if (string.IsNullOrEmpty(o)) return string.Empty; |
|
foreach (Filter filter in vassalConfiguration.OutputFilters) |
{ |
public const uint SET_DISPLAY_NAME_SUCCESS = 200; |
public const string LASTNAME_PLACEHOLDER = @"Resident"; |
public const uint MAXIMUM_DISPLAY_NAME_CHARACTERS = 31; |
public const uint MINIMUM_DISPLAY_NAME_CHARACTERS = 1; |
public const uint MAXIMUM_NUMBER_OF_ATTACHMENTS = 38; |
|
public struct PROFILE |
switch (filter) |
{ |
public const uint SECOND_LIFE_TEXT_SIZE = 510; |
public const uint FIRST_LIFE_TEXT_SIZE = 253; |
case Filter.RFC1738: |
o = wasURLEscapeDataString(o); |
break; |
case Filter.RFC3986: |
o = wasURIEscapeDataString(o); |
break; |
case Filter.ENIGMA: |
o = wasEnigma(o, vassalConfiguration.ENIGMA.rotors.ToArray(), |
vassalConfiguration.ENIGMA.plugs.ToArray(), |
vassalConfiguration.ENIGMA.reflector); |
break; |
case Filter.VIGENERE: |
o = wasEncryptVIGENERE(o, vassalConfiguration.VIGENERESecret); |
break; |
case Filter.ATBASH: |
o = wasATBASH(o); |
break; |
case Filter.BASE64: |
o = Convert.ToBase64String(Encoding.UTF8.GetBytes(o)); |
break; |
} |
|
public struct PICKS |
{ |
public const uint MAXIMUM_PICKS = 10; |
public const uint MAXIMUM_PICK_DESCRIPTION_SIZE = 1022; |
} |
|
public struct CLASSIFIEDS |
{ |
public const uint MAXIMUM_CLASSIFIEDS = 100; |
} |
} |
return o; |
}; |
|
public struct PRIMITIVES |
private static readonly Action updateCurrentRegionName = () => |
{ |
try |
{ |
public const uint MAXIMUM_NAME_SIZE = 63; |
public const uint MAXIMUM_DESCRIPTION_SIZE = 127; |
public const double MAXIMUM_REZ_HEIGHT = 4096.0; |
public const double MINIMUM_SIZE_X = 0.01; |
public const double MINIMUM_SIZE_Y = 0.01; |
public const double MINIMUM_SIZE_Z = 0.01; |
public const double MAXIMUM_SIZE_X = 64.0; |
public const double MAXIMUM_SIZE_Y = 64.0; |
public const double MAXIMUM_SIZE_Z = 64.0; |
} |
|
public struct OBJECTS |
{ |
public const uint MAXIMUM_PRIMITIVE_COUNT = 256; |
} |
|
public struct DIRECTORY |
{ |
public struct EVENT |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "getregiondata"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"data", "Name"} |
}), 60000); |
bool success; |
if (string.IsNullOrEmpty(result) || |
!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
{ |
public const uint SEARCH_RESULTS_COUNT = 200; |
vassalForm.BeginInvoke( |
(MethodInvoker) |
(() => { vassalForm.StatusText.Text = @"Failed to query Corrade for current region."; })); |
return; |
} |
|
public struct GROUP |
switch (success) |
{ |
public const uint SEARCH_RESULTS_COUNT = 100; |
case true: |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
vassalForm.CurrentRegionAt.Visible = true; |
vassalForm.CurrentRegionName.Visible = true; |
vassalForm.CurrentRegionName.Text = |
wasCSVToEnumerable(wasInput(wasKeyValueGet("data", result))).Last(); |
})); |
break; |
default: |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
vassalForm.CurrentRegionAt.Visible = false; |
vassalForm.CurrentRegionName.Visible = false; |
vassalForm.StatusText.Text = @"Error getting current region: " + |
wasInput(wasKeyValueGet("error", result)); |
})); |
break; |
} |
|
public struct LAND |
{ |
public const uint SEARCH_RESULTS_COUNT = 100; |
} |
|
public struct PEOPLE |
{ |
public const uint SEARCH_RESULTS_COUNT = 100; |
} |
} |
|
public struct ESTATE |
catch (Exception ex) |
{ |
public const uint REGION_RESTART_DELAY = 120; |
public const uint MAXIMUM_BAN_LIST_LENGTH = 500; |
public const uint MAXIMUM_GROUP_LIST_LENGTH = 63; |
public const uint MAXIMUM_USER_LIST_LENGTH = 500; |
public const uint MAXIMUM_MANAGER_LIST_LENGTH = 10; |
|
public struct MESSAGES |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
public const string REGION_RESTART_MESSAGE = @"restart"; |
} |
vassalForm.StatusText.Text = |
@"Error getting current region: " + |
ex.Message; |
})); |
} |
}; |
|
public struct PARCELS |
{ |
public const double MAXIMUM_AUTO_RETURN_TIME = 999999; |
public const uint MINIMUM_AUTO_RETURN_TIME = 0; |
public const uint MAXIMUM_NAME_LENGTH = 63; |
public const uint MAXIMUM_DESCRIPTION_LENGTH = 255; |
} |
|
public struct GRID |
{ |
public const string SECOND_LIFE = @"Second Life"; |
public const string TIME_ZONE = @"Pacific Standard Time"; |
} |
|
public struct CHAT |
{ |
public const uint MAXIMUM_MESSAGE_LENGTH = 1024; |
} |
|
public struct GROUPS |
{ |
public const uint MAXIMUM_NUMBER_OF_ROLES = 10; |
public const string EVERYONE_ROLE_NAME = @"Everyone"; |
public const uint MAXIMUM_GROUP_NAME_LENGTH = 35; |
public const uint MAXIMUM_GROUP_TITLE_LENGTH = 20; |
} |
|
public struct NOTICES |
{ |
public const uint MAXIMUM_NOTICE_MESSAGE_LENGTH = 512; |
} |
|
public struct LSL |
{ |
public const string CSV_DELIMITER = @", "; |
public const float SENSOR_RANGE = 96; |
public const string DATE_TIME_STAMP = @"yyy-MM-ddTHH:mm:ss.ffffffZ"; |
} |
|
public struct REGION |
{ |
public const float TELEPORT_MINIMUM_DISTANCE = 1; |
public const float DEFAULT_AGENT_LIMIT = 40; |
public const float DEFAULT_OBJECT_BONUS = 1; |
public const bool DEFAULT_FIXED_SUN = false; |
public const float DEFAULT_TERRAIN_LOWER_LIMIT = -4; |
public const float DEFAULT_TERRAIN_RAISE_LIMIT = 4; |
public const bool DEFAULT_USE_ESTATE_SUN = true; |
public const float DEFAULT_WATER_HEIGHT = 20; |
public const float SUNRISE = 6; |
} |
|
public struct VIEWER |
{ |
public const float MAXIMUM_DRAW_DISTANCE = 4096; |
} |
|
public struct TELEPORTS |
{ |
public struct THROTTLE |
{ |
public const uint MAX_TELEPORTS = 10; |
public const uint GRACE_SECONDS = 15; |
} |
} |
public Vassal() |
{ |
InitializeComponent(); |
vassalForm = this; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
@@ -333,566 +291,7 @@ |
|
#endregion |
|
#region CRYPTOGRAPHY |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Gets a sub-array from an array. |
/// </summary> |
/// <typeparam name="T">the array type</typeparam> |
/// <param name="data">the array</param> |
/// <param name="start">the start index</param> |
/// <param name="stop">the stop index (-1 denotes the end)</param> |
/// <returns>the array slice between start and stop</returns> |
public static T[] wasGetSubArray<T>(T[] data, int start, int stop) |
{ |
if (stop.Equals(-1)) |
stop = data.Length - 1; |
T[] result = new T[stop - start + 1]; |
Array.Copy(data, start, result, 0, stop - start + 1); |
return result; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Delete a sub-array and return the result. |
/// </summary> |
/// <typeparam name="T">the array type</typeparam> |
/// <param name="data">the array</param> |
/// <param name="start">the start index</param> |
/// <param name="stop">the stop index (-1 denotes the end)</param> |
/// <returns>the array without elements between start and stop</returns> |
public static T[] wasDeleteSubArray<T>(T[] data, int start, int stop) |
{ |
if (stop.Equals(-1)) |
stop = data.Length - 1; |
T[] result = new T[data.Length - (stop - start) - 1]; |
Array.Copy(data, 0, result, 0, start); |
Array.Copy(data, stop + 1, result, start, data.Length - stop - 1); |
return result; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Concatenate multiple arrays. |
/// </summary> |
/// <typeparam name="T">the array type</typeparam> |
/// <param name="arrays">multiple arrays</param> |
/// <returns>a flat array with all arrays concatenated</returns> |
public static T[] wasConcatenateArrays<T>(params T[][] arrays) |
{ |
int resultLength = 0; |
foreach (T[] o in arrays) |
{ |
resultLength += o.Length; |
} |
T[] result = new T[resultLength]; |
int offset = 0; |
for (int x = 0; x < arrays.Length; x++) |
{ |
arrays[x].CopyTo(result, offset); |
offset += arrays[x].Length; |
} |
return result; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Permutes an array in reverse a given number of times. |
/// </summary> |
/// <typeparam name="T">the array type</typeparam> |
/// <param name="input">the array</param> |
/// <param name="times">the number of times to permute</param> |
/// <returns>the array with the elements permuted</returns> |
private static T[] wasReversePermuteArrayElements<T>(T[] input, int times) |
{ |
if (times.Equals(0)) return input; |
T[] slice = new T[input.Length]; |
Array.Copy(input, 1, slice, 0, input.Length - 1); |
Array.Copy(input, 0, slice, input.Length - 1, 1); |
return wasReversePermuteArrayElements(slice, --times); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Permutes an array forward a given number of times. |
/// </summary> |
/// <typeparam name="T">the array type</typeparam> |
/// <param name="input">the array</param> |
/// <param name="times">the number of times to permute</param> |
/// <returns>the array with the elements permuted</returns> |
private static T[] wasForwardPermuteArrayElements<T>(T[] input, int times) |
{ |
if (times.Equals(0)) return input; |
T[] slice = new T[input.Length]; |
Array.Copy(input, input.Length - 1, slice, 0, 1); |
Array.Copy(input, 0, slice, 1, input.Length - 1); |
return wasForwardPermuteArrayElements(slice, --times); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Encrypt or decrypt a message given a set of rotors, plugs and a reflector. |
/// </summary> |
/// <param name="message">the message to encyrpt or decrypt</param> |
/// <param name="rotors">any combination of: 1, 2, 3, 4, 5, 6, 7, 8, b, g</param> |
/// <param name="plugs">the letter representing the start character for the rotor</param> |
/// <param name="reflector">any one of: B, b, C, c</param> |
/// <returns>either a decrypted or encrypted string</returns> |
private static string wasEnigma(string message, char[] rotors, char[] plugs, char reflector) |
{ |
Dictionary<char, char[]> def_rotors = new Dictionary<char, char[]> |
{ |
{ |
'1', new[] |
{ |
'e', 'k', 'm', 'f', 'l', |
'g', 'd', 'q', 'v', 'z', |
'n', 't', 'o', 'w', 'y', |
'h', 'x', 'u', 's', 'p', |
'a', 'i', 'b', 'r', 'c', |
'j' |
} |
}, |
{ |
'2', new[] |
{ |
'a', 'j', 'd', 'k', 's', |
'i', 'r', 'u', 'x', 'b', |
'l', 'h', 'w', 't', 'm', |
'c', 'q', 'g', 'z', 'n', |
'p', 'y', 'f', 'v', 'o', |
'e' |
} |
}, |
{ |
'3', new[] |
{ |
'b', 'd', 'f', 'h', 'j', |
'l', 'c', 'p', 'r', 't', |
'x', 'v', 'z', 'n', 'y', |
'e', 'i', 'w', 'g', 'a', |
'k', 'm', 'u', 's', 'q', |
'o' |
} |
}, |
{ |
'4', new[] |
{ |
'e', 's', 'o', 'v', 'p', |
'z', 'j', 'a', 'y', 'q', |
'u', 'i', 'r', 'h', 'x', |
'l', 'n', 'f', 't', 'g', |
'k', 'd', 'c', 'm', 'w', |
'b' |
} |
}, |
{ |
'5', new[] |
{ |
'v', 'z', 'b', 'r', 'g', |
'i', 't', 'y', 'u', 'p', |
's', 'd', 'n', 'h', 'l', |
'x', 'a', 'w', 'm', 'j', |
'q', 'o', 'f', 'e', 'c', |
'k' |
} |
}, |
{ |
'6', new[] |
{ |
'j', 'p', 'g', 'v', 'o', |
'u', 'm', 'f', 'y', 'q', |
'b', 'e', 'n', 'h', 'z', |
'r', 'd', 'k', 'a', 's', |
'x', 'l', 'i', 'c', 't', |
'w' |
} |
}, |
{ |
'7', new[] |
{ |
'n', 'z', 'j', 'h', 'g', |
'r', 'c', 'x', 'm', 'y', |
's', 'w', 'b', 'o', 'u', |
'f', 'a', 'i', 'v', 'l', |
'p', 'e', 'k', 'q', 'd', |
't' |
} |
}, |
{ |
'8', new[] |
{ |
'f', 'k', 'q', 'h', 't', |
'l', 'x', 'o', 'c', 'b', |
'j', 's', 'p', 'd', 'z', |
'r', 'a', 'm', 'e', 'w', |
'n', 'i', 'u', 'y', 'g', |
'v' |
} |
}, |
{ |
'b', new[] |
{ |
'l', 'e', 'y', 'j', 'v', |
'c', 'n', 'i', 'x', 'w', |
'p', 'b', 'q', 'm', 'd', |
'r', 't', 'a', 'k', 'z', |
'g', 'f', 'u', 'h', 'o', |
's' |
} |
}, |
{ |
'g', new[] |
{ |
'f', 's', 'o', 'k', 'a', |
'n', 'u', 'e', 'r', 'h', |
'm', 'b', 't', 'i', 'y', |
'c', 'w', 'l', 'q', 'p', |
'z', 'x', 'v', 'g', 'j', |
'd' |
} |
} |
}; |
|
Dictionary<char, char[]> def_reflectors = new Dictionary<char, char[]> |
{ |
{ |
'B', new[] |
{ |
'a', 'y', 'b', 'r', 'c', 'u', 'd', 'h', |
'e', 'q', 'f', 's', 'g', 'l', 'i', 'p', |
'j', 'x', 'k', 'n', 'm', 'o', 't', 'z', |
'v', 'w' |
} |
}, |
{ |
'b', new[] |
{ |
'a', 'e', 'b', 'n', 'c', 'k', 'd', 'q', |
'f', 'u', 'g', 'y', 'h', 'w', 'i', 'j', |
'l', 'o', 'm', 'p', 'r', 'x', 's', 'z', |
't', 'v' |
} |
}, |
{ |
'C', new[] |
{ |
'a', 'f', 'b', 'v', 'c', 'p', 'd', 'j', |
'e', 'i', 'g', 'o', 'h', 'y', 'k', 'r', |
'l', 'z', 'm', 'x', 'n', 'w', 't', 'q', |
's', 'u' |
} |
}, |
{ |
'c', new[] |
{ |
'a', 'r', 'b', 'd', 'c', 'o', 'e', 'j', |
'f', 'n', 'g', 't', 'h', 'k', 'i', 'v', |
'l', 'm', 'p', 'w', 'q', 'z', 's', 'x', |
'u', 'y' |
} |
} |
}; |
|
// Setup rotors from plugs. |
foreach (char rotor in rotors) |
{ |
char plug = plugs[Array.IndexOf(rotors, rotor)]; |
int i = Array.IndexOf(def_rotors[rotor], plug); |
if (i.Equals(0)) continue; |
def_rotors[rotor] = wasConcatenateArrays(new[] {plug}, |
wasGetSubArray(wasDeleteSubArray(def_rotors[rotor], i, i), i, -1), |
wasGetSubArray(wasDeleteSubArray(def_rotors[rotor], i + 1, -1), 0, i - 1)); |
} |
|
StringBuilder result = new StringBuilder(); |
foreach (char c in message) |
{ |
if (!char.IsLetter(c)) |
{ |
result.Append(c); |
continue; |
} |
|
// Normalize to lower. |
char l = char.ToLower(c); |
|
Action<char[]> rotate = o => |
{ |
int i = o.Length - 1; |
do |
{ |
def_rotors[o[0]] = wasForwardPermuteArrayElements(def_rotors[o[0]], 1); |
if (i.Equals(0)) |
{ |
rotors = wasReversePermuteArrayElements(o, 1); |
continue; |
} |
l = wasGetElementAt(def_rotors[o[1]], Array.IndexOf(def_rotors[o[0]], l) - 1); |
o = wasReversePermuteArrayElements(o, 1); |
} while (--i > -1); |
}; |
|
// Forward pass through the Enigma's rotors. |
rotate.Invoke(rotors); |
|
// Reflect |
int x = Array.IndexOf(def_reflectors[reflector], l); |
l = (x + 1)%2 == 0 ? def_reflectors[reflector][x - 1] : def_reflectors[reflector][x + 1]; |
|
// Reverse the order of the rotors. |
Array.Reverse(rotors); |
|
// Reverse pass through the Enigma's rotors. |
rotate.Invoke(rotors); |
|
if (char.IsUpper(c)) |
{ |
l = char.ToUpper(l); |
} |
result.Append(l); |
} |
|
return result.ToString(); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Expand the VIGENRE key to the length of the input. |
/// </summary> |
/// <param name="input">the input to expand to</param> |
/// <param name="enc_key">the key to expand</param> |
/// <returns>the expanded key</returns> |
private static string wasVigenereExpandKey(string input, string enc_key) |
{ |
string exp_key = string.Empty; |
int i = 0, j = 0; |
do |
{ |
char p = input[i]; |
if (!char.IsLetter(p)) |
{ |
exp_key += p; |
++i; |
continue; |
} |
int m = j%enc_key.Length; |
exp_key += enc_key[m]; |
++j; |
++i; |
} while (i < input.Length); |
return exp_key; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Encrypt using VIGENERE. |
/// </summary> |
/// <param name="input">the input to encrypt</param> |
/// <param name="enc_key">the key to encrypt with</param> |
/// <returns>the encrypted input</returns> |
private static string wasEncryptVIGENERE(string input, string enc_key) |
{ |
char[] a = |
{ |
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', |
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' |
}; |
|
enc_key = wasVigenereExpandKey(input, enc_key); |
string result = string.Empty; |
int i = 0; |
do |
{ |
char p = input[i]; |
if (!char.IsLetter(p)) |
{ |
result += p; |
++i; |
continue; |
} |
char q = |
wasReversePermuteArrayElements(a, Array.IndexOf(a, enc_key[i]))[ |
Array.IndexOf(a, char.ToLowerInvariant(p))]; |
if (char.IsUpper(p)) |
{ |
q = char.ToUpperInvariant(q); |
} |
result += q; |
++i; |
} while (i < input.Length); |
return result; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Decrypt using VIGENERE. |
/// </summary> |
/// <param name="input">the input to decrypt</param> |
/// <param name="enc_key">the key to decrypt with</param> |
/// <returns>the decrypted input</returns> |
private static string wasDecryptVIGENERE(string input, string enc_key) |
{ |
char[] a = |
{ |
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', |
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' |
}; |
|
enc_key = wasVigenereExpandKey(input, enc_key); |
string result = string.Empty; |
int i = 0; |
do |
{ |
char p = input[i]; |
if (!char.IsLetter(p)) |
{ |
result += p; |
++i; |
continue; |
} |
char q = |
a[ |
Array.IndexOf(wasReversePermuteArrayElements(a, Array.IndexOf(a, enc_key[i])), |
char.ToLowerInvariant(p))]; |
if (char.IsUpper(p)) |
{ |
q = char.ToUpperInvariant(q); |
} |
result += q; |
++i; |
} while (i < input.Length); |
return result; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2015 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// An implementation of the ATBASH cypher for latin alphabets. |
/// </summary> |
/// <param name="data">the data to encrypt or decrypt</param> |
/// <returns>the encrypted or decrypted data</returns> |
private static string wasATBASH(string data) |
{ |
char[] a = |
{ |
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', |
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' |
}; |
|
char[] input = data.ToArray(); |
|
Parallel.ForEach(Enumerable.Range(0, data.Length), i => |
{ |
char e = input[i]; |
if (!char.IsLetter(e)) return; |
int x = 25 - Array.BinarySearch(a, char.ToLowerInvariant(e)); |
if (!char.IsUpper(e)) |
{ |
input[i] = a[x]; |
return; |
} |
input[i] = char.ToUpperInvariant(a[x]); |
}); |
|
return new string(input); |
} |
|
#endregion |
|
/// <summary> |
/// Corrade's input filter function. |
/// </summary> |
private static readonly Func<string, string> wasInput = o => |
{ |
if (string.IsNullOrEmpty(o)) return string.Empty; |
|
foreach (Filter filter in vassalConfiguration.InputFilters) |
{ |
switch (filter) |
{ |
case Filter.RFC1738: |
o = wasURLUnescapeDataString(o); |
break; |
case Filter.RFC3986: |
o = wasURIUnescapeDataString(o); |
break; |
case Filter.ENIGMA: |
o = wasEnigma(o, vassalConfiguration.ENIGMA.rotors.ToArray(), |
vassalConfiguration.ENIGMA.plugs.ToArray(), |
vassalConfiguration.ENIGMA.reflector); |
break; |
case Filter.VIGENERE: |
o = wasDecryptVIGENERE(o, vassalConfiguration.VIGENERESecret); |
break; |
case Filter.ATBASH: |
o = wasATBASH(o); |
break; |
case Filter.BASE64: |
o = Encoding.UTF8.GetString(Convert.FromBase64String(o)); |
break; |
} |
} |
return o; |
}; |
|
/// <summary> |
/// Corrade's output filter function. |
/// </summary> |
private static readonly Func<string, string> wasOutput = o => |
{ |
if (string.IsNullOrEmpty(o)) return string.Empty; |
|
foreach (Filter filter in vassalConfiguration.OutputFilters) |
{ |
switch (filter) |
{ |
case Filter.RFC1738: |
o = wasURLEscapeDataString(o); |
break; |
case Filter.RFC3986: |
o = wasURIEscapeDataString(o); |
break; |
case Filter.ENIGMA: |
o = wasEnigma(o, vassalConfiguration.ENIGMA.rotors.ToArray(), |
vassalConfiguration.ENIGMA.plugs.ToArray(), |
vassalConfiguration.ENIGMA.reflector); |
break; |
case Filter.VIGENERE: |
o = wasEncryptVIGENERE(o, vassalConfiguration.VIGENERESecret); |
break; |
case Filter.ATBASH: |
o = wasATBASH(o); |
break; |
case Filter.BASE64: |
o = Convert.ToBase64String(Encoding.UTF8.GetBytes(o)); |
break; |
} |
} |
return o; |
}; |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) 2014 Wizardry and Steamworks - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary>Escapes a dictionary's keys and values for sending as POST data.</summary> |
@@ -927,7 +326,7 @@ |
break; |
} |
}); |
return String.Join(",", csv); |
return string.Join(",", csv); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
@@ -987,7 +386,7 @@ |
/// <returns>a key-value data encoded string</returns> |
private static string wasKeyValueEncode(Dictionary<string, string> data) |
{ |
return String.Join("&", data.AsParallel().Select(o => String.Join("=", o.Key, o.Value))); |
return string.Join("&", data.AsParallel().Select(o => string.Join("=", o.Key, o.Value))); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
@@ -1006,7 +405,10 @@ |
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(URL); |
request.UserAgent = VASSAL_CONSTANTS.USER_AGENT; |
request.Proxy = WebRequest.DefaultWebProxy; |
request.Pipelined = true; |
request.KeepAlive = true; |
request.Timeout = (int) millisecondsTimeout; |
request.ReadWriteTimeout = (int) millisecondsTimeout; |
request.AllowAutoRedirect = true; |
request.AllowWriteStreamBuffering = true; |
request.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; |
@@ -1047,164 +449,58 @@ |
} |
catch (Exception) |
{ |
|
} |
|
return null; |
} |
|
/// <summary> |
/// Constants used by Corrade. |
/// </summary> |
public struct VASSAL_CONSTANTS |
private void RegionSelected(object sender, EventArgs e) |
{ |
/// <summary> |
/// Copyright. |
/// </summary> |
public const string COPYRIGHT = @"(c) Copyright 2013 Wizardry and Steamworks"; |
new Thread(() => |
{ |
try |
{ |
// Stop timers. |
vassalTimer.Stop(); |
overviewTabTimer.Stop(); |
regionsStateTabTimer.Stop(); |
residentListTabTimer.Stop(); |
estateTopTabTimer.Stop(); |
estateTexturesTabTimer.Stop(); |
|
public const string WIZARDRY_AND_STEAMWORKS = @"Wizardry and Steamworks"; |
public const string VASSAL = @"Vassal"; |
public const string WIZARDRY_AND_STEAMWORKS_WEBSITE = @"http://grimore.org"; |
Monitor.Enter(ClientInstanceTeleportLock); |
|
/// <summary> |
/// Vassal version. |
/// </summary> |
public static readonly string VASSAL_VERSION = Assembly.GetEntryAssembly().GetName().Version.ToString(); |
string selectedRegionName = string.Empty; |
Vector3 selectedRegionPosition = Vector3.Zero; |
bool startTeleport = false; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
ListViewItem listViewItem = LoadedRegionsBox.SelectedItem as ListViewItem; |
switch (listViewItem != null && LoadedRegionsBox.SelectedIndex != -1) |
{ |
case true: |
selectedRegionName = listViewItem.Text; |
selectedRegionPosition = (Vector3) listViewItem.Tag; |
startTeleport = true; |
break; |
default: |
startTeleport = false; |
break; |
} |
})); |
|
/// <summary> |
/// Corrade user agent. |
/// </summary> |
public static readonly string USER_AGENT = |
$"{VASSAL}/{VASSAL_VERSION} ({WIZARDRY_AND_STEAMWORKS_WEBSITE})"; |
if (!startTeleport) throw new Exception(); |
|
/// <summary> |
/// Vassal compile date. |
/// </summary> |
public static readonly string VASSAL_COMPILE_DATE = new DateTime(2000, 1, 1).Add(new TimeSpan( |
TimeSpan.TicksPerDay*Assembly.GetEntryAssembly().GetName().Version.Build + // days since 1 January 2000 |
TimeSpan.TicksPerSecond*2*Assembly.GetEntryAssembly().GetName().Version.Revision)).ToLongDateString(); |
|
/// <summary> |
/// Vassal configuration file. |
/// </summary> |
public static readonly string VASSAL_CONFIGURATION_FILE = @"Vassal.ini"; |
|
/// <summary> |
/// Vassal regions file. |
/// </summary> |
public static readonly string VASSAL_REGIONS = @"Regions.csv"; |
|
/// <summary> |
/// Conten-types that Corrade can send and receive. |
/// </summary> |
public struct CONTENT_TYPE |
{ |
public const string TEXT_PLAIN = @"text/plain"; |
public const string WWW_FORM_URLENCODED = @"application/x-www-form-urlencoded"; |
} |
} |
|
private static readonly System.Action updateCurrentRegionName = () => |
{ |
try |
{ |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
// Announce teleport. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
{"command", "getregiondata"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"data", "Name"} |
}), 60000); |
bool success; |
if (string.IsNullOrEmpty(result) || |
!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
{ |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Failed to query Corrade for current region."; |
vassalForm.RegionTeleportGroup.Enabled = false; |
vassalForm.StatusProgress.Value = 0; |
vassalForm.StatusText.Text = @"Teleporting to " + selectedRegionName; |
})); |
return; |
} |
switch (success) |
{ |
case true: |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
vassalForm.CurrentRegionAt.Visible = true; |
vassalForm.CurrentRegionName.Visible = true; |
vassalForm.CurrentRegionName.Text = |
wasCSVToEnumerable(wasInput(wasKeyValueGet("data", result))).Last(); |
})); |
break; |
default: |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
vassalForm.CurrentRegionAt.Visible = false; |
vassalForm.CurrentRegionName.Visible = false; |
vassalForm.StatusText.Text = @"Error getting current region: " + |
wasInput(wasKeyValueGet("error", result)); |
})); |
break; |
} |
} |
catch (Exception ex) |
{ |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = |
@"Error getting current region: " + |
ex.Message; |
})); |
} |
}; |
|
public Vassal() |
{ |
InitializeComponent(); |
vassalForm = this; |
} |
|
private void RegionSelected(object sender, EventArgs e) |
{ |
string selectedRegionName = string.Empty; |
Vector3 selectedRegionPosition = Vector3.Zero; |
bool startTeleport = false; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
ListViewItem listViewItem = LoadedRegions.SelectedItem as ListViewItem; |
switch (listViewItem != null && LoadedRegions.SelectedIndex != -1) |
{ |
case true: |
selectedRegionName = listViewItem.Text; |
selectedRegionPosition = (Vector3) listViewItem.Tag; |
startTeleport = true; |
break; |
default: |
startTeleport = false; |
break; |
} |
})); |
|
if (!startTeleport) return; |
|
|
// Announce teleport. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.RegionTeleportGroup.Enabled = false; |
vassalForm.StatusProgress.Value = 0; |
vassalForm.StatusText.Text = @"Teleporting to " + selectedRegionName; |
})); |
|
new Thread(() => |
{ |
Monitor.Enter(ClientInstanceTeleportLock); |
try |
{ |
int elapsedSeconds = 0; |
System.Timers.Timer teleportTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); |
Timer teleportTimer = new Timer(TimeSpan.FromSeconds(1).TotalMilliseconds); |
teleportTimer.Elapsed += (o, p) => |
{ |
vassalForm.Invoke((MethodInvoker) (() => |
@@ -1257,10 +553,13 @@ |
})); |
break; |
default: |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Failed teleporting to " + selectedRegionName; |
})); |
vassalForm.Invoke( |
(MethodInvoker) |
(() => |
{ |
vassalForm.StatusText.Text = @"Failed teleporting to " + |
selectedRegionName; |
})); |
break; |
} |
break; |
@@ -1268,21 +567,19 @@ |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Error communicating with Corrade: " + ex.Message; |
})); |
vassalForm.Invoke( |
(MethodInvoker) |
(() => { vassalForm.StatusText.Text = @"Error communicating with Corrade: " + ex.Message; })); |
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
vassalForm.StatusProgress.Value = 100; |
vassalForm.RegionTeleportGroup.Enabled = true; |
// Set the map image to the loading spinner. |
Assembly thisAssembly = System.Reflection.Assembly.GetExecutingAssembly(); |
System.IO.Stream file = |
Assembly thisAssembly = Assembly.GetExecutingAssembly(); |
Stream file = |
thisAssembly.GetManifestResourceStream("Vassal.img.loading.gif"); |
switch (file != null) |
{ |
@@ -1301,6 +598,10 @@ |
TopScriptsGridView.Rows.Clear(); |
// Clear the top colliders table. |
TopCollidersGridView.Rows.Clear(); |
// Clear the estate list table. |
EstateListGridView.Rows.Clear(); |
// Clear the estate list selection box. |
EstateListSelectBox.SelectedIndex = -1; |
// Invalidate data for overview tab. |
vassalForm.CurrentRegionAt.Visible = false; |
vassalForm.CurrentRegionName.Visible = false; |
@@ -1321,6 +622,16 @@ |
Objects.Text = string.Empty; |
Objects.Enabled = false; |
})); |
|
Monitor.Exit(ClientInstanceTeleportLock); |
|
// start timers |
vassalTimer.Start(); |
overviewTabTimer.Start(); |
regionsStateTabTimer.Start(); |
residentListTabTimer.Start(); |
estateTopTabTimer.Start(); |
estateTexturesTabTimer.Start(); |
} |
}) |
{IsBackground = true}.Start(); |
@@ -1328,6 +639,7 @@ |
|
private void SettingsRequested(object sender, EventArgs e) |
{ |
vassalForm.BeginInvoke((MethodInvoker) (() => { VassalStatusGroup.Enabled = false; })); |
SettingsForm settingsForm = new SettingsForm {TopMost = true}; |
settingsForm.Show(); |
} |
@@ -1338,9 +650,19 @@ |
vassalForm.Version.Text = @"v" + VASSAL_CONSTANTS.VASSAL_VERSION; |
|
// Disable estate manager tabs since we will enable these dynamically. |
TopScriptsTab.Enabled = false; |
TopCollidersTab.Enabled = false; |
EstateTopTab.Enabled = false; |
EstateListsTab.Enabled = false; |
ResidentListBanGroup.Enabled = false; |
EstateTerrainDownloadUploadGroup.Enabled = false; |
// Estate textures |
RegionTexturesLowUUIDApplyBox.Enabled = false; |
RegionTexturesLowUUIDApplyButton.Enabled = false; |
RegionTexturesMiddleLowUUIDApplyBox.Enabled = false; |
RegionTexturesMiddleLowUUIDApplyButton.Enabled = false; |
RegionTexturesMiddleHighUUIDApplyBox.Enabled = false; |
RegionTexturesMiddleHighUUIDApplyButton.Enabled = false; |
RegionTexturesHighUUIDApplyBox.Enabled = false; |
RegionTexturesHighUUIDApplyButton.Enabled = false; |
|
// Get the configuration file settings if it exists. |
if (File.Exists(VASSAL_CONSTANTS.VASSAL_CONFIGURATION_FILE)) |
@@ -1351,40 +673,6 @@ |
RegionRestartDelayBox.Text = vassalConfiguration.RegionRestartDelay.ToString(Utils.EnUsCulture); |
} |
|
// Spawn a thread to check Corrade's connection status. |
new Thread(() => |
{ |
TcpClient tcpClient = new TcpClient(); |
try |
{ |
System.Uri uri = new System.Uri(vassalConfiguration.HTTPServerURL); |
tcpClient.Connect(uri.Host, uri.Port); |
// port open |
vassalForm.BeginInvoke((MethodInvoker) (() => { Tabs.Enabled = true; })); |
// set the loading spinner |
Assembly thisAssembly = System.Reflection.Assembly.GetExecutingAssembly(); |
System.IO.Stream file = |
thisAssembly.GetManifestResourceStream("Vassal.img.loading.gif"); |
switch (file != null) |
{ |
case true: |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
RegionAvatarsMap.SizeMode = PictureBoxSizeMode.CenterImage; |
RegionAvatarsMap.Image = Image.FromStream(file); |
RegionAvatarsMap.Refresh(); |
})); |
break; |
} |
} |
catch (Exception) |
{ |
// port closed |
vassalForm.BeginInvoke((MethodInvoker) (() => { Tabs.Enabled = false; })); |
} |
}) |
{IsBackground = true}.Start(); |
|
// Get all the regions if they exist. |
if (File.Exists(VASSAL_CONSTANTS.VASSAL_REGIONS)) |
{ |
@@ -1399,8 +687,8 @@ |
? localPosition |
: Vector3.Zero).OrderBy(o => o.Key).ToDictionary(o => o.Key, o => o.Value)); |
// Populate the loaded regions. |
LoadedRegions.Items.Clear(); |
LoadedRegions.Items.AddRange( |
LoadedRegionsBox.Items.Clear(); |
LoadedRegionsBox.Items.AddRange( |
ConfiguredRegions.Select(o => (object) new ListViewItem {Text = o.Key, Tag = o.Value}) |
.ToArray()); |
// Populate the batch restart grid view. |
@@ -1416,17 +704,65 @@ |
} |
} |
|
// Start the overview timer. |
overviewTabTimer.Elapsed += (o, p) => |
// Start the vassal timer. |
vassalTimer.Elapsed += (o, p) => |
{ |
if (!Monitor.TryEnter(ClientInstanceTeleportLock)) |
return; |
try |
{ |
// Check Corrade connection status. |
TcpClient tcpClient = new TcpClient(); |
Uri uri = new Uri(vassalConfiguration.HTTPServerURL); |
tcpClient.Connect(uri.Host, uri.Port); |
// port open |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
vassalForm.CurrentRegionAt.Visible = true; |
vassalForm.CurrentRegionName.Visible = true; |
Assembly thisAssembly = Assembly.GetExecutingAssembly(); |
Stream file = |
thisAssembly.GetManifestResourceStream("Vassal.img.online.png"); |
switch (file != null) |
{ |
case true: |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
ConnectionStatusPictureBox.Image = Image.FromStream(file); |
ConnectionStatusPictureBox.Refresh(); |
})); |
break; |
} |
Tabs.Enabled = true; |
})); |
} |
catch (Exception) |
{ |
// port closed |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
vassalForm.CurrentRegionAt.Visible = false; |
vassalForm.CurrentRegionName.Visible = false; |
Assembly thisAssembly = Assembly.GetExecutingAssembly(); |
Stream file = |
thisAssembly.GetManifestResourceStream("Vassal.img.offline.png"); |
switch (file != null) |
{ |
case true: |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
ConnectionStatusPictureBox.Image = Image.FromStream(file); |
ConnectionStatusPictureBox.Refresh(); |
})); |
break; |
} |
Tabs.Enabled = false; |
})); |
} |
|
try |
{ |
// Always run the overview regardless which tab is active. |
|
// Get the statistics. |
// Get the simulator name and if we are an estate manager. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
@@ -1436,14 +772,6 @@ |
{ |
"data", wasEnumerableToCSV(new[] |
{ |
"Agents", |
"LastLag", |
"Dilation", |
"FPS", |
"PhysicsFPS", |
"ActiveScripts", |
"ScriptTime", |
"Objects", |
"Name", |
"IsEstateManager" |
}) |
@@ -1468,14 +796,38 @@ |
isEstateManager) |
{ |
case true: // we are an estate manager |
TopScriptsTab.Enabled = true; |
TopCollidersTab.Enabled = true; |
EstateTopTab.Enabled = true; |
EstateListsTab.Enabled = true; |
ResidentListBanGroup.Enabled = true; |
EstateTerrainDownloadUploadGroup.Enabled = true; |
RegionToolsRegionDebugGroup.Enabled = true; |
RegionToolsRegionInfoGroup.Enabled = true; |
// Estate textures |
RegionTexturesLowUUIDApplyBox.Enabled = true; |
RegionTexturesLowUUIDApplyButton.Enabled = true; |
RegionTexturesMiddleLowUUIDApplyBox.Enabled = true; |
RegionTexturesMiddleLowUUIDApplyButton.Enabled = true; |
RegionTexturesMiddleHighUUIDApplyBox.Enabled = true; |
RegionTexturesMiddleHighUUIDApplyButton.Enabled = true; |
RegionTexturesHighUUIDApplyBox.Enabled = true; |
RegionTexturesHighUUIDApplyButton.Enabled = true; |
break; |
default: |
TopScriptsTab.Enabled = false; |
TopCollidersTab.Enabled = false; |
EstateTopTab.Enabled = false; |
EstateListsTab.Enabled = false; |
ResidentListBanGroup.Enabled = false; |
EstateTerrainDownloadUploadGroup.Enabled = false; |
RegionToolsRegionDebugGroup.Enabled = false; |
RegionToolsRegionInfoGroup.Enabled = false; |
// Estate textures |
RegionTexturesLowUUIDApplyBox.Enabled = false; |
RegionTexturesLowUUIDApplyButton.Enabled = false; |
RegionTexturesMiddleLowUUIDApplyBox.Enabled = false; |
RegionTexturesMiddleLowUUIDApplyButton.Enabled = false; |
RegionTexturesMiddleHighUUIDApplyBox.Enabled = false; |
RegionTexturesMiddleHighUUIDApplyButton.Enabled = false; |
RegionTexturesHighUUIDApplyBox.Enabled = false; |
RegionTexturesHighUUIDApplyButton.Enabled = false; |
break; |
} |
|
@@ -1483,7 +835,67 @@ |
vassalForm.CurrentRegionName.Text = data[data.IndexOf("Name") + 1]; |
vassalForm.CurrentRegionAt.Visible = true; |
vassalForm.CurrentRegionName.Visible = true; |
})); |
} |
catch (Exception) |
{ |
} |
|
Monitor.Exit(ClientInstanceTeleportLock); |
}; |
vassalTimer.Start(); |
|
// Start the overview timer. |
overviewTabTimer.Elapsed += (o, p) => |
{ |
// Do not do anything in case the tab is not selected. |
bool run = false; |
vassalForm.Invoke((MethodInvoker) (() => { run = Tabs.SelectedTab.Equals(OverviewTab); })); |
|
if (!run) |
{ |
overviewTabTimer.Stop(); |
return; |
} |
|
overviewTabTimer.Stop(); |
|
try |
{ |
// Get the statistics. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "getregiondata"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{ |
"data", wasEnumerableToCSV(new[] |
{ |
"Agents", |
"LastLag", |
"Dilation", |
"FPS", |
"PhysicsFPS", |
"ActiveScripts", |
"ScriptTime", |
"Objects", |
"AvatarPositions" |
}) |
} |
}), vassalConfiguration.DataTimeout); |
|
bool success; |
if (string.IsNullOrEmpty(result) || |
!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception(); |
|
List<string> data = wasCSVToEnumerable(wasInput(wasKeyValueGet("data", result))).ToList(); |
if (data.Count.Equals(0)) |
throw new Exception(); |
|
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
// Populate the overview tab. |
Agents.Text = data[data.IndexOf("Agents") + 1]; |
Agents.Enabled = true; |
@@ -1503,6 +915,21 @@ |
Objects.Enabled = true; |
})); |
|
// Get avatar positions. |
// Pattern: [...], X, 10, Y, 63, Z, 200, [...], X, 52, Y, 73, Z, 55, [...[...]] |
float X = 0, Y = 0, Z = 0; |
List<Vector3> positions = data.Select((x, i) => new {Item = x, Index = i}) |
.Where(x => x.Item.Equals("X") || x.Item.Equals("Y") || x.Item.Equals("Z")) |
.Select(z => data[z.Index + 1]).Select((x, i) => new {Value = x, Index = i}) |
.GroupBy(x => x.Index/3) |
.Select(x => x.Select(v => v.Value).ToList()) |
.Where( |
x => |
float.TryParse(x[0], out X) && float.TryParse(x[1], out Y) && |
float.TryParse(x[2], out Z)) |
.Select(x => new Vector3(X, Y, Z)) |
.ToList(); |
|
// Get the map image. |
result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
@@ -1528,7 +955,7 @@ |
{"password", vassalConfiguration.Password}, |
{"item", data.Last()}, |
{"type", "Texture"}, |
{"format", "Jpeg"}, |
{"format", "Jpeg"} |
}), vassalConfiguration.DataTimeout); |
if (string.IsNullOrEmpty(result) || |
!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
@@ -1540,39 +967,12 @@ |
mapImage = Image.FromStream(memoryStream); |
} |
|
// Get the avatar positions. |
result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "getavatarpositions"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"entity", "region"} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result) || |
!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception(); |
|
// Every thrid element represents a Vecto3 of the avatar position. |
data = |
wasCSVToEnumerable(wasInput(wasKeyValueGet("data", result))) |
.Skip(2) |
.Where((x, i) => i%3 == 0) |
.ToList(); |
|
// Draw the avatars onto the map. |
Graphics mapGraphics = Graphics.FromImage(mapImage); |
Vector3 position; |
foreach (string vector in data) |
foreach (Vector3 position in positions) |
{ |
switch (Vector3.TryParse(vector, out position)) |
{ |
case true: |
mapGraphics.FillEllipse(Brushes.Chartreuse, |
new Rectangle((int) position.X, (int) position.Y, 4, 4)); |
break; |
} |
mapGraphics.FillEllipse(Brushes.Chartreuse, |
new Rectangle((int) position.X, (int) position.Y, 4, 4)); |
} |
mapGraphics.DrawImage(mapImage, new Point(0, 0)); |
|
@@ -1585,13 +985,9 @@ |
} |
catch (Exception) |
{ |
|
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
} |
|
overviewTabTimer.Start(); |
}; |
overviewTabTimer.Start(); |
|
@@ -1599,15 +995,16 @@ |
{ |
// Do not do anything in case the tab is not selected. |
bool run = false; |
vassalForm.Invoke((MethodInvoker) (() => |
vassalForm.Invoke((MethodInvoker) (() => { run = Tabs.SelectedTab.Equals(RegionsStateTab); })); |
|
if (!run) |
{ |
run = Tabs.SelectedTab.Equals(RegionsStateTab); |
})); |
if (!run) return; |
|
if (!Monitor.TryEnter(RegionsStateCheckLock)) |
regionsStateTabTimer.Stop(); |
return; |
} |
|
regionsStateTabTimer.Stop(); |
|
try |
{ |
string regionName = string.Empty; |
@@ -1616,6 +1013,8 @@ |
regionName = |
RegionsStateGridView.Rows[regionsStateCheckIndex].Cells["RegionsStateRegionName"].Value |
.ToString(); |
RegionsStateGridView.Rows[regionsStateCheckIndex].DefaultCellStyle.BackColor = |
Color.Gold; |
})); |
|
if (string.IsNullOrEmpty(regionName)) |
@@ -1663,17 +1062,14 @@ |
} |
RegionsStateGridView.Rows[regionsStateCheckIndex].Cells["RegionsStateLastCheck"].Value = DateTime |
.Now.ToUniversalTime() |
.ToString(Vassal.LINDEN_CONSTANTS.LSL.DATE_TIME_STAMP); |
|
.ToString(LINDEN_CONSTANTS.LSL.DATE_TIME_STAMP); |
})); |
} |
catch (Exception) |
{ |
|
} |
finally |
{ |
Monitor.Exit(RegionsStateCheckLock); |
++regionsStateCheckIndex; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
@@ -1683,26 +1079,29 @@ |
} |
})); |
} |
|
regionsStateTabTimer.Start(); |
}; |
regionsStateTabTimer.Start(); |
|
// Start the top scores timer. |
topScriptsTabTimer.Elapsed += (o, p) => |
estateTopTabTimer.Elapsed += (o, p) => |
{ |
// Do not do anything in case the tab is not selected. |
bool run = false; |
vassalForm.Invoke((MethodInvoker) (() => |
vassalForm.Invoke((MethodInvoker) (() => { run = Tabs.SelectedTab.Equals(EstateTopTab); })); |
|
if (!run) |
{ |
run = Tabs.SelectedTab.Equals(TopScriptsTab); |
})); |
if (!run) return; |
|
if (!Monitor.TryEnter(ClientInstanceTeleportLock)) |
estateTopTabTimer.Stop(); |
return; |
} |
|
estateTopTabTimer.Stop(); |
|
try |
{ |
// Get the statistics. |
// Get the top scripts. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
@@ -1761,36 +1160,9 @@ |
} |
} |
})); |
} |
catch (Exception) |
{ |
|
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
} |
}; |
topScriptsTabTimer.Start(); |
|
// Start the top colliders timer. |
topCollidersTabTimer.Elapsed += (o, p) => |
{ |
// Do not do anything in case the tab is not selected. |
bool run = false; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
run = Tabs.SelectedTab.Equals(TopCollidersTab); |
})); |
if (!run) return; |
|
if (!Monitor.TryEnter(ClientInstanceTeleportLock)) |
return; |
|
try |
{ |
// Get the statistics. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
// Get the top colliders. |
result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "getregiontop"}, |
@@ -1799,16 +1171,14 @@ |
{"type", "colliders"} |
}), vassalConfiguration.DataTimeout); |
|
bool success; |
if (string.IsNullOrEmpty(result) || |
!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception(); |
|
HashSet<List<string>> data = |
new HashSet<List<string>>(wasCSVToEnumerable(wasInput(wasKeyValueGet("data", result))) |
.Select((x, i) => new {Index = i, Value = x}) |
.GroupBy(x => x.Index/5) |
.Select(x => x.Select(v => v.Value).ToList())); |
data = new HashSet<List<string>>(wasCSVToEnumerable(wasInput(wasKeyValueGet("data", result))) |
.Select((x, i) => new {Index = i, Value = x}) |
.GroupBy(x => x.Index/5) |
.Select(x => x.Select(v => v.Value).ToList())); |
if (data.Count.Equals(0)) |
throw new Exception(); |
|
@@ -1848,34 +1218,31 @@ |
break; |
} |
} |
|
})); |
} |
catch (Exception) |
{ |
} |
|
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
} |
estateTopTabTimer.Start(); |
}; |
topCollidersTabTimer.Start(); |
estateTopTabTimer.Start(); |
|
// Start the resident list timer. |
residentListTimer.Elapsed += (o, p) => |
residentListTabTimer.Elapsed += (o, p) => |
{ |
// Do not do anything in case the tab is not selected. |
bool run = false; |
vassalForm.Invoke((MethodInvoker) (() => |
vassalForm.Invoke((MethodInvoker) (() => { run = Tabs.SelectedTab.Equals(ResidentListTab); })); |
|
if (!run) |
{ |
run = Tabs.SelectedTab.Equals(ResidentListTab); |
})); |
if (!run) return; |
|
if (!Monitor.TryEnter(ClientInstanceTeleportLock)) |
residentListTabTimer.Stop(); |
return; |
} |
|
residentListTabTimer.Stop(); |
|
try |
{ |
// Get the avatar positions. |
@@ -1934,25 +1301,137 @@ |
break; |
} |
} |
|
})); |
} |
catch (Exception) |
{ |
} |
|
residentListTabTimer.Start(); |
}; |
residentListTabTimer.Start(); |
|
estateTexturesTabTimer.Elapsed += (o, p) => |
{ |
// Do not do anything in case the tab is not selected. |
bool run = false; |
vassalForm.Invoke((MethodInvoker) (() => { run = Tabs.SelectedTab.Equals(EstateTexturesTab); })); |
|
if (!run) |
{ |
estateTexturesTabTimer.Stop(); |
return; |
} |
finally |
|
estateTexturesTabTimer.Stop(); |
|
try |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
// Get the region terrain texture UUIDs. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "getregionterraintextures"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password} |
}), vassalConfiguration.DataTimeout); |
|
bool success; |
if (string.IsNullOrEmpty(result) || |
!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception(); |
|
List<string> data = wasCSVToEnumerable(wasInput(wasKeyValueGet("data", result))).ToList(); |
if (!data.Count.Equals(4)) |
throw new Exception(); |
|
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTexturesLowUUIDBox.Text = data[0]; |
if (string.IsNullOrEmpty(RegionTexturesLowUUIDApplyBox.Text)) |
{ |
RegionTexturesLowUUIDApplyBox.Text = data[0]; |
} |
RegionTexturesMiddleLowUUIDBox.Text = data[1]; |
if (string.IsNullOrEmpty(RegionTexturesMiddleLowUUIDApplyBox.Text)) |
{ |
RegionTexturesMiddleLowUUIDApplyBox.Text = data[1]; |
} |
RegionTexturesMiddleHighUUIDBox.Text = data[2]; |
if (string.IsNullOrEmpty(RegionTexturesMiddleHighUUIDApplyBox.Text)) |
{ |
RegionTexturesMiddleHighUUIDApplyBox.Text = data[2]; |
} |
RegionTexturesHighUUIDBox.Text = data[3]; |
if (string.IsNullOrEmpty(RegionTexturesHighUUIDApplyBox.Text)) |
{ |
RegionTexturesHighUUIDApplyBox.Text = data[1]; |
} |
})); |
|
Parallel.ForEach(Enumerable.Range(0, 4), i => |
{ |
result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "download"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"item", data[i]}, |
{"type", "Texture"}, |
{"format", "Jpeg"} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result) || |
!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
return; |
|
byte[] mapImageBytes = Convert.FromBase64String(wasInput(wasKeyValueGet("data", result))); |
using (MemoryStream memoryStream = new MemoryStream(mapImageBytes, 0, mapImageBytes.Length)) |
{ |
groundTextureImages[i] = Image.FromStream(memoryStream); |
} |
|
switch (i) |
{ |
case 0: |
vassalForm.BeginInvoke( |
(MethodInvoker) |
(() => { RegionTexturesLowPictureBox.Image = groundTextureImages[0]; })); |
|
break; |
case 1: |
vassalForm.BeginInvoke( |
(MethodInvoker) |
(() => { RegionTexturesMiddleLowPictureBox.Image = groundTextureImages[1]; })); |
|
break; |
case 2: |
vassalForm.BeginInvoke( |
(MethodInvoker) |
(() => { RegionTexturesMiddleHighPictureBox.Image = groundTextureImages[2]; })); |
break; |
case 3: |
vassalForm.BeginInvoke( |
(MethodInvoker) |
(() => { RegionTexturesHighPictureBox.Image = groundTextureImages[3]; })); |
break; |
} |
}); |
} |
catch (Exception) |
{ |
} |
|
estateTexturesTabTimer.Start(); |
}; |
residentListTimer.Start(); |
estateTexturesTabTimer.Start(); |
} |
|
private void RequestedEditRegions(object sender, EventArgs e) |
{ |
// Clear any selection. |
LoadedRegions.SelectedIndex = -1; |
LoadedRegionsBox.SelectedIndex = -1; |
RegionEditForm regionEditForm = new RegionEditForm {TopMost = true}; |
regionEditForm.Show(); |
} |
@@ -2158,10 +1637,7 @@ |
|
try |
{ |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusProgress.Value = 0; |
})); |
vassalForm.Invoke((MethodInvoker) (() => { vassalForm.StatusProgress.Value = 0; })); |
int totalObjects = returnUUIDs.Count; |
do |
{ |
@@ -2168,16 +1644,12 @@ |
// Dequeue the first object. |
KeyValuePair<UUID, Vector3> objectData = returnUUIDs.Dequeue(); |
|
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Returning object UUID: " + objectData.Key.ToString(); |
})); |
vassalForm.Invoke( |
(MethodInvoker) |
(() => { vassalForm.StatusText.Text = @"Returning object UUID: " + objectData.Key; })); |
|
string currentRegionName = string.Empty; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
currentRegionName = CurrentRegionName.Text; |
})); |
vassalForm.Invoke((MethodInvoker) (() => { currentRegionName = CurrentRegionName.Text; })); |
|
// Teleport to the object. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
@@ -2193,10 +1665,9 @@ |
|
if (string.IsNullOrEmpty(result)) |
{ |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Error communicating with Corrade."; |
})); |
vassalForm.Invoke( |
(MethodInvoker) |
(() => { vassalForm.StatusText.Text = @"Error communicating with Corrade."; })); |
continue; |
} |
|
@@ -2214,10 +1685,9 @@ |
|
if (string.IsNullOrEmpty(result)) |
{ |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Error communicating with Corrade."; |
})); |
vassalForm.Invoke( |
(MethodInvoker) |
(() => { vassalForm.StatusText.Text = @"Error communicating with Corrade."; })); |
continue; |
} |
|
@@ -2224,10 +1694,9 @@ |
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
{ |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"No success status could be retrieved. "; |
})); |
vassalForm.Invoke( |
(MethodInvoker) |
(() => { vassalForm.StatusText.Text = @"No success status could be retrieved. "; })); |
continue; |
} |
|
@@ -2236,7 +1705,7 @@ |
case true: |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Returned object: " + objectData.Key.ToString(); |
vassalForm.StatusText.Text = @"Returned object: " + objectData.Key; |
// Remove the row from the grid view. |
DataGridViewRow row = |
TopScriptsGridView.Rows.AsParallel() |
@@ -2251,31 +1720,24 @@ |
case false: |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Could not return object " + objectData.Key.ToString() + |
vassalForm.StatusText.Text = @"Could not return object " + objectData.Key + |
@": " + |
wasInput(wasKeyValueGet("error", result)); |
})); |
break; |
} |
|
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusProgress.Value = |
Math.Min((int) (Math.Abs(returnUUIDs.Count - totalObjects)/ |
(double) totalObjects), 100); |
Math.Min((int) (100d*Math.Abs(returnUUIDs.Count - totalObjects)/totalObjects), 100); |
})); |
} while (!returnUUIDs.Count.Equals(0)); |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusProgress.Value = 100; |
})); |
vassalForm.Invoke((MethodInvoker) (() => { vassalForm.StatusProgress.Value = 100; })); |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Unexpected error: " + ex.Message; |
})); |
vassalForm.Invoke( |
(MethodInvoker) (() => { vassalForm.StatusText.Text = @"Unexpected error: " + ex.Message; })); |
} |
finally |
{ |
@@ -2337,10 +1799,7 @@ |
|
try |
{ |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusProgress.Value = 0; |
})); |
vassalForm.Invoke((MethodInvoker) (() => { vassalForm.StatusProgress.Value = 0; })); |
int totalObjects = returnObjectUUIDQueue.Count; |
do |
{ |
@@ -2347,16 +1806,12 @@ |
// Dequeue the first object. |
KeyValuePair<UUID, Vector3> objectData = returnObjectUUIDQueue.Dequeue(); |
|
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Returning UUID: " + objectData.Key.ToString(); |
})); |
vassalForm.Invoke( |
(MethodInvoker) |
(() => { vassalForm.StatusText.Text = @"Returning UUID: " + objectData.Key; })); |
|
string currentRegionName = string.Empty; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
currentRegionName = CurrentRegionName.Text; |
})); |
vassalForm.Invoke((MethodInvoker) (() => { currentRegionName = CurrentRegionName.Text; })); |
|
// Teleport to the object. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
@@ -2372,10 +1827,9 @@ |
|
if (string.IsNullOrEmpty(result)) |
{ |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Error communicating with Corrade."; |
})); |
vassalForm.Invoke( |
(MethodInvoker) |
(() => { vassalForm.StatusText.Text = @"Error communicating with Corrade."; })); |
continue; |
} |
|
@@ -2393,10 +1847,9 @@ |
|
if (string.IsNullOrEmpty(result)) |
{ |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Error communicating with Corrade."; |
})); |
vassalForm.Invoke( |
(MethodInvoker) |
(() => { vassalForm.StatusText.Text = @"Error communicating with Corrade."; })); |
continue; |
} |
|
@@ -2403,10 +1856,9 @@ |
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
{ |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"No success status could be retrieved. "; |
})); |
vassalForm.Invoke( |
(MethodInvoker) |
(() => { vassalForm.StatusText.Text = @"No success status could be retrieved. "; })); |
continue; |
} |
|
@@ -2415,7 +1867,7 @@ |
case true: |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Returned object: " + objectData.Key.ToString(); |
vassalForm.StatusText.Text = @"Returned object: " + objectData.Key; |
// Remove the row from the grid view. |
DataGridViewRow row = |
TopCollidersGridView.Rows.AsParallel() |
@@ -2430,31 +1882,25 @@ |
case false: |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Could not return object " + objectData.Key.ToString() + |
vassalForm.StatusText.Text = @"Could not return object " + objectData.Key + |
@": " + |
wasInput(wasKeyValueGet("error", result)); |
})); |
break; |
} |
|
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusProgress.Value = |
Math.Min((int) (Math.Abs(returnObjectUUIDQueue.Count - totalObjects)/ |
(double) totalObjects), 100); |
Math.Min( |
(int) (100d*Math.Abs(returnObjectUUIDQueue.Count - totalObjects)/totalObjects), 100); |
})); |
} while (!returnObjectUUIDQueue.Count.Equals(0)); |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusProgress.Value = 100; |
})); |
vassalForm.Invoke((MethodInvoker) (() => { vassalForm.StatusProgress.Value = 100; })); |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Unexpected error: " + ex.Message; |
})); |
vassalForm.Invoke( |
(MethodInvoker) (() => { vassalForm.StatusText.Text = @"Unexpected error: " + ex.Message; })); |
} |
finally |
{ |
@@ -2567,27 +2013,30 @@ |
|
if (string.IsNullOrEmpty(result)) |
{ |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Error communicating with Corrade."; |
})); |
vassalForm.Invoke( |
(MethodInvoker) |
(() => |
{ |
vassalForm.StatusText.Text = @"Error communicating with Corrade."; |
})); |
continue; |
} |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
{ |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"No success status could be retrieved. "; |
})); |
vassalForm.Invoke( |
(MethodInvoker) |
(() => |
{ |
vassalForm.StatusText.Text = @"No success status could be retrieved. "; |
})); |
continue; |
} |
switch (success) |
{ |
case true: |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Teleport succeeded."; |
})); |
vassalForm.Invoke( |
(MethodInvoker) |
(() => { vassalForm.StatusText.Text = @"Teleport succeeded."; })); |
Thread.Sleep(TimeSpan.FromSeconds(1).Milliseconds); |
break; |
default: |
@@ -2602,10 +2051,9 @@ |
success = true; |
break; |
default: |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.StatusText.Text = @"Teleport failed."; |
})); |
vassalForm.Invoke( |
(MethodInvoker) |
(() => { vassalForm.StatusText.Text = @"Teleport failed."; })); |
Thread.Sleep(10000); |
break; |
} |
@@ -2652,7 +2100,8 @@ |
{"password", vassalConfiguration.Password}, |
{"action", "restart"}, |
{ |
"delay", vassalConfiguration.RegionRestartDelay.ToString(Utils.EnUsCulture) |
"delay", |
vassalConfiguration.RegionRestartDelay.ToString(Utils.EnUsCulture) |
} |
}), vassalConfiguration.DataTimeout); |
|
@@ -2701,7 +2150,6 @@ |
} |
catch (Exception) |
{ |
|
} |
finally |
{ |
@@ -2715,7 +2163,6 @@ |
} |
}) |
{IsBackground = true}.Start(); |
|
} |
|
private void RequestFilterResidentList(object sender, EventArgs e) |
@@ -2806,10 +2253,8 @@ |
try |
{ |
bool alsoBan = false; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
alsoBan = vassalForm.ResidentBanAllEstatesBox.Checked; |
})); |
vassalForm.Invoke( |
(MethodInvoker) (() => { alsoBan = vassalForm.ResidentBanAllEstatesBox.Checked; })); |
|
// Teleport to the region. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
@@ -2866,12 +2311,10 @@ |
} |
})); |
} |
|
} while (agentsQueue.Count.Equals(0)); |
} |
catch (Exception) |
{ |
|
} |
finally |
{ |
@@ -2902,7 +2345,7 @@ |
|
try |
{ |
// Get the statistics. |
// Get the map heights. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
@@ -2941,16 +2384,18 @@ |
foreach (int y in Enumerable.Range(1, 255)) |
{ |
bitmap.SetPixel(x, 256 - y, |
Color.FromArgb((int) wasMapValueToRange(heights[256*x + y], 0, maxHeight, 0, 255), 0, 0)); |
Color.FromArgb( |
Math.Max((int) wasMapValueToRange(heights[256*x + y], 0, maxHeight, 0, 255), 0), |
0, 0)); |
} |
} |
Bitmap closureBitmap = (Bitmap)bitmap.Clone(); |
Bitmap closureBitmap = (Bitmap) bitmap.Clone(); |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
switch (vassalForm.SaveTerrainFileDialog.ShowDialog()) |
switch (vassalForm.SavePNGFileDialog.ShowDialog()) |
{ |
case DialogResult.OK: |
string file = vassalForm.SaveTerrainFileDialog.FileName; |
string file = vassalForm.SavePNGFileDialog.FileName; |
new Thread(() => |
{ |
vassalForm.BeginInvoke((MethodInvoker) (() => |
@@ -2975,31 +2420,2294 @@ |
} |
})); |
}) |
{IsBackground = true, Priority = ThreadPriority.Normal}.Start(); |
{IsBackground = true}.Start(); |
break; |
} |
})); |
} |
|
} |
catch (Exception ex) |
{ |
vassalForm.BeginInvoke((MethodInvoker)(() => |
vassalForm.BeginInvoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); |
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
StatusText.Text = ex.Message; |
RegionTeleportGroup.Enabled = true; |
RipTerrainButton.Enabled = true; |
})); |
} |
}) {IsBackground = true}.Start(); |
} |
|
private void RequestDownloadTerrain(object sender, EventArgs e) |
{ |
// Block teleports and disable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = false; |
DownloadTerrainButton.Enabled = false; |
})); |
|
new Thread(() => |
{ |
Monitor.Enter(ClientInstanceTeleportLock); |
|
try |
{ |
// Download the terrain. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "terrain"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"action", "get"} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade."); |
|
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved."); |
|
if (!success) |
throw new Exception("Could not download terrain."); |
|
byte[] data = Convert.FromBase64String(wasInput(wasKeyValueGet("data", result))); |
|
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
switch (vassalForm.SaveRawFileDialog.ShowDialog()) |
{ |
case DialogResult.OK: |
string file = vassalForm.SaveRawFileDialog.FileName; |
new Thread(() => |
{ |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
try |
{ |
vassalForm.StatusText.Text = @"saving terrain..."; |
vassalForm.StatusProgress.Value = 0; |
|
File.WriteAllBytes(file, data); |
|
vassalForm.StatusText.Text = @"terrain saved"; |
vassalForm.StatusProgress.Value = 100; |
} |
catch (Exception ex) |
{ |
vassalForm.StatusText.Text = ex.Message; |
} |
})); |
}) |
{IsBackground = true}.Start(); |
break; |
} |
})); |
} |
catch (Exception ex) |
{ |
vassalForm.BeginInvoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); |
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
vassalForm.BeginInvoke((MethodInvoker)(() => |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
DownloadTerrainButton.Enabled = true; |
RegionTeleportGroup.Enabled = true; |
RipTerrainButton.Enabled = true; |
})); |
} |
}) |
{IsBackground = true}.Start(); |
} |
|
}) {IsBackground = true}.Start(); |
private void RequestUploadTerrain(object sender, EventArgs e) |
{ |
// Block teleports and disable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = false; |
UploadTerrainButton.Enabled = false; |
})); |
|
new Thread(() => |
{ |
Monitor.Enter(ClientInstanceTeleportLock); |
|
try |
{ |
byte[] data = null; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
switch (vassalForm.LoadRawFileDialog.ShowDialog()) |
{ |
case DialogResult.OK: |
string file = vassalForm.LoadRawFileDialog.FileName; |
vassalForm.StatusText.Text = @"loading terrain..."; |
vassalForm.StatusProgress.Value = 0; |
|
data = File.ReadAllBytes(file); |
|
vassalForm.StatusText.Text = @"terrain loaded"; |
vassalForm.StatusProgress.Value = 100; |
break; |
} |
})); |
|
// Upload the terrain. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "terrain"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"action", "set"}, |
{"data", Convert.ToBase64String(data)} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade."); |
|
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved."); |
|
if (!success) |
throw new Exception("Could not upload terrain."); |
} |
catch (Exception ex) |
{ |
vassalForm.BeginInvoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); |
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
UploadTerrainButton.Enabled = true; |
RegionTeleportGroup.Enabled = true; |
})); |
} |
}) |
{IsBackground = true}.Start(); |
} |
|
private void RequestTabsChanged(object sender, EventArgs e) |
{ |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
overviewTabTimer.Stop(); |
regionsStateTabTimer.Stop(); |
residentListTabTimer.Stop(); |
estateTopTabTimer.Stop(); |
|
if (Tabs.SelectedTab.Equals(OverviewTab)) |
{ |
overviewTabTimer.Start(); |
return; |
} |
if (Tabs.SelectedTab.Equals(RegionsStateTab)) |
{ |
regionsStateTabTimer.Start(); |
return; |
} |
if (Tabs.SelectedTab.Equals(ResidentListTab)) |
{ |
residentListTabTimer.Start(); |
return; |
} |
if (Tabs.SelectedTab.Equals(EstateTopTab)) |
{ |
estateTopTabTimer.Start(); |
return; |
} |
if (Tabs.SelectedTab.Equals(EstateTexturesTab)) |
{ |
estateTexturesTabTimer.Start(); |
} |
})); |
} |
|
private void RequestFilterEstateList(object sender, EventArgs e) |
{ |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
Regex estateListRowRegex; |
switch (!string.IsNullOrEmpty(EstateListFilter.Text)) |
{ |
case true: |
estateListRowRegex = new Regex(EstateListFilter.Text, RegexOptions.Compiled); |
break; |
default: |
estateListRowRegex = new Regex(@".+?", RegexOptions.Compiled); |
break; |
} |
foreach (DataGridViewRow estateListRow in EstateListGridView.Rows.AsParallel().Cast<DataGridViewRow>()) |
{ |
estateListRow.Visible = |
estateListRowRegex.IsMatch(estateListRow.Cells["EstateListName"].Value.ToString()); |
} |
})); |
} |
|
private void EstateListSelected(object sender, EventArgs e) |
{ |
string selectedEstateListType = string.Empty; |
bool queryEstateList = false; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
if (vassalForm.EstateListSelectBox.SelectedItem == null) return; |
selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString(); |
switch ( |
!string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1) |
{ |
case true: |
queryEstateList = true; |
break; |
default: |
EstateListsResidentsGroup.Enabled = false; |
EstateListsGroupsGroup.Enabled = false; |
queryEstateList = false; |
break; |
} |
})); |
|
if (!queryEstateList) return; |
|
new Thread(() => |
{ |
try |
{ |
Monitor.Enter(ClientInstanceTeleportLock); |
|
// Disable controls. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = false; |
EstateListsResidentsGroup.Enabled = false; |
EstateListsGroupsGroup.Enabled = false; |
})); |
|
// Get the selected estate list. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "getestatelist"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"type", selectedEstateListType} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade."); |
|
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved."); |
|
if (!success) |
throw new Exception("Could not retrieve estate list."); |
|
vassalForm.Invoke((MethodInvoker) (() => { EstateListGridView.Rows.Clear(); })); |
foreach (List<string> data in wasCSVToEnumerable(wasInput(wasKeyValueGet("data", result))) |
.Where(x => !string.IsNullOrEmpty(x)) |
.Select((x, i) => new {Index = i, Value = x}) |
.GroupBy(x => x.Index/2) |
.Select(x => x.Select(v => v.Value).ToList()).Where(x => x.Count.Equals(2))) |
{ |
vassalForm.Invoke( |
(MethodInvoker) (() => { EstateListGridView.Rows.Add(data.First(), data.Last()); })); |
} |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke((MethodInvoker) (() => { vassalForm.StatusText.Text = ex.Message; })); |
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
// Enable controls |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
vassalForm.RegionTeleportGroup.Enabled = true; |
|
switch (selectedEstateListType) |
{ |
case "ban": |
case "manager": |
case "user": |
EstateListsResidentsGroup.Enabled = true; |
EstateListsGroupsGroup.Enabled = false; |
break; |
case "group": |
EstateListsResidentsGroup.Enabled = false; |
EstateListsGroupsGroup.Enabled = true; |
break; |
} |
})); |
} |
}) |
{IsBackground = true}.Start(); |
} |
|
private void RequestRemoveEstateListMember(object sender, EventArgs e) |
{ |
// Get the estate list type. |
string selectedEstateListType = string.Empty; |
bool queryEstateList = false; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
if (vassalForm.EstateListSelectBox.SelectedItem == null) |
{ |
queryEstateList = false; |
return; |
} |
selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString(); |
switch ( |
!string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1) |
{ |
case true: |
queryEstateList = true; |
break; |
default: |
queryEstateList = false; |
break; |
} |
})); |
|
// If not estate list type is selected then return. |
if (!queryEstateList) return; |
|
// Enqueue all the regions to restart. |
Queue<UUID> estateListMembersQueue = new Queue<UUID>(); |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
foreach ( |
DataGridViewRow estateListRow in |
EstateListGridView.Rows.AsParallel() |
.Cast<DataGridViewRow>() |
.Where(o => o.Selected || o.Cells.Cast<DataGridViewCell>().Any(p => p.Selected))) |
{ |
UUID estateListMemberUUID; |
if (!UUID.TryParse(estateListRow.Cells["EstateListUUID"].Value.ToString(), |
out estateListMemberUUID)) |
continue; |
estateListMembersQueue.Enqueue(estateListMemberUUID); |
} |
})); |
|
// If no rows were selected, enable teleports, the return button and return. |
if (estateListMembersQueue.Count.Equals(0)) return; |
|
// Block teleports and disable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = false; |
RemoveEstateListMemberButton.Enabled = false; |
})); |
|
new Thread(() => |
{ |
try |
{ |
Monitor.Enter(ClientInstanceTeleportLock); |
UUID memberUUID = UUID.Zero; |
do |
{ |
try |
{ |
memberUUID = estateListMembersQueue.Dequeue(); |
|
// Remove the agent or group from the list. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "setestatelist"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"type", selectedEstateListType}, |
{"action", "remove"}, |
{selectedEstateListType.Equals("group") ? "target" : "agent", memberUUID.ToString()} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade"); |
|
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved"); |
|
if (!success) |
throw new Exception("Unable to remove member"); |
|
vassalForm.Invoke((MethodInvoker) (() => |
{ |
foreach ( |
int i in |
EstateListGridView.Rows.AsParallel() |
.Cast<DataGridViewRow>() |
.Where( |
o => |
o.Cells["EstateListUUID"].Value.ToString() |
.Equals(memberUUID.ToString(), |
StringComparison.OrdinalIgnoreCase)).Select(o => o.Index) |
) |
{ |
EstateListGridView.Rows.RemoveAt(i); |
} |
})); |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke( |
(MethodInvoker) (() => { StatusText.Text = ex.Message + @": " + memberUUID; })); |
} |
} while (!estateListMembersQueue.Count.Equals(0)); |
} |
catch (Exception) |
{ |
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
// Enable teleports and enable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = true; |
RemoveEstateListMemberButton.Enabled = true; |
})); |
} |
}) |
{IsBackground = true}.Start(); |
} |
|
private void RequestEstateListsAddResident(object sender, EventArgs e) |
{ |
// Get the estate list type. |
string selectedEstateListType = string.Empty; |
bool queryEstateList = false; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString(); |
switch ( |
!string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1) |
{ |
case true: |
queryEstateList = true; |
break; |
default: |
queryEstateList = false; |
break; |
} |
})); |
|
// If not estate list type is selected then return. |
if (!queryEstateList) return; |
|
string firstName = string.Empty; |
string lastName = string.Empty; |
|
vassalForm.Invoke((MethodInvoker) (() => |
{ |
switch (string.IsNullOrEmpty(EstateListsResidentFirstName.Text)) |
{ |
case true: |
EstateListsResidentFirstName.BackColor = Color.MistyRose; |
return; |
default: |
EstateListsResidentFirstName.BackColor = Color.Empty; |
break; |
} |
firstName = EstateListsResidentFirstName.Text; |
switch (string.IsNullOrEmpty(EstateListsResidentLastName.Text)) |
{ |
case true: |
EstateListsResidentLastName.BackColor = Color.MistyRose; |
return; |
default: |
EstateListsResidentLastName.BackColor = Color.Empty; |
break; |
} |
lastName = EstateListsResidentLastName.Text; |
})); |
|
if (string.IsNullOrEmpty(firstName) || string.IsNullOrEmpty(lastName)) return; |
|
// Block teleports and disable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = false; |
EstateListsResidentsGroup.Enabled = false; |
})); |
|
new Thread(() => |
{ |
try |
{ |
Monitor.Enter(ClientInstanceTeleportLock); |
|
// Add the resident to the list. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "setestatelist"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"type", selectedEstateListType}, |
{"action", "add"}, |
{"firstname", firstName}, |
{"lastname", lastName} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade"); |
|
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved"); |
|
if (!success) |
throw new Exception("Unable to add resident"); |
|
// Retrieve the estate list for updates. |
result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "getestatelist"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"type", selectedEstateListType} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade."); |
|
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved."); |
|
if (!success) |
throw new Exception("Could not retrieve estate list."); |
|
vassalForm.Invoke((MethodInvoker) (() => { EstateListGridView.Rows.Clear(); })); |
foreach (List<string> data in wasCSVToEnumerable(wasInput(wasKeyValueGet("data", result))) |
.Where(x => !string.IsNullOrEmpty(x)) |
.Select((x, i) => new {Index = i, Value = x}) |
.GroupBy(x => x.Index/2) |
.Select(x => x.Select(v => v.Value).ToList()).Where(x => x.Count.Equals(2))) |
{ |
vassalForm.Invoke( |
(MethodInvoker) (() => { EstateListGridView.Rows.Add(data.First(), data.Last()); })); |
} |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke( |
(MethodInvoker) (() => { StatusText.Text = ex.Message + @": " + firstName + @" " + lastName; })); |
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
// Enable teleports and enable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = true; |
EstateListsResidentsGroup.Enabled = true; |
})); |
} |
}) |
{IsBackground = true}.Start(); |
} |
|
private void RequestEstateListsAddGroup(object sender, EventArgs e) |
{ |
// Get the estate list type. |
string selectedEstateListType = string.Empty; |
bool queryEstateList = false; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString(); |
switch ( |
!string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1) |
{ |
case true: |
queryEstateList = true; |
break; |
default: |
queryEstateList = false; |
break; |
} |
})); |
|
// If not estate list type is selected then return. |
if (!queryEstateList) return; |
|
string target = string.Empty; |
|
vassalForm.Invoke((MethodInvoker) (() => |
{ |
switch (string.IsNullOrEmpty(EstateListsAddGroupBox.Text)) |
{ |
case true: |
EstateListsAddGroupBox.BackColor = Color.MistyRose; |
return; |
default: |
EstateListsAddGroupBox.BackColor = Color.Empty; |
break; |
} |
target = EstateListsAddGroupBox.Text; |
})); |
|
if (string.IsNullOrEmpty(target)) return; |
|
// Block teleports and disable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = false; |
EstateListsGroupsGroup.Enabled = false; |
})); |
|
new Thread(() => |
{ |
try |
{ |
Monitor.Enter(ClientInstanceTeleportLock); |
|
// Add the group to the list. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "setestatelist"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"type", selectedEstateListType}, |
{"action", "add"}, |
{"target", target} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade"); |
|
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved"); |
|
if (!success) |
throw new Exception("Unable to add group"); |
|
// Retrieve the estate list for updates. |
result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "getestatelist"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"type", selectedEstateListType} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade."); |
|
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved."); |
|
if (!success) |
throw new Exception("Could not retrieve estate list."); |
|
vassalForm.Invoke((MethodInvoker) (() => { EstateListGridView.Rows.Clear(); })); |
foreach (List<string> data in wasCSVToEnumerable(wasInput(wasKeyValueGet("data", result))) |
.Where(x => !string.IsNullOrEmpty(x)) |
.Select((x, i) => new {Index = i, Value = x}) |
.GroupBy(x => x.Index/2) |
.Select(x => x.Select(v => v.Value).ToList()).Where(x => x.Count.Equals(2))) |
{ |
vassalForm.Invoke( |
(MethodInvoker) (() => { EstateListGridView.Rows.Add(data.First(), data.Last()); })); |
} |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message + @": " + target; })); |
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
// Enable teleports and enable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = true; |
EstateListsGroupsGroup.Enabled = true; |
})); |
} |
}) |
{IsBackground = true}.Start(); |
} |
|
private void RequestRegionDebugApply(object sender, EventArgs e) |
{ |
// Block teleports and disable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = false; |
ApplyRegionDebugButton.Enabled = false; |
})); |
|
new Thread(() => |
{ |
try |
{ |
Monitor.Enter(ClientInstanceTeleportLock); |
|
bool scripts = false; |
bool collisons = false; |
bool physics = false; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
scripts = RegionDebugScriptsBox.Checked; |
collisons = RegionDebugCollisionsBox.Checked; |
physics = RegionDebugPhysicsBox.Checked; |
})); |
|
// Set the debug settings. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "setregiondebug"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"scripts", scripts.ToString()}, |
{"collisions", collisons.ToString()}, |
{"physics", physics.ToString()} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade"); |
|
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved"); |
|
if (!success) |
throw new Exception("Unable to set region debug"); |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); |
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
} |
|
// Block teleports and disable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = true; |
ApplyRegionDebugButton.Enabled = true; |
})); |
}) |
{IsBackground = true}.Start(); |
} |
|
private void RequestApplyRegionInfo(object sender, EventArgs e) |
{ |
// Block teleports and disable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = false; |
ApplyRegionInfoButton.Enabled = false; |
})); |
|
new Thread(() => |
{ |
try |
{ |
Monitor.Enter(ClientInstanceTeleportLock); |
|
bool terraform = false; |
bool fly = false; |
bool damage = false; |
bool resell = false; |
bool push = false; |
bool parcel = false; |
bool mature = false; |
uint agentLimit = 20; |
double objectBonus = 2.0; |
|
bool run = false; |
|
vassalForm.Invoke((MethodInvoker) (() => |
{ |
terraform = RegionInfoTerraformBox.Checked; |
fly = RegionInfoFlyBox.Checked; |
damage = RegionInfoDamageBox.Checked; |
resell = RegioninfoResellBox.Checked; |
push = RegionInfoPushBox.Checked; |
parcel = RegionInfoParcelBox.Checked; |
mature = RegionInfoMatureBox.Checked; |
switch (!uint.TryParse(RegionInfoAgentLimitBox.Text, out agentLimit)) |
{ |
case true: |
RegionInfoAgentLimitBox.BackColor = Color.MistyRose; |
return; |
default: |
RegionInfoAgentLimitBox.BackColor = Color.Empty; |
run = true; |
break; |
} |
switch (!double.TryParse(RegionInfoObjectBonusBox.Text, out objectBonus)) |
{ |
case true: |
RegionInfoObjectBonusBox.BackColor = Color.MistyRose; |
return; |
default: |
RegionInfoAgentLimitBox.BackColor = Color.Empty; |
break; |
} |
|
run = true; |
})); |
|
if (!run) return; |
|
// Set the debug settings. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "setregioninfo"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"terraform", terraform.ToString()}, |
{"fly", fly.ToString()}, |
{"damage", damage.ToString()}, |
{"resell", resell.ToString()}, |
{"push", push.ToString()}, |
{"parcel", parcel.ToString()}, |
{"mature", mature.ToString()}, |
{"limit", agentLimit.ToString(Utils.EnUsCulture)}, |
{"bonus", objectBonus.ToString(Utils.EnUsCulture)} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade"); |
|
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved"); |
|
if (!success) |
throw new Exception("Unable to set region info"); |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); |
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
} |
|
// Block teleports and disable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = true; |
ApplyRegionInfoButton.Enabled = true; |
})); |
}) |
{IsBackground = true}.Start(); |
} |
|
private void RequestEstateTexturesApply(object sender, EventArgs e) |
{ |
List<UUID> groundTextureUUIDs = new List<UUID>(); |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
UUID textureUUID; |
switch (!UUID.TryParse(RegionTexturesLowUUIDApplyBox.Text, out textureUUID)) |
{ |
case true: |
RegionTexturesLowUUIDApplyBox.BackColor = Color.MistyRose; |
return; |
default: |
RegionTexturesLowUUIDApplyBox.BackColor = Color.Empty; |
break; |
} |
groundTextureUUIDs.Add(textureUUID); |
|
switch (!UUID.TryParse(RegionTexturesMiddleLowUUIDApplyBox.Text, out textureUUID)) |
{ |
case true: |
RegionTexturesMiddleLowUUIDApplyBox.BackColor = Color.MistyRose; |
return; |
default: |
RegionTexturesMiddleLowUUIDApplyBox.BackColor = Color.Empty; |
break; |
} |
groundTextureUUIDs.Add(textureUUID); |
|
switch (!UUID.TryParse(RegionTexturesMiddleHighUUIDApplyBox.Text, out textureUUID)) |
{ |
case true: |
RegionTexturesMiddleHighUUIDApplyBox.BackColor = Color.MistyRose; |
return; |
default: |
RegionTexturesMiddleHighUUIDApplyBox.BackColor = Color.Empty; |
break; |
} |
groundTextureUUIDs.Add(textureUUID); |
|
switch (!UUID.TryParse(RegionTexturesHighUUIDApplyBox.Text, out textureUUID)) |
{ |
case true: |
RegionTexturesHighUUIDApplyBox.BackColor = Color.MistyRose; |
return; |
default: |
RegionTexturesHighUUIDApplyBox.BackColor = Color.Empty; |
break; |
} |
groundTextureUUIDs.Add(textureUUID); |
})); |
|
if (!groundTextureUUIDs.Count.Equals(4)) return; |
|
// Block teleports and disable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = false; |
GroundTexturesGroup.Enabled = false; |
})); |
|
new Thread(() => |
{ |
try |
{ |
Monitor.Enter(ClientInstanceTeleportLock); |
|
// Set the debug settings. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "setregionterraintextures"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"data", wasEnumerableToCSV(groundTextureUUIDs.Select(o => o.ToString()))} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade"); |
|
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved"); |
|
if (!success) |
throw new Exception("Unable to apply estate ground textures"); |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); |
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
} |
|
// Block teleports and disable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = true; |
GroundTexturesGroup.Enabled = true; |
})); |
}) |
{IsBackground = true}; |
} |
|
private void RequestDownloadRegionTexture(object sender, EventArgs e) |
{ |
string textureName = string.Empty; |
UUID textureUUID = UUID.Zero; |
bool run = false; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
Button button = sender as Button; |
if (button == null) |
{ |
run = false; |
return; |
} |
textureName = button.Tag.ToString(); |
switch (textureName) |
{ |
case "Low": |
if (!UUID.TryParse(RegionTexturesLowUUIDBox.Text, out textureUUID)) |
{ |
run = false; |
return; |
} |
goto case "MiddleLow"; |
case "MiddleLow": |
if (!UUID.TryParse(RegionTexturesMiddleLowUUIDBox.Text, out textureUUID)) |
{ |
run = false; |
return; |
} |
goto case "MiddleHigh"; |
case "MiddleHigh": |
if (!UUID.TryParse(RegionTexturesMiddleHighUUIDBox.Text, out textureUUID)) |
{ |
run = false; |
return; |
} |
goto case "High"; |
case "High": |
if (!UUID.TryParse(RegionTexturesHighUUIDBox.Text, out textureUUID)) |
{ |
run = false; |
return; |
} |
run = true; |
break; |
} |
})); |
|
if (!run) return; |
|
// Block teleports and disable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = false; |
GroundTexturesGroup.Enabled = false; |
})); |
|
new Thread(() => |
{ |
try |
{ |
Monitor.Enter(ClientInstanceTeleportLock); |
|
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "download"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"item", textureUUID.ToString()}, |
{"type", "Texture"}, |
{"format", "Png"} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade"); |
|
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved"); |
|
byte[] mapImageBytes = Convert.FromBase64String(wasInput(wasKeyValueGet("data", result))); |
Image mapImage; |
using (MemoryStream memoryStream = new MemoryStream(mapImageBytes, 0, mapImageBytes.Length)) |
{ |
mapImage = Image.FromStream(memoryStream); |
} |
|
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
switch (vassalForm.SavePNGFileDialog.ShowDialog()) |
{ |
case DialogResult.OK: |
string file = vassalForm.SavePNGFileDialog.FileName; |
new Thread(() => |
{ |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
try |
{ |
vassalForm.StatusText.Text = @"saving texture..."; |
vassalForm.StatusProgress.Value = 0; |
|
mapImage.Save(file, ImageFormat.Png); |
|
vassalForm.StatusText.Text = @"texture saved"; |
vassalForm.StatusProgress.Value = 100; |
} |
catch (Exception ex) |
{ |
vassalForm.StatusText.Text = ex.Message; |
} |
finally |
{ |
mapImage.Dispose(); |
} |
})); |
}) |
{IsBackground = true}.Start(); |
break; |
} |
})); |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); |
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
} |
|
// Block teleports and disable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = true; |
GroundTexturesGroup.Enabled = true; |
})); |
}) |
{IsBackground = true}.Start(); |
} |
|
private void RequestEstateListsAddGroupsFromCSV(object sender, EventArgs e) |
{ |
// Get the estate list type. |
string selectedEstateListType = string.Empty; |
bool queryEstateList = false; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
if (vassalForm.EstateListSelectBox.SelectedItem == null) return; |
selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString(); |
switch ( |
!string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1) |
{ |
case true: |
queryEstateList = true; |
break; |
default: |
queryEstateList = false; |
break; |
} |
})); |
|
// If not estate list type is selected then return. |
if (!queryEstateList) return; |
|
Queue<KeyValuePair<string, UUID>> targets = new Queue<KeyValuePair<string, UUID>>(); |
|
vassalForm.Invoke((MethodInvoker) (() => |
{ |
switch (vassalForm.LoadCSVFile.ShowDialog()) |
{ |
case DialogResult.OK: |
string file = vassalForm.LoadCSVFile.FileName; |
try |
{ |
vassalForm.StatusText.Text = @"loading group list..."; |
vassalForm.StatusProgress.Value = 0; |
|
// import groups |
UUID targetUUID; |
foreach (KeyValuePair<string, UUID> target in |
File.ReadAllLines(file) |
.AsParallel() |
.Select(o => new List<string>(wasCSVToEnumerable(o))) |
.Where(o => o.Count == 2) |
.ToDictionary(o => o.First(), |
p => |
UUID.TryParse(p.Last(), out targetUUID) |
? targetUUID |
: UUID.Zero)) |
{ |
targets.Enqueue(target); |
} |
|
vassalForm.StatusText.Text = @"group list loaded"; |
vassalForm.StatusProgress.Value = 100; |
} |
catch (Exception ex) |
{ |
vassalForm.StatusText.Text = ex.Message; |
} |
break; |
} |
})); |
|
if (targets.Count.Equals(0)) return; |
int initialQueueSize = targets.Count; |
|
// Block teleports and disable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = false; |
EstateListsGroupsGroup.Enabled = false; |
})); |
|
new Thread(() => |
{ |
try |
{ |
Monitor.Enter(ClientInstanceTeleportLock); |
|
do |
{ |
KeyValuePair<string, UUID> target = targets.Dequeue(); |
|
vassalForm.Invoke((MethodInvoker) (() => |
{ |
StatusText.Text = @"Adding to estate list: " + target.Key; |
vassalForm.StatusProgress.Value = |
Math.Min((int) (100d*Math.Abs(targets.Count - initialQueueSize)/initialQueueSize), 100); |
})); |
|
// Skip any items that already exist. |
bool run = false; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
run = |
!EstateListGridView.Rows.AsParallel() |
.Cast<DataGridViewRow>() |
.Any(o => o.Cells["EstateListUUID"].Value.ToString().Equals(target.Value.ToString())); |
})); |
if (!run) continue; |
|
// Skip broken UUIDs. |
if (target.Value.Equals(UUID.Zero)) continue; |
|
try |
{ |
// Add the group to the list. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "setestatelist"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"type", selectedEstateListType}, |
{"action", "add"}, |
{"target", target.Value.ToString()} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade"); |
|
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved"); |
|
if (!success) |
throw new Exception("Unable to add group"); |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke( |
(MethodInvoker) (() => { StatusText.Text = ex.Message + @": " + target.Value; })); |
} |
} while (!targets.Count.Equals(0)); |
|
// Retrieve the estate list. |
try |
{ |
// Retrieve the estate list for updates. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "getestatelist"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"type", selectedEstateListType} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade."); |
|
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved."); |
|
if (!success) |
throw new Exception("Could not retrieve estate list."); |
|
vassalForm.Invoke((MethodInvoker) (() => { EstateListGridView.Rows.Clear(); })); |
foreach (List<string> data in wasCSVToEnumerable(wasInput(wasKeyValueGet("data", result))) |
.Where(x => !string.IsNullOrEmpty(x)) |
.Select((x, i) => new {Index = i, Value = x}) |
.GroupBy(x => x.Index/2) |
.Select(x => x.Select(v => v.Value).ToList())) |
{ |
vassalForm.BeginInvoke( |
(MethodInvoker) (() => { EstateListGridView.Rows.Add(data.First(), data.Last()); })); |
} |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); |
} |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); |
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
// Enable teleports and enable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = true; |
EstateListsGroupsGroup.Enabled = true; |
})); |
} |
}) |
{IsBackground = true}.Start(); |
} |
|
private void RequestEstateListsAddResidentsFromCSV(object sender, EventArgs e) |
{ |
// Get the estate list type. |
string selectedEstateListType = string.Empty; |
bool queryEstateList = false; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
if (vassalForm.EstateListSelectBox.SelectedItem == null) return; |
selectedEstateListType = vassalForm.EstateListSelectBox.SelectedItem.ToString(); |
switch ( |
!string.IsNullOrEmpty(selectedEstateListType) && vassalForm.EstateListSelectBox.SelectedIndex != -1) |
{ |
case true: |
queryEstateList = true; |
break; |
default: |
queryEstateList = false; |
break; |
} |
})); |
|
// If not estate list type is selected then return. |
if (!queryEstateList) return; |
|
Queue<KeyValuePair<string, UUID>> targets = new Queue<KeyValuePair<string, UUID>>(); |
|
vassalForm.Invoke((MethodInvoker) (() => |
{ |
switch (vassalForm.LoadCSVFile.ShowDialog()) |
{ |
case DialogResult.OK: |
string file = vassalForm.LoadCSVFile.FileName; |
try |
{ |
vassalForm.StatusText.Text = @"loading residents list..."; |
vassalForm.StatusProgress.Value = 0; |
|
// import groups |
UUID targetUUID; |
foreach (KeyValuePair<string, UUID> target in |
File.ReadAllLines(file) |
.AsParallel() |
.Select(o => new List<string>(wasCSVToEnumerable(o))) |
.Where(o => o.Count == 2) |
.ToDictionary(o => o.First(), |
p => |
UUID.TryParse(p.Last(), out targetUUID) |
? targetUUID |
: UUID.Zero)) |
{ |
targets.Enqueue(target); |
} |
|
vassalForm.StatusText.Text = @"residents list loaded"; |
vassalForm.StatusProgress.Value = 100; |
} |
catch (Exception ex) |
{ |
vassalForm.StatusText.Text = ex.Message; |
} |
break; |
} |
})); |
|
if (targets.Count.Equals(0)) return; |
int initialQueueSize = targets.Count; |
|
// Block teleports and disable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = false; |
EstateListsResidentsGroup.Enabled = false; |
})); |
|
new Thread(() => |
{ |
try |
{ |
Monitor.Enter(ClientInstanceTeleportLock); |
|
do |
{ |
KeyValuePair<string, UUID> target = targets.Dequeue(); |
|
vassalForm.Invoke((MethodInvoker) (() => |
{ |
StatusText.Text = @"Adding to estate list: " + target.Key; |
vassalForm.StatusProgress.Value = |
Math.Min((int) (100d*Math.Abs(targets.Count - initialQueueSize)/initialQueueSize), 100); |
})); |
|
// Skip any items that already exist. |
bool run = false; |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
run = |
!EstateListGridView.Rows.AsParallel() |
.Cast<DataGridViewRow>() |
.Any(o => o.Cells["EstateListUUID"].Value.ToString().Equals(target.Value.ToString())); |
})); |
if (!run) continue; |
|
// Skip broken UUIDs. |
if (target.Value.Equals(UUID.Zero)) continue; |
|
try |
{ |
// Add the group to the list. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "setestatelist"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"type", selectedEstateListType}, |
{"action", "add"}, |
{"agent", target.Value.ToString()} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade"); |
|
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved"); |
|
if (!success) |
throw new Exception("Unable to add resident"); |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke( |
(MethodInvoker) (() => { StatusText.Text = ex.Message + @": " + target.Value; })); |
} |
} while (!targets.Count.Equals(0)); |
|
// Retrieve the estate list. |
try |
{ |
// Retrieve the estate list for updates. |
string result = wasPOST(vassalConfiguration.HTTPServerURL, |
wasKeyValueEscape(new Dictionary<string, string> |
{ |
{"command", "getestatelist"}, |
{"group", vassalConfiguration.Group}, |
{"password", vassalConfiguration.Password}, |
{"type", selectedEstateListType} |
}), vassalConfiguration.DataTimeout); |
|
if (string.IsNullOrEmpty(result)) |
throw new Exception("Error communicating with Corrade."); |
|
bool success; |
if (!bool.TryParse(wasInput(wasKeyValueGet("success", result)), out success)) |
throw new Exception("No success status could be retrieved."); |
|
if (!success) |
throw new Exception("Could not retrieve estate list."); |
|
vassalForm.Invoke((MethodInvoker) (() => { EstateListGridView.Rows.Clear(); })); |
foreach (List<string> data in wasCSVToEnumerable(wasInput(wasKeyValueGet("data", result))) |
.Where(x => !string.IsNullOrEmpty(x)) |
.Select((x, i) => new {Index = i, Value = x}) |
.GroupBy(x => x.Index/2) |
.Select(x => x.Select(v => v.Value).ToList())) |
{ |
vassalForm.BeginInvoke( |
(MethodInvoker) (() => { EstateListGridView.Rows.Add(data.First(), data.Last()); })); |
} |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); |
} |
} |
catch (Exception ex) |
{ |
vassalForm.Invoke((MethodInvoker) (() => { StatusText.Text = ex.Message; })); |
} |
finally |
{ |
Monitor.Exit(ClientInstanceTeleportLock); |
// Enable teleports and enable button. |
vassalForm.Invoke((MethodInvoker) (() => |
{ |
RegionTeleportGroup.Enabled = true; |
EstateListsResidentsGroup.Enabled = true; |
})); |
} |
}) |
{IsBackground = true}.Start(); |
} |
|
private void RequestExportEstateList(object sender, EventArgs e) |
{ |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
switch (vassalForm.ExportCSVDialog.ShowDialog()) |
{ |
case DialogResult.OK: |
string file = vassalForm.ExportCSVDialog.FileName; |
new Thread(() => |
{ |
vassalForm.BeginInvoke((MethodInvoker) (() => |
{ |
try |
{ |
vassalForm.StatusText.Text = @"exporting..."; |
vassalForm.StatusProgress.Value = 0; |
|
using (StreamWriter streamWriter = new StreamWriter(file, false, Encoding.UTF8)) |
{ |
foreach (DataGridViewRow estateListRow in EstateListGridView.Rows) |
{ |
streamWriter.WriteLine(wasEnumerableToCSV(new[] |
{ |
estateListRow.Cells["EstateListName"].Value.ToString(), |
estateListRow.Cells["EstateListUUID"].Value.ToString() |
})); |
} |
} |
|
vassalForm.StatusText.Text = @"exported"; |
vassalForm.StatusProgress.Value = 100; |
} |
catch (Exception ex) |
{ |
vassalForm.StatusText.Text = ex.Message; |
} |
})); |
}) |
{IsBackground = true}.Start(); |
break; |
} |
})); |
} |
|
/// <summary> |
/// Linden constants. |
/// </summary> |
public struct LINDEN_CONSTANTS |
{ |
public struct ALERTS |
{ |
public const string NO_ROOM_TO_SIT_HERE = @"No room to sit here, try another spot."; |
|
public const string UNABLE_TO_SET_HOME = |
@"You can only set your 'Home Location' on your land or at a mainland Infohub."; |
|
public const string HOME_SET = @"Home position set."; |
} |
|
public struct ASSETS |
{ |
public struct NOTECARD |
{ |
public const string NEWLINE = "\n"; |
public const uint MAXIMUM_BODY_LENTH = 65536; |
} |
} |
|
public struct AVATARS |
{ |
public const uint SET_DISPLAY_NAME_SUCCESS = 200; |
public const string LASTNAME_PLACEHOLDER = @"Resident"; |
public const uint MAXIMUM_DISPLAY_NAME_CHARACTERS = 31; |
public const uint MINIMUM_DISPLAY_NAME_CHARACTERS = 1; |
public const uint MAXIMUM_NUMBER_OF_ATTACHMENTS = 38; |
|
public struct PROFILE |
{ |
public const uint SECOND_LIFE_TEXT_SIZE = 510; |
public const uint FIRST_LIFE_TEXT_SIZE = 253; |
} |
|
public struct PICKS |
{ |
public const uint MAXIMUM_PICKS = 10; |
public const uint MAXIMUM_PICK_DESCRIPTION_SIZE = 1022; |
} |
|
public struct CLASSIFIEDS |
{ |
public const uint MAXIMUM_CLASSIFIEDS = 100; |
} |
} |
|
public struct PRIMITIVES |
{ |
public const uint MAXIMUM_NAME_SIZE = 63; |
public const uint MAXIMUM_DESCRIPTION_SIZE = 127; |
public const double MAXIMUM_REZ_HEIGHT = 4096.0; |
public const double MINIMUM_SIZE_X = 0.01; |
public const double MINIMUM_SIZE_Y = 0.01; |
public const double MINIMUM_SIZE_Z = 0.01; |
public const double MAXIMUM_SIZE_X = 64.0; |
public const double MAXIMUM_SIZE_Y = 64.0; |
public const double MAXIMUM_SIZE_Z = 64.0; |
} |
|
public struct OBJECTS |
{ |
public const uint MAXIMUM_PRIMITIVE_COUNT = 256; |
} |
|
public struct DIRECTORY |
{ |
public struct EVENT |
{ |
public const uint SEARCH_RESULTS_COUNT = 200; |
} |
|
public struct GROUP |
{ |
public const uint SEARCH_RESULTS_COUNT = 100; |
} |
|
public struct LAND |
{ |
public const uint SEARCH_RESULTS_COUNT = 100; |
} |
|
public struct PEOPLE |
{ |
public const uint SEARCH_RESULTS_COUNT = 100; |
} |
} |
|
public struct ESTATE |
{ |
public const uint REGION_RESTART_DELAY = 120; |
public const uint MAXIMUM_BAN_LIST_LENGTH = 500; |
public const uint MAXIMUM_GROUP_LIST_LENGTH = 63; |
public const uint MAXIMUM_USER_LIST_LENGTH = 500; |
public const uint MAXIMUM_MANAGER_LIST_LENGTH = 10; |
|
public struct MESSAGES |
{ |
public const string REGION_RESTART_MESSAGE = @"restart"; |
} |
} |
|
public struct PARCELS |
{ |
public const double MAXIMUM_AUTO_RETURN_TIME = 999999; |
public const uint MINIMUM_AUTO_RETURN_TIME = 0; |
public const uint MAXIMUM_NAME_LENGTH = 63; |
public const uint MAXIMUM_DESCRIPTION_LENGTH = 255; |
} |
|
public struct GRID |
{ |
public const string SECOND_LIFE = @"Second Life"; |
public const string TIME_ZONE = @"Pacific Standard Time"; |
} |
|
public struct CHAT |
{ |
public const uint MAXIMUM_MESSAGE_LENGTH = 1024; |
} |
|
public struct GROUPS |
{ |
public const uint MAXIMUM_NUMBER_OF_ROLES = 10; |
public const string EVERYONE_ROLE_NAME = @"Everyone"; |
public const uint MAXIMUM_GROUP_NAME_LENGTH = 35; |
public const uint MAXIMUM_GROUP_TITLE_LENGTH = 20; |
} |
|
public struct NOTICES |
{ |
public const uint MAXIMUM_NOTICE_MESSAGE_LENGTH = 512; |
} |
|
public struct LSL |
{ |
public const string CSV_DELIMITER = @", "; |
public const float SENSOR_RANGE = 96; |
public const string DATE_TIME_STAMP = @"yyy-MM-ddTHH:mm:ss.ffffffZ"; |
} |
|
public struct REGION |
{ |
public const float TELEPORT_MINIMUM_DISTANCE = 1; |
public const float DEFAULT_AGENT_LIMIT = 40; |
public const float DEFAULT_OBJECT_BONUS = 1; |
public const bool DEFAULT_FIXED_SUN = false; |
public const float DEFAULT_TERRAIN_LOWER_LIMIT = -4; |
public const float DEFAULT_TERRAIN_RAISE_LIMIT = 4; |
public const bool DEFAULT_USE_ESTATE_SUN = true; |
public const float DEFAULT_WATER_HEIGHT = 20; |
public const float SUNRISE = 6; |
} |
|
public struct VIEWER |
{ |
public const float MAXIMUM_DRAW_DISTANCE = 4096; |
} |
|
public struct TELEPORTS |
{ |
public struct THROTTLE |
{ |
public const uint MAX_TELEPORTS = 10; |
public const uint GRACE_SECONDS = 15; |
} |
} |
} |
|
/// <summary> |
/// Constants used by Corrade. |
/// </summary> |
public struct VASSAL_CONSTANTS |
{ |
/// <summary> |
/// Copyright. |
/// </summary> |
public const string COPYRIGHT = @"(c) Copyright 2013 Wizardry and Steamworks"; |
|
public const string WIZARDRY_AND_STEAMWORKS = @"Wizardry and Steamworks"; |
public const string VASSAL = @"Vassal"; |
public const string WIZARDRY_AND_STEAMWORKS_WEBSITE = @"http://grimore.org"; |
|
/// <summary> |
/// Vassal version. |
/// </summary> |
public static readonly string VASSAL_VERSION = Assembly.GetEntryAssembly().GetName().Version.ToString(); |
|
/// <summary> |
/// Corrade user agent. |
/// </summary> |
public static readonly string USER_AGENT = |
$"{VASSAL}/{VASSAL_VERSION} ({WIZARDRY_AND_STEAMWORKS_WEBSITE})"; |
|
/// <summary> |
/// Vassal compile date. |
/// </summary> |
public static readonly string VASSAL_COMPILE_DATE = new DateTime(2000, 1, 1).Add(new TimeSpan( |
TimeSpan.TicksPerDay*Assembly.GetEntryAssembly().GetName().Version.Build + // days since 1 January 2000 |
TimeSpan.TicksPerSecond*2*Assembly.GetEntryAssembly().GetName().Version.Revision)).ToLongDateString(); |
|
/// <summary> |
/// Vassal configuration file. |
/// </summary> |
public static readonly string VASSAL_CONFIGURATION_FILE = @"Vassal.ini"; |
|
/// <summary> |
/// Vassal regions file. |
/// </summary> |
public static readonly string VASSAL_REGIONS = @"Regions.csv"; |
|
/// <summary> |
/// Conten-types that Corrade can send and receive. |
/// </summary> |
public struct CONTENT_TYPE |
{ |
public const string TEXT_PLAIN = @"text/plain"; |
public const string WWW_FORM_URLENCODED = @"application/x-www-form-urlencoded"; |
} |
} |
|
#region CRYPTOGRAPHY |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Gets a sub-array from an array. |
/// </summary> |
/// <typeparam name="T">the array type</typeparam> |
/// <param name="data">the array</param> |
/// <param name="start">the start index</param> |
/// <param name="stop">the stop index (-1 denotes the end)</param> |
/// <returns>the array slice between start and stop</returns> |
public static T[] wasGetSubArray<T>(T[] data, int start, int stop) |
{ |
if (stop.Equals(-1)) |
stop = data.Length - 1; |
T[] result = new T[stop - start + 1]; |
Array.Copy(data, start, result, 0, stop - start + 1); |
return result; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Delete a sub-array and return the result. |
/// </summary> |
/// <typeparam name="T">the array type</typeparam> |
/// <param name="data">the array</param> |
/// <param name="start">the start index</param> |
/// <param name="stop">the stop index (-1 denotes the end)</param> |
/// <returns>the array without elements between start and stop</returns> |
public static T[] wasDeleteSubArray<T>(T[] data, int start, int stop) |
{ |
if (stop.Equals(-1)) |
stop = data.Length - 1; |
T[] result = new T[data.Length - (stop - start) - 1]; |
Array.Copy(data, 0, result, 0, start); |
Array.Copy(data, stop + 1, result, start, data.Length - stop - 1); |
return result; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Concatenate multiple arrays. |
/// </summary> |
/// <typeparam name="T">the array type</typeparam> |
/// <param name="arrays">multiple arrays</param> |
/// <returns>a flat array with all arrays concatenated</returns> |
public static T[] wasConcatenateArrays<T>(params T[][] arrays) |
{ |
int resultLength = 0; |
foreach (T[] o in arrays) |
{ |
resultLength += o.Length; |
} |
T[] result = new T[resultLength]; |
int offset = 0; |
for (int x = 0; x < arrays.Length; x++) |
{ |
arrays[x].CopyTo(result, offset); |
offset += arrays[x].Length; |
} |
return result; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Permutes an array in reverse a given number of times. |
/// </summary> |
/// <typeparam name="T">the array type</typeparam> |
/// <param name="input">the array</param> |
/// <param name="times">the number of times to permute</param> |
/// <returns>the array with the elements permuted</returns> |
private static T[] wasReversePermuteArrayElements<T>(T[] input, int times) |
{ |
if (times.Equals(0)) return input; |
T[] slice = new T[input.Length]; |
Array.Copy(input, 1, slice, 0, input.Length - 1); |
Array.Copy(input, 0, slice, input.Length - 1, 1); |
return wasReversePermuteArrayElements(slice, --times); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Permutes an array forward a given number of times. |
/// </summary> |
/// <typeparam name="T">the array type</typeparam> |
/// <param name="input">the array</param> |
/// <param name="times">the number of times to permute</param> |
/// <returns>the array with the elements permuted</returns> |
private static T[] wasForwardPermuteArrayElements<T>(T[] input, int times) |
{ |
if (times.Equals(0)) return input; |
T[] slice = new T[input.Length]; |
Array.Copy(input, input.Length - 1, slice, 0, 1); |
Array.Copy(input, 0, slice, 1, input.Length - 1); |
return wasForwardPermuteArrayElements(slice, --times); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Encrypt or decrypt a message given a set of rotors, plugs and a reflector. |
/// </summary> |
/// <param name="message">the message to encyrpt or decrypt</param> |
/// <param name="rotors">any combination of: 1, 2, 3, 4, 5, 6, 7, 8, b, g</param> |
/// <param name="plugs">the letter representing the start character for the rotor</param> |
/// <param name="reflector">any one of: B, b, C, c</param> |
/// <returns>either a decrypted or encrypted string</returns> |
private static string wasEnigma(string message, char[] rotors, char[] plugs, char reflector) |
{ |
Dictionary<char, char[]> def_rotors = new Dictionary<char, char[]> |
{ |
{ |
'1', new[] |
{ |
'e', 'k', 'm', 'f', 'l', |
'g', 'd', 'q', 'v', 'z', |
'n', 't', 'o', 'w', 'y', |
'h', 'x', 'u', 's', 'p', |
'a', 'i', 'b', 'r', 'c', |
'j' |
} |
}, |
{ |
'2', new[] |
{ |
'a', 'j', 'd', 'k', 's', |
'i', 'r', 'u', 'x', 'b', |
'l', 'h', 'w', 't', 'm', |
'c', 'q', 'g', 'z', 'n', |
'p', 'y', 'f', 'v', 'o', |
'e' |
} |
}, |
{ |
'3', new[] |
{ |
'b', 'd', 'f', 'h', 'j', |
'l', 'c', 'p', 'r', 't', |
'x', 'v', 'z', 'n', 'y', |
'e', 'i', 'w', 'g', 'a', |
'k', 'm', 'u', 's', 'q', |
'o' |
} |
}, |
{ |
'4', new[] |
{ |
'e', 's', 'o', 'v', 'p', |
'z', 'j', 'a', 'y', 'q', |
'u', 'i', 'r', 'h', 'x', |
'l', 'n', 'f', 't', 'g', |
'k', 'd', 'c', 'm', 'w', |
'b' |
} |
}, |
{ |
'5', new[] |
{ |
'v', 'z', 'b', 'r', 'g', |
'i', 't', 'y', 'u', 'p', |
's', 'd', 'n', 'h', 'l', |
'x', 'a', 'w', 'm', 'j', |
'q', 'o', 'f', 'e', 'c', |
'k' |
} |
}, |
{ |
'6', new[] |
{ |
'j', 'p', 'g', 'v', 'o', |
'u', 'm', 'f', 'y', 'q', |
'b', 'e', 'n', 'h', 'z', |
'r', 'd', 'k', 'a', 's', |
'x', 'l', 'i', 'c', 't', |
'w' |
} |
}, |
{ |
'7', new[] |
{ |
'n', 'z', 'j', 'h', 'g', |
'r', 'c', 'x', 'm', 'y', |
's', 'w', 'b', 'o', 'u', |
'f', 'a', 'i', 'v', 'l', |
'p', 'e', 'k', 'q', 'd', |
't' |
} |
}, |
{ |
'8', new[] |
{ |
'f', 'k', 'q', 'h', 't', |
'l', 'x', 'o', 'c', 'b', |
'j', 's', 'p', 'd', 'z', |
'r', 'a', 'm', 'e', 'w', |
'n', 'i', 'u', 'y', 'g', |
'v' |
} |
}, |
{ |
'b', new[] |
{ |
'l', 'e', 'y', 'j', 'v', |
'c', 'n', 'i', 'x', 'w', |
'p', 'b', 'q', 'm', 'd', |
'r', 't', 'a', 'k', 'z', |
'g', 'f', 'u', 'h', 'o', |
's' |
} |
}, |
{ |
'g', new[] |
{ |
'f', 's', 'o', 'k', 'a', |
'n', 'u', 'e', 'r', 'h', |
'm', 'b', 't', 'i', 'y', |
'c', 'w', 'l', 'q', 'p', |
'z', 'x', 'v', 'g', 'j', |
'd' |
} |
} |
}; |
|
Dictionary<char, char[]> def_reflectors = new Dictionary<char, char[]> |
{ |
{ |
'B', new[] |
{ |
'a', 'y', 'b', 'r', 'c', 'u', 'd', 'h', |
'e', 'q', 'f', 's', 'g', 'l', 'i', 'p', |
'j', 'x', 'k', 'n', 'm', 'o', 't', 'z', |
'v', 'w' |
} |
}, |
{ |
'b', new[] |
{ |
'a', 'e', 'b', 'n', 'c', 'k', 'd', 'q', |
'f', 'u', 'g', 'y', 'h', 'w', 'i', 'j', |
'l', 'o', 'm', 'p', 'r', 'x', 's', 'z', |
't', 'v' |
} |
}, |
{ |
'C', new[] |
{ |
'a', 'f', 'b', 'v', 'c', 'p', 'd', 'j', |
'e', 'i', 'g', 'o', 'h', 'y', 'k', 'r', |
'l', 'z', 'm', 'x', 'n', 'w', 't', 'q', |
's', 'u' |
} |
}, |
{ |
'c', new[] |
{ |
'a', 'r', 'b', 'd', 'c', 'o', 'e', 'j', |
'f', 'n', 'g', 't', 'h', 'k', 'i', 'v', |
'l', 'm', 'p', 'w', 'q', 'z', 's', 'x', |
'u', 'y' |
} |
} |
}; |
|
// Setup rotors from plugs. |
foreach (char rotor in rotors) |
{ |
char plug = plugs[Array.IndexOf(rotors, rotor)]; |
int i = Array.IndexOf(def_rotors[rotor], plug); |
if (i.Equals(0)) continue; |
def_rotors[rotor] = wasConcatenateArrays(new[] {plug}, |
wasGetSubArray(wasDeleteSubArray(def_rotors[rotor], i, i), i, -1), |
wasGetSubArray(wasDeleteSubArray(def_rotors[rotor], i + 1, -1), 0, i - 1)); |
} |
|
StringBuilder result = new StringBuilder(); |
foreach (char c in message) |
{ |
if (!char.IsLetter(c)) |
{ |
result.Append(c); |
continue; |
} |
|
// Normalize to lower. |
char l = char.ToLower(c); |
|
Action<char[]> rotate = o => |
{ |
int i = o.Length - 1; |
do |
{ |
def_rotors[o[0]] = wasForwardPermuteArrayElements(def_rotors[o[0]], 1); |
if (i.Equals(0)) |
{ |
rotors = wasReversePermuteArrayElements(o, 1); |
continue; |
} |
l = wasGetElementAt(def_rotors[o[1]], Array.IndexOf(def_rotors[o[0]], l) - 1); |
o = wasReversePermuteArrayElements(o, 1); |
} while (--i > -1); |
}; |
|
// Forward pass through the Enigma's rotors. |
rotate.Invoke(rotors); |
|
// Reflect |
int x = Array.IndexOf(def_reflectors[reflector], l); |
l = (x + 1)%2 == 0 ? def_reflectors[reflector][x - 1] : def_reflectors[reflector][x + 1]; |
|
// Reverse the order of the rotors. |
Array.Reverse(rotors); |
|
// Reverse pass through the Enigma's rotors. |
rotate.Invoke(rotors); |
|
if (char.IsUpper(c)) |
{ |
l = char.ToUpper(l); |
} |
result.Append(l); |
} |
|
return result.ToString(); |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Expand the VIGENRE key to the length of the input. |
/// </summary> |
/// <param name="input">the input to expand to</param> |
/// <param name="enc_key">the key to expand</param> |
/// <returns>the expanded key</returns> |
private static string wasVigenereExpandKey(string input, string enc_key) |
{ |
string exp_key = string.Empty; |
int i = 0, j = 0; |
do |
{ |
char p = input[i]; |
if (!char.IsLetter(p)) |
{ |
exp_key += p; |
++i; |
continue; |
} |
int m = j%enc_key.Length; |
exp_key += enc_key[m]; |
++j; |
++i; |
} while (i < input.Length); |
return exp_key; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Encrypt using VIGENERE. |
/// </summary> |
/// <param name="input">the input to encrypt</param> |
/// <param name="enc_key">the key to encrypt with</param> |
/// <returns>the encrypted input</returns> |
private static string wasEncryptVIGENERE(string input, string enc_key) |
{ |
char[] a = |
{ |
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', |
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' |
}; |
|
enc_key = wasVigenereExpandKey(input, enc_key); |
string result = string.Empty; |
int i = 0; |
do |
{ |
char p = input[i]; |
if (!char.IsLetter(p)) |
{ |
result += p; |
++i; |
continue; |
} |
char q = |
wasReversePermuteArrayElements(a, Array.IndexOf(a, enc_key[i]))[ |
Array.IndexOf(a, char.ToLowerInvariant(p))]; |
if (char.IsUpper(p)) |
{ |
q = char.ToUpperInvariant(q); |
} |
result += q; |
++i; |
} while (i < input.Length); |
return result; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2014 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// Decrypt using VIGENERE. |
/// </summary> |
/// <param name="input">the input to decrypt</param> |
/// <param name="enc_key">the key to decrypt with</param> |
/// <returns>the decrypted input</returns> |
private static string wasDecryptVIGENERE(string input, string enc_key) |
{ |
char[] a = |
{ |
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', |
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' |
}; |
|
enc_key = wasVigenereExpandKey(input, enc_key); |
string result = string.Empty; |
int i = 0; |
do |
{ |
char p = input[i]; |
if (!char.IsLetter(p)) |
{ |
result += p; |
++i; |
continue; |
} |
char q = |
a[ |
Array.IndexOf(wasReversePermuteArrayElements(a, Array.IndexOf(a, enc_key[i])), |
char.ToLowerInvariant(p))]; |
if (char.IsUpper(p)) |
{ |
q = char.ToUpperInvariant(q); |
} |
result += q; |
++i; |
} while (i < input.Length); |
return result; |
} |
|
/////////////////////////////////////////////////////////////////////////// |
// Copyright (C) Wizardry and Steamworks 2015 - License: GNU GPLv3 // |
/////////////////////////////////////////////////////////////////////////// |
/// <summary> |
/// An implementation of the ATBASH cypher for latin alphabets. |
/// </summary> |
/// <param name="data">the data to encrypt or decrypt</param> |
/// <returns>the encrypted or decrypted data</returns> |
private static string wasATBASH(string data) |
{ |
char[] a = |
{ |
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', |
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' |
}; |
|
char[] input = data.ToArray(); |
|
Parallel.ForEach(Enumerable.Range(0, data.Length), i => |
{ |
char e = input[i]; |
if (!char.IsLetter(e)) return; |
int x = 25 - Array.BinarySearch(a, char.ToLowerInvariant(e)); |
if (!char.IsUpper(e)) |
{ |
input[i] = a[x]; |
return; |
} |
input[i] = char.ToUpperInvariant(a[x]); |
}); |
|
return new string(input); |
} |
|
#endregion |
} |
} |
} |