Code from Illumious Beltran (IBM) implementing more LSL
The functions implemented are: llListen llListenControl llListenRemove llOpenRemoteDataChannel llCloseRemoteDataChannel llRemoteDataReply The events implemented are: listen remote_dataafrisby
parent
c3d8f1f425
commit
29aa41daa0
|
@ -0,0 +1,15 @@
|
||||||
|
using libsecondlife;
|
||||||
|
using OpenSim.Region.Environment.Modules;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Interfaces
|
||||||
|
{
|
||||||
|
public interface IWorldComm
|
||||||
|
{
|
||||||
|
int Listen(uint LocalID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg);
|
||||||
|
void DeliverMessage(string sourceItemID, int type, int channel, string name, string msg);
|
||||||
|
bool HasMessages();
|
||||||
|
ListenerInfo GetNextMessage();
|
||||||
|
void ListenControl(int handle, int active);
|
||||||
|
void ListenRemove(int handle);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
using libsecondlife;
|
||||||
|
using OpenSim.Region.Environment.Modules;
|
||||||
|
|
||||||
|
namespace OpenSim.Region.Environment.Interfaces
|
||||||
|
{
|
||||||
|
public interface IXMLRPC
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -34,6 +34,12 @@ namespace OpenSim.Region.Environment
|
||||||
module = new AvatarProfilesModule();
|
module = new AvatarProfilesModule();
|
||||||
InitialiseModule(module, scene);
|
InitialiseModule(module, scene);
|
||||||
|
|
||||||
|
module = new XMLRPCModule();
|
||||||
|
InitialiseModule(module, scene);
|
||||||
|
|
||||||
|
module = new WorldCommModule();
|
||||||
|
InitialiseModule(module, scene);
|
||||||
|
|
||||||
LoadRegionModule("OpenSim.Region.ExtensionsScriptModule.dll", "ExtensionsScriptingModule", scene);
|
LoadRegionModule("OpenSim.Region.ExtensionsScriptModule.dll", "ExtensionsScriptingModule", scene);
|
||||||
|
|
||||||
string lslPath = Path.Combine("ScriptEngines", "OpenSim.Region.ScriptEngine.DotNetEngine.dll");
|
string lslPath = Path.Combine("ScriptEngines", "OpenSim.Region.ScriptEngine.DotNetEngine.dll");
|
||||||
|
|
|
@ -0,0 +1,481 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using libsecondlife;
|
||||||
|
using OpenSim.Framework.Interfaces;
|
||||||
|
using OpenSim.Framework.Utilities;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
|
using Nwc.XmlRpc;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
/*****************************************************
|
||||||
|
*
|
||||||
|
* WorldCommModule
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Holding place for world comms - basically llListen
|
||||||
|
* function implementation.
|
||||||
|
*
|
||||||
|
* lLListen(integer channel, string name, key id, string msg)
|
||||||
|
* The name, id, and msg arguments specify the filtering
|
||||||
|
* criteria. You can pass the empty string
|
||||||
|
* (or NULL_KEY for id) for these to set a completely
|
||||||
|
* open filter; this causes the listen() event handler to be
|
||||||
|
* invoked for all chat on the channel. To listen only
|
||||||
|
* for chat spoken by a specific object or avatar,
|
||||||
|
* specify the name and/or id arguments. To listen
|
||||||
|
* only for a specific command, specify the
|
||||||
|
* (case-sensitive) msg argument. If msg is not empty,
|
||||||
|
* listener will only hear strings which are exactly equal
|
||||||
|
* to msg. You can also use all the arguments to establish
|
||||||
|
* the most restrictive filtering criteria.
|
||||||
|
*
|
||||||
|
* It might be useful for each listener to maintain a message
|
||||||
|
* digest, with a list of recent messages by UUID. This can
|
||||||
|
* be used to prevent in-world repeater loops. However, the
|
||||||
|
* linden functions do not have this capability, so for now
|
||||||
|
* thats the way it works.
|
||||||
|
*
|
||||||
|
* **************************************************/
|
||||||
|
namespace OpenSim.Region.Environment.Modules
|
||||||
|
{
|
||||||
|
public class WorldCommModule : IRegionModule, IWorldComm
|
||||||
|
{
|
||||||
|
private Scene m_scene;
|
||||||
|
private object CommListLock = new object();
|
||||||
|
private string m_name = "WorldCommModule";
|
||||||
|
private ListenerManager m_listenerManager;
|
||||||
|
private Queue<ListenerInfo> m_pending;
|
||||||
|
|
||||||
|
public WorldCommModule()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialise(Scene scene)
|
||||||
|
{
|
||||||
|
|
||||||
|
m_scene = scene;
|
||||||
|
m_scene.RegisterModuleInterface<IWorldComm>(this);
|
||||||
|
m_listenerManager = new ListenerManager();
|
||||||
|
m_pending = new Queue<ListenerInfo>();
|
||||||
|
m_scene.EventManager.OnNewClient += NewClient;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CloseDown()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSharedModule()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void NewClient(IClientAPI client)
|
||||||
|
{
|
||||||
|
client.OnChatFromViewer += DeliverClientMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DeliverClientMessage(byte[] message, byte type, int channel, LLVector3 fromPos, string fromName,
|
||||||
|
LLUUID fromAgentID)
|
||||||
|
{
|
||||||
|
ASCIIEncoding ae = new ASCIIEncoding();
|
||||||
|
|
||||||
|
DeliverMessage(fromAgentID.ToString(), type, channel, fromName, ae.GetString(message));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public int Listen(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg)
|
||||||
|
{
|
||||||
|
return m_listenerManager.AddListener(localID, itemID, hostID, channel, name, id, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ListenControl(int handle, int active)
|
||||||
|
{
|
||||||
|
if ( active == 1 )
|
||||||
|
m_listenerManager.Activate(handle);
|
||||||
|
else if ( active == 0 )
|
||||||
|
m_listenerManager.Dectivate(handle);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ListenRemove(int handle)
|
||||||
|
{
|
||||||
|
m_listenerManager.Remove(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This method scans nearby objects and determines if they are listeners,
|
||||||
|
// and if so if this message fits the filter. If it does, then
|
||||||
|
// enqueue the message for delivery to the objects listen event handler.
|
||||||
|
// Objects that do an llSay have their messages delivered here, and for
|
||||||
|
// nearby avatards, the SimChat function is used.
|
||||||
|
public void DeliverMessage(string sourceItemID, int type, int channel, string name, string msg)
|
||||||
|
{
|
||||||
|
|
||||||
|
SceneObjectPart source = null;
|
||||||
|
ScenePresence avatar = null;
|
||||||
|
|
||||||
|
source = m_scene.GetSceneObjectPart(new LLUUID(sourceItemID));
|
||||||
|
if (source == null)
|
||||||
|
{
|
||||||
|
avatar = m_scene.GetScenePresence(new LLUUID(sourceItemID));
|
||||||
|
}
|
||||||
|
if( (avatar != null) || (source != null) )
|
||||||
|
{
|
||||||
|
// Loop through the objects in the scene
|
||||||
|
// 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)
|
||||||
|
{
|
||||||
|
EntityBase sPart;
|
||||||
|
|
||||||
|
m_scene.Entities.TryGetValue(eb, out sPart);
|
||||||
|
|
||||||
|
// Dont process if this message is from itself!
|
||||||
|
if (eb.ToString().Equals(sourceItemID) ||
|
||||||
|
sPart.UUID.ToString().Equals(sourceItemID) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
double dis = 0;
|
||||||
|
|
||||||
|
if (source != null)
|
||||||
|
dis = sPart.AbsolutePosition.GetDistanceTo(source.AbsolutePosition);
|
||||||
|
else
|
||||||
|
dis = sPart.AbsolutePosition.GetDistanceTo(avatar.AbsolutePosition);
|
||||||
|
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case 0: // Whisper
|
||||||
|
|
||||||
|
if ((dis < 10) && (dis > -10))
|
||||||
|
{
|
||||||
|
ListenerInfo isListener = m_listenerManager.IsListenerMatch(
|
||||||
|
sourceItemID, sPart.UUID, channel, name, msg
|
||||||
|
);
|
||||||
|
if (isListener != null)
|
||||||
|
{
|
||||||
|
m_pending.Enqueue(isListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: // Say
|
||||||
|
|
||||||
|
if ((dis < 30) && (dis > -30))
|
||||||
|
{
|
||||||
|
ListenerInfo isListener = m_listenerManager.IsListenerMatch(
|
||||||
|
sourceItemID, sPart.UUID, channel, name, msg
|
||||||
|
);
|
||||||
|
if (isListener != null)
|
||||||
|
{
|
||||||
|
m_pending.Enqueue(isListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2: // Shout
|
||||||
|
if ((dis < 100) && (dis > -100))
|
||||||
|
{
|
||||||
|
ListenerInfo isListener = m_listenerManager.IsListenerMatch(
|
||||||
|
sourceItemID, sPart.UUID, channel, name, msg
|
||||||
|
);
|
||||||
|
if (isListener != null)
|
||||||
|
{
|
||||||
|
m_pending.Enqueue(isListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xff: // Broadcast
|
||||||
|
ListenerInfo isListen = m_listenerManager.IsListenerMatch(sourceItemID, eb, channel, name, msg);
|
||||||
|
if (isListen != null)
|
||||||
|
{
|
||||||
|
ListenerInfo isListener = m_listenerManager.IsListenerMatch(
|
||||||
|
sourceItemID, sPart.UUID, channel, name, msg
|
||||||
|
);
|
||||||
|
if (isListener != null)
|
||||||
|
{
|
||||||
|
m_pending.Enqueue(isListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasMessages()
|
||||||
|
{
|
||||||
|
return (m_pending.Count > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListenerInfo GetNextMessage()
|
||||||
|
{
|
||||||
|
|
||||||
|
ListenerInfo li = null;
|
||||||
|
|
||||||
|
lock (CommListLock)
|
||||||
|
{
|
||||||
|
li = m_pending.Dequeue();
|
||||||
|
}
|
||||||
|
|
||||||
|
return li;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// hostID: the ID of the ScenePart
|
||||||
|
// itemID: the ID of the script host engine
|
||||||
|
// localID: local ID of host engine
|
||||||
|
public class ListenerManager
|
||||||
|
{
|
||||||
|
private Dictionary<int, ListenerInfo> m_listeners;
|
||||||
|
private object ListenersLock = new object();
|
||||||
|
private int m_MaxListeners = 100;
|
||||||
|
|
||||||
|
public ListenerManager()
|
||||||
|
{
|
||||||
|
m_listeners = new Dictionary<int, ListenerInfo>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int AddListener(uint localID, LLUUID itemID, LLUUID hostID, int channel, string name, string id, string msg)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ( m_listeners.Count < m_MaxListeners )
|
||||||
|
{
|
||||||
|
ListenerInfo isListener = IsListenerMatch(LLUUID.Zero.ToString(), itemID, channel, name, msg);
|
||||||
|
|
||||||
|
if(isListener == null)
|
||||||
|
{
|
||||||
|
int newHandle = GetNewHandle();
|
||||||
|
|
||||||
|
if (newHandle > -1)
|
||||||
|
{
|
||||||
|
|
||||||
|
ListenerInfo li = new ListenerInfo(localID, newHandle, itemID, hostID, channel, name, id, msg);
|
||||||
|
|
||||||
|
lock (ListenersLock)
|
||||||
|
{
|
||||||
|
m_listeners.Add(newHandle, li);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newHandle;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Remove(int handle)
|
||||||
|
{
|
||||||
|
m_listeners.Remove(handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int GetNewHandle()
|
||||||
|
{
|
||||||
|
|
||||||
|
for (int i = 0; i < int.MaxValue - 1; i++)
|
||||||
|
{
|
||||||
|
if (!m_listeners.ContainsKey(i))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsListener(LLUUID hostID)
|
||||||
|
{
|
||||||
|
|
||||||
|
foreach (ListenerInfo li in m_listeners.Values)
|
||||||
|
{
|
||||||
|
if (li.GetHostID().Equals(hostID))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Activate(int handle)
|
||||||
|
{
|
||||||
|
|
||||||
|
ListenerInfo li;
|
||||||
|
|
||||||
|
if( m_listeners.TryGetValue(handle, out li) )
|
||||||
|
{
|
||||||
|
li.Activate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dectivate(int handle)
|
||||||
|
{
|
||||||
|
|
||||||
|
ListenerInfo li;
|
||||||
|
|
||||||
|
if( m_listeners.TryGetValue(handle, out li) )
|
||||||
|
{
|
||||||
|
li.Deactivate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Theres probably a more clever and efficient way to
|
||||||
|
// do this, maybe with regex.
|
||||||
|
public ListenerInfo IsListenerMatch(string sourceItemID, LLUUID listenerKey, int channel, string name, string msg)
|
||||||
|
{
|
||||||
|
|
||||||
|
bool isMatch = true;
|
||||||
|
|
||||||
|
foreach (ListenerInfo li in m_listeners.Values)
|
||||||
|
{
|
||||||
|
if (li.GetHostID().Equals(listenerKey))
|
||||||
|
{
|
||||||
|
if ( li.IsActive() )
|
||||||
|
{
|
||||||
|
if ( channel == li.GetChannel() )
|
||||||
|
{
|
||||||
|
if ( (li.GetID().ToString().Length > 0) &&
|
||||||
|
(!li.GetID().Equals(LLUUID.Zero)) )
|
||||||
|
{
|
||||||
|
if (!li.GetID().ToString().Equals(sourceItemID))
|
||||||
|
{
|
||||||
|
isMatch = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( isMatch && (li.GetName().Length > 0) )
|
||||||
|
{
|
||||||
|
if ( li.GetName().Equals(name) )
|
||||||
|
{
|
||||||
|
isMatch = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( isMatch )
|
||||||
|
{
|
||||||
|
return new ListenerInfo(
|
||||||
|
li.GetLocalID(), li.GetHandle(), li.GetItemID(), li.GetHostID(),
|
||||||
|
li.GetChannel(), name, li.GetID(), msg, new LLUUID(sourceItemID)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ListenerInfo
|
||||||
|
{
|
||||||
|
|
||||||
|
private LLUUID m_itemID; // ID of the host script engine
|
||||||
|
private LLUUID m_hostID; // ID of the host/scene part
|
||||||
|
private LLUUID m_sourceItemID; // ID of the scenePart or avatar source of the message
|
||||||
|
private int m_channel; // Channel
|
||||||
|
private int m_handle; // Assigned handle of this listener
|
||||||
|
private uint m_localID; // Local ID from script engine
|
||||||
|
private string m_name; // Object name to filter messages from
|
||||||
|
private LLUUID m_id; // ID to filter messages from
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
m_handle = handle;
|
||||||
|
m_channel = channel;
|
||||||
|
m_itemID = ItemID;
|
||||||
|
m_hostID = hostID;
|
||||||
|
m_name = name;
|
||||||
|
m_id = id;
|
||||||
|
m_message = message;
|
||||||
|
m_active = true;
|
||||||
|
m_localID = localID;
|
||||||
|
}
|
||||||
|
public LLUUID GetItemID()
|
||||||
|
{
|
||||||
|
return m_itemID;
|
||||||
|
}
|
||||||
|
public LLUUID GetHostID()
|
||||||
|
{
|
||||||
|
return m_hostID;
|
||||||
|
}
|
||||||
|
public LLUUID GetSourceItemID()
|
||||||
|
{
|
||||||
|
return m_sourceItemID;
|
||||||
|
}
|
||||||
|
public int GetChannel()
|
||||||
|
{
|
||||||
|
return m_channel;
|
||||||
|
}
|
||||||
|
public uint GetLocalID()
|
||||||
|
{
|
||||||
|
return m_localID;
|
||||||
|
}
|
||||||
|
public int GetHandle()
|
||||||
|
{
|
||||||
|
return m_handle;
|
||||||
|
}
|
||||||
|
public string GetMessage()
|
||||||
|
{
|
||||||
|
return m_message;
|
||||||
|
}
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
public bool IsActive()
|
||||||
|
{
|
||||||
|
return m_active;
|
||||||
|
}
|
||||||
|
public void Deactivate()
|
||||||
|
{
|
||||||
|
m_active = false;
|
||||||
|
}
|
||||||
|
public void Activate()
|
||||||
|
{
|
||||||
|
m_active = true;
|
||||||
|
}
|
||||||
|
public LLUUID GetID()
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,360 @@
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Threading;
|
||||||
|
using libsecondlife;
|
||||||
|
using OpenSim.Framework.Interfaces;
|
||||||
|
using OpenSim.Framework.Utilities;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
using OpenSim.Region.Environment.Scenes;
|
||||||
|
using OpenSim.Framework.Servers;
|
||||||
|
using Nwc.XmlRpc;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
/*****************************************************
|
||||||
|
*
|
||||||
|
* XMLRPCModule
|
||||||
|
*
|
||||||
|
* Module for accepting incoming communications from
|
||||||
|
* external XMLRPC client and calling a remote data
|
||||||
|
* procedure for a registered data channel/prim.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 1. On module load, open a listener port
|
||||||
|
* 2. Attach an XMLRPC handler
|
||||||
|
* 3. When a request is received:
|
||||||
|
* 3.1 Parse into components: channel key, int, string
|
||||||
|
* 3.2 Look up registered channel listeners
|
||||||
|
* 3.3 Call the channel (prim) remote data method
|
||||||
|
* 3.4 Capture the response (llRemoteDataReply)
|
||||||
|
* 3.5 Return response to client caller
|
||||||
|
* 3.6 If no response from llRemoteDataReply within
|
||||||
|
* RemoteReplyScriptTimeout, generate script timeout fault
|
||||||
|
*
|
||||||
|
* Prims in script must:
|
||||||
|
* 1. Open a remote data channel
|
||||||
|
* 1.1 Generate a channel ID
|
||||||
|
* 1.2 Register primid,channelid pair with module
|
||||||
|
* 2. Implement the remote data procedure handler
|
||||||
|
*
|
||||||
|
* llOpenRemoteDataChannel
|
||||||
|
* llRemoteDataReply
|
||||||
|
* remote_data(integer type, key channel, key messageid, string sender, integer ival, string sval)
|
||||||
|
* llCloseRemoteDataChannel
|
||||||
|
*
|
||||||
|
* **************************************************/
|
||||||
|
namespace OpenSim.Region.Environment.Modules
|
||||||
|
{
|
||||||
|
public class XMLRPCModule : IRegionModule, IXMLRPC
|
||||||
|
{
|
||||||
|
private Scene m_scene;
|
||||||
|
private Queue<RPCRequestInfo> rpcQueue = new Queue<RPCRequestInfo>();
|
||||||
|
private object XMLRPCListLock = new object();
|
||||||
|
private string m_name = "XMLRPCModule";
|
||||||
|
private int RemoteReplyScriptWait = 100;
|
||||||
|
private int RemoteReplyScriptTimeout = 300;
|
||||||
|
|
||||||
|
// <channel id, RPCChannelInfo>
|
||||||
|
private Dictionary<LLUUID, RPCChannelInfo> m_openChannels;
|
||||||
|
|
||||||
|
// <channel id, RPCRequestInfo>
|
||||||
|
private Dictionary<LLUUID, RPCRequestInfo> m_pendingResponse;
|
||||||
|
|
||||||
|
public XMLRPCModule()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Initialise(Scene scene)
|
||||||
|
{
|
||||||
|
m_scene = scene;
|
||||||
|
|
||||||
|
m_scene.RegisterModuleInterface<IXMLRPC>(this);
|
||||||
|
|
||||||
|
m_openChannels = new Dictionary<LLUUID, RPCChannelInfo>();
|
||||||
|
m_pendingResponse = new Dictionary<LLUUID, RPCRequestInfo>();
|
||||||
|
|
||||||
|
// Start http server
|
||||||
|
// Attach xmlrpc handlers
|
||||||
|
BaseHttpServer httpServer = new BaseHttpServer(20800);
|
||||||
|
httpServer.AddXmlRPCHandler("llRemoteData", this.XmlRpcRemoteData);
|
||||||
|
httpServer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void PostInitialise()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CloseDown()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public string GetName()
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsSharedModule()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************
|
||||||
|
* OpenXMLRPCChannel
|
||||||
|
*
|
||||||
|
* Generate a LLUUID channel key and add it and
|
||||||
|
* the prim id to dictionary <channelUUID, primUUID>
|
||||||
|
*
|
||||||
|
* First check if there is a channel assigned for
|
||||||
|
* this itemID. If there is, then someone called
|
||||||
|
* llOpenRemoteDataChannel twice. Just return the
|
||||||
|
* original channel. Other option is to delete the
|
||||||
|
* current channel and assign a new one.
|
||||||
|
*
|
||||||
|
* ********************************************/
|
||||||
|
public LLUUID OpenXMLRPCChannel(uint localID, LLUUID itemID)
|
||||||
|
{
|
||||||
|
LLUUID channel = null;
|
||||||
|
|
||||||
|
//Is a dupe?
|
||||||
|
foreach (RPCChannelInfo ci in m_openChannels.Values)
|
||||||
|
{
|
||||||
|
if (ci.GetItemID().Equals(itemID))
|
||||||
|
{
|
||||||
|
// return the original channel ID for this item
|
||||||
|
channel = ci.GetChannelID();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (channel == null) || (channel.Equals(LLUUID.Zero)) )
|
||||||
|
{
|
||||||
|
channel = LLUUID.Random();
|
||||||
|
RPCChannelInfo rpcChanInfo = new RPCChannelInfo(localID, itemID, channel);
|
||||||
|
lock (XMLRPCListLock)
|
||||||
|
{
|
||||||
|
m_openChannels.Add(channel, rpcChanInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************
|
||||||
|
* Remote Data Reply
|
||||||
|
*
|
||||||
|
* Response to RPC message
|
||||||
|
*
|
||||||
|
*********************************************/
|
||||||
|
public void RemoteDataReply(string channel, string message_id, string sdata, int idata)
|
||||||
|
{
|
||||||
|
RPCRequestInfo rpcInfo;
|
||||||
|
LLUUID message_key = new LLUUID(message_id);
|
||||||
|
|
||||||
|
if (m_pendingResponse.TryGetValue(message_key, out rpcInfo))
|
||||||
|
{
|
||||||
|
rpcInfo.SetRetval(sdata);
|
||||||
|
rpcInfo.SetProcessed(true);
|
||||||
|
|
||||||
|
lock (XMLRPCListLock)
|
||||||
|
{
|
||||||
|
m_pendingResponse.Remove(message_key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**********************************************
|
||||||
|
* CloseXMLRPCChannel
|
||||||
|
*
|
||||||
|
* Remove channel from dictionary
|
||||||
|
*
|
||||||
|
*********************************************/
|
||||||
|
public void CloseXMLRPCChannel(LLUUID channelKey)
|
||||||
|
{
|
||||||
|
if(m_openChannels.ContainsKey(channelKey))
|
||||||
|
m_openChannels.Remove(channelKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public XmlRpcResponse XmlRpcRemoteData(XmlRpcRequest request)
|
||||||
|
{
|
||||||
|
|
||||||
|
XmlRpcResponse response = new XmlRpcResponse();
|
||||||
|
|
||||||
|
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"]);
|
||||||
|
RPCChannelInfo rpcChanInfo;
|
||||||
|
if (m_openChannels.TryGetValue(channel, out rpcChanInfo))
|
||||||
|
{
|
||||||
|
string intVal = (string)requestData["IntValue"];
|
||||||
|
string strVal = (string)requestData["StringValue"];
|
||||||
|
|
||||||
|
RPCRequestInfo rpcInfo;
|
||||||
|
|
||||||
|
lock (XMLRPCListLock)
|
||||||
|
{
|
||||||
|
rpcInfo = new RPCRequestInfo(rpcChanInfo.GetLocalID(), rpcChanInfo.GetItemID(), channel, strVal, intVal);
|
||||||
|
rpcQueue.Enqueue(rpcInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
int timeoutCtr = 0;
|
||||||
|
|
||||||
|
while(!rpcInfo.IsProcessed() && (timeoutCtr < RemoteReplyScriptTimeout))
|
||||||
|
{
|
||||||
|
Thread.Sleep(RemoteReplyScriptWait);
|
||||||
|
timeoutCtr += RemoteReplyScriptWait;
|
||||||
|
}
|
||||||
|
if (rpcInfo.IsProcessed())
|
||||||
|
{
|
||||||
|
response.Value = rpcInfo.GetRetval();
|
||||||
|
rpcInfo = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response.SetFault(-1, "Script timeout");
|
||||||
|
lock (XMLRPCListLock)
|
||||||
|
{
|
||||||
|
m_pendingResponse.Remove(rpcInfo.GetMessageID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response.SetFault(-1, "Invalid channel");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool hasRequests()
|
||||||
|
{
|
||||||
|
return (rpcQueue.Count > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public RPCRequestInfo GetNextRequest()
|
||||||
|
{
|
||||||
|
lock (XMLRPCListLock)
|
||||||
|
{
|
||||||
|
RPCRequestInfo rpcInfo = rpcQueue.Dequeue();
|
||||||
|
m_pendingResponse.Add(rpcInfo.GetMessageID(), rpcInfo);
|
||||||
|
return rpcInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************
|
||||||
|
*
|
||||||
|
* 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)
|
||||||
|
{
|
||||||
|
m_localID = localID;
|
||||||
|
m_StrVal = strVal;
|
||||||
|
m_IntVal = intVal;
|
||||||
|
m_ItemID = itemID;
|
||||||
|
m_ChannelKey = channelKey;
|
||||||
|
m_MessageID = LLUUID.Random();
|
||||||
|
m_processed = false;
|
||||||
|
m_resp = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsProcessed()
|
||||||
|
{
|
||||||
|
return m_processed;
|
||||||
|
}
|
||||||
|
public LLUUID GetChannelKey()
|
||||||
|
{
|
||||||
|
return m_ChannelKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -91,6 +91,8 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
|
|
||||||
private IHttpRequests m_httpRequestModule = null;
|
private IHttpRequests m_httpRequestModule = null;
|
||||||
private ISimChat m_simChatModule = null;
|
private ISimChat m_simChatModule = null;
|
||||||
|
private IXMLRPC m_xmlrpcModule = null;
|
||||||
|
private IWorldComm m_worldCommModule = null;
|
||||||
|
|
||||||
|
|
||||||
// Central Update Loop
|
// Central Update Loop
|
||||||
|
@ -210,6 +212,8 @@ namespace OpenSim.Region.Environment.Scenes
|
||||||
{
|
{
|
||||||
m_simChatModule = RequestModuleInterface<ISimChat>();
|
m_simChatModule = RequestModuleInterface<ISimChat>();
|
||||||
m_httpRequestModule = RequestModuleInterface<IHttpRequests>();
|
m_httpRequestModule = RequestModuleInterface<IHttpRequests>();
|
||||||
|
m_xmlrpcModule = RequestModuleInterface<IXMLRPC>();
|
||||||
|
m_worldCommModule = RequestModuleInterface<IWorldComm>();
|
||||||
|
|
||||||
XferManager = RequestModuleInterface<IXfer>();
|
XferManager = RequestModuleInterface<IXfer>();
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,14 +177,19 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler
|
||||||
//type for whisper is 0
|
//type for whisper is 0
|
||||||
World.SimChat(Helpers.StringToField(text),
|
World.SimChat(Helpers.StringToField(text),
|
||||||
0, channelID, m_host.AbsolutePosition, m_host.Name, m_host.UUID);
|
0, channelID, m_host.AbsolutePosition, m_host.Name, m_host.UUID);
|
||||||
|
|
||||||
|
IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
|
||||||
|
wComm.DeliverMessage(m_host.UUID.ToString(), 0, channelID, m_host.Name, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void llSay(int channelID, string text)
|
public void llSay(int channelID, string text)
|
||||||
{
|
{
|
||||||
//type for say is 1
|
//type for say is 1
|
||||||
|
|
||||||
World.SimChat(Helpers.StringToField(text),
|
World.SimChat(Helpers.StringToField(text),
|
||||||
1, channelID, m_host.AbsolutePosition, m_host.Name, m_host.UUID);
|
1, channelID, m_host.AbsolutePosition, m_host.Name, m_host.UUID);
|
||||||
|
|
||||||
|
IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
|
||||||
|
wComm.DeliverMessage(m_host.UUID.ToString(), 1, channelID, m_host.Name, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void llShout(int channelID, string text)
|
public void llShout(int channelID, string text)
|
||||||
|
@ -192,11 +197,32 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler
|
||||||
//type for shout is 2
|
//type for shout is 2
|
||||||
World.SimChat(Helpers.StringToField(text),
|
World.SimChat(Helpers.StringToField(text),
|
||||||
2, channelID, m_host.AbsolutePosition, m_host.Name, m_host.UUID);
|
2, channelID, m_host.AbsolutePosition, m_host.Name, m_host.UUID);
|
||||||
|
|
||||||
|
IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
|
||||||
|
wComm.DeliverMessage(m_host.UUID.ToString(), 2, channelID, m_host.Name, text);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int llListen(int channelID, string name, string ID, string msg) {
|
||||||
|
|
||||||
|
IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
|
||||||
|
return wComm.Listen(m_localID, m_itemID, m_host.UUID, channelID, name, ID, msg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void llListenControl(int number, int active) {
|
||||||
|
|
||||||
|
IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
|
||||||
|
wComm.ListenControl(number, active);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void llListenRemove(int number) {
|
||||||
|
|
||||||
|
IWorldComm wComm = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
|
||||||
|
wComm.ListenRemove(number);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int llListen(int channelID, string name, string ID, string msg) { NotImplemented("llListen"); return 0; }
|
|
||||||
public void llListenControl(int number, int active) { NotImplemented("llListenControl"); return; }
|
|
||||||
public void llListenRemove(int number) { NotImplemented("llListenRemove"); return; }
|
|
||||||
public void llSensor(string name, string id, int type, double range, double arc) { NotImplemented("llSensor"); return; }
|
public void llSensor(string name, string id, int type, double range, double arc) { NotImplemented("llSensor"); return; }
|
||||||
public void llSensorRepeat(string name, string id, int type, double range, double arc, double rate) { NotImplemented("llSensorRepeat"); return; }
|
public void llSensorRepeat(string name, string id, int type, double range, double arc, double rate) { NotImplemented("llSensorRepeat"); return; }
|
||||||
public void llSensorRemove() { NotImplemented("llSensorRemove"); return; }
|
public void llSensorRemove() { NotImplemented("llSensorRemove"); return; }
|
||||||
|
@ -927,10 +953,37 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine.Compiler
|
||||||
public void llRemoteLoadScript() { NotImplemented("llRemoteLoadScript"); }
|
public void llRemoteLoadScript() { NotImplemented("llRemoteLoadScript"); }
|
||||||
public void llSetRemoteScriptAccessPin(int pin) { NotImplemented("llSetRemoteScriptAccessPin"); }
|
public void llSetRemoteScriptAccessPin(int pin) { NotImplemented("llSetRemoteScriptAccessPin"); }
|
||||||
public void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param) { NotImplemented("llRemoteLoadScriptPin"); }
|
public void llRemoteLoadScriptPin(string target, string name, int pin, int running, int start_param) { NotImplemented("llRemoteLoadScriptPin"); }
|
||||||
public void llOpenRemoteDataChannel() { NotImplemented("llOpenRemoteDataChannel"); }
|
|
||||||
|
// remote_data(integer type, key channel, key message_id, string sender, integer ival, string sval)
|
||||||
|
// Not sure where these constants should live:
|
||||||
|
// REMOTE_DATA_CHANNEL = 1
|
||||||
|
// REMOTE_DATA_REQUEST = 2
|
||||||
|
// REMOTE_DATA_REPLY = 3
|
||||||
|
public void llOpenRemoteDataChannel() {
|
||||||
|
|
||||||
|
IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
|
||||||
|
LLUUID channelID = xmlrpcMod.OpenXMLRPCChannel(m_localID, m_itemID);
|
||||||
|
object[] resobj = new object[] { 1, channelID.ToString(), LLUUID.Zero.ToString(), "", 0, "" };
|
||||||
|
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(m_localID, m_itemID, "remote_data", resobj);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public string llSendRemoteData(string channel, string dest, int idata, string sdata) { NotImplemented("llSendRemoteData"); return ""; }
|
public string llSendRemoteData(string channel, string dest, int idata, string sdata) { NotImplemented("llSendRemoteData"); return ""; }
|
||||||
public void llRemoteDataReply(string channel, string message_id, string sdata, int idata) { NotImplemented("llRemoteDataReply"); }
|
|
||||||
public void llCloseRemoteDataChannel(string channel) { NotImplemented("llCloseRemoteDataChannel"); }
|
public void llRemoteDataReply(string channel, string message_id, string sdata, int idata)
|
||||||
|
{
|
||||||
|
|
||||||
|
IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
|
||||||
|
xmlrpcMod.RemoteDataReply(channel, message_id, sdata, idata);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void llCloseRemoteDataChannel(string channel) {
|
||||||
|
|
||||||
|
IXMLRPC xmlrpcMod = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
|
||||||
|
xmlrpcMod.CloseXMLRPCChannel(channel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public string llMD5String(string src, int nonce)
|
public string llMD5String(string src, int nonce)
|
||||||
{
|
{
|
||||||
|
|
|
@ -4,6 +4,8 @@ using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using libsecondlife;
|
using libsecondlife;
|
||||||
using OpenSim.Region.ScriptEngine.Common;
|
using OpenSim.Region.ScriptEngine.Common;
|
||||||
|
using OpenSim.Region.Environment.Modules;
|
||||||
|
using OpenSim.Region.Environment.Interfaces;
|
||||||
|
|
||||||
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
{
|
{
|
||||||
|
@ -26,6 +28,7 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
cmdHandlerThread.Priority = ThreadPriority.BelowNormal;
|
cmdHandlerThread.Priority = ThreadPriority.BelowNormal;
|
||||||
cmdHandlerThread.IsBackground = true;
|
cmdHandlerThread.IsBackground = true;
|
||||||
cmdHandlerThread.Start();
|
cmdHandlerThread.Start();
|
||||||
|
|
||||||
}
|
}
|
||||||
~LSLLongCmdHandler()
|
~LSLLongCmdHandler()
|
||||||
{
|
{
|
||||||
|
@ -50,11 +53,19 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
{
|
{
|
||||||
// Check timers
|
// Check timers
|
||||||
CheckTimerEvents();
|
CheckTimerEvents();
|
||||||
|
Thread.Sleep(25);
|
||||||
// Check HttpRequests
|
// Check HttpRequests
|
||||||
CheckHttpRequests();
|
CheckHttpRequests();
|
||||||
|
Thread.Sleep(25);
|
||||||
|
// Check XMLRPCRequests
|
||||||
|
CheckXMLRPCRequests();
|
||||||
|
Thread.Sleep(25);
|
||||||
|
// Check Listeners
|
||||||
|
CheckListeners();
|
||||||
|
Thread.Sleep(25);
|
||||||
|
|
||||||
// Sleep before next cycle
|
// Sleep before next cycle
|
||||||
Thread.Sleep(cmdHandlerThreadCycleSleepms);
|
//Thread.Sleep(cmdHandlerThreadCycleSleepms);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,5 +269,53 @@ namespace OpenSim.Region.ScriptEngine.DotNetEngine
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
public void CheckXMLRPCRequests()
|
||||||
|
{
|
||||||
|
|
||||||
|
IXMLRPC xmlrpc = m_ScriptEngine.World.RequestModuleInterface<IXMLRPC>();
|
||||||
|
|
||||||
|
while (xmlrpc.hasRequests())
|
||||||
|
{
|
||||||
|
RPCRequestInfo rInfo = xmlrpc.GetNextRequest();
|
||||||
|
System.Console.WriteLine("PICKED REQUEST");
|
||||||
|
|
||||||
|
//Deliver data to prim's remote_data handler
|
||||||
|
object[] resobj = new object[] {
|
||||||
|
2, rInfo.GetChannelKey().ToString(), rInfo.GetMessageID().ToString(), "", rInfo.GetIntValue(), rInfo.GetStrVal()
|
||||||
|
};
|
||||||
|
m_ScriptEngine.m_EventQueueManager.AddToScriptQueue(
|
||||||
|
rInfo.GetLocalID(), rInfo.GetItemID(), "remote_data", resobj
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CheckListeners()
|
||||||
|
{
|
||||||
|
|
||||||
|
IWorldComm comms = m_ScriptEngine.World.RequestModuleInterface<IWorldComm>();
|
||||||
|
|
||||||
|
while (comms.HasMessages())
|
||||||
|
{
|
||||||
|
ListenerInfo lInfo = comms.GetNextMessage();
|
||||||
|
System.Console.WriteLine("PICKED LISTENER");
|
||||||
|
|
||||||
|
//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", resobj
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -474,6 +474,7 @@
|
||||||
<Reference name="OpenSim.Framework.Console"/>
|
<Reference name="OpenSim.Framework.Console"/>
|
||||||
<Reference name="OpenSim.Region.Physics.Manager"/>
|
<Reference name="OpenSim.Region.Physics.Manager"/>
|
||||||
<Reference name="OpenSim.Framework.Servers"/>
|
<Reference name="OpenSim.Framework.Servers"/>
|
||||||
|
<Reference name="OpenSim.Region.ScriptEngine.DotNetEngine"/>
|
||||||
<!-- For scripting in funny languages by default -->
|
<!-- For scripting in funny languages by default -->
|
||||||
<Reference name="Microsoft.JScript"/>
|
<Reference name="Microsoft.JScript"/>
|
||||||
<Reference name="XMLRPC.dll"/>
|
<Reference name="XMLRPC.dll"/>
|
||||||
|
|
Loading…
Reference in New Issue