diff --git a/OpenSim/Grid/ScriptEngine/DotNetEngine/Compiler/LSL/LSL_BaseClass.cs b/OpenSim/Grid/ScriptEngine/DotNetEngine/Compiler/LSL/LSL_BaseClass.cs
index 04bc6cf366..2c7cc341aa 100644
--- a/OpenSim/Grid/ScriptEngine/DotNetEngine/Compiler/LSL/LSL_BaseClass.cs
+++ b/OpenSim/Grid/ScriptEngine/DotNetEngine/Compiler/LSL/LSL_BaseClass.cs
@@ -2115,9 +2115,11 @@ namespace OpenSim.Grid.ScriptEngine.DotNetEngine.Compiler.LSL
public const double DEG_TO_RAD = 0.01745329238f;
public const double RAD_TO_DEG = 57.29578f;
public const double SQRT2 = 1.414213538f;
+ public const int DEBUG_CHANNEL 0x7FFFFFFF;
+ public const int PUBLIC_CHANNEL 0x00000000
// Can not be public const?
public vector ZERO_VECTOR = new vector(0, 0, 0);
public rotation ZERO_ROTATION = new rotation(0, 0, 0, 0);
}
-}
\ No newline at end of file
+}
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs
index 2b137519cb..47117487c3 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.Inventory.cs
@@ -93,7 +93,7 @@ namespace OpenSim.Region.Environment.Scenes
/// Reset LLUUIDs for all the items in the prim's inventory. This involves either generating
/// new ones or setting existing UUIDs to the correct parent UUIDs
///
- /// Link number for the part
public void ResetInventoryIDs()
{
lock (TaskInventory)
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
index e9d4c66ae7..3d52119a62 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
@@ -1087,7 +1087,7 @@ namespace OpenSim.Region.Environment.Scenes
/// Reset LLUUIDs for this part. This involves generate this part's own LLUUID and
/// generating new LLUUIDs for all the items in the inventory.
///
- /// Link number for the part
public void ResetIDs(int linkNum)
{
UUID = LLUUID.Random();
diff --git a/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs b/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs
index 957f55c86d..9e30958c6a 100644
--- a/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs
+++ b/OpenSim/Region/ScriptEngine/Common/BuiltIn_Commands_BaseClass.cs
@@ -2310,9 +2310,9 @@ namespace OpenSim.Region.ScriptEngine.Common
public const double DEG_TO_RAD = 0.01745329238f;
public const double RAD_TO_DEG = 57.29578f;
public const double SQRT2 = 1.414213538f;
- public const int STRING_TRIM_HEAD = 1;
- public const int STRING_TRIM_TAIL = 2;
- public const int STRING_TRIM = 3;
+ public const int STRING_TRIM_HEAD = 1;
+ public const int STRING_TRIM_TAIL = 2;
+ public const int STRING_TRIM = 3;
public const int LIST_STAT_RANGE = 0;
public const int LIST_STAT_MIN = 1;
public const int LIST_STAT_MAX = 2;
@@ -2333,6 +2333,9 @@ namespace OpenSim.Region.ScriptEngine.Common
public const int PARCEL_COUNT_SELECTED = 4;
public const int PARCEL_COUNT_TEMP = 5;
+ public const int DEBUG_CHANNEL = 0x7FFFFFFF;
+ public const int PUBLIC_CHANNEL = 0x00000000;
+
// Can not be public const?
public vector ZERO_VECTOR = new vector(0.0, 0.0, 0.0);
public rotation ZERO_ROTATION = new rotation(0.0, 0, 0.0, 1.0);
diff --git a/OpenSim/Region/ScriptEngine/Common/ExecutorBase.cs b/OpenSim/Region/ScriptEngine/Common/ExecutorBase.cs
index 30c40f40be..c272400a73 100644
--- a/OpenSim/Region/ScriptEngine/Common/ExecutorBase.cs
+++ b/OpenSim/Region/ScriptEngine/Common/ExecutorBase.cs
@@ -42,6 +42,25 @@ namespace OpenSim.Region.ScriptEngine.Common
/// If set to False events will not be executed.
///
protected bool m_Running = true;
+ ///
+ /// True indicates that the ScriptManager has stopped
+ /// this script. This prevents a script that has been
+ /// stopped as part of deactivation from being
+ /// resumed by a pending llSetScriptState request.
+ ///
+ protected bool m_Disable = false;
+
+ ///
+ /// Indicate the scripts current running status.
+ ///
+ public bool Running
+ {
+ get { return m_Running; }
+ set {
+ if(!m_Disable)
+ m_Running = value;
+ }
+ }
///
/// Create a new instance of ExecutorBase
@@ -102,6 +121,8 @@ namespace OpenSim.Region.ScriptEngine.Common
public void StopScript()
{
m_Running = false;
+ m_Disable = true;
}
+
}
}
diff --git a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
index daf5e21f42..58b22d9585 100644
--- a/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
+++ b/OpenSim/Region/ScriptEngine/Common/LSL_BuiltIn_Commands.cs
@@ -50,9 +50,9 @@ namespace OpenSim.Region.ScriptEngine.Common
///
public class LSL_BuiltIn_Commands : MarshalByRefObject, LSL_BuiltIn_Commands_Interface
{
- //private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
+ // private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
- private ASCIIEncoding enc = new ASCIIEncoding();
+ // private ASCIIEncoding enc = new ASCIIEncoding();
private ScriptEngineBase.ScriptEngine m_ScriptEngine;
private SceneObjectPart m_host;
private uint m_localID;
@@ -76,14 +76,10 @@ namespace OpenSim.Region.ScriptEngine.Common
{
get { return m_state; }
set {
- bool changed = false;
+ // Set it if it changed
if (m_state != value)
- changed = true;
- // Set it
- m_state = value;
-
- if (changed)
{
+ m_state = value;
m_ScriptEngine.m_EventManager.state_entry(m_localID);
}
}
@@ -1793,8 +1789,33 @@ namespace OpenSim.Region.ScriptEngine.Common
public void llSetScriptState(string name, int run)
{
+
+ LLUUID item;
+ ScriptManager sm;
+ IScript script = null;
+
m_host.AddScriptLPS(1);
- NotImplemented("llSetScriptState");
+
+ // These functions are supposed to be robust,
+ // so get the state one step at a time.
+
+ if((item = ScriptByName(name)) != LLUUID.Zero)
+ if((sm = m_ScriptEngine.m_ScriptManager) != null)
+ if(sm.Scripts.ContainsKey(m_localID))
+ if((script = sm.GetScript(m_localID, item)) != null)
+ script.Exec.Running = (run==0) ? false : true;
+
+
+ // Required by SL
+
+ if(script == null)
+ ShoutError("llSetScriptState: script "+name+" not found");
+
+ // If we didn;t find it, then it's safe to
+ // assume it is not running.
+
+ return;
+
}
public double llGetEnergy()
@@ -1911,9 +1932,22 @@ namespace OpenSim.Region.ScriptEngine.Common
public string llGetScriptName()
{
+
+ string result = null;
+
m_host.AddScriptLPS(1);
- return String.Empty;
+ foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
+ {
+ if(item.Type == 10 && item.ItemID == m_itemID)
+ {
+ result = item.Name;
+ break;
+ }
+ }
+
+ return result;
+
}
public int llGetNumberOfSides()
@@ -2269,81 +2303,216 @@ namespace OpenSim.Region.ScriptEngine.Common
return ret;
}
+ ///
+ /// The supplied string is scanned for commas
+ /// and converted into a list. Commas are only
+ /// effective if they are encountered outside
+ /// of '<' '>' delimiters. Any whitespace
+ /// before or after an element is trimmed.
+ ///
+
public LSL_Types.list llCSV2List(string src)
{
+
+ LSL_Types.list result = new LSL_Types.list();
+ int parens = 0;
+ int start = 0;
+ int length = 0;
+
m_host.AddScriptLPS(1);
- return new LSL_Types.list(src.Split(",".ToCharArray()));
+
+ for(int i=0; i' :
+ if(parens > 0)
+ parens--;
+ length++;
+ break;
+ case ',' :
+ if(parens == 0)
+ {
+ result.Add(src.Substring(start,length).Trim());
+ start += length+1;
+ length = 0;
+ } else
+ length++;
+ break;
+ default :
+ length++;
+ break;
+ }
+ }
+
+ result.Add(src.Substring(start,length).Trim());
+
+ return result;
+
}
+ ///
+ /// Randomizes the list, be arbitrarily reordering
+ /// sublists of stride elements. As the stride approaches
+ /// the size of the list, the options become very
+ /// limited.
+ ///
+ ///
+ /// This could take a while for very large list
+ /// sizes.
+ ///
+
public LSL_Types.list llListRandomize(LSL_Types.list src, int stride)
{
+
+ LSL_Types.list result;
+ Random rand = new Random();
+
+ int chunkk;
+ int[] chunks;
+ int index1;
+ int index2;
+ int tmp;
+
m_host.AddScriptLPS(1);
- //int s = stride;
- //if (s < 1)
- // s = 1;
- // This is a cowardly way of doing it ;)
- // TODO: Instead, randomize and check if random is mod stride or if it can not be, then array.removerange
- //List tmp = new List();
+ if(stride == 0)
+ stride = 1;
- // Add chunks to an array
- //int c = 0;
- //LSL_Types.list chunk = new LSL_Types.list();
- //foreach (string element in src)
- //{
- // c++;
- // if (c > s)
- // {
- // tmp.Add(chunk);
- // chunk = new LSL_Types.list();
- // c = 0;
- // }
- // chunk.Add(element);
- //}
- //if (chunk.Count > 0)
- // tmp.Add(chunk);
+ // Stride MUST be a factor of the list length
+ // If not, then return the src list. This also
+ // traps those cases where stride > length.
+
+ if(src.Length != stride && src.Length%stride == 0)
+ {
- // Decreate (<- what kind of word is that? :D ) array back into a list
- //int rnd;
- //LSL_Types.list ret = new LSL_Types.list();
- //while (tmp.Count > 0)
- //{
- // rnd = Util.RandomClass.Next(tmp.Count);
- // foreach (string str in tmp[rnd])
- // {
- // ret.Add(str);
- // }
- // tmp.RemoveAt(rnd);
- //}
+ chunkk = src.Length/stride;
+
+ chunks = new int[chunkk];
+
+ for(int i=0;i
+ /// Elements in the source list starting with 0 and then
+ /// every i+stride. If the stride is negative then the scan
+ /// is backwards producing an inverted result.
+ /// Only those elements that are also in the specified
+ /// range are included in the result.
+ ///
+
public LSL_Types.list llList2ListStrided(LSL_Types.list src, int start, int end, int stride)
{
- m_host.AddScriptLPS(1);
- LSL_Types.list ret = new LSL_Types.list();
- //int s = stride;
- //if (s < 1)
- // s = 1;
- //int sc = s;
- //for (int i = start; i < src.Count; i++)
- //{
- // sc--;
- // if (sc == 0)
- // {
- // sc = s;
- // // Addthis
- // ret.Add(src[i]);
- // }
- // if (i == end)
- // break;
- //}
- NotImplemented("llList2ListStrided");
- return ret;
+ LSL_Types.list result = new LSL_Types.list();
+ int[] si = new int[2];
+ int[] ei = new int[2];
+ bool twopass = false;
+
+ m_host.AddScriptLPS(1);
+
+ // First step is always to deal with negative indices
+
+ if(start < 0)
+ start = src.Length+start;
+ if(end < 0)
+ end = src.Length+end;
+
+ // Out of bounds indices are OK, just trim them
+ // accordingly
+
+ if(start > src.Length)
+ start = src.Length;
+
+ if(end > src.Length)
+ end = src.Length;
+
+ // There may be one or two ranges to be considered
+
+ if(start != end)
+ {
+
+ if(start <= end)
+ {
+ si[0] = start;
+ ei[0] = end;
+ }
+ else
+ {
+ si[1] = start;
+ ei[1] = src.Length;
+ si[0] = 0;
+ ei[0] = end;
+ twopass = true;
+ }
+
+ // The scan always starts from the beginning of the
+ // source list, but members are only selected if they
+ // fall within the specified sub-range. The specified
+ // range values are inclusive.
+ // A negative stride reverses the direction of the
+ // scan producing an inverted list as a result.
+
+ if(stride == 0)
+ stride = 1;
+
+ if(stride > 0)
+ for(int i=0;i=si[0])
+ result.Add(src.Data[i]);
+ if(twopass && i>=si[1] && i<=ei[1])
+ result.Add(src.Data[i]);
+ }
+ else if(stride < 0)
+ for(int i=src.Length-1;i>=0;i+=stride)
+ {
+ if(i<=ei[0] && i>=si[0])
+ result.Add(src.Data[i]);
+ if(twopass && i>=si[1] && i<=ei[1])
+ result.Add(src.Data[i]);
+ }
+ }
+
+ return result;
+
}
public LSL_Types.Vector3 llGetRegionCorner()
@@ -2358,19 +2527,42 @@ namespace OpenSim.Region.ScriptEngine.Common
return dest.GetSublist(0, start - 1) + src + dest.GetSublist(start, -1);
}
+ ///
+ /// Returns the index of the first occurrence of test
+ /// in src.
+ ///
+
public int llListFindList(LSL_Types.list src, LSL_Types.list test)
{
+
+ int index = -1;
+ int length = src.Length - test.Length + 1;
+
m_host.AddScriptLPS(1);
- //foreach (string s in test)
- //{
- // for (int ci = 0; ci < src.Count; ci++)
- // {
- // if (s == src[ci])
- // return ci;
- // }
- //}
- NotImplemented("llListFindList");
- return -1;
+
+ // If either list is empty, do not match
+
+ if(src.Length != 0 && test.Length != 0)
+ {
+ for(int i=0; i< length; i++)
+ {
+ if(src.Data[i].Equals(test.Data[0]))
+ {
+ int j;
+ for(j=1;j
+ /// Reset the named script. The script must be present
+ /// in the same prim.
+ ///
+
public void llResetOtherScript(string name)
{
+
+ LLUUID item;
+ ScriptManager sm;
+ IScript script = null;
+
m_host.AddScriptLPS(1);
- NotImplemented("llResetOtherScript");
+
+ // These functions are supposed to be robust,
+ // so get the state one step at a time.
+
+ if((item = ScriptByName(name)) != LLUUID.Zero)
+ if((sm = m_ScriptEngine.m_ScriptManager) != null)
+ sm.ResetScript(m_localID, item);
+
+ // Required by SL
+
+ if(script == null)
+ ShoutError("llResetOtherScript: script "+name+" not found");
+
+ // If we didn;t find it, then it's safe to
+ // assume it is not running.
+
+ return;
+
}
public int llGetScriptState(string name)
{
+
+ LLUUID item;
+ ScriptManager sm;
+ IScript script = null;
+
m_host.AddScriptLPS(1);
- //NotImplemented("llGetScriptState");
+ // These functions are supposed to be robust,
+ // so get the state one step at a time.
+
+ if((item = ScriptByName(name)) != LLUUID.Zero)
+ if((sm = m_ScriptEngine.m_ScriptManager) != null)
+ if((script = sm.GetScript(m_localID, item)) != null)
+ return script.Exec.Running?1:0;
+
+ // Required by SL
+
+ if(script == null)
+ ShoutError("llGetScriptState: script "+name+" not found");
+
+ // If we didn;t find it, then it's safe to
+ // assume it is not running.
+
return 0;
+
}
public void llRemoteLoadScript()
{
m_host.AddScriptLPS(1);
- NotImplemented("llRemoteLoadScript");
+ ShoutError("llRemoteLoadScript: deprecated");
}
public void llSetRemoteScriptAccessPin(int pin)
@@ -3880,7 +4120,7 @@ namespace OpenSim.Region.ScriptEngine.Common
{
m_host.AddScriptLPS(1);
Int64 tmp = 0;
- Int64 val = Math.DivRem(Convert.ToInt64(Math.Pow(a, b)), c, out tmp);
+ Math.DivRem(Convert.ToInt64(Math.Pow(a, b)), c, out tmp);
return Convert.ToInt32(tmp);
}
@@ -4237,18 +4477,19 @@ namespace OpenSim.Region.ScriptEngine.Common
return ret;
}
- public string llStringTrim(string src, int type)
+ public string llStringTrim(string src, int type)
{
m_host.AddScriptLPS(1);
- if (type == (int)BuiltIn_Commands_BaseClass.STRING_TRIM_HEAD) { return src.TrimStart(); }
- if (type == (int)BuiltIn_Commands_BaseClass.STRING_TRIM_TAIL) { return src.TrimEnd(); }
- if (type == (int)BuiltIn_Commands_BaseClass.STRING_TRIM) { return src.Trim(); }
- return src;
- }
+ if (type == (int)BuiltIn_Commands_BaseClass.STRING_TRIM_HEAD) { return src.TrimStart(); }
+ if (type == (int)BuiltIn_Commands_BaseClass.STRING_TRIM_TAIL) { return src.TrimEnd(); }
+ if (type == (int)BuiltIn_Commands_BaseClass.STRING_TRIM) { return src.Trim(); }
+ return src;
+ }
//
// OpenSim functions
//
+
public int osTerrainSetHeight(int x, int y, double val)
{
m_host.AddScriptLPS(1);
@@ -4413,6 +4654,21 @@ namespace OpenSim.Region.ScriptEngine.Common
return false;
}
+ private LLUUID ScriptByName(string name)
+ {
+ foreach (TaskInventoryItem item in m_host.TaskInventory.Values)
+ {
+ if(item.Type == 10 && item.Name == name)
+ return item.ItemID;
+ }
+ return LLUUID.Zero;
+ }
+
+ private void ShoutError(string msg)
+ {
+ llShout(BuiltIn_Commands_BaseClass.DEBUG_CHANNEL,msg);
+ }
+
public void osSetPrimFloatOnWater(int floatYN)
{
m_host.AddScriptLPS(1);