From 7e97f0e8989ff1bc7fab80c726dfef23dffc5cca Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 21 May 2012 21:00:22 +0100 Subject: minor: extend commented out LinkInventoryItem log message for future use --- OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 8a26df1..79c9309 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs @@ -939,8 +939,8 @@ namespace OpenSim.Region.Framework.Scenes sbyte invType, sbyte type, UUID olditemID) { // m_log.DebugFormat( -// "[AGENT INVENTORY]: Received request from {0} to create inventory item link {1} in folder {2} pointing to {3}", -// remoteClient.Name, name, folderID, olditemID); +// "[AGENT INVENTORY]: Received request from {0} to create inventory item link {1} in folder {2} pointing to {3}, assetType {4}, inventoryType {5}", +// remoteClient.Name, name, folderID, olditemID, (AssetType)type, (InventoryType)invType); if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) return; @@ -973,10 +973,10 @@ namespace OpenSim.Region.Framework.Scenes asset.Type = type; asset.Name = name; asset.Description = description; - + CreateNewInventoryItem( - remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, 0, callbackID, asset, invType, - (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, + remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, name, 0, callbackID, asset, invType, + (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch()); } else -- cgit v1.1 From 9ab0c81c1dfb95e423d73599bd1fc66778749f0d Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Mon, 21 May 2012 21:33:59 +0100 Subject: Setting 'in transit' on a local teleport as well as inter-region teleports. This is to eliminate possible race conditions if two teleport calls are made concurrently, where at least one is a local teleport. This is pretty much impossible on a manual user teleport but can happen on script-invoked teleports. --- .../CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 5dbe5e4..36e9da6 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -230,6 +230,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Teleport for {0} to {1} within {2}", sp.Name, position, sp.Scene.RegionInfo.RegionName); + if (!SetInTransit(sp.UUID)) + { + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.", + sp.Name, sp.UUID, position); + } + // Teleport within the same region if (IsOutsideRegion(sp.Scene, position) || position.Z < 0) { @@ -268,6 +275,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); } + + ResetFromTransit(sp.UUID); } /// -- cgit v1.1 From ff429a259b41f1205a6b153bb6da383d9a9f5daf Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 01:58:10 +0100 Subject: Fix bug where an avatar that had an object they owned attached through llAttachToAvatar() or osForceAttachToAvatar() would wrongly have next permissions come into play when they detached that object and rezzed it in scene. This is because the attachments module code was setting the 'object slam' bit by using PermissionMask.All Solution here is to route the attachment item creation call through the existing inventory code in BasicInventoryAccessModule rather than copy/pasted code in AttachmentsModule itself. --- .../Avatar/Attachments/AttachmentsModule.cs | 206 +++++++-------------- .../Attachments/Tests/AttachmentsModuleTests.cs | 13 +- .../InventoryAccess/InventoryAccessModule.cs | 59 +++--- .../Framework/Interfaces/IInventoryAccessModule.cs | 10 +- .../Scenes/AsyncSceneObjectGroupDeleter.cs | 2 +- .../Framework/Scenes/SceneObjectPartInventory.cs | 7 + .../CoalescedSceneObjectsSerializer.cs | 20 +- 7 files changed, 151 insertions(+), 166 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 2e1948d..d099511 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -49,6 +49,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private Scene m_scene; private IDialogModule m_dialogModule; + private IInventoryAccessModule m_invAccessModule; /// /// Are attachments enabled? @@ -87,7 +88,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.EventManager.OnNewClient -= SubscribeToClientEvents; } - public void RegionLoaded(Scene scene) {} + public void RegionLoaded(Scene scene) + { + m_invAccessModule = m_scene.RequestModuleInterface(); + } public void Close() { @@ -578,90 +582,23 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// The user inventory item created that holds the attachment. private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IScenePresence sp, SceneObjectGroup grp) { + if (m_invAccessModule == null) + return null; + // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", // grp.Name, grp.LocalId, remoteClient.Name); - Vector3 inventoryStoredPosition = new Vector3 - (((grp.AbsolutePosition.X > (int)Constants.RegionSize) - ? Constants.RegionSize - 6 - : grp.AbsolutePosition.X) - , - (grp.AbsolutePosition.Y > (int)Constants.RegionSize) - ? Constants.RegionSize - 6 - : grp.AbsolutePosition.Y, - grp.AbsolutePosition.Z); - - Vector3 originalPosition = grp.AbsolutePosition; - - grp.AbsolutePosition = inventoryStoredPosition; - - // If we're being called from a script, then trying to serialize that same script's state will not complete - // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if - // the client/server crashes rather than logging out normally, the attachment's scripts will resume - // without state on relog. Arguably, this is what we want anyway. - string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp, false); - - grp.AbsolutePosition = originalPosition; - - AssetBase asset = m_scene.CreateAsset( - grp.GetPartName(grp.LocalId), - grp.GetPartDescription(grp.LocalId), - (sbyte)AssetType.Object, - Utils.StringToBytes(sceneObjectXml), - sp.UUID); - - m_scene.AssetService.Store(asset); - - InventoryItemBase item = new InventoryItemBase(); - item.CreatorId = grp.RootPart.CreatorID.ToString(); - item.CreatorData = grp.RootPart.CreatorData; - item.Owner = sp.UUID; - item.ID = UUID.Random(); - item.AssetID = asset.FullID; - item.Description = asset.Description; - item.Name = asset.Name; - item.AssetType = asset.Type; - item.InvType = (int)InventoryType.Object; - - InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object); - if (folder != null) - item.Folder = folder.ID; - else // oopsies - item.Folder = UUID.Zero; - - if ((sp.UUID != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions()) - { - item.BasePermissions = grp.RootPart.NextOwnerMask; - item.CurrentPermissions = grp.RootPart.NextOwnerMask; - item.NextPermissions = grp.RootPart.NextOwnerMask; - item.EveryOnePermissions = grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask; - item.GroupPermissions = grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask; - } - else - { - item.BasePermissions = grp.RootPart.BaseMask; - item.CurrentPermissions = grp.RootPart.OwnerMask; - item.NextPermissions = grp.RootPart.NextOwnerMask; - item.EveryOnePermissions = grp.RootPart.EveryoneMask; - item.GroupPermissions = grp.RootPart.GroupMask; - } - item.CreationDate = Util.UnixTimeSinceEpoch(); + InventoryItemBase newItem = m_invAccessModule.CopyToInventory( + DeRezAction.TakeCopy, + m_scene.InventoryService.GetFolderForType(sp.UUID, AssetType.Object).ID, + new List { grp }, + sp.ControllingClient, true)[0]; // sets itemID so client can show item as 'attached' in inventory - grp.FromItemID = item.ID; + grp.FromItemID = newItem.ID; - if (m_scene.AddInventoryItem(item)) - { - sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0); - } - else - { - if (m_dialogModule != null) - m_dialogModule.SendAlertToUser(sp.ControllingClient, "Operation failed"); - } - - return item; + return newItem; } // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. @@ -709,70 +646,69 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) { - IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); - if (invAccess != null) + if (m_invAccessModule == null) + return null; + + lock (sp.AttachmentsSyncLock) { - lock (sp.AttachmentsSyncLock) + SceneObjectGroup objatt; + + if (itemID != UUID.Zero) + objatt = m_invAccessModule.RezObject(sp.ControllingClient, + itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, + false, false, sp.UUID, true); + else + objatt = m_invAccessModule.RezObject(sp.ControllingClient, + null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, + false, false, sp.UUID, true); + + // m_log.DebugFormat( + // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", + // objatt.Name, remoteClient.Name, AttachmentPt); + + if (objatt != null) { - SceneObjectGroup objatt; - - if (itemID != UUID.Zero) - objatt = invAccess.RezObject(sp.ControllingClient, - itemID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, - false, false, sp.UUID, true); - else - objatt = invAccess.RezObject(sp.ControllingClient, - null, assetID, Vector3.Zero, Vector3.Zero, UUID.Zero, (byte)1, true, - false, false, sp.UUID, true); - - // m_log.DebugFormat( - // "[ATTACHMENTS MODULE]: Retrieved single object {0} for attachment to {1} on point {2}", - // objatt.Name, remoteClient.Name, AttachmentPt); - - if (objatt != null) + // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. + objatt.HasGroupChanged = false; + bool tainted = false; + if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) + tainted = true; + + // This will throw if the attachment fails + try { - // HasGroupChanged is being set from within RezObject. Ideally it would be set by the caller. - objatt.HasGroupChanged = false; - bool tainted = false; - if (attachmentPt != 0 && attachmentPt != objatt.AttachmentPoint) - tainted = true; - - // This will throw if the attachment fails - try - { - AttachObject(sp, objatt, attachmentPt, false); - } - catch (Exception e) - { - m_log.ErrorFormat( - "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", - objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); - - // Make sure the object doesn't stick around and bail - sp.RemoveAttachment(objatt); - m_scene.DeleteSceneObject(objatt, false); - return null; - } + AttachObject(sp, objatt, attachmentPt, false); + } + catch (Exception e) + { + m_log.ErrorFormat( + "[ATTACHMENTS MODULE]: Failed to attach {0} {1} for {2}, exception {3}{4}", + objatt.Name, objatt.UUID, sp.Name, e.Message, e.StackTrace); + + // Make sure the object doesn't stick around and bail + sp.RemoveAttachment(objatt); + m_scene.DeleteSceneObject(objatt, false); + return null; + } - if (tainted) - objatt.HasGroupChanged = true; + if (tainted) + objatt.HasGroupChanged = true; - // Fire after attach, so we don't get messy perms dialogs - // 4 == AttachedRez - objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); - objatt.ResumeScripts(); + // Fire after attach, so we don't get messy perms dialogs + // 4 == AttachedRez + objatt.CreateScriptInstances(0, true, m_scene.DefaultScriptEngine, 4); + objatt.ResumeScripts(); - // Do this last so that event listeners have access to all the effects of the attachment - m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); + // Do this last so that event listeners have access to all the effects of the attachment + m_scene.EventManager.TriggerOnAttach(objatt.LocalId, itemID, sp.UUID); - return objatt; - } - else - { - m_log.WarnFormat( - "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", - itemID, sp.Name, attachmentPt); - } + return objatt; + } + else + { + m_log.WarnFormat( + "[ATTACHMENTS MODULE]: Could not retrieve item {0} for attaching to avatar {1} at point {2}", + itemID, sp.Name, attachmentPt); } } diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 42d07fd..5e89eec 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -99,12 +99,12 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests public void TestAddAttachmentFromGround() { TestHelpers.InMethod(); -// log4net.Config.XmlConfigurator.Configure(); +// TestHelpers.EnableLogging(); AddPresence(); string attName = "att"; - SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup; + SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName, m_presence.UUID).ParentGroup; m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false); @@ -123,6 +123,15 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests Assert.That( m_presence.Appearance.GetAttachpoint(attSo.FromItemID), Is.EqualTo((int)AttachmentPoint.Chest)); + + InventoryItemBase attachmentItem = scene.InventoryService.GetItem(new InventoryItemBase(attSo.FromItemID)); + Assert.That(attachmentItem, Is.Not.Null); + Assert.That(attachmentItem.Name, Is.EqualTo(attName)); + + InventoryFolderBase targetFolder = scene.InventoryService.GetFolderForType(m_presence.UUID, AssetType.Object); + Assert.That(attachmentItem.Folder, Is.EqualTo(targetFolder.ID)); + +// TestHelpers.DisableLogging(); } [Test] diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 8171487..f219d4c 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -295,9 +295,12 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess return UUID.Zero; } - public virtual UUID CopyToInventory(DeRezAction action, UUID folderID, - List objectGroups, IClientAPI remoteClient) + public virtual List CopyToInventory( + DeRezAction action, UUID folderID, + List objectGroups, IClientAPI remoteClient, bool asAttachment) { + List copiedItems = new List(); + Dictionary> bundlesToCopy = new Dictionary>(); if (CoalesceMultipleObjectsToInventory) @@ -324,16 +327,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } } - // This is method scoped and will be returned. It will be the - // last created asset id - UUID assetID = UUID.Zero; +// m_log.DebugFormat( +// "[INVENTORY ACCESS MODULE]: Copying {0} object bundles to folder {1} action {2} for {3}", +// bundlesToCopy.Count, folderID, action, remoteClient.Name); // Each iteration is really a separate asset being created, // with distinct destinations as well. foreach (List bundle in bundlesToCopy.Values) - assetID = CopyBundleToInventory(action, folderID, bundle, remoteClient); + copiedItems.Add(CopyBundleToInventory(action, folderID, bundle, remoteClient, asAttachment)); - return assetID; + return copiedItems; } /// @@ -344,12 +347,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess /// /// /// - /// - protected UUID CopyBundleToInventory( - DeRezAction action, UUID folderID, List objlist, IClientAPI remoteClient) + /// Should be true if the bundle is being copied as an attachment. This prevents + /// attempted serialization of any script state which would abort any operating scripts. + /// The inventory item created by the copy + protected InventoryItemBase CopyBundleToInventory( + DeRezAction action, UUID folderID, List objlist, IClientAPI remoteClient, + bool asAttachment) { - UUID assetID = UUID.Zero; - CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); Dictionary originalPositions = new Dictionary(); @@ -385,18 +389,27 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess string itemXml; + // If we're being called from a script, then trying to serialize that same script's state will not complete + // in any reasonable time period. Therefore, we'll avoid it. The worst that can happen is that if + // the client/server crashes rather than logging out normally, the attachment's scripts will resume + // without state on relog. Arguably, this is what we want anyway. if (objlist.Count > 1) - itemXml = CoalescedSceneObjectsSerializer.ToXml(coa); + itemXml = CoalescedSceneObjectsSerializer.ToXml(coa, !asAttachment); else - itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0]); + itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment); // Restore the position of each group now that it has been stored to inventory. foreach (SceneObjectGroup objectGroup in objlist) objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); + +// m_log.DebugFormat( +// "[INVENTORY ACCESS MODULE]: Created item is {0}", +// item != null ? item.ID.ToString() : "NULL"); + if (item == null) - return UUID.Zero; + return null; // Can't know creator is the same, so null it in inventory if (objlist.Count > 1) @@ -406,7 +419,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } else { - item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); + item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); + item.CreatorData = objlist[0].RootPart.CreatorData; item.SaleType = objlist[0].RootPart.ObjectSaleType; item.SalePrice = objlist[0].RootPart.SalePrice; } @@ -419,8 +433,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess objlist[0].OwnerID.ToString()); m_Scene.AssetService.Store(asset); - item.AssetID = asset.FullID; - assetID = asset.FullID; + item.AssetID = asset.FullID; if (DeRezAction.SaveToExistingUserInventoryItem == action) { @@ -453,9 +466,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // This is a hook to do some per-asset post-processing for subclasses that need that if (remoteClient != null) - ExportAsset(remoteClient.AgentId, assetID); + ExportAsset(remoteClient.AgentId, asset.FullID); - return assetID; + return item; } protected virtual void ExportAsset(UUID agentID, UUID assetID) @@ -643,7 +656,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { // Catch all. Use lost & found // - folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); } } @@ -964,8 +976,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess so.FromFolderID = item.Folder; -// Console.WriteLine("rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}", -// rootPart.OwnerID, item.Owner, item.CurrentPermissions); +// m_log.DebugFormat( +// "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}", +// rootPart.OwnerID, item.Owner, item.CurrentPermissions); if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & 16) != 0) diff --git a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs index 1904011..3576e35 100644 --- a/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IInventoryAccessModule.cs @@ -49,11 +49,15 @@ namespace OpenSim.Region.Framework.Interfaces /// /// /// + /// + /// Should be true if the object(s) are begin taken as attachments. False otherwise. + /// /// - /// Returns the UUID of the newly created item asset (not the item itself). - /// FIXME: This is not very useful. It would be far more useful to return a list of items instead. + /// A list of the items created. If there was more than one object and objects are not being coaleseced in + /// inventory, then the order of items is in the same order as the input objects. /// - UUID CopyToInventory(DeRezAction action, UUID folderID, List objectGroups, IClientAPI remoteClient); + List CopyToInventory( + DeRezAction action, UUID folderID, List objectGroups, IClientAPI remoteClient, bool asAttachment); /// /// Rez an object into the scene from the user's inventory diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index 834464b..f555b49 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs @@ -155,7 +155,7 @@ namespace OpenSim.Region.Framework.Scenes { IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); if (invAccess != null) - invAccess.CopyToInventory(x.action, x.folderID, x.objectGroups, x.remoteClient); + invAccess.CopyToInventory(x.action, x.folderID, x.objectGroups, x.remoteClient, false); if (x.permissionToDelete) { diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 3734e03..d27d9e1 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -1027,10 +1027,16 @@ namespace OpenSim.Region.Framework.Scenes public void ApplyNextOwnerPermissions() { + Util.PrintCallStack(); + lock (m_items) { foreach (TaskInventoryItem item in m_items.Values) { +// m_log.DebugFormat ( +// "[SCENE OBJECT PART INVENTORY]: Applying next permissions {0} to {1} in {2} with current {3}, base {4}, everyone {5}", +// item.NextPermissions, item.Name, m_part.Name, item.CurrentPermissions, item.BasePermissions, item.EveryonePermissions); + if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) { if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) @@ -1040,6 +1046,7 @@ namespace OpenSim.Region.Framework.Scenes if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) item.CurrentPermissions &= ~(uint)PermissionMask.Modify; } + item.CurrentPermissions &= item.NextPermissions; item.BasePermissions &= item.NextPermissions; item.EveryonePermissions &= item.NextPermissions; diff --git a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs index 55455cc..a4f730d 100644 --- a/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs +++ b/OpenSim/Region/Framework/Scenes/Serialization/CoalescedSceneObjectsSerializer.cs @@ -47,14 +47,30 @@ namespace OpenSim.Region.Framework.Scenes.Serialization /// public class CoalescedSceneObjectsSerializer { - private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); /// /// Serialize coalesced objects to Xml /// /// + /// + /// If true then serialize script states. This will halt any running scripts + /// /// public static string ToXml(CoalescedSceneObjects coa) + { + return ToXml(coa, true); + } + + /// + /// Serialize coalesced objects to Xml + /// + /// + /// + /// If true then serialize script states. This will halt any running scripts + /// + /// + public static string ToXml(CoalescedSceneObjects coa, bool doScriptStates) { using (StringWriter sw = new StringWriter()) { @@ -91,7 +107,7 @@ namespace OpenSim.Region.Framework.Scenes.Serialization writer.WriteAttributeString("offsety", offsets[i].Y.ToString()); writer.WriteAttributeString("offsetz", offsets[i].Z.ToString()); - SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, true); + SceneObjectSerializer.ToOriginalXmlFormat(obj, writer, doScriptStates); writer.WriteEndElement(); // SceneObjectGroup } -- cgit v1.1 From ec8745cf511de3a452a882a44034c55baf2350a1 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 02:05:48 +0100 Subject: minor: Make log class names in InventoryAccessModule uniform --- .../InventoryAccess/InventoryAccessModule.cs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index f219d4c..69767c1 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -175,7 +175,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess sbyte assetType, byte wearableType, uint nextOwnerMask, int creationDate) { - m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item {0} in folder {1}", name, folderID); + m_log.DebugFormat("[INVENTORY ACCESS MODULE]: Received request to create inventory item {0} in folder {1}", name, folderID); if (!m_Scene.Permissions.CanCreateUserInventory(invType, remoteClient.AgentId)) return; @@ -210,7 +210,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess else { m_log.ErrorFormat( - "ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", + "[INVENTORY ACCESS MODULE]: ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem", remoteClient.AgentId); } } @@ -288,7 +288,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess else { m_log.ErrorFormat( - "[AGENT INVENTORY]: Could not find item {0} for caps inventory update", + "[INVENTORY ACCESS MODULE]: Could not find item {0} for caps inventory update", itemID); } @@ -605,7 +605,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (null == item) { m_log.DebugFormat( - "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", + "[INVENTORY ACCESS MODULE]: Object {0} {1} scheduled for save to inventory has already been deleted.", so.Name, so.UUID); return null; @@ -706,7 +706,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (item == null) { m_log.WarnFormat( - "[InventoryAccessModule]: Could not find item {0} for {1} in RezObject()", + "[INVENTORY ACCESS MODULE]: Could not find item {0} for {1} in RezObject()", itemID, remoteClient.Name); return null; @@ -738,7 +738,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess else { m_log.WarnFormat( - "[InventoryAccessModule]: Could not find asset {0} for {1} in RezObject()", + "[INVENTORY ACCESS MODULE]: Could not find asset {0} for {1} in RezObject()", assetID, remoteClient.Name); } @@ -815,7 +815,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess group = objlist[i]; // m_log.DebugFormat( -// "[InventoryAccessModule]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", +// "[INVENTORY ACCESS MODULE]: Preparing to rez {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", // group.Name, group.LocalId, group.UUID, // group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, // remoteClient.Name); @@ -823,7 +823,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess // Vector3 storedPosition = group.AbsolutePosition; if (group.UUID == UUID.Zero) { - m_log.Debug("[InventoryAccessModule]: Object has UUID.Zero! Position 3"); + m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3"); } foreach (SceneObjectPart part in group.Parts) @@ -886,7 +886,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess } // m_log.DebugFormat( -// "[InventoryAccessModule]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", +// "[INVENTORY ACCESS MODULE]: Rezzed {0} {1} {2} ownermask={3:X} nextownermask={4:X} groupmask={5:X} everyonemask={6:X} for {7}", // group.Name, group.LocalId, group.UUID, // group.RootPart.OwnerMask, group.RootPart.NextOwnerMask, group.RootPart.GroupMask, group.RootPart.EveryoneMask, // remoteClient.Name); @@ -1101,7 +1101,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess if (assetRequestItem.AssetID != requestID) { m_log.WarnFormat( - "[CLIENT]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", + "[INVENTORY ACCESS MODULE]: {0} requested asset {1} from item {2} but this does not match item's asset {3}", Name, requestID, itemID, assetRequestItem.AssetID); return false; -- cgit v1.1 From 68918d632f0521941f67fe2c7b9c87ed048e2b92 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 02:09:31 +0100 Subject: Fetch the dialog module reference in AttachmentsModule in RegionLoaded() not AddRegion() The reference is not guaranteed to be there when AddRegion() is called but will definitely be present at RegionLoaded() if it's going to be present at all. --- OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index d099511..510b483 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -71,7 +71,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void AddRegion(Scene scene) { m_scene = scene; - m_dialogModule = m_scene.RequestModuleInterface(); m_scene.RegisterModuleInterface(this); if (Enabled) @@ -90,6 +89,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void RegionLoaded(Scene scene) { + m_dialogModule = m_scene.RequestModuleInterface(); m_invAccessModule = m_scene.RequestModuleInterface(); } -- cgit v1.1 From 2222d979cc723ee2f3bad92ffe4991d074b2403a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 02:37:38 +0100 Subject: refactor: rename ConsoleTable -> ConsoleDisplayTable for clarity --- .../OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs index a95514c..df32a1d 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -145,7 +145,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments { sb.AppendFormat("Attachments for {0}\n", sp.Name); - ConsoleTable ct = new ConsoleTable() { Indent = 2 }; + ConsoleDisplayTable ct = new ConsoleDisplayTable() { Indent = 2 }; ct.Columns.Add(new ConsoleTableColumn("Attachment Name", 36)); ct.Columns.Add(new ConsoleTableColumn("Local ID", 10)); ct.Columns.Add(new ConsoleTableColumn("Item ID", 36)); -- cgit v1.1 From 8f88c17df969b1fd3e4a93747201e9436c9a1fcd Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 03:23:37 +0100 Subject: refactor: Rename ConsoleTableRow and ConsoleTableColumn to ConsoleDisplayTableRow and ConsoleDisplayTableColumn --- .../Avatar/Attachments/AttachmentsCommandModule.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs index df32a1d..1b9e3ac 100644 --- a/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/Attachments/AttachmentsCommandModule.cs @@ -146,11 +146,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments sb.AppendFormat("Attachments for {0}\n", sp.Name); ConsoleDisplayTable ct = new ConsoleDisplayTable() { Indent = 2 }; - ct.Columns.Add(new ConsoleTableColumn("Attachment Name", 36)); - ct.Columns.Add(new ConsoleTableColumn("Local ID", 10)); - ct.Columns.Add(new ConsoleTableColumn("Item ID", 36)); - ct.Columns.Add(new ConsoleTableColumn("Attach Point", 14)); - ct.Columns.Add(new ConsoleTableColumn("Position", 15)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Attachment Name", 36)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Local ID", 10)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Item ID", 36)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Attach Point", 14)); + ct.Columns.Add(new ConsoleDisplayTableColumn("Position", 15)); // sb.AppendFormat( // " {0,-36} {1,-10} {2,-36} {3,-14} {4,-15}\n", @@ -176,7 +176,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.Attachments // attachmentObject.Name, attachmentObject.LocalId, attachmentObject.FromItemID, // (AttachmentPoint)attachmentObject.AttachmentPoint, attachmentObject.RootPart.AttachedPos); ct.Rows.Add( - new ConsoleTableRow( + new ConsoleDisplayTableRow( new List() { attachmentObject.Name, -- cgit v1.1 From ee98b9c394900f55684e33829be1c182e84b2cab Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 04:10:45 +0100 Subject: Add "show scene" command which lists stats for the currently selected console scene(s) This includes prim count, script count, avatar count, etc. Information is currently the same as "show stats", though show stats can only show one scene at a time because it listens for the latest outgoing stats packet (a bad approach that needs to change). Might be better to tie this module into the other stats module to display arbitrary stats rather than fetching directly from scene.SimStatsReporter. Console command is "show scene" because "show region" already exists for the grid service, which is unfortunate. Might need to make a distinction between "scene" relating to a live scene and "region" relating to more static region data (url, coords, etc.) --- .../World/Region/RegionCommandsModule.cs | 155 +++++++++++++++++++++ OpenSim/Region/Framework/Scenes/Scene.cs | 7 +- 2 files changed, 161 insertions(+), 1 deletion(-) create mode 100644 OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs new file mode 100644 index 0000000..be4f497 --- /dev/null +++ b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs @@ -0,0 +1,155 @@ +/* + * 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.Text; +using System.Text.RegularExpressions; +using log4net; +using Mono.Addins; +using NDesk.Options; +using Nini.Config; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Console; +using OpenSim.Framework.Statistics; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; + +namespace OpenSim.Region.CoreModules.World.Objects.Commands +{ + /// + /// A module that holds commands for manipulating objects in the scene. + /// + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "RegionCommandsModule")] + public class RegionCommandsModule : INonSharedRegionModule + { + private Scene m_scene; + private ICommandConsole m_console; + + public string Name { get { return "Region Commands Module"; } } + + public Type ReplaceableInterface { get { return null; } } + + public void Initialise(IConfigSource source) + { +// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: INITIALIZED MODULE"); + } + + public void PostInitialise() + { +// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: POST INITIALIZED MODULE"); + } + + public void Close() + { +// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: CLOSED MODULE"); + } + + public void AddRegion(Scene scene) + { +// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); + + m_scene = scene; + m_console = MainConsole.Instance; + + m_console.Commands.AddCommand( + "Regions", false, "show scene", + "show scene", + "Show live scene information for the currently selected region.", HandleShowScene); + } + + public void RemoveRegion(Scene scene) + { +// m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); + } + + public void RegionLoaded(Scene scene) + { +// m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); + } + + private void HandleShowScene(string module, string[] cmd) + { + if (!(MainConsole.Instance.ConsoleScene == null || MainConsole.Instance.ConsoleScene == m_scene)) + return; + + SimStatsReporter r = m_scene.StatsReporter; + float[] stats = r.LastReportedSimStats; + + float timeDilation = stats[0]; + float simFps = stats[1]; + float physicsFps = stats[2]; + float agentUpdates = stats[3]; + float rootAgents = stats[4]; + float childAgents = stats[5]; + float totalPrims = stats[6]; + float activePrims = stats[7]; + float totalFrameTime = stats[8]; +// float netFrameTime = stats.StatsBlock[9].StatValue; // Ignored - not used by OpenSimulator + float physicsFrameTime = stats[10]; + float otherFrameTime = stats[11]; +// float imageFrameTime = stats.StatsBlock[12].StatValue; // Ignored + float inPacketsPerSecond = stats[13]; + float outPacketsPerSecond = stats[14]; + float unackedBytes = stats[15]; +// float agentFrameTime = stats.StatsBlock[16].StatValue; // Not really used + float pendingDownloads = stats[17]; + float pendingUploads = stats[18]; + float activeScripts = stats[19]; + float scriptLinesPerSecond = stats[20]; + + StringBuilder sb = new StringBuilder(); + sb.AppendFormat("Scene statistics for {0}\n", m_scene.RegionInfo.RegionName); + + ConsoleDisplayList dispList = new ConsoleDisplayList(); + dispList.AddRow("Time Dilation", timeDilation); + dispList.AddRow("Sim FPS", simFps); + dispList.AddRow("Physics FPS", physicsFps); + dispList.AddRow("Avatars", rootAgents); + dispList.AddRow("Child agents", childAgents); + dispList.AddRow("Total prims", totalPrims); + dispList.AddRow("Scripts", activeScripts); + dispList.AddRow("Script lines processed per second", scriptLinesPerSecond); + dispList.AddRow("Physics enabled prims", activePrims); + dispList.AddRow("Total frame time", totalFrameTime); + dispList.AddRow("Physics frame time", physicsFrameTime); + dispList.AddRow("Other frame time", otherFrameTime); + dispList.AddRow("Agent Updates per second", agentUpdates); + dispList.AddRow("Packets processed from clients per second", inPacketsPerSecond); + dispList.AddRow("Packets sent to clients per second", outPacketsPerSecond); + dispList.AddRow("Bytes unacknowledged by clients", unackedBytes); + dispList.AddRow("Pending asset downloads to clients", pendingDownloads); + dispList.AddRow("Pending asset uploads from clients", pendingUploads); + + dispList.AddToStringBuilder(sb); + + MainConsole.Instance.Output(sb.ToString()); + } + } +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 5a0f564..fbe56f6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -77,7 +77,12 @@ namespace OpenSim.Region.Framework.Scenes public bool DebugUpdates { get; private set; } public SynchronizeSceneHandler SynchronizeScene; - public SimStatsReporter StatsReporter; + + /// + /// Statistical information for this scene. + /// + public SimStatsReporter StatsReporter { get; private set; } + public List NorthBorders = new List(); public List EastBorders = new List(); public List SouthBorders = new List(); -- cgit v1.1 From 4d1986c0e480466383fa0a79a1305fe108430d68 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 23 May 2012 04:20:54 +0100 Subject: minor: Change [OBJECT COMMANDS MODULE] log strings to [REGION COMMANDS MODULE] strings, though all these are currently commented out anyway --- .../Region/CoreModules/World/Region/RegionCommandsModule.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs index be4f497..2838e0c 100644 --- a/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs +++ b/OpenSim/Region/CoreModules/World/Region/RegionCommandsModule.cs @@ -58,22 +58,22 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands public void Initialise(IConfigSource source) { -// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: INITIALIZED MODULE"); +// m_log.DebugFormat("[REGION COMMANDS MODULE]: INITIALIZED MODULE"); } public void PostInitialise() { -// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: POST INITIALIZED MODULE"); +// m_log.DebugFormat("[REGION COMMANDS MODULE]: POST INITIALIZED MODULE"); } public void Close() { -// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: CLOSED MODULE"); +// m_log.DebugFormat("[REGION COMMANDS MODULE]: CLOSED MODULE"); } public void AddRegion(Scene scene) { -// m_log.DebugFormat("[OBJECT COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); +// m_log.DebugFormat("[REGION COMMANDS MODULE]: REGION {0} ADDED", scene.RegionInfo.RegionName); m_scene = scene; m_console = MainConsole.Instance; @@ -86,12 +86,12 @@ namespace OpenSim.Region.CoreModules.World.Objects.Commands public void RemoveRegion(Scene scene) { -// m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); +// m_log.DebugFormat("[REGION COMMANDS MODULE]: REGION {0} REMOVED", scene.RegionInfo.RegionName); } public void RegionLoaded(Scene scene) { -// m_log.DebugFormat("[OBJECTS COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); +// m_log.DebugFormat("[REGION COMMANDS MODULE]: REGION {0} LOADED", scene.RegionInfo.RegionName); } private void HandleShowScene(string module, string[] cmd) -- cgit v1.1 From 682d4075e3fe7c52d4c29d00ba9dc0456b7322f3 Mon Sep 17 00:00:00 2001 From: BlueWall Date: Wed, 23 May 2012 15:07:03 -0400 Subject: Fix llGetSimulatorHostname to return configured hostname --- OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs | 4 ++++ OpenSim/Region/Framework/Interfaces/IUrlModule.cs | 1 + OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | 3 ++- 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs index d58fc0f..d2cd163 100644 --- a/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LSLHttp/UrlModule.cs @@ -84,6 +84,10 @@ namespace OpenSim.Region.CoreModules.Scripting.LSLHttp private IHttpServer m_HttpsServer = null; private string m_ExternalHostNameForLSL = ""; + public string ExternalHostNameForLSL + { + get { return m_ExternalHostNameForLSL; } + } public Type ReplaceableInterface { diff --git a/OpenSim/Region/Framework/Interfaces/IUrlModule.cs b/OpenSim/Region/Framework/Interfaces/IUrlModule.cs index 1b91166..457444c 100644 --- a/OpenSim/Region/Framework/Interfaces/IUrlModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IUrlModule.cs @@ -34,6 +34,7 @@ namespace OpenSim.Region.Framework.Interfaces { public interface IUrlModule { + string ExternalHostNameForLSL { get; } UUID RequestURL(IScriptModule engine, SceneObjectPart host, UUID itemID); UUID RequestSecureURL(IScriptModule engine, SceneObjectPart host, UUID itemID); void ReleaseURL(string url); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index d213c35..4b28808 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -8743,7 +8743,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api public LSL_String llGetSimulatorHostname() { m_host.AddScriptLPS(1); - return System.Environment.MachineName; + IUrlModule UrlModule = World.RequestModuleInterface(); + return UrlModule.ExternalHostNameForLSL; } // -- cgit v1.1 From bc543c1797c629a8584dd2e74d3c5f7a67de96c9 Mon Sep 17 00:00:00 2001 From: PixelTomsen Date: Wed, 23 May 2012 21:06:25 +0200 Subject: Environment Module - allows Environment settings for Viewer3 warning: includes database region store migrations for mssql, mysql, sqlite enable/disable this module: Cap_EnvironmentSettings = "localhost" (for enable) Cap_EnvironmentSettings = "" (for disable) at ClientStack.LindenCaps section (OpenSimDefaults.ini file) or owerwrite in OpenSim.ini mantis: http://opensimulator.org/mantis/view.php?id=5860 Signed-off-by: BlueWall --- .../CoreModules/LightShare/EnvironmentModule.cs | 224 +++++++++++++++++++++ .../Framework/Interfaces/IEnvironmentModule.cs | 36 ++++ .../Framework/Interfaces/ISimulationDataService.cs | 21 ++ .../Framework/Interfaces/ISimulationDataStore.cs | 20 ++ 4 files changed, 301 insertions(+) create mode 100644 OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs create mode 100644 OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs b/OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs new file mode 100644 index 0000000..1526886 --- /dev/null +++ b/OpenSim/Region/CoreModules/LightShare/EnvironmentModule.cs @@ -0,0 +1,224 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSimulator Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +using System; +using System.Reflection; +using OpenMetaverse; +using OpenSim.Framework; +using OpenSim.Framework.Capabilities; +using OpenSim.Framework.Servers.HttpServer; +using OpenSim.Region.Framework.Interfaces; +using OpenSim.Region.Framework.Scenes; +using log4net; +using Nini.Config; +using Mono.Addins; + +using Caps = OpenSim.Framework.Capabilities.Caps; + + +namespace OpenSim.Region.CoreModules.World.LightShare +{ + [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "EnvironmentModule")] + + public class EnvironmentModule : INonSharedRegionModule, IEnvironmentModule + { + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + + private Scene m_scene = null; + private UUID regionID = UUID.Zero; + private static bool Enabled = false; + + private static readonly string capsName = "EnvironmentSettings"; + private static readonly string capsBase = "/CAPS/0020/"; + + private LLSDEnvironmentSetResponse setResponse = null; + + #region INonSharedRegionModule + public void Initialise(IConfigSource source) + { + IConfig config = source.Configs["ClientStack.LindenCaps"]; + + if (null == config) + return; + + if (config.GetString("Cap_EnvironmentSettings", String.Empty) != "localhost") + { + m_log.InfoFormat("[{0}]: Module is disabled.", Name); + return; + } + + Enabled = true; + + m_log.InfoFormat("[{0}]: Module is enabled.", Name); + } + + public void Close() + { + } + + public string Name + { + get { return "EnvironmentModule"; } + } + + public Type ReplaceableInterface + { + get { return null; } + } + + public void AddRegion(Scene scene) + { + if (!Enabled) + return; + + scene.RegisterModuleInterface(this); + m_scene = scene; + regionID = scene.RegionInfo.RegionID; + } + + public void RegionLoaded(Scene scene) + { + if (!Enabled) + return; + + setResponse = new LLSDEnvironmentSetResponse(); + scene.EventManager.OnRegisterCaps += OnRegisterCaps; + } + + public void RemoveRegion(Scene scene) + { + if (Enabled) + return; + + scene.EventManager.OnRegisterCaps -= OnRegisterCaps; + m_scene = null; + } + #endregion + + #region IEnvironmentModule + public void ResetEnvironmentSettings(UUID regionUUID) + { + if (!Enabled) + return; + + m_scene.SimulationDataService.RemoveRegionEnvironmentSettings(regionUUID); + } + #endregion + + #region Events + private void OnRegisterCaps(UUID agentID, Caps caps) + { +// m_log.DebugFormat("[{0}]: Register capability for agentID {1} in region {2}", +// Name, agentID, caps.RegionName); + + string capsPath = capsBase + UUID.Random(); + + // Get handler + caps.RegisterHandler( + capsName, + new RestStreamHandler( + "GET", + capsPath, + (request, path, param, httpRequest, httpResponse) + => GetEnvironmentSettings(request, path, param, agentID, caps), + capsName, + agentID.ToString())); + + // Set handler + caps.HttpListener.AddStreamHandler( + new RestStreamHandler( + "POST", + capsPath, + (request, path, param, httpRequest, httpResponse) + => SetEnvironmentSettings(request, path, param, agentID, caps), + capsName, + agentID.ToString())); + } + #endregion + + private string GetEnvironmentSettings(string request, string path, string param, + UUID agentID, Caps caps) + { +// m_log.DebugFormat("[{0}]: Environment GET handle for agentID {1} in region {2}", +// Name, agentID, caps.RegionName); + + string env = String.Empty; + + try + { + env = m_scene.SimulationDataService.LoadRegionEnvironmentSettings(regionID); + } + catch (Exception e) + { + m_log.ErrorFormat("[{0}]: Unable to load environment settings for region {1}, Exception: {2} - {3}", + Name, caps.RegionName, e.Message, e.StackTrace); + } + + if (String.IsNullOrEmpty(env)) + env = EnvironmentSettings.EmptySettings(UUID.Zero, regionID); + + return env; + } + + private string SetEnvironmentSettings(string request, string path, string param, + UUID agentID, Caps caps) + { + +// m_log.DebugFormat("[{0}]: Environment SET handle from agentID {1} in region {2}", +// Name, agentID, caps.RegionName); + + setResponse.regionID = regionID; + setResponse.success = false; + + if (!m_scene.Permissions.CanIssueEstateCommand(agentID, false)) + { + setResponse.fail_reason = "Insufficient estate permissions, settings has not been saved."; + return LLSDHelpers.SerialiseLLSDReply(setResponse); + } + + try + { + m_scene.SimulationDataService.StoreRegionEnvironmentSettings(regionID, request); + setResponse.success = true; + + m_log.InfoFormat("[{0}]: New Environment settings has been saved from agentID {1} in region {2}", + Name, agentID, caps.RegionName); + } + catch (Exception e) + { + m_log.ErrorFormat("[{0}]: Environment settings has not been saved for region {1}, Exception: {2} - {3}", + Name, caps.RegionName, e.Message, e.StackTrace); + + setResponse.success = false; + setResponse.fail_reason = String.Format("Environment Set for region {0} has failed, settings has not been saved.", caps.RegionName); + } + + return LLSDHelpers.SerialiseLLSDReply(setResponse); + } + } +} + diff --git a/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs b/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs new file mode 100644 index 0000000..7a7b782 --- /dev/null +++ b/OpenSim/Region/Framework/Interfaces/IEnvironmentModule.cs @@ -0,0 +1,36 @@ +/* + * 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 OpenMetaverse; + +namespace OpenSim.Region.Framework.Interfaces +{ + public interface IEnvironmentModule + { + void ResetEnvironmentSettings(UUID regionUUID); + } +} diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs index 5295a72..0fcafcc 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataService.cs @@ -95,5 +95,26 @@ namespace OpenSim.Region.Framework.Interfaces RegionLightShareData LoadRegionWindlightSettings(UUID regionUUID); void StoreRegionWindlightSettings(RegionLightShareData wl); void RemoveRegionWindlightSettings(UUID regionID); + + /// + /// Load Environment settings from region storage + /// + /// the region UUID + /// LLSD string for viewer + string LoadRegionEnvironmentSettings(UUID regionUUID); + + /// + /// Store Environment settings into region storage + /// + /// the region UUID + /// LLSD string from viewer + void StoreRegionEnvironmentSettings(UUID regionUUID, string settings); + + /// + /// Delete Environment settings from region storage + /// + /// the region UUID + void RemoveRegionEnvironmentSettings(UUID regionUUID); + } } diff --git a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs index 615f377..e424976 100644 --- a/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs +++ b/OpenSim/Region/Framework/Interfaces/ISimulationDataStore.cs @@ -107,6 +107,26 @@ namespace OpenSim.Region.Framework.Interfaces void StoreRegionWindlightSettings(RegionLightShareData wl); void RemoveRegionWindlightSettings(UUID regionID); + /// + /// Load Environment settings from region storage + /// + /// the region UUID + /// LLSD string for viewer + string LoadRegionEnvironmentSettings(UUID regionUUID); + + /// + /// Store Environment settings into region storage + /// + /// the region UUID + /// LLSD string from viewer + void StoreRegionEnvironmentSettings(UUID regionUUID, string settings); + + /// + /// Delete Environment settings from region storage + /// + /// the region UUID + void RemoveRegionEnvironmentSettings(UUID regionUUID); + void Shutdown(); } } -- cgit v1.1 From 459c7635afdbc4002cacbf5780185645a4296f6a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 May 2012 00:31:14 +0100 Subject: If an agent is still registered as 'in transit' by the source region, don't allow an immediate teleport back. This is to help relieve a race condition when an agent teleports then immediately attempts to teleport back before the source region has properly cleaned up/demoted the old ScenePresence. This is rare in viewers but much more possible via scripting or region module. However, more needs to be done since virtually all clean up happens after the transit flag is cleared . Possibly need to add a 'cleaning up' state to in transit. This change required making the EntityTransferModule and HGEntityTransferModule per-region rather than shared, in order to allow separate transit lists. Changes were also required in LocalSimulationConnector. Tested in standalone, grid and with local and remote region crossings with attachments. --- .../EntityTransfer/EntityTransferModule.cs | 69 ++++---- .../EntityTransfer/HGEntityTransferModule.cs | 55 +++--- .../Simulation/LocalSimulationConnector.cs | 186 +++++++++++---------- .../Framework/Interfaces/IEntityTransferModule.cs | 7 + OpenSim/Region/Framework/Scenes/Scene.cs | 67 +++++--- .../Scenes/Tests/ScenePresenceTeleportTests.cs | 42 +++-- 6 files changed, 233 insertions(+), 193 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 36e9da6..408d63d 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -46,7 +46,7 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { - public class EntityTransferModule : ISharedRegionModule, IEntityTransferModule + public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -65,9 +65,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public bool EnableWaitForCallbackFromTeleportDest { get; set; } protected bool m_Enabled = false; - protected Scene m_aScene; - protected List m_Scenes = new List(); + + protected Scene m_scene; + protected List m_agentsInTransit; + private ExpiringCache> m_bannedRegions = new ExpiringCache>(); @@ -129,10 +131,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!m_Enabled) return; - if (m_aScene == null) - m_aScene = scene; + m_scene = scene; - m_Scenes.Add(scene); scene.RegisterModuleInterface(this); scene.EventManager.OnNewClient += OnNewClient; } @@ -143,27 +143,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer client.OnTeleportLandmarkRequest += RequestTeleportLandmark; } - public virtual void Close() - { - if (!m_Enabled) - return; - } + public virtual void Close() {} - public virtual void RemoveRegion(Scene scene) - { - if (!m_Enabled) - return; - if (scene == m_aScene) - m_aScene = null; + public virtual void RemoveRegion(Scene scene) {} - m_Scenes.Remove(scene); - } - - public virtual void RegionLoaded(Scene scene) - { - if (!m_Enabled) - return; - } + public virtual void RegionLoaded(Scene scene) {} #endregion @@ -294,7 +278,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { 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); + GridRegion reg = m_scene.GridService.GetRegionByPosition(sp.Scene.RegionInfo.ScopeID, (int)x, (int)y); if (reg != null) { @@ -441,7 +425,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer string reason; string version; - if (!m_aScene.SimulationService.QueryAccess( + if (!m_scene.SimulationService.QueryAccess( finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) { sp.ControllingClient.SendTeleportFailed(reason); @@ -660,7 +644,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer EnableChildAgents(sp); // Finally, kill the agent we just created at the destination. - m_aScene.SimulationService.CloseAgent(finalDestination, sp.UUID); + m_scene.SimulationService.CloseAgent(finalDestination, sp.UUID); sp.Scene.EventManager.TriggerTeleportFail(sp.ControllingClient, logout); } @@ -668,7 +652,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual bool CreateAgent(ScenePresence sp, GridRegion reg, GridRegion finalDestination, AgentCircuitData agentCircuit, uint teleportFlags, out string reason, out bool logout) { logout = false; - bool success = m_aScene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); + bool success = m_scene.SimulationService.CreateAgent(finalDestination, agentCircuit, teleportFlags, out reason); if (success) sp.Scene.EventManager.TriggerTeleportStart(sp.ControllingClient, reg, finalDestination, teleportFlags, logout); @@ -678,7 +662,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected virtual bool UpdateAgent(GridRegion reg, GridRegion finalDestination, AgentData agent) { - return m_aScene.SimulationService.UpdateAgent(finalDestination, agent); + return m_scene.SimulationService.UpdateAgent(finalDestination, agent); } protected virtual void SetCallbackURL(AgentData agent, RegionInfo region) @@ -730,7 +714,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return false; } - #endregion #region Landmark Teleport @@ -742,7 +725,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// public virtual void RequestTeleportLandmark(IClientAPI remoteClient, AssetLandmark lm) { - GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); + GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); if (info == null) { @@ -763,12 +746,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); - //OpenSim.Services.Interfaces.PresenceInfo pinfo = m_aScene.PresenceService.GetAgent(client.SessionId); - GridUserInfo uinfo = m_aScene.GridUserService.GetGridUserInfo(client.AgentId.ToString()); + //OpenSim.Services.Interfaces.PresenceInfo pinfo = m_scene.PresenceService.GetAgent(client.SessionId); + GridUserInfo uinfo = m_scene.GridUserService.GetGridUserInfo(client.AgentId.ToString()); if (uinfo != null) { - GridRegion regionInfo = m_aScene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); + GridRegion regionInfo = m_scene.GridService.GetRegionByUUID(UUID.Zero, uinfo.HomeRegionID); if (regionInfo == null) { // can't find the Home region: Tell viewer and abort @@ -1625,7 +1608,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Agent Arrived public void AgentArrivedAtDestination(UUID id) { - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Agent {0} released", id); ResetFromTransit(id); } @@ -1896,8 +1878,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer //// 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, newPosition, grp, true); + if (m_scene.SimulationService != null) + successYN = m_scene.SimulationService.CreateObject(destination, newPosition, grp, true); if (successYN) { @@ -2004,7 +1986,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer /// /// true if the agent is in the process of being teleported, false otherwise. /// The agent ID - protected bool IsInTransit(UUID id) + public bool IsInTransit(UUID id) { lock (m_agentsInTransit) return m_agentsInTransit.Contains(id); @@ -2024,10 +2006,19 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (m_agentsInTransit.Contains(id)) { m_agentsInTransit.Remove(id); + + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Agent {0} cleared from transit in {1}", + id, m_scene.RegionInfo.RegionName); + return true; } } + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Agent {0} requested to clear from transit in {1} but was already cleared.", + id, m_scene.RegionInfo.RegionName); + return false; } diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index b578bcb..4124667 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -45,11 +45,11 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { - public class HGEntityTransferModule : EntityTransferModule, ISharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule + public class HGEntityTransferModule + : EntityTransferModule, INonSharedRegionModule, IEntityTransferModule, IUserAgentVerificationModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - private bool m_Initialized = false; private int m_levelHGTeleport = 0; private GatekeeperServiceConnector m_GatekeeperConnector; @@ -64,6 +64,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public override void Initialise(IConfigSource source) { IConfig moduleConfig = source.Configs["Modules"]; + if (moduleConfig != null) { string name = moduleConfig.GetString("EntityTransferModule", ""); @@ -82,10 +83,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public override void AddRegion(Scene scene) { base.AddRegion(scene); + if (m_Enabled) - { scene.RegisterModuleInterface(this); - } } protected override void OnNewClient(IClientAPI client) @@ -98,33 +98,28 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public override void RegionLoaded(Scene scene) { base.RegionLoaded(scene); - if (m_Enabled) - if (!m_Initialized) - { - m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); - m_Initialized = true; - - } + if (m_Enabled) + m_GatekeeperConnector = new GatekeeperServiceConnector(scene.AssetService); } + public override void RemoveRegion(Scene scene) { base.AddRegion(scene); + if (m_Enabled) - { scene.UnregisterModuleInterface(this); - } } - #endregion #region HG overrides of IEntiryTransferModule protected override GridRegion GetFinalDestination(GridRegion region) { - int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, region.RegionID); + int flags = m_scene.GridService.GetRegionFlags(m_scene.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); @@ -135,6 +130,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.WarnFormat("[HG ENTITY TRANSFER MODULE]: GetHyperlinkRegion to Gatekeeper {0} failed", region.ServerURI); return real_destination; } + return region; } @@ -143,7 +139,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (base.NeedsClosing(drawdist, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) return true; - int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); + int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, reg.RegionID); if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) return true; @@ -156,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (logout) { // Log them out of this grid - m_aScene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); + m_scene.PresenceService.LogoutAgent(sp.ControllingClient.SessionId); } } @@ -165,7 +161,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: CreateAgent {0} {1}", reg.ServerURI, finalDestination.ServerURI); reason = string.Empty; logout = false; - int flags = m_aScene.GridService.GetRegionFlags(m_aScene.RegionInfo.ScopeID, reg.RegionID); + int flags = m_scene.GridService.GetRegionFlags(m_scene.RegionInfo.ScopeID, reg.RegionID); if (flags == -1 /* no region in DB */ || (flags & (int)OpenSim.Data.RegionFlags.Hyperlink) != 0) { // this user is going to another grid @@ -205,7 +201,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Request to teleport {0} {1} home", client.Name, client.AgentId); // Let's find out if this is a foreign user or a local user - IUserManagement uMan = m_aScene.RequestModuleInterface(); + IUserManagement uMan = m_scene.RequestModuleInterface(); if (uMan != null && uMan.IsLocalGridUser(id)) { // local grid user @@ -262,19 +258,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Teleporting agent via landmark to {0} region {1} position {2}", (lm.Gatekeeper == string.Empty) ? "local" : lm.Gatekeeper, lm.RegionID, lm.Position); + if (lm.Gatekeeper == string.Empty) { base.RequestTeleportLandmark(remoteClient, lm); return; } - GridRegion info = m_aScene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); + GridRegion info = m_scene.GridService.GetRegionByUUID(UUID.Zero, lm.RegionID); // Local region? if (info != null) { ((Scene)(remoteClient.Scene)).RequestTeleportLocation(remoteClient, info.RegionHandle, lm.Position, Vector3.Zero, (uint)(Constants.TeleportFlags.SetLastToTarget | Constants.TeleportFlags.ViaLandmark)); + return; } else @@ -285,6 +283,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer GridRegion gatekeeper = new GridRegion(); gatekeeper.ServerURI = lm.Gatekeeper; GridRegion finalDestination = gConn.GetHyperlinkRegion(gatekeeper, new UUID(lm.RegionID)); + if (finalDestination != null) { ScenePresence sp = scene.GetScenePresence(remoteClient.AgentId); @@ -314,8 +313,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer IUserAgentService security = new UserAgentServiceConnector(url); return security.VerifyClient(aCircuit.SessionID, token); } - else - m_log.DebugFormat("[HG ENTITY TRANSFER MODULE]: Agent {0} {1} does not have a HomeURI OH NO!", aCircuit.firstname, aCircuit.lastname); + else + { + m_log.DebugFormat( + "[HG ENTITY TRANSFER MODULE]: Agent {0} {1} does not have a HomeURI OH NO!", + aCircuit.firstname, aCircuit.lastname); + } return false; } @@ -332,8 +335,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } // Let's find out if this is a foreign user or a local user - IUserManagement uMan = m_aScene.RequestModuleInterface(); - UserAccount account = m_aScene.UserAccountService.GetUserAccount(m_aScene.RegionInfo.ScopeID, obj.AgentId); + IUserManagement uMan = m_scene.RequestModuleInterface(); + UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, obj.AgentId); if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) { // local grid user @@ -356,7 +359,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion - private GridRegion MakeRegion(AgentCircuitData aCircuit) { GridRegion region = new GridRegion(); @@ -373,6 +375,5 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer region.InternalEndPoint = new System.Net.IPEndPoint(System.Net.IPAddress.Parse("0.0.0.0"), (int)0); return region; } - } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 90f27c4..270daad 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs @@ -26,6 +26,7 @@ */ using System; using System.Collections.Generic; +using System.Linq; using System.Reflection; using log4net; using Nini.Config; @@ -41,22 +42,20 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation public class LocalSimulationConnectorModule : ISharedRegionModule, ISimulationService { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); - // Version of this service - private const string m_Version = "SIMULATION/0.1"; - private List m_sceneList = new List(); + /// + /// Version of this service + /// + private const string m_Version = "SIMULATION/0.1"; - private IEntityTransferModule m_AgentTransferModule; - protected IEntityTransferModule AgentTransferModule - { - get - { - if (m_AgentTransferModule == null) - m_AgentTransferModule = m_sceneList[0].RequestModuleInterface(); - return m_AgentTransferModule; - } - } + /// + /// Map region ID to scene. + /// + private Dictionary m_scenes = new Dictionary(); + /// + /// Is this module enabled? + /// private bool m_ModuleEnabled = false; #region IRegionModule @@ -129,12 +128,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation /// public void RemoveScene(Scene scene) { - lock (m_sceneList) + lock (m_scenes) { - if (m_sceneList.Contains(scene)) - { - m_sceneList.Remove(scene); - } + if (m_scenes.ContainsKey(scene.RegionInfo.RegionID)) + m_scenes.Remove(scene.RegionInfo.RegionID); + else + m_log.WarnFormat( + "[LOCAL SIMULATION CONNECTOR]: Tried to remove region {0} but it was not present", + scene.RegionInfo.RegionName); } } @@ -144,13 +145,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation /// public void Init(Scene scene) { - if (!m_sceneList.Contains(scene)) + lock (m_scenes) { - lock (m_sceneList) - { - m_sceneList.Add(scene); - } - + if (!m_scenes.ContainsKey(scene.RegionInfo.RegionID)) + m_scenes[scene.RegionInfo.RegionID] = scene; + else + m_log.WarnFormat( + "[LOCAL SIMULATION CONNECTOR]: Tried to add region {0} but it is already present", + scene.RegionInfo.RegionName); } } @@ -160,13 +162,14 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation public IScene GetScene(ulong regionhandle) { - foreach (Scene s in m_sceneList) + foreach (Scene s in m_scenes.Values) { if (s.RegionInfo.RegionHandle == regionhandle) return s; } + // ? weird. should not happen - return m_sceneList[0]; + return m_scenes.Values.ToArray()[0]; } public ISimulationService GetInnerService() @@ -187,13 +190,10 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return false; } - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionHandle == destination.RegionHandle) - { // m_log.DebugFormat("[LOCAL SIMULATION CONNECTOR]: Found region {0} to send SendCreateChildAgent", destination.RegionName); - return s.NewUserConnection(aCircuit, teleportFlags, out reason); - } + return m_scenes[destination.RegionID].NewUserConnection(aCircuit, teleportFlags, out reason); } reason = "Did not find region " + destination.RegionName; @@ -205,17 +205,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionHandle == destination.RegionHandle) - { // m_log.DebugFormat( // "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", // s.RegionInfo.RegionName, destination.RegionHandle); - s.IncomingChildAgentDataUpdate(cAgentData); - return true; - } + return m_scenes[destination.RegionID].IncomingChildAgentDataUpdate(cAgentData); } // m_log.DebugFormat("[LOCAL COMMS]: Did not find region {0} for ChildAgentUpdate", regionHandle); @@ -231,11 +227,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation // simulator so when we receive the update we need to hand it to each of the // scenes; scenes each check to see if the is a scene presence for the avatar // note that we really don't need the GridRegion for this call - foreach (Scene s in m_sceneList) + foreach (Scene s in m_scenes.Values) { //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); s.IncomingChildAgentDataUpdate(cAgentData); } + //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); return true; } @@ -247,14 +244,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionHandle == destination.RegionHandle) - { - //m_log.Debug("[LOCAL COMMS]: Found region to send ChildAgentUpdate"); - return s.IncomingRetrieveRootAgent(id, out agent); - } +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + return m_scenes[destination.RegionID].IncomingRetrieveRootAgent(id, out agent); } + //m_log.Debug("[LOCAL COMMS]: region not found for ChildAgentUpdate"); return false; } @@ -266,27 +264,31 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionID == destination.RegionID) - return s.QueryAccess(id, position, out reason); +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + return m_scenes[destination.RegionID].QueryAccess(id, position, out reason); } + //m_log.Debug("[LOCAL COMMS]: region not found for QueryAccess"); return false; } - public bool ReleaseAgent(UUID origin, UUID id, string uri) + public bool ReleaseAgent(UUID originId, UUID agentId, string uri) { - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(originId)) { - if (s.RegionInfo.RegionID == origin) - { -// m_log.Debug("[LOCAL COMMS]: Found region to SendReleaseAgent"); - AgentTransferModule.AgentArrivedAtDestination(id); - return true; -// return s.IncomingReleaseAgent(id); - } +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + m_scenes[originId].EntityTransferModule.AgentArrivedAtDestination(agentId); + return true; } + //m_log.Debug("[LOCAL COMMS]: region not found in SendReleaseAgent " + origin); return false; } @@ -296,17 +298,16 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionID == destination.RegionID) - { - //m_log.Debug("[LOCAL COMMS]: Found region to SendCloseAgent"); - // Let's spawn a threadlet right here, because this may take - // a while - Util.FireAndForget(delegate { s.IncomingCloseAgent(id); }); - return true; - } +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + Util.FireAndForget(delegate { m_scenes[destination.RegionID].IncomingCloseAgent(id); }); + return true; } + //m_log.Debug("[LOCAL COMMS]: region not found in SendCloseAgent"); return false; } @@ -320,25 +321,28 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionHandle == destination.RegionHandle) +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + Scene s = m_scenes[destination.RegionID]; + + if (isLocalCall) { - //m_log.Debug("[LOCAL COMMS]: Found region to SendCreateObject"); - if (isLocalCall) - { - // We need to make a local copy of the object - ISceneObject sogClone = sog.CloneForNewScene(); - sogClone.SetState(sog.GetStateSnapshot(), s); - return s.IncomingCreateObject(newPosition, sogClone); - } - else - { - // Use the object as it came through the wire - return s.IncomingCreateObject(newPosition, sog); - } + // We need to make a local copy of the object + ISceneObject sogClone = sog.CloneForNewScene(); + sogClone.SetState(sog.GetStateSnapshot(), s); + return s.IncomingCreateObject(newPosition, sogClone); + } + else + { + // Use the object as it came through the wire + return s.IncomingCreateObject(newPosition, sog); } } + return false; } @@ -347,13 +351,15 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation if (destination == null) return false; - foreach (Scene s in m_sceneList) + if (m_scenes.ContainsKey(destination.RegionID)) { - if (s.RegionInfo.RegionHandle == destination.RegionHandle) - { - return s.IncomingCreateObject(userID, itemID); - } +// m_log.DebugFormat( +// "[LOCAL SIMULATION CONNECTOR]: Found region {0} {1} to send AgentUpdate", +// s.RegionInfo.RegionName, destination.RegionHandle); + + return m_scenes[destination.RegionID].IncomingCreateObject(userID, itemID); } + return false; } @@ -364,20 +370,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation public bool IsLocalRegion(ulong regionhandle) { - foreach (Scene s in m_sceneList) + foreach (Scene s in m_scenes.Values) if (s.RegionInfo.RegionHandle == regionhandle) return true; + return false; } public bool IsLocalRegion(UUID id) { - foreach (Scene s in m_sceneList) - if (s.RegionInfo.RegionID == id) - return true; - return false; + return m_scenes.ContainsKey(id); } #endregion } -} +} \ No newline at end of file diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index 18e9e3c..75c44d5 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -74,6 +74,13 @@ namespace OpenSim.Region.Framework.Interfaces /// void TeleportHome(UUID id, IClientAPI client); + /// + /// Show whether the given agent is being teleported. + /// + /// true if the agent is in the process of being teleported, false otherwise. + /// The agent ID + bool IsInTransit(UUID id); + bool Cross(ScenePresence agent, bool isFlying); void AgentArrivedAtDestination(UUID agent); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index fbe56f6..755b1e6 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -166,7 +166,6 @@ namespace OpenSim.Region.Framework.Scenes protected IConfigSource m_config; protected IRegionSerialiserModule m_serialiser; protected IDialogModule m_dialogModule; - protected IEntityTransferModule m_teleportModule; protected ICapabilitiesModule m_capsModule; protected IGroupsModule m_groupsModule; @@ -498,6 +497,7 @@ namespace OpenSim.Region.Framework.Scenes } public IAttachmentsModule AttachmentsModule { get; set; } + public IEntityTransferModule EntityTransferModule { get; private set; } public IAvatarFactoryModule AvatarFactory { @@ -924,8 +924,8 @@ namespace OpenSim.Region.Framework.Scenes List old = new List(); old.Add(otherRegion.RegionHandle); agent.DropOldNeighbours(old); - if (m_teleportModule != null && agent.PresenceType != PresenceType.Npc) - m_teleportModule.EnableChildAgent(agent, otherRegion); + if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc) + EntityTransferModule.EnableChildAgent(agent, otherRegion); }); } catch (NullReferenceException) @@ -1062,8 +1062,8 @@ namespace OpenSim.Region.Framework.Scenes { ForEachRootScenePresence(delegate(ScenePresence agent) { - if (m_teleportModule != null && agent.PresenceType != PresenceType.Npc) - m_teleportModule.EnableChildAgent(agent, r); + if (EntityTransferModule != null && agent.PresenceType != PresenceType.Npc) + EntityTransferModule.EnableChildAgent(agent, r); }); } catch (NullReferenceException) @@ -1238,7 +1238,7 @@ namespace OpenSim.Region.Framework.Scenes m_serialiser = RequestModuleInterface(); m_dialogModule = RequestModuleInterface(); m_capsModule = RequestModuleInterface(); - m_teleportModule = RequestModuleInterface(); + EntityTransferModule = RequestModuleInterface(); m_groupsModule = RequestModuleInterface(); } @@ -2275,8 +2275,8 @@ namespace OpenSim.Region.Framework.Scenes return; } - if (m_teleportModule != null) - m_teleportModule.Cross(grp, attemptedPosition, silent); + if (EntityTransferModule != null) + EntityTransferModule.Cross(grp, attemptedPosition, silent); } public Border GetCrossedBorder(Vector3 position, Cardinals gridline) @@ -3078,8 +3078,10 @@ namespace OpenSim.Region.Framework.Scenes /// The IClientAPI for the client public virtual void TeleportClientHome(UUID agentId, IClientAPI client) { - if (m_teleportModule != null) - m_teleportModule.TeleportHome(agentId, client); + if (EntityTransferModule != null) + { + EntityTransferModule.TeleportHome(agentId, client); + } else { m_log.DebugFormat("[SCENE]: Unable to teleport user home: no AgentTransferModule is active"); @@ -3638,7 +3640,6 @@ namespace OpenSim.Region.Framework.Scenes private bool TestLandRestrictions(AgentCircuitData agent, ILandObject land, out string reason) { - bool banned = land.IsBannedFromLand(agent.AgentID); bool restricted = land.IsRestrictedFromLand(agent.AgentID); @@ -4131,8 +4132,10 @@ namespace OpenSim.Region.Framework.Scenes position.Y -= shifty; } - if (m_teleportModule != null) - m_teleportModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags); + if (EntityTransferModule != null) + { + EntityTransferModule.Teleport(sp, regionHandle, position, lookAt, teleportFlags); + } else { m_log.DebugFormat("[SCENE]: Unable to perform teleports: no AgentTransferModule is active"); @@ -4143,8 +4146,10 @@ namespace OpenSim.Region.Framework.Scenes public bool CrossAgentToNewRegion(ScenePresence agent, bool isFlying) { - if (m_teleportModule != null) - return m_teleportModule.Cross(agent, isFlying); + if (EntityTransferModule != null) + { + return EntityTransferModule.Cross(agent, isFlying); + } else { m_log.DebugFormat("[SCENE]: Unable to cross agent to neighbouring region, because there is no AgentTransferModule"); @@ -5188,14 +5193,34 @@ namespace OpenSim.Region.Framework.Scenes throw new Exception(error); } - // This method is called across the simulation connector to - // determine if a given agent is allowed in this region - // AS A ROOT AGENT. Returning false here will prevent them - // from logging into the region, teleporting into the region - // or corssing the broder walking, but will NOT prevent - // child agent creation, thereby emulating the SL behavior. + /// + /// This method is called across the simulation connector to + /// determine if a given agent is allowed in this region + /// AS A ROOT AGENT + /// + /// + /// Returning false here will prevent them + /// from logging into the region, teleporting into the region + /// or corssing the broder walking, but will NOT prevent + /// child agent creation, thereby emulating the SL behavior. + /// + /// + /// + /// + /// public bool QueryAccess(UUID agentID, Vector3 position, out string reason) { + if (EntityTransferModule.IsInTransit(agentID)) + { + reason = "Agent is already in transit on this region"; + + m_log.DebugFormat( + "[SCENE]: Denying agent {0} entry into {1} since region already has them registered as in transit", + agentID, RegionInfo.RegionName); + + return false; + } + // FIXME: Root agent count is currently known to be inaccurate. This forces a recount before we check. // However, the long term fix is to make sure root agent count is always accurate. m_sceneGraph.RecalculateStats(); diff --git a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs index 41bff7f..ccfe4ff 100644 --- a/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs +++ b/OpenSim/Region/Framework/Scenes/Tests/ScenePresenceTeleportTests.cs @@ -110,12 +110,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = TestHelpers.ParseTail(0x1); - EntityTransferModule etm = new EntityTransferModule(); + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); IConfig modulesConfig = config.AddConfig("Modules"); - modulesConfig.Set("EntityTransferModule", etm.Name); + modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("SimulationServices", lscm.Name); IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); @@ -127,7 +128,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000); - SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); + SceneHelpers.SetupSceneModules(sceneA, config, etmA); + SceneHelpers.SetupSceneModules(sceneB, config, etmB); + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); @@ -174,12 +177,14 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = TestHelpers.ParseTail(0x1); Vector3 preTeleportPosition = new Vector3(30, 31, 32); - EntityTransferModule etm = new EntityTransferModule(); + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); + LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); - config.Configs["Modules"].Set("EntityTransferModule", etm.Name); + config.Configs["Modules"].Set("EntityTransferModule", etmA.Name); config.Configs["Modules"].Set("SimulationServices", lscm.Name); config.AddConfig("EntityTransfer"); @@ -195,13 +200,15 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000); + SceneHelpers.SetupSceneModules(sceneA, config, etmA ); + // We need to set up the permisions module on scene B so that our later use of agent limit to deny // QueryAccess won't succeed anyway because administrators are always allowed in and the default // IsAdministrator if no permissions module is present is true. - SceneHelpers.SetupSceneModules(sceneB, config, new object[] { new PermissionsModule() }); + SceneHelpers.SetupSceneModules(sceneB, config, new object[] { new PermissionsModule(), etmB }); // Shared scene modules - SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); @@ -249,12 +256,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = TestHelpers.ParseTail(0x1); Vector3 preTeleportPosition = new Vector3(30, 31, 32); - EntityTransferModule etm = new EntityTransferModule(); + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); config.AddConfig("Modules"); - config.Configs["Modules"].Set("EntityTransferModule", etm.Name); + config.Configs["Modules"].Set("EntityTransferModule", etmA.Name); config.Configs["Modules"].Set("SimulationServices", lscm.Name); config.AddConfig("EntityTransfer"); @@ -267,8 +275,11 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1002, 1000); + SceneHelpers.SetupSceneModules(sceneA, config, etmA); + SceneHelpers.SetupSceneModules(sceneB, config, etmB); + // Shared scene modules - SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); @@ -312,12 +323,13 @@ namespace OpenSim.Region.Framework.Scenes.Tests UUID userId = TestHelpers.ParseTail(0x1); - EntityTransferModule etm = new EntityTransferModule(); + EntityTransferModule etmA = new EntityTransferModule(); + EntityTransferModule etmB = new EntityTransferModule(); LocalSimulationConnectorModule lscm = new LocalSimulationConnectorModule(); IConfigSource config = new IniConfigSource(); IConfig modulesConfig = config.AddConfig("Modules"); - modulesConfig.Set("EntityTransferModule", etm.Name); + modulesConfig.Set("EntityTransferModule", etmA.Name); modulesConfig.Set("SimulationServices", lscm.Name); IConfig entityTransferConfig = config.AddConfig("EntityTransfer"); @@ -329,9 +341,9 @@ namespace OpenSim.Region.Framework.Scenes.Tests TestScene sceneA = sh.SetupScene("sceneA", TestHelpers.ParseTail(0x100), 1000, 1000); TestScene sceneB = sh.SetupScene("sceneB", TestHelpers.ParseTail(0x200), 1001, 1000); - SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, etm, lscm); - SceneHelpers.SetupSceneModules(sceneA, new CapabilitiesModule()); - SceneHelpers.SetupSceneModules(sceneB, new CapabilitiesModule()); + SceneHelpers.SetupSceneModules(new Scene[] { sceneA, sceneB }, config, lscm); + SceneHelpers.SetupSceneModules(sceneA, config, new CapabilitiesModule(), etmA); + SceneHelpers.SetupSceneModules(sceneB, config, new CapabilitiesModule(), etmB); Vector3 teleportPosition = new Vector3(10, 11, 12); Vector3 teleportLookAt = new Vector3(20, 21, 22); -- cgit v1.1 From 38ce9d45a523db277d3eb4d3ed310b7cd9ca6b43 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 May 2012 01:00:18 +0100 Subject: Make ISimulationScene.GetScene() used the more efficient region id for lookup rather than the region handle. --- .../Simulation/LocalSimulationConnector.cs | 20 ++++++++++++++------ .../Simulation/RemoteSimulationConnector.cs | 4 ++-- 2 files changed, 16 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs index 270daad..026c6c8 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/LocalSimulationConnector.cs @@ -160,16 +160,24 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation #region ISimulation - public IScene GetScene(ulong regionhandle) + public IScene GetScene(UUID regionId) { - foreach (Scene s in m_scenes.Values) + if (m_scenes.ContainsKey(regionId)) { - if (s.RegionInfo.RegionHandle == regionhandle) - return s; + return m_scenes[regionId]; } + else + { + // FIXME: This was pre-existing behaviour but possibly not a good idea, since it hides an error rather + // than making it obvious and fixable. Need to see if the error message comes up in practice. + Scene s = m_scenes.Values.ToArray()[0]; - // ? weird. should not happen - return m_scenes.Values.ToArray()[0]; + m_log.ErrorFormat( + "[LOCAL SIMULATION CONNECTOR]: Region with id {0} not found. Returning {1} {2} instead", + regionId, s.RegionInfo.RegionName, s.RegionInfo.RegionID); + + return s; + } } public ISimulationService GetInnerService() diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index eaf9506..3d28518 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs @@ -151,9 +151,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation #region IInterregionComms - public IScene GetScene(ulong handle) + public IScene GetScene(UUID regionId) { - return m_localBackend.GetScene(handle); + return m_localBackend.GetScene(regionId); } public ISimulationService GetInnerService() -- cgit v1.1 From f4cd4c8e284c8f1166028fe7f1585948a8c7c22f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 May 2012 04:33:36 +0100 Subject: Comment out accidentally left in log line that was printing out the control file on OAR save --- .../CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs index 504f09b..4edaaca 100644 --- a/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs +++ b/OpenSim/Region/CoreModules/World/Archiver/ArchiveWriteRequestPreparation.cs @@ -428,9 +428,9 @@ namespace OpenSim.Region.CoreModules.World.Archiver s = sw.ToString(); } - if (m_scene != null) - Console.WriteLine( - "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s); +// if (m_scene != null) +// Console.WriteLine( +// "[ARCHIVE WRITE REQUEST PREPARATION]: Control file for {0} is: {1}", m_scene.RegionInfo.RegionName, s); return s; } -- cgit v1.1 From 5c9086ade688b457e9aa9cd0d2099985b7336b71 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 May 2012 22:26:02 +0100 Subject: Fix issue where a dns resolution failure on the final destination might leave the user unable to teleport since the transit flag was not being reset. This moves the 'already in transit' check further up and resets the flag if dns resolution fails and in the new required places. --- .../EntityTransfer/EntityTransferModule.cs | 392 +++++++++++---------- 1 file changed, 200 insertions(+), 192 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 408d63d..4988e93 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -358,33 +358,21 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer ScenePresence sp, GridRegion reg, GridRegion finalDestination, Vector3 position, Vector3 lookAt, uint teleportFlags) { - RegionInfo sourceRegion = sp.Scene.RegionInfo; - - if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination)) + // Record that this agent is in transit so that we can prevent simultaneous requests and do later detection + // of whether the destination region completes the teleport. + if (!SetInTransit(sp.UUID)) { - sp.ControllingClient.SendTeleportFailed( - string.Format( - "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", - finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY, - sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, - MaxTransferDistance)); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", + sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); return; } - IEventQueue eq = sp.Scene.RequestModuleInterface(); - if (reg == null || finalDestination == null) { sp.ControllingClient.SendTeleportFailed("Unable to locate destination"); - return; - } - - if (!SetInTransit(sp.UUID)) // Avie is already on the way. Caller shouldn't do this. - { - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Ignoring teleport request of {0} {1} to {2} ({3}) {4}/{5} - agent is already in transit.", - sp.Name, sp.UUID, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); + ResetFromTransit(sp.UUID); return; } @@ -394,6 +382,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer sp.Name, sp.UUID, sp.Scene.RegionInfo.RegionName, reg.ServerURI, finalDestination.ServerURI, finalDestination.RegionName, position); + RegionInfo sourceRegion = sp.Scene.RegionInfo; + + if (!IsWithinMaxTeleportDistance(sourceRegion, finalDestination)) + { + sp.ControllingClient.SendTeleportFailed( + string.Format( + "Can't teleport to {0} ({1},{2}) from {3} ({4},{5}), destination is more than {6} regions way", + finalDestination.RegionName, finalDestination.RegionCoordX, finalDestination.RegionCoordY, + sourceRegion.RegionName, sourceRegion.RegionLocX, sourceRegion.RegionLocY, + MaxTransferDistance)); + + ResetFromTransit(sp.UUID); + + return; + } + + IEventQueue eq = sp.Scene.RequestModuleInterface(); + uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); @@ -405,17 +411,24 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // 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) + + 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(); + sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); + ResetFromTransit(sp.UUID); + + return; + } - if (!sp.ValidateAttachments()) - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", - sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); + // 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()) + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", + sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName); // if (!sp.ValidateAttachments()) // { @@ -423,211 +436,206 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // return; // } - string reason; - string version; - if (!m_scene.SimulationService.QueryAccess( - finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) - { - sp.ControllingClient.SendTeleportFailed(reason); - ResetFromTransit(sp.UUID); + string reason; + string version; + if (!m_scene.SimulationService.QueryAccess( + finalDestination, sp.ControllingClient.AgentId, Vector3.Zero, out version, out reason)) + { + sp.ControllingClient.SendTeleportFailed(reason); + ResetFromTransit(sp.UUID); - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", - sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: {0} was stopped from teleporting from {1} to {2} because {3}", + sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); - return; - } + return; + } - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); - sp.ControllingClient.SendTeleportStart(teleportFlags); + sp.ControllingClient.SendTeleportStart(teleportFlags); - // 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 = avatar.KnownRegionHandles; - // 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); + // 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 = avatar.KnownRegionHandles; + // 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; + 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; - agentCircuit.IPAddress = currentAgentCircuit.IPAddress; - agentCircuit.Viewer = currentAgentCircuit.Viewer; - agentCircuit.Channel = currentAgentCircuit.Channel; - agentCircuit.Mac = currentAgentCircuit.Mac; - agentCircuit.Id0 = currentAgentCircuit.Id0; - } + 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; + agentCircuit.IPAddress = currentAgentCircuit.IPAddress; + agentCircuit.Viewer = currentAgentCircuit.Viewer; + agentCircuit.Channel = currentAgentCircuit.Channel; + agentCircuit.Mac = currentAgentCircuit.Mac; + agentCircuit.Id0 = currentAgentCircuit.Id0; + } - if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) - { - // brand new agent, let's create a new caps seed - agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); - } + if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) + { + // brand new agent, let's create a new caps seed + agentCircuit.CapsPath = CapsUtil.GetRandomCapsObjectPath(); + } - // Let's create an agent there if one doesn't exist yet. - bool logout = false; - if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) - { - sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); - ResetFromTransit(sp.UUID); + // Let's create an agent there if one doesn't exist yet. + bool logout = false; + if (!CreateAgent(sp, reg, finalDestination, agentCircuit, teleportFlags, out reason, out logout)) + { + sp.ControllingClient.SendTeleportFailed(String.Format("Teleport refused: {0}", reason)); + ResetFromTransit(sp.UUID); - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", - sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Teleport of {0} from {1} to {2} was refused because {3}", + sp.Name, sp.Scene.RegionInfo.RegionName, finalDestination.RegionName, reason); - return; - } + return; + } - // OK, it got this agent. Let's close some child agents - sp.CloseChildAgents(newRegionX, newRegionY); + // OK, it got this agent. Let's close some child agents + sp.CloseChildAgents(newRegionX, newRegionY); - IClientIPEndpoint ipepClient; - if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) + IClientIPEndpoint ipepClient; + if (NeedsNewAgent(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY)) + { + //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); + #region IP Translation for NAT + // Uses ipepClient above + if (sp.ClientView.TryGet(out ipepClient)) { - //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Creating agent..."); - #region IP Translation for NAT - // Uses ipepClient above - if (sp.ClientView.TryGet(out ipepClient)) - { - endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); - } - #endregion - capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + endPoint.Address = NetworkUtil.GetIPFor(ipepClient.EndPoint, endPoint.Address); + } + #endregion + capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); - if (eq != null) - { - eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); + if (eq != null) + { + 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(200); + // ES makes the client send a UseCircuitCode message to the destination, + // which triggers a bunch of things there. + // So let's wait + Thread.Sleep(200); - eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); - } - else - { - sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); - } } else { - agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); - capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + sp.ControllingClient.InformClientOfNeighbour(destinationHandle, endPoint); } + } + else + { + agentCircuit.CapsPath = sp.Scene.CapsModule.GetChildSeed(sp.UUID, reg.RegionHandle); + capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); + } - // 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); + // 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); - //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); + //sp.ControllingClient.SendTeleportProgress(teleportFlags, "Updating agent..."); - if (!UpdateAgent(reg, finalDestination, agent)) - { - // Region doesn't take it - m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", - sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - - Fail(sp, finalDestination, logout); - return; - } + if (!UpdateAgent(reg, finalDestination, agent)) + { + // Region doesn't take it + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: UpdateAgent failed on teleport of {0} to {1} from {2}. Returning avatar to source region.", + sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); + + Fail(sp, finalDestination, logout); + return; + } - sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); + sp.ControllingClient.SendTeleportProgress(teleportFlags | (uint)TeleportFlags.DisableCancel, "sending_dest"); - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", - capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", + capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); - if (eq != null) - { - eq.TeleportFinishEvent(destinationHandle, 13, endPoint, - 0, teleportFlags, capsPath, sp.UUID); - } - else - { - sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, - teleportFlags, capsPath); - } + if (eq != null) + { + eq.TeleportFinishEvent(destinationHandle, 13, endPoint, + 0, teleportFlags, capsPath, sp.UUID); + } + else + { + sp.ControllingClient.SendRegionTeleport(destinationHandle, 13, endPoint, 4, + teleportFlags, capsPath); + } - // Let's set this to true tentatively. This does not trigger OnChildAgent - sp.IsChildAgent = true; + // Let's set this to true tentatively. This does not trigger OnChildAgent + sp.IsChildAgent = true; - // 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 close things here. - if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID)) - { - m_log.WarnFormat( - "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", - sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); - - Fail(sp, finalDestination, logout); - return; - } + // 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 close things here. + if (EnableWaitForCallbackFromTeleportDest && !WaitForCallback(sp.UUID)) + { + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Teleport of {0} to {1} from {2} failed due to no callback from destination region. Returning avatar to source region.", + sp.Name, finalDestination.RegionName, sp.Scene.RegionInfo.RegionName); + + Fail(sp, finalDestination, logout); + return; + } - // For backwards compatibility - if (version == "Unknown" || version == string.Empty) - { - // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one..."); - CrossAttachmentsIntoNewRegion(finalDestination, sp, true); - } + // For backwards compatibility + if (version == "Unknown" || version == string.Empty) + { + // CrossAttachmentsIntoNewRegion is a synchronous call. We shouldn't need to wait after it + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Old simulator, sending attachments one by one..."); + CrossAttachmentsIntoNewRegion(finalDestination, sp, true); + } - // May need to logout or other cleanup - AgentHasMovedAway(sp, logout); + // May need to logout or other cleanup + AgentHasMovedAway(sp, logout); - // Well, this is it. The agent is over there. - KillEntity(sp.Scene, sp.LocalId); + // Well, this is it. The agent is over there. + KillEntity(sp.Scene, sp.LocalId); - // Now let's make it officially a child agent - sp.MakeChildAgent(); + // Now let's make it officially a child agent + sp.MakeChildAgent(); // sp.Scene.CleanDroppedAttachments(); - // Finally, let's close this previously-known-as-root agent, when the jump is outside the view zone - - if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) - { - // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before - // they regard the new region as the current region after receiving the AgentMovementComplete - // response. If close is sent before then, it will cause the viewer to quit instead. - // However, if this delay is longer, then a viewer can teleport back to this region and experience - // a failure because the old ScenePresence has not yet been cleaned up. - Thread.Sleep(2000); - - 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 - // 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); - } + if (NeedsClosing(sp.DrawDistance, oldRegionX, newRegionX, oldRegionY, newRegionY, reg)) + { + // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before + // they regard the new region as the current region after receiving the AgentMovementComplete + // response. If close is sent before then, it will cause the viewer to quit instead. + // However, if this delay is longer, then a viewer can teleport back to this region and experience + // a failure because the old ScenePresence has not yet been cleaned up. + Thread.Sleep(2000); + + sp.Close(); + sp.Scene.IncomingCloseAgent(sp.UUID); } else { - sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); + // 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); } } -- cgit v1.1 From cd225215b1284b4a50e5ebb928c1aecc3f005e05 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 May 2012 22:40:24 +0100 Subject: Now that the EntityTransferModule is per-region, fetch the event queue module once rather than repeatedly via scene presences --- .../EntityTransfer/EntityTransferModule.cs | 40 ++++++++++++---------- 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 4988e93..361e453 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -73,6 +73,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer private ExpiringCache> m_bannedRegions = new ExpiringCache>(); + private IEventQueue m_eqModule; + #region ISharedRegionModule public Type ReplaceableInterface @@ -147,7 +149,13 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer public virtual void RemoveRegion(Scene scene) {} - public virtual void RegionLoaded(Scene scene) {} + public virtual void RegionLoaded(Scene scene) + { + if (!m_Enabled) + return; + + m_eqModule = m_scene.RequestModuleInterface(); + } #endregion @@ -398,8 +406,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - IEventQueue eq = sp.Scene.RequestModuleInterface(); - uint newRegionX = (uint)(reg.RegionHandle >> 40); uint newRegionY = (((uint)(reg.RegionHandle)) >> 8); uint oldRegionX = (uint)(sp.Scene.RegionInfo.RegionHandle >> 40); @@ -416,7 +422,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { sp.ControllingClient.SendTeleportFailed("Remote Region appears to be down"); ResetFromTransit(sp.UUID); - + return; } @@ -516,16 +522,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #endregion capsPath = finalDestination.ServerURI + CapsUtil.GetCapsSeedPath(agentCircuit.CapsPath); - if (eq != null) + if (m_eqModule != null) { - eq.EnableSimulator(destinationHandle, endPoint, sp.UUID); + m_eqModule.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(200); - eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); } else @@ -564,10 +570,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} from {1} to {2}", capsPath, sp.Scene.RegionInfo.RegionName, sp.Name); - if (eq != null) + if (m_eqModule != null) { - eq.TeleportFinishEvent(destinationHandle, 13, endPoint, - 0, teleportFlags, capsPath, sp.UUID); + m_eqModule.TeleportFinishEvent(destinationHandle, 13, endPoint, 0, teleportFlags, capsPath, sp.UUID); } else { @@ -1122,11 +1127,11 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer 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) + if (m_eqModule != null) { - eq.CrossRegion(neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, - capsPath, agent.UUID, agent.ControllingClient.SessionId); + m_eqModule.CrossRegion( + neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, + capsPath, agent.UUID, agent.ControllingClient.SessionId); } else { @@ -1474,8 +1479,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (regionAccepted && newAgent) { - IEventQueue eq = sp.Scene.RequestModuleInterface(); - if (eq != null) + if (m_eqModule != null) { #region IP Translation for NAT IClientIPEndpoint ipepClient; @@ -1489,8 +1493,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "and EstablishAgentCommunication with seed cap {4}", scene.RegionInfo.RegionName, sp.Name, reg.RegionName, reg.RegionHandle, capsPath); - eq.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); - eq.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); + m_eqModule.EnableSimulator(reg.RegionHandle, endPoint, sp.UUID); + m_eqModule.EstablishAgentCommunication(sp.UUID, endPoint, capsPath); } else { -- cgit v1.1 From cc53d91d2f53adf952703f7fb91a7ab33c7a5d8a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 May 2012 22:46:45 +0100 Subject: On inter-region teleport, only stand the avatar up if the QueryAccess call to the destination scene actually succeeds. --- .../Framework/EntityTransfer/EntityTransferModule.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 361e453..5afe553 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -153,7 +153,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { if (!m_Enabled) return; - + m_eqModule = m_scene.RequestModuleInterface(); } @@ -426,11 +426,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer 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(); - if (!sp.ValidateAttachments()) m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for teleport of {0} from {1} to {2}. Continuing.", @@ -457,7 +452,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); + + // Fixing a bug where teleporting while sitting results in the avatar ending up removed from + // both regions + if (sp.ParentID != (uint)0) + sp.StandUp(); sp.ControllingClient.SendTeleportStart(teleportFlags); -- cgit v1.1 From 93ff27053a2d46a934bb6a1780ccfecd505ab44f Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 24 May 2012 22:59:52 +0100 Subject: Don't actually proceed on a within-region teleport if another is already taking place, rather than just (falsely) logging that we're not going to proceed. An oversight from recent commit 9ab0c81 --- .../Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 5afe553..b5717cd 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -227,6 +227,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.DebugFormat( "[ENTITY TRANSFER MODULE]: Ignoring within region teleport request of {0} {1} to {2} - agent is already in transit.", sp.Name, sp.UUID, position); + + return; } // Teleport within the same region -- cgit v1.1 From 40c78b06246d1131e07982dc6a9366666d9ea031 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 May 2012 02:02:53 +0100 Subject: Stop it being possible for an agent to teleport back to its source region before the source region has finished cleaning up old agent data and structures. If this is allowed, then the client usually gets forcibly logged out and data structures might be put into bad states. To prevent this, the binary state machine of EMT.m_agentsInTransit is replaced with a 4 state machine (Preparing, Transferring, ReceivedAtDestination, CleaningUp). This is necessary because the source region needs to know when the destination region has received the user but a teleport back cannot happen until the source region has cleaned up. Tested on standalone, grid and with v1 and v3 clients. --- .../EntityTransfer/EntityTransferModule.cs | 189 ++++++++++++++++++--- .../Framework/Interfaces/IEntityTransferModule.cs | 2 +- OpenSim/Region/Framework/Scenes/Scene.cs | 6 +- 3 files changed, 169 insertions(+), 28 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index b5717cd..ddb621d 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -46,6 +46,29 @@ using Nini.Config; namespace OpenSim.Region.CoreModules.Framework.EntityTransfer { + /// + /// The possible states that an agent can be in when its being transferred between regions. + /// + /// + /// This is a state machine. + /// + /// [Entry] => Preparing + /// Preparing => { Transferring || CleaningUp || [Exit] } + /// Transferring => { ReceivedAtDestination || CleaningUp } + /// ReceivedAtDestination => CleaningUp + /// CleaningUp => [Exit] + /// + /// In other words, agents normally travel throwing Preparing => Transferring => ReceivedAtDestination => CleaningUp + /// However, any state can transition to CleaningUp if the teleport has failed. + /// + enum AgentTransferState + { + Preparing, // The agent is being prepared for transfer + Transferring, // The agent is in the process of being transferred to a destination + ReceivedAtDestination, // The destination has notified us that the agent has been successfully received + CleaningUp // The agent is being changed to child/removed after a transfer + } + public class EntityTransferModule : INonSharedRegionModule, IEntityTransferModule { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); @@ -68,7 +91,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer protected Scene m_scene; - protected List m_agentsInTransit; + private Dictionary m_agentsInTransit; private ExpiringCache> m_bannedRegions = new ExpiringCache>(); @@ -120,7 +143,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer MaxTransferDistance = DefaultMaxTransferDistance; } - m_agentsInTransit = new List(); + m_agentsInTransit = new Dictionary(); m_Enabled = true; } @@ -259,17 +282,22 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer position.Z = newPosZ; } + UpdateInTransit(sp.UUID, AgentTransferState.Transferring); + sp.ControllingClient.SendTeleportStart(teleportFlags); sp.ControllingClient.SendLocalTeleport(position, lookAt, teleportFlags); sp.Velocity = Vector3.Zero; sp.Teleport(position); + UpdateInTransit(sp.UUID, AgentTransferState.ReceivedAtDestination); + foreach (SceneObjectGroup grp in sp.GetAttachments()) { sp.Scene.EventManager.TriggerOnScriptChangedEvent(grp.LocalId, (uint)Changed.TELEPORT); } + UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); ResetFromTransit(sp.UUID); } @@ -454,7 +482,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Destination is running version {0}", version); // Fixing a bug where teleporting while sitting results in the avatar ending up removed from // both regions @@ -508,6 +536,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } + // Past this point we have to attempt clean up if the teleport fails, so update transfer state. + UpdateInTransit(sp.UUID, AgentTransferState.Transferring); + // OK, it got this agent. Let's close some child agents sp.CloseChildAgents(newRegionX, newRegionY); @@ -598,6 +629,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return; } + UpdateInTransit(sp.UUID, AgentTransferState.CleaningUp); + // For backwards compatibility if (version == "Unknown" || version == string.Empty) { @@ -624,8 +657,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // We need to delay here because Imprudence viewers, unlike v1 or v3, have a short (<200ms, <500ms) delay before // they regard the new region as the current region after receiving the AgentMovementComplete // response. If close is sent before then, it will cause the viewer to quit instead. - // However, if this delay is longer, then a viewer can teleport back to this region and experience - // a failure because the old ScenePresence has not yet been cleaned up. + // + // This sleep can be increased if necessary. However, whilst it's active, + // an agent cannot teleport back to this region if it has teleported away. Thread.Sleep(2000); sp.Close(); @@ -644,6 +678,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer "[ENTITY TRANSFER MODULE]: User {0} is going to another region, profile cache removed", sp.UUID); } + + ResetFromTransit(sp.UUID); } protected virtual void Fail(ScenePresence sp, GridRegion finalDestination, bool logout) @@ -1089,6 +1125,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); agent.RemoveFromPhysicalScene(); + SetInTransit(agent.UUID); AgentData cAgent = new AgentData(); @@ -1100,6 +1137,9 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // We don't need the callback anymnore cAgent.CallbackURI = String.Empty; + // Beyond this point, extra cleanup is needed beyond removing transit state + UpdateInTransit(agent.UUID, AgentTransferState.Transferring); + if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) { // region doesn't take it @@ -1141,8 +1181,16 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer capsPath); } - // SUCCESS! + // SUCCESS! + UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); + + // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. + UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); + agent.MakeChildAgent(); + + // FIXME: Possibly this should occur lower down after other commands to close other agents, + // but not sure yet what the side effects would be. ResetFromTransit(agent.UUID); // now we have a child agent in this region. Request all interesting data about other (root) agents @@ -1622,7 +1670,37 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Agent Arrived public void AgentArrivedAtDestination(UUID id) { - ResetFromTransit(id); + lock (m_agentsInTransit) + { + if (!m_agentsInTransit.ContainsKey(id)) + { + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but no teleport request is active", + m_scene.RegionInfo.RegionName, id); + + return; + } + + AgentTransferState currentState = m_agentsInTransit[id]; + + if (currentState == AgentTransferState.ReceivedAtDestination) + { + // An anomoly but don't make this an outright failure - destination region could be overzealous in sending notification. + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but notification has already previously been received", + m_scene.RegionInfo.RegionName, id); + } + else if (currentState != AgentTransferState.Transferring) + { + m_log.ErrorFormat( + "[ENTITY TRANSFER MODULE]: Region {0} received notification of arrival in destination scene of agent {1} but agent is in transfer state {2}", + m_scene.RegionInfo.RegionName, id, currentState); + + return; + } + + m_agentsInTransit[id] = AgentTransferState.ReceivedAtDestination; + } } #endregion @@ -1964,10 +2042,29 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer #region Misc - protected bool WaitForCallback(UUID id) + private bool WaitForCallback(UUID id) { + lock (m_agentsInTransit) + { + if (!IsInTransit(id)) + throw new Exception( + string.Format( + "Asked to wait for destination callback for agent with ID {0} but it is not in transit")); + + AgentTransferState currentState = m_agentsInTransit[id]; + + if (currentState != AgentTransferState.Transferring && currentState != AgentTransferState.ReceivedAtDestination) + throw new Exception( + string.Format( + "Asked to wait for destination callback for agent with ID {0} but it is in state {1}", + currentState)); + } + int count = 200; - while (m_agentsInTransit.Contains(id) && count-- > 0) + + // There should be no race condition here since no other code should be removing the agent transfer or + // changing the state to another other than Transferring => ReceivedAtDestination. + while (m_agentsInTransit[id] != AgentTransferState.ReceivedAtDestination && count-- > 0) { // m_log.Debug(" >>> Waiting... " + count); Thread.Sleep(100); @@ -1977,17 +2074,17 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } /// - /// Set that an agent is in the process of being teleported. + /// Set that an agent is in transit. /// /// The ID of the agent being teleported /// true if the agent was not already in transit, false if it was - protected bool SetInTransit(UUID id) + private bool SetInTransit(UUID id) { lock (m_agentsInTransit) { - if (!m_agentsInTransit.Contains(id)) + if (!m_agentsInTransit.ContainsKey(id)) { - m_agentsInTransit.Add(id); + m_agentsInTransit[id] = AgentTransferState.Preparing; return true; } } @@ -1996,29 +2093,73 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer } /// - /// Show whether the given agent is being teleported. + /// Updates the state of an agent that is already in transit. /// - /// true if the agent is in the process of being teleported, false otherwise. - /// The agent ID + /// + /// + /// + /// Illegal transitions will throw an Exception + private void UpdateInTransit(UUID id, AgentTransferState newState) + { + lock (m_agentsInTransit) + { + // Illegal to try and update an agent that's not actually in transit. + if (!m_agentsInTransit.ContainsKey(id)) + throw new Exception(string.Format("Agent with ID {0} is not registered as in transit", id)); + + AgentTransferState oldState = m_agentsInTransit[id]; + + bool transitionOkay = false; + + if (newState == AgentTransferState.CleaningUp && oldState != AgentTransferState.CleaningUp) + transitionOkay = true; + else if (newState == AgentTransferState.Transferring && oldState == AgentTransferState.Preparing) + transitionOkay = true; + else if (newState == AgentTransferState.ReceivedAtDestination && oldState == AgentTransferState.Transferring) + transitionOkay = true; + + if (transitionOkay) + m_agentsInTransit[id] = newState; + else + throw new Exception( + string.Format( + "Agent with ID {0} is not allowed to move from old transit state {1} to new state {2}", + id, oldState, newState)); + } + } + public bool IsInTransit(UUID id) { lock (m_agentsInTransit) - return m_agentsInTransit.Contains(id); + return m_agentsInTransit.ContainsKey(id); } /// - /// Set that an agent is no longer being teleported. + /// Removes an agent from the transit state machine. /// - /// - /// - /// true if the agent was flagged as being teleported when this method was called, false otherwise - /// - protected bool ResetFromTransit(UUID id) + /// + /// true if the agent was flagged as being teleported when this method was called, false otherwise + private bool ResetFromTransit(UUID id) { lock (m_agentsInTransit) { - if (m_agentsInTransit.Contains(id)) + if (m_agentsInTransit.ContainsKey(id)) { + AgentTransferState state = m_agentsInTransit[id]; + + if (state == AgentTransferState.Transferring || state == AgentTransferState.ReceivedAtDestination) + { + // FIXME: For now, we allow exit from any state since a thrown exception in teleport is now guranteed + // to be handled properly - ResetFromTransit() could be invoked at any step along the process + m_log.WarnFormat( + "[ENTITY TRANSFER MODULE]: Agent with ID should not exit directly from state {1}, should go to {2} state first", + state, AgentTransferState.CleaningUp); + +// throw new Exception( +// "Agent with ID {0} cannot exit directly from state {1}, it must go to {2} state first", +// state, AgentTransferState.CleaningUp); + } + m_agentsInTransit.Remove(id); m_log.DebugFormat( diff --git a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs index 75c44d5..69be83e 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityTransferModule.cs @@ -77,8 +77,8 @@ namespace OpenSim.Region.Framework.Interfaces /// /// Show whether the given agent is being teleported. /// - /// true if the agent is in the process of being teleported, false otherwise. /// The agent ID + /// true if the agent is in the process of being teleported, false otherwise. bool IsInTransit(UUID id); bool Cross(ScenePresence agent, bool isFlying); diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 755b1e6..98a75e4 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -5212,10 +5212,10 @@ namespace OpenSim.Region.Framework.Scenes { if (EntityTransferModule.IsInTransit(agentID)) { - reason = "Agent is already in transit on this region"; + reason = "Agent is still in transit from this region"; - m_log.DebugFormat( - "[SCENE]: Denying agent {0} entry into {1} since region already has them registered as in transit", + m_log.WarnFormat( + "[SCENE]: Denying agent {0} entry into {1} since region still has them registered as in transit", agentID, RegionInfo.RegionName); return false; -- cgit v1.1 From 96cde407ab0d40856fb10b3b9f304433ffe734a2 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 May 2012 02:37:22 +0100 Subject: Fix bug where a failed QueryAccess to a remove region would always have the reason "Communications failure" no matter what the destination region actually returned --- .../ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs index 3d28518..f980f68 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Simulation/RemoteSimulationConnector.cs @@ -226,13 +226,13 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return m_remoteConnector.RetrieveAgent(destination, id, out agent); return false; - } public bool QueryAccess(GridRegion destination, UUID id, Vector3 position, out string version, out string reason) { reason = "Communications failure"; version = "Unknown"; + if (destination == null) return false; @@ -245,7 +245,6 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Simulation return m_remoteConnector.QueryAccess(destination, id, position, out version, out reason); return false; - } public bool ReleaseAgent(UUID origin, UUID id, string uri) -- cgit v1.1 From 9f1fc7ea8816e8a052e41b58d4cde077bc58b9e5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 May 2012 02:54:37 +0100 Subject: Remove a call stack debugging line accidentally left in from a few days ago at SceneObjectPartInventory.ApplyNextOwnerPermissions(). --- OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 2 -- 1 file changed, 2 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index d27d9e1..aaf9ffa 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -1027,8 +1027,6 @@ namespace OpenSim.Region.Framework.Scenes public void ApplyNextOwnerPermissions() { - Util.PrintCallStack(); - lock (m_items) { foreach (TaskInventoryItem item in m_items.Values) -- cgit v1.1 From 888210ea4af0f9d41263193d450d73eba5d866fc Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 May 2012 03:06:26 +0100 Subject: refactor: make ETM.CrossAgentToNewRegionAsync neighbourRegion == null check return earlier to simplify method --- .../EntityTransfer/EntityTransferModule.cs | 182 +++++++++++---------- 1 file changed, 92 insertions(+), 90 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index ddb621d..7295383 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1106,119 +1106,121 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer ScenePresence agent, Vector3 pos, uint neighbourx, uint neighboury, GridRegion neighbourRegion, bool isFlying, string version) { + if (neighbourRegion == null) + return agent; + try { ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", agent.Firstname, agent.Lastname, neighbourx, neighboury, version); + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Crossing agent {0} {1} to {2}-{3} running version {4}", + agent.Firstname, agent.Lastname, neighbourx, neighboury, version); Scene m_scene = agent.Scene; - - if (neighbourRegion != null) - { - if (!agent.ValidateAttachments()) - m_log.DebugFormat( - "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", - agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); - pos = pos + agent.Velocity; - Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); + if (!agent.ValidateAttachments()) + m_log.DebugFormat( + "[ENTITY TRANSFER MODULE]: Failed validation of all attachments for region crossing of {0} from {1} to {2}. Continuing.", + agent.Name, agent.Scene.RegionInfo.RegionName, neighbourRegion.RegionName); - agent.RemoveFromPhysicalScene(); + pos = pos + agent.Velocity; + Vector3 vel2 = new Vector3(agent.Velocity.X, agent.Velocity.Y, 0); - SetInTransit(agent.UUID); + agent.RemoveFromPhysicalScene(); - AgentData cAgent = new AgentData(); - agent.CopyTo(cAgent); - cAgent.Position = pos; - if (isFlying) - cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; + SetInTransit(agent.UUID); - // We don't need the callback anymnore - cAgent.CallbackURI = String.Empty; + AgentData cAgent = new AgentData(); + agent.CopyTo(cAgent); + cAgent.Position = pos; + if (isFlying) + cAgent.ControlFlags |= (uint)AgentManager.ControlFlags.AGENT_CONTROL_FLY; - // Beyond this point, extra cleanup is needed beyond removing transit state - UpdateInTransit(agent.UUID, AgentTransferState.Transferring); + // We don't need the callback anymnore + cAgent.CallbackURI = String.Empty; - if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) - { - // region doesn't take it - ReInstantiateScripts(agent); - agent.AddToPhysicalScene(isFlying); - ResetFromTransit(agent.UUID); - return agent; - } - - //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("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", - neighbourRegion.RegionHandle); - return agent; - } - // No turning back - agent.IsChildAgent = true; + // Beyond this point, extra cleanup is needed beyond removing transit state + UpdateInTransit(agent.UUID, AgentTransferState.Transferring); - string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); - - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); + if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) + { + // region doesn't take it + ReInstantiateScripts(agent); + agent.AddToPhysicalScene(isFlying); + ResetFromTransit(agent.UUID); + return agent; + } - if (m_eqModule != null) - { - m_eqModule.CrossRegion( - neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, - capsPath, agent.UUID, agent.ControllingClient.SessionId); - } - else - { - agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, - capsPath); - } + //AgentCircuitData circuitdata = m_controllingClient.RequestClientInfo(); + agent.ControllingClient.RequestClientInfo(); - // SUCCESS! - UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); + //m_log.Debug("BEFORE CROSS"); + //Scene.DumpChildrenSeeds(UUID); + //DumpKnownRegions(); + string agentcaps; + if (!agent.KnownRegions.TryGetValue(neighbourRegion.RegionHandle, out agentcaps)) + { + m_log.ErrorFormat("[ENTITY TRANSFER MODULE]: No ENTITY TRANSFER MODULE information for region handle {0}, exiting CrossToNewRegion.", + neighbourRegion.RegionHandle); + return agent; + } + // No turning back + agent.IsChildAgent = true; - // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. - UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); + string capsPath = neighbourRegion.ServerURI + CapsUtil.GetCapsSeedPath(agentcaps); - agent.MakeChildAgent(); + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: Sending new CAPS seed url {0} to client {1}", capsPath, agent.UUID); - // FIXME: Possibly this should occur lower down after other commands to close other agents, - // but not sure yet what the side effects would be. - ResetFromTransit(agent.UUID); + if (m_eqModule != null) + { + m_eqModule.CrossRegion( + neighbourHandle, pos, vel2 /* agent.Velocity */, neighbourRegion.ExternalEndPoint, + capsPath, agent.UUID, agent.ControllingClient.SessionId); + } + else + { + agent.ControllingClient.CrossRegion(neighbourHandle, pos, agent.Velocity, neighbourRegion.ExternalEndPoint, + capsPath); + } - // now we have a child agent in this region. Request all interesting data about other (root) agents - agent.SendOtherAgentsAvatarDataToMe(); - agent.SendOtherAgentsAppearanceToMe(); + // SUCCESS! + UpdateInTransit(agent.UUID, AgentTransferState.ReceivedAtDestination); - // Backwards compatibility. Best effort - if (version == "Unknown" || version == string.Empty) - { - m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); - Thread.Sleep(3000); // wait a little now that we're not waiting for the callback - CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); - } + // Unlike a teleport, here we do not wait for the destination region to confirm the receipt. + UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); + agent.MakeChildAgent(); - // Next, let's close the child agent connections that are too far away. - agent.CloseChildAgents(neighbourx, neighboury); - - AgentHasMovedAway(agent, false); - - // 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( - "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); - } + // FIXME: Possibly this should occur lower down after other commands to close other agents, + // but not sure yet what the side effects would be. + ResetFromTransit(agent.UUID); + + // now we have a child agent in this region. Request all interesting data about other (root) agents + agent.SendOtherAgentsAvatarDataToMe(); + agent.SendOtherAgentsAppearanceToMe(); + + // Backwards compatibility. Best effort + if (version == "Unknown" || version == string.Empty) + { + m_log.DebugFormat("[ENTITY TRANSFER MODULE]: neighbor with old version, passing attachments one by one..."); + Thread.Sleep(3000); // wait a little now that we're not waiting for the callback + CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); + } + + + // Next, let's close the child agent connections that are too far away. + agent.CloseChildAgents(neighbourx, neighboury); + + AgentHasMovedAway(agent, false); + + // 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( + "[ENTITY TRANSFER MODULE]: User {0} is going to another region", agent.UUID); } //m_log.Debug("AFTER CROSS"); -- cgit v1.1 From ab59c0a658c25f129255198f27704cdbbcb13d6b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 May 2012 03:39:10 +0100 Subject: on agent cross, remove from physics scene after its been placed in transit, not before. --- .../Framework/EntityTransfer/EntityTransferModule.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 7295383..a5fb0c2 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1111,6 +1111,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer try { + SetInTransit(agent.UUID); + ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize)); m_log.DebugFormat( @@ -1129,8 +1131,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer agent.RemoveFromPhysicalScene(); - SetInTransit(agent.UUID); - AgentData cAgent = new AgentData(); agent.CopyTo(cAgent); cAgent.Position = pos; @@ -1146,9 +1146,12 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer if (!m_scene.SimulationService.UpdateAgent(neighbourRegion, cAgent)) { // region doesn't take it + UpdateInTransit(agent.UUID, AgentTransferState.CleaningUp); + ReInstantiateScripts(agent); agent.AddToPhysicalScene(isFlying); ResetFromTransit(agent.UUID); + return agent; } @@ -1208,7 +1211,6 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer CrossAttachmentsIntoNewRegion(neighbourRegion, agent, true); } - // Next, let's close the child agent connections that are too far away. agent.CloseChildAgents(neighbourx, neighboury); @@ -1232,6 +1234,8 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer m_log.ErrorFormat( "[ENTITY TRANSFER MODULE]: Problem crossing user {0} to new region {1} from {2}. Exception {3}{4}", agent.Name, neighbourRegion.RegionName, agent.Scene.RegionInfo.RegionName, e.Message, e.StackTrace); + + // TODO: Might be worth attempting other restoration here such as reinstantiation of scripts, etc. } return agent; -- cgit v1.1 From 67ebe80dd95ffa2c5e9b071497b472f9c99f00f8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 25 May 2012 04:03:16 +0100 Subject: Resolve some mono compiler warnings. --- .../Avatar/Attachments/AttachmentsModule.cs | 2 -- .../CoreModules/Avatar/Friends/HGFriendsModule.cs | 13 ++++++---- .../EntityTransfer/EntityTransferModule.cs | 2 +- .../EntityTransfer/HGEntityTransferModule.cs | 2 +- .../InventoryAccess/HGInventoryAccessModule.cs | 5 ++-- .../Hypergrid/HypergridServiceInConnectorModule.cs | 3 ++- .../ServiceConnectorsOut/Asset/HGAssetBroker.cs | 2 +- .../CoreModules/World/Terrain/FileLoaders/TIFF.cs | 2 +- .../World/Terrain/FileLoaders/Terragen.cs | 28 ++++++++++++---------- 9 files changed, 33 insertions(+), 26 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 510b483..88071f6 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -48,7 +48,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; - private IDialogModule m_dialogModule; private IInventoryAccessModule m_invAccessModule; /// @@ -89,7 +88,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void RegionLoaded(Scene scene) { - m_dialogModule = m_scene.RequestModuleInterface(); m_invAccessModule = m_scene.RequestModuleInterface(); } diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs index 3728b85..06f27e2 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/HGFriendsModule.cs @@ -415,12 +415,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends protected override void StoreBackwards(UUID friendID, UUID agentID) { - Boolean agentIsLocal = true; - Boolean friendIsLocal = true; + bool agentIsLocal = true; +// bool friendIsLocal = true; + if (UserManagementModule != null) { agentIsLocal = UserManagementModule.IsLocalGridUser(agentID); - friendIsLocal = UserManagementModule.IsLocalGridUser(friendID); +// friendIsLocal = UserManagementModule.IsLocalGridUser(friendID); } // Is the requester a local user? @@ -507,7 +508,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Friends { friendUUI = finfo.Friend; theFriendUUID = friendUUI; - UUID utmp = UUID.Zero; String url = String.Empty; String first = String.Empty, last = String.Empty, tmp = String.Empty; + UUID utmp = UUID.Zero; + string url = String.Empty; + string first = String.Empty; + string last = String.Empty; + // If it's confirming the friendship, we already have the full UUI with the secret if (Util.ParseUniversalUserIdentifier(theFriendUUID, out utmp, out url, out first, out last, out secret)) { diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index a5fb0c2..ae9fb53 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1240,7 +1240,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer return agent; } - + private void CrossAgentToNewRegionCompleted(IAsyncResult iar) { CrossAgentToNewRegionDelegate icon = (CrossAgentToNewRegionDelegate)iar.AsyncState; diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs index 4124667..0fdd457 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/HGEntityTransferModule.cs @@ -336,7 +336,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer // Let's find out if this is a foreign user or a local user IUserManagement uMan = m_scene.RequestModuleInterface(); - UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, obj.AgentId); +// UserAccount account = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, obj.AgentId); if (uMan != null && uMan.IsLocalGridUser(obj.AgentId)) { // local grid user diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index a71584a..cf72b58 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs @@ -364,8 +364,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { m_log.DebugFormat("[HG INVENTORY ACCESS MODULE]: Changing root inventory for user {0}", client.Name); InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID); - List fids = new List(); - List iids = new List(); + List keep = new List(); foreach (InventoryFolderBase f in content.Folders) @@ -395,4 +394,4 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess #endregion } -} +} \ No newline at end of file diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs index 8df1c7b..a7dd0dd 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsIn/Hypergrid/HypergridServiceInConnectorModule.cs @@ -122,7 +122,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsIn.Hypergrid ISimulationService simService = scene.RequestModuleInterface(); IFriendsSimConnector friendsConn = scene.RequestModuleInterface(); Object[] args = new Object[] { m_Config }; - IFriendsService friendsService = ServerUtils.LoadPlugin(m_LocalServiceDll, args); +// IFriendsService friendsService = ServerUtils.LoadPlugin(m_LocalServiceDll, args) + ServerUtils.LoadPlugin(m_LocalServiceDll, args); m_HypergridHandler = new GatekeeperServiceInConnector(m_Config, MainServer.Instance, simService); diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs index 8395f83..008465f 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Asset/HGAssetBroker.cs @@ -149,7 +149,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Asset m_aScene = scene; - scene.RegisterModuleInterface(this); + m_aScene.RegisterModuleInterface(this); } public void RemoveRegion(Scene scene) diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs index 5d2f893..b416b82 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/TIFF.cs @@ -59,7 +59,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders } //Returns true if this extension is supported for terrain save-tile - public bool SupportsTileSave() + public override bool SupportsTileSave() { return false; } diff --git a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs index 1ebf916..71c71e6 100644 --- a/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs +++ b/OpenSim/Region/CoreModules/World/Terrain/FileLoaders/Terragen.cs @@ -65,7 +65,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders bool eof = false; int fileXPoints = 0; - int fileYPoints = 0; +// int fileYPoints = 0; // Terragen file while (eof == false) @@ -75,7 +75,7 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders { case "SIZE": fileXPoints = bs.ReadInt16() + 1; - fileYPoints = fileXPoints; +// fileYPoints = fileXPoints; bs.ReadInt16(); break; case "XPTS": @@ -83,7 +83,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders bs.ReadInt16(); break; case "YPTS": - fileYPoints = bs.ReadInt16(); +// fileYPoints = bs.ReadInt16(); + bs.ReadInt16(); bs.ReadInt16(); break; case "ALTW": @@ -164,10 +165,8 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders bool eof = false; if (Encoding.ASCII.GetString(bs.ReadBytes(16)) == "TERRAGENTERRAIN ") { - - int fileWidth = w; - int fileHeight = h; - +// int fileWidth = w; +// int fileHeight = h; // Terragen file while (eof == false) @@ -176,17 +175,22 @@ namespace OpenSim.Region.CoreModules.World.Terrain.FileLoaders switch (tmp) { case "SIZE": - int sztmp = bs.ReadInt16() + 1; - fileWidth = sztmp; - fileHeight = sztmp; +// int sztmp = bs.ReadInt16() + 1; +// fileWidth = sztmp; +// fileHeight = sztmp; + bs.ReadInt16(); + bs.ReadInt16(); + bs.ReadInt16(); bs.ReadInt16(); break; case "XPTS": - fileWidth = bs.ReadInt16(); +// fileWidth = bs.ReadInt16(); + bs.ReadInt16(); bs.ReadInt16(); break; case "YPTS": - fileHeight = bs.ReadInt16(); +// fileHeight = bs.ReadInt16(); + bs.ReadInt16(); bs.ReadInt16(); break; case "ALTW": -- cgit v1.1 From 120f8145fcfe2cdc4e39a92e5838a2a41eb51406 Mon Sep 17 00:00:00 2001 From: Talun Date: Wed, 23 May 2012 00:33:45 +0100 Subject: Mantis 6028 osAvatarStopAnimation not stopping animations via UUID Corrected to stop animations using the animation UUID similar to llStopAnimation. See http://opensimulator.org/wiki/OsAvatarStopAnimation --- .../ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index ad1a358..5dbd9ec 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -957,16 +957,20 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScenePresence target = (ScenePresence)World.Entities[avatarID]; if (target != null) { - UUID animID = UUID.Zero; - lock (m_host.TaskInventory) + UUID animID = new UUID(); + if (!UUID.TryParse(animation, out animID)) { - foreach (KeyValuePair inv in m_host.TaskInventory) + animID = UUID.Zero; + lock (m_host.TaskInventory) { - if (inv.Value.Name == animation) + foreach (KeyValuePair inv in m_host.TaskInventory) { - if (inv.Value.Type == (int)AssetType.Animation) - animID = inv.Value.AssetID; - continue; + if (inv.Value.Name == animation) + { + if (inv.Value.Type == (int)AssetType.Animation) + animID = inv.Value.AssetID; + continue; + } } } } -- cgit v1.1 From ff53add54dbc666e585b928ba51b4babb7441611 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 26 May 2012 00:36:01 +0100 Subject: refactor: replace LSL_Api.InventoryKey(string) largely with SceneObjectPartInventory.GetInventoryItem(string) Also gets llStopAnimation() to call KeyOrName rather than duplicating logic. --- .../Framework/Interfaces/IEntityInventory.cs | 13 ++++++ .../Framework/Scenes/SceneObjectPartInventory.cs | 22 +++++---- .../Shared/Api/Implementation/LSL_Api.cs | 52 +++++++--------------- 3 files changed, 42 insertions(+), 45 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 30ed7d1..4370fcc 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs @@ -164,6 +164,19 @@ namespace OpenSim.Region.Framework.Interfaces List GetInventoryItems(); /// + /// Gets an inventory item by name + /// + /// + /// This method returns the first inventory item that matches the given name. In SL this is all you need + /// since each item in a prim inventory must have a unique name. + /// + /// + /// + /// The inventory item. Null if no such item was found. + /// + TaskInventoryItem GetInventoryItem(string name); + + /// /// Get inventory items by name. /// /// diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index aaf9ffa..8810903 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs @@ -582,14 +582,20 @@ namespace OpenSim.Region.Framework.Scenes return item; } - /// - /// Get inventory items by name. - /// - /// - /// - /// A list of inventory items with that name. - /// If no inventory item has that name then an empty list is returned. - /// + public TaskInventoryItem GetInventoryItem(string name) + { + lock (m_items) + { + foreach (TaskInventoryItem item in m_items.Values) + { + if (item.Name == name) + return item; + } + } + + return null; + } + public List GetInventoryItems(string name) { List items = new List(); diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 4b28808..9908a39 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -104,9 +104,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected int m_scriptConsoleChannel = 0; protected bool m_scriptConsoleChannelEnabled = false; protected IUrlModule m_UrlModule = null; - protected Dictionary m_userInfoCache = - new Dictionary(); - protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. + protected Dictionary m_userInfoCache = new Dictionary(); + protected int EMAIL_PAUSE_TIME = 20; // documented delay value for smtp. public void Initialize(IScriptEngine ScriptEngine, SceneObjectPart host, TaskInventoryItem item) { @@ -304,25 +303,6 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return UUID.Zero; } - protected UUID InventoryKey(string name) - { - m_host.AddScriptLPS(1); - - lock (m_host.TaskInventory) - { - foreach (KeyValuePair inv in m_host.TaskInventory) - { - if (inv.Value.Name == name) - { - return inv.Value.AssetID; - } - } - } - - return UUID.Zero; - } - - /// /// accepts a valid UUID, -or- a name of an inventory item. /// Returns a valid UUID or UUID.Zero if key invalid and item not found @@ -332,19 +312,22 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api /// protected UUID KeyOrName(string k) { - UUID key = UUID.Zero; + UUID key; // if we can parse the string as a key, use it. - if (UUID.TryParse(k, out key)) - { - return key; - } // else try to locate the name in inventory of object. found returns key, - // not found returns UUID.Zero which will translate to the default particle texture - else + // not found returns UUID.Zero + if (!UUID.TryParse(k, out key)) { - return InventoryKey(k); + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(k); + + if (item != null) + key = item.AssetID; + else + key = UUID.Zero; } + + return key; } // convert a LSL_Rotation to a Quaternion @@ -3315,17 +3298,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api if ((m_item.PermsMask & ScriptBaseClass.PERMISSION_TRIGGER_ANIMATION) != 0) { - UUID animID = new UUID(); - - if (!UUID.TryParse(anim, out animID)) - { - animID = InventoryKey(anim); - } - ScenePresence presence = World.GetScenePresence(m_item.PermsGranter); if (presence != null) { + UUID animID = KeyOrName(anim); + if (animID == UUID.Zero) presence.Animator.RemoveAnimation(anim); else -- cgit v1.1 From f2a5fad18f30d24cd8911de829ecb1a07b475e38 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 26 May 2012 00:54:00 +0100 Subject: Use SceneObjectPartInventory.GetInventoryItem() in OSSL.AvatarStopAnimation instead of searching the task inventory manually. --- .../Shared/Api/Implementation/OSSL_Api.cs | 26 ++++++++++------------ 1 file changed, 12 insertions(+), 14 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs index 5dbd9ec..7ea8b7a 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/OSSL_Api.cs @@ -952,27 +952,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api UUID avatarID = (UUID)avatar; m_host.AddScriptLPS(1); + + // FIXME: What we really want to do here is factor out the similar code in llStopAnimation() to a common + // method (though see that doesn't do the is animation check, which is probably a bug) and have both + // these functions call that common code. However, this does mean navigating the brain-dead requirement + // of calling InitLSL() if (World.Entities.ContainsKey(avatarID) && World.Entities[avatarID] is ScenePresence) { ScenePresence target = (ScenePresence)World.Entities[avatarID]; if (target != null) { - UUID animID = new UUID(); + UUID animID; + if (!UUID.TryParse(animation, out animID)) { - animID = UUID.Zero; - lock (m_host.TaskInventory) - { - foreach (KeyValuePair inv in m_host.TaskInventory) - { - if (inv.Value.Name == animation) - { - if (inv.Value.Type == (int)AssetType.Animation) - animID = inv.Value.AssetID; - continue; - } - } - } + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(animation); + if (item != null && item.Type == (int)AssetType.Animation) + animID = item.AssetID; + else + animID = UUID.Zero; } if (animID == UUID.Zero) -- cgit v1.1 From d6476b627752c99a6aea5093d080d3633aa6dde8 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 26 May 2012 01:03:53 +0100 Subject: Use GetInventoryItem() in LSL_Api.InventoryKey(string name, int type). Also removes small bug where calling this method would add 1 to LPS, evne though all callers already did this. --- .../Shared/Api/Implementation/LSL_Api.cs | 24 +++++++--------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 9908a39..6438bcc 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -284,23 +284,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api protected UUID InventoryKey(string name, int type) { - m_host.AddScriptLPS(1); + TaskInventoryItem item = m_host.Inventory.GetInventoryItem(name); - lock (m_host.TaskInventory) - { - foreach (KeyValuePair inv in m_host.TaskInventory) - { - if (inv.Value.Name == name) - { - if (inv.Value.Type != type) - return UUID.Zero; - - return inv.Value.AssetID; - } - } - } - - return UUID.Zero; + if (item != null && item.Type == type) + return item.AssetID; + else + return UUID.Zero; } /// @@ -1707,14 +1696,15 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api return rgb; } + if (face >= 0 && face < GetNumberOfSides(part)) { texcolor = tex.GetFace((uint)face).RGBA; rgb.x = texcolor.R; rgb.y = texcolor.G; rgb.z = texcolor.B; + return rgb; - } else { -- cgit v1.1 From 33b66009e43fa7c488b06c557dc46273288750d4 Mon Sep 17 00:00:00 2001 From: Blake.Bourque Date: Wed, 23 May 2012 07:38:03 -0400 Subject: One can now get hyoergrid region co-ordinates with llRequestSimulatorData --- .../Shared/Api/Implementation/LSL_Api.cs | 26 +++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 6438bcc..84493b1 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -9098,7 +9098,8 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api GridRegion info; - if (m_ScriptEngine.World.RegionInfo.RegionName == simulator) + if (m_ScriptEngine.World.RegionInfo.RegionName == simulator) //Det data for this simulator? + info = new GridRegion(m_ScriptEngine.World.RegionInfo); else info = m_ScriptEngine.World.GridService.GetRegionByName(m_ScriptEngine.World.RegionInfo.ScopeID, simulator); @@ -9111,10 +9112,25 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api ScriptSleep(1000); return UUID.Zero.ToString(); } - reply = new LSL_Vector( - info.RegionLocX, - info.RegionLocY, - 0).ToString(); + if (m_ScriptEngine.World.RegionInfo.RegionName != simulator) + { + //Hypergrid Region co-ordinates + uint rx = 0, ry = 0; + Utils.LongToUInts(Convert.ToUInt64(info.RegionSecret), out rx, out ry); + + reply = new LSL_Vector( + rx, + ry, + 0).ToString(); + } + else + { + //Local-cooridnates + reply = new LSL_Vector( + info.RegionLocX, + info.RegionLocY, + 0).ToString(); + } break; case ScriptBaseClass.DATA_SIM_STATUS: if (info != null) -- cgit v1.1 From 43a6f286209e87ebaeabc9e1f966444fa2fac18e Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 26 May 2012 01:55:35 +0100 Subject: If restating a region, clean up the physics scene after the main scene has been closed not before. If this is done before then on ODE agent update calls still incoming can fail as they try to use a raycastmanager that has been disposed. Bullet plugin does nothing on Dispose() However, I wouldn't be at all surprised if individual region restarting was buggy in lots of other areas. --- OpenSim/Region/Framework/Scenes/Scene.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 98a75e4..ce386be 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs @@ -1032,13 +1032,13 @@ namespace OpenSim.Region.Framework.Scenes } } + m_log.Error("[REGION]: Closing"); + Close(); + if (PhysicsScene != null) { PhysicsScene.Dispose(); - } - - m_log.Error("[REGION]: Closing"); - Close(); + } m_log.Error("[REGION]: Firing Region Restart Message"); -- cgit v1.1 From 0b72f773c7df849b335895d7c7a6cfe949f59f00 Mon Sep 17 00:00:00 2001 From: Talun Date: Tue, 22 May 2012 23:06:40 +0100 Subject: Mantis 6025 llRequestPermissions auto grant for NPCs. If the script requesting permissions is owned by either the NPC or the NPCs owner (if the NPC is created as owned) then grant any permissions automatically. --- .../Shared/Api/Implementation/LSL_Api.cs | 24 +++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 84493b1..f3787a0 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3406,9 +3406,31 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } ScenePresence presence = World.GetScenePresence(agentID); - if (presence != null) { + // If permissions are being requested from an NPC and were not implicitly granted above then + // auto grant all reuqested permissions if the script is owned by the NPC or the NPCs owner + INPCModule npcModule = World.RequestModuleInterface(); + if (npcModule != null && npcModule.IsNPC(agentID, World)) + { + if (agentID == m_host.ParentGroup.OwnerID || npcModule.GetOwner(agentID) == m_host.ParentGroup.OwnerID) + { + lock (m_host.TaskInventory) + { + m_host.TaskInventory[m_item.ItemID].PermsGranter = agentID; + m_host.TaskInventory[m_item.ItemID].PermsMask = perm; + } + + m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( + "run_time_permissions", new Object[] { + new LSL_Integer(perm) }, + new DetectParams[0])); + } + // it is an NPC, exit even if the permissions werent granted above, they are not going to answer + // the question! + return; + } + string ownerName = resolveName(m_host.ParentGroup.RootPart.OwnerID); if (ownerName == String.Empty) ownerName = "(hippos)"; -- cgit v1.1 From 7fd38788b4a654983c11efbcddb107feb4b3634a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 26 May 2012 02:14:32 +0100 Subject: minor: code formatting from 0b72f773 --- .../Shared/Api/Implementation/LSL_Api.cs | 23 +++++++++++----------- 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region') diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index f3787a0..deb68b8 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs @@ -3421,11 +3421,12 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.TaskInventory[m_item.ItemID].PermsMask = perm; } - m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( - "run_time_permissions", new Object[] { - new LSL_Integer(perm) }, - new DetectParams[0])); + m_ScriptEngine.PostScriptEvent( + m_item.ItemID, + new EventParams( + "run_time_permissions", new Object[] { new LSL_Integer(perm) }, new DetectParams[0])); } + // it is an NPC, exit even if the permissions werent granted above, they are not going to answer // the question! return; @@ -3454,10 +3455,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api } // Requested agent is not in range, refuse perms - m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( - "run_time_permissions", new Object[] { - new LSL_Integer(0) }, - new DetectParams[0])); + m_ScriptEngine.PostScriptEvent( + m_item.ItemID, + new EventParams("run_time_permissions", new Object[] { new LSL_Integer(0) }, new DetectParams[0])); } void handleScriptAnswer(IClientAPI client, UUID taskID, UUID itemID, int answer) @@ -3476,10 +3476,9 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api m_host.TaskInventory[m_item.ItemID].PermsMask = answer; } - m_ScriptEngine.PostScriptEvent(m_item.ItemID, new EventParams( - "run_time_permissions", new Object[] { - new LSL_Integer(answer) }, - new DetectParams[0])); + m_ScriptEngine.PostScriptEvent( + m_item.ItemID, + new EventParams("run_time_permissions", new Object[] { new LSL_Integer(answer) }, new DetectParams[0])); } public LSL_String llGetPermissionsKey() -- cgit v1.1