From f4efa325bb8a1e4ae876ec5f080cf87c1f8c1de9 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 31 Dec 2009 11:42:33 -0800 Subject: [PATCH] More progress on both the Simulation service and the Login service. Both still unfinished. --- OpenSim/Framework/Util.cs | 27 ++ .../Simulation/SimulationServiceConnector.cs | 242 ++++++++++++++++++ .../Services/LLLoginService/LLLoginService.cs | 162 +++++++++++- 3 files changed, 429 insertions(+), 2 deletions(-) create mode 100644 OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs diff --git a/OpenSim/Framework/Util.cs b/OpenSim/Framework/Util.cs index 72150863f4..234021c233 100644 --- a/OpenSim/Framework/Util.cs +++ b/OpenSim/Framework/Util.cs @@ -1186,6 +1186,33 @@ namespace OpenSim.Framework return null; } + public static OSDMap GetOSDMap(string data) + { + OSDMap args = null; + try + { + OSD buffer; + // We should pay attention to the content-type, but let's assume we know it's Json + buffer = OSDParser.DeserializeJson(data); + if (buffer.Type == OSDType.Map) + { + args = (OSDMap)buffer; + return args; + } + else + { + // uh? + m_log.Debug(("[UTILS]: Got OSD of unexpected type " + buffer.Type.ToString())); + return null; + } + } + catch (Exception ex) + { + m_log.Debug("[UTILS]: exception on GetOSDMap " + ex.Message); + return null; + } + } + public static string[] Glob(string path) { string vol=String.Empty; diff --git a/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs new file mode 100644 index 0000000000..6f71197de7 --- /dev/null +++ b/OpenSim/Services/Connectors/Simulation/SimulationServiceConnector.cs @@ -0,0 +1,242 @@ +/* + * 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 OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Reflection; +using System.Text; + +using OpenSim.Framework; +using OpenSim.Services.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +using OpenMetaverse; +using OpenMetaverse.StructuredData; +using log4net; + +namespace OpenSim.Services.Connectors.Simulation +{ + public class SimulationServiceConnector : ISimulationService + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private GridRegion m_Region; + + public SimulationServiceConnector() + { + } + + public SimulationServiceConnector(GridRegion region) + { + m_Region = region; + } + + public IScene GetScene(ulong regionHandle) + { + return null; + } + + #region Agents + + public bool CreateAgent(ulong regionHandle, AgentCircuitData aCircuit, uint flags, out string reason) + { + reason = String.Empty; + + // Eventually, we want to use a caps url instead of the agentID + string uri = string.Empty; + try + { + uri = "http://" + m_Region.ExternalEndPoint.Address + ":" + m_Region.HttpPort + "/agent/" + aCircuit.AgentID + "/"; + } + catch (Exception e) + { + m_log.Debug("[REST COMMS]: Unable to resolve external endpoint on agent create. Reason: " + e.Message); + reason = e.Message; + return false; + } + + //Console.WriteLine(" >>> DoCreateChildAgentCall <<< " + uri); + + HttpWebRequest AgentCreateRequest = (HttpWebRequest)WebRequest.Create(uri); + AgentCreateRequest.Method = "POST"; + AgentCreateRequest.ContentType = "application/json"; + AgentCreateRequest.Timeout = 10000; + //AgentCreateRequest.KeepAlive = false; + //AgentCreateRequest.Headers.Add("Authorization", authKey); + + // Fill it in + OSDMap args = null; + try + { + args = aCircuit.PackAgentCircuitData(); + } + catch (Exception e) + { + m_log.Debug("[REST COMMS]: PackAgentCircuitData failed with exception: " + e.Message); + } + // Add the regionhandle and the name of the destination region + args["destination_handle"] = OSD.FromString(m_Region.RegionHandle.ToString()); + args["destination_name"] = OSD.FromString(m_Region.RegionName); + args["teleport_flags"] = OSD.FromString(flags.ToString()); + + string strBuffer = ""; + byte[] buffer = new byte[1]; + try + { + strBuffer = OSDParser.SerializeJsonString(args); + Encoding str = Util.UTF8; + buffer = str.GetBytes(strBuffer); + + } + catch (Exception e) + { + m_log.WarnFormat("[REST COMMS]: Exception thrown on serialization of ChildCreate: {0}", e.Message); + // ignore. buffer will be empty, caller should check. + } + + Stream os = null; + try + { // send the Post + AgentCreateRequest.ContentLength = buffer.Length; //Count bytes to send + os = AgentCreateRequest.GetRequestStream(); + os.Write(buffer, 0, strBuffer.Length); //Send it + //m_log.InfoFormat("[REST COMMS]: Posted CreateChildAgent request to remote sim {0}", uri); + } + //catch (WebException ex) + catch + { + //m_log.InfoFormat("[REST COMMS]: Bad send on ChildAgentUpdate {0}", ex.Message); + reason = "cannot contact remote region"; + return false; + } + finally + { + if (os != null) + os.Close(); + } + + // Let's wait for the response + //m_log.Info("[REST COMMS]: Waiting for a reply after DoCreateChildAgentCall"); + + WebResponse webResponse = null; + StreamReader sr = null; + try + { + webResponse = AgentCreateRequest.GetResponse(); + if (webResponse == null) + { + m_log.Info("[REST COMMS]: Null reply on DoCreateChildAgentCall post"); + } + else + { + + sr = new StreamReader(webResponse.GetResponseStream()); + string response = sr.ReadToEnd().Trim(); + m_log.InfoFormat("[REST COMMS]: DoCreateChildAgentCall reply was {0} ", response); + + if (!String.IsNullOrEmpty(response)) + { + try + { + // we assume we got an OSDMap back + OSDMap r = Util.GetOSDMap(response); + bool success = r["success"].AsBoolean(); + reason = r["reason"].AsString(); + return success; + } + catch (NullReferenceException e) + { + m_log.InfoFormat("[REST COMMS]: exception on reply of DoCreateChildAgentCall {0}", e.Message); + + // check for old style response + if (response.ToLower().StartsWith("true")) + return true; + + return false; + } + } + } + } + catch (WebException ex) + { + m_log.InfoFormat("[REST COMMS]: exception on reply of DoCreateChildAgentCall {0}", ex.Message); + // ignore, really + } + finally + { + if (sr != null) + sr.Close(); + } + + return true; + } + + public bool UpdateAgent(ulong regionHandle, AgentData data) + { + return false; + } + + public bool UpdateAgent(ulong regionHandle, AgentPosition data) + { + return false; + } + + public bool RetrieveAgent(ulong regionHandle, UUID id, out IAgentData agent) + { + agent = null; + return false; + } + + public bool ReleaseAgent(ulong regionHandle, UUID id, string uri) + { + return false; + } + + public bool CloseAgent(ulong regionHandle, UUID id) + { + return false; + } + + #endregion Agents + + #region Objects + + public bool CreateObject(ulong regionHandle, ISceneObject sog, bool isLocalCall) + { + return false; + } + + public bool CreateObject(ulong regionHandle, UUID userID, UUID itemID) + { + return false; + } + + #endregion Objects + } +} diff --git a/OpenSim/Services/LLLoginService/LLLoginService.cs b/OpenSim/Services/LLLoginService/LLLoginService.cs index 2c31ed58dc..4501da2037 100644 --- a/OpenSim/Services/LLLoginService/LLLoginService.cs +++ b/OpenSim/Services/LLLoginService/LLLoginService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Reflection; +using System.Text.RegularExpressions; using log4net; using Nini.Config; @@ -9,17 +10,24 @@ using OpenMetaverse; using OpenSim.Framework; using OpenSim.Server.Base; using OpenSim.Services.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; namespace OpenSim.Services.LLLoginService { public class LLLoginService : ILoginService { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private IUserAccountService m_UserAccountService; private IAuthenticationService m_AuthenticationService; private IInventoryService m_InventoryService; private IGridService m_GridService; private IPresenceService m_PresenceService; + private string m_DefaultRegionName; + private string m_LocalSimulationDll; + private string m_RemoteSimulationDll; + public LLLoginService(IConfigSource config) { IConfig serverConfig = config.Configs["LoginService"]; @@ -32,6 +40,10 @@ namespace OpenSim.Services.LLLoginService string gridService = serverConfig.GetString("GridService", String.Empty); string presenceService = serverConfig.GetString("PresenceService", String.Empty); + m_DefaultRegionName = serverConfig.GetString("DefaultRegion", String.Empty); + m_LocalSimulationDll = serverConfig.GetString("LocalSimulationService", String.Empty); + m_RemoteSimulationDll = serverConfig.GetString("RemoteSimulationService", String.Empty); + // These 3 are required; the other 2 aren't if (accountService == string.Empty || authService == string.Empty || invService == string.Empty) @@ -57,8 +69,8 @@ namespace OpenSim.Services.LLLoginService // Authenticate this user string token = m_AuthenticationService.Authenticate(account.PrincipalID, passwd, 30); - UUID session = UUID.Zero; - if ((token == string.Empty) || (token != string.Empty && !UUID.TryParse(token, out session))) + UUID secureSession = UUID.Zero; + if ((token == string.Empty) || (token != string.Empty && !UUID.TryParse(token, out secureSession))) return LLFailedLoginResponse.UserProblem; // Get the user's inventory @@ -66,9 +78,155 @@ namespace OpenSim.Services.LLLoginService if ((inventorySkel == null) || (inventorySkel != null && inventorySkel.Count == 0)) return LLFailedLoginResponse.InventoryProblem; + // Login the presence + UUID session = UUID.Random(); + if (m_PresenceService != null) + { + bool success = m_PresenceService.LoginAgent(account.PrincipalID.ToString(), session, secureSession); + if (!success) + return LLFailedLoginResponse.GridProblem; + } + // lots of things missing... need to do the simulation service + string where = string.Empty; + Vector3 position = Vector3.Zero; + Vector3 lookAt = Vector3.Zero; + GridRegion destination = FindDestination(account, session, startLocation, out where, out position, out lookAt); + if (destination == null) + return LLFailedLoginResponse.GridProblem; + + ISimulationService sim = null; + Object[] args = new Object[] { destination }; + // HG standalones have both a localSimulatonDll and a remoteSimulationDll + // non-HG standalones have just a localSimulationDll + // independent login servers have just a remoteSimulationDll + if (!startLocation.Contains("@") && (m_LocalSimulationDll != string.Empty)) + sim = ServerUtils.LoadPlugin(m_LocalSimulationDll, args); + else + sim = ServerUtils.LoadPlugin(m_RemoteSimulationDll, args); + return null; } + + private GridRegion FindDestination(UserAccount account, UUID sessionID, string startLocation, out string where, out Vector3 position, out Vector3 lookAt) + { + where = "home"; + position = new Vector3(128, 128, 0); + lookAt = new Vector3(0, 1, 0); + if (startLocation.Equals("home")) + { + // logging into home region + if (m_PresenceService == null || m_GridService == null) + return null; + + GridRegion region = null; + PresenceInfo pinfo = m_PresenceService.GetAgent(sessionID); + // this should succeed; if it doesn't there's something wrong with this grid + if (pinfo == null) + return null; + + if (pinfo.HomeRegionID.Equals(UUID.Zero)) + region = m_GridService.GetRegionByName(account.ScopeID, m_DefaultRegionName); + else + region = m_GridService.GetRegionByUUID(account.ScopeID, pinfo.HomeRegionID); + + return region; + } + else if (startLocation.Equals("last")) + { + // logging into last visited region + where = "last"; + if (m_PresenceService == null || m_GridService == null) + return null; + + GridRegion region = null; + PresenceInfo pinfo = m_PresenceService.GetAgent(sessionID); + // this should succeed; if it doesn't there's something wrong with this grid + if (pinfo == null) + return null; + + if (pinfo.RegionID.Equals(UUID.Zero)) + region = m_GridService.GetRegionByName(account.ScopeID, m_DefaultRegionName); + else + { + region = m_GridService.GetRegionByUUID(account.ScopeID, pinfo.RegionID); + position = pinfo.Position; + lookAt = pinfo.LookAt; + } + return region; + + } + else + { + // free uri form + // e.g. New Moon&135&46 New Moon@osgrid.org:8002&153&34 + where = "url"; + Regex reURI = new Regex(@"^uri:(?[^&]+)&(?\d+)&(?\d+)&(?\d+)$"); + Match uriMatch = reURI.Match(startLocation); + if (uriMatch == null) + { + m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, but can't process it", startLocation); + return null; + } + else + { + position = new Vector3(float.Parse(uriMatch.Groups["x"].Value), + float.Parse(uriMatch.Groups["y"].Value), + float.Parse(uriMatch.Groups["z"].Value)); + + string regionName = uriMatch.Groups["region"].ToString(); + if (regionName != null) + { + if (!regionName.Contains("@")) + { + List regions = m_GridService.GetRegionsByName(account.ScopeID, regionName, 1); + if ((regions == null) || (regions != null && regions.Count == 0)) + { + m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, can't locate region {1}", startLocation, regionName); + return null; + } + return regions[0]; + } + else + { + string[] parts = regionName.Split(new char[] { '@' }); + if (parts.Length < 2) + { + m_log.InfoFormat("[LLLOGIN SERVICE]: Got Custom Login URI {0}, can't locate region {1}", startLocation, regionName); + return null; + } + // Valid specification of a remote grid + regionName = parts[0]; + string domainLocator = parts[1]; + parts = domainLocator.Split(new char[] {':'}); + string domainName = parts[0]; + uint port = 0; + if (parts.Length > 1) + UInt32.TryParse(parts[1], out port); + GridRegion region = new GridRegion(); + region.ExternalHostName = domainName; + region.HttpPort = port; + region.RegionName = regionName; + return region; + } + + } + else + { + if (m_PresenceService == null || m_GridService == null) + return null; + + return m_GridService.GetRegionByName(account.ScopeID, m_DefaultRegionName); + + } + } + //response.LookAt = "[r0,r1,r0]"; + //// can be: last, home, safe, url + //response.StartLocation = "url"; + + } + + } } }