From: Michael Osias <mosias@us.ibm.com>
This patch implements the llSendRemoteData command and fixes mantis 552, and possibly 586.ThreadPoolClientBranch
parent
69b1edebf6
commit
530cc24884
|
@ -38,5 +38,7 @@ namespace OpenSim.Region.Environment.Interfaces
|
|||
LLUUID StartHttpRequest(uint localID, LLUUID itemID, string url, List<string> parameters, string body);
|
||||
void StopHttpRequest(uint m_localID, LLUUID m_itemID);
|
||||
HttpRequestClass GetNextCompletedRequest();
|
||||
void RemoveCompletedRequest(LLUUID id);
|
||||
|
||||
}
|
||||
}
|
|
@ -41,5 +41,8 @@ namespace OpenSim.Region.Environment.Interfaces
|
|||
void ListenControl(int handle, int active);
|
||||
void ListenRemove(int handle);
|
||||
void DeleteListener(LLUUID itemID);
|
||||
uint PeekNextMessageLocalID();
|
||||
LLUUID PeekNextMessageItemID();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
using libsecondlife;
|
||||
using OpenSim.Region.Environment.Modules;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace OpenSim.Region.Environment.Interfaces
|
||||
{
|
||||
|
@ -36,9 +38,14 @@ namespace OpenSim.Region.Environment.Interfaces
|
|||
LLUUID OpenXMLRPCChannel(uint localID, LLUUID itemID);
|
||||
void CloseXMLRPCChannel(LLUUID channelKey);
|
||||
bool hasRequests();
|
||||
RPCRequestInfo GetNextRequest();
|
||||
void RemoteDataReply(string channel, string message_id, string sdata, int idata);
|
||||
bool IsEnabled();
|
||||
void DeleteChannel(LLUUID itemID);
|
||||
RPCRequestInfo GetNextCompletedRequest();
|
||||
void RemoveCompletedRequest(LLUUID id);
|
||||
void DeleteChannels(LLUUID itemID);
|
||||
LLUUID SendRemoteData(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata);
|
||||
SendRemoteDataRequest GetNextCompletedSRDRequest();
|
||||
void RemoveCompletedSRDRequest(LLUUID id);
|
||||
void CancelSRDRequests(LLUUID itemID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -184,13 +184,15 @@ namespace OpenSim.Region.Environment.Modules
|
|||
|
||||
public void StopHttpRequest(uint m_localID, LLUUID m_itemID)
|
||||
{
|
||||
lock (HttpListLock)
|
||||
{
|
||||
HttpRequestClass tmpReq;
|
||||
if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
|
||||
if(m_pendingRequests != null) {
|
||||
lock (HttpListLock)
|
||||
{
|
||||
tmpReq.Stop();
|
||||
m_pendingRequests.Remove(m_itemID);
|
||||
HttpRequestClass tmpReq;
|
||||
if (m_pendingRequests.TryGetValue(m_itemID, out tmpReq))
|
||||
{
|
||||
tmpReq.Stop();
|
||||
m_pendingRequests.Remove(m_itemID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -216,7 +218,6 @@ namespace OpenSim.Region.Environment.Modules
|
|||
{
|
||||
if (tmpReq.finished)
|
||||
{
|
||||
m_pendingRequests.Remove(luid);
|
||||
return tmpReq;
|
||||
}
|
||||
}
|
||||
|
@ -224,6 +225,21 @@ namespace OpenSim.Region.Environment.Modules
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void RemoveCompletedRequest(LLUUID id)
|
||||
{
|
||||
lock (HttpListLock)
|
||||
{
|
||||
HttpRequestClass tmpReq;
|
||||
if (m_pendingRequests.TryGetValue(id, out tmpReq))
|
||||
{
|
||||
tmpReq.Stop();
|
||||
tmpReq = null;
|
||||
m_pendingRequests.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -269,6 +285,7 @@ namespace OpenSim.Region.Environment.Modules
|
|||
httpThread.Name = "HttpRequestThread";
|
||||
httpThread.Priority = ThreadPriority.BelowNormal;
|
||||
httpThread.IsBackground = true;
|
||||
finished = false;
|
||||
httpThread.Start();
|
||||
}
|
||||
|
||||
|
|
|
@ -84,8 +84,8 @@ namespace OpenSim.Region.Environment.Modules
|
|||
m_scene = scene;
|
||||
m_scene.RegisterModuleInterface<IWorldComm>(this);
|
||||
m_listenerManager = new ListenerManager();
|
||||
m_pending = new Queue<ListenerInfo>();
|
||||
m_scene.EventManager.OnNewClient += NewClient;
|
||||
m_pending = new Queue<ListenerInfo>();
|
||||
}
|
||||
|
||||
public void PostInitialise()
|
||||
|
@ -139,9 +139,12 @@ namespace OpenSim.Region.Environment.Modules
|
|||
|
||||
public void DeleteListener(LLUUID itemID)
|
||||
{
|
||||
lock (ListLock)
|
||||
if (m_listenerManager != null)
|
||||
{
|
||||
m_listenerManager.DeleteListener(itemID);
|
||||
lock (ListLock)
|
||||
{
|
||||
m_listenerManager.DeleteListener(itemID);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -167,14 +170,14 @@ namespace OpenSim.Region.Environment.Modules
|
|||
// If they are in proximity, then if they are
|
||||
// listeners, if so add them to the pending queue
|
||||
|
||||
foreach (LLUUID eb in m_scene.Entities.Keys)
|
||||
foreach (ListenerInfo li in m_listenerManager.GetListeners())
|
||||
{
|
||||
EntityBase sPart;
|
||||
|
||||
m_scene.Entities.TryGetValue(eb, out sPart);
|
||||
m_scene.Entities.TryGetValue(li.GetHostID(), out sPart);
|
||||
|
||||
// Dont process if this message is from itself!
|
||||
if (eb.ToString().Equals(sourceItemID) ||
|
||||
if (li.GetHostID().ToString().Equals(sourceItemID) ||
|
||||
sPart.UUID.ToString().Equals(sourceItemID))
|
||||
continue;
|
||||
|
||||
|
@ -196,7 +199,10 @@ namespace OpenSim.Region.Environment.Modules
|
|||
);
|
||||
if (isListener != null)
|
||||
{
|
||||
m_pending.Enqueue(isListener);
|
||||
lock (CommListLock)
|
||||
{
|
||||
m_pending.Enqueue(isListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -210,7 +216,10 @@ namespace OpenSim.Region.Environment.Modules
|
|||
);
|
||||
if (isListener != null)
|
||||
{
|
||||
m_pending.Enqueue(isListener);
|
||||
lock (CommListLock)
|
||||
{
|
||||
m_pending.Enqueue(isListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -223,14 +232,17 @@ namespace OpenSim.Region.Environment.Modules
|
|||
);
|
||||
if (isListener != null)
|
||||
{
|
||||
m_pending.Enqueue(isListener);
|
||||
lock (CommListLock)
|
||||
{
|
||||
m_pending.Enqueue(isListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ChatTypeEnum.Broadcast:
|
||||
ListenerInfo isListen =
|
||||
m_listenerManager.IsListenerMatch(sourceItemID, eb, channel, name, msg);
|
||||
m_listenerManager.IsListenerMatch(sourceItemID, li.GetItemID(), channel, name, msg);
|
||||
if (isListen != null)
|
||||
{
|
||||
ListenerInfo isListener = m_listenerManager.IsListenerMatch(
|
||||
|
@ -238,19 +250,24 @@ namespace OpenSim.Region.Environment.Modules
|
|||
);
|
||||
if (isListener != null)
|
||||
{
|
||||
m_pending.Enqueue(isListener);
|
||||
lock (CommListLock)
|
||||
{
|
||||
m_pending.Enqueue(isListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasMessages()
|
||||
{
|
||||
return (m_pending.Count > 0);
|
||||
if (m_pending != null)
|
||||
return (m_pending.Count > 0);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
public ListenerInfo GetNextMessage()
|
||||
|
@ -264,6 +281,17 @@ namespace OpenSim.Region.Environment.Modules
|
|||
|
||||
return li;
|
||||
}
|
||||
|
||||
public uint PeekNextMessageLocalID()
|
||||
{
|
||||
return m_pending.Peek().GetLocalID();
|
||||
}
|
||||
|
||||
public LLUUID PeekNextMessageItemID()
|
||||
{
|
||||
return m_pending.Peek().GetItemID();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// hostID: the ID of the ScenePart
|
||||
|
@ -280,8 +308,7 @@ namespace OpenSim.Region.Environment.Modules
|
|||
m_listeners = new Dictionary<int, ListenerInfo>();
|
||||
}
|
||||
|
||||
public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id,
|
||||
string msg)
|
||||
public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg)
|
||||
{
|
||||
if (m_listeners.Count < m_MaxListeners)
|
||||
{
|
||||
|
@ -410,6 +437,11 @@ namespace OpenSim.Region.Environment.Modules
|
|||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Dictionary<int, ListenerInfo>.ValueCollection GetListeners()
|
||||
{
|
||||
return m_listeners.Values;
|
||||
}
|
||||
}
|
||||
|
||||
public class ListenerInfo
|
||||
|
@ -425,21 +457,20 @@ namespace OpenSim.Region.Environment.Modules
|
|||
private string m_message; // The message
|
||||
private bool m_active; // Listener is active or not
|
||||
|
||||
public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id,
|
||||
string message)
|
||||
public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id, string message)
|
||||
{
|
||||
Initialise(localID, handle, ItemID, hostID, channel, name, id, message);
|
||||
}
|
||||
|
||||
public ListenerInfo(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name, LLUUID id,
|
||||
string message, LLUUID sourceItemID)
|
||||
string message, LLUUID sourceItemID)
|
||||
{
|
||||
Initialise(localID, handle, ItemID, hostID, channel, name, id, message);
|
||||
m_sourceItemID = sourceItemID;
|
||||
}
|
||||
|
||||
private void Initialise(uint localID, int handle, LLUUID ItemID, LLUUID hostID, int channel, string name,
|
||||
LLUUID id, string message)
|
||||
LLUUID id, string message)
|
||||
{
|
||||
m_handle = handle;
|
||||
m_channel = channel;
|
||||
|
@ -511,5 +542,6 @@ namespace OpenSim.Region.Environment.Modules
|
|||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,19 +78,20 @@ namespace OpenSim.Region.Environment.Modules
|
|||
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
private Scene m_scene;
|
||||
private Queue<RPCRequestInfo> rpcQueue = new Queue<RPCRequestInfo>();
|
||||
private object XMLRPCListLock = new object();
|
||||
private string m_name = "XMLRPCModule";
|
||||
private int RemoteReplyScriptWait = 300;
|
||||
private int RemoteReplyScriptTimeout = 900;
|
||||
private int RemoteReplyScriptTimeout = 9000;
|
||||
private int m_remoteDataPort = 0;
|
||||
private List<Scene> m_scenes = new List<Scene>();
|
||||
|
||||
// <channel id, RPCChannelInfo>
|
||||
private Dictionary<LLUUID, RPCChannelInfo> m_openChannels;
|
||||
|
||||
// <channel id, RPCRequestInfo>
|
||||
private Dictionary<LLUUID, RPCRequestInfo> m_pendingResponse;
|
||||
private Dictionary<LLUUID, RPCRequestInfo> m_rpcPending;
|
||||
private Dictionary<LLUUID, RPCRequestInfo> m_rpcPendingResponses;
|
||||
|
||||
private Dictionary<LLUUID, SendRemoteDataRequest> m_pendingSRDResponses;
|
||||
|
||||
public void Initialise(Scene scene, IConfigSource config)
|
||||
{
|
||||
|
@ -115,13 +116,15 @@ namespace OpenSim.Region.Environment.Modules
|
|||
if (IsEnabled())
|
||||
{
|
||||
m_openChannels = new Dictionary<LLUUID, RPCChannelInfo>();
|
||||
m_pendingResponse = new Dictionary<LLUUID, RPCRequestInfo>();
|
||||
m_rpcPending = new Dictionary<LLUUID, RPCRequestInfo>();
|
||||
m_rpcPendingResponses = new Dictionary<LLUUID, RPCRequestInfo>();
|
||||
m_pendingSRDResponses = new Dictionary<LLUUID, SendRemoteDataRequest>();
|
||||
|
||||
// Start http server
|
||||
// Attach xmlrpc handlers
|
||||
m_log.Info("[REMOTE_DATA]: " +
|
||||
"Starting XMLRPC Server on port " + m_remoteDataPort + " for llRemoteData commands.");
|
||||
BaseHttpServer httpServer = new BaseHttpServer((uint) m_remoteDataPort);
|
||||
BaseHttpServer httpServer = new BaseHttpServer((uint)m_remoteDataPort);
|
||||
httpServer.AddXmlRPCHandler("llRemoteData", XmlRpcRemoteData);
|
||||
httpServer.Start();
|
||||
}
|
||||
|
@ -188,18 +191,28 @@ namespace OpenSim.Region.Environment.Modules
|
|||
return channel;
|
||||
}
|
||||
|
||||
public void DeleteChannel(LLUUID itemID)
|
||||
// Delete channels based on itemID
|
||||
// for when a script is deleted
|
||||
public void DeleteChannels(LLUUID itemID)
|
||||
{
|
||||
|
||||
foreach (RPCChannelInfo li in m_openChannels.Values)
|
||||
if (m_openChannels != null)
|
||||
{
|
||||
ArrayList tmp = new ArrayList();
|
||||
|
||||
if (li.GetItemID().Equals(itemID))
|
||||
lock (XMLRPCListLock)
|
||||
{
|
||||
foreach (RPCChannelInfo li in m_openChannels.Values)
|
||||
{
|
||||
if (li.GetItemID().Equals(itemID))
|
||||
{
|
||||
tmp.Add(itemID);
|
||||
}
|
||||
}
|
||||
|
||||
m_openChannels.Remove(li.GetChannelID());
|
||||
return;
|
||||
|
||||
System.Collections.IEnumerator tmpEnumerator = tmp.GetEnumerator();
|
||||
while ( tmpEnumerator.MoveNext() )
|
||||
m_openChannels.Remove((LLUUID)tmpEnumerator.Current);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -218,15 +231,12 @@ namespace OpenSim.Region.Environment.Modules
|
|||
RPCRequestInfo rpcInfo;
|
||||
LLUUID message_key = new LLUUID(message_id);
|
||||
|
||||
if (m_pendingResponse.TryGetValue(message_key, out rpcInfo))
|
||||
if (m_rpcPendingResponses.TryGetValue(message_key, out rpcInfo))
|
||||
{
|
||||
rpcInfo.SetRetval(sdata);
|
||||
rpcInfo.SetStrRetval(sdata);
|
||||
rpcInfo.SetIntRetval(idata);
|
||||
rpcInfo.SetProcessed(true);
|
||||
|
||||
lock (XMLRPCListLock)
|
||||
{
|
||||
m_pendingResponse.Remove(message_key);
|
||||
}
|
||||
m_rpcPendingResponses.Remove(message_key);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -248,18 +258,18 @@ namespace OpenSim.Region.Environment.Modules
|
|||
{
|
||||
XmlRpcResponse response = new XmlRpcResponse();
|
||||
|
||||
Hashtable requestData = (Hashtable) request.Params[0];
|
||||
Hashtable requestData = (Hashtable)request.Params[0];
|
||||
bool GoodXML = (requestData.Contains("Channel") && requestData.Contains("IntValue") &&
|
||||
requestData.Contains("StringValue"));
|
||||
|
||||
if (GoodXML)
|
||||
{
|
||||
LLUUID channel = new LLUUID((string) requestData["Channel"]);
|
||||
LLUUID channel = new LLUUID((string)requestData["Channel"]);
|
||||
RPCChannelInfo rpcChanInfo;
|
||||
if (m_openChannels.TryGetValue(channel, out rpcChanInfo))
|
||||
{
|
||||
string intVal = (string) requestData["IntValue"];
|
||||
string strVal = (string) requestData["StringValue"];
|
||||
string intVal = (string)requestData["IntValue"];
|
||||
string strVal = (string)requestData["StringValue"];
|
||||
|
||||
RPCRequestInfo rpcInfo;
|
||||
|
||||
|
@ -268,7 +278,7 @@ namespace OpenSim.Region.Environment.Modules
|
|||
rpcInfo =
|
||||
new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal,
|
||||
intVal);
|
||||
rpcQueue.Enqueue(rpcInfo);
|
||||
m_rpcPending.Add(rpcInfo.GetMessageID(), rpcInfo);
|
||||
}
|
||||
|
||||
int timeoutCtr = 0;
|
||||
|
@ -280,16 +290,20 @@ namespace OpenSim.Region.Environment.Modules
|
|||
}
|
||||
if (rpcInfo.IsProcessed())
|
||||
{
|
||||
response.Value = rpcInfo.GetRetval();
|
||||
Hashtable param = new Hashtable();
|
||||
param["StringValue"] = rpcInfo.GetStrRetval();
|
||||
param["IntValue"] = Convert.ToString(rpcInfo.GetIntRetval());
|
||||
|
||||
ArrayList parameters = new ArrayList();
|
||||
parameters.Add(param);
|
||||
|
||||
response.Value = parameters;
|
||||
rpcInfo = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
response.SetFault(-1, "Script timeout");
|
||||
lock (XMLRPCListLock)
|
||||
{
|
||||
m_pendingResponse.Remove(rpcInfo.GetMessageID());
|
||||
}
|
||||
rpcInfo = null;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -303,129 +317,365 @@ namespace OpenSim.Region.Environment.Modules
|
|||
|
||||
public bool hasRequests()
|
||||
{
|
||||
return (rpcQueue.Count > 0);
|
||||
lock (XMLRPCListLock)
|
||||
{
|
||||
if (m_rpcPending != null)
|
||||
return (m_rpcPending.Count > 0);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public RPCRequestInfo GetNextRequest()
|
||||
public RPCRequestInfo GetNextCompletedRequest()
|
||||
{
|
||||
if (m_rpcPending != null)
|
||||
{
|
||||
lock (XMLRPCListLock)
|
||||
{
|
||||
foreach (LLUUID luid in m_rpcPending.Keys)
|
||||
{
|
||||
RPCRequestInfo tmpReq;
|
||||
|
||||
if (m_rpcPending.TryGetValue(luid, out tmpReq))
|
||||
{
|
||||
|
||||
if (!tmpReq.IsProcessed()) return tmpReq;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void RemoveCompletedRequest(LLUUID id)
|
||||
{
|
||||
lock (XMLRPCListLock)
|
||||
{
|
||||
RPCRequestInfo rpcInfo = rpcQueue.Dequeue();
|
||||
m_pendingResponse.Add(rpcInfo.GetMessageID(), rpcInfo);
|
||||
return rpcInfo;
|
||||
RPCRequestInfo tmp;
|
||||
if (m_rpcPending.TryGetValue(id, out tmp))
|
||||
{
|
||||
m_rpcPending.Remove(id);
|
||||
m_rpcPendingResponses.Add(id, tmp);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("UNABLE TO REMOVE COMPLETED REQUEST");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public LLUUID SendRemoteData(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata)
|
||||
{
|
||||
|
||||
SendRemoteDataRequest req = new SendRemoteDataRequest(
|
||||
localID, itemID, channel, dest, idata, sdata
|
||||
);
|
||||
m_pendingSRDResponses.Add(req.GetReqID(), req);
|
||||
return req.process();
|
||||
|
||||
}
|
||||
|
||||
public SendRemoteDataRequest GetNextCompletedSRDRequest()
|
||||
{
|
||||
if (m_pendingSRDResponses != null)
|
||||
{
|
||||
lock (XMLRPCListLock)
|
||||
{
|
||||
foreach (LLUUID luid in m_pendingSRDResponses.Keys)
|
||||
{
|
||||
SendRemoteDataRequest tmpReq;
|
||||
|
||||
if (m_pendingSRDResponses.TryGetValue(luid, out tmpReq))
|
||||
{
|
||||
if (tmpReq.finished)
|
||||
return tmpReq;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void RemoveCompletedSRDRequest(LLUUID id)
|
||||
{
|
||||
lock (XMLRPCListLock)
|
||||
{
|
||||
SendRemoteDataRequest tmpReq;
|
||||
if (m_pendingSRDResponses.TryGetValue(id, out tmpReq))
|
||||
{
|
||||
m_pendingSRDResponses.Remove(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void CancelSRDRequests(LLUUID itemID)
|
||||
{
|
||||
if (m_pendingSRDResponses != null)
|
||||
{
|
||||
lock (XMLRPCListLock)
|
||||
{
|
||||
foreach (SendRemoteDataRequest li in m_pendingSRDResponses.Values)
|
||||
{
|
||||
if (li.m_itemID.Equals(itemID))
|
||||
m_pendingSRDResponses.Remove(li.GetReqID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**************************************************************
|
||||
*
|
||||
* Class RPCRequestInfo
|
||||
*
|
||||
* Holds details about incoming requests until they are picked
|
||||
* from the queue by LSLLongCmdHandler
|
||||
* ***********************************************************/
|
||||
|
||||
/**************************************************************
|
||||
*
|
||||
* Class RPCRequestInfo
|
||||
*
|
||||
* Holds details about incoming requests until they are picked
|
||||
* from the queue by LSLLongCmdHandler
|
||||
* ***********************************************************/
|
||||
|
||||
public class RPCRequestInfo
|
||||
{
|
||||
private string m_StrVal;
|
||||
private string m_IntVal;
|
||||
private bool m_processed;
|
||||
private string m_resp;
|
||||
private uint m_localID;
|
||||
private LLUUID m_ItemID;
|
||||
private LLUUID m_MessageID;
|
||||
private LLUUID m_ChannelKey;
|
||||
|
||||
public RPCRequestInfo(uint localID, LLUUID itemID, LLUUID channelKey, string strVal, string intVal)
|
||||
public class RPCRequestInfo
|
||||
{
|
||||
m_localID = localID;
|
||||
m_StrVal = strVal;
|
||||
m_IntVal = intVal;
|
||||
m_ItemID = itemID;
|
||||
m_ChannelKey = channelKey;
|
||||
m_MessageID = LLUUID.Random();
|
||||
m_processed = false;
|
||||
m_resp = String.Empty;
|
||||
private string m_StrVal;
|
||||
private string m_IntVal;
|
||||
private bool m_processed;
|
||||
private string m_respStr;
|
||||
private int m_respInt;
|
||||
private uint m_localID;
|
||||
private LLUUID m_ItemID;
|
||||
private LLUUID m_MessageID;
|
||||
private LLUUID m_ChannelKey;
|
||||
|
||||
public RPCRequestInfo(uint localID, LLUUID itemID, LLUUID channelKey, string strVal, string intVal)
|
||||
{
|
||||
m_localID = localID;
|
||||
m_StrVal = strVal;
|
||||
m_IntVal = intVal;
|
||||
m_ItemID = itemID;
|
||||
m_ChannelKey = channelKey;
|
||||
m_MessageID = LLUUID.Random();
|
||||
m_processed = false;
|
||||
m_respStr = String.Empty;
|
||||
m_respInt = 0;
|
||||
}
|
||||
|
||||
public bool IsProcessed()
|
||||
{
|
||||
return m_processed;
|
||||
}
|
||||
|
||||
public LLUUID GetChannelKey()
|
||||
{
|
||||
return m_ChannelKey;
|
||||
}
|
||||
|
||||
public void SetProcessed(bool processed)
|
||||
{
|
||||
m_processed = processed;
|
||||
}
|
||||
|
||||
public void SetStrRetval(string resp)
|
||||
{
|
||||
m_respStr = resp;
|
||||
}
|
||||
|
||||
public string GetStrRetval()
|
||||
{
|
||||
return m_respStr;
|
||||
}
|
||||
public void SetIntRetval(int resp)
|
||||
{
|
||||
m_respInt = resp;
|
||||
}
|
||||
|
||||
public int GetIntRetval()
|
||||
{
|
||||
return m_respInt;
|
||||
}
|
||||
public uint GetLocalID()
|
||||
{
|
||||
return m_localID;
|
||||
}
|
||||
|
||||
public LLUUID GetItemID()
|
||||
{
|
||||
return m_ItemID;
|
||||
}
|
||||
|
||||
public string GetStrVal()
|
||||
{
|
||||
return m_StrVal;
|
||||
}
|
||||
|
||||
public int GetIntValue()
|
||||
{
|
||||
return int.Parse(m_IntVal);
|
||||
}
|
||||
|
||||
public LLUUID GetMessageID()
|
||||
{
|
||||
return m_MessageID;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsProcessed()
|
||||
public class RPCChannelInfo
|
||||
{
|
||||
return m_processed;
|
||||
private LLUUID m_itemID;
|
||||
private uint m_localID;
|
||||
private LLUUID m_ChannelKey;
|
||||
|
||||
public RPCChannelInfo(uint localID, LLUUID itemID, LLUUID channelID)
|
||||
{
|
||||
m_ChannelKey = channelID;
|
||||
m_localID = localID;
|
||||
m_itemID = itemID;
|
||||
}
|
||||
|
||||
public LLUUID GetItemID()
|
||||
{
|
||||
return m_itemID;
|
||||
}
|
||||
|
||||
public LLUUID GetChannelID()
|
||||
{
|
||||
return m_ChannelKey;
|
||||
}
|
||||
|
||||
public uint GetLocalID()
|
||||
{
|
||||
return m_localID;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public LLUUID GetChannelKey()
|
||||
public class SendRemoteDataRequest
|
||||
{
|
||||
return m_ChannelKey;
|
||||
|
||||
public LLUUID reqID;
|
||||
public string destURL;
|
||||
public string channel;
|
||||
public string sdata;
|
||||
public int idata;
|
||||
public bool finished;
|
||||
public string response_sdata;
|
||||
public int response_idata;
|
||||
public XmlRpcRequest request;
|
||||
private Thread httpThread;
|
||||
public LLUUID m_itemID;
|
||||
public uint m_localID;
|
||||
private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
|
||||
|
||||
public SendRemoteDataRequest(uint localID, LLUUID itemID, string channel, string dest, int idata, string sdata)
|
||||
{
|
||||
|
||||
this.channel = channel;
|
||||
this.destURL = dest;
|
||||
this.idata = idata;
|
||||
this.sdata = sdata;
|
||||
m_itemID = itemID;
|
||||
m_localID = localID;
|
||||
|
||||
reqID = LLUUID.Random();
|
||||
|
||||
}
|
||||
|
||||
public LLUUID process()
|
||||
{
|
||||
httpThread = new Thread(SendRequest);
|
||||
httpThread.Name = "HttpRequestThread";
|
||||
httpThread.Priority = ThreadPriority.BelowNormal;
|
||||
httpThread.IsBackground = true;
|
||||
finished = false;
|
||||
httpThread.Start();
|
||||
|
||||
return reqID;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* TODO: More work on the response codes. Right now
|
||||
* returning 200 for success or 499 for exception
|
||||
*/
|
||||
|
||||
public void SendRequest()
|
||||
{
|
||||
|
||||
Hashtable param = new Hashtable();
|
||||
|
||||
// Check if channel is an LLUUID
|
||||
// if not, use as method name
|
||||
LLUUID parseUID;
|
||||
string mName = "llRemoteData";
|
||||
if( (channel != null) && (channel != "") )
|
||||
if( !LLUUID.TryParse(channel, out parseUID) )
|
||||
mName = channel;
|
||||
else
|
||||
param["Channel"] = channel;
|
||||
|
||||
param["StringValue"] = sdata;
|
||||
param["IntValue"] = Convert.ToString(idata);
|
||||
|
||||
ArrayList parameters = new ArrayList();
|
||||
parameters.Add(param);
|
||||
XmlRpcRequest req = new XmlRpcRequest(mName, parameters);
|
||||
try
|
||||
{
|
||||
XmlRpcResponse resp = req.Send(destURL, 30000);
|
||||
if (resp != null)
|
||||
{
|
||||
Hashtable respParms;
|
||||
if(resp.Value.GetType().Equals(Type.GetType("System.Collections.Hashtable"))) {
|
||||
respParms = (Hashtable)resp.Value;
|
||||
}
|
||||
else {
|
||||
ArrayList respData = (ArrayList)resp.Value;
|
||||
respParms = (Hashtable)respData[0];
|
||||
}
|
||||
if (respParms != null)
|
||||
{
|
||||
if (respParms.Contains("StringValue"))
|
||||
{
|
||||
sdata = (string)respParms["StringValue"];
|
||||
}
|
||||
if (respParms.Contains("IntValue"))
|
||||
{
|
||||
idata = Convert.ToInt32((string)respParms["IntValue"]);
|
||||
}
|
||||
if (respParms.Contains("faultString"))
|
||||
{
|
||||
sdata = (string)respParms["faultString"];
|
||||
}
|
||||
if (respParms.Contains("faultCode"))
|
||||
{
|
||||
idata = Convert.ToInt32(respParms["faultCode"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (System.Net.WebException we)
|
||||
{
|
||||
sdata = we.Message;
|
||||
m_log.Warn("[SendRemoteDataRequest]: Request failed");
|
||||
m_log.Warn(we.StackTrace);
|
||||
}
|
||||
|
||||
finished = true;
|
||||
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
try
|
||||
{
|
||||
httpThread.Abort();
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public LLUUID GetReqID()
|
||||
{
|
||||
return reqID;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void SetProcessed(bool processed)
|
||||
{
|
||||
m_processed = processed;
|
||||
}
|
||||
|
||||
public void SetRetval(string resp)
|
||||
{
|
||||
m_resp = resp;
|
||||
}
|
||||
|
||||
public string GetRetval()
|
||||
{
|
||||
return m_resp;
|
||||
}
|
||||
|
||||
public uint GetLocalID()
|
||||
{
|
||||
return m_localID;
|
||||
}
|
||||
|
||||
public LLUUID GetItemID()
|
||||
{
|
||||
return m_ItemID;
|
||||
}
|
||||
|
||||
public string GetStrVal()
|
||||
{
|
||||
return m_StrVal;
|
||||
}
|
||||
|
||||
public int GetIntValue()
|
||||
{
|
||||
return int.Parse(m_IntVal);
|
||||
}
|
||||
|
||||
public LLUUID GetMessageID()
|
||||
{
|
||||
return m_MessageID;
|
||||
}
|
||||
}
|
||||
|
||||
public class RPCChannelInfo
|
||||
{
|
||||
private LLUUID m_itemID;
|
||||
private uint m_localID;
|
||||
private LLUUID m_ChannelKey;
|
||||
|
||||
public RPCChannelInfo(uint localID, LLUUID itemID, LLUUID channelID)
|
||||
{
|
||||
m_ChannelKey = channelID;
|
||||
m_localID = localID;
|
||||
m_itemID = itemID;
|
||||
}
|
||||
|
||||
public LLUUID GetItemID()
|
||||
{
|
||||
return m_itemID;
|
||||
}
|
||||
|
||||
public LLUUID GetChannelID()
|
||||
{
|
||||
return m_ChannelKey;
|
||||
}
|
||||
|
||||
public uint GetLocalID()
|
||||
{
|
||||
return m_localID;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2091,6 +2091,10 @@ namespace OpenSim.Region.ScriptEngine.Common
|
|||
public const int REMOTE_DATA_CHANNEL = 1;
|
||||
public const int REMOTE_DATA_REQUEST = 2;
|
||||
public const int REMOTE_DATA_REPLY = 3;
|
||||
public const int HTTP_METHOD = 0;
|
||||
public const int HTTP_MIMETYPE = 1;
|
||||
public const int HTTP_BODY_MAXLENGTH = 2;
|
||||
public const int HTTP_VERIFY_CERT = 3;
|
||||
|
||||
public const int PRIM_MATERIAL = 2;
|
||||
public const int PRIM_PHYSICS = 3;
|
||||
|
|
|
@ -2880,8 +2880,8 @@ namespace OpenSim.Region.ScriptEngine.Common
|
|||
public string llSendRemoteData(string channel, string dest, int idata, string sdata)
|
||||
{
|
||||
m_host.AddScriptLPS(1);
|
||||
NotImplemented("llSendRemoteData");
|
||||
return String.Empty;
|
||||
IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
|
||||
return (xmlrpcMod.SendRemoteData(m_localID, m_itemID, channel, dest, idata, sdata)).ToString();
|
||||
}
|
||||
|
||||
public void llRemoteDataReply(string channel, string message_id, string sdata, int idata)
|
||||
|
|
|
@ -125,8 +125,10 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
|||
comms.DeleteListener(itemID);
|
||||
|
||||
IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
|
||||
xmlrpc.DeleteChannel(itemID);
|
||||
xmlrpc.DeleteChannels(itemID);
|
||||
|
||||
xmlrpc.CancelSRDRequests(itemID);
|
||||
|
||||
}
|
||||
|
||||
#region TIMER
|
||||
|
@ -238,24 +240,29 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
|||
// implemented here yet anyway. Should be fixed if/when maxsize
|
||||
// is supported
|
||||
|
||||
object[] resobj = new object[]
|
||||
if (m_ScriptEngine.m_ScriptManager.GetScript(httpInfo.localID, httpInfo.itemID) != null)
|
||||
{
|
||||
iHttpReq.RemoveCompletedRequest(httpInfo.reqID);
|
||||
object[] resobj = new object[]
|
||||
{
|
||||
httpInfo.reqID.ToString(), httpInfo.status, null, httpInfo.response_body
|
||||
};
|
||||
|
||||
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
|
||||
httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj
|
||||
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
|
||||
httpInfo.localID, httpInfo.itemID, "http_response", EventQueueManager.llDetectNull, resobj
|
||||
);
|
||||
|
||||
httpInfo.Stop();
|
||||
httpInfo = null;
|
||||
}
|
||||
|
||||
httpInfo = iHttpReq.GetNextCompletedRequest();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Check llRemoteData channels
|
||||
|
||||
public void CheckXMLRPCRequests()
|
||||
{
|
||||
if (m_ScriptEngine.World == null)
|
||||
|
@ -265,47 +272,96 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
|||
|
||||
if (xmlrpc != null)
|
||||
{
|
||||
while (xmlrpc.hasRequests())
|
||||
{
|
||||
RPCRequestInfo rInfo = xmlrpc.GetNextRequest();
|
||||
//Console.WriteLine("PICKED REQUEST");
|
||||
RPCRequestInfo rInfo = xmlrpc.GetNextCompletedRequest();
|
||||
|
||||
//Deliver data to prim's remote_data handler
|
||||
object[] resobj = new object[]
|
||||
while (rInfo != null)
|
||||
{
|
||||
if (m_ScriptEngine.m_ScriptManager.GetScript(rInfo.GetLocalID(), rInfo.GetItemID()) != null)
|
||||
{
|
||||
xmlrpc.RemoveCompletedRequest(rInfo.GetMessageID());
|
||||
|
||||
//Deliver data to prim's remote_data handler
|
||||
object[] resobj = new object[]
|
||||
{
|
||||
2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), String.Empty,
|
||||
rInfo.GetIntValue(),
|
||||
rInfo.GetStrVal()
|
||||
};
|
||||
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
|
||||
rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", EventQueueManager.llDetectNull, resobj
|
||||
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
|
||||
rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", EventQueueManager.llDetectNull, resobj
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
rInfo = xmlrpc.GetNextCompletedRequest();
|
||||
|
||||
}
|
||||
|
||||
SendRemoteDataRequest srdInfo = xmlrpc.GetNextCompletedSRDRequest();
|
||||
|
||||
while (srdInfo != null)
|
||||
{
|
||||
if (m_ScriptEngine.m_ScriptManager.GetScript(srdInfo.m_localID, srdInfo.m_itemID) != null)
|
||||
{
|
||||
xmlrpc.RemoveCompletedSRDRequest(srdInfo.GetReqID());
|
||||
|
||||
//Deliver data to prim's remote_data handler
|
||||
object[] resobj = new object[]
|
||||
{
|
||||
3, srdInfo.channel.ToString(), srdInfo.GetReqID().ToString(), String.Empty,
|
||||
srdInfo.idata,
|
||||
srdInfo.sdata
|
||||
};
|
||||
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
|
||||
srdInfo.m_localID, srdInfo.m_itemID, "remote_data", EventQueueManager.llDetectNull, resobj
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
srdInfo = xmlrpc.GetNextCompletedSRDRequest();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Check llListeners
|
||||
|
||||
public void CheckListeners()
|
||||
{
|
||||
if (m_ScriptEngine.World == null)
|
||||
return;
|
||||
IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
|
||||
|
||||
while (comms.HasMessages())
|
||||
if (comms != null)
|
||||
{
|
||||
ListenerInfo lInfo = comms.GetNextMessage();
|
||||
|
||||
//Deliver data to prim's listen handler
|
||||
object[] resobj = new object[]
|
||||
while (comms.HasMessages())
|
||||
{
|
||||
if (m_ScriptEngine.m_ScriptManager.GetScript(
|
||||
comms.PeekNextMessageLocalID(), comms.PeekNextMessageItemID()) != null)
|
||||
{
|
||||
lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage()
|
||||
};
|
||||
ListenerInfo lInfo = comms.GetNextMessage();
|
||||
|
||||
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
|
||||
lInfo.GetLocalID(), lInfo.GetItemID(), "listen", EventQueueManager.llDetectNull, resobj
|
||||
);
|
||||
//Deliver data to prim's listen handler
|
||||
object[] resobj = new object[]
|
||||
{
|
||||
lInfo.GetChannel(), lInfo.GetName(), lInfo.GetID().ToString(), lInfo.GetMessage()
|
||||
};
|
||||
|
||||
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
|
||||
lInfo.GetLocalID(), lInfo.GetItemID(), "listen", EventQueueManager.llDetectNull, resobj
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// If set to true then threads and stuff should try to make a graceful exit
|
||||
/// </summary>
|
||||
|
@ -317,4 +373,4 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
|||
private bool _PleaseShutdown = false;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
|||
private Queue<LUStruct> LUQueue = new Queue<LUStruct>();
|
||||
private static bool PrivateThread;
|
||||
private int LoadUnloadMaxQueueSize;
|
||||
private Object scriptLock = new Object();
|
||||
|
||||
// Load/Unload structure
|
||||
private struct LUStruct
|
||||
|
@ -304,7 +305,9 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
|||
//ScriptBaseInterface Script = (ScriptBaseInterface)GetScript(localID, itemID);
|
||||
IScript Script = GetScript(localID, itemID);
|
||||
if (Script == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//cfk 2-7-08 dont need this right now and the default Linux build has DEBUG defined
|
||||
///#if DEBUG
|
||||
/// Console.WriteLine("ScriptEngine: Executing event: " + FunctionName);
|
||||
|
@ -331,37 +334,42 @@ namespace OpenSim.Region.ScriptEngine.Common.ScriptEngineBase
|
|||
|
||||
public IScript GetScript(uint localID, LLUUID itemID)
|
||||
{
|
||||
if (Scripts.ContainsKey(localID) == false)
|
||||
return null;
|
||||
lock (scriptLock)
|
||||
{
|
||||
if (Scripts.ContainsKey(localID) == false)
|
||||
return null;
|
||||
|
||||
Dictionary<LLUUID, IScript> Obj;
|
||||
Scripts.TryGetValue(localID, out Obj);
|
||||
if (Obj.ContainsKey(itemID) == false)
|
||||
return null;
|
||||
Dictionary<LLUUID, IScript> Obj;
|
||||
Scripts.TryGetValue(localID, out Obj);
|
||||
if (Obj.ContainsKey(itemID) == false)
|
||||
return null;
|
||||
|
||||
// Get script
|
||||
IScript Script;
|
||||
Obj.TryGetValue(itemID, out Script);
|
||||
|
||||
return Script;
|
||||
// Get script
|
||||
IScript Script;
|
||||
Obj.TryGetValue(itemID, out Script);
|
||||
return Script;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetScript(uint localID, LLUUID itemID, IScript Script)
|
||||
{
|
||||
// Create object if it doesn't exist
|
||||
if (Scripts.ContainsKey(localID) == false)
|
||||
lock (scriptLock)
|
||||
{
|
||||
Scripts.Add(localID, new Dictionary<LLUUID, IScript>());
|
||||
// Create object if it doesn't exist
|
||||
if (Scripts.ContainsKey(localID) == false)
|
||||
{
|
||||
Scripts.Add(localID, new Dictionary<LLUUID, IScript>());
|
||||
}
|
||||
|
||||
// Delete script if it exists
|
||||
Dictionary<LLUUID, IScript> Obj;
|
||||
Scripts.TryGetValue(localID, out Obj);
|
||||
if (Obj.ContainsKey(itemID) == true)
|
||||
Obj.Remove(itemID);
|
||||
|
||||
// Add to object
|
||||
Obj.Add(itemID, Script);
|
||||
}
|
||||
|
||||
// Delete script if it exists
|
||||
Dictionary<LLUUID, IScript> Obj;
|
||||
Scripts.TryGetValue(localID, out Obj);
|
||||
if (Obj.ContainsKey(itemID) == true)
|
||||
Obj.Remove(itemID);
|
||||
|
||||
// Add to object
|
||||
Obj.Add(itemID, Script);
|
||||
}
|
||||
|
||||
public void RemoveScript(uint localID, LLUUID itemID)
|
||||
|
|
Loading…
Reference in New Issue