* Applied patch from Melanie, mantis issue #1581 - "Refactor LSL language, api and compiler out of XEngine"

"First stage in a major Script Engine refactor, that will result in the LSL implementaions ebing reconverged. Not there yet, but one major part is done."
Thank you, Melanie!
This commit is contained in:
lbsa71
2008-06-24 21:09:49 +00:00
parent c0a083ad38
commit 6b7930104b
50 changed files with 15820 additions and 1354 deletions

View File

@@ -0,0 +1,128 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using libsecondlife;
using OpenSim.Region.ScriptEngine.Shared;
using OpenSim.Region.ScriptEngine.Shared.Api;
namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
{
public class Dataserver
{
public AsyncCommandManager m_CmdManager;
private Dictionary<string, DataserverRequest> DataserverRequests =
new Dictionary<string, DataserverRequest>();
public Dataserver(AsyncCommandManager CmdManager)
{
m_CmdManager = CmdManager;
}
private class DataserverRequest
{
public uint localID;
public LLUUID itemID;
public LLUUID ID;
public string handle;
public DateTime startTime;
}
public LLUUID RegisterRequest(uint localID, LLUUID itemID,
string identifier)
{
lock (DataserverRequests)
{
if (DataserverRequests.ContainsKey(identifier))
return LLUUID.Zero;
DataserverRequest ds = new DataserverRequest();
ds.localID = localID;
ds.itemID = itemID;
ds.ID = LLUUID.Random();
ds.handle = identifier;
ds.startTime = DateTime.Now;
DataserverRequests[identifier]=ds;
return ds.ID;
}
}
public void DataserverReply(string identifier, string reply)
{
DataserverRequest ds;
lock (DataserverRequests)
{
if (!DataserverRequests.ContainsKey(identifier))
return;
ds=DataserverRequests[identifier];
DataserverRequests.Remove(identifier);
}
m_CmdManager.m_ScriptEngine.PostObjectEvent(ds.localID,
new EventParams("dataserver", new Object[]
{ new LSL_Types.LSLString(ds.ID.ToString()),
new LSL_Types.LSLString(reply)},
new DetectParams[0]));
}
public void RemoveEvents(uint localID, LLUUID itemID)
{
lock (DataserverRequests)
{
foreach (DataserverRequest ds in new List<DataserverRequest>(DataserverRequests.Values))
{
if (ds.itemID == itemID)
DataserverRequests.Remove(ds.handle);
}
}
}
public void ExpireRequests()
{
lock (DataserverRequests)
{
foreach (DataserverRequest ds in new List<DataserverRequest>(DataserverRequests.Values))
{
if (ds.startTime > DateTime.Now.AddSeconds(30))
DataserverRequests.Remove(ds.handle);
}
}
}
}
}

View File

@@ -0,0 +1,91 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Modules.Scripting.HttpRequest;
using OpenSim.Region.ScriptEngine.Shared;
using OpenSim.Region.ScriptEngine.Interfaces;
using OpenSim.Region.ScriptEngine.Shared.Api;
namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
{
public class HttpRequest
{
public AsyncCommandManager m_CmdManager;
public HttpRequest(AsyncCommandManager CmdManager)
{
m_CmdManager = CmdManager;
}
public void CheckHttpRequests()
{
if (m_CmdManager.m_ScriptEngine.World == null)
return;
IHttpRequests iHttpReq =
m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IHttpRequests>();
HttpRequestClass httpInfo = null;
if (iHttpReq != null)
httpInfo = iHttpReq.GetNextCompletedRequest();
while (httpInfo != null)
{
//m_ScriptEngine.Log.Info("[AsyncLSL]:" + httpInfo.response_body + httpInfo.status);
// Deliver data to prim's remote_data handler
//
// TODO: Returning null for metadata, since the lsl function
// only returns the byte for HTTP_BODY_TRUNCATED, which is not
// implemented here yet anyway. Should be fixed if/when maxsize
// is supported
iHttpReq.RemoveCompletedRequest(httpInfo.reqID);
object[] resobj = new object[]
{
new LSL_Types.LSLString(httpInfo.reqID.ToString()),
new LSL_Types.LSLInteger(httpInfo.status),
new LSL_Types.list(),
new LSL_Types.LSLString(httpInfo.response_body)
};
foreach (AsyncCommandManager m in m_CmdManager.Managers)
{
if (m.m_ScriptEngine.PostObjectEvent(httpInfo.localID,
new EventParams("http_response",
resobj, new DetectParams[0])))
break;
}
httpInfo = iHttpReq.GetNextCompletedRequest();
}
}
}
}

View File

@@ -0,0 +1,92 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using libsecondlife;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Modules.Scripting.WorldComm;
using OpenSim.Region.ScriptEngine.Shared;
using OpenSim.Region.ScriptEngine.Shared.Api;
namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
{
public class Listener
{
// private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
public AsyncCommandManager m_CmdManager;
public Listener(AsyncCommandManager CmdManager)
{
m_CmdManager = CmdManager;
}
public void CheckListeners()
{
if (m_CmdManager.m_ScriptEngine.World == null)
return;
IWorldComm comms = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
if (comms != null)
{
while (comms.HasMessages())
{
ListenerInfo lInfo = comms.GetNextMessage();
//Deliver data to prim's listen handler
object[] resobj = new object[]
{
new LSL_Types.LSLInteger(lInfo.GetChannel()),
new LSL_Types.LSLString(lInfo.GetName()),
new LSL_Types.LSLString(lInfo.GetID().ToString()),
new LSL_Types.LSLString(lInfo.GetMessage())
};
m_CmdManager.m_ScriptEngine.PostScriptEvent(
lInfo.GetItemID(), new EventParams(
"listen", resobj,
new DetectParams[0]));
}
}
}
public Object[] GetSerializationData(LLUUID itemID)
{
IWorldComm comms = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
return comms.GetSerializationData(itemID);
}
public void CreateFromData(uint localID, LLUUID itemID, LLUUID hostID,
Object[] data)
{
IWorldComm comms = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
comms.CreateFromData(localID, itemID, hostID, data);
}
}
}

View File

@@ -0,0 +1,389 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections.Generic;
using libsecondlife;
using OpenSim.Framework;
using OpenSim.Region.Environment.Scenes;
using OpenSim.Region.ScriptEngine.Shared;
using OpenSim.Region.ScriptEngine.Shared.Api;
namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
{
public class SensorRepeat
{
public AsyncCommandManager m_CmdManager;
public SensorRepeat(AsyncCommandManager CmdManager)
{
m_CmdManager = CmdManager;
}
public Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>> SenseEvents =
new Dictionary<uint, Dictionary<LLUUID, LSL_Types.list>>();
private Object SenseLock = new Object();
//
// SenseRepeater and Sensors
//
private class SenseRepeatClass
{
public uint localID;
public LLUUID itemID;
public double interval;
public DateTime next;
public string name;
public LLUUID keyID;
public int type;
public double range;
public double arc;
public SceneObjectPart host;
}
private List<SenseRepeatClass> SenseRepeaters = new List<SenseRepeatClass>();
private object SenseRepeatListLock = new object();
public void SetSenseRepeatEvent(uint m_localID, LLUUID m_itemID,
string name, LLUUID keyID, int type, double range,
double arc, double sec, SceneObjectPart host)
{
// Always remove first, in case this is a re-set
UnSetSenseRepeaterEvents(m_localID, m_itemID);
if (sec == 0) // Disabling timer
return;
// Add to timer
SenseRepeatClass ts = new SenseRepeatClass();
ts.localID = m_localID;
ts.itemID = m_itemID;
ts.interval = sec;
ts.name = name;
ts.keyID = keyID;
ts.type = type;
ts.range = range;
ts.arc = arc;
ts.host = host;
ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
lock (SenseRepeatListLock)
{
SenseRepeaters.Add(ts);
}
}
public void UnSetSenseRepeaterEvents(uint m_localID, LLUUID m_itemID)
{
// Remove from timer
lock (SenseRepeatListLock)
{
List<SenseRepeatClass> NewSensors = new List<SenseRepeatClass>();
foreach (SenseRepeatClass ts in SenseRepeaters)
{
if (ts.localID != m_localID && ts.itemID != m_itemID)
{
NewSensors.Add(ts);
}
}
SenseRepeaters.Clear();
SenseRepeaters = NewSensors;
}
}
public void CheckSenseRepeaterEvents()
{
// Nothing to do here?
if (SenseRepeaters.Count == 0)
return;
lock (SenseRepeatListLock)
{
// Go through all timers
foreach (SenseRepeatClass ts in SenseRepeaters)
{
// Time has passed?
if (ts.next.ToUniversalTime() < DateTime.Now.ToUniversalTime())
{
SensorSweep(ts);
// set next interval
ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
}
}
} // lock
}
public void SenseOnce(uint m_localID, LLUUID m_itemID,
string name, LLUUID keyID, int type,
double range, double arc, SceneObjectPart host)
{
// Add to timer
SenseRepeatClass ts = new SenseRepeatClass();
ts.localID = m_localID;
ts.itemID = m_itemID;
ts.interval = 0;
ts.name = name;
ts.keyID = keyID;
ts.type = type;
ts.range = range;
ts.arc = arc;
ts.host = host;
SensorSweep(ts);
}
public LSL_Types.list GetSensorList(uint m_localID, LLUUID m_itemID)
{
lock (SenseLock)
{
Dictionary<LLUUID, LSL_Types.list> Obj = null;
if (!SenseEvents.TryGetValue(m_localID, out Obj))
{
return null;
}
lock (Obj)
{
// Get script
LSL_Types.list SenseList = null;
if (!Obj.TryGetValue(m_itemID, out SenseList))
{
return null;
}
return SenseList;
}
}
}
private void SensorSweep(SenseRepeatClass ts)
{
SceneObjectPart SensePoint = ts.host;
if (SensePoint == null)
{
return;
}
LLVector3 sensorPos = SensePoint.AbsolutePosition;
LLVector3 regionPos = new LLVector3(m_CmdManager.m_ScriptEngine.World.RegionInfo.RegionLocX * Constants.RegionSize, m_CmdManager.m_ScriptEngine.World.RegionInfo.RegionLocY * Constants.RegionSize, 0);
LLVector3 fromRegionPos = sensorPos + regionPos;
LLQuaternion q = SensePoint.RotationOffset;
LSL_Types.Quaternion r = new LSL_Types.Quaternion(q.X, q.Y, q.Z, q.W);
LSL_Types.Vector3 forward_dir = (new LSL_Types.Vector3(1, 0, 0) * r);
double mag_fwd = LSL_Types.Vector3.Mag(forward_dir);
// Here we should do some smart culling ...
// math seems quicker than strings so try that first
LSL_Types.list SensedObjects = new LSL_Types.list();
LSL_Types.Vector3 ZeroVector = new LSL_Types.Vector3(0, 0, 0);
foreach (EntityBase ent in m_CmdManager.m_ScriptEngine.World.Entities.Values)
{
LLVector3 toRegionPos = ent.AbsolutePosition + regionPos;
double dis = Math.Abs((double)Util.GetDistanceTo(toRegionPos, fromRegionPos));
if (dis <= ts.range)
{
// In Range, is it the right Type ?
int objtype = 0;
if (m_CmdManager.m_ScriptEngine.World.GetScenePresence(ent.UUID) != null) objtype |= 0x01; // actor
if (ent.Velocity.Equals(ZeroVector))
objtype |= 0x04; // passive non-moving
else
objtype |= 0x02; // active moving
SceneObjectPart part = m_CmdManager.m_ScriptEngine.World.GetSceneObjectPart(ent.UUID);
if (part != null && part.ContainsScripts()) objtype |= 0x08; // Scripted. It COULD have one hidden ...
if (((ts.type & objtype) != 0) || ((ts.type & objtype) == ts.type))
{
// docs claim AGENT|ACTIVE should find agent objects OR active objects
// so the bitwise AND with object type should be non-zero
// Right type too, what about the other params , key and name ?
bool keep = true;
if (ts.arc < Math.PI)
{
// not omni-directional. Can you see it ?
// vec forward_dir = llRot2Fwd(llGetRot())
// vec obj_dir = toRegionPos-fromRegionPos
// dot=dot(forward_dir,obj_dir)
// mag_fwd = mag(forward_dir)
// mag_obj = mag(obj_dir)
// ang = acos(dot /(mag_fwd*mag_obj))
double ang_obj = 0;
try
{
LLVector3 diff = toRegionPos - fromRegionPos;
LSL_Types.Vector3 obj_dir = new LSL_Types.Vector3(diff.X, diff.Y, diff.Z);
double dot = LSL_Types.Vector3.Dot(forward_dir, obj_dir);
double mag_obj = LSL_Types.Vector3.Mag(obj_dir);
ang_obj = Math.Acos(dot / (mag_fwd * mag_obj));
}
catch
{
}
if (ang_obj > ts.arc) keep = false;
}
if (keep && (ts.keyID != LLUUID.Zero) && (ts.keyID != ent.UUID))
{
keep = false;
}
if (keep && (ts.name.Length > 0))
{
string avatarname=null;
string objectname=null;
string entname =ent.Name;
// try avatar username surname
UserProfileData profile = m_CmdManager.m_ScriptEngine.World.CommsManager.UserService.GetUserProfile(ent.UUID);
if (profile != null)
{
avatarname = profile.FirstName + " " + profile.SurName;
}
// try an scene object
SceneObjectPart SOP = m_CmdManager.m_ScriptEngine.World.GetSceneObjectPart(ent.UUID);
if (SOP != null)
{
objectname = SOP.Name;
}
if ((ts.name != entname) && (ts.name != avatarname) && (ts.name != objectname))
{
keep = false;
}
}
if (keep == true) SensedObjects.Add(ent.UUID);
}
}
}
lock (SenseLock)
{
// Create object if it doesn't exist
if (SenseEvents.ContainsKey(ts.localID) == false)
{
SenseEvents.Add(ts.localID, new Dictionary<LLUUID, LSL_Types.list>());
}
// clear if previous traces exist
Dictionary<LLUUID, LSL_Types.list> Obj;
SenseEvents.TryGetValue(ts.localID, out Obj);
if (Obj.ContainsKey(ts.itemID) == true)
Obj.Remove(ts.itemID);
// note list may be zero length
Obj.Add(ts.itemID, SensedObjects);
if (SensedObjects.Length == 0)
{
// send a "no_sensor"
// Add it to queue
m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
new EventParams("no_sensor", new Object[0],
new DetectParams[0]));
}
else
{
DetectParams[] detect =
new DetectParams[SensedObjects.Length];
int idx;
for (idx = 0; idx < SensedObjects.Length; idx++)
{
detect[idx] = new DetectParams();
detect[idx].Key=(LLUUID)(SensedObjects.Data[idx]);
detect[idx].Populate(m_CmdManager.m_ScriptEngine.World);
}
m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
new EventParams("sensor",
new Object[] {
new LSL_Types.LSLInteger(SensedObjects.Length) },
detect));
}
}
}
public Object[] GetSerializationData(LLUUID itemID)
{
List<Object> data = new List<Object>();
foreach (SenseRepeatClass ts in SenseRepeaters)
{
if (ts.itemID == itemID)
{
data.Add(ts.interval);
data.Add(ts.name);
data.Add(ts.keyID);
data.Add(ts.type);
data.Add(ts.range);
data.Add(ts.arc);
}
}
return data.ToArray();
}
public void CreateFromData(uint localID, LLUUID itemID, LLUUID objectID,
Object[] data)
{
SceneObjectPart part =
m_CmdManager.m_ScriptEngine.World.GetSceneObjectPart(
objectID);
if (part == null)
return;
int idx = 0;
while (idx < data.Length)
{
SenseRepeatClass ts = new SenseRepeatClass();
ts.localID = localID;
ts.itemID = itemID;
ts.interval = (double)data[idx];
ts.name = (string)data[idx+1];
ts.keyID = (LLUUID)data[idx+2];
ts.type = (int)data[idx+3];
ts.range = (double)data[idx+4];
ts.arc = (double)data[idx+5];
ts.host = part;
ts.next =
DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
SenseRepeaters.Add(ts);
idx += 6;
}
}
}
}

View File

@@ -0,0 +1,162 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using libsecondlife;
using OpenSim.Region.ScriptEngine.Shared.Api;
namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
{
public class Timer
{
public AsyncCommandManager m_CmdManager;
public Timer(AsyncCommandManager CmdManager)
{
m_CmdManager = CmdManager;
}
//
// TIMER
//
private class TimerClass
{
public uint localID;
public LLUUID itemID;
//public double interval;
public long interval;
//public DateTime next;
public long next;
}
private List<TimerClass> Timers = new List<TimerClass>();
private object TimerListLock = new object();
public void SetTimerEvent(uint m_localID, LLUUID m_itemID, double sec)
{
// Always remove first, in case this is a re-set
UnSetTimerEvents(m_localID, m_itemID);
if (sec == 0) // Disabling timer
return;
// Add to timer
TimerClass ts = new TimerClass();
ts.localID = m_localID;
ts.itemID = m_itemID;
ts.interval = Convert.ToInt64(sec * 10000000); // How many 100 nanoseconds (ticks) should we wait
// 2193386136332921 ticks
// 219338613 seconds
//ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
ts.next = DateTime.Now.Ticks + ts.interval;
lock (TimerListLock)
{
Timers.Add(ts);
}
}
public void UnSetTimerEvents(uint m_localID, LLUUID m_itemID)
{
// Remove from timer
lock (TimerListLock)
{
foreach (TimerClass ts in new ArrayList(Timers))
{
if (ts.localID == m_localID && ts.itemID == m_itemID)
Timers.Remove(ts);
}
}
}
public void CheckTimerEvents()
{
// Nothing to do here?
if (Timers.Count == 0)
return;
lock (TimerListLock)
{
// Go through all timers
foreach (TimerClass ts in Timers)
{
// Time has passed?
if (ts.next < DateTime.Now.Ticks)
{
// Console.WriteLine("Time has passed: Now: " + DateTime.Now.Ticks + ", Passed: " + ts.next);
// Add it to queue
m_CmdManager.m_ScriptEngine.PostScriptEvent(ts.itemID,
new EventParams("timer", new Object[0],
new DetectParams[0]));
// set next interval
//ts.next = DateTime.Now.ToUniversalTime().AddSeconds(ts.interval);
ts.next = DateTime.Now.Ticks + ts.interval;
}
}
}
}
public Object[] GetSerializationData(LLUUID itemID)
{
List<Object> data = new List<Object>();
lock (TimerListLock)
{
foreach (TimerClass ts in Timers)
{
if (ts.itemID == itemID)
{
data.Add(ts.interval);
data.Add(ts.next-DateTime.Now.Ticks);
}
}
}
return data.ToArray();
}
public void CreateFromData(uint localID, LLUUID itemID, LLUUID objectID,
Object[] data)
{
int idx = 0;
while (idx < data.Length)
{
TimerClass ts = new TimerClass();
ts.localID = localID;
ts.itemID = itemID;
ts.interval = (long)data[idx];
ts.next = DateTime.Now.Ticks + (long)data[idx+1];
idx += 2;
Timers.Add(ts);
}
}
}
}

View File

@@ -0,0 +1,117 @@
/*
* Copyright (c) Contributors, http://opensimulator.org/
* See CONTRIBUTORS.TXT for a full list of copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the OpenSim Project nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
using System;
using OpenSim.Region.Environment.Interfaces;
using OpenSim.Region.Environment.Modules.Scripting.XMLRPC;
using OpenSim.Region.ScriptEngine.Interfaces;
using OpenSim.Region.ScriptEngine.Shared;
using OpenSim.Region.ScriptEngine.Shared.Api;
namespace OpenSim.Region.ScriptEngine.Shared.Api.Plugins
{
public class XmlRequest
{
public AsyncCommandManager m_CmdManager;
public XmlRequest(AsyncCommandManager CmdManager)
{
m_CmdManager = CmdManager;
}
public void CheckXMLRPCRequests()
{
if (m_CmdManager.m_ScriptEngine.World == null)
return;
IXMLRPC xmlrpc = m_CmdManager.m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
if (xmlrpc != null)
{
RPCRequestInfo rInfo = xmlrpc.GetNextCompletedRequest();
while (rInfo != null)
{
xmlrpc.RemoveCompletedRequest(rInfo.GetMessageID());
//Deliver data to prim's remote_data handler
object[] resobj = new object[]
{
new LSL_Types.LSLInteger(2),
new LSL_Types.LSLString(
rInfo.GetChannelKey().ToString()),
new LSL_Types.LSLString(
rInfo.GetMessageID().ToString()),
new LSL_Types.LSLString(String.Empty),
new LSL_Types.LSLInteger(rInfo.GetIntValue()),
new LSL_Types.LSLString(rInfo.GetStrVal())
};
foreach (AsyncCommandManager m in m_CmdManager.Managers)
{
if (m.m_ScriptEngine.PostScriptEvent(
rInfo.GetItemID(), new EventParams(
"remote_data", resobj,
new DetectParams[0])))
break;
}
rInfo = xmlrpc.GetNextCompletedRequest();
}
SendRemoteDataRequest srdInfo = xmlrpc.GetNextCompletedSRDRequest();
while (srdInfo != null)
{
xmlrpc.RemoveCompletedSRDRequest(srdInfo.GetReqID());
//Deliver data to prim's remote_data handler
object[] resobj = new object[]
{
new LSL_Types.LSLInteger(3),
new LSL_Types.LSLString(srdInfo.channel.ToString()),
new LSL_Types.LSLString(srdInfo.GetReqID().ToString()),
new LSL_Types.LSLString(String.Empty),
new LSL_Types.LSLInteger(srdInfo.idata),
new LSL_Types.LSLString(srdInfo.sdata)
};
foreach (AsyncCommandManager m in m_CmdManager.Managers)
{
if (m.m_ScriptEngine.PostScriptEvent(
srdInfo.m_itemID, new EventParams(
"remote_data", resobj,
new DetectParams[0])))
break;
}
srdInfo = xmlrpc.GetNextCompletedSRDRequest();
}
}
}
}
}