diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 5679ad5dcb..504f09ba5b 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -67,7 +67,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// Determine whether this archive will save assets. Default is true. /// public bool SaveAssets { get; set; } - + + protected ArchiverModule m_module; protected Scene m_scene; protected Stream m_saveStream; protected Guid m_requestId; @@ -75,13 +76,13 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// /// Constructor /// - /// + /// Calling module /// The path to which to save data. /// The id associated with this request /// /// If there was a problem opening a stream for the file specified by the savePath /// - public ArchiveWriteRequestPreparation(Scene scene, string savePath, Guid requestId) : this(scene, requestId) + public ArchiveWriteRequestPreparation(ArchiverModule module, string savePath, Guid requestId) : this(module, requestId) { try { @@ -99,17 +100,23 @@ namespace OpenSim.Region.CoreModules.World.Archiver /// /// Constructor. /// - /// + /// Calling module /// The stream to which to save data. /// The id associated with this request - public ArchiveWriteRequestPreparation(Scene scene, Stream saveStream, Guid requestId) : this(scene, requestId) + public ArchiveWriteRequestPreparation(ArchiverModule module, Stream saveStream, Guid requestId) : this(module, requestId) { m_saveStream = saveStream; } - protected ArchiveWriteRequestPreparation(Scene scene, Guid requestId) + protected ArchiveWriteRequestPreparation(ArchiverModule module, Guid requestId) { - m_scene = scene; + m_module = module; + + // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix + // this. + if (m_module != null) + m_scene = m_module.Scene; + m_requestId = requestId; SaveAssets = true; @@ -364,32 +371,66 @@ namespace OpenSim.Region.CoreModules.World.Archiver //if (majorVersion == 1) //{ // m_log.WarnFormat("[ARCHIVER]: Please be aware that version 1.0 OARs are not compatible with OpenSim 0.7.0.2 and earlier. Please use the --version=0 option if you want to produce a compatible OAR"); - //} + //} + + String s; - StringWriter sw = new StringWriter(); - XmlTextWriter xtw = new XmlTextWriter(sw); - xtw.Formatting = Formatting.Indented; - xtw.WriteStartDocument(); - xtw.WriteStartElement("archive"); - xtw.WriteAttributeString("major_version", majorVersion.ToString()); - xtw.WriteAttributeString("minor_version", minorVersion.ToString()); + using (StringWriter sw = new StringWriter()) + { + using (XmlTextWriter xtw = new XmlTextWriter(sw)) + { + xtw.Formatting = Formatting.Indented; + xtw.WriteStartDocument(); + xtw.WriteStartElement("archive"); + xtw.WriteAttributeString("major_version", majorVersion.ToString()); + xtw.WriteAttributeString("minor_version", minorVersion.ToString()); + + xtw.WriteStartElement("creation_info"); + DateTime now = DateTime.UtcNow; + TimeSpan t = now - new DateTime(1970, 1, 1); + xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString()); + xtw.WriteElementString("id", UUID.Random().ToString()); + xtw.WriteEndElement(); - xtw.WriteStartElement("creation_info"); - DateTime now = DateTime.UtcNow; - TimeSpan t = now - new DateTime(1970, 1, 1); - xtw.WriteElementString("datetime", ((int)t.TotalSeconds).ToString()); - xtw.WriteElementString("id", UUID.Random().ToString()); - xtw.WriteEndElement(); + xtw.WriteStartElement("region_info"); - xtw.WriteElementString("assets_included", SaveAssets.ToString()); + bool isMegaregion; + Vector2 size; + IRegionCombinerModule rcMod = null; - xtw.WriteEndElement(); + // FIXME: This is only here for regression test purposes since they do not supply a module. Need to fix + // this, possibly by doing control file creation somewhere else. + if (m_module != null) + rcMod = m_module.RegionCombinerModule; - xtw.Flush(); - xtw.Close(); + if (rcMod != null) + isMegaregion = rcMod.IsRootForMegaregion(m_scene.RegionInfo.RegionID); + else + isMegaregion = false; - String s = sw.ToString(); - sw.Close(); + if (isMegaregion) + size = rcMod.GetSizeOfMegaregion(m_scene.RegionInfo.RegionID); + else + size = new Vector2((float)Constants.RegionSize, (float)Constants.RegionSize); + + xtw.WriteElementString("is_megaregion", isMegaregion.ToString()); + xtw.WriteElementString("size_in_meters", string.Format("{0},{1}", size.X, size.Y)); + + xtw.WriteEndElement(); + + xtw.WriteElementString("assets_included", SaveAssets.ToString()); + + xtw.WriteEndElement(); + + xtw.Flush(); + } + + s = sw.ToString(); + } + + if (m_scene != null) + Console.WriteLine( + "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s); return s; } diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs index f5a5a8d1be..bf3b1240a4 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiverModule.cs @@ -45,7 +45,8 @@ namespace OpenSim.Region.CoreModules.World.Archiver private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private Scene m_scene; + public Scene Scene { get; private set; } + public IRegionCombinerModule RegionCombinerModule { get; private set; } /// /// The file used to load and save an opensimulator archive if no filename has been specified @@ -70,13 +71,14 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void AddRegion(Scene scene) { - m_scene = scene; - m_scene.RegisterModuleInterface(this); + Scene = scene; + Scene.RegisterModuleInterface(this); //m_log.DebugFormat("[ARCHIVER]: Enabled for region {0}", scene.RegionInfo.RegionName); } public void RegionLoaded(Scene scene) { + RegionCombinerModule = scene.RequestModuleInterface(); } public void RemoveRegion(Scene scene) @@ -165,9 +167,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void ArchiveRegion(string savePath, Guid requestId, Dictionary options) { m_log.InfoFormat( - "[ARCHIVER]: Writing archive for region {0} to {1}", m_scene.RegionInfo.RegionName, savePath); + "[ARCHIVER]: Writing archive for region {0} to {1}", Scene.RegionInfo.RegionName, savePath); - new ArchiveWriteRequestPreparation(m_scene, savePath, requestId).ArchiveRegion(options); + new ArchiveWriteRequestPreparation(this, savePath, requestId).ArchiveRegion(options); } public void ArchiveRegion(Stream saveStream) @@ -182,7 +184,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void ArchiveRegion(Stream saveStream, Guid requestId, Dictionary options) { - new ArchiveWriteRequestPreparation(m_scene, saveStream, requestId).ArchiveRegion(options); + new ArchiveWriteRequestPreparation(this, saveStream, requestId).ArchiveRegion(options); } public void DearchiveRegion(string loadPath) @@ -193,9 +195,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void DearchiveRegion(string loadPath, bool merge, bool skipAssets, Guid requestId) { m_log.InfoFormat( - "[ARCHIVER]: Loading archive to region {0} from {1}", m_scene.RegionInfo.RegionName, loadPath); + "[ARCHIVER]: Loading archive to region {0} from {1}", Scene.RegionInfo.RegionName, loadPath); - new ArchiveReadRequest(m_scene, loadPath, merge, skipAssets, requestId).DearchiveRegion(); + new ArchiveReadRequest(Scene, loadPath, merge, skipAssets, requestId).DearchiveRegion(); } public void DearchiveRegion(Stream loadStream) @@ -205,7 +207,7 @@ namespace OpenSim.Region.CoreModules.World.Archiver public void DearchiveRegion(Stream loadStream, bool merge, bool skipAssets, Guid requestId) { - new ArchiveReadRequest(m_scene, loadStream, merge, skipAssets, requestId).DearchiveRegion(); + new ArchiveReadRequest(Scene, loadStream, merge, skipAssets, requestId).DearchiveRegion(); } } } diff --git a/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs new file mode 100644 index 0000000000..e03ac5a26f --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IRegionCombinerModule.cs @@ -0,0 +1,59 @@ +/* + * 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.Linq; +using System.Text; +using OpenSim.Region.Framework.Scenes; +using System.IO; +using OpenMetaverse; + +namespace OpenSim.Region.Framework.Interfaces +{ + public interface IRegionCombinerModule + { + /// + /// Does the given id belong to the root region of a megaregion? + /// + bool IsRootForMegaregion(UUID regionId); + + /// + /// Gets the size of megaregion. + /// + /// + /// Returns size in meters. + /// Do not rely on this method remaining the same - this area is actively under development. + /// + /// + /// The id of the root region for a megaregion. + /// This may change in the future to allow any region id that makes up a megaregion. + /// Currently, will throw an exception if this does not match a root region. + /// + Vector2 GetSizeOfMegaregion(UUID regionId); + } +} \ No newline at end of file diff --git a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs index a142f26be2..40daf1343c 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionCombinerModule.cs @@ -43,9 +43,8 @@ using Mono.Addins; [assembly: AddinDependency("OpenSim", "0.5")] namespace OpenSim.Region.RegionCombinerModule { - [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule")] - public class RegionCombinerModule : ISharedRegionModule + public class RegionCombinerModule : ISharedRegionModule, IRegionCombinerModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -59,8 +58,22 @@ namespace OpenSim.Region.RegionCombinerModule get { return null; } } - private Dictionary m_regions = new Dictionary(); + /// + /// Is this module enabled? + /// private bool enabledYN = false; + + /// + /// This holds the root regions for the megaregions. + /// + /// + /// Usually there is only ever one megaregion (and hence only one entry here). + /// + private Dictionary m_regions = new Dictionary(); + + /// + /// The scenes that comprise the megaregion. + /// private Dictionary m_startingScenes = new Dictionary(); public void Initialise(IConfigSource source) @@ -69,9 +82,11 @@ namespace OpenSim.Region.RegionCombinerModule enabledYN = myConfig.GetBoolean("CombineContiguousRegions", false); if (enabledYN) + { MainConsole.Instance.Commands.AddCommand( "RegionCombinerModule", false, "fix-phantoms", "fix-phantoms", "Fixes phantom objects after an import to megaregions", FixPhantoms); + } } public void Close() @@ -80,6 +95,8 @@ namespace OpenSim.Region.RegionCombinerModule public void AddRegion(Scene scene) { + if (enabledYN) + scene.RegisterModuleInterface(this); } public void RemoveRegion(Scene scene) @@ -96,6 +113,27 @@ namespace OpenSim.Region.RegionCombinerModule } } + public bool IsRootForMegaregion(UUID regionId) + { + lock (m_regions) + return m_regions.ContainsKey(regionId); + } + + public Vector2 GetSizeOfMegaregion(UUID regionId) + { + lock (m_regions) + { + if (m_regions.ContainsKey(regionId)) + { + RegionConnections rootConn = m_regions[regionId]; + + return new Vector2((float)rootConn.XEnd, (float)rootConn.YEnd); + } + } + + throw new Exception(string.Format("Region with id {0} not found", regionId)); + } + private void NewPresence(ScenePresence presence) { if (presence.IsChildAgent) @@ -206,24 +244,21 @@ namespace OpenSim.Region.RegionCombinerModule westBorder.CrossDirection = Cardinals.W; scene.WestBorders[0] = westBorder; - - - RegionConnections regionConnections = new RegionConnections(); - regionConnections.ConnectedRegions = new List(); - regionConnections.RegionScene = scene; - regionConnections.RegionLandChannel = scene.LandChannel; - regionConnections.RegionId = scene.RegionInfo.originRegionID; - regionConnections.X = scene.RegionInfo.RegionLocX; - regionConnections.Y = scene.RegionInfo.RegionLocY; - regionConnections.XEnd = (int)Constants.RegionSize; - regionConnections.YEnd = (int)Constants.RegionSize; - + RegionConnections newConn = new RegionConnections(); + newConn.ConnectedRegions = new List(); + newConn.RegionScene = scene; + newConn.RegionLandChannel = scene.LandChannel; + newConn.RegionId = scene.RegionInfo.originRegionID; + newConn.X = scene.RegionInfo.RegionLocX; + newConn.Y = scene.RegionInfo.RegionLocY; + newConn.XEnd = (int)Constants.RegionSize; + newConn.YEnd = (int)Constants.RegionSize; lock (m_regions) { bool connectedYN = false; - foreach (RegionConnections conn in m_regions.Values) + foreach (RegionConnections rootConn in m_regions.Values) { #region commented /* @@ -388,13 +423,9 @@ namespace OpenSim.Region.RegionCombinerModule //xxy //xxx - - if ((((int)conn.X * (int)Constants.RegionSize) + conn.XEnd - >= (regionConnections.X * (int)Constants.RegionSize)) - && (((int)conn.Y * (int)Constants.RegionSize) - >= (regionConnections.Y * (int)Constants.RegionSize))) + if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY >= newConn.PosY) { - connectedYN = DoWorkForOneRegionOverPlusXY(conn, regionConnections, scene); + connectedYN = DoWorkForOneRegionOverPlusXY(rootConn, newConn, scene); break; } @@ -402,12 +433,9 @@ namespace OpenSim.Region.RegionCombinerModule //xyx //xxx //xxx - if ((((int)conn.X * (int)Constants.RegionSize) - >= (regionConnections.X * (int)Constants.RegionSize)) - && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd - >= (regionConnections.Y * (int)Constants.RegionSize))) + if (rootConn.PosX >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) { - connectedYN = DoWorkForOneRegionOverXPlusY(conn, regionConnections, scene); + connectedYN = DoWorkForOneRegionOverXPlusY(rootConn, newConn, scene); break; } @@ -415,12 +443,9 @@ namespace OpenSim.Region.RegionCombinerModule //xxy //xxx //xxx - if ((((int)conn.X * (int)Constants.RegionSize) + conn.XEnd - >= (regionConnections.X * (int)Constants.RegionSize)) - && (((int)conn.Y * (int)Constants.RegionSize) + conn.YEnd - >= (regionConnections.Y * (int)Constants.RegionSize))) + if (rootConn.PosX + rootConn.XEnd >= newConn.PosX && rootConn.PosY + rootConn.YEnd >= newConn.PosY) { - connectedYN = DoWorkForOneRegionOverPlusXPlusY(conn, regionConnections, scene); + connectedYN = DoWorkForOneRegionOverPlusXPlusY(rootConn, newConn, scene); break; } @@ -429,66 +454,63 @@ namespace OpenSim.Region.RegionCombinerModule // If !connectYN means that this region is a root region if (!connectedYN) { - DoWorkForRootRegion(regionConnections, scene); - + DoWorkForRootRegion(newConn, scene); } } + // Set up infinite borders around the entire AABB of the combined ConnectedRegions AdjustLargeRegionBounds(); } - private bool DoWorkForOneRegionOverPlusXY(RegionConnections conn, RegionConnections regionConnections, Scene scene) + private bool DoWorkForOneRegionOverPlusXY(RegionConnections rootConn, RegionConnections newConn, Scene scene) { Vector3 offset = Vector3.Zero; - offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - - ((conn.X * (int)Constants.RegionSize))); - offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) - - ((conn.Y * (int)Constants.RegionSize))); + offset.X = newConn.PosX - rootConn.PosX; + offset.Y = newConn.PosY - rootConn.PosY; Vector3 extents = Vector3.Zero; - extents.Y = conn.YEnd; - extents.X = conn.XEnd + regionConnections.XEnd; + extents.Y = rootConn.YEnd; + extents.X = rootConn.XEnd + newConn.XEnd; - conn.UpdateExtents(extents); + rootConn.UpdateExtents(extents); - m_log.DebugFormat("Scene: {0} to the west of Scene{1} Offset: {2}. Extents:{3}", - conn.RegionScene.RegionInfo.RegionName, - regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); + m_log.DebugFormat( + "[REGION COMBINER MODULE]: Root region {0} is to the west of region {1}, Offset: {2}, Extents: {3}", + rootConn.RegionScene.RegionInfo.RegionName, + newConn.RegionScene.RegionInfo.RegionName, offset, extents); scene.BordersLocked = true; - conn.RegionScene.BordersLocked = true; + rootConn.RegionScene.BordersLocked = true; RegionData ConnectedRegion = new RegionData(); ConnectedRegion.Offset = offset; ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; ConnectedRegion.RegionScene = scene; - conn.ConnectedRegions.Add(ConnectedRegion); + rootConn.ConnectedRegions.Add(ConnectedRegion); // Inform root region Physics about the extents of this region - conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); + rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); // Inform Child region that it needs to forward it's terrain to the root region - scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); + scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); // Extend the borders as appropriate - lock (conn.RegionScene.EastBorders) - conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; + lock (rootConn.RegionScene.EastBorders) + rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; - lock (conn.RegionScene.NorthBorders) - conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; + lock (rootConn.RegionScene.NorthBorders) + rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - lock (conn.RegionScene.SouthBorders) - conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; + lock (rootConn.RegionScene.SouthBorders) + rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; lock (scene.WestBorders) { - - - scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West + scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West // Trigger auto teleport to root region - scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; - scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; + scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; + scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; } // Reset Terrain.. since terrain loads before we get here, we need to load @@ -497,56 +519,58 @@ namespace OpenSim.Region.RegionCombinerModule scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); // Unlock borders - conn.RegionScene.BordersLocked = false; + rootConn.RegionScene.BordersLocked = false; scene.BordersLocked = false; // Create a client event forwarder and add this region's events to the root region. - if (conn.ClientEventForwarder != null) - conn.ClientEventForwarder.AddSceneToEventForwarding(scene); + if (rootConn.ClientEventForwarder != null) + rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); return true; } - private bool DoWorkForOneRegionOverXPlusY(RegionConnections conn, RegionConnections regionConnections, Scene scene) + private bool DoWorkForOneRegionOverXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene) { Vector3 offset = Vector3.Zero; - offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - - ((conn.X * (int)Constants.RegionSize))); - offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) - - ((conn.Y * (int)Constants.RegionSize))); + offset.X = newConn.PosX - rootConn.PosX; + offset.Y = newConn.PosY - rootConn.PosY; Vector3 extents = Vector3.Zero; - extents.Y = regionConnections.YEnd + conn.YEnd; - extents.X = conn.XEnd; - conn.UpdateExtents(extents); + extents.Y = newConn.YEnd + rootConn.YEnd; + extents.X = rootConn.XEnd; + rootConn.UpdateExtents(extents); scene.BordersLocked = true; - conn.RegionScene.BordersLocked = true; + rootConn.RegionScene.BordersLocked = true; RegionData ConnectedRegion = new RegionData(); ConnectedRegion.Offset = offset; ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; ConnectedRegion.RegionScene = scene; - conn.ConnectedRegions.Add(ConnectedRegion); + rootConn.ConnectedRegions.Add(ConnectedRegion); - m_log.DebugFormat("Scene: {0} to the northeast of Scene{1} Offset: {2}. Extents:{3}", - conn.RegionScene.RegionInfo.RegionName, - regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); + m_log.DebugFormat( + "[REGION COMBINER MODULE]: Root region {0} is to the south of region {1}, Offset: {2}, Extents: {3}", + rootConn.RegionScene.RegionInfo.RegionName, + newConn.RegionScene.RegionInfo.RegionName, offset, extents); - conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); - scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); + rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); + scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); + + lock (rootConn.RegionScene.NorthBorders) + rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; + + lock (rootConn.RegionScene.EastBorders) + rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; + + lock (rootConn.RegionScene.WestBorders) + rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; - lock (conn.RegionScene.NorthBorders) - conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; - lock (conn.RegionScene.EastBorders) - conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; - lock (conn.RegionScene.WestBorders) - conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; lock (scene.SouthBorders) { - scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south - scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; - scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; + scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south + scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; + scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; } // Reset Terrain.. since terrain normally loads first. @@ -555,83 +579,92 @@ namespace OpenSim.Region.RegionCombinerModule //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); scene.BordersLocked = false; - conn.RegionScene.BordersLocked = false; - if (conn.ClientEventForwarder != null) - conn.ClientEventForwarder.AddSceneToEventForwarding(scene); + rootConn.RegionScene.BordersLocked = false; + + if (rootConn.ClientEventForwarder != null) + rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); + return true; } - private bool DoWorkForOneRegionOverPlusXPlusY(RegionConnections conn, RegionConnections regionConnections, Scene scene) + private bool DoWorkForOneRegionOverPlusXPlusY(RegionConnections rootConn, RegionConnections newConn, Scene scene) { Vector3 offset = Vector3.Zero; - offset.X = (((regionConnections.X * (int)Constants.RegionSize)) - - ((conn.X * (int)Constants.RegionSize))); - offset.Y = (((regionConnections.Y * (int)Constants.RegionSize)) - - ((conn.Y * (int)Constants.RegionSize))); + offset.X = newConn.PosX - rootConn.PosX; + offset.Y = newConn.PosY - rootConn.PosY; Vector3 extents = Vector3.Zero; - extents.Y = regionConnections.YEnd + conn.YEnd; - extents.X = regionConnections.XEnd + conn.XEnd; - conn.UpdateExtents(extents); + + // We do not want to inflate the extents for regions strictly to the NE of the root region, since this + // would double count regions strictly to the north and east that have already been added. +// extents.Y = regionConnections.YEnd + conn.YEnd; +// extents.X = regionConnections.XEnd + conn.XEnd; +// conn.UpdateExtents(extents); + + extents.Y = rootConn.YEnd; + extents.X = rootConn.XEnd; scene.BordersLocked = true; - conn.RegionScene.BordersLocked = true; + rootConn.RegionScene.BordersLocked = true; RegionData ConnectedRegion = new RegionData(); ConnectedRegion.Offset = offset; ConnectedRegion.RegionId = scene.RegionInfo.originRegionID; ConnectedRegion.RegionScene = scene; - conn.ConnectedRegions.Add(ConnectedRegion); + rootConn.ConnectedRegions.Add(ConnectedRegion); - m_log.DebugFormat("Scene: {0} to the NorthEast of Scene{1} Offset: {2}. Extents:{3}", - conn.RegionScene.RegionInfo.RegionName, - regionConnections.RegionScene.RegionInfo.RegionName, offset, extents); + m_log.DebugFormat( + "[REGION COMBINER MODULE]: Region {0} is to the southwest of Scene {1}, Offset: {2}, Extents: {3}", + rootConn.RegionScene.RegionInfo.RegionName, + newConn.RegionScene.RegionInfo.RegionName, offset, extents); - conn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); - scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset, Vector3.Zero); - lock (conn.RegionScene.NorthBorders) + rootConn.RegionScene.PhysicsScene.Combine(null, Vector3.Zero, extents); + scene.PhysicsScene.Combine(rootConn.RegionScene.PhysicsScene, offset, Vector3.Zero); + + lock (rootConn.RegionScene.NorthBorders) { - if (conn.RegionScene.NorthBorders.Count == 1)// && 2) + if (rootConn.RegionScene.NorthBorders.Count == 1)// && 2) { //compound border // already locked above - conn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; + rootConn.RegionScene.NorthBorders[0].BorderLine.Z += (int)Constants.RegionSize; - lock (conn.RegionScene.EastBorders) - conn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; - lock (conn.RegionScene.WestBorders) - conn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; + lock (rootConn.RegionScene.EastBorders) + rootConn.RegionScene.EastBorders[0].BorderLine.Y += (int)Constants.RegionSize; + + lock (rootConn.RegionScene.WestBorders) + rootConn.RegionScene.WestBorders[0].BorderLine.Y += (int)Constants.RegionSize; } } lock (scene.SouthBorders) { - scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - conn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south - scene.SouthBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; - scene.SouthBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; + scene.SouthBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocY - rootConn.RegionScene.RegionInfo.RegionLocY) * (int)Constants.RegionSize); //auto teleport south + scene.SouthBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; + scene.SouthBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; } - lock (conn.RegionScene.EastBorders) + lock (rootConn.RegionScene.EastBorders) { - if (conn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2) + if (rootConn.RegionScene.EastBorders.Count == 1)// && conn.RegionScene.EastBorders.Count == 2) { - conn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; - lock (conn.RegionScene.NorthBorders) - conn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; - lock (conn.RegionScene.SouthBorders) - conn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; + rootConn.RegionScene.EastBorders[0].BorderLine.Z += (int)Constants.RegionSize; + lock (rootConn.RegionScene.NorthBorders) + rootConn.RegionScene.NorthBorders[0].BorderLine.Y += (int)Constants.RegionSize; + lock (rootConn.RegionScene.SouthBorders) + rootConn.RegionScene.SouthBorders[0].BorderLine.Y += (int)Constants.RegionSize; } } lock (scene.WestBorders) { - scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - conn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West - scene.WestBorders[0].TriggerRegionX = conn.RegionScene.RegionInfo.RegionLocX; - scene.WestBorders[0].TriggerRegionY = conn.RegionScene.RegionInfo.RegionLocY; + scene.WestBorders[0].BorderLine.Z = (int)((scene.RegionInfo.RegionLocX - rootConn.RegionScene.RegionInfo.RegionLocX) * (int)Constants.RegionSize); //auto teleport West + scene.WestBorders[0].TriggerRegionX = rootConn.RegionScene.RegionInfo.RegionLocX; + scene.WestBorders[0].TriggerRegionY = rootConn.RegionScene.RegionInfo.RegionLocY; } /* @@ -650,46 +683,50 @@ namespace OpenSim.Region.RegionCombinerModule scene.PhysicsScene.SetTerrain(scene.Heightmap.GetFloatsSerialised()); //conn.RegionScene.PhysicsScene.SetTerrain(conn.RegionScene.Heightmap.GetFloatsSerialised()); scene.BordersLocked = false; - conn.RegionScene.BordersLocked = false; + rootConn.RegionScene.BordersLocked = false; - if (conn.ClientEventForwarder != null) - conn.ClientEventForwarder.AddSceneToEventForwarding(scene); + if (rootConn.ClientEventForwarder != null) + rootConn.ClientEventForwarder.AddSceneToEventForwarding(scene); return true; //scene.PhysicsScene.Combine(conn.RegionScene.PhysicsScene, offset,extents); - } - private void DoWorkForRootRegion(RegionConnections regionConnections, Scene scene) + private void DoWorkForRootRegion(RegionConnections rootConn, Scene scene) { + m_log.DebugFormat("[REGION COMBINER MODULE]: Adding root region {0}", scene.RegionInfo.RegionName); + RegionData rdata = new RegionData(); rdata.Offset = Vector3.Zero; rdata.RegionId = scene.RegionInfo.originRegionID; rdata.RegionScene = scene; // save it's land channel - regionConnections.RegionLandChannel = scene.LandChannel; + rootConn.RegionLandChannel = scene.LandChannel; // Substitue our landchannel RegionCombinerLargeLandChannel lnd = new RegionCombinerLargeLandChannel(rdata, scene.LandChannel, - regionConnections.ConnectedRegions); + rootConn.ConnectedRegions); + scene.LandChannel = lnd; + // Forward the permissions modules of each of the connected regions to the root region lock (m_regions) { - foreach (RegionData r in regionConnections.ConnectedRegions) + foreach (RegionData r in rootConn.ConnectedRegions) { - ForwardPermissionRequests(regionConnections, r.RegionScene); + ForwardPermissionRequests(rootConn, r.RegionScene); } + + // Create the root region's Client Event Forwarder + rootConn.ClientEventForwarder = new RegionCombinerClientEventForwarder(rootConn); + + // Sets up the CoarseLocationUpdate forwarder for this root region + scene.EventManager.OnNewPresence += SetCourseLocationDelegate; + + // Adds this root region to a dictionary of regions that are connectable + m_regions.Add(scene.RegionInfo.originRegionID, rootConn); } - // Create the root region's Client Event Forwarder - regionConnections.ClientEventForwarder = new RegionCombinerClientEventForwarder(regionConnections); - - // Sets up the CoarseLocationUpdate forwarder for this root region - scene.EventManager.OnNewPresence += SetCourseLocationDelegate; - - // Adds this root region to a dictionary of regions that are connectable - m_regions.Add(scene.RegionInfo.originRegionID, regionConnections); } private void SetCourseLocationDelegate(ScenePresence presence) @@ -946,6 +983,7 @@ namespace OpenSim.Region.RegionCombinerModule return true; } } + oborder = null; return false; } @@ -955,14 +993,19 @@ namespace OpenSim.Region.RegionCombinerModule pPosition = pPosition/(int) Constants.RegionSize; int OffsetX = (int) pPosition.X; int OffsetY = (int) pPosition.Y; - foreach (RegionConnections regConn in m_regions.Values) + + lock (m_regions) { - foreach (RegionData reg in regConn.ConnectedRegions) + foreach (RegionConnections regConn in m_regions.Values) { - if (reg.Offset.X == OffsetX && reg.Offset.Y == OffsetY) - return reg; + foreach (RegionData reg in regConn.ConnectedRegions) + { + if (reg.Offset.X == OffsetX && reg.Offset.Y == OffsetY) + return reg; + } } } + return new RegionData(); } @@ -1018,18 +1061,17 @@ namespace OpenSim.Region.RegionCombinerModule } #region console commands + public void FixPhantoms(string module, string[] cmdparams) { - List scenes = new List(m_startingScenes.Values); + List scenes = new List(m_startingScenes.Values); + foreach (Scene s in scenes) { - s.ForEachSOG(delegate(SceneObjectGroup e) - { - e.AbsolutePosition = e.AbsolutePosition; - } - ); + s.ForEachSOG(so => so.AbsolutePosition = so.AbsolutePosition); } } + #endregion } } diff --git a/OpenSim/Region/RegionCombinerModule/RegionConnections.cs b/OpenSim/Region/RegionCombinerModule/RegionConnections.cs index 3aa9f20f1a..fba51d2efa 100644 --- a/OpenSim/Region/RegionCombinerModule/RegionConnections.cs +++ b/OpenSim/Region/RegionCombinerModule/RegionConnections.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using OpenMetaverse; +using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; @@ -49,17 +50,45 @@ namespace OpenSim.Region.RegionCombinerModule /// LargeLandChannel for combined region /// public ILandChannel RegionLandChannel; + + /// + /// The x map co-ordinate for this region (where each co-ordinate is a Constants.RegionSize block). + /// public uint X; + + /// + /// The y co-ordinate for this region (where each cor-odinate is a Constants.RegionSize block). + /// public uint Y; - public int XEnd; - public int YEnd; + + /// + /// The X meters position of this connection. + /// + public uint PosX { get { return X * Constants.RegionSize; } } + + /// + /// The Y meters co-ordinate of this connection. + /// + public uint PosY { get { return Y * Constants.RegionSize; } } + + /// + /// The size of the megaregion in meters. + /// + public uint XEnd; + + /// + /// The size of the megaregion in meters. + /// + public uint YEnd; + public List ConnectedRegions; public RegionCombinerPermissionModule PermissionModule; public RegionCombinerClientEventForwarder ClientEventForwarder; + public void UpdateExtents(Vector3 extents) { - XEnd = (int)extents.X; - YEnd = (int)extents.Y; + XEnd = (uint)extents.X; + YEnd = (uint)extents.Y; } } } \ No newline at end of file