From c4e6397a92644d94a624432c5d487562738f9033 Mon Sep 17 00:00:00 2001 From: diva Date: Sat, 2 May 2009 14:47:33 +0000 Subject: Rename CoreModules.Communications to CoreModule.ServiceConnectors and, inside it, REST to Remote. --- .../Communications/Local/LocalInterregionComms.cs | 302 ------- .../Communications/REST/RESTInterregionComms.cs | 922 --------------------- .../Local/LocalInterregionComms.cs | 302 +++++++ .../Remote/RESTInterregionComms.cs | 922 +++++++++++++++++++++ 4 files changed, 1224 insertions(+), 1224 deletions(-) delete mode 100644 OpenSim/Region/CoreModules/Communications/Local/LocalInterregionComms.cs delete mode 100644 OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs create mode 100644 OpenSim/Region/CoreModules/ServiceConnectors/Local/LocalInterregionComms.cs create mode 100644 OpenSim/Region/CoreModules/ServiceConnectors/Remote/RESTInterregionComms.cs diff --git a/OpenSim/Region/CoreModules/Communications/Local/LocalInterregionComms.cs b/OpenSim/Region/CoreModules/Communications/Local/LocalInterregionComms.cs deleted file mode 100644 index 1e430e5..0000000 --- a/OpenSim/Region/CoreModules/Communications/Local/LocalInterregionComms.cs +++ /dev/null @@ -1,302 +0,0 @@ -/* - * 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.Collections.Generic; -using System.Reflection; -using log4net; -using Nini.Config; -using OpenMetaverse; -using OpenSim.Framework; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; - -namespace OpenSim.Region.CoreModules.Communications.Local -{ - public class LocalInterregionComms : IRegionModule, IInterregionCommsOut, IInterregionCommsIn - { - private bool m_enabled = false; - - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private List m_sceneList = new List(); - - #region Events - public event ChildAgentUpdateReceived OnChildAgentUpdate; - - #endregion /* Events */ - - #region IRegionModule - - public void Initialise(Scene scene, IConfigSource config) - { - if (m_sceneList.Count == 0) - { - IConfig startupConfig = config.Configs["Communications"]; - - if ((startupConfig != null) && (startupConfig.GetString("InterregionComms", "RESTComms") == "LocalComms")) - { - m_log.Debug("[LOCAL COMMS]: Enabling InterregionComms LocalComms module"); - m_enabled = true; - } - } - - if (!m_enabled) - return; - - Init(scene); - } - - public void PostInitialise() - { - } - - public void Close() - { - } - - public string Name - { - get { return "LocalInterregionCommsModule"; } - } - - public bool IsSharedModule - { - get { return true; } - } - /// - /// Can be called from other modules. - /// - /// - public void Init(Scene scene) - { - if (!m_sceneList.Contains(scene)) - { - lock (m_sceneList) - { - m_sceneList.Add(scene); - if (m_enabled) - scene.RegisterModuleInterface(this); - scene.RegisterModuleInterface(this); - } - - } - } - - #endregion /* IRegionModule */ - - #region IInterregionComms - - /** - * Agent-related communications - */ - - public bool SendCreateChildAgent(ulong regionHandle, AgentCircuitData aCircuit) - { - foreach (Scene s in m_sceneList) - { - if (s.RegionInfo.RegionHandle == regionHandle) - { -// m_log.DebugFormat("[LOCAL COMMS]: Found region {0} to send SendCreateChildAgent", regionHandle); - s.NewUserConnection(aCircuit); - return true; - } - } - -// m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for SendCreateChildAgent", regionHandle); - return false; - } - - public bool SendChildAgentUpdate(ulong regionHandle, AgentData cAgentData) - { - foreach (Scene s in m_sceneList) - { - if (s.RegionInfo.RegionHandle == regionHandle) - { - //m_log.DebugFormat( - // "[LOCAL COMMS]: Found region {0} {1} to send ChildAgentUpdate", - // s.RegionInfo.RegionName, regionHandle); - - s.IncomingChildAgentDataUpdate(cAgentData); - return true; - } - } - -// m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle); - return false; - } - - public bool SendChildAgentUpdate(ulong regionHandle, AgentPosition cAgentData) - { - foreach (Scene s in m_sceneList) - { - if (s.RegionInfo.RegionHandle == regionHandle) - { - //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); - s.IncomingChildAgentDataUpdate(cAgentData); - return true; - } - } - //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); - return false; - } - - public bool SendRetrieveRootAgent(ulong regionHandle, UUID id, out IAgentData agent) - { - agent = null; - foreach (Scene s in m_sceneList) - { - if (s.RegionInfo.RegionHandle == regionHandle) - { - //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); - return s.IncomingRetrieveRootAgent(id, out agent); - } - } - //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); - return false; - } - - public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri) - { - //uint x, y; - //Utils.LongToUInts(regionHandle, out x, out y); - //x = x / Constants.RegionSize; - //y = y / Constants.RegionSize; - //m_log.Debug("\n >>> Local SendReleaseAgent " + x + "-" + y); - foreach (Scene s in m_sceneList) - { - if (s.RegionInfo.RegionHandle == regionHandle) - { - //m_log.Debug("[LOCAL COMMS]: Found region to SendReleaseAgent"); - return s.IncomingReleaseAgent(id); - } - } - //m_log.Debug("[LOCAL COMMS]: region not found in SendReleaseAgent"); - return false; - } - - public bool SendCloseAgent(ulong regionHandle, UUID id) - { - //uint x, y; - //Utils.LongToUInts(regionHandle, out x, out y); - //x = x / Constants.RegionSize; - //y = y / Constants.RegionSize; - //m_log.Debug("\n >>> Local SendCloseAgent " + x + "-" + y); - foreach (Scene s in m_sceneList) - { - if (s.RegionInfo.RegionHandle == regionHandle) - { - //m_log.Debug("[LOCAL COMMS]: Found region to SendCloseAgent"); - return s.IncomingCloseAgent(id); - } - } - //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); - return false; - } - - /** - * Object-related communications - */ - - public bool SendCreateObject(ulong regionHandle, ISceneObject sog, bool isLocalCall) - { - foreach (Scene s in m_sceneList) - { - if (s.RegionInfo.RegionHandle == regionHandle) - { - //m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); - if (isLocalCall) - { - // We need to make a local copy of the object - ISceneObject sogClone = sog.CloneForNewScene(); - sogClone.SetState(sog.GetStateSnapshot(), - s.RegionInfo.RegionID); - return s.IncomingCreateObject(sogClone); - } - else - { - // Use the object as it came through the wire - return s.IncomingCreateObject(sog); - } - } - } - return false; - } - - public bool SendCreateObject(ulong regionHandle, UUID userID, UUID itemID) - { - foreach (Scene s in m_sceneList) - { - if (s.RegionInfo.RegionHandle == regionHandle) - { - return s.IncomingCreateObject(userID, itemID); - } - } - return false; - } - - - /** - * Region-related communications - */ - - public bool SendHelloNeighbour(ulong regionHandle, RegionInfo thisRegion) - { - foreach (Scene s in m_sceneList) - { - if (s.RegionInfo.RegionHandle == regionHandle) - { - //m_log.Debug("[LOCAL COMMS]: Found region to SendHelloNeighbour"); - return s.IncomingHelloNeighbour(thisRegion); - } - } - return false; - } - - #endregion /* IInterregionComms */ - - #region Misc - - public UUID GetRegionID(ulong regionhandle) - { - foreach (Scene s in m_sceneList) - { - if (s.RegionInfo.RegionHandle == regionhandle) - return s.RegionInfo.RegionID; - } - // ? weird. should not happen - return m_sceneList[0].RegionInfo.RegionID; - } - - public bool IsLocalRegion(ulong regionhandle) - { - foreach (Scene s in m_sceneList) - if (s.RegionInfo.RegionHandle == regionhandle) - return true; - return false; - } - - #endregion - } -} diff --git a/OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs b/OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs deleted file mode 100644 index 97ffeae..0000000 --- a/OpenSim/Region/CoreModules/Communications/REST/RESTInterregionComms.cs +++ /dev/null @@ -1,922 +0,0 @@ -/* - * 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.IO; -using System.Net; -using System.Reflection; -using System.Text; -using log4net; -using Nini.Config; -using OpenMetaverse; -using OpenMetaverse.StructuredData; -using OpenSim.Framework; -using OpenSim.Framework.Communications; -using OpenSim.Framework.Communications.Clients; -using OpenSim.Region.CoreModules.Communications.Local; -using OpenSim.Region.Framework.Interfaces; -using OpenSim.Region.Framework.Scenes; -using OpenSim.Region.Framework.Scenes.Hypergrid; - -namespace OpenSim.Region.CoreModules.Communications.REST -{ - public class RESTInterregionComms : IRegionModule, IInterregionCommsOut - { - private bool initialized = false; - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - - protected bool m_enabled = false; - protected Scene m_aScene; - // RESTInterregionComms does not care about local regions; it delegates that to the Local module - protected LocalInterregionComms m_localBackend; - - protected CommunicationsManager m_commsManager; - - protected RegionToRegionClient m_regionClient; - - protected bool m_safemode; - protected IPAddress m_thisIP; - - #region IRegionModule - - public virtual void Initialise(Scene scene, IConfigSource config) - { - if (!initialized) - { - initialized = true; - IConfig startupConfig = config.Configs["Communications"]; - - if ((startupConfig == null) - || (startupConfig != null) - && (startupConfig.GetString("InterregionComms", "RESTComms") == "RESTComms")) - { - m_log.Info("[REST COMMS]: Enabling InterregionComms RESTComms module"); - m_enabled = true; - if (config.Configs["Hypergrid"] != null) - m_safemode = config.Configs["Hypergrid"].GetBoolean("safemode", false); - - InitOnce(scene); - } - } - - if (!m_enabled) - return; - - InitEach(scene); - - } - - public virtual void PostInitialise() - { - if (m_enabled) - AddHTTPHandlers(); - } - - public virtual void Close() - { - } - - public virtual string Name - { - get { return "RESTInterregionCommsModule"; } - } - - public virtual bool IsSharedModule - { - get { return true; } - } - - protected virtual void InitEach(Scene scene) - { - m_localBackend.Init(scene); - scene.RegisterModuleInterface(this); - } - - protected virtual void InitOnce(Scene scene) - { - m_localBackend = new LocalInterregionComms(); - m_commsManager = scene.CommsManager; - m_aScene = scene; - m_regionClient = new RegionToRegionClient(m_aScene); - m_thisIP = Util.GetHostFromDNS(scene.RegionInfo.ExternalHostName); - } - - protected virtual void AddHTTPHandlers() - { - m_aScene.CommsManager.HttpServer.AddHTTPHandler("/agent/", AgentHandler); - m_aScene.CommsManager.HttpServer.AddHTTPHandler("/object/", ObjectHandler); - m_aScene.CommsManager.HttpServer.AddHTTPHandler("/region/", RegionHandler); - } - - #endregion /* IRegionModule */ - - #region IInterregionComms - - /** - * Agent-related communications - */ - - public bool SendCreateChildAgent(ulong regionHandle, AgentCircuitData aCircuit) - { - // Try local first - if (m_localBackend.SendCreateChildAgent(regionHandle, aCircuit)) - return true; - - // else do the remote thing - if (!m_localBackend.IsLocalRegion(regionHandle)) - { - RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); - if (regInfo != null) - { - m_regionClient.SendUserInformation(regInfo, aCircuit); - - return m_regionClient.DoCreateChildAgentCall(regInfo, aCircuit, "None"); - } - //else - // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); - } - return false; - } - - public bool SendChildAgentUpdate(ulong regionHandle, AgentData cAgentData) - { - // Try local first - if (m_localBackend.SendChildAgentUpdate(regionHandle, cAgentData)) - return true; - - // else do the remote thing - if (!m_localBackend.IsLocalRegion(regionHandle)) - { - RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); - if (regInfo != null) - { - return m_regionClient.DoChildAgentUpdateCall(regInfo, cAgentData); - } - //else - // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); - } - return false; - - } - - public bool SendChildAgentUpdate(ulong regionHandle, AgentPosition cAgentData) - { - // Try local first - if (m_localBackend.SendChildAgentUpdate(regionHandle, cAgentData)) - return true; - - // else do the remote thing - if (!m_localBackend.IsLocalRegion(regionHandle)) - { - RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); - if (regInfo != null) - { - return m_regionClient.DoChildAgentUpdateCall(regInfo, cAgentData); - } - //else - // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); - } - return false; - - } - - public bool SendRetrieveRootAgent(ulong regionHandle, UUID id, out IAgentData agent) - { - // Try local first - if (m_localBackend.SendRetrieveRootAgent(regionHandle, id, out agent)) - return true; - - // else do the remote thing - if (!m_localBackend.IsLocalRegion(regionHandle)) - { - RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); - if (regInfo != null) - { - return m_regionClient.DoRetrieveRootAgentCall(regInfo, id, out agent); - } - //else - // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); - } - return false; - - } - - public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri) - { - // Try local first - if (m_localBackend.SendReleaseAgent(regionHandle, id, uri)) - return true; - - // else do the remote thing - return m_regionClient.DoReleaseAgentCall(regionHandle, id, uri); - } - - - public bool SendCloseAgent(ulong regionHandle, UUID id) - { - // Try local first - if (m_localBackend.SendCloseAgent(regionHandle, id)) - return true; - - // else do the remote thing - if (!m_localBackend.IsLocalRegion(regionHandle)) - { - RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); - if (regInfo != null) - { - return m_regionClient.DoCloseAgentCall(regInfo, id); - } - //else - // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); - } - return false; - } - - /** - * Object-related communications - */ - - public bool SendCreateObject(ulong regionHandle, ISceneObject sog, bool isLocalCall) - { - // Try local first - if (m_localBackend.SendCreateObject(regionHandle, sog, true)) - { - //m_log.Debug("[REST COMMS]: LocalBackEnd SendCreateObject succeeded"); - return true; - } - - // else do the remote thing - if (!m_localBackend.IsLocalRegion(regionHandle)) - { - RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); - if (regInfo != null) - { - return m_regionClient.DoCreateObjectCall(regInfo, sog, m_aScene.m_allowScriptCrossings); - } - //else - // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); - } - return false; - } - - public bool SendCreateObject(ulong regionHandle, UUID userID, UUID itemID) - { - // Not Implemented - return false; - } - - /** - * Region-related communications - */ - - public bool SendHelloNeighbour(ulong regionHandle, RegionInfo thisRegion) - { - // Try local first - if (m_localBackend.SendHelloNeighbour(regionHandle, thisRegion)) - { - //m_log.Debug("[REST COMMS]: LocalBackEnd SendHelloNeighbour succeeded"); - return true; - } - - // else do the remote thing - RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); - if ((regInfo != null) && - // Don't remote-call this instance; that's a startup hickup - !((regInfo.ExternalHostName == thisRegion.ExternalHostName) && (regInfo.HttpPort == thisRegion.HttpPort))) - { - return m_regionClient.DoHelloNeighbourCall(regInfo, thisRegion); - } - //else - // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); - return false; - } - - #endregion /* IInterregionComms */ - - #region Incoming calls from remote instances - - /** - * Agent-related incoming calls - */ - - public Hashtable AgentHandler(Hashtable request) - { - //m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called"); - - m_log.Debug("---------------------------"); - m_log.Debug(" >> uri=" + request["uri"]); - m_log.Debug(" >> content-type=" + request["content-type"]); - m_log.Debug(" >> http-method=" + request["http-method"]); - m_log.Debug("---------------------------\n"); - - Hashtable responsedata = new Hashtable(); - responsedata["content_type"] = "text/html"; - responsedata["keepalive"] = false; - - - UUID agentID; - string action; - ulong regionHandle; - if (!GetParams((string)request["uri"], out agentID, out regionHandle, out action)) - { - m_log.InfoFormat("[REST COMMS]: Invalid parameters for agent message {0}", request["uri"]); - responsedata["int_response_code"] = 404; - responsedata["str_response_string"] = "false"; - - return responsedata; - } - - // Next, let's parse the verb - string method = (string)request["http-method"]; - if (method.Equals("PUT")) - { - DoAgentPut(request, responsedata); - return responsedata; - } - else if (method.Equals("POST")) - { - DoAgentPost(request, responsedata, agentID); - return responsedata; - } - else if (method.Equals("GET")) - { - DoAgentGet(request, responsedata, agentID, regionHandle); - return responsedata; - } - else if (method.Equals("DELETE")) - { - DoAgentDelete(request, responsedata, agentID, action, regionHandle); - return responsedata; - } - else - { - m_log.InfoFormat("[REST COMMS]: method {0} not supported in agent message", method); - responsedata["int_response_code"] = 404; - responsedata["str_response_string"] = "false"; - - return responsedata; - } - - } - - protected virtual void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) - { - if (m_safemode) - { - // Authentication - string authority = string.Empty; - string authToken = string.Empty; - if (!GetAuthentication(request, out authority, out authToken)) - { - m_log.InfoFormat("[REST COMMS]: Authentication failed for agent message {0}", request["uri"]); - responsedata["int_response_code"] = 403; - responsedata["str_response_string"] = "Forbidden"; - return ; - } - if (!VerifyKey(id, authority, authToken)) - { - m_log.InfoFormat("[REST COMMS]: Authentication failed for agent message {0}", request["uri"]); - responsedata["int_response_code"] = 403; - responsedata["str_response_string"] = "Forbidden"; - return ; - } - m_log.DebugFormat("[REST COMMS]: Authentication succeeded for {0}", id); - } - - OSDMap args = RegionClient.GetOSDMap((string)request["body"]); - if (args == null) - { - responsedata["int_response_code"] = 400; - responsedata["str_response_string"] = "false"; - return; - } - - // retrieve the regionhandle - ulong regionhandle = 0; - if (args["destination_handle"] != null) - UInt64.TryParse(args["destination_handle"].AsString(), out regionhandle); - - AgentCircuitData aCircuit = new AgentCircuitData(); - try - { - aCircuit.UnpackAgentCircuitData(args); - } - catch (Exception ex) - { - m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildCreate message {0}", ex.Message); - return; - } - - // This is the meaning of POST agent - m_regionClient.AdjustUserInformation(aCircuit); - bool result = m_localBackend.SendCreateChildAgent(regionhandle, aCircuit); - - responsedata["int_response_code"] = 200; - responsedata["str_response_string"] = result.ToString(); - } - - protected virtual void DoAgentPut(Hashtable request, Hashtable responsedata) - { - OSDMap args = RegionClient.GetOSDMap((string)request["body"]); - if (args == null) - { - responsedata["int_response_code"] = 400; - responsedata["str_response_string"] = "false"; - return; - } - - // retrieve the regionhandle - ulong regionhandle = 0; - if (args["destination_handle"] != null) - UInt64.TryParse(args["destination_handle"].AsString(), out regionhandle); - - string messageType; - if (args["message_type"] != null) - messageType = args["message_type"].AsString(); - else - { - m_log.Warn("[REST COMMS]: Agent Put Message Type not found. "); - messageType = "AgentData"; - } - - bool result = true; - if ("AgentData".Equals(messageType)) - { - AgentData agent = new AgentData(); - try - { - agent.Unpack(args); - } - catch (Exception ex) - { - m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); - return; - } - - //agent.Dump(); - // This is one of the meanings of PUT agent - result = m_localBackend.SendChildAgentUpdate(regionhandle, agent); - - } - else if ("AgentPosition".Equals(messageType)) - { - AgentPosition agent = new AgentPosition(); - try - { - agent.Unpack(args); - } - catch (Exception ex) - { - m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); - return; - } - //agent.Dump(); - // This is one of the meanings of PUT agent - result = m_localBackend.SendChildAgentUpdate(regionhandle, agent); - - } - - responsedata["int_response_code"] = 200; - responsedata["str_response_string"] = result.ToString(); - } - - protected virtual void DoAgentGet(Hashtable request, Hashtable responsedata, UUID id, ulong regionHandle) - { - IAgentData agent = null; - bool result = m_localBackend.SendRetrieveRootAgent(regionHandle, id, out agent); - OSDMap map = null; - if (result) - { - if (agent != null) // just to make sure - { - map = agent.Pack(); - string strBuffer = ""; - try - { - strBuffer = OSDParser.SerializeJsonString(map); - } - catch (Exception e) - { - m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of CreateObject: {0}", e.Message); - // ignore. buffer will be empty, caller should check. - } - - responsedata["content_type"] = "application/json"; - responsedata["int_response_code"] = 200; - responsedata["str_response_string"] = strBuffer; - } - else - { - responsedata["int_response_code"] = 500; - responsedata["str_response_string"] = "Internal error"; - } - } - else - { - responsedata["int_response_code"] = 404; - responsedata["str_response_string"] = "Not Found"; - } - } - - protected virtual void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, ulong regionHandle) - { - //m_log.Debug(" >>> DoDelete action:" + action + "; regionHandle:" + regionHandle); - - if (action.Equals("release")) - m_localBackend.SendReleaseAgent(regionHandle, id, ""); - else - m_localBackend.SendCloseAgent(regionHandle, id); - - responsedata["int_response_code"] = 200; - responsedata["str_response_string"] = "OpenSim agent " + id.ToString(); - - m_log.Debug("[REST COMMS]: Agent Deleted."); - } - - /** - * Object-related incoming calls - */ - - public Hashtable ObjectHandler(Hashtable request) - { - m_log.Debug("[CONNECTION DEBUGGING]: ObjectHandler Called"); - - m_log.Debug("---------------------------"); - m_log.Debug(" >> uri=" + request["uri"]); - m_log.Debug(" >> content-type=" + request["content-type"]); - m_log.Debug(" >> http-method=" + request["http-method"]); - m_log.Debug("---------------------------\n"); - - Hashtable responsedata = new Hashtable(); - responsedata["content_type"] = "text/html"; - - UUID objectID; - string action; - ulong regionHandle; - if (!GetParams((string)request["uri"], out objectID, out regionHandle, out action)) - { - m_log.InfoFormat("[REST COMMS]: Invalid parameters for object message {0}", request["uri"]); - responsedata["int_response_code"] = 404; - responsedata["str_response_string"] = "false"; - - return responsedata; - } - - // Next, let's parse the verb - string method = (string)request["http-method"]; - if (method.Equals("POST")) - { - DoObjectPost(request, responsedata, regionHandle); - return responsedata; - } - else if (method.Equals("PUT")) - { - DoObjectPut(request, responsedata, regionHandle); - return responsedata; - } - //else if (method.Equals("DELETE")) - //{ - // DoObjectDelete(request, responsedata, agentID, action, regionHandle); - // return responsedata; - //} - else - { - m_log.InfoFormat("[REST COMMS]: method {0} not supported in object message", method); - responsedata["int_response_code"] = 404; - responsedata["str_response_string"] = "false"; - - return responsedata; - } - - } - - protected virtual void DoObjectPost(Hashtable request, Hashtable responsedata, ulong regionhandle) - { - OSDMap args = RegionClient.GetOSDMap((string)request["body"]); - if (args == null) - { - responsedata["int_response_code"] = 400; - responsedata["str_response_string"] = "false"; - return; - } - - string sogXmlStr = "", extraStr = "", stateXmlStr = ""; - if (args["sog"] != null) - sogXmlStr = args["sog"].AsString(); - if (args["extra"] != null) - extraStr = args["extra"].AsString(); - - UUID regionID = m_localBackend.GetRegionID(regionhandle); - SceneObjectGroup sog = null; - try - { - sog = new SceneObjectGroup(sogXmlStr); - sog.ExtraFromXmlString(extraStr); - } - catch (Exception ex) - { - m_log.InfoFormat("[REST COMMS]: exception on deserializing scene object {0}", ex.Message); - responsedata["int_response_code"] = 400; - responsedata["str_response_string"] = "false"; - return; - } - - if ((args["state"] != null) && m_aScene.m_allowScriptCrossings) - { - stateXmlStr = args["state"].AsString(); - if (stateXmlStr != "") - { - try - { - sog.SetState(stateXmlStr, regionID); - } - catch (Exception ex) - { - m_log.InfoFormat("[REST COMMS]: exception on setting state for scene object {0}", ex.Message); - - } - } - } - // This is the meaning of POST object - bool result = m_localBackend.SendCreateObject(regionhandle, sog, false); - - responsedata["int_response_code"] = 200; - responsedata["str_response_string"] = result.ToString(); - } - - protected virtual void DoObjectPut(Hashtable request, Hashtable responsedata, ulong regionhandle) - { - OSDMap args = RegionClient.GetOSDMap((string)request["body"]); - if (args == null) - { - responsedata["int_response_code"] = 400; - responsedata["str_response_string"] = "false"; - return; - } - - UUID userID = UUID.Zero, itemID = UUID.Zero; - if (args["userid"] != null) - userID = args["userid"].AsUUID(); - if (args["itemid"] != null) - itemID = args["itemid"].AsUUID(); - - //UUID regionID = m_localBackend.GetRegionID(regionhandle); - - // This is the meaning of PUT object - bool result = m_localBackend.SendCreateObject(regionhandle, userID, itemID); - - responsedata["int_response_code"] = 200; - responsedata["str_response_string"] = result.ToString(); - } - - /* - * Region-related incoming calls - * - */ - - public Hashtable RegionHandler(Hashtable request) - { - //m_log.Debug("[CONNECTION DEBUGGING]: RegionHandler Called"); - - //m_log.Debug("---------------------------"); - //m_log.Debug(" >> uri=" + request["uri"]); - //m_log.Debug(" >> content-type=" + request["content-type"]); - //m_log.Debug(" >> http-method=" + request["http-method"]); - //m_log.Debug("---------------------------\n"); - - Hashtable responsedata = new Hashtable(); - responsedata["content_type"] = "text/html"; - - UUID regionID; - string action; - ulong regionHandle; - if (!GetParams((string)request["uri"], out regionID, out regionHandle, out action)) - { - m_log.InfoFormat("[REST COMMS]: Invalid parameters for object message {0}", request["uri"]); - responsedata["int_response_code"] = 404; - responsedata["str_response_string"] = "false"; - - return responsedata; - } - - // Next, let's parse the verb - string method = (string)request["http-method"]; - if (method.Equals("POST")) - { - DoRegionPost(request, responsedata, regionID); - return responsedata; - } - //else if (method.Equals("PUT")) - //{ - // DoRegionPut(request, responsedata, regionID); - // return responsedata; - //} - //else if (method.Equals("DELETE")) - //{ - // DoRegionDelete(request, responsedata, regiontID); - // return responsedata; - //} - else - { - m_log.InfoFormat("[REST COMMS]: method {0} not supported in region message", method); - responsedata["int_response_code"] = 404; - responsedata["str_response_string"] = "false"; - - return responsedata; - } - - } - - protected virtual void DoRegionPost(Hashtable request, Hashtable responsedata, UUID id) - { - OSDMap args = RegionClient.GetOSDMap((string)request["body"]); - if (args == null) - { - responsedata["int_response_code"] = 400; - responsedata["str_response_string"] = "false"; - return; - } - - // retrieve the regionhandle - ulong regionhandle = 0; - if (args["destination_handle"] != null) - UInt64.TryParse(args["destination_handle"].AsString(), out regionhandle); - - RegionInfo aRegion = new RegionInfo(); - try - { - aRegion.UnpackRegionInfoData(args); - } - catch (Exception ex) - { - m_log.InfoFormat("[REST COMMS]: exception on unpacking HelloNeighbour message {0}", ex.Message); - return; - } - - // This is the meaning of POST region - bool result = m_localBackend.SendHelloNeighbour(regionhandle, aRegion); - - responsedata["int_response_code"] = 200; - responsedata["str_response_string"] = result.ToString(); - } - - - #endregion - - #region Misc - - - /// - /// Extract the param from an uri. - /// - /// Something like this: /agent/uuid/ or /agent/uuid/handle/release - /// uuid on uuid field - /// optional action - public static bool GetParams(string uri, out UUID uuid, out ulong regionHandle, out string action) - { - uuid = UUID.Zero; - action = ""; - regionHandle = 0; - - uri = uri.Trim(new char[] { '/' }); - string[] parts = uri.Split('/'); - if (parts.Length <= 1) - { - return false; - } - else - { - if (!UUID.TryParse(parts[1], out uuid)) - return false; - - if (parts.Length >= 3) - UInt64.TryParse(parts[2], out regionHandle); - if (parts.Length >= 4) - action = parts[3]; - - return true; - } - } - - public static bool GetAuthentication(Hashtable request, out string authority, out string authKey) - { - authority = string.Empty; - authKey = string.Empty; - - Uri authUri; - Hashtable headers = (Hashtable)request["headers"]; - - // Authorization keys look like this: - // http://orgrid.org:8002/ - if (headers.ContainsKey("authorization") && (string)headers["authorization"] != "None") - { - if (Uri.TryCreate((string)headers["authorization"], UriKind.Absolute, out authUri)) - { - authority = authUri.Authority; - authKey = authUri.PathAndQuery.Trim('/'); - m_log.DebugFormat("[REST COMMS]: Got authority {0} and key {1}", authority, authKey); - return true; - } - else - m_log.Debug("[REST COMMS]: Wrong format for Authorization header: " + (string)headers["authorization"]); - } - else - m_log.Debug("[REST COMMS]: Authorization header not found"); - - return false; - } - - bool VerifyKey(UUID userID, string authority, string key) - { - string[] parts = authority.Split(':'); - IPAddress ipaddr = IPAddress.None; - uint port = 0; - if (parts.Length <= 2) - ipaddr = Util.GetHostFromDNS(parts[0]); - if (parts.Length == 2) - UInt32.TryParse(parts[1], out port); - - // local authority (standalone), local call - if (m_thisIP.Equals(ipaddr) && (m_aScene.RegionInfo.HttpPort == port)) - return ((IAuthentication)m_aScene.CommsManager.UserAdminService).VerifyKey(userID, key); - // remote call - else - return AuthClient.VerifyKey("http://" + authority, userID, key); - } - - - #endregion Misc - - protected class RegionToRegionClient : RegionClient - { - Scene m_aScene = null; - - public RegionToRegionClient(Scene s) - { - m_aScene = s; - } - - public override ulong GetRegionHandle(ulong handle) - { - if (m_aScene.SceneGridService is HGSceneCommunicationService) - return ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.FindRegionHandle(handle); - - return handle; - } - - public override bool IsHyperlink(ulong handle) - { - if (m_aScene.SceneGridService is HGSceneCommunicationService) - return ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.IsHyperlinkRegion(handle); - - return false; - } - - public override void SendUserInformation(RegionInfo regInfo, AgentCircuitData aCircuit) - { - try - { - if (m_aScene.SceneGridService is HGSceneCommunicationService) - { - ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.SendUserInformation(regInfo, aCircuit); - } - } - catch // Bad cast - { } - - } - - public override void AdjustUserInformation(AgentCircuitData aCircuit) - { - if (m_aScene.SceneGridService is HGSceneCommunicationService) - ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.AdjustUserInformation(aCircuit); - } - } - - } -} diff --git a/OpenSim/Region/CoreModules/ServiceConnectors/Local/LocalInterregionComms.cs b/OpenSim/Region/CoreModules/ServiceConnectors/Local/LocalInterregionComms.cs new file mode 100644 index 0000000..1e430e5 --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectors/Local/LocalInterregionComms.cs @@ -0,0 +1,302 @@ +/* + * 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.Collections.Generic; +using System.Reflection; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.Communications.Local +{ + public class LocalInterregionComms : IRegionModule, IInterregionCommsOut, IInterregionCommsIn + { + private bool m_enabled = false; + + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private List m_sceneList = new List(); + + #region Events + public event ChildAgentUpdateReceived OnChildAgentUpdate; + + #endregion /* Events */ + + #region IRegionModule + + public void Initialise(Scene scene, IConfigSource config) + { + if (m_sceneList.Count == 0) + { + IConfig startupConfig = config.Configs["Communications"]; + + if ((startupConfig != null) && (startupConfig.GetString("InterregionComms", "RESTComms") == "LocalComms")) + { + m_log.Debug("[LOCAL COMMS]: Enabling InterregionComms LocalComms module"); + m_enabled = true; + } + } + + if (!m_enabled) + return; + + Init(scene); + } + + public void PostInitialise() + { + } + + public void Close() + { + } + + public string Name + { + get { return "LocalInterregionCommsModule"; } + } + + public bool IsSharedModule + { + get { return true; } + } + /// + /// Can be called from other modules. + /// + /// + public void Init(Scene scene) + { + if (!m_sceneList.Contains(scene)) + { + lock (m_sceneList) + { + m_sceneList.Add(scene); + if (m_enabled) + scene.RegisterModuleInterface(this); + scene.RegisterModuleInterface(this); + } + + } + } + + #endregion /* IRegionModule */ + + #region IInterregionComms + + /** + * Agent-related communications + */ + + public bool SendCreateChildAgent(ulong regionHandle, AgentCircuitData aCircuit) + { + foreach (Scene s in m_sceneList) + { + if (s.RegionInfo.RegionHandle == regionHandle) + { +// m_log.DebugFormat("[LOCAL COMMS]: Found region {0} to send SendCreateChildAgent", regionHandle); + s.NewUserConnection(aCircuit); + return true; + } + } + +// m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for SendCreateChildAgent", regionHandle); + return false; + } + + public bool SendChildAgentUpdate(ulong regionHandle, AgentData cAgentData) + { + foreach (Scene s in m_sceneList) + { + if (s.RegionInfo.RegionHandle == regionHandle) + { + //m_log.DebugFormat( + // "[LOCAL COMMS]: Found region {0} {1} to send ChildAgentUpdate", + // s.RegionInfo.RegionName, regionHandle); + + s.IncomingChildAgentDataUpdate(cAgentData); + return true; + } + } + +// m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle); + return false; + } + + public bool SendChildAgentUpdate(ulong regionHandle, AgentPosition cAgentData) + { + foreach (Scene s in m_sceneList) + { + if (s.RegionInfo.RegionHandle == regionHandle) + { + //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); + s.IncomingChildAgentDataUpdate(cAgentData); + return true; + } + } + //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); + return false; + } + + public bool SendRetrieveRootAgent(ulong regionHandle, UUID id, out IAgentData agent) + { + agent = null; + foreach (Scene s in m_sceneList) + { + if (s.RegionInfo.RegionHandle == regionHandle) + { + //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); + return s.IncomingRetrieveRootAgent(id, out agent); + } + } + //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); + return false; + } + + public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri) + { + //uint x, y; + //Utils.LongToUInts(regionHandle, out x, out y); + //x = x / Constants.RegionSize; + //y = y / Constants.RegionSize; + //m_log.Debug("\n >>> Local SendReleaseAgent " + x + "-" + y); + foreach (Scene s in m_sceneList) + { + if (s.RegionInfo.RegionHandle == regionHandle) + { + //m_log.Debug("[LOCAL COMMS]: Found region to SendReleaseAgent"); + return s.IncomingReleaseAgent(id); + } + } + //m_log.Debug("[LOCAL COMMS]: region not found in SendReleaseAgent"); + return false; + } + + public bool SendCloseAgent(ulong regionHandle, UUID id) + { + //uint x, y; + //Utils.LongToUInts(regionHandle, out x, out y); + //x = x / Constants.RegionSize; + //y = y / Constants.RegionSize; + //m_log.Debug("\n >>> Local SendCloseAgent " + x + "-" + y); + foreach (Scene s in m_sceneList) + { + if (s.RegionInfo.RegionHandle == regionHandle) + { + //m_log.Debug("[LOCAL COMMS]: Found region to SendCloseAgent"); + return s.IncomingCloseAgent(id); + } + } + //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); + return false; + } + + /** + * Object-related communications + */ + + public bool SendCreateObject(ulong regionHandle, ISceneObject sog, bool isLocalCall) + { + foreach (Scene s in m_sceneList) + { + if (s.RegionInfo.RegionHandle == regionHandle) + { + //m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); + if (isLocalCall) + { + // We need to make a local copy of the object + ISceneObject sogClone = sog.CloneForNewScene(); + sogClone.SetState(sog.GetStateSnapshot(), + s.RegionInfo.RegionID); + return s.IncomingCreateObject(sogClone); + } + else + { + // Use the object as it came through the wire + return s.IncomingCreateObject(sog); + } + } + } + return false; + } + + public bool SendCreateObject(ulong regionHandle, UUID userID, UUID itemID) + { + foreach (Scene s in m_sceneList) + { + if (s.RegionInfo.RegionHandle == regionHandle) + { + return s.IncomingCreateObject(userID, itemID); + } + } + return false; + } + + + /** + * Region-related communications + */ + + public bool SendHelloNeighbour(ulong regionHandle, RegionInfo thisRegion) + { + foreach (Scene s in m_sceneList) + { + if (s.RegionInfo.RegionHandle == regionHandle) + { + //m_log.Debug("[LOCAL COMMS]: Found region to SendHelloNeighbour"); + return s.IncomingHelloNeighbour(thisRegion); + } + } + return false; + } + + #endregion /* IInterregionComms */ + + #region Misc + + public UUID GetRegionID(ulong regionhandle) + { + foreach (Scene s in m_sceneList) + { + if (s.RegionInfo.RegionHandle == regionhandle) + return s.RegionInfo.RegionID; + } + // ? weird. should not happen + return m_sceneList[0].RegionInfo.RegionID; + } + + public bool IsLocalRegion(ulong regionhandle) + { + foreach (Scene s in m_sceneList) + if (s.RegionInfo.RegionHandle == regionhandle) + return true; + return false; + } + + #endregion + } +} diff --git a/OpenSim/Region/CoreModules/ServiceConnectors/Remote/RESTInterregionComms.cs b/OpenSim/Region/CoreModules/ServiceConnectors/Remote/RESTInterregionComms.cs new file mode 100644 index 0000000..97ffeae --- /dev/null +++ b/OpenSim/Region/CoreModules/ServiceConnectors/Remote/RESTInterregionComms.cs @@ -0,0 +1,922 @@ +/* + * 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.IO; +using System.Net; +using System.Reflection; +using System.Text; +using log4net; +using Nini.Config; +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using OpenSim.Framework; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Communications.Clients; +using OpenSim.Region.CoreModules.Communications.Local; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Hypergrid; + +namespace OpenSim.Region.CoreModules.Communications.REST +{ + public class RESTInterregionComms : IRegionModule, IInterregionCommsOut + { + private bool initialized = false; + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + protected bool m_enabled = false; + protected Scene m_aScene; + // RESTInterregionComms does not care about local regions; it delegates that to the Local module + protected LocalInterregionComms m_localBackend; + + protected CommunicationsManager m_commsManager; + + protected RegionToRegionClient m_regionClient; + + protected bool m_safemode; + protected IPAddress m_thisIP; + + #region IRegionModule + + public virtual void Initialise(Scene scene, IConfigSource config) + { + if (!initialized) + { + initialized = true; + IConfig startupConfig = config.Configs["Communications"]; + + if ((startupConfig == null) + || (startupConfig != null) + && (startupConfig.GetString("InterregionComms", "RESTComms") == "RESTComms")) + { + m_log.Info("[REST COMMS]: Enabling InterregionComms RESTComms module"); + m_enabled = true; + if (config.Configs["Hypergrid"] != null) + m_safemode = config.Configs["Hypergrid"].GetBoolean("safemode", false); + + InitOnce(scene); + } + } + + if (!m_enabled) + return; + + InitEach(scene); + + } + + public virtual void PostInitialise() + { + if (m_enabled) + AddHTTPHandlers(); + } + + public virtual void Close() + { + } + + public virtual string Name + { + get { return "RESTInterregionCommsModule"; } + } + + public virtual bool IsSharedModule + { + get { return true; } + } + + protected virtual void InitEach(Scene scene) + { + m_localBackend.Init(scene); + scene.RegisterModuleInterface(this); + } + + protected virtual void InitOnce(Scene scene) + { + m_localBackend = new LocalInterregionComms(); + m_commsManager = scene.CommsManager; + m_aScene = scene; + m_regionClient = new RegionToRegionClient(m_aScene); + m_thisIP = Util.GetHostFromDNS(scene.RegionInfo.ExternalHostName); + } + + protected virtual void AddHTTPHandlers() + { + m_aScene.CommsManager.HttpServer.AddHTTPHandler("/agent/", AgentHandler); + m_aScene.CommsManager.HttpServer.AddHTTPHandler("/object/", ObjectHandler); + m_aScene.CommsManager.HttpServer.AddHTTPHandler("/region/", RegionHandler); + } + + #endregion /* IRegionModule */ + + #region IInterregionComms + + /** + * Agent-related communications + */ + + public bool SendCreateChildAgent(ulong regionHandle, AgentCircuitData aCircuit) + { + // Try local first + if (m_localBackend.SendCreateChildAgent(regionHandle, aCircuit)) + return true; + + // else do the remote thing + if (!m_localBackend.IsLocalRegion(regionHandle)) + { + RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + m_regionClient.SendUserInformation(regInfo, aCircuit); + + return m_regionClient.DoCreateChildAgentCall(regInfo, aCircuit, "None"); + } + //else + // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); + } + return false; + } + + public bool SendChildAgentUpdate(ulong regionHandle, AgentData cAgentData) + { + // Try local first + if (m_localBackend.SendChildAgentUpdate(regionHandle, cAgentData)) + return true; + + // else do the remote thing + if (!m_localBackend.IsLocalRegion(regionHandle)) + { + RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + return m_regionClient.DoChildAgentUpdateCall(regInfo, cAgentData); + } + //else + // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); + } + return false; + + } + + public bool SendChildAgentUpdate(ulong regionHandle, AgentPosition cAgentData) + { + // Try local first + if (m_localBackend.SendChildAgentUpdate(regionHandle, cAgentData)) + return true; + + // else do the remote thing + if (!m_localBackend.IsLocalRegion(regionHandle)) + { + RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + return m_regionClient.DoChildAgentUpdateCall(regInfo, cAgentData); + } + //else + // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); + } + return false; + + } + + public bool SendRetrieveRootAgent(ulong regionHandle, UUID id, out IAgentData agent) + { + // Try local first + if (m_localBackend.SendRetrieveRootAgent(regionHandle, id, out agent)) + return true; + + // else do the remote thing + if (!m_localBackend.IsLocalRegion(regionHandle)) + { + RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + return m_regionClient.DoRetrieveRootAgentCall(regInfo, id, out agent); + } + //else + // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); + } + return false; + + } + + public bool SendReleaseAgent(ulong regionHandle, UUID id, string uri) + { + // Try local first + if (m_localBackend.SendReleaseAgent(regionHandle, id, uri)) + return true; + + // else do the remote thing + return m_regionClient.DoReleaseAgentCall(regionHandle, id, uri); + } + + + public bool SendCloseAgent(ulong regionHandle, UUID id) + { + // Try local first + if (m_localBackend.SendCloseAgent(regionHandle, id)) + return true; + + // else do the remote thing + if (!m_localBackend.IsLocalRegion(regionHandle)) + { + RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + return m_regionClient.DoCloseAgentCall(regInfo, id); + } + //else + // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); + } + return false; + } + + /** + * Object-related communications + */ + + public bool SendCreateObject(ulong regionHandle, ISceneObject sog, bool isLocalCall) + { + // Try local first + if (m_localBackend.SendCreateObject(regionHandle, sog, true)) + { + //m_log.Debug("[REST COMMS]: LocalBackEnd SendCreateObject succeeded"); + return true; + } + + // else do the remote thing + if (!m_localBackend.IsLocalRegion(regionHandle)) + { + RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); + if (regInfo != null) + { + return m_regionClient.DoCreateObjectCall(regInfo, sog, m_aScene.m_allowScriptCrossings); + } + //else + // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); + } + return false; + } + + public bool SendCreateObject(ulong regionHandle, UUID userID, UUID itemID) + { + // Not Implemented + return false; + } + + /** + * Region-related communications + */ + + public bool SendHelloNeighbour(ulong regionHandle, RegionInfo thisRegion) + { + // Try local first + if (m_localBackend.SendHelloNeighbour(regionHandle, thisRegion)) + { + //m_log.Debug("[REST COMMS]: LocalBackEnd SendHelloNeighbour succeeded"); + return true; + } + + // else do the remote thing + RegionInfo regInfo = m_commsManager.GridService.RequestNeighbourInfo(regionHandle); + if ((regInfo != null) && + // Don't remote-call this instance; that's a startup hickup + !((regInfo.ExternalHostName == thisRegion.ExternalHostName) && (regInfo.HttpPort == thisRegion.HttpPort))) + { + return m_regionClient.DoHelloNeighbourCall(regInfo, thisRegion); + } + //else + // m_log.Warn("[REST COMMS]: Region not found " + regionHandle); + return false; + } + + #endregion /* IInterregionComms */ + + #region Incoming calls from remote instances + + /** + * Agent-related incoming calls + */ + + public Hashtable AgentHandler(Hashtable request) + { + //m_log.Debug("[CONNECTION DEBUGGING]: AgentHandler Called"); + + m_log.Debug("---------------------------"); + m_log.Debug(" >> uri=" + request["uri"]); + m_log.Debug(" >> content-type=" + request["content-type"]); + m_log.Debug(" >> http-method=" + request["http-method"]); + m_log.Debug("---------------------------\n"); + + Hashtable responsedata = new Hashtable(); + responsedata["content_type"] = "text/html"; + responsedata["keepalive"] = false; + + + UUID agentID; + string action; + ulong regionHandle; + if (!GetParams((string)request["uri"], out agentID, out regionHandle, out action)) + { + m_log.InfoFormat("[REST COMMS]: Invalid parameters for agent message {0}", request["uri"]); + responsedata["int_response_code"] = 404; + responsedata["str_response_string"] = "false"; + + return responsedata; + } + + // Next, let's parse the verb + string method = (string)request["http-method"]; + if (method.Equals("PUT")) + { + DoAgentPut(request, responsedata); + return responsedata; + } + else if (method.Equals("POST")) + { + DoAgentPost(request, responsedata, agentID); + return responsedata; + } + else if (method.Equals("GET")) + { + DoAgentGet(request, responsedata, agentID, regionHandle); + return responsedata; + } + else if (method.Equals("DELETE")) + { + DoAgentDelete(request, responsedata, agentID, action, regionHandle); + return responsedata; + } + else + { + m_log.InfoFormat("[REST COMMS]: method {0} not supported in agent message", method); + responsedata["int_response_code"] = 404; + responsedata["str_response_string"] = "false"; + + return responsedata; + } + + } + + protected virtual void DoAgentPost(Hashtable request, Hashtable responsedata, UUID id) + { + if (m_safemode) + { + // Authentication + string authority = string.Empty; + string authToken = string.Empty; + if (!GetAuthentication(request, out authority, out authToken)) + { + m_log.InfoFormat("[REST COMMS]: Authentication failed for agent message {0}", request["uri"]); + responsedata["int_response_code"] = 403; + responsedata["str_response_string"] = "Forbidden"; + return ; + } + if (!VerifyKey(id, authority, authToken)) + { + m_log.InfoFormat("[REST COMMS]: Authentication failed for agent message {0}", request["uri"]); + responsedata["int_response_code"] = 403; + responsedata["str_response_string"] = "Forbidden"; + return ; + } + m_log.DebugFormat("[REST COMMS]: Authentication succeeded for {0}", id); + } + + OSDMap args = RegionClient.GetOSDMap((string)request["body"]); + if (args == null) + { + responsedata["int_response_code"] = 400; + responsedata["str_response_string"] = "false"; + return; + } + + // retrieve the regionhandle + ulong regionhandle = 0; + if (args["destination_handle"] != null) + UInt64.TryParse(args["destination_handle"].AsString(), out regionhandle); + + AgentCircuitData aCircuit = new AgentCircuitData(); + try + { + aCircuit.UnpackAgentCircuitData(args); + } + catch (Exception ex) + { + m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildCreate message {0}", ex.Message); + return; + } + + // This is the meaning of POST agent + m_regionClient.AdjustUserInformation(aCircuit); + bool result = m_localBackend.SendCreateChildAgent(regionhandle, aCircuit); + + responsedata["int_response_code"] = 200; + responsedata["str_response_string"] = result.ToString(); + } + + protected virtual void DoAgentPut(Hashtable request, Hashtable responsedata) + { + OSDMap args = RegionClient.GetOSDMap((string)request["body"]); + if (args == null) + { + responsedata["int_response_code"] = 400; + responsedata["str_response_string"] = "false"; + return; + } + + // retrieve the regionhandle + ulong regionhandle = 0; + if (args["destination_handle"] != null) + UInt64.TryParse(args["destination_handle"].AsString(), out regionhandle); + + string messageType; + if (args["message_type"] != null) + messageType = args["message_type"].AsString(); + else + { + m_log.Warn("[REST COMMS]: Agent Put Message Type not found. "); + messageType = "AgentData"; + } + + bool result = true; + if ("AgentData".Equals(messageType)) + { + AgentData agent = new AgentData(); + try + { + agent.Unpack(args); + } + catch (Exception ex) + { + m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); + return; + } + + //agent.Dump(); + // This is one of the meanings of PUT agent + result = m_localBackend.SendChildAgentUpdate(regionhandle, agent); + + } + else if ("AgentPosition".Equals(messageType)) + { + AgentPosition agent = new AgentPosition(); + try + { + agent.Unpack(args); + } + catch (Exception ex) + { + m_log.InfoFormat("[REST COMMS]: exception on unpacking ChildAgentUpdate message {0}", ex.Message); + return; + } + //agent.Dump(); + // This is one of the meanings of PUT agent + result = m_localBackend.SendChildAgentUpdate(regionhandle, agent); + + } + + responsedata["int_response_code"] = 200; + responsedata["str_response_string"] = result.ToString(); + } + + protected virtual void DoAgentGet(Hashtable request, Hashtable responsedata, UUID id, ulong regionHandle) + { + IAgentData agent = null; + bool result = m_localBackend.SendRetrieveRootAgent(regionHandle, id, out agent); + OSDMap map = null; + if (result) + { + if (agent != null) // just to make sure + { + map = agent.Pack(); + string strBuffer = ""; + try + { + strBuffer = OSDParser.SerializeJsonString(map); + } + catch (Exception e) + { + m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of CreateObject: {0}", e.Message); + // ignore. buffer will be empty, caller should check. + } + + responsedata["content_type"] = "application/json"; + responsedata["int_response_code"] = 200; + responsedata["str_response_string"] = strBuffer; + } + else + { + responsedata["int_response_code"] = 500; + responsedata["str_response_string"] = "Internal error"; + } + } + else + { + responsedata["int_response_code"] = 404; + responsedata["str_response_string"] = "Not Found"; + } + } + + protected virtual void DoAgentDelete(Hashtable request, Hashtable responsedata, UUID id, string action, ulong regionHandle) + { + //m_log.Debug(" >>> DoDelete action:" + action + "; regionHandle:" + regionHandle); + + if (action.Equals("release")) + m_localBackend.SendReleaseAgent(regionHandle, id, ""); + else + m_localBackend.SendCloseAgent(regionHandle, id); + + responsedata["int_response_code"] = 200; + responsedata["str_response_string"] = "OpenSim agent " + id.ToString(); + + m_log.Debug("[REST COMMS]: Agent Deleted."); + } + + /** + * Object-related incoming calls + */ + + public Hashtable ObjectHandler(Hashtable request) + { + m_log.Debug("[CONNECTION DEBUGGING]: ObjectHandler Called"); + + m_log.Debug("---------------------------"); + m_log.Debug(" >> uri=" + request["uri"]); + m_log.Debug(" >> content-type=" + request["content-type"]); + m_log.Debug(" >> http-method=" + request["http-method"]); + m_log.Debug("---------------------------\n"); + + Hashtable responsedata = new Hashtable(); + responsedata["content_type"] = "text/html"; + + UUID objectID; + string action; + ulong regionHandle; + if (!GetParams((string)request["uri"], out objectID, out regionHandle, out action)) + { + m_log.InfoFormat("[REST COMMS]: Invalid parameters for object message {0}", request["uri"]); + responsedata["int_response_code"] = 404; + responsedata["str_response_string"] = "false"; + + return responsedata; + } + + // Next, let's parse the verb + string method = (string)request["http-method"]; + if (method.Equals("POST")) + { + DoObjectPost(request, responsedata, regionHandle); + return responsedata; + } + else if (method.Equals("PUT")) + { + DoObjectPut(request, responsedata, regionHandle); + return responsedata; + } + //else if (method.Equals("DELETE")) + //{ + // DoObjectDelete(request, responsedata, agentID, action, regionHandle); + // return responsedata; + //} + else + { + m_log.InfoFormat("[REST COMMS]: method {0} not supported in object message", method); + responsedata["int_response_code"] = 404; + responsedata["str_response_string"] = "false"; + + return responsedata; + } + + } + + protected virtual void DoObjectPost(Hashtable request, Hashtable responsedata, ulong regionhandle) + { + OSDMap args = RegionClient.GetOSDMap((string)request["body"]); + if (args == null) + { + responsedata["int_response_code"] = 400; + responsedata["str_response_string"] = "false"; + return; + } + + string sogXmlStr = "", extraStr = "", stateXmlStr = ""; + if (args["sog"] != null) + sogXmlStr = args["sog"].AsString(); + if (args["extra"] != null) + extraStr = args["extra"].AsString(); + + UUID regionID = m_localBackend.GetRegionID(regionhandle); + SceneObjectGroup sog = null; + try + { + sog = new SceneObjectGroup(sogXmlStr); + sog.ExtraFromXmlString(extraStr); + } + catch (Exception ex) + { + m_log.InfoFormat("[REST COMMS]: exception on deserializing scene object {0}", ex.Message); + responsedata["int_response_code"] = 400; + responsedata["str_response_string"] = "false"; + return; + } + + if ((args["state"] != null) && m_aScene.m_allowScriptCrossings) + { + stateXmlStr = args["state"].AsString(); + if (stateXmlStr != "") + { + try + { + sog.SetState(stateXmlStr, regionID); + } + catch (Exception ex) + { + m_log.InfoFormat("[REST COMMS]: exception on setting state for scene object {0}", ex.Message); + + } + } + } + // This is the meaning of POST object + bool result = m_localBackend.SendCreateObject(regionhandle, sog, false); + + responsedata["int_response_code"] = 200; + responsedata["str_response_string"] = result.ToString(); + } + + protected virtual void DoObjectPut(Hashtable request, Hashtable responsedata, ulong regionhandle) + { + OSDMap args = RegionClient.GetOSDMap((string)request["body"]); + if (args == null) + { + responsedata["int_response_code"] = 400; + responsedata["str_response_string"] = "false"; + return; + } + + UUID userID = UUID.Zero, itemID = UUID.Zero; + if (args["userid"] != null) + userID = args["userid"].AsUUID(); + if (args["itemid"] != null) + itemID = args["itemid"].AsUUID(); + + //UUID regionID = m_localBackend.GetRegionID(regionhandle); + + // This is the meaning of PUT object + bool result = m_localBackend.SendCreateObject(regionhandle, userID, itemID); + + responsedata["int_response_code"] = 200; + responsedata["str_response_string"] = result.ToString(); + } + + /* + * Region-related incoming calls + * + */ + + public Hashtable RegionHandler(Hashtable request) + { + //m_log.Debug("[CONNECTION DEBUGGING]: RegionHandler Called"); + + //m_log.Debug("---------------------------"); + //m_log.Debug(" >> uri=" + request["uri"]); + //m_log.Debug(" >> content-type=" + request["content-type"]); + //m_log.Debug(" >> http-method=" + request["http-method"]); + //m_log.Debug("---------------------------\n"); + + Hashtable responsedata = new Hashtable(); + responsedata["content_type"] = "text/html"; + + UUID regionID; + string action; + ulong regionHandle; + if (!GetParams((string)request["uri"], out regionID, out regionHandle, out action)) + { + m_log.InfoFormat("[REST COMMS]: Invalid parameters for object message {0}", request["uri"]); + responsedata["int_response_code"] = 404; + responsedata["str_response_string"] = "false"; + + return responsedata; + } + + // Next, let's parse the verb + string method = (string)request["http-method"]; + if (method.Equals("POST")) + { + DoRegionPost(request, responsedata, regionID); + return responsedata; + } + //else if (method.Equals("PUT")) + //{ + // DoRegionPut(request, responsedata, regionID); + // return responsedata; + //} + //else if (method.Equals("DELETE")) + //{ + // DoRegionDelete(request, responsedata, regiontID); + // return responsedata; + //} + else + { + m_log.InfoFormat("[REST COMMS]: method {0} not supported in region message", method); + responsedata["int_response_code"] = 404; + responsedata["str_response_string"] = "false"; + + return responsedata; + } + + } + + protected virtual void DoRegionPost(Hashtable request, Hashtable responsedata, UUID id) + { + OSDMap args = RegionClient.GetOSDMap((string)request["body"]); + if (args == null) + { + responsedata["int_response_code"] = 400; + responsedata["str_response_string"] = "false"; + return; + } + + // retrieve the regionhandle + ulong regionhandle = 0; + if (args["destination_handle"] != null) + UInt64.TryParse(args["destination_handle"].AsString(), out regionhandle); + + RegionInfo aRegion = new RegionInfo(); + try + { + aRegion.UnpackRegionInfoData(args); + } + catch (Exception ex) + { + m_log.InfoFormat("[REST COMMS]: exception on unpacking HelloNeighbour message {0}", ex.Message); + return; + } + + // This is the meaning of POST region + bool result = m_localBackend.SendHelloNeighbour(regionhandle, aRegion); + + responsedata["int_response_code"] = 200; + responsedata["str_response_string"] = result.ToString(); + } + + + #endregion + + #region Misc + + + /// + /// Extract the param from an uri. + /// + /// Something like this: /agent/uuid/ or /agent/uuid/handle/release + /// uuid on uuid field + /// optional action + public static bool GetParams(string uri, out UUID uuid, out ulong regionHandle, out string action) + { + uuid = UUID.Zero; + action = ""; + regionHandle = 0; + + uri = uri.Trim(new char[] { '/' }); + string[] parts = uri.Split('/'); + if (parts.Length <= 1) + { + return false; + } + else + { + if (!UUID.TryParse(parts[1], out uuid)) + return false; + + if (parts.Length >= 3) + UInt64.TryParse(parts[2], out regionHandle); + if (parts.Length >= 4) + action = parts[3]; + + return true; + } + } + + public static bool GetAuthentication(Hashtable request, out string authority, out string authKey) + { + authority = string.Empty; + authKey = string.Empty; + + Uri authUri; + Hashtable headers = (Hashtable)request["headers"]; + + // Authorization keys look like this: + // http://orgrid.org:8002/ + if (headers.ContainsKey("authorization") && (string)headers["authorization"] != "None") + { + if (Uri.TryCreate((string)headers["authorization"], UriKind.Absolute, out authUri)) + { + authority = authUri.Authority; + authKey = authUri.PathAndQuery.Trim('/'); + m_log.DebugFormat("[REST COMMS]: Got authority {0} and key {1}", authority, authKey); + return true; + } + else + m_log.Debug("[REST COMMS]: Wrong format for Authorization header: " + (string)headers["authorization"]); + } + else + m_log.Debug("[REST COMMS]: Authorization header not found"); + + return false; + } + + bool VerifyKey(UUID userID, string authority, string key) + { + string[] parts = authority.Split(':'); + IPAddress ipaddr = IPAddress.None; + uint port = 0; + if (parts.Length <= 2) + ipaddr = Util.GetHostFromDNS(parts[0]); + if (parts.Length == 2) + UInt32.TryParse(parts[1], out port); + + // local authority (standalone), local call + if (m_thisIP.Equals(ipaddr) && (m_aScene.RegionInfo.HttpPort == port)) + return ((IAuthentication)m_aScene.CommsManager.UserAdminService).VerifyKey(userID, key); + // remote call + else + return AuthClient.VerifyKey("http://" + authority, userID, key); + } + + + #endregion Misc + + protected class RegionToRegionClient : RegionClient + { + Scene m_aScene = null; + + public RegionToRegionClient(Scene s) + { + m_aScene = s; + } + + public override ulong GetRegionHandle(ulong handle) + { + if (m_aScene.SceneGridService is HGSceneCommunicationService) + return ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.FindRegionHandle(handle); + + return handle; + } + + public override bool IsHyperlink(ulong handle) + { + if (m_aScene.SceneGridService is HGSceneCommunicationService) + return ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.IsHyperlinkRegion(handle); + + return false; + } + + public override void SendUserInformation(RegionInfo regInfo, AgentCircuitData aCircuit) + { + try + { + if (m_aScene.SceneGridService is HGSceneCommunicationService) + { + ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.SendUserInformation(regInfo, aCircuit); + } + } + catch // Bad cast + { } + + } + + public override void AdjustUserInformation(AgentCircuitData aCircuit) + { + if (m_aScene.SceneGridService is HGSceneCommunicationService) + ((HGSceneCommunicationService)(m_aScene.SceneGridService)).m_hg.AdjustUserInformation(aCircuit); + } + } + + } +} -- cgit v1.1