From 04e29c1bacbc1e2df980ae15896a847ce7535da2 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 16 Jan 2010 21:42:44 -0800 Subject: Beginning of rewriting HG. Compiles, and runs, but HG functions not restored yet. --- .../Connectors/Grid/HypergridServiceConnector.cs | 8 + .../Hypergrid/HypergridServiceConnector.cs | 245 ++++++++++++ .../Services/HypergridService/GatekeeperService.cs | 167 +++++++++ OpenSim/Services/HypergridService/HGCommands.cs | 317 ++++++++++++++++ .../Services/HypergridService/HypergridService.cs | 415 +++++++++++++++++++++ .../HypergridService/HypergridServiceBase.cs | 84 +++++ OpenSim/Services/Interfaces/IGatekeeperService.cs | 13 + OpenSim/Services/Interfaces/IHypergridService.cs | 47 +++ 8 files changed, 1296 insertions(+) create mode 100644 OpenSim/Services/Connectors/Hypergrid/HypergridServiceConnector.cs create mode 100644 OpenSim/Services/HypergridService/GatekeeperService.cs create mode 100644 OpenSim/Services/HypergridService/HGCommands.cs create mode 100644 OpenSim/Services/HypergridService/HypergridService.cs create mode 100644 OpenSim/Services/HypergridService/HypergridServiceBase.cs create mode 100644 OpenSim/Services/Interfaces/IGatekeeperService.cs create mode 100644 OpenSim/Services/Interfaces/IHypergridService.cs (limited to 'OpenSim/Services') diff --git a/OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs b/OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs index 7098b07..8b39171 100644 --- a/OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs +++ b/OpenSim/Services/Connectors/Grid/HypergridServiceConnector.cs @@ -55,6 +55,14 @@ namespace OpenSim.Services.Connectors.Grid m_AssetService = assService; } + public bool LinkRegion(GridRegion info, out UUID regionID, out ulong regionHandle, out string reason) + { + regionID = LinkRegion(info, out regionHandle); + // reason... + reason = string.Empty; + return true; + } + public UUID LinkRegion(GridRegion info, out ulong realHandle) { UUID uuid = UUID.Zero; diff --git a/OpenSim/Services/Connectors/Hypergrid/HypergridServiceConnector.cs b/OpenSim/Services/Connectors/Hypergrid/HypergridServiceConnector.cs new file mode 100644 index 0000000..460acae --- /dev/null +++ b/OpenSim/Services/Connectors/Hypergrid/HypergridServiceConnector.cs @@ -0,0 +1,245 @@ +/* + * 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; +using System.Collections.Generic; +using System.Text; +using System.Drawing; +using System.Net; +using System.Reflection; +using OpenSim.Services.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +using OpenSim.Framework; + +using OpenMetaverse; +using OpenMetaverse.Imaging; +using log4net; +using Nwc.XmlRpc; + +namespace OpenSim.Services.Connectors.Hypergrid +{ + public class HypergridServiceConnector + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private IAssetService m_AssetService; + + public HypergridServiceConnector(IAssetService assService) + { + m_AssetService = assService; + } + + public bool LinkRegion(GridRegion info, out UUID regionID, out ulong realHandle, out string imageURL, out string reason) + { + regionID = UUID.Zero; + imageURL = string.Empty; + realHandle = 0; + reason = string.Empty; + + Hashtable hash = new Hashtable(); + hash["region_name"] = info.RegionName; + + IList paramList = new ArrayList(); + paramList.Add(hash); + + XmlRpcRequest request = new XmlRpcRequest("link_region", paramList); + string uri = "http://" + info.ExternalEndPoint.Address + ":" + info.HttpPort + "/"; + m_log.Debug("[HGrid]: Linking to " + uri); + XmlRpcResponse response = null; + try + { + response = request.Send(uri, 10000); + } + catch (Exception e) + { + m_log.Debug("[HGrid]: Exception " + e.Message); + reason = "Error contacting remote server"; + return false; + } + + if (response.IsFault) + { + reason = response.FaultString; + m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString); + return false; + } + + hash = (Hashtable)response.Value; + //foreach (Object o in hash) + // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); + try + { + bool success = false; + Boolean.TryParse((string)hash["result"], out success); + if (success) + { + UUID.TryParse((string)hash["uuid"], out regionID); + //m_log.Debug(">> HERE, uuid: " + uuid); + if ((string)hash["handle"] != null) + { + realHandle = Convert.ToUInt64((string)hash["handle"]); + //m_log.Debug(">> HERE, realHandle: " + realHandle); + } + if (hash["region_image"] != null) + { + imageURL = (string)hash["region_image"]; + } + } + + } + catch (Exception e) + { + reason = "Error parsing return arguments"; + m_log.Error("[HGrid]: Got exception while parsing hyperlink response " + e.StackTrace); + return false; + } + + return true; + } + + public UUID GetMapImage(UUID regionID, string imageURL) + { + try + { + + WebClient c = new WebClient(); + //m_log.Debug("JPEG: " + uri); + string filename = regionID.ToString(); + c.DownloadFile(imageURL, filename + ".jpg"); + Bitmap m = new Bitmap(filename + ".jpg"); + //m_log.Debug("Size: " + m.PhysicalDimension.Height + "-" + m.PhysicalDimension.Width); + byte[] imageData = OpenJPEG.EncodeFromImage(m, true); + AssetBase ass = new AssetBase(UUID.Random(), "region " + filename, (sbyte)AssetType.Texture); + + // !!! for now + //info.RegionSettings.TerrainImageID = ass.FullID; + + ass.Temporary = true; + ass.Local = true; + ass.Data = imageData; + + m_AssetService.Store(ass); + + // finally + return ass.FullID; + + } + catch // LEGIT: Catching problems caused by OpenJPEG p/invoke + { + m_log.Warn("[HGrid]: Failed getting/storing map image, because it is probably already in the cache"); + } + return UUID.Zero; + } + + public GridRegion GetHyperlinkRegion(GridRegion gatekeeper, UUID regionID) + { + Hashtable hash = new Hashtable(); + hash["region_uuid"] = regionID.ToString(); + + IList paramList = new ArrayList(); + paramList.Add(hash); + + XmlRpcRequest request = new XmlRpcRequest("get_region", paramList); + string uri = "http://" + gatekeeper.ExternalEndPoint.Address + ":" + gatekeeper.HttpPort + "/"; + m_log.Debug("[HGrid]: contacting " + uri); + XmlRpcResponse response = null; + try + { + response = request.Send(uri, 10000); + } + catch (Exception e) + { + m_log.Debug("[HGrid]: Exception " + e.Message); + return null; + } + + if (response.IsFault) + { + m_log.ErrorFormat("[HGrid]: remote call returned an error: {0}", response.FaultString); + return null; + } + + hash = (Hashtable)response.Value; + //foreach (Object o in hash) + // m_log.Debug(">> " + ((DictionaryEntry)o).Key + ":" + ((DictionaryEntry)o).Value); + try + { + bool success = false; + Boolean.TryParse((string)hash["result"], out success); + if (success) + { + GridRegion region = new GridRegion(); + + UUID.TryParse((string)hash["uuid"], out region.RegionID); + //m_log.Debug(">> HERE, uuid: " + uuid); + int n = 0; + if (hash["x"] != null) + { + Int32.TryParse((string)hash["x"], out n); + region.RegionLocX = n; + } + if (hash["y"] != null) + { + Int32.TryParse((string)hash["y"], out n); + region.RegionLocY = n; + } + if (hash["region_name"] != null) + { + region.RegionName = (string)hash["region_name"]; + } + if (hash["hostname"] != null) + region.ExternalHostName = (string)hash["hostname"]; + if (hash["http_port"] != null) + { + uint p = 0; + UInt32.TryParse((string)hash["http_port"], out p); + region.HttpPort = p; + } + if (hash["internal_port"] != null) + { + int p = 0; + Int32.TryParse((string)hash["internal_port"], out p); + region.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), p); + } + + // Successful return + return region; + } + + } + catch (Exception e) + { + m_log.Error("[HGrid]: Got exception while parsing hyperlink response " + e.StackTrace); + return null; + } + + return null; + } + } +} diff --git a/OpenSim/Services/HypergridService/GatekeeperService.cs b/OpenSim/Services/HypergridService/GatekeeperService.cs new file mode 100644 index 0000000..174174c --- /dev/null +++ b/OpenSim/Services/HypergridService/GatekeeperService.cs @@ -0,0 +1,167 @@ +using System; +using System.Collections.Generic; +using System.Reflection; + +using OpenSim.Framework; +using OpenSim.Services.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using OpenSim.Server.Base; + +using OpenMetaverse; + +using Nini.Config; +using log4net; + +namespace OpenSim.Services.HypergridService +{ + public class GatekeeperService : IGatekeeperService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + IGridService m_GridService; + IPresenceService m_PresenceService; + IAuthenticationService m_AuthenticationService; + IUserAccountService m_UserAccountService; + ISimulationService m_SimulationService; + + string m_AuthDll; + + UUID m_ScopeID; + bool m_AllowTeleportsToAnyRegion; + GridRegion m_DefaultGatewayRegion; + + public GatekeeperService(IConfigSource config, ISimulationService simService) + { + IConfig serverConfig = config.Configs["GatekeeperService"]; + if (serverConfig == null) + throw new Exception(String.Format("No section GatekeeperService in config file")); + + string accountService = serverConfig.GetString("UserAccountService", String.Empty); + string gridService = serverConfig.GetString("GridService", String.Empty); + string presenceService = serverConfig.GetString("PresenceService", String.Empty); + string simulationService = serverConfig.GetString("SimulationService", String.Empty); + + m_AuthDll = serverConfig.GetString("AuthenticationService", String.Empty); + + if (accountService == string.Empty || gridService == string.Empty || + presenceService == string.Empty || m_AuthDll == string.Empty) + throw new Exception("Incomplete specifications, Gatekeeper Service cannot function."); + + string scope = serverConfig.GetString("ScopeID", UUID.Zero.ToString()); + UUID.TryParse(scope, out m_ScopeID); + //m_WelcomeMessage = serverConfig.GetString("WelcomeMessage", "Welcome to OpenSim!"); + m_AllowTeleportsToAnyRegion = serverConfig.GetBoolean("AllowTeleportsToAnyRegion", true); + + Object[] args = new Object[] { config }; + m_UserAccountService = ServerUtils.LoadPlugin(accountService, args); + m_GridService = ServerUtils.LoadPlugin(gridService, args); + m_PresenceService = ServerUtils.LoadPlugin(presenceService, args); + if (simService != null) + m_SimulationService = simService; + else if (simulationService != string.Empty) + m_SimulationService = ServerUtils.LoadPlugin(simulationService, args); + + if (m_UserAccountService == null || m_GridService == null || + m_PresenceService == null || m_SimulationService == null) + throw new Exception("Unable to load a required plugin, Gatekeeper Service cannot function."); + + m_log.Debug("[GATEKEEPER SERVICE]: Starting..."); + } + + public GatekeeperService(IConfigSource config) + : this(config, null) + { + } + + public bool LinkRegion(string regionName, out UUID regionID, out ulong regionHandle, out string imageURL, out string reason) + { + regionID = m_DefaultGatewayRegion.RegionID; + regionHandle = m_DefaultGatewayRegion.RegionHandle; + imageURL = string.Empty; + reason = string.Empty; + + if (!m_AllowTeleportsToAnyRegion) + { + regionID = m_DefaultGatewayRegion.RegionID; + regionHandle = m_DefaultGatewayRegion.RegionHandle; + if (regionName != string.Empty) + { + reason = "Direct links to regions not allowed"; + return false; + } + + return true; + } + + GridRegion region = m_GridService.GetRegionByName(m_ScopeID, regionName); + if (region == null) + { + reason = "Region not found"; + return false; + } + + regionID = region.RegionID; + regionHandle = region.RegionHandle; + string regionimage = "regionImage" + region.RegionID.ToString(); + regionimage = regionimage.Replace("-", ""); + + imageURL = "http://" + region.ExternalHostName + ":" + region.HttpPort + "/index.php?method=" + regionimage; + + return true; + } + + public GridRegion GetHyperlinkRegion(UUID regionID) + { + if (!m_AllowTeleportsToAnyRegion) + // Don't even check the given regionID + return m_DefaultGatewayRegion; + + GridRegion region = m_GridService.GetRegionByUUID(m_ScopeID, regionID); + return region; + } + + public bool LoginAgent(AgentCircuitData aCircuit, GridRegion destination) + { + if (!Authenticate(aCircuit)) + return false; + + // Check to see if we have a local user with that UUID + UserAccount account = m_UserAccountService.GetUserAccount(m_ScopeID, aCircuit.AgentID); + if (account != null) + // No, sorry; go away + return false; + + // May want to authorize + + // Login the presence + if (!m_PresenceService.LoginAgent(aCircuit.AgentID.ToString(), aCircuit.SessionID, aCircuit.SecureSessionID)) + return false; + + // Finally launch the agent at the destination + string reason = string.Empty; + return m_SimulationService.CreateAgent(destination, aCircuit, 0, out reason); + } + + public bool LoginAttachments(ISceneObject sog, GridRegion destination) + { + // May want to filter attachments + return m_SimulationService.CreateObject(destination, sog, false); + } + + protected bool Authenticate(AgentCircuitData aCircuit) + { + string authURL = string.Empty; // GetAuthURL(aCircuit); + if (authURL == string.Empty) + return false; + + Object[] args = new Object[] { authURL }; + IAuthenticationService authService = ServerUtils.LoadPlugin(m_AuthDll, args); + if (authService != null) + return authService.Verify(aCircuit.AgentID, aCircuit.SecureSessionID.ToString(), 30); + + return false; + } + } +} diff --git a/OpenSim/Services/HypergridService/HGCommands.cs b/OpenSim/Services/HypergridService/HGCommands.cs new file mode 100644 index 0000000..10d04ff --- /dev/null +++ b/OpenSim/Services/HypergridService/HGCommands.cs @@ -0,0 +1,317 @@ +/* + * 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.Reflection; +using System.Xml; +using log4net; +using Nini.Config; +using OpenSim.Framework; +//using OpenSim.Framework.Communications; +using OpenSim.Framework.Console; +using OpenSim.Services.Interfaces; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +namespace OpenSim.Services.HypergridService +{ + public class HGCommands + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private HypergridService m_HypergridService; + + private static uint m_autoMappingX = 0; + private static uint m_autoMappingY = 0; + private static bool m_enableAutoMapping = false; + + public HGCommands(HypergridService service) + { + m_HypergridService = service; + } + + public void HandleShow(string module, string[] cmd) + { + if (cmd.Length != 2) + { + MainConsole.Instance.Output("Syntax: show hyperlinks"); + return; + } + List regions = new List(m_HypergridService.m_HyperlinkRegions.Values); + if (regions == null || regions.Count < 1) + { + MainConsole.Instance.Output("No hyperlinks"); + return; + } + + MainConsole.Instance.Output("Region Name Region UUID"); + MainConsole.Instance.Output("Location URI"); + MainConsole.Instance.Output("Owner ID Flags"); + MainConsole.Instance.Output("-------------------------------------------------------------------------------"); + foreach (GridRegion r in regions) + { + MainConsole.Instance.Output(String.Format("{0,-20} {1}\n{2,-20} {3}\n{4,-39} \n\n", + r.RegionName, r.RegionID, + String.Format("{0},{1}", r.RegionLocX, r.RegionLocY), "http://" + r.ExternalHostName + ":" + r.HttpPort.ToString(), + r.EstateOwner.ToString())); + } + return; + } + public void RunCommand(string module, string[] cmdparams) + { + List args = new List(cmdparams); + if (args.Count < 1) + return; + + string command = args[0]; + args.RemoveAt(0); + + cmdparams = args.ToArray(); + + RunHGCommand(command, cmdparams); + + } + + private void RunHGCommand(string command, string[] cmdparams) + { + if (command.Equals("link-mapping")) + { + if (cmdparams.Length == 2) + { + try + { + m_autoMappingX = Convert.ToUInt32(cmdparams[0]); + m_autoMappingY = Convert.ToUInt32(cmdparams[1]); + m_enableAutoMapping = true; + } + catch (Exception) + { + m_autoMappingX = 0; + m_autoMappingY = 0; + m_enableAutoMapping = false; + } + } + } + else if (command.Equals("link-region")) + { + if (cmdparams.Length < 3) + { + if ((cmdparams.Length == 1) || (cmdparams.Length == 2)) + { + LoadXmlLinkFile(cmdparams); + } + else + { + LinkRegionCmdUsage(); + } + return; + } + + if (cmdparams[2].Contains(":")) + { + // New format + int xloc, yloc; + string mapName; + try + { + xloc = Convert.ToInt32(cmdparams[0]); + yloc = Convert.ToInt32(cmdparams[1]); + mapName = cmdparams[2]; + if (cmdparams.Length > 3) + for (int i = 3; i < cmdparams.Length; i++) + mapName += " " + cmdparams[i]; + + //m_log.Info(">> MapName: " + mapName); + } + catch (Exception e) + { + MainConsole.Instance.Output("[HGrid] Wrong format for link-region command: " + e.Message); + LinkRegionCmdUsage(); + return; + } + + // Convert cell coordinates given by the user to meters + xloc = xloc * (int)Constants.RegionSize; + yloc = yloc * (int)Constants.RegionSize; + string reason = string.Empty; + if (m_HypergridService.TryLinkRegionToCoords(mapName, xloc, yloc, out reason) == null) + MainConsole.Instance.Output("Failed to link region: " + reason); + } + else + { + // old format + GridRegion regInfo; + int xloc, yloc; + uint externalPort; + string externalHostName; + try + { + xloc = Convert.ToInt32(cmdparams[0]); + yloc = Convert.ToInt32(cmdparams[1]); + externalPort = Convert.ToUInt32(cmdparams[3]); + externalHostName = cmdparams[2]; + //internalPort = Convert.ToUInt32(cmdparams[4]); + //remotingPort = Convert.ToUInt32(cmdparams[5]); + } + catch (Exception e) + { + MainConsole.Instance.Output("[HGrid] Wrong format for link-region command: " + e.Message); + LinkRegionCmdUsage(); + return; + } + + // Convert cell coordinates given by the user to meters + xloc = xloc * (int)Constants.RegionSize; + yloc = yloc * (int)Constants.RegionSize; + string reason = string.Empty; + if (m_HypergridService.TryCreateLink(xloc, yloc, "", externalPort, externalHostName, out regInfo, out reason)) + { + if (cmdparams.Length >= 5) + { + regInfo.RegionName = ""; + for (int i = 4; i < cmdparams.Length; i++) + regInfo.RegionName += cmdparams[i] + " "; + } + } + } + return; + } + else if (command.Equals("unlink-region")) + { + if (cmdparams.Length < 1) + { + UnlinkRegionCmdUsage(); + return; + } + if (m_HypergridService.TryUnlinkRegion(cmdparams[0])) + MainConsole.Instance.Output("Successfully unlinked " + cmdparams[0]); + else + MainConsole.Instance.Output("Unable to unlink " + cmdparams[0] + ", region not found."); + } + } + + private void LoadXmlLinkFile(string[] cmdparams) + { + //use http://www.hgurl.com/hypergrid.xml for test + try + { + XmlReader r = XmlReader.Create(cmdparams[0]); + XmlConfigSource cs = new XmlConfigSource(r); + string[] excludeSections = null; + + if (cmdparams.Length == 2) + { + if (cmdparams[1].ToLower().StartsWith("excludelist:")) + { + string excludeString = cmdparams[1].ToLower(); + excludeString = excludeString.Remove(0, 12); + char[] splitter = { ';' }; + + excludeSections = excludeString.Split(splitter); + } + } + + for (int i = 0; i < cs.Configs.Count; i++) + { + bool skip = false; + if ((excludeSections != null) && (excludeSections.Length > 0)) + { + for (int n = 0; n < excludeSections.Length; n++) + { + if (excludeSections[n] == cs.Configs[i].Name.ToLower()) + { + skip = true; + break; + } + } + } + if (!skip) + { + ReadLinkFromConfig(cs.Configs[i]); + } + } + } + catch (Exception e) + { + m_log.Error(e.ToString()); + } + } + + + private void ReadLinkFromConfig(IConfig config) + { + GridRegion regInfo; + int xloc, yloc; + uint externalPort; + string externalHostName; + uint realXLoc, realYLoc; + + xloc = Convert.ToInt32(config.GetString("xloc", "0")); + yloc = Convert.ToInt32(config.GetString("yloc", "0")); + externalPort = Convert.ToUInt32(config.GetString("externalPort", "0")); + externalHostName = config.GetString("externalHostName", ""); + realXLoc = Convert.ToUInt32(config.GetString("real-xloc", "0")); + realYLoc = Convert.ToUInt32(config.GetString("real-yloc", "0")); + + if (m_enableAutoMapping) + { + xloc = (int)((xloc % 100) + m_autoMappingX); + yloc = (int)((yloc % 100) + m_autoMappingY); + } + + if (((realXLoc == 0) && (realYLoc == 0)) || + (((realXLoc - xloc < 3896) || (xloc - realXLoc < 3896)) && + ((realYLoc - yloc < 3896) || (yloc - realYLoc < 3896)))) + { + xloc = xloc * (int)Constants.RegionSize; + yloc = yloc * (int)Constants.RegionSize; + string reason = string.Empty; + if (m_HypergridService.TryCreateLink(xloc, yloc, "", externalPort, + externalHostName, out regInfo, out reason)) + { + regInfo.RegionName = config.GetString("localName", ""); + } + else + MainConsole.Instance.Output("Unable to link " + externalHostName + ": " + reason); + } + } + + + private void LinkRegionCmdUsage() + { + MainConsole.Instance.Output("Usage: link-region :[:]"); + MainConsole.Instance.Output("Usage: link-region []"); + MainConsole.Instance.Output("Usage: link-region []"); + } + + private void UnlinkRegionCmdUsage() + { + MainConsole.Instance.Output("Usage: unlink-region :"); + MainConsole.Instance.Output("Usage: unlink-region "); + } + + } +} diff --git a/OpenSim/Services/HypergridService/HypergridService.cs b/OpenSim/Services/HypergridService/HypergridService.cs new file mode 100644 index 0000000..747b98a --- /dev/null +++ b/OpenSim/Services/HypergridService/HypergridService.cs @@ -0,0 +1,415 @@ +/* + * 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.Net; +using System.Reflection; +using Nini.Config; +using log4net; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Data; +using OpenSim.Server.Base; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Connectors.Hypergrid; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; +using OpenMetaverse; + +namespace OpenSim.Services.HypergridService +{ + public class HypergridService : HypergridServiceBase, IHypergridService + { + private static readonly ILog m_log = + LogManager.GetLogger( + MethodBase.GetCurrentMethod().DeclaringType); + + private static HypergridService m_RootInstance = null; + protected IConfigSource m_config; + + protected IAuthenticationService m_AuthenticationService = null; + protected IGridService m_GridService; + protected IAssetService m_AssetService; + protected HypergridServiceConnector m_HypergridConnector; + + protected bool m_AllowDuplicateNames = false; + protected UUID m_ScopeID = UUID.Zero; + + // Hyperlink regions are hyperlinks on the map + public readonly Dictionary m_HyperlinkRegions = new Dictionary(); + protected Dictionary m_HyperlinkHandles = new Dictionary(); + + protected GridRegion m_DefaultRegion; + protected GridRegion DefaultRegion + { + get + { + if (m_DefaultRegion == null) + { + List defs = m_GridService.GetDefaultRegions(m_ScopeID); + if (defs != null && defs.Count > 0) + m_DefaultRegion = defs[0]; + else + { + // Best guess, may be totally off + m_DefaultRegion = new GridRegion(1000, 1000); + m_log.WarnFormat("[HYPERGRID SERVICE]: This grid does not have a default region. Assuming default coordinates at 1000, 1000."); + } + } + return m_DefaultRegion; + } + } + + public HypergridService(IConfigSource config) + : base(config) + { + m_log.DebugFormat("[HYPERGRID SERVICE]: Starting..."); + + m_config = config; + IConfig gridConfig = config.Configs["HypergridService"]; + if (gridConfig != null) + { + string gridService = gridConfig.GetString("GridService", string.Empty); + string authService = gridConfig.GetString("AuthenticationService", String.Empty); + string assetService = gridConfig.GetString("AssetService", string.Empty); + + Object[] args = new Object[] { config }; + if (gridService != string.Empty) + m_GridService = ServerUtils.LoadPlugin(gridService, args); + + if (m_GridService == null) + throw new Exception("HypergridService cannot function without a GridService"); + + if (authService != String.Empty) + m_AuthenticationService = ServerUtils.LoadPlugin(authService, args); + + if (assetService != string.Empty) + m_AssetService = ServerUtils.LoadPlugin(assetService, args); + + m_AllowDuplicateNames = gridConfig.GetBoolean("AllowDuplicateNames", m_AllowDuplicateNames); + + string scope = gridConfig.GetString("ScopeID", string.Empty); + if (scope != string.Empty) + UUID.TryParse(scope, out m_ScopeID); + + m_HypergridConnector = new HypergridServiceConnector(m_AssetService); + + m_log.DebugFormat("[HYPERGRID SERVICE]: Loaded all services..."); + } + + if (m_RootInstance == null) + { + m_RootInstance = this; + + HGCommands hgCommands = new HGCommands(this); + MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-region", + "link-region :[:] ", + "Link a hypergrid region", hgCommands.RunCommand); + MainConsole.Instance.Commands.AddCommand("hypergrid", false, "unlink-region", + "unlink-region or : ", + "Unlink a hypergrid region", hgCommands.RunCommand); + MainConsole.Instance.Commands.AddCommand("hypergrid", false, "link-mapping", "link-mapping [ ] ", + "Set local coordinate to map HG regions to", hgCommands.RunCommand); + MainConsole.Instance.Commands.AddCommand("hypergrid", false, "show hyperlinks", "show hyperlinks ", + "List the HG regions", hgCommands.HandleShow); + } + } + + #region Link Region + + public bool LinkRegion(string regionDescriptor, out UUID regionID, out ulong regionHandle, out string imageURL, out string reason) + { + regionID = UUID.Zero; + imageURL = string.Empty; + regionHandle = 0; + reason = string.Empty; + int xloc = random.Next(0, Int16.MaxValue) * (int)Constants.RegionSize; + GridRegion region = TryLinkRegionToCoords(regionDescriptor, xloc, 0, out reason); + if (region == null) + return false; + + regionID = region.RegionID; + regionHandle = region.RegionHandle; + return true; + } + + private static Random random = new Random(); + + // From the command line link-region + public GridRegion TryLinkRegionToCoords(string mapName, int xloc, int yloc, out string reason) + { + reason = string.Empty; + string host = "127.0.0.1"; + string portstr; + string regionName = ""; + uint port = 9000; + string[] parts = mapName.Split(new char[] { ':' }); + if (parts.Length >= 1) + { + host = parts[0]; + } + if (parts.Length >= 2) + { + portstr = parts[1]; + //m_log.Debug("-- port = " + portstr); + if (!UInt32.TryParse(portstr, out port)) + regionName = parts[1]; + } + // always take the last one + if (parts.Length >= 3) + { + regionName = parts[2]; + } + + // Sanity check. Don't ever link to this sim. + IPAddress ipaddr = null; + try + { + ipaddr = Util.GetHostFromDNS(host); + } + catch { } + + GridRegion regInfo; + bool success = TryCreateLink(xloc, yloc, regionName, port, host, out regInfo, out reason); + if (success) + { + regInfo.RegionName = mapName; + return regInfo; + } + + return null; + } + + + // From the command line and the 2 above + public bool TryCreateLink(int xloc, int yloc, + string externalRegionName, uint externalPort, string externalHostName, out GridRegion regInfo, out string reason) + { + m_log.DebugFormat("[HYPERGRID SERVICE]: Link to {0}:{1}, in {2}-{3}", externalHostName, externalPort, xloc, yloc); + + reason = string.Empty; + regInfo = new GridRegion(); + regInfo.RegionName = externalRegionName; + regInfo.HttpPort = externalPort; + regInfo.ExternalHostName = externalHostName; + regInfo.RegionLocX = xloc; + regInfo.RegionLocY = yloc; + + try + { + regInfo.InternalEndPoint = new IPEndPoint(IPAddress.Parse("0.0.0.0"), (int)0); + } + catch (Exception e) + { + m_log.Warn("[HYPERGRID SERVICE]: Wrong format for link-region: " + e.Message); + reason = "Internal error"; + return false; + } + + // Finally, link it + ulong handle = 0; + UUID regionID = UUID.Zero; + string imageURL = string.Empty; + if (!m_HypergridConnector.LinkRegion(regInfo, out regionID, out handle, out imageURL, out reason)) + return false; + + if (regionID != UUID.Zero) + { + regInfo.RegionID = regionID; + + AddHyperlinkRegion(regInfo, handle); + m_log.Info("[HYPERGRID SERVICE]: Successfully linked to region_uuid " + regInfo.RegionID); + + // Try get the map image + regInfo.TerrainImage = m_HypergridConnector.GetMapImage(regionID, imageURL); + } + else + { + m_log.Warn("[HYPERGRID SERVICE]: Unable to link region"); + reason = "Remote region could not be found"; + return false; + } + + uint x, y; + if (!Check4096(regInfo, out x, out y)) + { + RemoveHyperlinkRegion(regInfo.RegionID); + reason = "Region is too far (" + x + ", " + y + ")"; + m_log.Info("[HYPERGRID SERVICE]: Unable to link, region is too far (" + x + ", " + y + ")"); + return false; + } + + m_log.Debug("[HYPERGRID SERVICE]: link region succeeded"); + return true; + } + + public bool TryUnlinkRegion(string mapName) + { + GridRegion regInfo = null; + if (mapName.Contains(":")) + { + string host = "127.0.0.1"; + //string portstr; + //string regionName = ""; + uint port = 9000; + string[] parts = mapName.Split(new char[] { ':' }); + if (parts.Length >= 1) + { + host = parts[0]; + } + + foreach (GridRegion r in m_HyperlinkRegions.Values) + if (host.Equals(r.ExternalHostName) && (port == r.HttpPort)) + regInfo = r; + } + else + { + foreach (GridRegion r in m_HyperlinkRegions.Values) + if (r.RegionName.Equals(mapName)) + regInfo = r; + } + if (regInfo != null) + { + RemoveHyperlinkRegion(regInfo.RegionID); + return true; + } + else + { + m_log.InfoFormat("[HYPERGRID SERVICE]: Region {0} not found", mapName); + return false; + } + } + + /// + /// Cope with this viewer limitation. + /// + /// + /// + public bool Check4096(GridRegion regInfo, out uint x, out uint y) + { + GridRegion defRegion = DefaultRegion; + + ulong realHandle = m_HyperlinkHandles[regInfo.RegionID]; + uint ux = 0, uy = 0; + Utils.LongToUInts(realHandle, out ux, out uy); + x = ux / Constants.RegionSize; + y = uy / Constants.RegionSize; + + if ((Math.Abs((int)defRegion.RegionLocX - ux) >= 4096 * Constants.RegionSize) || + (Math.Abs((int)defRegion.RegionLocY - uy) >= 4096 * Constants.RegionSize)) + { + return false; + } + return true; + } + + private void AddHyperlinkRegion(GridRegion regionInfo, ulong regionHandle) + { + m_HyperlinkRegions[regionInfo.RegionID] = regionInfo; + m_HyperlinkHandles[regionInfo.RegionID] = regionHandle; + } + + private void RemoveHyperlinkRegion(UUID regionID) + { + // Try the hyperlink collection + if (m_HyperlinkRegions.ContainsKey(regionID)) + { + m_HyperlinkRegions.Remove(regionID); + m_HyperlinkHandles.Remove(regionID); + } + } + + #endregion + + #region Get Hyperlinks + + public GridRegion GetHyperlinkRegion(UUID regionID) + { + //GridRegion region = m_HypergridConnector. + return null; + } + + #endregion + + #region GetRegionBy X + + public GridRegion GetRegionByUUID(UUID regionID) + { + if (m_HyperlinkRegions.ContainsKey(regionID)) + return m_HyperlinkRegions[regionID]; + + return null; + } + + public GridRegion GetRegionByPosition(int x, int y) + { + foreach (GridRegion r in m_HyperlinkRegions.Values) + if (r.RegionLocX == x && r.RegionLocY == y) + return r; + + return null; + } + + public GridRegion GetRegionByName(string name) + { + foreach (GridRegion r in m_HyperlinkRegions.Values) + if (r.RegionName.ToLower() == name.ToLower()) + return r; + + return null; + } + + public List GetRegionsByName(string name) + { + List regions = new List(); + + foreach (GridRegion r in m_HyperlinkRegions.Values) + if ((r.RegionName != null) && r.RegionName.ToLower().StartsWith(name.ToLower())) + regions.Add(r); + + return regions; + + } + + public List GetRegionRange(int xmin, int xmax, int ymin, int ymax) + { + List regions = new List(); + + foreach (GridRegion r in m_HyperlinkRegions.Values) + if ((r.RegionLocX > xmin) && (r.RegionLocX < xmax) && + (r.RegionLocY > ymin) && (r.RegionLocY < ymax)) + regions.Add(r); + + return regions; + } + + #endregion + + + + } +} diff --git a/OpenSim/Services/HypergridService/HypergridServiceBase.cs b/OpenSim/Services/HypergridService/HypergridServiceBase.cs new file mode 100644 index 0000000..4f91f64 --- /dev/null +++ b/OpenSim/Services/HypergridService/HypergridServiceBase.cs @@ -0,0 +1,84 @@ +/* + * 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.Reflection; +using Nini.Config; +using OpenSim.Framework; +using OpenSim.Data; +using OpenSim.Services.Interfaces; +using OpenSim.Services.Base; + +namespace OpenSim.Services.HypergridService +{ + public class HypergridServiceBase : ServiceBase + { + protected IRegionData m_Database = null; + + public HypergridServiceBase(IConfigSource config) + : base(config) + { + string dllName = String.Empty; + string connString = String.Empty; + string realm = "TBD"; + + // + // Try reading the [DatabaseService] section, if it exists + // + IConfig dbConfig = config.Configs["DatabaseService"]; + if (dbConfig != null) + { + if (dllName == String.Empty) + dllName = dbConfig.GetString("StorageProvider", String.Empty); + if (connString == String.Empty) + connString = dbConfig.GetString("ConnectionString", String.Empty); + } + + // + // [HypergridService] section overrides [DatabaseService], if it exists + // + IConfig gridConfig = config.Configs["HypergridService"]; + if (gridConfig != null) + { + dllName = gridConfig.GetString("StorageProvider", dllName); + connString = gridConfig.GetString("ConnectionString", connString); + realm = gridConfig.GetString("Realm", realm); + } + + //// + //// We tried, but this doesn't exist. We can't proceed. + //// + //if (dllName.Equals(String.Empty)) + // throw new Exception("No StorageProvider configured"); + + //m_Database = LoadPlugin(dllName, new Object[] { connString, realm }); + //if (m_Database == null) + // throw new Exception("Could not find a storage interface in the given module"); + + } + } +} diff --git a/OpenSim/Services/Interfaces/IGatekeeperService.cs b/OpenSim/Services/Interfaces/IGatekeeperService.cs new file mode 100644 index 0000000..c4d1cbf --- /dev/null +++ b/OpenSim/Services/Interfaces/IGatekeeperService.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +using OpenMetaverse; + +namespace OpenSim.Services.Interfaces +{ + public interface IGatekeeperService + { + bool LinkRegion(string regionDescriptor, out UUID regionID, out ulong regionHandle, out string imageURL, out string reason); + GridRegion GetHyperlinkRegion(UUID regionID); + } +} diff --git a/OpenSim/Services/Interfaces/IHypergridService.cs b/OpenSim/Services/Interfaces/IHypergridService.cs new file mode 100644 index 0000000..b49657a --- /dev/null +++ b/OpenSim/Services/Interfaces/IHypergridService.cs @@ -0,0 +1,47 @@ +/* + * 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.Collections.Generic; +using OpenSim.Framework; +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +using OpenMetaverse; + +namespace OpenSim.Services.Interfaces +{ + public interface IHypergridService + { + bool LinkRegion(string regionDescriptor, out UUID regionID, out ulong regionHandle, out string imageURL, out string reason); + GridRegion GetHyperlinkRegion(UUID regionID); + + GridRegion GetRegionByUUID(UUID regionID); + GridRegion GetRegionByPosition(int x, int y); + GridRegion GetRegionByName(string name); + List GetRegionsByName(string name); + List GetRegionRange(int xmin, int xmax, int ymin, int ymax); + } +} -- cgit v1.1