474 lines
16 KiB
C#
474 lines
16 KiB
C#
// /**
|
|
// ********
|
|
// *
|
|
// * ORIGINAL CODE BASE IS Copyright (C) 2006-2010 by Alphons van der Heijden
|
|
// * The code was donated on 4/28/2010 by Alphons van der Heijden
|
|
// * To Brandon 'Dimentox Travanti' Husbands & Malcolm J. Kudra, who in turn License under the GPLv2.
|
|
// * In agreement with Alphons van der Heijden's wishes.
|
|
// *
|
|
// * The community would like to thank Alphons for all of his hard work, blood sweat and tears.
|
|
// * Without his work the community would be stuck with crappy editors.
|
|
// *
|
|
// * The source code in this file ("Source Code") is provided by The LSLEditor Group
|
|
// * to you under the terms of the GNU General Public License, version 2.0
|
|
// * ("GPL"), unless you have obtained a separate licensing agreement
|
|
// * ("Other License"), formally executed by you and The LSLEditor Group. Terms of
|
|
// * the GPL can be found in the gplv2.txt document.
|
|
// *
|
|
// ********
|
|
// * GPLv2 Header
|
|
// ********
|
|
// * LSLEditor, a External editor for the LSL Language.
|
|
// * Copyright (C) 2010 The LSLEditor Group.
|
|
//
|
|
// * This program is free software; you can redistribute it and/or
|
|
// * modify it under the terms of the GNU General Public License
|
|
// * as published by the Free Software Foundation; either version 2
|
|
// * of the License, or (at your option) any later version.
|
|
// *
|
|
// * This program is distributed in the hope that it will be useful,
|
|
// * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// * GNU General Public License for more details.
|
|
// *
|
|
// * You should have received a copy of the GNU General Public License
|
|
// * along with this program; if not, write to the Free Software
|
|
// * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
// ********
|
|
// *
|
|
// * The above copyright notice and this permission notice shall be included in all
|
|
// * copies or substantial portions of the Software.
|
|
// *
|
|
// ********
|
|
// */
|
|
using System;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
|
|
|
|
//
|
|
// (C) 2006,2007 Alphons van der Heijden
|
|
// mail: alphons@heijden.com
|
|
//
|
|
|
|
namespace LSLEditor
|
|
{
|
|
public enum CommunicationType
|
|
{
|
|
Whisper, Say, Shout, OwnerSay, RegionSay, RegionSayTo
|
|
}
|
|
|
|
public partial class SecondLife
|
|
{
|
|
// Make friends with my host
|
|
public SecondLifeHost host;
|
|
|
|
#region members
|
|
// Random generator
|
|
private Random m_random;
|
|
|
|
private DateTime m_DateTimeScriptStarted;
|
|
|
|
private Boolean m_AllowDrop = false;
|
|
private Hashtable m_LandPassList;
|
|
|
|
private Hashtable m_LandBanList;
|
|
|
|
private Float m_Volume;
|
|
|
|
private String m_ObjectName;
|
|
private String m_ParcelMusicURL;
|
|
private vector m_pos;
|
|
private rotation m_rot;
|
|
private rotation m_rotlocal;
|
|
private vector m_scale;
|
|
private String m_SitText;
|
|
private Float m_SoundRadius;
|
|
|
|
private vector m_RegionCorner;
|
|
|
|
private integer m_start_parameter;
|
|
|
|
#endregion
|
|
|
|
#region Properties
|
|
|
|
public vector GetLocalPos
|
|
{
|
|
// TODO change this to use a call to llGetLocalPos specifying NOT to be Verbose. After all functions have been changed to allow verbose/silent option.
|
|
get { return m_pos; }
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region constructor
|
|
public SecondLife()
|
|
{
|
|
host = null;
|
|
m_random = new Random();
|
|
m_DateTimeScriptStarted = DateTime.Now.ToUniversalTime();
|
|
m_LandPassList = new Hashtable();
|
|
m_LandBanList = new Hashtable();
|
|
m_Volume = 0.0;
|
|
m_ObjectName = null;
|
|
m_pos = new vector(127, 128, 20);
|
|
m_rot = rotation.ZERO_ROTATION;
|
|
m_rotlocal = rotation.ZERO_ROTATION;
|
|
m_scale = vector.ZERO_VECTOR;
|
|
m_SitText = "sittext";
|
|
m_SoundRadius = 1.0;
|
|
m_start_parameter = 0;
|
|
|
|
m_RegionCorner = vector.ZERO_VECTOR;
|
|
}
|
|
#endregion
|
|
|
|
#region internal routines
|
|
private void Verbose(string strLine, params object[] parameters)
|
|
{
|
|
if (parameters.Length == 0)
|
|
host.VerboseMessage(strLine);
|
|
else
|
|
host.VerboseMessage(string.Format(strLine, parameters));
|
|
}
|
|
|
|
private void Chat(integer channel, string message, CommunicationType how)
|
|
{
|
|
host.Chat(host, channel, host.GetObjectName(), host.GetKey(), message, how);
|
|
}
|
|
|
|
public void state(string strStateName)
|
|
{
|
|
Verbose("state->" + strStateName);
|
|
host.State(strStateName, false);
|
|
System.Threading.Thread.Sleep(1000);
|
|
System.Windows.Forms.MessageBox.Show("If you see this, something is wrong", "Oops...");
|
|
}
|
|
#endregion
|
|
|
|
#region Helper Functions
|
|
|
|
#region List Functions
|
|
|
|
private bool CorrectIt(int length, ref int start, ref int end)
|
|
{
|
|
if (start < 0)
|
|
start = length + start;
|
|
|
|
if (end < 0)
|
|
end = length + end;
|
|
|
|
if (start <= end)
|
|
{
|
|
if (start >= length)
|
|
return false;
|
|
if (end < 0)
|
|
return false;
|
|
}
|
|
|
|
start = Math.Max(0, start);
|
|
end = Math.Min(length - 1, end);
|
|
|
|
return true;
|
|
}
|
|
|
|
public ArrayList RandomShuffle(ArrayList collection)
|
|
{
|
|
// We have to copy all items anyway, and there isn't a way to produce the items
|
|
// on the fly that is linear. So copying to an array and shuffling it is as efficient as we can get.
|
|
|
|
if (collection == null)
|
|
throw new ArgumentNullException("collection");
|
|
|
|
int count = collection.Count;
|
|
for (int i = count - 1; i >= 1; --i)
|
|
{
|
|
// Pick an random number 0 through i inclusive.
|
|
int j = m_random.Next(i + 1);
|
|
|
|
// Swap array[i] and array[j]
|
|
object temp = collection[i];
|
|
collection[i] = collection[j];
|
|
collection[j] = temp;
|
|
}
|
|
return collection;
|
|
}
|
|
|
|
private ArrayList List2Buckets(list src, int stride)
|
|
{
|
|
ArrayList buckets = null;
|
|
if ((src.Count % stride) == 0 && stride <= src.Count)
|
|
{
|
|
buckets = new ArrayList();
|
|
for (int intI = 0; intI < src.Count; intI += stride)
|
|
{
|
|
object[] bucket = new object[stride];
|
|
for (int intJ = 0; intJ < stride; intJ++)
|
|
bucket[intJ] = src[intI + intJ];
|
|
buckets.Add(bucket);
|
|
}
|
|
}
|
|
return buckets;
|
|
}
|
|
|
|
private list Buckets2List(ArrayList buckets, int stride)
|
|
{
|
|
object[] items = new object[buckets.Count * stride];
|
|
for (int intI = 0; intI < buckets.Count; intI++)
|
|
{
|
|
for (int intJ = 0; intJ < stride; intJ++)
|
|
items[intI * stride + intJ] = ((object[])buckets[intI])[intJ];
|
|
}
|
|
return new list(items);
|
|
}
|
|
|
|
private class BucketComparer : IComparer
|
|
{
|
|
private integer ascending;
|
|
public BucketComparer(integer ascending)
|
|
{
|
|
this.ascending = ascending;
|
|
}
|
|
public int Compare(object x, object y)
|
|
{
|
|
object[] xx = x as object[];
|
|
object[] yy = y as object[];
|
|
|
|
object A, B;
|
|
|
|
if (ascending == TRUE)
|
|
{
|
|
A = xx[0];
|
|
B = yy[0];
|
|
}
|
|
else
|
|
{
|
|
B = xx[0];
|
|
A = yy[0];
|
|
}
|
|
|
|
string strType = A.GetType().ToString();
|
|
|
|
if (((A is string) && (B is string)) ||
|
|
((A is SecondLife.String) && (B is SecondLife.String)))
|
|
return string.Compare(A.ToString(), B.ToString());
|
|
|
|
if ((A is SecondLife.integer) && (B is SecondLife.integer))
|
|
return SecondLife.integer.Compare((SecondLife.integer)A, (SecondLife.integer)B);
|
|
|
|
if ((A is SecondLife.Float) && (B is SecondLife.Float))
|
|
return SecondLife.Float.Compare((SecondLife.Float)A, (SecondLife.Float)B);
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region String Functions
|
|
private list ParseString(String src, list separators, list spacers, bool blnKeepNulls)
|
|
{
|
|
list result = new list();
|
|
int intFrom = 0;
|
|
string s = src;
|
|
for (int intI = 0; intI < s.Length; intI++)
|
|
{
|
|
string strTmp = s.Substring(intI);
|
|
bool blnFound = false;
|
|
for (int intJ = 0; intJ < separators.Count; intJ++)
|
|
{
|
|
string strSeparator = separators[intJ].ToString();
|
|
if (strSeparator.Length == 0)
|
|
continue; // check this
|
|
if (strTmp.IndexOf(strSeparator) == 0)
|
|
{
|
|
string strBefore = s.Substring(intFrom, intI - intFrom);
|
|
if (strBefore != "" || blnKeepNulls)
|
|
result.Add(strBefore);
|
|
intI += strSeparator.Length - 1;
|
|
intFrom = intI + 1;
|
|
blnFound = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (blnFound)
|
|
continue;
|
|
|
|
for (int intJ = 0; intJ < spacers.Count; intJ++)
|
|
{
|
|
string strSpacer = spacers[intJ].ToString();
|
|
if (strSpacer.Length == 0)
|
|
continue; // check this
|
|
if (strTmp.IndexOf(strSpacer) == 0)
|
|
{
|
|
string strBefore = s.Substring(intFrom, intI - intFrom);
|
|
if (strBefore != "" || blnKeepNulls)
|
|
result.Add(strBefore);
|
|
result.Add(strSpacer);
|
|
intI += strSpacer.Length - 1;
|
|
intFrom = intI + 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
string strLast = s.Substring(intFrom);
|
|
if (strLast != "" || blnKeepNulls)
|
|
result.Add(strLast);
|
|
return result;
|
|
}
|
|
|
|
private string StringToBase64(string str)
|
|
{
|
|
byte[] data = Encoding.UTF8.GetBytes(str);
|
|
return Convert.ToBase64String(data);
|
|
}
|
|
|
|
private string Base64ToString(string str)
|
|
{
|
|
byte[] data = Convert.FromBase64String(str);
|
|
int intLen = Array.IndexOf(data, (byte)0x00);
|
|
if (intLen < 0)
|
|
intLen = data.Length;
|
|
return Encoding.UTF8.GetString(data, 0, intLen);
|
|
}
|
|
|
|
private int LookupBase64(string s, int intIndex)
|
|
{
|
|
if (intIndex < s.Length)
|
|
{
|
|
int intReturn = FastLookupBase64[s[intIndex]];
|
|
if (intReturn == 0)
|
|
if (s[intIndex] != 'A')
|
|
throw new Exception();
|
|
return intReturn;
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
static readonly int[] FastLookupBase64 =
|
|
{// 0 1 2 3 4 5 6 7 8 9 A B C D E F
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,62, 0, 0, 0,63, // 20
|
|
52,53,54,55,56,57,58,59,60,61, 0, 0, 0, 0, 0, 0, // 30
|
|
0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, // 40
|
|
15,16,17,18,19,20,21,22,23,24,25, 0, 0, 0, 0, 0, // 50
|
|
0,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, // 60
|
|
41,42,43,44,45,46,47,48,49,50,51, 0, 0, 0, 0, 0, // 70
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 90
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // A0
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // B0
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // C0
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // D0
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // E0
|
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // F0
|
|
#endregion
|
|
|
|
#region Math Functions
|
|
|
|
|
|
private integer ModPow1(integer a, integer b, integer c)
|
|
{
|
|
return (int)Math.Pow((int)a, (int)b & (int)0xffff) % (int)c;
|
|
}
|
|
|
|
private integer ModPow2(integer x, integer y, integer m)
|
|
{
|
|
if (!x) return 0;
|
|
integer k = 1 + (int)Math.Ceiling(Math.Log(Math.Abs(x)) / 0.69314718055994530941723212145818);//ceil(log2(x))
|
|
integer w = 32;
|
|
integer p = w / k;
|
|
integer r = y / p;
|
|
integer f = y % p;
|
|
integer z = 1;
|
|
if (r) z = ModPow2(ModPow1(x, p, m), r, m);
|
|
if (f) z = (z * ModPow1(x, f, m)) % m;
|
|
return z;
|
|
}
|
|
|
|
#endregion Math Functions
|
|
|
|
private List<double> GetListOfNumbers(list input)
|
|
{
|
|
List<double> result = new List<double>();
|
|
for (int intI = 0; intI < input.Count; intI++)
|
|
{
|
|
object objI = input[intI];
|
|
string strType = objI.GetType().ToString().Replace("LSLEditor.SecondLife+", "");
|
|
switch (strType)
|
|
{
|
|
case "Float":
|
|
result.Add(Convert.ToDouble((Float)objI));
|
|
break;
|
|
case "System.Int32":
|
|
result.Add(Convert.ToDouble((int)objI));
|
|
break;
|
|
case "System.Double":
|
|
result.Add(Convert.ToDouble((double)objI));
|
|
break;
|
|
case "integer":
|
|
result.Add(Convert.ToDouble((integer)objI));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private double GetAverage(double[] data)
|
|
{
|
|
try
|
|
{
|
|
double DataTotal = 0;
|
|
for (int i = 0; i < data.Length; i++)
|
|
{
|
|
DataTotal += data[i];
|
|
}
|
|
return SafeDivide(DataTotal, data.Length);
|
|
}
|
|
catch (Exception) { throw; }
|
|
}
|
|
|
|
public double GetStandardDeviation(double[] num)
|
|
{
|
|
double Sum = 0.0, SumOfSqrs = 0.0;
|
|
for (int i = 0; i < num.Length; i++)
|
|
{
|
|
Sum += num[i];
|
|
SumOfSqrs += Math.Pow(num[i], 2);
|
|
}
|
|
double topSum = (num.Length * SumOfSqrs) - (Math.Pow(Sum, 2));
|
|
double n = (double)num.Length;
|
|
return Math.Sqrt(topSum / (n * (n - 1)));
|
|
}
|
|
|
|
private double SafeDivide(double value1, double value2)
|
|
{
|
|
double ret = 0;
|
|
try
|
|
{
|
|
if ((value1 == 0) || (value2 == 0)) { return ret; }
|
|
ret = value1 / value2;
|
|
}
|
|
catch { }
|
|
return ret;
|
|
}
|
|
|
|
private byte HexToInt(byte b)
|
|
{
|
|
if (b >= '0' && b <= '9')
|
|
return (byte)(b - '0');
|
|
else if ((b >= 'a' && b <= 'f') || (b >= 'A' && b <= 'F'))
|
|
return (byte)((b & 0x5f) - 0x37);
|
|
else
|
|
return 0; // error
|
|
}
|
|
#endregion
|
|
|
|
}
|
|
}
|