From 8a9677a5319793ff630d0761e204ae8961f375aa Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 1 Jan 2010 21:12:46 -0800 Subject: The Library Service is now working. UserProfileCacheService.LibraryRoot is obsolete. Didn't delete it yet to avoid merge conflicts later -- want to stay out of core as much as possible. --- .../CoreModules/Framework/Library/LibraryModule.cs | 33 +++++++++++++++++----- .../Framework/Library/LocalInventoryService.cs | 4 +-- 2 files changed, 28 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index 6941e00..f1022fd 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs @@ -37,6 +37,7 @@ using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Interfaces; +using OpenSim.Server.Base; using OpenMetaverse; using log4net; @@ -53,6 +54,8 @@ namespace OpenSim.Region.CoreModules.Framework.Library private string m_LibraryName = "OpenSim Library"; private Scene m_Scene; + private ILibraryService m_Library; + #region ISharedRegionModule public void Initialise(IConfigSource config) @@ -60,9 +63,22 @@ namespace OpenSim.Region.CoreModules.Framework.Library m_Enabled = config.Configs["Modules"].GetBoolean("LibraryModule", m_Enabled); if (m_Enabled) { - IConfig libConfig = config.Configs["LibraryModule"]; + IConfig libConfig = config.Configs["LibraryService"]; if (libConfig != null) - m_LibraryName = libConfig.GetString("LibraryName", m_LibraryName); + { + string dllName = libConfig.GetString("LocalServiceModule", string.Empty); + m_log.Debug("[LIBRARY MODULE]: Library service dll is " + dllName); + if (dllName != string.Empty) + { + Object[] args = new Object[] { config }; + m_Library = ServerUtils.LoadPlugin(dllName, args); + } + } + } + if (m_Library == null) + { + m_log.Warn("[LIBRARY MODULE]: No local library service. Module will be disabled."); + m_Enabled = false; } } @@ -91,10 +107,15 @@ namespace OpenSim.Region.CoreModules.Framework.Library { m_Scene = scene; } + scene.RegisterModuleInterface(m_Library); } public void RemoveRegion(Scene scene) { + if (!m_Enabled) + return; + + scene.UnregisterModuleInterface(m_Library); } public void RegionLoaded(Scene scene) @@ -127,19 +148,17 @@ namespace OpenSim.Region.CoreModules.Framework.Library protected void LoadLibrariesFromArchives() { - InventoryFolderImpl lib = m_Scene.CommsManager.UserProfileCacheService.LibraryRoot; + InventoryFolderImpl lib = m_Library.LibraryRootFolder; if (lib == null) { m_log.Debug("[LIBRARY MODULE]: No library. Ignoring Library Module"); return; } - lib.Name = m_LibraryName; - RegionInfo regInfo = new RegionInfo(); Scene m_MockScene = new Scene(regInfo); m_MockScene.CommsManager = m_Scene.CommsManager; - LocalInventoryService invService = new LocalInventoryService((LibraryRootFolder)lib); + LocalInventoryService invService = new LocalInventoryService(lib); m_MockScene.RegisterModuleInterface(invService); m_MockScene.RegisterModuleInterface(m_Scene.AssetService); @@ -181,7 +200,7 @@ namespace OpenSim.Region.CoreModules.Framework.Library private void DumpLibrary() { - InventoryFolderImpl lib = m_Scene.CommsManager.UserProfileCacheService.LibraryRoot; + InventoryFolderImpl lib = m_Library.LibraryRootFolder; m_log.DebugFormat(" - folder {0}", lib.Name); DumpFolder(lib); diff --git a/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs b/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs index 2c95b5a..685c031 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs @@ -41,9 +41,9 @@ namespace OpenSim.Region.CoreModules.Framework.Library { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private LibraryRootFolder m_Library; + private InventoryFolderImpl m_Library; - public LocalInventoryService(LibraryRootFolder lib) + public LocalInventoryService(InventoryFolderImpl lib) { m_Library = lib; } -- cgit v1.1 From 1e1b2ab221851efc414678b7ea52ef2ca788ce9f Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 10 Jan 2010 10:40:07 -0800 Subject: * OMG! All but one references to UserProfileCacheService have been rerouted! * HG is seriously broken here * Compiles. Untested. --- OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index f1022fd..cc5b0e4 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs @@ -162,11 +162,10 @@ namespace OpenSim.Region.CoreModules.Framework.Library m_MockScene.RegisterModuleInterface(invService); m_MockScene.RegisterModuleInterface(m_Scene.AssetService); - UserProfileData profile = new UserProfileData(); - profile.FirstName = "OpenSim"; - profile.ID = lib.Owner; - profile.SurName = "Library"; - CachedUserInfo uinfo = new CachedUserInfo(invService, profile); + UserAccount uinfo = new UserAccount(lib.Owner); + uinfo.FirstName = "OpenSim"; + uinfo.LastName = "Library"; + uinfo.ServiceURLs = new Dictionary(); foreach (string iarFileName in Directory.GetFiles(pathToLibraries, "*.iar")) { -- cgit v1.1 From 001d3695683d9511446d194feeb763c437170028 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 11 Jan 2010 07:45:47 -0800 Subject: CommunicationsManager deleted. --- OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs | 1 - 1 file changed, 1 deletion(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index cc5b0e4..cf06e01 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs @@ -157,7 +157,6 @@ namespace OpenSim.Region.CoreModules.Framework.Library RegionInfo regInfo = new RegionInfo(); Scene m_MockScene = new Scene(regInfo); - m_MockScene.CommsManager = m_Scene.CommsManager; LocalInventoryService invService = new LocalInventoryService(lib); m_MockScene.RegisterModuleInterface(invService); m_MockScene.RegisterModuleInterface(m_Scene.AssetService); -- cgit v1.1 From c5ea783526611a968400a1936e4c6764ee1c7013 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 11 Jan 2010 07:51:33 -0800 Subject: OpenSim/Framework/Communications/Cache deleted. LibraryRootFolder deleted. --- OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs | 2 +- OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs index cf06e01..e53290c 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LibraryModule.cs @@ -31,7 +31,7 @@ using System.Reflection; using OpenSim.Framework; using OpenSim.Framework.Communications; -using OpenSim.Framework.Communications.Cache; + using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; using OpenSim.Region.Framework; using OpenSim.Region.Framework.Interfaces; diff --git a/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs b/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs index 685c031..49589fd 100644 --- a/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs +++ b/OpenSim/Region/CoreModules/Framework/Library/LocalInventoryService.cs @@ -29,7 +29,7 @@ using System.Collections.Generic; using System.Reflection; using OpenSim.Framework; -using OpenSim.Framework.Communications.Cache; + using OpenSim.Services.Interfaces; using OpenMetaverse; -- cgit v1.1 From 4ac3c0e81b8760ef31f741cd55e703eee86b93b7 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 15 Jan 2010 17:14:48 -0800 Subject: Renamed IAgentTransferModule to IEntityTransferModule -- accounts for objects too. --- .../EntityTransfer/EntityTransferModule.cs | 1201 ++++++++++++++++++++ 1 file changed, 1201 insertions(+) create mode 100644 OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs new file mode 100644 index 0000000..af004b0 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -0,0 +1,1201 @@ +/* + * 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 System.Threading; + +using OpenSim.Framework; +using OpenSim.Framework.Capabilities; +using OpenSim.Framework.Client; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; + +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +using OpenMetaverse; +using log4net; +using Nini.Config; + +namespace OpenSim.Region.CoreModules.Framework.EntityTransfer +{ + public class AgentTransferModule : ISharedRegionModule, IEntityTransferModule + { + #region ISharedRegionModule + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private bool m_Enabled = false; + protected Scene m_aScene; + protected List m_agentsInTransit; + + public Type ReplaceableInterface + { + get { return null; } + } + + public string Name + { + get { return "AgentTransferModule"; } + } + + public virtual void Initialise(IConfigSource source) + { + IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) + { + string name = moduleConfig.GetString("AgentTransferModule", ""); + if (name == Name) + { + m_agentsInTransit = new List(); + m_Enabled = true; + m_log.Info("[AGENT TRANSFER MODULE]: Enabled."); + } + } + } + + public virtual void PostInitialise() + { + } + + public virtual void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + if (m_aScene == null) + m_aScene = scene; + + scene.RegisterModuleInterface(this); + } + + public virtual void Close() + { + if (!m_Enabled) + return; + } + + + public virtual void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + if (scene == m_aScene) + m_aScene = null; + } + + public virtual void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + } + + + #endregion + + #region Teleports + + public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) + { + if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) + return; + + bool destRegionUp = true; + + IEventQueue eq = sp.Scene.RequestModuleInterface(); + + // Reset animations; the viewer does that in teleports. + sp.Animator.ResetAnimations(); + + if (regionHandle == sp.Scene.RegionInfo.RegionHandle) + { + m_log.DebugFormat( + "[AGENT TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", + position, sp.Scene.RegionInfo.RegionName); + + // Teleport within the same region + if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) + { + Vector3 emergencyPos = new Vector3(128, 128, 128); + + m_log.WarnFormat( + "[AGENT TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", + position, sp.Name, sp.UUID, emergencyPos); + position = emergencyPos; + } + + // TODO: Get proper AVG Height + float localAVHeight = 1.56f; + float posZLimit = 22; + + // TODO: Check other Scene HeightField + if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) + { + posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; + } + + float newPosZ = posZLimit + localAVHeight; + if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) + { + position.Z = newPosZ; + } + + // Only send this if the event queue is null + if (eq == null) + sp.ControllingClient.SendTeleportLocationStart(); + + sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); + sp.Teleport(position); + } + else + { + uint x = 0, y = 0; + Utils.LongToUInts(regionHandle, out x, out y); + GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); + + if (reg != null) + { + m_log.DebugFormat( + "[AGENT TRANSFER MODULE]: RequestTeleportToLocation to {0} in {1}", + position, reg.RegionName); + + uint newRegionX = (uint)(reg.RegionHandle >> 40); + uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); + uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); + uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8); + + ulong destinationHandle = GetRegionHandle(reg); + GridRegion finalDestination = GetFinalDestination(reg); + + if (eq == null) + sp.ControllingClient.SendTeleportLocationStart(); + + // Let's do DNS resolution only once in this process, please! + // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, + // it's actually doing a lot of work. + IPEndPoint endPoint = reg.ExternalEndPoint; + if (endPoint.Address == null) + { + // Couldn't resolve the name. Can't TP, because the viewer wants IP addresses. + destRegionUp = false; + } + + if (destRegionUp) + { + // Fixing a bug where teleporting while sitting results in the avatar ending up removed from + // both regions + if (sp.ParentID != (uint)0) + sp.StandUp(); + + if (!sp.ValidateAttachments()) + { + sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); + return; + } + + // the avatar.Close below will clear the child region list. We need this below for (possibly) + // closing the child agents, so save it here (we need a copy as it is Clear()-ed). + //List childRegions = new List(avatar.GetKnownRegionList()); + // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport + // failure at this point (unlike a border crossing failure). So perhaps this can never fail + // once we reach here... + //avatar.Scene.RemoveCapsHandler(avatar.UUID); + + string capsPath = String.Empty; + AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); + agentCircuit.BaseFolder = UUID.Zero; + agentCircuit.InventoryFolder = UUID.Zero; + agentCircuit.startpos = position; + agentCircuit.child = true; + agentCircuit.Appearance = sp.Appearance; + + if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) + { + // brand new agent, let's create a new caps seed + agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); + } + + string reason = String.Empty; + + // Let's create an agent there if one doesn't exist yet. + if (!m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason)) + { + sp.ControllingClient.SendTeleportFailed(String.Format("Destination is not accepting teleports: {0}", + reason)); + return; + } + + // OK, it got this agent. Let's close some child agents + sp.CloseChildAgents(newRegionX, newRegionY); + + if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) + { + #region IP Translation for NAT + IClientIPEndpoint ipepClient; + if (sp.ClientView.TryGet(out ipepClient)) + { + capsPath + = "http://" + + NetworkUtil.GetHostFor(ipepClient.EndPoint, reg.ExternalHostName) + + ":" + + reg.HttpPort + + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + } + else + { + capsPath + = "http://" + + reg.ExternalHostName + + ":" + + reg.HttpPort + + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + } + #endregion + + if (eq != null) + { + #region IP Translation for NAT + // Uses ipepClient above + if (sp.ClientView.TryGet(out ipepClient)) + { + endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + } + #endregion + + eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); + + // ES makes the client send a UseCircuitCode message to the destination, + // which triggers a bunch of things there. + // So let's wait + Thread.Sleep(2000); + + eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + + } + else + { + sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); + } + } + else + { + agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); + capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort + + "/CAPS/" + agentCircuit.CapsPath + "0000/"; + } + + // Expect avatar crossing is a heavy-duty function at the destination. + // That is where MakeRoot is called, which fetches appearance and inventory. + // Plus triggers OnMakeRoot, which spawns a series of asynchronous updates. + //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, + // position, false); + + //{ + // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); + // // We should close that agent we just created over at destination... + // List lst = new List(); + // lst.Add(reg.RegionHandle); + // SendCloseChildAgentAsync(avatar.UUID, lst); + // return; + //} + + SetInTransit(sp.UUID); + + // Let's send a full update of the agent. This is a synchronous call. + AgentData agent = new AgentData(); + sp.CopyTo(agent); + agent.Position = position; + agent.CallbackURI = "http://" + sp.Scene.RegionInfo.ExternalHostName + ":" + sp.Scene.RegionInfo.HttpPort + + "/agent/" + sp.UUID.ToString() + "/" + sp.Scene.RegionInfo.RegionID.ToString() + "/release/"; + + m_aScene.SimulationService.UpdateAgent(reg, agent); + + m_log.DebugFormat( + "[AGENT TRANSFER MODULE]: Sending new AGENT TRANSFER MODULE seed url {0} to client {1}", capsPath, sp.UUID); + + + if (eq != null) + { + eq.TeleportFinishEvent(destinationHandle, 13, endPoint, + 0, teleportFlags, capsPath, sp.UUID); + } + else + { + sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, + teleportFlags, capsPath); + } + + // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which + // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation + // that the client contacted the destination before we send the attachments and close things here. + if (!WaitForCallback(sp.UUID)) + { + // Client never contacted destination. Let's restore everything back + sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); + + ResetFromTransit(sp.UUID); + + // Yikes! We should just have a ref to scene here. + //sp.Scene.InformClientOfNeighbours(sp); + EnableChildAgents(sp); + + // Finally, kill the agent we just created at the destination. + m_aScene.SimulationService.CloseAgent(reg, sp.UUID); + + return; + } + + KillEntity(sp.Scene, sp.LocalId); + + sp.MakeChildAgent(); + + // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it + sp.CrossAttachmentsIntoNewRegion(reg, true); + + // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone + + if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) + { + Thread.Sleep(5000); + sp.Close(); + sp.Scene.IncomingCloseAgent(sp.UUID); + } + else + // now we have a child agent in this region. + sp.Reset(); + + + // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! + if (sp.Scene.NeedSceneCacheClear(sp.UUID)) + { + m_log.DebugFormat( + "[AGENT TRANSFER MODULE]: User {0} is going to another region, profile cache removed", + sp.UUID); + } + } + else + { + sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); + } + } + else + { + // TP to a place that doesn't exist (anymore) + // Inform the viewer about that + sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); + + // and set the map-tile to '(Offline)' + uint regX, regY; + Utils.LongToUInts(regionHandle, out regX, out regY); + + MapBlockData block = new MapBlockData(); + block.X = (ushort)(regX / Constants.RegionSize); + block.Y = (ushort)(regY / Constants.RegionSize); + block.Access = 254; // == not there + + List blocks = new List(); + blocks.Add(block); + sp.ControllingClient.SendMapBlock(blocks, 0); + } + } + } + + protected void KillEntity(Scene scene, uint localID) + { + scene.SendKillObject(localID); + } + + protected virtual ulong GetRegionHandle(GridRegion region) + { + return region.RegionHandle; + } + + protected virtual GridRegion GetFinalDestination(GridRegion region) + { + return region; + } + + protected virtual bool NeedsNewAgent(uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY) + { + return Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY); + } + + protected virtual bool NeedsClosing(uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) + { + return Util.IsOutsideView(oldRegionX, newRegionX, oldRegionY, newRegionY); + } + + protected virtual bool IsOutsideRegion(Scene s, Vector3 pos) + { + + if (s.TestBorderCross(pos, Cardinals.N)) + return true; + if (s.TestBorderCross(pos, Cardinals.S)) + return true; + if (s.TestBorderCross(pos, Cardinals.E)) + return true; + if (s.TestBorderCross(pos, Cardinals.W)) + return true; + + return false; + } + + + #endregion + + #region Enable Child Agent + /// + /// This informs a single neighboring region about agent "avatar". + /// Calls an asynchronous method to do so.. so it doesn't lag the sim. + /// + public void EnableChildAgent(ScenePresence sp, GridRegion region) + { + AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); + agent.BaseFolder = UUID.Zero; + agent.InventoryFolder = UUID.Zero; + agent.startpos = new Vector3(128, 128, 70); + agent.child = true; + agent.Appearance = sp.Appearance; + + InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; + d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, + InformClientOfNeighbourCompleted, + d); + } + #endregion + + #region Crossings + + public void Cross(ScenePresence agent, bool isFlying) + { + Scene scene = agent.Scene; + Vector3 pos = agent.AbsolutePosition; + Vector3 newpos = new Vector3(pos.X, pos.Y, pos.Z); + uint neighbourx = scene.RegionInfo.RegionLocX; + uint neighboury = scene.RegionInfo.RegionLocY; + const float boundaryDistance = 1.7f; + Vector3 northCross = new Vector3(0, boundaryDistance, 0); + Vector3 southCross = new Vector3(0, -1 * boundaryDistance, 0); + Vector3 eastCross = new Vector3(boundaryDistance, 0, 0); + Vector3 westCross = new Vector3(-1 * boundaryDistance, 0, 0); + + // distance to edge that will trigger crossing + + + // distance into new region to place avatar + const float enterDistance = 0.5f; + + if (scene.TestBorderCross(pos + westCross, Cardinals.W)) + { + if (scene.TestBorderCross(pos + northCross, Cardinals.N)) + { + Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); + neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); + } + else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) + { + Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); + if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) + { + neighboury--; + newpos.Y = Constants.RegionSize - enterDistance; + } + else + { + neighboury = b.TriggerRegionY; + neighbourx = b.TriggerRegionX; + + Vector3 newposition = pos; + newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; + newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; + agent.ControllingClient.SendAgentAlertMessage( + String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); + InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); + return; + } + } + + Border ba = scene.GetCrossedBorder(pos + westCross, Cardinals.W); + if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) + { + neighbourx--; + newpos.X = Constants.RegionSize - enterDistance; + } + else + { + neighboury = ba.TriggerRegionY; + neighbourx = ba.TriggerRegionX; + + + Vector3 newposition = pos; + newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; + newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; + agent.ControllingClient.SendAgentAlertMessage( + String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); + InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); + + + return; + } + + } + else if (scene.TestBorderCross(pos + eastCross, Cardinals.E)) + { + Border b = scene.GetCrossedBorder(pos + eastCross, Cardinals.E); + neighbourx += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); + newpos.X = enterDistance; + + if (scene.TestBorderCross(pos + southCross, Cardinals.S)) + { + Border ba = scene.GetCrossedBorder(pos + southCross, Cardinals.S); + if (ba.TriggerRegionX == 0 && ba.TriggerRegionY == 0) + { + neighboury--; + newpos.Y = Constants.RegionSize - enterDistance; + } + else + { + neighboury = ba.TriggerRegionY; + neighbourx = ba.TriggerRegionX; + Vector3 newposition = pos; + newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; + newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; + agent.ControllingClient.SendAgentAlertMessage( + String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); + InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); + return; + } + } + else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) + { + Border c = scene.GetCrossedBorder(pos + northCross, Cardinals.N); + neighboury += (uint)(int)(c.BorderLine.Z / (int)Constants.RegionSize); + newpos.Y = enterDistance; + } + + + } + else if (scene.TestBorderCross(pos + southCross, Cardinals.S)) + { + Border b = scene.GetCrossedBorder(pos + southCross, Cardinals.S); + if (b.TriggerRegionX == 0 && b.TriggerRegionY == 0) + { + neighboury--; + newpos.Y = Constants.RegionSize - enterDistance; + } + else + { + neighboury = b.TriggerRegionY; + neighbourx = b.TriggerRegionX; + Vector3 newposition = pos; + newposition.X += (scene.RegionInfo.RegionLocX - neighbourx) * Constants.RegionSize; + newposition.Y += (scene.RegionInfo.RegionLocY - neighboury) * Constants.RegionSize; + agent.ControllingClient.SendAgentAlertMessage( + String.Format("Moving you to region {0},{1}", neighbourx, neighboury), false); + InformClientToInitateTeleportToLocation(agent, neighbourx, neighboury, newposition, scene); + return; + } + } + else if (scene.TestBorderCross(pos + northCross, Cardinals.N)) + { + + Border b = scene.GetCrossedBorder(pos + northCross, Cardinals.N); + neighboury += (uint)(int)(b.BorderLine.Z / (int)Constants.RegionSize); + newpos.Y = enterDistance; + } + + /* + + if (pos.X < boundaryDistance) //West + { + neighbourx--; + newpos.X = Constants.RegionSize - enterDistance; + } + else if (pos.X > Constants.RegionSize - boundaryDistance) // East + { + neighbourx++; + newpos.X = enterDistance; + } + + if (pos.Y < boundaryDistance) // South + { + neighboury--; + newpos.Y = Constants.RegionSize - enterDistance; + } + else if (pos.Y > Constants.RegionSize - boundaryDistance) // North + { + neighboury++; + newpos.Y = enterDistance; + } + */ + + CrossAgentToNewRegionDelegate d = CrossAgentToNewRegionAsync; + d.BeginInvoke(agent, newpos, neighbourx, neighboury, isFlying, CrossAgentToNewRegionCompleted, d); + + } + + + public delegate void InformClientToInitateTeleportToLocationDelegate(ScenePresence agent, uint regionX, uint regionY, + Vector3 position, + Scene initiatingScene); + + private void InformClientToInitateTeleportToLocation(ScenePresence agent, uint regionX, uint regionY, Vector3 position, Scene initiatingScene) + { + + // This assumes that we know what our neighbors are. + + InformClientToInitateTeleportToLocationDelegate d = InformClientToInitiateTeleportToLocationAsync; + d.BeginInvoke(agent, regionX, regionY, position, initiatingScene, + InformClientToInitiateTeleportToLocationCompleted, + d); + } + + public void InformClientToInitiateTeleportToLocationAsync(ScenePresence agent, uint regionX, uint regionY, Vector3 position, + Scene initiatingScene) + { + Thread.Sleep(10000); + IMessageTransferModule im = initiatingScene.RequestModuleInterface(); + if (im != null) + { + UUID gotoLocation = Util.BuildFakeParcelID( + Util.UIntsToLong( + (regionX * + (uint)Constants.RegionSize), + (regionY * + (uint)Constants.RegionSize)), + (uint)(int)position.X, + (uint)(int)position.Y, + (uint)(int)position.Z); + GridInstantMessage m = new GridInstantMessage(initiatingScene, UUID.Zero, + "Region", agent.UUID, + (byte)InstantMessageDialog.GodLikeRequestTeleport, false, + "", gotoLocation, false, new Vector3(127, 0, 0), + new Byte[0]); + im.SendInstantMessage(m, delegate(bool success) + { + m_log.DebugFormat("[AGENT TRANSFER MODULE]: Client Initiating Teleport sending IM success = {0}", success); + }); + + } + } + + private void InformClientToInitiateTeleportToLocationCompleted(IAsyncResult iar) + { + InformClientToInitateTeleportToLocationDelegate icon = + (InformClientToInitateTeleportToLocationDelegate)iar.AsyncState; + icon.EndInvoke(iar); + } + + public delegate ScenePresence CrossAgentToNewRegionDelegate(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, bool isFlying); + + /// + /// This Closes child agents on neighboring regions + /// Calls an asynchronous method to do so.. so it doesn't lag the sim. + /// + protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, bool isFlying) + { + m_log.DebugFormat("[AGENT TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3}", agent.Firstname, agent.Lastname, neighbourx, neighboury); + + Scene m_scene = agent.Scene; + ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); + + int x = (int)(neighbourx * Constants.RegionSize), y = (int)(neighboury * Constants.RegionSize); + GridRegion neighbourRegion = m_scene.GridService.GetRegionByPosition(m_scene.RegionInfo.ScopeID, (int)x, (int)y); + + if (neighbourRegion != null && agent.ValidateAttachments()) + { + pos = pos + (agent.Velocity); + + SetInTransit(agent.UUID); + AgentData cAgent = new AgentData(); + agent.CopyTo(cAgent); + cAgent.Position = pos; + if (isFlying) + cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; + cAgent.CallbackURI = "http://" + m_scene.RegionInfo.ExternalHostName + ":" + m_scene.RegionInfo.HttpPort + + "/agent/" + agent.UUID.ToString() + "/" + m_scene.RegionInfo.RegionID.ToString() + "/release/"; + + m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent); + + // Next, let's close the child agent connections that are too far away. + agent.CloseChildAgents(neighbourx, neighboury); + + //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); + agent.ControllingClient.RequestClientInfo(); + + //m_log.Debug("BEFORE CROSS"); + //Scene.DumpChildrenSeeds(UUID); + //DumpKnownRegions(); + string agentcaps; + if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) + { + m_log.ErrorFormat("[AGENT TRANSFER MODULE]: No AGENT TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", + neighbourRegion.RegionHandle); + return agent; + } + // TODO Should construct this behind a method + string capsPath = + "http://" + neighbourRegion.ExternalHostName + ":" + neighbourRegion.HttpPort + + "/CAPS/" + agentcaps /*circuitdata.CapsPath*/ + "0000/"; + + m_log.DebugFormat("[AGENT TRANSFER MODULE]: Sending new AGENT TRANSFER MODULE seed url {0} to client {1}", capsPath, agent.UUID); + + IEventQueue eq = agent.Scene.RequestModuleInterface(); + if (eq != null) + { + eq.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, + capsPath, agent.UUID, agent.ControllingClient.SessionId); + } + else + { + agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, + capsPath); + } + + if (!WaitForCallback(agent.UUID)) + { + m_log.Debug("[AGENT TRANSFER MODULE]: Callback never came in crossing agent"); + ResetFromTransit(agent.UUID); + + // Yikes! We should just have a ref to scene here. + //agent.Scene.InformClientOfNeighbours(agent); + EnableChildAgents(agent); + + return agent; + } + + agent.MakeChildAgent(); + // now we have a child agent in this region. Request all interesting data about other (root) agents + agent.SendInitialFullUpdateToAllClients(); + + agent.CrossAttachmentsIntoNewRegion(neighbourRegion, true); + + // m_scene.SendKillObject(m_localId); + + agent.Scene.NotifyMyCoarseLocationChange(); + // the user may change their profile information in other region, + // so the userinfo in UserProfileCache is not reliable any more, delete it + // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! + if (agent.Scene.NeedSceneCacheClear(agent.UUID)) + { + m_log.DebugFormat( + "[AGENT TRANSFER MODULE]: User {0} is going to another region", agent.UUID); + } + } + + //m_log.Debug("AFTER CROSS"); + //Scene.DumpChildrenSeeds(UUID); + //DumpKnownRegions(); + return agent; + } + + private void CrossAgentToNewRegionCompleted(IAsyncResult iar) + { + CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState; + ScenePresence agent = icon.EndInvoke(iar); + + // If the cross was successful, this agent is a child agent + if (agent.IsChildAgent) + agent.Reset(); + else // Not successful + agent.RestoreInCurrentScene(); + + // In any case + agent.NotInTransit(); + + //m_log.DebugFormat("[AGENT TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); + } + + #endregion + + + #region Enable Child Agents + + private delegate void InformClientOfNeighbourDelegate( + ScenePresence avatar, AgentCircuitData a, GridRegion reg, IPEndPoint endPoint, bool newAgent); + + /// + /// This informs all neighboring regions about agent "avatar". + /// Calls an asynchronous method to do so.. so it doesn't lag the sim. + /// + public void EnableChildAgents(ScenePresence sp) + { + List neighbours = new List(); + RegionInfo m_regionInfo = sp.Scene.RegionInfo; + + if (m_regionInfo != null) + { + neighbours = RequestNeighbours(sp.Scene, m_regionInfo.RegionLocX, m_regionInfo.RegionLocY); + } + else + { + m_log.Debug("[AGENT TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?"); + } + + /// We need to find the difference between the new regions where there are no child agents + /// and the regions where there are already child agents. We only send notification to the former. + List neighbourHandles = NeighbourHandles(neighbours); // on this region + neighbourHandles.Add(sp.Scene.RegionInfo.RegionHandle); // add this region too + List previousRegionNeighbourHandles; + + if (sp.Scene.CapsModule != null) + { + previousRegionNeighbourHandles = + new List(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID).Keys); + } + else + { + previousRegionNeighbourHandles = new List(); + } + + List newRegions = NewNeighbours(neighbourHandles, previousRegionNeighbourHandles); + List oldRegions = OldNeighbours(neighbourHandles, previousRegionNeighbourHandles); + + //Dump("Current Neighbors", neighbourHandles); + //Dump("Previous Neighbours", previousRegionNeighbourHandles); + //Dump("New Neighbours", newRegions); + //Dump("Old Neighbours", oldRegions); + + /// Update the scene presence's known regions here on this region + sp.DropOldNeighbours(oldRegions); + + /// Collect as many seeds as possible + Dictionary seeds; + if (sp.Scene.CapsModule != null) + seeds + = new Dictionary(sp.Scene.CapsModule.GetChildrenSeeds(sp.UUID)); + else + seeds = new Dictionary(); + + //m_log.Debug(" !!! No. of seeds: " + seeds.Count); + if (!seeds.ContainsKey(sp.Scene.RegionInfo.RegionHandle)) + seeds.Add(sp.Scene.RegionInfo.RegionHandle, sp.ControllingClient.RequestClientInfo().CapsPath); + + /// Create the necessary child agents + List cagents = new List(); + foreach (GridRegion neighbour in neighbours) + { + if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) + { + + AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); + agent.BaseFolder = UUID.Zero; + agent.InventoryFolder = UUID.Zero; + agent.startpos = new Vector3(128, 128, 70); + agent.child = true; + agent.Appearance = sp.Appearance; + + if (newRegions.Contains(neighbour.RegionHandle)) + { + agent.CapsPath = CapsUtil.GetRandomCapsObjectPath(); + sp.AddNeighbourRegion(neighbour.RegionHandle, agent.CapsPath); + seeds.Add(neighbour.RegionHandle, agent.CapsPath); + } + else + agent.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, neighbour.RegionHandle); + + cagents.Add(agent); + } + } + + /// Update all child agent with everyone's seeds + foreach (AgentCircuitData a in cagents) + { + a.ChildrenCapSeeds = new Dictionary(seeds); + } + + if (sp.Scene.CapsModule != null) + { + sp.Scene.CapsModule.SetChildrenSeed(sp.UUID, seeds); + } + sp.KnownRegions = seeds; + //avatar.Scene.DumpChildrenSeeds(avatar.UUID); + //avatar.DumpKnownRegions(); + + bool newAgent = false; + int count = 0; + foreach (GridRegion neighbour in neighbours) + { + //m_log.WarnFormat("--> Going to send child agent to {0}", neighbour.RegionName); + // Don't do it if there's already an agent in that region + if (newRegions.Contains(neighbour.RegionHandle)) + newAgent = true; + else + newAgent = false; + + if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) + { + InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; + try + { + d.BeginInvoke(sp, cagents[count], neighbour, neighbour.ExternalEndPoint, newAgent, + InformClientOfNeighbourCompleted, + d); + } + + catch (ArgumentOutOfRangeException) + { + m_log.ErrorFormat( + "[AGENT TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbor list. The following region will not display to the client: {0} for region {1} ({2}, {3}).", + neighbour.ExternalHostName, + neighbour.RegionHandle, + neighbour.RegionLocX, + neighbour.RegionLocY); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[AGENT TRANSFER MODULE]: Could not resolve external hostname {0} for region {1} ({2}, {3}). {4}", + neighbour.ExternalHostName, + neighbour.RegionHandle, + neighbour.RegionLocX, + neighbour.RegionLocY, + e); + + // FIXME: Okay, even though we've failed, we're still going to throw the exception on, + // since I don't know what will happen if we just let the client continue + + // XXX: Well, decided to swallow the exception instead for now. Let us see how that goes. + // throw e; + + } + } + count++; + } + } + + private void InformClientOfNeighbourCompleted(IAsyncResult iar) + { + InformClientOfNeighbourDelegate icon = (InformClientOfNeighbourDelegate)iar.AsyncState; + icon.EndInvoke(iar); + //m_log.WarnFormat(" --> InformClientOfNeighbourCompleted"); + } + + /// + /// Async component for informing client of which neighbours exist + /// + /// + /// This needs to run asynchronously, as a network timeout may block the thread for a long while + /// + /// + /// + /// + /// + private void InformClientOfNeighbourAsync(ScenePresence sp, AgentCircuitData a, GridRegion reg, + IPEndPoint endPoint, bool newAgent) + { + // Let's wait just a little to give time to originating regions to catch up with closing child agents + // after a cross here + Thread.Sleep(500); + + Scene m_scene = sp.Scene; + + uint x, y; + Utils.LongToUInts(reg.RegionHandle, out x, out y); + x = x / Constants.RegionSize; + y = y / Constants.RegionSize; + m_log.Info("[AGENT TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint.ToString() + ")"); + + string capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort + + "/CAPS/" + a.CapsPath + "0000/"; + + string reason = String.Empty; + + + bool regionAccepted = m_scene.SimulationService.CreateAgent(reg, a, 0, out reason); // m_interregionCommsOut.SendCreateChildAgent(reg.RegionHandle, a, 0, out reason); + + if (regionAccepted && newAgent) + { + IEventQueue eq = sp.Scene.RequestModuleInterface(); + if (eq != null) + { + #region IP Translation for NAT + IClientIPEndpoint ipepClient; + if (sp.ClientView.TryGet(out ipepClient)) + { + endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + } + #endregion + + eq.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); + eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + m_log.DebugFormat("[AGENT TRANSFER MODULE]: Sending new AGENT TRANSFER MODULE seed url {0} to client {1} in region {2}", + capsPath, sp.UUID, sp.Scene.RegionInfo.RegionName); + } + else + { + sp.ControllingClient.InformClientOfNeighbour(reg.RegionHandle, endPoint); + // TODO: make Event Queue disablable! + } + + m_log.Info("[AGENT TRANSFER MODULE]: Completed inform client about neighbour " + endPoint.ToString()); + + } + + } + + protected List RequestNeighbours(Scene pScene, uint pRegionLocX, uint pRegionLocY) + { + RegionInfo m_regionInfo = pScene.RegionInfo; + + Border[] northBorders = pScene.NorthBorders.ToArray(); + Border[] southBorders = pScene.SouthBorders.ToArray(); + Border[] eastBorders = pScene.EastBorders.ToArray(); + Border[] westBorders = pScene.WestBorders.ToArray(); + + // Legacy one region. Provided for simplicity while testing the all inclusive method in the else statement. + if (northBorders.Length <= 1 && southBorders.Length <= 1 && eastBorders.Length <= 1 && westBorders.Length <= 1) + { + return pScene.GridService.GetNeighbours(m_regionInfo.ScopeID, m_regionInfo.RegionID); + } + else + { + Vector2 extent = Vector2.Zero; + for (int i = 0; i < eastBorders.Length; i++) + { + extent.X = (eastBorders[i].BorderLine.Z > extent.X) ? eastBorders[i].BorderLine.Z : extent.X; + } + for (int i = 0; i < northBorders.Length; i++) + { + extent.Y = (northBorders[i].BorderLine.Z > extent.Y) ? northBorders[i].BorderLine.Z : extent.Y; + } + + // Loss of fraction on purpose + extent.X = ((int)extent.X / (int)Constants.RegionSize) + 1; + extent.Y = ((int)extent.Y / (int)Constants.RegionSize) + 1; + + int startX = (int)(pRegionLocX - 1) * (int)Constants.RegionSize; + int startY = (int)(pRegionLocY - 1) * (int)Constants.RegionSize; + + int endX = ((int)pRegionLocX + (int)extent.X) * (int)Constants.RegionSize; + int endY = ((int)pRegionLocY + (int)extent.Y) * (int)Constants.RegionSize; + + List neighbours = pScene.GridService.GetRegionRange(m_regionInfo.ScopeID, startX, endX, startY, endY); + neighbours.RemoveAll(delegate(GridRegion r) { return r.RegionID == m_regionInfo.RegionID; }); + + return neighbours; + } + } + + private List NewNeighbours(List currentNeighbours, List previousNeighbours) + { + return currentNeighbours.FindAll(delegate(ulong handle) { return !previousNeighbours.Contains(handle); }); + } + + // private List CommonNeighbours(List currentNeighbours, List previousNeighbours) + // { + // return currentNeighbours.FindAll(delegate(ulong handle) { return previousNeighbours.Contains(handle); }); + // } + + private List OldNeighbours(List currentNeighbours, List previousNeighbours) + { + return previousNeighbours.FindAll(delegate(ulong handle) { return !currentNeighbours.Contains(handle); }); + } + + private List NeighbourHandles(List neighbours) + { + List handles = new List(); + foreach (GridRegion reg in neighbours) + { + handles.Add(reg.RegionHandle); + } + return handles; + } + + private void Dump(string msg, List handles) + { + m_log.InfoFormat("-------------- HANDLE DUMP ({0}) ---------", msg); + foreach (ulong handle in handles) + { + uint x, y; + Utils.LongToUInts(handle, out x, out y); + x = x / Constants.RegionSize; + y = y / Constants.RegionSize; + m_log.InfoFormat("({0}, {1})", x, y); + } + } + + #endregion + + + #region Agent Arrived + public void AgentArrivedAtDestination(UUID id) + { + //m_log.Debug(" >>> ReleaseAgent called <<< "); + ResetFromTransit(id); + } + + #endregion + + + #region Misc + + protected bool WaitForCallback(UUID id) + { + int count = 200; + while (m_agentsInTransit.Contains(id) && count-- > 0) + { + //m_log.Debug(" >>> Waiting... " + count); + Thread.Sleep(100); + } + + if (count > 0) + return true; + else + return false; + } + + protected void SetInTransit(UUID id) + { + lock (m_agentsInTransit) + { + if (!m_agentsInTransit.Contains(id)) + m_agentsInTransit.Add(id); + } + } + + protected bool ResetFromTransit(UUID id) + { + lock (m_agentsInTransit) + { + if (m_agentsInTransit.Contains(id)) + { + m_agentsInTransit.Remove(id); + return true; + } + } + return false; + } + + + #endregion + + } +} -- cgit v1.1 From bd6d1a24448dafea5be7ddbcd591b352040e4412 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 16 Jan 2010 07:46:07 -0800 Subject: Moved prim crossing to EntityTransferModule. Not complete yet. --- .../EntityTransfer/EntityTransferModule.cs | 421 ++++++++++++++++++--- 1 file changed, 372 insertions(+), 49 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index af004b0..44d3858 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -46,15 +46,16 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { - public class AgentTransferModule : ISharedRegionModule, IEntityTransferModule + public class EntityTransferModule : ISharedRegionModule, IEntityTransferModule { - #region ISharedRegionModule - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private bool m_Enabled = false; protected Scene m_aScene; protected List m_agentsInTransit; + #region ISharedRegionModule + public Type ReplaceableInterface { get { return null; } @@ -62,7 +63,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public string Name { - get { return "AgentTransferModule"; } + get { return "BasicEntityTransferModule"; } } public virtual void Initialise(IConfigSource source) @@ -70,12 +71,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer IConfig moduleConfig = source.Configs["Modules"]; if (moduleConfig != null) { - string name = moduleConfig.GetString("AgentTransferModule", ""); + string name = moduleConfig.GetString("EntityTransferModule", ""); if (name == Name) { m_agentsInTransit = new List(); m_Enabled = true; - m_log.Info("[AGENT TRANSFER MODULE]: Enabled."); + m_log.InfoFormat("[ENTITY TRANSFER MODULE]: {0} nabled.", Name); } } } @@ -120,7 +121,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion - #region Teleports + #region Agent Teleports public void Teleport(ScenePresence sp, ulong regionHandle, Vector3 position, Vector3 lookAt, uint teleportFlags) { @@ -137,7 +138,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (regionHandle == sp.Scene.RegionInfo.RegionHandle) { m_log.DebugFormat( - "[AGENT TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", + "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", position, sp.Scene.RegionInfo.RegionName); // Teleport within the same region @@ -146,7 +147,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Vector3 emergencyPos = new Vector3(128, 128, 128); m_log.WarnFormat( - "[AGENT TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", + "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", position, sp.Name, sp.UUID, emergencyPos); position = emergencyPos; } @@ -183,7 +184,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (reg != null) { m_log.DebugFormat( - "[AGENT TRANSFER MODULE]: RequestTeleportToLocation to {0} in {1}", + "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation to {0} in {1}", position, reg.RegionName); uint newRegionX = (uint)(reg.RegionHandle >> 40); @@ -338,7 +339,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_aScene.SimulationService.UpdateAgent(reg, agent); m_log.DebugFormat( - "[AGENT TRANSFER MODULE]: Sending new AGENT TRANSFER MODULE seed url {0} to client {1}", capsPath, sp.UUID); + "[ENTITY TRANSFER MODULE]: Sending new ENTITY TRANSFER MODULE seed url {0} to client {1}", capsPath, sp.UUID); if (eq != null) @@ -377,7 +378,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.MakeChildAgent(); // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it - sp.CrossAttachmentsIntoNewRegion(reg, true); + CrossAttachmentsIntoNewRegion(reg, sp, true); // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone @@ -396,7 +397,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (sp.Scene.NeedSceneCacheClear(sp.UUID)) { m_log.DebugFormat( - "[AGENT TRANSFER MODULE]: User {0} is going to another region, profile cache removed", + "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", sp.UUID); } } @@ -470,28 +471,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion - #region Enable Child Agent - /// - /// This informs a single neighboring region about agent "avatar". - /// Calls an asynchronous method to do so.. so it doesn't lag the sim. - /// - public void EnableChildAgent(ScenePresence sp, GridRegion region) - { - AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); - agent.BaseFolder = UUID.Zero; - agent.InventoryFolder = UUID.Zero; - agent.startpos = new Vector3(128, 128, 70); - agent.child = true; - agent.Appearance = sp.Appearance; - - InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; - d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, - InformClientOfNeighbourCompleted, - d); - } - #endregion - - #region Crossings + #region Agent Crossings public void Cross(ScenePresence agent, bool isFlying) { @@ -700,7 +680,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer new Byte[0]); im.SendInstantMessage(m, delegate(bool success) { - m_log.DebugFormat("[AGENT TRANSFER MODULE]: Client Initiating Teleport sending IM success = {0}", success); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Client Initiating Teleport sending IM success = {0}", success); }); } @@ -721,7 +701,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// protected ScenePresence CrossAgentToNewRegionAsync(ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, bool isFlying) { - m_log.DebugFormat("[AGENT TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3}", agent.Firstname, agent.Lastname, neighbourx, neighboury); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3}", agent.Firstname, agent.Lastname, neighbourx, neighboury); Scene m_scene = agent.Scene; ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); @@ -756,7 +736,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer string agentcaps; if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) { - m_log.ErrorFormat("[AGENT TRANSFER MODULE]: No AGENT TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", + m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", neighbourRegion.RegionHandle); return agent; } @@ -765,7 +745,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "http://" + neighbourRegion.ExternalHostName + ":" + neighbourRegion.HttpPort + "/CAPS/" + agentcaps /*circuitdata.CapsPath*/ + "0000/"; - m_log.DebugFormat("[AGENT TRANSFER MODULE]: Sending new AGENT TRANSFER MODULE seed url {0} to client {1}", capsPath, agent.UUID); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new ENTITY TRANSFER MODULE seed url {0} to client {1}", capsPath, agent.UUID); IEventQueue eq = agent.Scene.RequestModuleInterface(); if (eq != null) @@ -781,7 +761,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!WaitForCallback(agent.UUID)) { - m_log.Debug("[AGENT TRANSFER MODULE]: Callback never came in crossing agent"); + m_log.Debug("[ENTITY TRANSFER MODULE]: Callback never came in crossing agent"); ResetFromTransit(agent.UUID); // Yikes! We should just have a ref to scene here. @@ -795,7 +775,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // now we have a child agent in this region. Request all interesting data about other (root) agents agent.SendInitialFullUpdateToAllClients(); - agent.CrossAttachmentsIntoNewRegion(neighbourRegion, true); + CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); // m_scene.SendKillObject(m_localId); @@ -806,7 +786,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (agent.Scene.NeedSceneCacheClear(agent.UUID)) { m_log.DebugFormat( - "[AGENT TRANSFER MODULE]: User {0} is going to another region", agent.UUID); + "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); } } @@ -830,11 +810,31 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // In any case agent.NotInTransit(); - //m_log.DebugFormat("[AGENT TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); + //m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} completed.", agent.Firstname, agent.Lastname); } #endregion + #region Enable Child Agent + /// + /// This informs a single neighboring region about agent "avatar". + /// Calls an asynchronous method to do so.. so it doesn't lag the sim. + /// + public void EnableChildAgent(ScenePresence sp, GridRegion region) + { + AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); + agent.BaseFolder = UUID.Zero; + agent.InventoryFolder = UUID.Zero; + agent.startpos = new Vector3(128, 128, 70); + agent.child = true; + agent.Appearance = sp.Appearance; + + InformClientOfNeighbourDelegate d = InformClientOfNeighbourAsync; + d.BeginInvoke(sp, agent, region, region.ExternalEndPoint, true, + InformClientOfNeighbourCompleted, + d); + } + #endregion #region Enable Child Agents @@ -856,7 +856,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } else { - m_log.Debug("[AGENT TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?"); + m_log.Debug("[ENTITY TRANSFER MODULE]: m_regionInfo was null in EnableChildAgents, is this a NPC?"); } /// We need to find the difference between the new regions where there are no child agents @@ -963,7 +963,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer catch (ArgumentOutOfRangeException) { m_log.ErrorFormat( - "[AGENT TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbor list. The following region will not display to the client: {0} for region {1} ({2}, {3}).", + "[ENTITY TRANSFER MODULE]: Neighbour Regions response included the current region in the neighbor list. The following region will not display to the client: {0} for region {1} ({2}, {3}).", neighbour.ExternalHostName, neighbour.RegionHandle, neighbour.RegionLocX, @@ -972,7 +972,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer catch (Exception e) { m_log.ErrorFormat( - "[AGENT TRANSFER MODULE]: Could not resolve external hostname {0} for region {1} ({2}, {3}). {4}", + "[ENTITY TRANSFER MODULE]: Could not resolve external hostname {0} for region {1} ({2}, {3}). {4}", neighbour.ExternalHostName, neighbour.RegionHandle, neighbour.RegionLocX, @@ -1021,7 +1021,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Utils.LongToUInts(reg.RegionHandle, out x, out y); x = x / Constants.RegionSize; y = y / Constants.RegionSize; - m_log.Info("[AGENT TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint.ToString() + ")"); + m_log.Info("[ENTITY TRANSFER MODULE]: Starting to inform client about neighbour " + x + ", " + y + "(" + endPoint.ToString() + ")"); string capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort + "/CAPS/" + a.CapsPath + "0000/"; @@ -1046,7 +1046,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer eq.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); - m_log.DebugFormat("[AGENT TRANSFER MODULE]: Sending new AGENT TRANSFER MODULE seed url {0} to client {1} in region {2}", + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new ENTITY TRANSFER MODULE seed url {0} to client {1} in region {2}", capsPath, sp.UUID, sp.Scene.RegionInfo.RegionName); } else @@ -1055,7 +1055,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // TODO: make Event Queue disablable! } - m_log.Info("[AGENT TRANSFER MODULE]: Completed inform client about neighbour " + endPoint.ToString()); + m_log.Info("[ENTITY TRANSFER MODULE]: Completed inform client about neighbour " + endPoint.ToString()); } @@ -1154,6 +1154,329 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion + #region Object Crossings + /// + /// Move the given scene object into a new region depending on which region its absolute position has moved + /// into. + /// + /// This method locates the new region handle and offsets the prim position for the new region + /// + /// the attempted out of region position of the scene object + /// the scene object that we're crossing + public void Cross(SceneObjectGroup grp, Vector3 attemptedPosition, bool silent) + { + if (grp == null) + return; + if (grp.IsDeleted) + return; + + Scene scene = grp.Scene; + if (scene == null) + return; + + if (grp.RootPart.DIE_AT_EDGE) + { + // We remove the object here + try + { + scene.DeleteSceneObject(grp, false); + } + catch (Exception) + { + m_log.Warn("[DATABASE]: exception when trying to remove the prim that crossed the border."); + } + return; + } + + int thisx = (int)scene.RegionInfo.RegionLocX; + int thisy = (int)scene.RegionInfo.RegionLocY; + Vector3 EastCross = new Vector3(0.1f, 0, 0); + Vector3 WestCross = new Vector3(-0.1f, 0, 0); + Vector3 NorthCross = new Vector3(0, 0.1f, 0); + Vector3 SouthCross = new Vector3(0, -0.1f, 0); + + + // use this if no borders were crossed! + ulong newRegionHandle + = Util.UIntsToLong((uint)((thisx) * Constants.RegionSize), + (uint)((thisy) * Constants.RegionSize)); + + Vector3 pos = attemptedPosition; + + int changeX = 1; + int changeY = 1; + + if (scene.TestBorderCross(attemptedPosition + WestCross, Cardinals.W)) + { + if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) + { + + Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W); + + if (crossedBorderx.BorderLine.Z > 0) + { + pos.X = ((pos.X + crossedBorderx.BorderLine.Z)); + changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize); + } + else + pos.X = ((pos.X + Constants.RegionSize)); + + Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); + //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) + + if (crossedBordery.BorderLine.Z > 0) + { + pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); + changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); + } + else + pos.Y = ((pos.Y + Constants.RegionSize)); + + + + newRegionHandle + = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), + (uint)((thisy - changeY) * Constants.RegionSize)); + // x - 1 + // y - 1 + } + else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N)) + { + Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W); + + if (crossedBorderx.BorderLine.Z > 0) + { + pos.X = ((pos.X + crossedBorderx.BorderLine.Z)); + changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize); + } + else + pos.X = ((pos.X + Constants.RegionSize)); + + + Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); + //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) + + if (crossedBordery.BorderLine.Z > 0) + { + pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); + changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); + } + else + pos.Y = ((pos.Y + Constants.RegionSize)); + + newRegionHandle + = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), + (uint)((thisy + changeY) * Constants.RegionSize)); + // x - 1 + // y + 1 + } + else + { + Border crossedBorderx = scene.GetCrossedBorder(attemptedPosition + WestCross, Cardinals.W); + + if (crossedBorderx.BorderLine.Z > 0) + { + pos.X = ((pos.X + crossedBorderx.BorderLine.Z)); + changeX = (int)(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize); + } + else + pos.X = ((pos.X + Constants.RegionSize)); + + newRegionHandle + = Util.UIntsToLong((uint)((thisx - changeX) * Constants.RegionSize), + (uint)(thisy * Constants.RegionSize)); + // x - 1 + } + } + else if (scene.TestBorderCross(attemptedPosition + EastCross, Cardinals.E)) + { + if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) + { + + pos.X = ((pos.X - Constants.RegionSize)); + Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); + //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) + + if (crossedBordery.BorderLine.Z > 0) + { + pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); + changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); + } + else + pos.Y = ((pos.Y + Constants.RegionSize)); + + + newRegionHandle + = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize), + (uint)((thisy - changeY) * Constants.RegionSize)); + // x + 1 + // y - 1 + } + else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N)) + { + pos.X = ((pos.X - Constants.RegionSize)); + pos.Y = ((pos.Y - Constants.RegionSize)); + newRegionHandle + = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize), + (uint)((thisy + changeY) * Constants.RegionSize)); + // x + 1 + // y + 1 + } + else + { + pos.X = ((pos.X - Constants.RegionSize)); + newRegionHandle + = Util.UIntsToLong((uint)((thisx + changeX) * Constants.RegionSize), + (uint)(thisy * Constants.RegionSize)); + // x + 1 + } + } + else if (scene.TestBorderCross(attemptedPosition + SouthCross, Cardinals.S)) + { + Border crossedBordery = scene.GetCrossedBorder(attemptedPosition + SouthCross, Cardinals.S); + //(crossedBorderx.BorderLine.Z / (int)Constants.RegionSize) + + if (crossedBordery.BorderLine.Z > 0) + { + pos.Y = ((pos.Y + crossedBordery.BorderLine.Z)); + changeY = (int)(crossedBordery.BorderLine.Z / (int)Constants.RegionSize); + } + else + pos.Y = ((pos.Y + Constants.RegionSize)); + + newRegionHandle + = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy - changeY) * Constants.RegionSize)); + // y - 1 + } + else if (scene.TestBorderCross(attemptedPosition + NorthCross, Cardinals.N)) + { + + pos.Y = ((pos.Y - Constants.RegionSize)); + newRegionHandle + = Util.UIntsToLong((uint)(thisx * Constants.RegionSize), (uint)((thisy + changeY) * Constants.RegionSize)); + // y + 1 + } + + // Offset the positions for the new region across the border + Vector3 oldGroupPosition = grp.RootPart.GroupPosition; + grp.OffsetForNewRegion(pos); + + // If we fail to cross the border, then reset the position of the scene object on that border. + uint x = 0, y = 0; + Utils.LongToUInts(newRegionHandle, out x, out y); + GridRegion destination = scene.GridService.GetRegionByPosition(UUID.Zero, (int)x, (int)y); + if (destination != null && !CrossPrimGroupIntoNewRegion(destination, grp, silent)) + { + grp.OffsetForNewRegion(oldGroupPosition); + grp.ScheduleGroupForFullUpdate(); + } + } + + + /// + /// Move the given scene object into a new region + /// + /// + /// Scene Object Group that we're crossing + /// + /// true if the crossing itself was successful, false on failure + /// FIMXE: we still return true if the crossing object was not successfully deleted from the originating region + /// + protected bool CrossPrimGroupIntoNewRegion(GridRegion destination, SceneObjectGroup grp, bool silent) + { + //m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<"); + + bool successYN = false; + grp.RootPart.UpdateFlag = 0; + //int primcrossingXMLmethod = 0; + + if (destination != null) + { + //string objectState = grp.GetStateSnapshot(); + + //successYN + // = m_sceneGridService.PrimCrossToNeighboringRegion( + // newRegionHandle, grp.UUID, m_serialiser.SaveGroupToXml2(grp), primcrossingXMLmethod); + //if (successYN && (objectState != "") && m_allowScriptCrossings) + //{ + // successYN = m_sceneGridService.PrimCrossToNeighboringRegion( + // newRegionHandle, grp.UUID, objectState, 100); + //} + + //// And the new channel... + //if (m_interregionCommsOut != null) + // successYN = m_interregionCommsOut.SendCreateObject(newRegionHandle, grp, true); + if (m_aScene.SimulationService != null) + successYN = m_aScene.SimulationService.CreateObject(destination, grp, true); + + if (successYN) + { + // We remove the object here + try + { + grp.Scene.DeleteSceneObject(grp, silent); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ENTITY TRANSFER MODULE]: Exception deleting the old object left behind on a border crossing for {0}, {1}", + grp, e); + } + } + else + { + if (!grp.IsDeleted) + { + if (grp.RootPart.PhysActor != null) + { + grp.RootPart.PhysActor.CrossingFailure(); + } + } + + m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: Prim crossing failed for {0}", grp); + } + } + else + { + m_log.Error("[ENTITY TRANSFER MODULE]: destination was unexpectedly null in Scene.CrossPrimGroupIntoNewRegion()"); + } + + return successYN; + } + + protected bool CrossAttachmentsIntoNewRegion(GridRegion destination, ScenePresence sp, bool silent) + { + List m_attachments = sp.Attachments; + lock (m_attachments) + { + // Validate + foreach (SceneObjectGroup gobj in m_attachments) + { + if (gobj == null || gobj.IsDeleted) + return false; + } + + foreach (SceneObjectGroup gobj in m_attachments) + { + // If the prim group is null then something must have happened to it! + if (gobj != null && gobj.RootPart != null) + { + // Set the parent localID to 0 so it transfers over properly. + gobj.RootPart.SetParentLocalId(0); + gobj.AbsolutePosition = gobj.RootPart.AttachedPos; + gobj.RootPart.IsAttachment = false; + //gobj.RootPart.LastOwnerID = gobj.GetFromAssetID(); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending attachment {0} to region {1}", gobj.UUID, destination.RegionName); + CrossPrimGroupIntoNewRegion(destination, gobj, silent); + } + } + m_attachments.Clear(); + + return true; + } + } + + #endregion #region Misc -- cgit v1.1 From ee1fb81376041f6eef27bbb3e84b56ae6e2357b3 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 16 Jan 2010 08:42:20 -0800 Subject: Finished moving object crossings into EntityTransferModule --- .../CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 44d3858..25415af 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -339,7 +339,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_aScene.SimulationService.UpdateAgent(reg, agent); m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Sending new ENTITY TRANSFER MODULE seed url {0} to client {1}", capsPath, sp.UUID); + "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID); if (eq != null) @@ -745,7 +745,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "http://" + neighbourRegion.ExternalHostName + ":" + neighbourRegion.HttpPort + "/CAPS/" + agentcaps /*circuitdata.CapsPath*/ + "0000/"; - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new ENTITY TRANSFER MODULE seed url {0} to client {1}", capsPath, agent.UUID); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); IEventQueue eq = agent.Scene.RequestModuleInterface(); if (eq != null) @@ -1046,7 +1046,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer eq.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new ENTITY TRANSFER MODULE seed url {0} to client {1} in region {2}", + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1} in region {2}", capsPath, sp.UUID, sp.Scene.RegionInfo.RegionName); } else -- cgit v1.1 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. --- .../Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 25415af..827dafe 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1154,7 +1154,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion - #region Object Crossings + #region Object Transfers /// /// Move the given scene object into a new region depending on which region its absolute position has moved /// into. -- cgit v1.1 From f276ba57bf5bd732fbc6a255213c9bb7f5f5f148 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 17 Jan 2010 11:33:47 -0800 Subject: HG agent transfers are starting to work. Gatekeeper handlers are missing. --- .../EntityTransfer/EntityTransferModule.cs | 469 +++++++++++---------- 1 file changed, 240 insertions(+), 229 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 827dafe..d0171fe 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -61,7 +61,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer get { return null; } } - public string Name + public virtual string Name { get { return "BasicEntityTransferModule"; } } @@ -76,7 +76,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { m_agentsInTransit = new List(); m_Enabled = true; - m_log.InfoFormat("[ENTITY TRANSFER MODULE]: {0} nabled.", Name); + m_log.InfoFormat("[ENTITY TRANSFER MODULE]: {0} enabled.", Name); } } } @@ -135,296 +135,312 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Reset animations; the viewer does that in teleports. sp.Animator.ResetAnimations(); - if (regionHandle == sp.Scene.RegionInfo.RegionHandle) + try { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", - position, sp.Scene.RegionInfo.RegionName); - - // Teleport within the same region - if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) - { - Vector3 emergencyPos = new Vector3(128, 128, 128); - - m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", - position, sp.Name, sp.UUID, emergencyPos); - position = emergencyPos; - } - - // TODO: Get proper AVG Height - float localAVHeight = 1.56f; - float posZLimit = 22; - - // TODO: Check other Scene HeightField - if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) + if (regionHandle == sp.Scene.RegionInfo.RegionHandle) { - posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; - } - - float newPosZ = posZLimit + localAVHeight; - if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) - { - position.Z = newPosZ; - } + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation {0} within {1}", + position, sp.Scene.RegionInfo.RegionName); - // Only send this if the event queue is null - if (eq == null) - sp.ControllingClient.SendTeleportLocationStart(); + // Teleport within the same region + if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) + { + Vector3 emergencyPos = new Vector3(128, 128, 128); - sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); - sp.Teleport(position); - } - else - { - uint x = 0, y = 0; - Utils.LongToUInts(regionHandle, out x, out y); - GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation() was given an illegal position of {0} for avatar {1}, {2}. Substituting {3}", + position, sp.Name, sp.UUID, emergencyPos); + position = emergencyPos; + } - if (reg != null) - { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation to {0} in {1}", - position, reg.RegionName); + // TODO: Get proper AVG Height + float localAVHeight = 1.56f; + float posZLimit = 22; - uint newRegionX = (uint)(reg.RegionHandle >> 40); - uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); - uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); - uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8); + // TODO: Check other Scene HeightField + if (position.X > 0 && position.X <= (int)Constants.RegionSize && position.Y > 0 && position.Y <= (int)Constants.RegionSize) + { + posZLimit = (float)sp.Scene.Heightmap[(int)position.X, (int)position.Y]; + } - ulong destinationHandle = GetRegionHandle(reg); - GridRegion finalDestination = GetFinalDestination(reg); + float newPosZ = posZLimit + localAVHeight; + if (posZLimit >= (position.Z - (localAVHeight / 2)) && !(Single.IsInfinity(newPosZ) || Single.IsNaN(newPosZ))) + { + position.Z = newPosZ; + } + // Only send this if the event queue is null if (eq == null) sp.ControllingClient.SendTeleportLocationStart(); - // Let's do DNS resolution only once in this process, please! - // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, - // it's actually doing a lot of work. - IPEndPoint endPoint = reg.ExternalEndPoint; - if (endPoint.Address == null) - { - // Couldn't resolve the name. Can't TP, because the viewer wants IP addresses. - destRegionUp = false; - } + sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); + sp.Teleport(position); + } + else + { + uint x = 0, y = 0; + Utils.LongToUInts(regionHandle, out x, out y); + GridRegion reg = m_aScene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); - if (destRegionUp) + if (reg != null) { - // Fixing a bug where teleporting while sitting results in the avatar ending up removed from - // both regions - if (sp.ParentID != (uint)0) - sp.StandUp(); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation to {0} in {1}", + position, reg.RegionName); + + uint newRegionX = (uint)(reg.RegionHandle >> 40); + uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); + uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); + uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8); - if (!sp.ValidateAttachments()) + GridRegion finalDestination = GetFinalDestination(reg); + if (finalDestination == null) { - sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is having problems. Unable to teleport agent."); + sp.ControllingClient.SendTeleportFailed("Problem at destination"); return; } + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is x={0} y={1} uuid={2}", finalDestination.RegionLocX, finalDestination.RegionLocY, finalDestination.RegionID); + ulong destinationHandle = finalDestination.RegionHandle; - // the avatar.Close below will clear the child region list. We need this below for (possibly) - // closing the child agents, so save it here (we need a copy as it is Clear()-ed). - //List childRegions = new List(avatar.GetKnownRegionList()); - // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport - // failure at this point (unlike a border crossing failure). So perhaps this can never fail - // once we reach here... - //avatar.Scene.RemoveCapsHandler(avatar.UUID); - - string capsPath = String.Empty; - AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); - agentCircuit.BaseFolder = UUID.Zero; - agentCircuit.InventoryFolder = UUID.Zero; - agentCircuit.startpos = position; - agentCircuit.child = true; - agentCircuit.Appearance = sp.Appearance; - - if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) + if (eq == null) + sp.ControllingClient.SendTeleportLocationStart(); + + // Let's do DNS resolution only once in this process, please! + // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, + // it's actually doing a lot of work. + IPEndPoint endPoint = finalDestination.ExternalEndPoint; + if (endPoint.Address == null) { - // brand new agent, let's create a new caps seed - agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); + // Couldn't resolve the name. Can't TP, because the viewer wants IP addresses. + destRegionUp = false; } - string reason = String.Empty; - - // Let's create an agent there if one doesn't exist yet. - if (!m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason)) + if (destRegionUp) { - sp.ControllingClient.SendTeleportFailed(String.Format("Destination is not accepting teleports: {0}", - reason)); - return; - } + // Fixing a bug where teleporting while sitting results in the avatar ending up removed from + // both regions + if (sp.ParentID != (uint)0) + sp.StandUp(); - // OK, it got this agent. Let's close some child agents - sp.CloseChildAgents(newRegionX, newRegionY); + if (!sp.ValidateAttachments()) + { + sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); + return; + } - if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) - { - #region IP Translation for NAT - IClientIPEndpoint ipepClient; - if (sp.ClientView.TryGet(out ipepClient)) + // the avatar.Close below will clear the child region list. We need this below for (possibly) + // closing the child agents, so save it here (we need a copy as it is Clear()-ed). + //List childRegions = new List(avatar.GetKnownRegionList()); + // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport + // failure at this point (unlike a border crossing failure). So perhaps this can never fail + // once we reach here... + //avatar.Scene.RemoveCapsHandler(avatar.UUID); + + string capsPath = String.Empty; + AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); + agentCircuit.BaseFolder = UUID.Zero; + agentCircuit.InventoryFolder = UUID.Zero; + agentCircuit.startpos = position; + agentCircuit.child = true; + agentCircuit.Appearance = sp.Appearance; + + if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) { - capsPath - = "http://" - + NetworkUtil.GetHostFor(ipepClient.EndPoint, reg.ExternalHostName) - + ":" - + reg.HttpPort - + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + // brand new agent, let's create a new caps seed + agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); } - else + + string reason = String.Empty; + + // Let's create an agent there if one doesn't exist yet. + if (!m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason)) { - capsPath - = "http://" - + reg.ExternalHostName - + ":" - + reg.HttpPort - + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + sp.ControllingClient.SendTeleportFailed(String.Format("Destination is not accepting teleports: {0}", + reason)); + return; } - #endregion - if (eq != null) + // OK, it got this agent. Let's close some child agents + sp.CloseChildAgents(newRegionX, newRegionY); + + if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) { #region IP Translation for NAT - // Uses ipepClient above + IClientIPEndpoint ipepClient; if (sp.ClientView.TryGet(out ipepClient)) { - endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + capsPath + = "http://" + + NetworkUtil.GetHostFor(ipepClient.EndPoint, finalDestination.ExternalHostName) + + ":" + + finalDestination.HttpPort + + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + } + else + { + capsPath + = "http://" + + finalDestination.ExternalHostName + + ":" + + finalDestination.HttpPort + + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); } #endregion - eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); + if (eq != null) + { + #region IP Translation for NAT + // Uses ipepClient above + if (sp.ClientView.TryGet(out ipepClient)) + { + endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + } + #endregion + + eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); - // ES makes the client send a UseCircuitCode message to the destination, - // which triggers a bunch of things there. - // So let's wait - Thread.Sleep(2000); + // ES makes the client send a UseCircuitCode message to the destination, + // which triggers a bunch of things there. + // So let's wait + Thread.Sleep(2000); - eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + } + else + { + sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); + } } else { - sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); + agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); + capsPath = "http://" + finalDestination.ExternalHostName + ":" + finalDestination.HttpPort + + "/CAPS/" + agentCircuit.CapsPath + "0000/"; } - } - else - { - agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); - capsPath = "http://" + reg.ExternalHostName + ":" + reg.HttpPort - + "/CAPS/" + agentCircuit.CapsPath + "0000/"; - } - - // Expect avatar crossing is a heavy-duty function at the destination. - // That is where MakeRoot is called, which fetches appearance and inventory. - // Plus triggers OnMakeRoot, which spawns a series of asynchronous updates. - //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, - // position, false); - - //{ - // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); - // // We should close that agent we just created over at destination... - // List lst = new List(); - // lst.Add(reg.RegionHandle); - // SendCloseChildAgentAsync(avatar.UUID, lst); - // return; - //} - SetInTransit(sp.UUID); + // Expect avatar crossing is a heavy-duty function at the destination. + // That is where MakeRoot is called, which fetches appearance and inventory. + // Plus triggers OnMakeRoot, which spawns a series of asynchronous updates. + //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, + // position, false); + + //{ + // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); + // // We should close that agent we just created over at destination... + // List lst = new List(); + // lst.Add(reg.RegionHandle); + // SendCloseChildAgentAsync(avatar.UUID, lst); + // return; + //} + + SetInTransit(sp.UUID); + + // Let's send a full update of the agent. This is a synchronous call. + AgentData agent = new AgentData(); + sp.CopyTo(agent); + agent.Position = position; + agent.CallbackURI = "http://" + sp.Scene.RegionInfo.ExternalHostName + ":" + sp.Scene.RegionInfo.HttpPort + + "/agent/" + sp.UUID.ToString() + "/" + sp.Scene.RegionInfo.RegionID.ToString() + "/release/"; + + // Straight to the region. Safe. + m_aScene.SimulationService.UpdateAgent(reg, agent); - // Let's send a full update of the agent. This is a synchronous call. - AgentData agent = new AgentData(); - sp.CopyTo(agent); - agent.Position = position; - agent.CallbackURI = "http://" + sp.Scene.RegionInfo.ExternalHostName + ":" + sp.Scene.RegionInfo.HttpPort + - "/agent/" + sp.UUID.ToString() + "/" + sp.Scene.RegionInfo.RegionID.ToString() + "/release/"; + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID); - m_aScene.SimulationService.UpdateAgent(reg, agent); - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID); + if (eq != null) + { + eq.TeleportFinishEvent(destinationHandle, 13, endPoint, + 0, teleportFlags, capsPath, sp.UUID); + } + else + { + sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, + teleportFlags, capsPath); + } + // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which + // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation + // that the client contacted the destination before we send the attachments and close things here. + if (!WaitForCallback(sp.UUID)) + { + // Client never contacted destination. Let's restore everything back + sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); - if (eq != null) - { - eq.TeleportFinishEvent(destinationHandle, 13, endPoint, - 0, teleportFlags, capsPath, sp.UUID); - } - else - { - sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, - teleportFlags, capsPath); - } + ResetFromTransit(sp.UUID); - // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which - // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation - // that the client contacted the destination before we send the attachments and close things here. - if (!WaitForCallback(sp.UUID)) - { - // Client never contacted destination. Let's restore everything back - sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); + // Yikes! We should just have a ref to scene here. + //sp.Scene.InformClientOfNeighbours(sp); + EnableChildAgents(sp); - ResetFromTransit(sp.UUID); + // Finally, kill the agent we just created at the destination. + m_aScene.SimulationService.CloseAgent(reg, sp.UUID); - // Yikes! We should just have a ref to scene here. - //sp.Scene.InformClientOfNeighbours(sp); - EnableChildAgents(sp); + return; + } - // Finally, kill the agent we just created at the destination. - m_aScene.SimulationService.CloseAgent(reg, sp.UUID); + KillEntity(sp.Scene, sp.LocalId); - return; - } + sp.MakeChildAgent(); - KillEntity(sp.Scene, sp.LocalId); + // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it + CrossAttachmentsIntoNewRegion(reg, sp, true); - sp.MakeChildAgent(); + // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone - // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it - CrossAttachmentsIntoNewRegion(reg, sp, true); + if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) + { + Thread.Sleep(5000); + sp.Close(); + sp.Scene.IncomingCloseAgent(sp.UUID); + } + else + // now we have a child agent in this region. + sp.Reset(); - // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone - if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) - { - Thread.Sleep(5000); - sp.Close(); - sp.Scene.IncomingCloseAgent(sp.UUID); + // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! + if (sp.Scene.NeedSceneCacheClear(sp.UUID)) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", + sp.UUID); + } } else - // now we have a child agent in this region. - sp.Reset(); - - - // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! - if (sp.Scene.NeedSceneCacheClear(sp.UUID)) { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", - sp.UUID); + sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); } } else { - sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); + // TP to a place that doesn't exist (anymore) + // Inform the viewer about that + sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); + + // and set the map-tile to '(Offline)' + uint regX, regY; + Utils.LongToUInts(regionHandle, out regX, out regY); + + MapBlockData block = new MapBlockData(); + block.X = (ushort)(regX / Constants.RegionSize); + block.Y = (ushort)(regY / Constants.RegionSize); + block.Access = 254; // == not there + + List blocks = new List(); + blocks.Add(block); + sp.ControllingClient.SendMapBlock(blocks, 0); } } - else - { - // TP to a place that doesn't exist (anymore) - // Inform the viewer about that - sp.ControllingClient.SendTeleportFailed("The region you tried to teleport to doesn't exist anymore"); - - // and set the map-tile to '(Offline)' - uint regX, regY; - Utils.LongToUInts(regionHandle, out regX, out regY); - - MapBlockData block = new MapBlockData(); - block.X = (ushort)(regX / Constants.RegionSize); - block.Y = (ushort)(regY / Constants.RegionSize); - block.Access = 254; // == not there - - List blocks = new List(); - blocks.Add(block); - sp.ControllingClient.SendMapBlock(blocks, 0); - } + } + catch (Exception e) + { + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Exception on teleport: {0}\n{1}", e.Message, e.StackTrace); + sp.ControllingClient.SendTeleportFailed("Internal error"); } } @@ -433,11 +449,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer scene.SendKillObject(localID); } - protected virtual ulong GetRegionHandle(GridRegion region) - { - return region.RegionHandle; - } - protected virtual GridRegion GetFinalDestination(GridRegion region) { return region; -- cgit v1.1 From 5e034f5933fd23d6023167cdb24a141eac1f2e85 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 17 Jan 2010 11:35:27 -0800 Subject: Oops, forgot this one. --- .../EntityTransfer/HGEntityTransferModule.cs | 137 +++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs new file mode 100644 index 0000000..5d88311 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -0,0 +1,137 @@ +/* + * 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 OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Connectors.Hypergrid; +using OpenSim.Services.Interfaces; + +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +using OpenMetaverse; +using log4net; +using Nini.Config; + +namespace OpenSim.Region.CoreModules.Framework.EntityTransfer +{ + public class HGEntityTransferModule : EntityTransferModule, ISharedRegionModule, IEntityTransferModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private bool m_Enabled = false; + private IHypergridService m_HypergridService; + private IHypergridService HyperGridService + { + get + { + if (m_HypergridService == null) + m_HypergridService = m_aScene.RequestModuleInterface(); + return m_HypergridService; + } + } + + #region ISharedRegionModule + + public override string Name + { + get { return "HGEntityTransferModule"; } + } + + public override void Initialise(IConfigSource source) + { + IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) + { + string name = moduleConfig.GetString("EntityTransferModule", ""); + if (name == Name) + { + m_agentsInTransit = new List(); + m_Enabled = true; + m_log.InfoFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); + } + } + } + + public override void PostInitialise() + { + } + + public override void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + if (m_aScene == null) + m_aScene = scene; + + scene.RegisterModuleInterface(this); + } + + public override void Close() + { + if (!m_Enabled) + return; + } + + + public override void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + if (scene == m_aScene) + m_aScene = null; + } + + public override void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + } + + #endregion + + #region HG overrides + + protected override GridRegion GetFinalDestination(GridRegion region) + { + return HyperGridService.GetHyperlinkRegion(region, region.RegionID); + } + + protected override bool NeedsClosing(uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) + { + return true; + } + + + #endregion + } +} -- cgit v1.1 From b2e6ec9e12ad07eb08496ebe8ca0476b793017d5 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 17 Jan 2010 18:04:55 -0800 Subject: Agent gets there through the Gatekeeper, but still a few quirks to fix. --- .../EntityTransfer/EntityTransferModule.cs | 23 +++++++++++++----- .../EntityTransfer/HGEntityTransferModule.cs | 27 ++++++++++++++++++++++ 2 files changed, 44 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index d0171fe..8268bfa 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -239,12 +239,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer //avatar.Scene.RemoveCapsHandler(avatar.UUID); string capsPath = String.Empty; + + AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); - agentCircuit.BaseFolder = UUID.Zero; - agentCircuit.InventoryFolder = UUID.Zero; agentCircuit.startpos = position; agentCircuit.child = true; agentCircuit.Appearance = sp.Appearance; + if (currentAgentCircuit != null) + agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) { @@ -255,9 +257,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer string reason = String.Empty; // Let's create an agent there if one doesn't exist yet. - if (!m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason)) + if (!CreateAgent(reg, finalDestination, agentCircuit, teleportFlags, out reason)) { - sp.ControllingClient.SendTeleportFailed(String.Format("Destination is not accepting teleports: {0}", + sp.ControllingClient.SendTeleportFailed(String.Format("Destination refused: {0}", reason)); return; } @@ -345,8 +347,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.CallbackURI = "http://" + sp.Scene.RegionInfo.ExternalHostName + ":" + sp.Scene.RegionInfo.HttpPort + "/agent/" + sp.UUID.ToString() + "/" + sp.Scene.RegionInfo.RegionID.ToString() + "/release/"; - // Straight to the region. Safe. - m_aScene.SimulationService.UpdateAgent(reg, agent); + UpdateAgent(reg, finalDestination, agent); m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID); @@ -444,6 +445,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } } + protected virtual bool CreateAgent(GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason) + { + return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); + } + + protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) + { + return m_aScene.SimulationService.UpdateAgent(reg, agent); + } + protected void KillEntity(Scene scene, uint localID) { scene.SendKillObject(localID); diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 5d88311..e5a862d 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -29,6 +29,7 @@ using System; using System.Collections.Generic; using System.Reflection; +using OpenSim.Framework; using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Connectors.Hypergrid; @@ -58,6 +59,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } } + private GatekeeperServiceConnector m_GatekeeperConnector; + #region ISharedRegionModule public override string Name @@ -74,6 +77,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (name == Name) { m_agentsInTransit = new List(); + m_GatekeeperConnector = new GatekeeperServiceConnector(); m_Enabled = true; m_log.InfoFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); } @@ -131,6 +135,29 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return true; } + protected override bool CreateAgent(GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason) + { + reason = string.Empty; + if (reg.RegionLocX != finalDestination.RegionLocX && reg.RegionLocY != finalDestination.RegionLocY) + { + // this user is going to another grid + reg.RegionName = finalDestination.RegionName; + return m_GatekeeperConnector.CreateAgent(reg, agentCircuit, teleportFlags, out reason); + } + + return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); + } + + protected override bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) + { + if (reg.RegionLocX != finalDestination.RegionLocX && reg.RegionLocY != finalDestination.RegionLocY) + { + // this user is going to another grid + return m_GatekeeperConnector.UpdateAgent(reg, agent); + } + + return m_aScene.SimulationService.UpdateAgent(reg, agent); + } #endregion } -- cgit v1.1 From b5fcb5e872ec138ff7138906bffae193b6dae1a6 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 17 Jan 2010 20:10:42 -0800 Subject: HG teleports through gatekeeper are working. --- .../Framework/EntityTransfer/EntityTransferModule.cs | 18 ++++++++++++------ .../Framework/EntityTransfer/HGEntityTransferModule.cs | 11 ----------- 2 files changed, 12 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 8268bfa..622d057 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -344,8 +344,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer AgentData agent = new AgentData(); sp.CopyTo(agent); agent.Position = position; - agent.CallbackURI = "http://" + sp.Scene.RegionInfo.ExternalHostName + ":" + sp.Scene.RegionInfo.HttpPort + - "/agent/" + sp.UUID.ToString() + "/" + sp.Scene.RegionInfo.RegionID.ToString() + "/release/"; + SetCallbackURL(agent, sp.Scene.RegionInfo); UpdateAgent(reg, finalDestination, agent); @@ -379,7 +378,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer EnableChildAgents(sp); // Finally, kill the agent we just created at the destination. - m_aScene.SimulationService.CloseAgent(reg, sp.UUID); + m_aScene.SimulationService.CloseAgent(finalDestination, sp.UUID); return; } @@ -389,7 +388,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.MakeChildAgent(); // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it - CrossAttachmentsIntoNewRegion(reg, sp, true); + CrossAttachmentsIntoNewRegion(finalDestination, sp, true); // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone @@ -447,12 +446,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual bool CreateAgent(GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason) { - return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); + return m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); } protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) { - return m_aScene.SimulationService.UpdateAgent(reg, agent); + return m_aScene.SimulationService.UpdateAgent(finalDestination, agent); + } + + protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) + { + agent.CallbackURI = "http://" + region.ExternalHostName + ":" + region.HttpPort + + "/agent/" + agent.AgentID.ToString() + "/" + region.RegionID.ToString() + "/release/"; + } protected void KillEntity(Scene scene, uint localID) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index e5a862d..6645293 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -148,17 +148,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); } - protected override bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) - { - if (reg.RegionLocX != finalDestination.RegionLocX && reg.RegionLocY != finalDestination.RegionLocY) - { - // this user is going to another grid - return m_GatekeeperConnector.UpdateAgent(reg, agent); - } - - return m_aScene.SimulationService.UpdateAgent(reg, agent); - } - #endregion } } -- cgit v1.1 From bbbe9e73cca2a0ed5d35db1b054b8ed4cd23bfea Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 18 Jan 2010 09:14:19 -0800 Subject: * Fixed misspelling of field in GridService * Moved TeleportClientHome to EntityTransferModule --- .../EntityTransfer/EntityTransferModule.cs | 35 +++++++++++++++++++- .../EntityTransfer/HGEntityTransferModule.cs | 37 ---------------------- 2 files changed, 34 insertions(+), 38 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 622d057..fcc7a85 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -50,7 +50,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private bool m_Enabled = false; + protected bool m_Enabled = false; protected Scene m_aScene; protected List m_agentsInTransit; @@ -94,6 +94,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_aScene = scene; scene.RegisterModuleInterface(this); + scene.EventManager.OnNewClient += OnNewClient; + } + + protected void OnNewClient(IClientAPI client) + { + client.OnTeleportHomeRequest += TeleportHome; } public virtual void Close() @@ -499,6 +505,33 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion + #region Teleport Home + + public virtual void TeleportHome(UUID id, IClientAPI client) + { + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.FirstName, client.LastName); + + OpenSim.Services.Interfaces.PresenceInfo pinfo = m_aScene.PresenceService.GetAgent(client.SessionId); + + if (pinfo != null) + { + GridRegion regionInfo = m_aScene.GridService.GetRegionByUUID(UUID.Zero, pinfo.HomeRegionID); + if (regionInfo == null) + { + // can't find the Home region: Tell viewer and abort + client.SendTeleportFailed("Your home region could not be found."); + return; + } + // a little eekie that this goes back to Scene and with a forced cast, will fix that at some point... + ((Scene)(client.Scene)).RequestTeleportLocation( + client, regionInfo.RegionHandle, pinfo.HomePosition, pinfo.HomeLookAt, + (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome)); + } + } + + #endregion + + #region Agent Crossings public void Cross(ScenePresence agent, bool isFlying) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 6645293..101aea0 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -47,7 +47,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private bool m_Enabled = false; private IHypergridService m_HypergridService; private IHypergridService HyperGridService { @@ -84,42 +83,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } } - public override void PostInitialise() - { - } - - public override void AddRegion(Scene scene) - { - if (!m_Enabled) - return; - - if (m_aScene == null) - m_aScene = scene; - - scene.RegisterModuleInterface(this); - } - - public override void Close() - { - if (!m_Enabled) - return; - } - - - public override void RemoveRegion(Scene scene) - { - if (!m_Enabled) - return; - if (scene == m_aScene) - m_aScene = null; - } - - public override void RegionLoaded(Scene scene) - { - if (!m_Enabled) - return; - - } #endregion -- cgit v1.1 From fd64823466ee667d0d827f95d3001ec8675512b2 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 18 Jan 2010 10:37:11 -0800 Subject: * Added missing GatekeeperServiceConnector * Added basic machinery for teleporting users home. Untested. --- .../EntityTransfer/EntityTransferModule.cs | 456 +++++++++++---------- .../EntityTransfer/HGEntityTransferModule.cs | 49 +++ 2 files changed, 281 insertions(+), 224 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index fcc7a85..e85f270 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -183,7 +183,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); sp.Teleport(position); } - else + else // Another region possibly in another simulator { uint x = 0, y = 0; Utils.LongToUInts(regionHandle, out x, out y); @@ -191,15 +191,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (reg != null) { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation to {0} in {1}", - position, reg.RegionName); - - uint newRegionX = (uint)(reg.RegionHandle >> 40); - uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); - uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); - uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8); - GridRegion finalDestination = GetFinalDestination(reg); if (finalDestination == null) { @@ -207,220 +198,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.ControllingClient.SendTeleportFailed("Problem at destination"); return; } - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is x={0} y={1} uuid={2}", finalDestination.RegionLocX, finalDestination.RegionLocY, finalDestination.RegionID); - ulong destinationHandle = finalDestination.RegionHandle; - - if (eq == null) - sp.ControllingClient.SendTeleportLocationStart(); - - // Let's do DNS resolution only once in this process, please! - // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, - // it's actually doing a lot of work. - IPEndPoint endPoint = finalDestination.ExternalEndPoint; - if (endPoint.Address == null) - { - // Couldn't resolve the name. Can't TP, because the viewer wants IP addresses. - destRegionUp = false; - } - - if (destRegionUp) - { - // Fixing a bug where teleporting while sitting results in the avatar ending up removed from - // both regions - if (sp.ParentID != (uint)0) - sp.StandUp(); - - if (!sp.ValidateAttachments()) - { - sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); - return; - } - - // the avatar.Close below will clear the child region list. We need this below for (possibly) - // closing the child agents, so save it here (we need a copy as it is Clear()-ed). - //List childRegions = new List(avatar.GetKnownRegionList()); - // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport - // failure at this point (unlike a border crossing failure). So perhaps this can never fail - // once we reach here... - //avatar.Scene.RemoveCapsHandler(avatar.UUID); - - string capsPath = String.Empty; - - AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); - AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); - agentCircuit.startpos = position; - agentCircuit.child = true; - agentCircuit.Appearance = sp.Appearance; - if (currentAgentCircuit != null) - agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; - - if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) - { - // brand new agent, let's create a new caps seed - agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); - } - - string reason = String.Empty; - - // Let's create an agent there if one doesn't exist yet. - if (!CreateAgent(reg, finalDestination, agentCircuit, teleportFlags, out reason)) - { - sp.ControllingClient.SendTeleportFailed(String.Format("Destination refused: {0}", - reason)); - return; - } - - // OK, it got this agent. Let's close some child agents - sp.CloseChildAgents(newRegionX, newRegionY); - - if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) - { - #region IP Translation for NAT - IClientIPEndpoint ipepClient; - if (sp.ClientView.TryGet(out ipepClient)) - { - capsPath - = "http://" - + NetworkUtil.GetHostFor(ipepClient.EndPoint, finalDestination.ExternalHostName) - + ":" - + finalDestination.HttpPort - + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); - } - else - { - capsPath - = "http://" - + finalDestination.ExternalHostName - + ":" - + finalDestination.HttpPort - + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); - } - #endregion - - if (eq != null) - { - #region IP Translation for NAT - // Uses ipepClient above - if (sp.ClientView.TryGet(out ipepClient)) - { - endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); - } - #endregion - - eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); - - // ES makes the client send a UseCircuitCode message to the destination, - // which triggers a bunch of things there. - // So let's wait - Thread.Sleep(2000); - - eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); - - } - else - { - sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); - } - } - else - { - agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); - capsPath = "http://" + finalDestination.ExternalHostName + ":" + finalDestination.HttpPort - + "/CAPS/" + agentCircuit.CapsPath + "0000/"; - } - - // Expect avatar crossing is a heavy-duty function at the destination. - // That is where MakeRoot is called, which fetches appearance and inventory. - // Plus triggers OnMakeRoot, which spawns a series of asynchronous updates. - //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, - // position, false); - - //{ - // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); - // // We should close that agent we just created over at destination... - // List lst = new List(); - // lst.Add(reg.RegionHandle); - // SendCloseChildAgentAsync(avatar.UUID, lst); - // return; - //} - - SetInTransit(sp.UUID); - - // Let's send a full update of the agent. This is a synchronous call. - AgentData agent = new AgentData(); - sp.CopyTo(agent); - agent.Position = position; - SetCallbackURL(agent, sp.Scene.RegionInfo); - - UpdateAgent(reg, finalDestination, agent); - - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID); - - - if (eq != null) - { - eq.TeleportFinishEvent(destinationHandle, 13, endPoint, - 0, teleportFlags, capsPath, sp.UUID); - } - else - { - sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, - teleportFlags, capsPath); - } - - // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which - // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation - // that the client contacted the destination before we send the attachments and close things here. - if (!WaitForCallback(sp.UUID)) - { - // Client never contacted destination. Let's restore everything back - sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); - - ResetFromTransit(sp.UUID); - - // Yikes! We should just have a ref to scene here. - //sp.Scene.InformClientOfNeighbours(sp); - EnableChildAgents(sp); - - // Finally, kill the agent we just created at the destination. - m_aScene.SimulationService.CloseAgent(finalDestination, sp.UUID); - - return; - } - - KillEntity(sp.Scene, sp.LocalId); - - sp.MakeChildAgent(); - - // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it - CrossAttachmentsIntoNewRegion(finalDestination, sp, true); - - // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone - - if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) - { - Thread.Sleep(5000); - sp.Close(); - sp.Scene.IncomingCloseAgent(sp.UUID); - } - else - // now we have a child agent in this region. - sp.Reset(); - - - // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! - if (sp.Scene.NeedSceneCacheClear(sp.UUID)) - { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", - sp.UUID); - } - } - else - { - sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); - } + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Final destination is x={0} y={1} uuid={2}", + finalDestination.RegionLocX / Constants.RegionSize, finalDestination.RegionLocY / Constants.RegionSize, finalDestination.RegionID); + + // + // This is it + // + DoTeleport(sp, reg, finalDestination, position, lookAt, teleportFlags, eq); + // + // + // } else { @@ -450,6 +237,227 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } } + protected void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation to {0} in {1}", + position, reg.RegionName); + + uint newRegionX = (uint)(reg.RegionHandle >> 40); + uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); + uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); + uint oldRegionY = (((uint)(sp.Scene.RegionInfo.RegionHandle)) >> 8); + + ulong destinationHandle = finalDestination.RegionHandle; + + if (eq == null) + sp.ControllingClient.SendTeleportLocationStart(); + + // Let's do DNS resolution only once in this process, please! + // This may be a costly operation. The reg.ExternalEndPoint field is not a passive field, + // it's actually doing a lot of work. + IPEndPoint endPoint = finalDestination.ExternalEndPoint; + if (endPoint.Address != null) + { + // Fixing a bug where teleporting while sitting results in the avatar ending up removed from + // both regions + if (sp.ParentID != (uint)0) + sp.StandUp(); + + if (!sp.ValidateAttachments()) + { + sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); + return; + } + + // the avatar.Close below will clear the child region list. We need this below for (possibly) + // closing the child agents, so save it here (we need a copy as it is Clear()-ed). + //List childRegions = new List(avatar.GetKnownRegionList()); + // Compared to ScenePresence.CrossToNewRegion(), there's no obvious code to handle a teleport + // failure at this point (unlike a border crossing failure). So perhaps this can never fail + // once we reach here... + //avatar.Scene.RemoveCapsHandler(avatar.UUID); + + string capsPath = String.Empty; + + AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); + AgentCircuitData agentCircuit = sp.ControllingClient.RequestClientInfo(); + agentCircuit.startpos = position; + agentCircuit.child = true; + agentCircuit.Appearance = sp.Appearance; + if (currentAgentCircuit != null) + agentCircuit.ServiceURLs = currentAgentCircuit.ServiceURLs; + + if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) + { + // brand new agent, let's create a new caps seed + agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); + } + + string reason = String.Empty; + + // Let's create an agent there if one doesn't exist yet. + if (!CreateAgent(reg, finalDestination, agentCircuit, teleportFlags, out reason)) + { + sp.ControllingClient.SendTeleportFailed(String.Format("Destination refused: {0}", + reason)); + return; + } + + // OK, it got this agent. Let's close some child agents + sp.CloseChildAgents(newRegionX, newRegionY); + + if (NeedsNewAgent(oldRegionX, newRegionX, oldRegionY, newRegionY)) + { + #region IP Translation for NAT + IClientIPEndpoint ipepClient; + if (sp.ClientView.TryGet(out ipepClient)) + { + capsPath + = "http://" + + NetworkUtil.GetHostFor(ipepClient.EndPoint, finalDestination.ExternalHostName) + + ":" + + finalDestination.HttpPort + + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + } + else + { + capsPath + = "http://" + + finalDestination.ExternalHostName + + ":" + + finalDestination.HttpPort + + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + } + #endregion + + if (eq != null) + { + #region IP Translation for NAT + // Uses ipepClient above + if (sp.ClientView.TryGet(out ipepClient)) + { + endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + } + #endregion + + eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); + + // ES makes the client send a UseCircuitCode message to the destination, + // which triggers a bunch of things there. + // So let's wait + Thread.Sleep(2000); + + eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + + } + else + { + sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); + } + } + else + { + agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); + capsPath = "http://" + finalDestination.ExternalHostName + ":" + finalDestination.HttpPort + + "/CAPS/" + agentCircuit.CapsPath + "0000/"; + } + + // Expect avatar crossing is a heavy-duty function at the destination. + // That is where MakeRoot is called, which fetches appearance and inventory. + // Plus triggers OnMakeRoot, which spawns a series of asynchronous updates. + //m_commsProvider.InterRegion.ExpectAvatarCrossing(reg.RegionHandle, avatar.ControllingClient.AgentId, + // position, false); + + //{ + // avatar.ControllingClient.SendTeleportFailed("Problem with destination."); + // // We should close that agent we just created over at destination... + // List lst = new List(); + // lst.Add(reg.RegionHandle); + // SendCloseChildAgentAsync(avatar.UUID, lst); + // return; + //} + + SetInTransit(sp.UUID); + + // Let's send a full update of the agent. This is a synchronous call. + AgentData agent = new AgentData(); + sp.CopyTo(agent); + agent.Position = position; + SetCallbackURL(agent, sp.Scene.RegionInfo); + + UpdateAgent(reg, finalDestination, agent); + + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, sp.UUID); + + + if (eq != null) + { + eq.TeleportFinishEvent(destinationHandle, 13, endPoint, + 0, teleportFlags, capsPath, sp.UUID); + } + else + { + sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, + teleportFlags, capsPath); + } + + // TeleportFinish makes the client send CompleteMovementIntoRegion (at the destination), which + // trigers a whole shebang of things there, including MakeRoot. So let's wait for confirmation + // that the client contacted the destination before we send the attachments and close things here. + if (!WaitForCallback(sp.UUID)) + { + // Client never contacted destination. Let's restore everything back + sp.ControllingClient.SendTeleportFailed("Problems connecting to destination."); + + ResetFromTransit(sp.UUID); + + // Yikes! We should just have a ref to scene here. + //sp.Scene.InformClientOfNeighbours(sp); + EnableChildAgents(sp); + + // Finally, kill the agent we just created at the destination. + m_aScene.SimulationService.CloseAgent(finalDestination, sp.UUID); + + return; + } + + KillEntity(sp.Scene, sp.LocalId); + + sp.MakeChildAgent(); + + // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it + CrossAttachmentsIntoNewRegion(finalDestination, sp, true); + + // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone + + if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) + { + Thread.Sleep(5000); + sp.Close(); + sp.Scene.IncomingCloseAgent(sp.UUID); + } + else + // now we have a child agent in this region. + sp.Reset(); + + + // REFACTORING PROBLEM. Well, not a problem, but this method is HORRIBLE! + if (sp.Scene.NeedSceneCacheClear(sp.UUID)) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", + sp.UUID); + } + } + else + { + sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); + } + } + + protected virtual bool CreateAgent(GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason) { return m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 101aea0..0e6323b 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -111,6 +111,55 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); } + public override void TeleportHome(UUID id, IClientAPI client) + { + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.FirstName, client.LastName); + + // Let's find out if this is a foreign user or a local user + UserAccount account = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, id); + if (account != null) + { + // local grid user + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: User is local"); + base.TeleportHome(id, client); + return; + } + + // Foreign user wants to go home + // + AgentCircuitData aCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); + if (aCircuit == null || (aCircuit != null && !aCircuit.ServiceURLs.ContainsKey("GatewayURI"))) + { + client.SendTeleportFailed("Your information has been lost"); + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information"); + return; + } + + GridRegion homeGatekeeper = MakeRegion(aCircuit); + if (homeGatekeeper == null) + { + client.SendTeleportFailed("Your information has been lost"); + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's gateway information is malformed"); + return; + } + + Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY; + GridRegion finalDestination = m_GatekeeperConnector.GetHomeRegion(homeGatekeeper, aCircuit.AgentID, out position, out lookAt); + } #endregion + + private GridRegion MakeRegion(AgentCircuitData aCircuit) + { + GridRegion region = new GridRegion(); + + Uri uri = null; + if (!Uri.TryCreate(aCircuit.ServiceURLs["GatewayURI"].ToString(), UriKind.Absolute, out uri)) + return null; + + region.ExternalHostName = uri.Host; + region.HttpPort = (uint)uri.Port; + region.RegionName = string.Empty; + return region; + } } } -- cgit v1.1 From 3d536944153d4931cf891d6a788a47484f3e6f4d Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Mon, 18 Jan 2010 16:34:23 -0800 Subject: Go Home works. With security!! --- .../EntityTransfer/EntityTransferModule.cs | 10 ++-- .../EntityTransfer/HGEntityTransferModule.cs | 69 +++++++++++++++++++++- 2 files changed, 71 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index e85f270..ed8c0fd 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -134,8 +134,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!sp.Scene.Permissions.CanTeleport(sp.UUID)) return; - bool destRegionUp = true; - IEventQueue eq = sp.Scene.RequestModuleInterface(); // Reset animations; the viewer does that in teleports. @@ -240,8 +238,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq) { m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: RequestTeleportToLocation to {0} in {1}", - position, reg.RegionName); + "[ENTITY TRANSFER MODULE]: Request Teleport to {0}:{1}:{2}/{3} final destination {4}", + reg.ExternalHostName, reg.HttpPort, reg.RegionName, position, finalDestination.RegionName); uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); @@ -297,7 +295,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer string reason = String.Empty; // Let's create an agent there if one doesn't exist yet. - if (!CreateAgent(reg, finalDestination, agentCircuit, teleportFlags, out reason)) + if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason)) { sp.ControllingClient.SendTeleportFailed(String.Format("Destination refused: {0}", reason)); @@ -458,7 +456,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } - protected virtual bool CreateAgent(GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason) + protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason) { return m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); } diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 0e6323b..d39537d 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -34,6 +34,7 @@ using OpenSim.Region.Framework.Interfaces; using OpenSim.Region.Framework.Scenes; using OpenSim.Services.Connectors.Hypergrid; using OpenSim.Services.Interfaces; +using OpenSim.Server.Base; using GridRegion = OpenSim.Services.Interfaces.GridRegion; @@ -59,6 +60,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } private GatekeeperServiceConnector m_GatekeeperConnector; + private IHomeUsersSecurityService m_Security; #region ISharedRegionModule @@ -77,12 +79,42 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { m_agentsInTransit = new List(); m_GatekeeperConnector = new GatekeeperServiceConnector(); + + IConfig config = source.Configs["HGEntityTransferModule"]; + if (config != null) + { + string dll = config.GetString("HomeUsersSecurityService", string.Empty); + if (dll != string.Empty) + { + Object[] args = new Object[] { source }; + m_Security = ServerUtils.LoadPlugin(dll, args); + if (m_Security == null) + m_log.Debug("[HG ENTITY TRANSFER MODULE]: Unable to load Home Users Security service"); + else + m_log.Debug("[HG ENTITY TRANSFER MODULE]: Home Users Security service loaded"); + } + } + m_Enabled = true; m_log.InfoFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); } } } + public override void AddRegion(Scene scene) + { + base.AddRegion(scene); + if (m_Enabled) + scene.RegisterModuleInterface(m_Security); + } + + public override void RemoveRegion(Scene scene) + { + base.AddRegion(scene); + if (m_Enabled) + scene.UnregisterModuleInterface(m_Security); + } + #endregion @@ -98,13 +130,25 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return true; } - protected override bool CreateAgent(GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason) + protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason) { reason = string.Empty; - if (reg.RegionLocX != finalDestination.RegionLocX && reg.RegionLocY != finalDestination.RegionLocY) + if (reg.RegionLocX != finalDestination.RegionLocX || reg.RegionLocY != finalDestination.RegionLocY) { // this user is going to another grid reg.RegionName = finalDestination.RegionName; + reg.RegionID = finalDestination.RegionID; + reg.RegionLocX = finalDestination.RegionLocX; + reg.RegionLocY = finalDestination.RegionLocY; + + // Log their session and remote endpoint in the home users security service + IHomeUsersSecurityService security = sp.Scene.RequestModuleInterface(); + if (security != null) + security.SetEndPoint(sp.ControllingClient.SessionId, sp.ControllingClient.RemoteEndPoint); + + // Log them out of this grid + sp.Scene.PresenceService.LogoutAgent(agentCircuit.SessionID, sp.AbsolutePosition, sp.Lookat); + return m_GatekeeperConnector.CreateAgent(reg, agentCircuit, teleportFlags, out reason); } @@ -145,6 +189,26 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY; GridRegion finalDestination = m_GatekeeperConnector.GetHomeRegion(homeGatekeeper, aCircuit.AgentID, out position, out lookAt); + if (finalDestination == null) + { + client.SendTeleportFailed("Your home region could not be found"); + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's home region not found"); + return; + } + + ScenePresence sp = ((Scene)(client.Scene)).GetScenePresence(client.AgentId); + if (sp == null) + { + client.SendTeleportFailed("Internal error"); + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent not found in the scene where it is supposed to be"); + return; + } + + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}:{5}", + aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ExternalHostName, homeGatekeeper.HttpPort, homeGatekeeper.RegionName); + + IEventQueue eq = sp.Scene.RequestModuleInterface(); + DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq); } #endregion @@ -159,6 +223,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer region.ExternalHostName = uri.Host; region.HttpPort = (uint)uri.Port; region.RegionName = string.Empty; + region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0); return region; } } -- cgit v1.1 From 48b03c2c61a422c3ac9843892a2ae93b29a9f7b8 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 24 Jan 2010 14:30:48 -0800 Subject: Integrated the hyperlinking with the GridService. --- .../EntityTransfer/HGEntityTransferModule.cs | 45 +++++++++++++--------- 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index d39537d..e237ca2 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -48,16 +48,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private IHypergridService m_HypergridService; - private IHypergridService HyperGridService - { - get - { - if (m_HypergridService == null) - m_HypergridService = m_aScene.RequestModuleInterface(); - return m_HypergridService; - } - } + private bool m_Initialized = false; private GatekeeperServiceConnector m_GatekeeperConnector; private IHomeUsersSecurityService m_Security; @@ -78,7 +69,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (name == Name) { m_agentsInTransit = new List(); - m_GatekeeperConnector = new GatekeeperServiceConnector(); IConfig config = source.Configs["HGEntityTransferModule"]; if (config != null) @@ -108,6 +98,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer scene.RegisterModuleInterface(m_Security); } + public override void RegionLoaded(Scene scene) + { + base.RegionLoaded(scene); + if (m_Enabled) + if (!m_Initialized) + { + m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); + m_Initialized = true; + } + + } public override void RemoveRegion(Scene scene) { base.AddRegion(scene); @@ -122,7 +123,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected override GridRegion GetFinalDestination(GridRegion region) { - return HyperGridService.GetHyperlinkRegion(region, region.RegionID); + int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, region.RegionID); + if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) + { + return m_GatekeeperConnector.GetHyperlinkRegion(region, region.RegionID); + } + return region; } protected override bool NeedsClosing(uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) @@ -133,13 +139,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason) { reason = string.Empty; - if (reg.RegionLocX != finalDestination.RegionLocX || reg.RegionLocY != finalDestination.RegionLocY) + int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); + if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) { // this user is going to another grid - reg.RegionName = finalDestination.RegionName; - reg.RegionID = finalDestination.RegionID; - reg.RegionLocX = finalDestination.RegionLocX; - reg.RegionLocY = finalDestination.RegionLocY; + // Take the IP address + port of the gatekeeper (reg) plus the info of finalDestination + GridRegion region = new GridRegion(reg); + region.RegionName = finalDestination.RegionName; + region.RegionID = finalDestination.RegionID; + region.RegionLocX = finalDestination.RegionLocX; + region.RegionLocY = finalDestination.RegionLocY; // Log their session and remote endpoint in the home users security service IHomeUsersSecurityService security = sp.Scene.RequestModuleInterface(); @@ -149,7 +158,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Log them out of this grid sp.Scene.PresenceService.LogoutAgent(agentCircuit.SessionID, sp.AbsolutePosition, sp.Lookat); - return m_GatekeeperConnector.CreateAgent(reg, agentCircuit, teleportFlags, out reason); + return m_GatekeeperConnector.CreateAgent(region, agentCircuit, teleportFlags, out reason); } return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); -- cgit v1.1 From ea3d287f70d48eb2d3abf6eb1506bf64674874c5 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sun, 24 Jan 2010 15:04:41 -0800 Subject: Some method implementations were missing from LocalGridServiceConnector. --- .../CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index e237ca2..a1de57a 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -124,8 +124,10 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected override GridRegion GetFinalDestination(GridRegion region) { int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, region.RegionID); + //m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) { + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); return m_GatekeeperConnector.GetHyperlinkRegion(region, region.RegionID); } return region; -- cgit v1.1 From 7c00469cd210cfdda3dd835867469159d4c8b9d9 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 27 Jan 2010 08:00:29 -0800 Subject: Added ExternalName config on Gatekeeper. --- .../CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs | 1 + 1 file changed, 1 insertion(+) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index a1de57a..4d5844c 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -157,6 +157,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (security != null) security.SetEndPoint(sp.ControllingClient.SessionId, sp.ControllingClient.RemoteEndPoint); + //string token = sp.Scene.AuthenticationService.MakeToken(sp.UUID, reg.ExternalHostName + ":" + reg.HttpPort, 30); // Log them out of this grid sp.Scene.PresenceService.LogoutAgent(agentCircuit.SessionID, sp.AbsolutePosition, sp.Lookat); -- cgit v1.1 From 00f7d622cbc2c2e61d2efaacd8275da3f9821d8b Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Thu, 28 Jan 2010 19:19:42 -0800 Subject: HG 1.5 is in place. Tested in standalone only. --- .../EntityTransfer/EntityTransferModule.cs | 10 +- .../EntityTransfer/HGEntityTransferModule.cs | 112 +++++++++++---------- 2 files changed, 69 insertions(+), 53 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index ed8c0fd..44f1191 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -237,9 +237,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected void DoTeleport(ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags, IEventQueue eq) { + if (reg == null || finalDestination == null) + { + sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); + return; + } + m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Request Teleport to {0}:{1}:{2}/{3} final destination {4}", - reg.ExternalHostName, reg.HttpPort, reg.RegionName, position, finalDestination.RegionName); + "[ENTITY TRANSFER MODULE]: Request Teleport to {0}:{1}:{2}/{3}", + reg.ExternalHostName, reg.HttpPort, finalDestination.RegionName, position); uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 4d5844c..85c2742 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -44,14 +44,13 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { - public class HGEntityTransferModule : EntityTransferModule, ISharedRegionModule, IEntityTransferModule + public class HGEntityTransferModule : EntityTransferModule, ISharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private bool m_Initialized = false; private GatekeeperServiceConnector m_GatekeeperConnector; - private IHomeUsersSecurityService m_Security; #region ISharedRegionModule @@ -69,21 +68,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (name == Name) { m_agentsInTransit = new List(); - - IConfig config = source.Configs["HGEntityTransferModule"]; - if (config != null) - { - string dll = config.GetString("HomeUsersSecurityService", string.Empty); - if (dll != string.Empty) - { - Object[] args = new Object[] { source }; - m_Security = ServerUtils.LoadPlugin(dll, args); - if (m_Security == null) - m_log.Debug("[HG ENTITY TRANSFER MODULE]: Unable to load Home Users Security service"); - else - m_log.Debug("[HG ENTITY TRANSFER MODULE]: Home Users Security service loaded"); - } - } m_Enabled = true; m_log.InfoFormat("[HG ENTITY TRANSFER MODULE]: {0} enabled.", Name); @@ -95,7 +79,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { base.AddRegion(scene); if (m_Enabled) - scene.RegisterModuleInterface(m_Security); + { + scene.RegisterModuleInterface(this); + scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(OnNewClient); + } + } + + void OnNewClient(IClientAPI client) + { + client.OnLogout += new Action(OnLogout); } public override void RegionLoaded(Scene scene) @@ -113,13 +105,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { base.AddRegion(scene); if (m_Enabled) - scene.UnregisterModuleInterface(m_Security); + { + scene.UnregisterModuleInterface(this); + } } #endregion - #region HG overrides + #region HG overrides of IEntiryTransferModule protected override GridRegion GetFinalDestination(GridRegion region) { @@ -142,26 +136,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { reason = string.Empty; int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); - if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) + if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) { // this user is going to another grid - // Take the IP address + port of the gatekeeper (reg) plus the info of finalDestination - GridRegion region = new GridRegion(reg); - region.RegionName = finalDestination.RegionName; - region.RegionID = finalDestination.RegionID; - region.RegionLocX = finalDestination.RegionLocX; - region.RegionLocY = finalDestination.RegionLocY; - - // Log their session and remote endpoint in the home users security service - IHomeUsersSecurityService security = sp.Scene.RequestModuleInterface(); - if (security != null) - security.SetEndPoint(sp.ControllingClient.SessionId, sp.ControllingClient.RemoteEndPoint); - - //string token = sp.Scene.AuthenticationService.MakeToken(sp.UUID, reg.ExternalHostName + ":" + reg.HttpPort, 30); - // Log them out of this grid - sp.Scene.PresenceService.LogoutAgent(agentCircuit.SessionID, sp.AbsolutePosition, sp.Lookat); - - return m_GatekeeperConnector.CreateAgent(region, agentCircuit, teleportFlags, out reason); + string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString(); + IUserAgentService connector = new UserAgentServiceConnector(userAgentDriver); + bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason); + if (success) + // Log them out of this grid + m_aScene.PresenceService.LogoutAgent(agentCircuit.SessionID, sp.AbsolutePosition, sp.Lookat); + + return success; } return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); @@ -184,23 +169,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Foreign user wants to go home // AgentCircuitData aCircuit = ((Scene)(client.Scene)).AuthenticateHandler.GetAgentCircuitData(client.CircuitCode); - if (aCircuit == null || (aCircuit != null && !aCircuit.ServiceURLs.ContainsKey("GatewayURI"))) + if (aCircuit == null || (aCircuit != null && !aCircuit.ServiceURLs.ContainsKey("HomeURI"))) { client.SendTeleportFailed("Your information has been lost"); m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Unable to locate agent's gateway information"); return; } - GridRegion homeGatekeeper = MakeRegion(aCircuit); - if (homeGatekeeper == null) - { - client.SendTeleportFailed("Your information has been lost"); - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent's gateway information is malformed"); - return; - } - + IUserAgentService userAgentService = new UserAgentServiceConnector(aCircuit.ServiceURLs["HomeURI"].ToString()); Vector3 position = Vector3.UnitY, lookAt = Vector3.UnitY; - GridRegion finalDestination = m_GatekeeperConnector.GetHomeRegion(homeGatekeeper, aCircuit.AgentID, out position, out lookAt); + GridRegion finalDestination = userAgentService.GetHomeRegion(aCircuit.AgentID, out position, out lookAt); if (finalDestination == null) { client.SendTeleportFailed("Your home region could not be found"); @@ -216,20 +194,52 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}:{5}", + IEventQueue eq = sp.Scene.RequestModuleInterface(); + GridRegion homeGatekeeper = MakeRegion(aCircuit); + + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: teleporting user {0} {1} home to {2} via {3}:{4}:{5}", aCircuit.firstname, aCircuit.lastname, finalDestination.RegionName, homeGatekeeper.ExternalHostName, homeGatekeeper.HttpPort, homeGatekeeper.RegionName); - IEventQueue eq = sp.Scene.RequestModuleInterface(); DoTeleport(sp, homeGatekeeper, finalDestination, position, lookAt, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaHome), eq); } #endregion + #region IUserAgentVerificationModule + + public bool VerifyClient(AgentCircuitData aCircuit, string token) + { + if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) + { + string url = aCircuit.ServiceURLs["HomeURI"].ToString(); + IUserAgentService security = new UserAgentServiceConnector(url); + return security.VerifyClient(aCircuit.SessionID, token); + } + + return false; + } + + void OnLogout(IClientAPI obj) + { + AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); + + if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) + { + string url = aCircuit.ServiceURLs["HomeURI"].ToString(); + IUserAgentService security = new UserAgentServiceConnector(url); + security.LogoutAgent(obj.AgentId, obj.SessionId); + } + + } + + #endregion + private GridRegion MakeRegion(AgentCircuitData aCircuit) { GridRegion region = new GridRegion(); Uri uri = null; - if (!Uri.TryCreate(aCircuit.ServiceURLs["GatewayURI"].ToString(), UriKind.Absolute, out uri)) + if (!aCircuit.ServiceURLs.ContainsKey("HomeURI") || + (aCircuit.ServiceURLs.ContainsKey("HomeURI") && !Uri.TryCreate(aCircuit.ServiceURLs["HomeURI"].ToString(), UriKind.Absolute, out uri))) return null; region.ExternalHostName = uri.Host; -- cgit v1.1 From 0c81966c0a8f69474fb542d7b4df1780ef756519 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 29 Jan 2010 09:12:22 -0800 Subject: Works for grid login. --- .../EntityTransfer/EntityTransferModule.cs | 6 +++- .../EntityTransfer/HGEntityTransferModule.cs | 39 ++++++++++++++++------ 2 files changed, 33 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 44f1191..ee6cb04 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -97,7 +97,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer scene.EventManager.OnNewClient += OnNewClient; } - protected void OnNewClient(IClientAPI client) + protected virtual void OnNewClient(IClientAPI client) { client.OnTeleportHomeRequest += TeleportHome; } @@ -268,6 +268,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (sp.ParentID != (uint)0) sp.StandUp(); + m_log.Debug("XXX HERE 1"); if (!sp.ValidateAttachments()) { sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); @@ -978,12 +979,15 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (neighbour.RegionHandle != sp.Scene.RegionInfo.RegionHandle) { + AgentCircuitData currentAgentCircuit = sp.Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); AgentCircuitData agent = sp.ControllingClient.RequestClientInfo(); agent.BaseFolder = UUID.Zero; agent.InventoryFolder = UUID.Zero; agent.startpos = new Vector3(128, 128, 70); agent.child = true; agent.Appearance = sp.Appearance; + if (currentAgentCircuit != null) + agent.ServiceURLs = currentAgentCircuit.ServiceURLs; if (newRegions.Contains(neighbour.RegionHandle)) { diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 85c2742..fbf8be9 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -85,8 +85,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } } - void OnNewClient(IClientAPI client) + protected override void OnNewClient(IClientAPI client) { + base.OnNewClient(client); client.OnLogout += new Action(OnLogout); } @@ -118,7 +119,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected override GridRegion GetFinalDestination(GridRegion region) { int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, region.RegionID); - //m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: region {0} flags: {1}", region.RegionID, flags); if ((flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) { m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Destination region {0} is hyperlink", region.RegionID); @@ -129,7 +130,14 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected override bool NeedsClosing(uint oldRegionX, uint newRegionX, uint oldRegionY, uint newRegionY, GridRegion reg) { - return true; + if (base.NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) + return true; + + int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); + if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) + return true; + + return false; } protected override bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason) @@ -139,14 +147,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) { // this user is going to another grid - string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString(); - IUserAgentService connector = new UserAgentServiceConnector(userAgentDriver); - bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason); - if (success) - // Log them out of this grid - m_aScene.PresenceService.LogoutAgent(agentCircuit.SessionID, sp.AbsolutePosition, sp.Lookat); - - return success; + if (agentCircuit.ServiceURLs.ContainsKey("HomeURI")) + { + string userAgentDriver = agentCircuit.ServiceURLs["HomeURI"].ToString(); + IUserAgentService connector = new UserAgentServiceConnector(userAgentDriver); + bool success = connector.LoginAgentToGrid(agentCircuit, reg, finalDestination, out reason); + if (success) + // Log them out of this grid + m_aScene.PresenceService.LogoutAgent(agentCircuit.SessionID, sp.AbsolutePosition, sp.Lookat); + + return success; + } + else + { + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent does not have a HomeURI address"); + return false; + } } return m_aScene.SimulationService.CreateAgent(reg, agentCircuit, teleportFlags, out reason); @@ -220,6 +236,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer void OnLogout(IClientAPI obj) { + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: client {0} logged out in {1}", obj.AgentId, obj.Scene.RegionInfo.RegionName); AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) -- cgit v1.1 From 5001f61c08fea2ebfcb2590be69073d04d129d70 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Fri, 29 Jan 2010 18:59:41 -0800 Subject: * HGGridConnector is no longer necessary. * Handle logout properly. This needed an addition to IClientAPI, because of how the logout packet is currently being handled -- the agent is being removed from the scene before the different event handlers are executed, which is broken. --- .../EntityTransfer/EntityTransferModule.cs | 9 ++++--- .../EntityTransfer/HGEntityTransferModule.cs | 28 ++++++++++++---------- 2 files changed, 20 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index ee6cb04..53de269 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -268,7 +268,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (sp.ParentID != (uint)0) sp.StandUp(); - m_log.Debug("XXX HERE 1"); if (!sp.ValidateAttachments()) { sp.ControllingClient.SendTeleportFailed("Inconsistent attachment state"); @@ -351,7 +350,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // ES makes the client send a UseCircuitCode message to the destination, // which triggers a bunch of things there. // So let's wait - Thread.Sleep(2000); + Thread.Sleep(200); eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); @@ -428,13 +427,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - KillEntity(sp.Scene, sp.LocalId); - - sp.MakeChildAgent(); // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it CrossAttachmentsIntoNewRegion(finalDestination, sp, true); + KillEntity(sp.Scene, sp.LocalId); + + sp.MakeChildAgent(); // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone if (NeedsClosing(oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index fbf8be9..28593fc 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -81,16 +81,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (m_Enabled) { scene.RegisterModuleInterface(this); - scene.EventManager.OnNewClient += new EventManager.OnNewClientDelegate(OnNewClient); } } protected override void OnNewClient(IClientAPI client) { - base.OnNewClient(client); - client.OnLogout += new Action(OnLogout); + client.OnTeleportHomeRequest += TeleportHome; + client.OnConnectionClosed += new Action(OnConnectionClosed); } + public override void RegionLoaded(Scene scene) { base.RegionLoaded(scene); @@ -234,18 +234,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return false; } - void OnLogout(IClientAPI obj) + void OnConnectionClosed(IClientAPI obj) { - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: client {0} logged out in {1}", obj.AgentId, obj.Scene.RegionInfo.RegionName); - AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); - - if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) + if (obj.IsLoggingOut) { - string url = aCircuit.ServiceURLs["HomeURI"].ToString(); - IUserAgentService security = new UserAgentServiceConnector(url); - security.LogoutAgent(obj.AgentId, obj.SessionId); - } + AgentCircuitData aCircuit = ((Scene)(obj.Scene)).AuthenticateHandler.GetAgentCircuitData(obj.CircuitCode); + if (aCircuit.ServiceURLs.ContainsKey("HomeURI")) + { + string url = aCircuit.ServiceURLs["HomeURI"].ToString(); + IUserAgentService security = new UserAgentServiceConnector(url); + security.LogoutAgent(obj.AgentId, obj.SessionId); + //m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Sent logout call to UserAgentService @ {0}", url); + } + else + m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: HomeURI not found for agent {0} logout", obj.AgentId); + } } #endregion -- cgit v1.1 From 42f978a478093da579907e15dc29680a3711b27e Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 30 Jan 2010 09:23:07 -0800 Subject: * HGScene is no more. * Moved a few key inventory access methods from Scene.Inventory to an IInventoryAccessModule module --- .../Framework/InventoryAccess/HGAssetMapper.cs | 200 +++++++ .../InventoryAccess/HGInventoryAccessModule.cs | 204 +++++++ .../Framework/InventoryAccess/HGUuidGatherer.cs | 57 ++ .../InventoryAccess/InventoryAccessModule.cs | 654 +++++++++++++++++++++ 4 files changed, 1115 insertions(+) create mode 100644 OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs create mode 100644 OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs create mode 100644 OpenSim/Region/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs create mode 100644 OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs new file mode 100644 index 0000000..e303a1f --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs @@ -0,0 +1,200 @@ +/* + * 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.Threading; +using log4net; +using OpenMetaverse; +using OpenSim.Framework; + +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Serialization; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Services.Interfaces; + +//using HyperGrid.Framework; +//using OpenSim.Region.Communications.Hypergrid; + +namespace OpenSim.Region.CoreModules.Framework.InventoryAccess +{ + public class HGAssetMapper + { + #region Fields + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + // This maps between inventory server urls and inventory server clients +// private Dictionary m_inventoryServers = new Dictionary(); + + private Scene m_scene; + + #endregion + + #region Constructor + + public HGAssetMapper(Scene scene) + { + m_scene = scene; + } + + #endregion + + #region Internal functions + + public AssetBase FetchAsset(string url, UUID assetID) + { + AssetBase asset = m_scene.AssetService.Get(url + "/" + assetID.ToString()); + + if (asset != null) + { + m_log.DebugFormat("[HG ASSET MAPPER]: Copied asset {0} from {1} to local asset server. ", asset.ID, url); + return asset; + } + return null; + } + + public bool PostAsset(string url, AssetBase asset) + { + if (asset != null) + { + // See long comment in AssetCache.AddAsset + if (!asset.Temporary || asset.Local) + { + // We need to copy the asset into a new asset, because + // we need to set its ID to be URL+UUID, so that the + // HGAssetService dispatches it to the remote grid. + // It's not pretty, but the best that can be done while + // not having a global naming infrastructure + AssetBase asset1 = new AssetBase(asset.FullID, asset.Name, asset.Type); + Copy(asset, asset1); + try + { + asset1.ID = url + "/" + asset.ID; + } + catch + { + m_log.Warn("[HG ASSET MAPPER]: Oops."); + } + + m_scene.AssetService.Store(asset1); + m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url); + } + return true; + } + else + m_log.Warn("[HG ASSET MAPPER]: Tried to post asset to remote server, but asset not in local cache."); + + return false; + } + + private void Copy(AssetBase from, AssetBase to) + { + to.Data = from.Data; + to.Description = from.Description; + to.FullID = from.FullID; + to.ID = from.ID; + to.Local = from.Local; + to.Name = from.Name; + to.Temporary = from.Temporary; + to.Type = from.Type; + + } + + // TODO: unused + // private void Dump(Dictionary lst) + // { + // m_log.Debug("XXX -------- UUID DUMP ------- XXX"); + // foreach (KeyValuePair kvp in lst) + // m_log.Debug(" >> " + kvp.Key + " (texture? " + kvp.Value + ")"); + // m_log.Debug("XXX -------- UUID DUMP ------- XXX"); + // } + + #endregion + + + #region Public interface + + public void Get(UUID assetID, UUID ownerID, string userAssetURL) + { + // Get the item from the remote asset server onto the local AssetCache + // and place an entry in m_assetMap + + m_log.Debug("[HG ASSET MAPPER]: Fetching object " + assetID + " from asset server " + userAssetURL); + AssetBase asset = FetchAsset(userAssetURL, assetID); + + if (asset != null) + { + // OK, now fetch the inside. + Dictionary ids = new Dictionary(); + HGUuidGatherer uuidGatherer = new HGUuidGatherer(this, m_scene.AssetService, userAssetURL); + uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids); + foreach (UUID uuid in ids.Keys) + FetchAsset(userAssetURL, uuid); + + m_log.DebugFormat("[HG ASSET MAPPER]: Successfully fetched asset {0} from asset server {1}", asset.ID, userAssetURL); + + } + else + m_log.Warn("[HG ASSET MAPPER]: Could not fetch asset from remote asset server " + userAssetURL); + } + + + public void Post(UUID assetID, UUID ownerID, string userAssetURL) + { + // Post the item from the local AssetCache onto the remote asset server + // and place an entry in m_assetMap + + m_log.Debug("[HG ASSET MAPPER]: Posting object " + assetID + " to asset server " + userAssetURL); + AssetBase asset = m_scene.AssetService.Get(assetID.ToString()); + if (asset != null) + { + Dictionary ids = new Dictionary(); + HGUuidGatherer uuidGatherer = new HGUuidGatherer(this, m_scene.AssetService, string.Empty); + uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids); + foreach (UUID uuid in ids.Keys) + { + asset = m_scene.AssetService.Get(uuid.ToString()); + if (asset == null) + m_log.DebugFormat("[HG ASSET MAPPER]: Could not find asset {0}", uuid); + else + PostAsset(userAssetURL, asset); + } + + // maybe all pieces got there... + m_log.DebugFormat("[HG ASSET MAPPER]: Successfully posted item {0} to asset server {1}", assetID, userAssetURL); + + } + else + m_log.DebugFormat("[HG ASSET MAPPER]: Something wrong with asset {0}, it could not be found", assetID); + + } + + #endregion + + } +} diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs new file mode 100644 index 0000000..ecd7002 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -0,0 +1,204 @@ +/* + * 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 OpenSim.Framework; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Connectors.Hypergrid; +using OpenSim.Services.Interfaces; +using OpenSim.Server.Base; + +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +using OpenMetaverse; +using log4net; +using Nini.Config; + +namespace OpenSim.Region.CoreModules.Framework.InventoryAccess +{ + public class HGInventoryAccessModule : InventoryAccessModule, INonSharedRegionModule, IInventoryAccessModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private static HGAssetMapper m_assMapper; + public static HGAssetMapper AssetMapper + { + get { return m_assMapper; } + } + + private bool m_Initialized = false; + + #region INonSharedRegionModule + + public override string Name + { + get { return "HGInventoryAccessModule"; } + } + + public override void Initialise(IConfigSource source) + { + IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) + { + string name = moduleConfig.GetString("InventoryAccessModule", ""); + if (name == Name) + { + m_Enabled = true; + m_log.InfoFormat("[HG INVENTORY ACCESS MODULE]: {0} enabled.", Name); + } + } + } + + public override void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + base.AddRegion(scene); + m_assMapper = new HGAssetMapper(scene); + scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem; + + } + + #endregion + + #region Event handlers + + public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel) + { + string userAssetServer = string.Empty; + if (IsForeignUser(avatarID, out userAssetServer)) + { + m_assMapper.Post(assetID, avatarID, userAssetServer); + } + } + + #endregion + + #region Overrides of Basic Inventory Access methods + /// + /// CapsUpdateInventoryItemAsset + /// + public override UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data) + { + UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data); + + UploadInventoryItem(remoteClient.AgentId, newAssetID, "", 0); + + return newAssetID; + } + + /// + /// DeleteToInventory + /// + public override UUID DeleteToInventory(DeRezAction action, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient) + { + UUID assetID = base.DeleteToInventory(action, folderID, objectGroup, remoteClient); + + if (!assetID.Equals(UUID.Zero)) + { + UploadInventoryItem(remoteClient.AgentId, assetID, "", 0); + } + else + m_log.Debug("[HGScene]: Scene.Inventory did not create asset"); + + return assetID; + } + + /// + /// RezObject + /// + public override SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, + UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, + bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) + { + m_log.DebugFormat("[HGScene] RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID); + + //if (fromTaskID.Equals(UUID.Zero)) + //{ + InventoryItemBase item = new InventoryItemBase(itemID); + item.Owner = remoteClient.AgentId; + item = m_Scene.InventoryService.GetItem(item); + //if (item == null) + //{ // Fetch the item + // item = new InventoryItemBase(); + // item.Owner = remoteClient.AgentId; + // item.ID = itemID; + // item = m_assMapper.Get(item, userInfo.RootFolder.ID, userInfo); + //} + string userAssetServer = string.Empty; + if (item != null && IsForeignUser(remoteClient.AgentId, out userAssetServer)) + { + m_assMapper.Get(item.AssetID, remoteClient.AgentId, userAssetServer); + + } + //} + + // OK, we're done fetching. Pass it up to the default RezObject + return base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, + RezSelected, RemoveItem, fromTaskID, attachment); + + } + + public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver) + { + string userAssetServer = string.Empty; + if (IsForeignUser(sender, out userAssetServer)) + m_assMapper.Get(item.AssetID, sender, userAssetServer); + + if (IsForeignUser(receiver, out userAssetServer)) + m_assMapper.Post(item.AssetID, receiver, userAssetServer); + } + + #endregion + + public bool IsForeignUser(UUID userID, out string assetServerURL) + { + assetServerURL = string.Empty; + UserAccount account = m_Scene.UserAccountService.GetUserAccount(m_Scene.RegionInfo.ScopeID, userID); + if (account == null) // foreign + { + ScenePresence sp = null; + if (m_Scene.TryGetAvatar(userID, out sp)) + { + AgentCircuitData aCircuit = m_Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); + if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) + { + assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString(); + return true; + } + } + } + + return false; + } + } +} diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs new file mode 100644 index 0000000..fcb544f --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGUuidGatherer.cs @@ -0,0 +1,57 @@ +/* + * 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 OpenSim.Framework; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Services.Interfaces; +using OpenMetaverse; + +namespace OpenSim.Region.CoreModules.Framework.InventoryAccess +{ + public class HGUuidGatherer : UuidGatherer + { + protected string m_assetServerURL; + protected HGAssetMapper m_assetMapper; + + public HGUuidGatherer(HGAssetMapper assMap, IAssetService assetCache, string assetServerURL) : base(assetCache) + { + m_assetMapper = assMap; + m_assetServerURL = assetServerURL; + } + + protected override AssetBase GetAsset(UUID uuid) + { + if (string.Empty == m_assetServerURL) + return m_assetCache.Get(uuid.ToString()); + else + return m_assetMapper.FetchAsset(m_assetServerURL, uuid); + } + } +} diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs new file mode 100644 index 0000000..d242a34 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -0,0 +1,654 @@ +/* + * 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 System.Threading; + +using OpenSim.Framework; +using OpenSim.Framework.Capabilities; +using OpenSim.Framework.Client; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using OpenSim.Region.Framework.Scenes.Serialization; +using OpenSim.Services.Interfaces; + +using GridRegion = OpenSim.Services.Interfaces.GridRegion; + +using OpenMetaverse; +using log4net; +using Nini.Config; + +namespace OpenSim.Region.CoreModules.Framework.InventoryAccess +{ + public class InventoryAccessModule : INonSharedRegionModule, IInventoryAccessModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + protected bool m_Enabled = false; + protected Scene m_Scene; + + #region INonSharedRegionModule + + public Type ReplaceableInterface + { + get { return null; } + } + + public virtual string Name + { + get { return "BasicInventoryAcessModule"; } + } + + public virtual void Initialise(IConfigSource source) + { + IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) + { + string name = moduleConfig.GetString("InventoryAccessModule", ""); + if (name == Name) + { + m_Enabled = true; + m_log.InfoFormat("[INVENTORY ACCESS MODULE]: {0} enabled.", Name); + } + } + } + + public virtual void PostInitialise() + { + } + + public virtual void AddRegion(Scene scene) + { + if (!m_Enabled) + return; + + m_Scene = scene; + + scene.RegisterModuleInterface(this); + scene.EventManager.OnNewClient += OnNewClient; + } + + protected virtual void OnNewClient(IClientAPI client) + { + + } + + public virtual void Close() + { + if (!m_Enabled) + return; + } + + + public virtual void RemoveRegion(Scene scene) + { + if (!m_Enabled) + return; + m_Scene = null; + } + + public virtual void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + } + + #endregion + + #region Inventory Access + + /// + /// Capability originating call to update the asset of an item in an agent's inventory + /// + /// + /// + /// + /// + public virtual UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data) + { + InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); + item = m_Scene.InventoryService.GetItem(item); + + if (item != null) + { + if ((InventoryType)item.InvType == InventoryType.Notecard) + { + if (!m_Scene.Permissions.CanEditNotecard(itemID, UUID.Zero, remoteClient.AgentId)) + { + remoteClient.SendAgentAlertMessage("Insufficient permissions to edit notecard", false); + return UUID.Zero; + } + + remoteClient.SendAgentAlertMessage("Notecard saved", false); + } + else if ((InventoryType)item.InvType == InventoryType.LSL) + { + if (!m_Scene.Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId)) + { + remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false); + return UUID.Zero; + } + + remoteClient.SendAgentAlertMessage("Script saved", false); + } + + AssetBase asset = + CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data); + item.AssetID = asset.FullID; + m_Scene.AssetService.Store(asset); + + m_Scene.InventoryService.UpdateItem(item); + + // remoteClient.SendInventoryItemCreateUpdate(item); + return (asset.FullID); + } + else + { + m_log.ErrorFormat( + "[AGENT INVENTORY]: Could not find item {0} for caps inventory update", + itemID); + } + + return UUID.Zero; + } + + /// + /// Delete a scene object from a scene and place in the given avatar's inventory. + /// Returns the UUID of the newly created asset. + /// + /// + /// + /// + /// + public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, + SceneObjectGroup objectGroup, IClientAPI remoteClient) + { + UUID assetID = UUID.Zero; + + Vector3 inventoryStoredPosition = new Vector3 + (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) + ? 250 + : objectGroup.AbsolutePosition.X) + , + (objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) + ? 250 + : objectGroup.AbsolutePosition.X, + objectGroup.AbsolutePosition.Z); + + Vector3 originalPosition = objectGroup.AbsolutePosition; + + objectGroup.AbsolutePosition = inventoryStoredPosition; + + string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); + + objectGroup.AbsolutePosition = originalPosition; + + // Get the user info of the item destination + // + UUID userID = UUID.Zero; + + if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || + action == DeRezAction.SaveToExistingUserInventoryItem) + { + // Take or take copy require a taker + // Saving changes requires a local user + // + if (remoteClient == null) + return UUID.Zero; + + userID = remoteClient.AgentId; + } + else + { + // All returns / deletes go to the object owner + // + + userID = objectGroup.RootPart.OwnerID; + } + + if (userID == UUID.Zero) // Can't proceed + { + return UUID.Zero; + } + + // If we're returning someone's item, it goes back to the + // owner's Lost And Found folder. + // Delete is treated like return in this case + // Deleting your own items makes them go to trash + // + + InventoryFolderBase folder = null; + InventoryItemBase item = null; + + if (DeRezAction.SaveToExistingUserInventoryItem == action) + { + item = new InventoryItemBase(objectGroup.RootPart.FromUserInventoryItemID, userID); + item = m_Scene.InventoryService.GetItem(item); + + //item = userInfo.RootFolder.FindItem( + // objectGroup.RootPart.FromUserInventoryItemID); + + if (null == item) + { + m_log.DebugFormat( + "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", + objectGroup.Name, objectGroup.UUID); + return UUID.Zero; + } + } + else + { + // Folder magic + // + if (action == DeRezAction.Delete) + { + // Deleting someone else's item + // + + + if (remoteClient == null || + objectGroup.OwnerID != remoteClient.AgentId) + { + // Folder skeleton may not be loaded and we + // have to wait for the inventory to find + // the destination folder + // + folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); + } + else + { + // Assume inventory skeleton was loaded during login + // and all folders can be found + // + folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); + } + } + else if (action == DeRezAction.Return) + { + + // Dump to lost + found unconditionally + // + folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); + } + + if (folderID == UUID.Zero && folder == null) + { + if (action == DeRezAction.Delete) + { + // Deletes go to trash by default + // + folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); + } + else + { + // Catch all. Use lost & found + // + + folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); + } + } + + if (folder == null) // None of the above + { + //folder = userInfo.RootFolder.FindFolder(folderID); + folder = new InventoryFolderBase(folderID); + + if (folder == null) // Nowhere to put it + { + return UUID.Zero; + } + } + + item = new InventoryItemBase(); + item.CreatorId = objectGroup.RootPart.CreatorID.ToString(); + item.ID = UUID.Random(); + item.InvType = (int)InventoryType.Object; + item.Folder = folder.ID; + item.Owner = userID; + } + + AssetBase asset = CreateAsset( + objectGroup.GetPartName(objectGroup.RootPart.LocalId), + objectGroup.GetPartDescription(objectGroup.RootPart.LocalId), + (sbyte)AssetType.Object, + Utils.StringToBytes(sceneObjectXml)); + m_Scene.AssetService.Store(asset); + assetID = asset.FullID; + + if (DeRezAction.SaveToExistingUserInventoryItem == action) + { + item.AssetID = asset.FullID; + m_Scene.InventoryService.UpdateItem(item); + } + else + { + item.AssetID = asset.FullID; + + if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) + { + uint perms = objectGroup.GetEffectivePermissions(); + uint nextPerms = (perms & 7) << 13; + if ((nextPerms & (uint)PermissionMask.Copy) == 0) + perms &= ~(uint)PermissionMask.Copy; + if ((nextPerms & (uint)PermissionMask.Transfer) == 0) + perms &= ~(uint)PermissionMask.Transfer; + if ((nextPerms & (uint)PermissionMask.Modify) == 0) + perms &= ~(uint)PermissionMask.Modify; + + item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask; + item.CurrentPermissions = item.BasePermissions; + item.NextPermissions = objectGroup.RootPart.NextOwnerMask; + item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask; + item.GroupPermissions = objectGroup.RootPart.GroupMask & objectGroup.RootPart.NextOwnerMask; + item.CurrentPermissions |= 8; // Slam! + } + else + { + item.BasePermissions = objectGroup.GetEffectivePermissions(); + item.CurrentPermissions = objectGroup.GetEffectivePermissions(); + item.NextPermissions = objectGroup.RootPart.NextOwnerMask; + item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask; + item.GroupPermissions = objectGroup.RootPart.GroupMask; + + item.CurrentPermissions |= 8; // Slam! + } + + // TODO: add the new fields (Flags, Sale info, etc) + item.CreationDate = Util.UnixTimeSinceEpoch(); + item.Description = asset.Description; + item.Name = asset.Name; + item.AssetType = asset.Type; + + m_Scene.InventoryService.AddItem(item); + + if (remoteClient != null && item.Owner == remoteClient.AgentId) + { + remoteClient.SendInventoryItemCreateUpdate(item, 0); + } + else + { + ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner); + if (notifyUser != null) + { + notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0); + } + } + } + + return assetID; + } + + + /// + /// Rez an object into the scene from the user's inventory + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// The SceneObjectGroup rezzed or null if rez was unsuccessful. + public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart, + UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, + bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) + { + // Work out position details + byte bRayEndIsIntersection = (byte)0; + + if (RayEndIsIntersection) + { + bRayEndIsIntersection = (byte)1; + } + else + { + bRayEndIsIntersection = (byte)0; + } + + Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f); + + + Vector3 pos = m_Scene.GetNewRezLocation( + RayStart, RayEnd, RayTargetID, Quaternion.Identity, + BypassRayCast, bRayEndIsIntersection, true, scale, false); + + // Rez object + InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId); + item = m_Scene.InventoryService.GetItem(item); + + if (item != null) + { + AssetBase rezAsset = m_Scene.AssetService.Get(item.AssetID.ToString()); + + if (rezAsset != null) + { + UUID itemId = UUID.Zero; + + // If we have permission to copy then link the rezzed object back to the user inventory + // item that it came from. This allows us to enable 'save object to inventory' + if (!m_Scene.Permissions.BypassPermissions()) + { + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy) + { + itemId = item.ID; + } + } + else + { + // Brave new fullperm world + // + itemId = item.ID; + } + + string xmlData = Utils.BytesToString(rezAsset.Data); + SceneObjectGroup group + = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData); + + if (!m_Scene.Permissions.CanRezObject( + group.Children.Count, remoteClient.AgentId, pos) + && !attachment) + { + // The client operates in no fail mode. It will + // have already removed the item from the folder + // if it's no copy. + // Put it back if it's not an attachment + // + if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment)) + remoteClient.SendBulkUpdateInventory(item); + return null; + } + + group.ResetIDs(); + + if (attachment) + { + group.RootPart.ObjectFlags |= (uint)PrimFlags.Phantom; + group.RootPart.IsAttachment = true; + } + + m_Scene.AddNewSceneObject(group, true); + + // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z); + // if attachment we set it's asset id so object updates can reflect that + // if not, we set it's position in world. + if (!attachment) + { + float offsetHeight = 0; + pos = m_Scene.GetNewRezLocation( + RayStart, RayEnd, RayTargetID, Quaternion.Identity, + BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false); + pos.Z += offsetHeight; + group.AbsolutePosition = pos; + // m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2} and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight); + + } + else + { + group.SetFromItemID(itemID); + } + + SceneObjectPart rootPart = null; + try + { + rootPart = group.GetChildPart(group.UUID); + } + catch (NullReferenceException) + { + string isAttachment = ""; + + if (attachment) + isAttachment = " Object was an attachment"; + + m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment); + } + + // Since renaming the item in the inventory does not affect the name stored + // in the serialization, transfer the correct name from the inventory to the + // object itself before we rez. + rootPart.Name = item.Name; + rootPart.Description = item.Description; + + List partList = new List(group.Children.Values); + + group.SetGroup(remoteClient.ActiveGroupId, remoteClient); + if (rootPart.OwnerID != item.Owner) + { + //Need to kill the for sale here + rootPart.ObjectSaleType = 0; + rootPart.SalePrice = 10; + + if (m_Scene.Permissions.PropagatePermissions()) + { + if ((item.CurrentPermissions & 8) != 0) + { + foreach (SceneObjectPart part in partList) + { + part.EveryoneMask = item.EveryOnePermissions; + part.NextOwnerMask = item.NextPermissions; + part.GroupMask = 0; // DO NOT propagate here + } + } + group.ApplyNextOwnerPermissions(); + } + } + + foreach (SceneObjectPart part in partList) + { + if (part.OwnerID != item.Owner) + { + part.LastOwnerID = part.OwnerID; + part.OwnerID = item.Owner; + part.Inventory.ChangeInventoryOwner(item.Owner); + } + else if (((item.CurrentPermissions & 8) != 0) && (!attachment)) // Slam! + { + part.EveryoneMask = item.EveryOnePermissions; + part.NextOwnerMask = item.NextPermissions; + + part.GroupMask = 0; // DO NOT propagate here + } + } + + rootPart.TrimPermissions(); + + if (!attachment) + { + if (group.RootPart.Shape.PCode == (byte)PCode.Prim) + { + group.ClearPartAttachmentData(); + } + } + + if (!attachment) + { + // Fire on_rez + group.CreateScriptInstances(0, true, m_Scene.DefaultScriptEngine, 0); + + rootPart.ScheduleFullUpdate(); + } + + if (!m_Scene.Permissions.BypassPermissions()) + { + if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) + { + // If this is done on attachments, no + // copy ones will be lost, so avoid it + // + if (!attachment) + { + List uuids = new List(); + uuids.Add(item.ID); + m_Scene.InventoryService.DeleteItems(item.Owner, uuids); + } + } + } + + return rootPart.ParentGroup; + } + } + + return null; + } + + public virtual void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver) + { + } + + #endregion + + #region Misc + + /// + /// Create a new asset data structure. + /// + /// + /// + /// + /// + /// + /// + private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data) + { + AssetBase asset = new AssetBase(UUID.Random(), name, assetType); + asset.Description = description; + asset.Data = (data == null) ? new byte[1] : data; + + return asset; + } + + #endregion + } +} -- cgit v1.1 From a0d79e621cc8ee4935dfc2816da75db9c23c1b84 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Sat, 30 Jan 2010 15:43:10 -0800 Subject: Bug fix: change HGBroker to a INonSharedRegionModule --- .../Framework/InventoryAccess/HGInventoryAccessModule.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index ecd7002..09798aa 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -183,7 +183,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess public bool IsForeignUser(UUID userID, out string assetServerURL) { assetServerURL = string.Empty; - UserAccount account = m_Scene.UserAccountService.GetUserAccount(m_Scene.RegionInfo.ScopeID, userID); + UserAccount account = null; + if (m_Scene.UserAccountService != null) + account = m_Scene.UserAccountService.GetUserAccount(m_Scene.RegionInfo.ScopeID, userID); + if (account == null) // foreign { ScenePresence sp = null; @@ -193,7 +196,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) { assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString(); - return true; + assetServerURL = assetServerURL.Trim(new char[] { '/' }); return true; } } } -- cgit v1.1 From 7665aad002ef066fc31fa9497225d2668641c769 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Mon, 22 Feb 2010 13:27:17 -0800 Subject: * Adds CreatorID to asset metadata. This is just the plumbing to support CreatorID, it doesn't modify database backends or OAR files to support storing/loading it --- .../CoreModules/Framework/InventoryAccess/HGAssetMapper.cs | 2 +- .../Framework/InventoryAccess/InventoryAccessModule.cs | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs index e303a1f..664f38d 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs @@ -90,7 +90,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // HGAssetService dispatches it to the remote grid. // It's not pretty, but the best that can be done while // not having a global naming infrastructure - AssetBase asset1 = new AssetBase(asset.FullID, asset.Name, asset.Type); + AssetBase asset1 = new AssetBase(asset.FullID, asset.Name, asset.Type, asset.Metadata.CreatorID); Copy(asset, asset1); try { diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index d242a34..eec852e 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -161,7 +161,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } AssetBase asset = - CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data); + CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data, remoteClient.AgentId); item.AssetID = asset.FullID; m_Scene.AssetService.Store(asset); @@ -339,7 +339,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess objectGroup.GetPartName(objectGroup.RootPart.LocalId), objectGroup.GetPartDescription(objectGroup.RootPart.LocalId), (sbyte)AssetType.Object, - Utils.StringToBytes(sceneObjectXml)); + Utils.StringToBytes(sceneObjectXml), + objectGroup.OwnerID); m_Scene.AssetService.Store(asset); assetID = asset.FullID; @@ -640,9 +641,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess /// /// /// - private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data) + private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data, UUID creatorID) { - AssetBase asset = new AssetBase(UUID.Random(), name, assetType); + AssetBase asset = new AssetBase(UUID.Random(), name, assetType, creatorID); asset.Description = description; asset.Data = (data == null) ? new byte[1] : data; -- cgit v1.1 From df76e95aa2dc9f3f3a0c546761b7624adc183ed0 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Mon, 22 Feb 2010 14:18:59 -0800 Subject: Changed asset CreatorID to a string --- .../CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index eec852e..37f1da9 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -161,7 +161,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } AssetBase asset = - CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data, remoteClient.AgentId); + CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data, remoteClient.AgentId.ToString()); item.AssetID = asset.FullID; m_Scene.AssetService.Store(asset); @@ -340,7 +340,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess objectGroup.GetPartDescription(objectGroup.RootPart.LocalId), (sbyte)AssetType.Object, Utils.StringToBytes(sceneObjectXml), - objectGroup.OwnerID); + objectGroup.OwnerID.ToString()); m_Scene.AssetService.Store(asset); assetID = asset.FullID; @@ -641,7 +641,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess /// /// /// - private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data, UUID creatorID) + private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data, string creatorID) { AssetBase asset = new AssetBase(UUID.Random(), name, assetType, creatorID); asset.Description = description; -- cgit v1.1 From d506449f6765ec7372615ffd4afefb0075d94af4 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Tue, 23 Feb 2010 00:59:24 -0800 Subject: * Removed the unused GridRegion.getInternalEndPointPort() (just use InternalEndPoint.Port). This class is complex enough as it is * Changed the failed to inform neighbor message from a warning to info, since this will fire for every empty neighbor space * Made the EnableSimulator/EstablishAgentCommunication log message more verbose and more clear about what is happening --- .../CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 53de269..80c0af8 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1120,10 +1120,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } #endregion + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: {0} is sending {1} EnableSimulator for neighbor region {2} @ {3} " + + "and EstablishAgentCommunication with seed cap {4}", + m_scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); + eq.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1} in region {2}", - capsPath, sp.UUID, sp.Scene.RegionInfo.RegionName); } else { -- cgit v1.1 From 267f3b81471bd36fab5c8da538a17bf59e98d9c1 Mon Sep 17 00:00:00 2001 From: Diva Canto Date: Wed, 24 Feb 2010 08:03:30 -0800 Subject: Fixed typo that was affecting the BasicInventoryAccessModule --- .../CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs | 2 +- .../CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/CoreModules/Framework') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 09798aa..25f5154 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -44,7 +44,7 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { - public class HGInventoryAccessModule : InventoryAccessModule, INonSharedRegionModule, IInventoryAccessModule + public class HGInventoryAccessModule : BasicInventoryAccessModule, INonSharedRegionModule, IInventoryAccessModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 37f1da9..e0df288 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -47,7 +47,7 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { - public class InventoryAccessModule : INonSharedRegionModule, IInventoryAccessModule + public class BasicInventoryAccessModule : INonSharedRegionModule, IInventoryAccessModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -63,7 +63,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess public virtual string Name { - get { return "BasicInventoryAcessModule"; } + get { return "BasicInventoryAccessModule"; } } public virtual void Initialise(IConfigSource source) -- cgit v1.1