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. --- .../Services/HypergridService/HypergridService.cs | 415 +++++++++++++++++++++ 1 file changed, 415 insertions(+) create mode 100644 OpenSim/Services/HypergridService/HypergridService.cs (limited to 'OpenSim/Services/HypergridService/HypergridService.cs') 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 + + + + } +} -- cgit v1.1