From 8fb3e71b14e28bf8a4ddb72e3d1b529128f090ce Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 15 Sep 2011 18:36:22 +0100 Subject: Shuffle order of code in invnetory connector GetFolderContent() calls to avoid a possible race condition --- .../Inventory/LocalInventoryServiceConnector.cs | 15 +++++++++------ .../Inventory/RemoteXInventoryServiceConnector.cs | 15 +++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs index 1c83f8e..097ff1a 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/LocalInventoryServiceConnector.cs @@ -185,15 +185,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory public InventoryCollection GetFolderContent(UUID userID, UUID folderID) { InventoryCollection invCol = m_InventoryService.GetFolderContent(userID, folderID); - Util.FireAndForget(delegate + + if (UserManager != null) { - if (UserManager != null) + // Protect ourselves against the caller subsequently modifying the items list + List items = new List(invCol.Items); + + Util.FireAndForget(delegate { - // Protect ourselves against the caller subsequently modifying the items list - foreach (InventoryItemBase item in new List(invCol.Items)) + foreach (InventoryItemBase item in items) UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); - } - }); + }); + } return invCol; } diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs index c9c716c..73ab4e3 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Inventory/RemoteXInventoryServiceConnector.cs @@ -193,15 +193,18 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Inventory public InventoryCollection GetFolderContent(UUID userID, UUID folderID) { InventoryCollection invCol = m_RemoteConnector.GetFolderContent(userID, folderID); - Util.FireAndForget(delegate + + if (UserManager != null) { - if (UserManager != null) + // Protect ourselves against the caller subsequently modifying the items list + List items = new List(invCol.Items); + + Util.FireAndForget(delegate { - // Protect ourselves against the caller subsequently modifying the items list - foreach (InventoryItemBase item in new List(invCol.Items)) + foreach (InventoryItemBase item in items) UserManager.AddUser(item.CreatorIdAsUuid, item.CreatorData); - } - }); + }); + } return invCol; } -- cgit v1.1 From de19dc3024e5359f594d0a32c593d905163c24ea Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 15 Sep 2011 18:58:58 +0100 Subject: refactor: rename SOG/SOP.GetProperties() to SendPropertiesToClient() to reflect what it actually does This also makes it consistent with some other methods that send data to the client. --- OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs index 8b78701..1e4f0a4 100644 --- a/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs +++ b/OpenSim/Region/CoreModules/World/Objects/BuySell/BuySellModule.cs @@ -101,7 +101,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell part.ParentGroup.HasGroupChanged = true; - part.GetProperties(client); + part.SendPropertiesToClient(client); } public bool BuyObject(IClientAPI remoteClient, UUID categoryID, uint localID, byte saleType, int salePrice) @@ -142,7 +142,7 @@ namespace OpenSim.Region.CoreModules.World.Objects.BuySell part.SalePrice = 10; group.HasGroupChanged = true; - part.GetProperties(remoteClient); + part.SendPropertiesToClient(remoteClient); part.TriggerScriptChangedEvent(Changed.OWNER); group.ResumeScripts(); part.ScheduleFullUpdate(); -- cgit v1.1 From c4efb97d49dec736151dfa3fa102efe6a5f6fbab Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 15 Sep 2011 22:59:29 +0100 Subject: Write code to create minimum necessary body parts/clothing and avatar entries to make a newly created user appear as a non-cloud on viewer 2 Viewer 2 no longer contains the default avatar assets (i.e. "Ruth") that would appear if the user had insufficient body part/clothing entries. Instead, avatars always appear as a cloud, which is a very bad experience for out-of-the-box OpenSim. Default is currently off. My intention is to switch it on for standalone shortly. This is not particularly flexible as "Ruth" is hardcoded, but this can change in the future, in co-ordination with the existing RemoteAdmin capabilities. Need to fix creation of suitable entries for users created as estate owners on standalone. Avatars still appear with spooky empty eyes, need to see if we can address this. This commit adds a "Default Iris" to the library (thanks to Eirynne Sieyes from http://opensimulator.org/mantis/view.php?id=1461) which can be used. --- OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index b6a1564..c5a1828 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -467,7 +467,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory return; } - // m_log.WarnFormat("[AVFACTORY]: Received request for wearables of {0}", client.AgentId); +// m_log.DebugFormat("[AVFACTORY]: Received request for wearables of {0}", client.Name); client.SendWearables(sp.Appearance.Wearables, sp.Appearance.Serial++); } -- cgit v1.1 From 522d6261f11ffaf8320c3f0775beb5d0608ce226 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 16 Sep 2011 00:12:12 +0100 Subject: Correctly create a freshly created estate owner's default items and avatar entries on standalone if applicable. --- .../LocalUserAccountServiceConnector.cs | 26 +++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs index 30ebb21..546fe88 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs @@ -45,7 +45,12 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts LogManager.GetLogger( MethodBase.GetCurrentMethod().DeclaringType); - private IUserAccountService m_UserService; + /// + /// This is not on the IUserAccountService. It's only being used so that standalone scenes can punch through + /// to a local UserAccountService when setting up an estate manager. + /// + public IUserAccountService UserAccountService { get; private set; } + private UserAccountCache m_Cache; private bool m_Enabled = false; @@ -86,9 +91,9 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts } Object[] args = new Object[] { source }; - m_UserService = ServerUtils.LoadPlugin(serviceDll, args); + UserAccountService = ServerUtils.LoadPlugin(serviceDll, args); - if (m_UserService == null) + if (UserAccountService == null) { m_log.ErrorFormat( "[LOCAL USER ACCOUNT SERVICE CONNECTOR]: Cannot load user account service specified as {0}", serviceDll); @@ -119,7 +124,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts if (!m_Enabled) return; - scene.RegisterModuleInterface(m_UserService); + scene.RegisterModuleInterface(UserAccountService); } public void RemoveRegion(Scene scene) @@ -147,7 +152,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts if (inCache) return account; - account = m_UserService.GetUserAccount(scopeID, userID); + account = UserAccountService.GetUserAccount(scopeID, userID); m_Cache.Cache(userID, account); return account; @@ -160,7 +165,7 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts if (inCache) return account; - account = m_UserService.GetUserAccount(scopeID, firstName, lastName); + account = UserAccountService.GetUserAccount(scopeID, firstName, lastName); if (account != null) m_Cache.Cache(account.PrincipalID, account); @@ -169,22 +174,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts public UserAccount GetUserAccount(UUID scopeID, string Email) { - return m_UserService.GetUserAccount(scopeID, Email); + return UserAccountService.GetUserAccount(scopeID, Email); } public List GetUserAccounts(UUID scopeID, string query) { - return m_UserService.GetUserAccounts(scopeID, query); + return UserAccountService.GetUserAccounts(scopeID, query); } // Update all updatable fields // public bool StoreUserAccount(UserAccount data) { - return m_UserService.StoreUserAccount(data); + return UserAccountService.StoreUserAccount(data); } #endregion - } -} +} \ No newline at end of file -- cgit v1.1 From 4ae4b14b5da9b828bbb7c4e5b05693ad8528556a Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 16 Sep 2011 00:24:23 +0100 Subject: refactor: move estate owner setup code into separate method --- .../UserAccounts/LocalUserAccountServiceConnector.cs | 2 ++ 1 file changed, 2 insertions(+) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs index 546fe88..0a0ce3c 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/UserAccounts/LocalUserAccountServiceConnector.cs @@ -124,6 +124,8 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.UserAccounts if (!m_Enabled) return; + // FIXME: Why do we bother setting this module and caching up if we just end up registering the inner + // user account service?! scene.RegisterModuleInterface(UserAccountService); } -- cgit v1.1 From 385c4a210deb63c25f082ab8a3f0c63c7bff8fb5 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 17 Sep 2011 00:26:53 +0100 Subject: On setting a new avatar appearance, if height hasn't changed then don't set that same height in ScenePresence. This prevents unnecessary work in the ODE module, though possibly that should be checking against same size sets itself --- .../Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index c5a1828..bb63bcd 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -211,8 +211,10 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // Process the visual params, this may change height as well if (visualParams != null) { + float oldHeight = sp.Appearance.AvatarHeight; changed = sp.Appearance.SetVisualParams(visualParams); - if (sp.Appearance.AvatarHeight > 0) + + if (sp.Appearance.AvatarHeight != oldHeight && sp.Appearance.AvatarHeight > 0) sp.SetHeight(sp.Appearance.AvatarHeight); } -- cgit v1.1 From 3ccb58c05c0a11fb4cff0f3adf90ca29d67b0c8b Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Thu, 22 Sep 2011 01:08:38 +0100 Subject: Fix failure to teleport when an agent is lured on the same sim (and probably in neighbouring sims) with HG lure active It turns out that the HG lure module was setting up a pending lure when it intercepted the instant message on its way out to the target avatar. However, an IM would only be sent if the user was remote, so it would not be set up for users on the same sim or in an immediate neighbour. We fix this by adding the pending lure when the message goes out and ignoring a duplicate pending lure add if it goes to out via IM. Hopefully addresses http://opensimulator.org/mantis/view.php?id=5690 --- .../Avatar/InstantMessage/HGMessageTransferModule.cs | 11 ++++++----- OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs | 16 ++++++++++++---- 2 files changed, 18 insertions(+), 9 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs index 7753c25..d294692 100644 --- a/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/InstantMessage/HGMessageTransferModule.cs @@ -24,6 +24,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.Collections; using System.Collections.Generic; @@ -145,14 +146,14 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage scene.Entities[toAgentID] is ScenePresence) { // m_log.DebugFormat( -// "[INSTANT MESSAGE]: Looking for root agent {0} in {1}", +// "[HG INSTANT MESSAGE]: Looking for root agent {0} in {1}", // toAgentID.ToString(), scene.RegionInfo.RegionName); ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; if (!user.IsChildAgent) { // Local message -// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID); +// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to root agent {0} {1}", user.Name, toAgentID); user.ControllingClient.SendInstantMessage(im); // Message sent @@ -166,7 +167,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage foreach (Scene scene in m_Scenes) { // m_log.DebugFormat( -// "[INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); +// "[HG INSTANT MESSAGE]: Looking for child of {0} in {1}", toAgentID, scene.RegionInfo.RegionName); if (scene.Entities.ContainsKey(toAgentID) && scene.Entities[toAgentID] is ScenePresence) @@ -174,7 +175,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage // Local message ScenePresence user = (ScenePresence) scene.Entities[toAgentID]; -// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID); +// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to child agent {0} {1}", user.Name, toAgentID); user.ControllingClient.SendInstantMessage(im); // Message sent @@ -183,7 +184,7 @@ namespace OpenSim.Region.CoreModules.Avatar.InstantMessage } } -// m_log.DebugFormat("[INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); +// m_log.DebugFormat("[HG INSTANT MESSAGE]: Delivering IM to {0} via XMLRPC", im.toAgentID); // Is the user a local user? UserAccount account = m_Scenes[0].UserAccountService.GetUserAccount(m_Scenes[0].RegionInfo.ScopeID, toAgentID); string url = string.Empty; diff --git a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs index d687e6a..bc5c1ff 100644 --- a/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Lure/HGLureModule.cs @@ -154,14 +154,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure if (im.dialog == (byte)InstantMessageDialog.RequestTeleport) { UUID sessionID = new UUID(im.imSessionID); - m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message); - m_PendingLures.Add(sessionID, im, 7200); // 2 hours + + if (!m_PendingLures.Contains(sessionID)) + { + m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", im.imSessionID, im.RegionID, im.message); + m_PendingLures.Add(sessionID, im, 7200); // 2 hours + } // Forward. We do this, because the IM module explicitly rejects // IMs of this type if (m_TransferModule != null) m_TransferModule.SendInstantMessage(im, delegate(bool success) { }); - } } @@ -177,12 +180,17 @@ namespace OpenSim.Region.CoreModules.Avatar.Lure m_log.DebugFormat("[HG LURE MODULE]: TP invite with message {0}", message); + UUID sessionID = UUID.Random(); + GridInstantMessage m = new GridInstantMessage(scene, client.AgentId, client.FirstName+" "+client.LastName, targetid, (byte)InstantMessageDialog.RequestTeleport, false, - message, UUID.Random(), false, presence.AbsolutePosition, + message, sessionID, false, presence.AbsolutePosition, new Byte[0]); m.RegionID = client.Scene.RegionInfo.RegionID.Guid; + + m_log.DebugFormat("[HG LURE MODULE]: RequestTeleport sessionID={0}, regionID={1}, message={2}", m.imSessionID, m.RegionID, m.message); + m_PendingLures.Add(sessionID, m, 7200); // 2 hours if (m_TransferModule != null) { -- cgit v1.1 From c8304b7f84b1a8d9fb978cae510f684e36419deb Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 23 Sep 2011 02:59:33 +0100 Subject: Fix avatar parameter updating for viewer 3 and maybe 2. When a slider parameter is changed, the viewer uploads a new shape (or other asset) and the item is updated to point to it. Viewer 1 uploaded the data in the initial request itself, so the asset references was almost always correctly updated. However, viewer 3/2 always uploads data in a subsequent xfer, which exposed a race condition where the viewer would make the item update before the asset had uploaded. This commit shuffles the order of operations to avoid this race, the item is updated with the new asset id instead of the old one while the upload was still taking place. A second race had to be fixed where avatar appearance would also be updated with the old asset id rather than the new one. This was fixed by updating the avatar appearance ids when the appearance was actually saved, rather than when the wearables update was made. --- .../AssetTransaction/AgentAssetsTransactions.cs | 168 +++++++++++++++------ .../AssetTransaction/AssetTransactionModule.cs | 25 ++- .../Agent/AssetTransaction/AssetXferUploader.cs | 127 +++++++++++++--- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 19 ++- 4 files changed, 253 insertions(+), 86 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs index 9d8082b..eed7cd5 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs @@ -41,14 +41,13 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction /// public class AgentAssetTransactions { -// private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); // Fields private bool m_dumpAssetsToFile; private Scene m_Scene; - public UUID UserID; - public Dictionary XferUploaders = - new Dictionary(); + private UUID UserID; + private Dictionary XferUploaders = new Dictionary(); // Methods public AgentAssetTransactions(UUID agentID, Scene scene, @@ -59,36 +58,94 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction m_dumpAssetsToFile = dumpAssetsToFile; } - public AssetXferUploader RequestXferUploader(UUID transactionID) + /// + /// Return a xfer uploader if one does not already exist. + /// + /// + /// + /// We must transfer the new asset ID into the uploader on creation, otherwise + /// we can see race conditions with other threads which can retrieve an item before it is updated with the new + /// asset id. + /// + /// + /// The xfer uploader requested. Null if one is already in existence. + /// FIXME: This is a bizarre thing to do, and is probably meant to signal an error condition if multiple + /// transfers are made. Needs to be corrected. + /// + public AssetXferUploader RequestXferUploader(UUID transactionID, UUID assetID) { - if (!XferUploaders.ContainsKey(transactionID)) + lock (XferUploaders) { - AssetXferUploader uploader = new AssetXferUploader(m_Scene, - m_dumpAssetsToFile); - - lock (XferUploaders) + if (!XferUploaders.ContainsKey(transactionID)) { + AssetXferUploader uploader = new AssetXferUploader(this, m_Scene, assetID, m_dumpAssetsToFile); + +// m_log.DebugFormat( +// "[AGENT ASSETS TRANSACTIONS]: Adding asset xfer uploader {0} since it didn't previously exist", transactionID); + XferUploaders.Add(transactionID, uploader); - } - return uploader; + return uploader; + } } + + m_log.WarnFormat("[AGENT ASSETS TRANSACTIONS]: Ignoring request for asset xfer uploader {0} since it already exists", transactionID); + return null; } public void HandleXfer(ulong xferID, uint packetID, byte[] data) { + AssetXferUploader foundUploader = null; + lock (XferUploaders) { foreach (AssetXferUploader uploader in XferUploaders.Values) { +// m_log.DebugFormat( +// "[AGENT ASSETS TRANSACTIONS]: In HandleXfer, inspect xfer upload with xfer id {0}", +// uploader.XferID); + if (uploader.XferID == xferID) { - uploader.HandleXferPacket(xferID, packetID, data); + foundUploader = uploader; break; } } } + + if (foundUploader != null) + { +// m_log.DebugFormat( +// "[AGENT ASSETS TRANSACTIONS]: Found xfer uploader for xfer id {0}, packet id {1}, data length {2}", +// xferID, packetID, data.Length); + + foundUploader.HandleXferPacket(xferID, packetID, data); + } + else + { + m_log.ErrorFormat( + "[AGENT ASSET TRANSACTIONS]: Could not find uploader for xfer id {0}, packet id {1}, data length {2}", + xferID, packetID, data.Length); + } + } + + public bool RemoveXferUploader(UUID transactionID) + { + lock (XferUploaders) + { + bool removed = XferUploaders.Remove(transactionID); + + if (!removed) + m_log.WarnFormat( + "[AGENT ASSET TRANSACTIONS]: Received request to remove xfer uploader with transaction ID {0} but none found", + transactionID); +// else +// m_log.DebugFormat( +// "[AGENT ASSET TRANSACTIONS]: Removed xfer uploader with transaction ID {0}", transactionID); + + return removed; + } } public void RequestCreateInventoryItem(IClientAPI remoteClient, @@ -96,16 +153,24 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction string description, string name, sbyte invType, sbyte type, byte wearableType, uint nextOwnerMask) { - if (XferUploaders.ContainsKey(transactionID)) + AssetXferUploader uploader = null; + + lock (XferUploaders) { - XferUploaders[transactionID].RequestCreateInventoryItem( - remoteClient, transactionID, folderID, - callbackID, description, name, invType, type, - wearableType, nextOwnerMask); + if (XferUploaders.ContainsKey(transactionID)) + uploader = XferUploaders[transactionID]; } - } - + if (uploader != null) + uploader.RequestCreateInventoryItem( + remoteClient, transactionID, folderID, + callbackID, description, name, invType, type, + wearableType, nextOwnerMask); + else + m_log.ErrorFormat( + "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to create inventory item {1} from {2}", + transactionID, name, remoteClient.Name); + } /// /// Get an uploaded asset. If the data is successfully retrieved, @@ -113,19 +178,18 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction /// /// /// The asset if the upload has completed, null if it has not. - public AssetBase GetTransactionAsset(UUID transactionID) + private AssetBase GetTransactionAsset(UUID transactionID) { - if (XferUploaders.ContainsKey(transactionID)) + lock (XferUploaders) { - AssetXferUploader uploader = XferUploaders[transactionID]; - AssetBase asset = uploader.GetAssetData(); - - lock (XferUploaders) + if (XferUploaders.ContainsKey(transactionID)) { - XferUploaders.Remove(transactionID); - } + AssetXferUploader uploader = XferUploaders[transactionID]; + AssetBase asset = uploader.GetAssetData(); + RemoveXferUploader(transactionID); - return asset; + return asset; + } } return null; @@ -135,7 +199,15 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction SceneObjectPart part, UUID transactionID, TaskInventoryItem item) { - if (XferUploaders.ContainsKey(transactionID)) + AssetXferUploader uploader = null; + + lock (XferUploaders) + { + if (XferUploaders.ContainsKey(transactionID)) + uploader = XferUploaders[transactionID]; + } + + if (uploader != null) { AssetBase asset = GetTransactionAsset(transactionID); @@ -161,28 +233,34 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction m_Scene.AssetService.Store(asset); } } + else + { + m_log.ErrorFormat( + "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update task inventory item {1} in {2}", + transactionID, item.Name, part.Name); + } } public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item) { - if (XferUploaders.ContainsKey(transactionID)) - { - AssetBase asset = GetTransactionAsset(transactionID); + AssetXferUploader uploader = null; - if (asset != null) - { - asset.FullID = UUID.Random(); - asset.Name = item.Name; - asset.Description = item.Description; - asset.Type = (sbyte)item.AssetType; - item.AssetID = asset.FullID; - - m_Scene.AssetService.Store(asset); + lock (XferUploaders) + { + if (XferUploaders.ContainsKey(transactionID)) + uploader = XferUploaders[transactionID]; + } - IInventoryService invService = m_Scene.InventoryService; - invService.UpdateItem(item); - } + if (uploader != null) + { + uploader.RequestUpdateInventoryItem(remoteClient, transactionID, item); + } + else + { + m_log.ErrorFormat( + "[AGENT ASSET TRANSACTIONS]: Could not find uploader with transaction ID {0} when handling request to update inventory item {1} for {2}", + transactionID, item.Name, remoteClient.Name); } } } diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs index 82558de..a28d5d7 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetTransactionModule.cs @@ -172,11 +172,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction /// /// Update an inventory item with data that has been received through a /// transaction. - /// + /// + /// /// This is called when clothing or body parts are updated (for /// instance, with new textures or colours). It may also be called in /// other situations. - /// + /// /// /// /// @@ -184,14 +185,12 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction UUID transactionID, InventoryItemBase item) { // m_log.DebugFormat( -// "[TRANSACTIONS MANAGER] Called HandleItemUpdateFromTransaction with item {0}", +// "[ASSET TRANSACTION MODULE]: Called HandleItemUpdateFromTransaction with item {0}", // item.Name); - AgentAssetTransactions transactions = - GetUserTransactions(remoteClient.AgentId); + AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); - transactions.RequestUpdateInventoryItem(remoteClient, - transactionID, item); + transactions.RequestUpdateInventoryItem(remoteClient, transactionID, item); } /// @@ -255,11 +254,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction } } - AgentAssetTransactions transactions = - GetUserTransactions(remoteClient.AgentId); - - AssetXferUploader uploader = - transactions.RequestXferUploader(transaction); + AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); + AssetXferUploader uploader = transactions.RequestXferUploader(transaction, assetID); if (uploader != null) { @@ -279,9 +275,8 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction public void HandleXfer(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) { - //m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data!"); - AgentAssetTransactions transactions = - GetUserTransactions(remoteClient.AgentId); +// m_log.Debug("xferID: " + xferID + " packetID: " + packetID + " data length " + data.Length); + AgentAssetTransactions transactions = GetUserTransactions(remoteClient.AgentId); transactions.HandleXfer(xferID, packetID, data); } diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs index a7929ba..ec4dfd0 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AssetXferUploader.cs @@ -40,11 +40,21 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction { private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); + /// + /// Reference to the object that holds this uploader. Used to remove ourselves from it's list if we + /// are performing a delayed update. + /// + AgentAssetTransactions m_transactions; + private AssetBase m_asset; private UUID InventFolder = UUID.Zero; private sbyte invType = 0; + private bool m_createItem = false; private uint m_createItemCallback = 0; + private bool m_updateItem = false; + private InventoryItemBase m_updateItemData; + private string m_description = String.Empty; private bool m_dumpAssetToFile; private bool m_finished = false; @@ -58,9 +68,11 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction public ulong XferID; private Scene m_Scene; - public AssetXferUploader(Scene scene, bool dumpAssetToFile) + public AssetXferUploader(AgentAssetTransactions transactions, Scene scene, UUID assetID, bool dumpAssetToFile) { + m_transactions = transactions; m_Scene = scene; + m_asset = new AssetBase() { FullID = assetID }; m_dumpAssetToFile = dumpAssetToFile; } @@ -73,6 +85,10 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction /// True if the transfer is complete, false otherwise or if the xferID was not valid public bool HandleXferPacket(ulong xferID, uint packetID, byte[] data) { +// m_log.DebugFormat( +// "[ASSET XFER UPLOADER]: Received packet {0} for xfer {1} (data length {2})", +// packetID, xferID, data.Length); + if (XferID == xferID) { if (m_asset.Data.Length > 1) @@ -107,16 +123,20 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction /// /// /// - /// True if the transfer is complete, false otherwise - public bool Initialise(IClientAPI remoteClient, UUID assetID, + public void Initialise(IClientAPI remoteClient, UUID assetID, UUID transaction, sbyte type, byte[] data, bool storeLocal, bool tempFile) { +// m_log.DebugFormat( +// "[ASSET XFER UPLOADER]: Initialised xfer from {0}, asset {1}, transaction {2}, type {3}, storeLocal {4}, tempFile {5}, already received data length {6}", +// remoteClient.Name, assetID, transaction, type, storeLocal, tempFile, data.Length); + ourClient = remoteClient; - m_asset = new AssetBase(assetID, "blank", type, - remoteClient.AgentId.ToString()); - m_asset.Data = data; + m_asset.Name = "blank"; m_asset.Description = "empty"; + m_asset.Type = type; + m_asset.CreatorID = remoteClient.AgentId.ToString(); + m_asset.Data = data; m_asset.Local = storeLocal; m_asset.Temporary = tempFile; @@ -126,21 +146,22 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction if (m_asset.Data.Length > 2) { SendCompleteMessage(); - return true; } else { RequestStartXfer(); } - - return false; } protected void RequestStartXfer() { XferID = Util.GetNextXferID(); - ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, - 0, new byte[0]); + +// m_log.DebugFormat( +// "[ASSET XFER UPLOADER]: Requesting Xfer of asset {0}, type {1}, transfer id {2} from {3}", +// m_asset.FullID, m_asset.Type, XferID, ourClient.Name); + + ourClient.SendXferRequest(XferID, m_asset.Type, m_asset.FullID, 0, new byte[0]); } protected void SendCompleteMessage() @@ -148,18 +169,32 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction ourClient.SendAssetUploadCompleteMessage(m_asset.Type, true, m_asset.FullID); - m_finished = true; - if (m_createItem) - { - DoCreateItem(m_createItemCallback); - } - else if (m_storeLocal) + // We must lock in order to avoid a race with a separate thread dealing with an inventory item or create + // message from other client UDP. + lock (this) { - m_Scene.AssetService.Store(m_asset); + m_finished = true; + if (m_createItem) + { + DoCreateItem(m_createItemCallback); + } + else if (m_updateItem) + { + StoreAssetForItemUpdate(m_updateItemData); + + // Remove ourselves from the list of transactions if completion was delayed until the transaction + // was complete. + // TODO: Should probably do the same for create item. + m_transactions.RemoveXferUploader(TransactionID); + } + else if (m_storeLocal) + { + m_Scene.AssetService.Store(m_asset); + } } m_log.DebugFormat( - "[ASSET TRANSACTIONS]: Uploaded asset {0} for transaction {1}", + "[ASSET XFER UPLOADER]: Uploaded asset {0} for transaction {1}", m_asset.FullID, TransactionID); if (m_dumpAssetToFile) @@ -205,18 +240,66 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction m_asset.Description = description; m_asset.Type = type; + // We must lock to avoid a race with a separate thread uploading the asset. + lock (this) + { + if (m_finished) + { + DoCreateItem(callbackID); + } + else + { + m_createItem = true; //set flag so the inventory item is created when upload is complete + m_createItemCallback = callbackID; + } + } + } + } + + public void RequestUpdateInventoryItem(IClientAPI remoteClient, UUID transactionID, InventoryItemBase item) + { + // We must lock to avoid a race with a separate thread uploading the asset. + lock (this) + { + m_asset.Name = item.Name; + m_asset.Description = item.Description; + m_asset.Type = (sbyte)item.AssetType; + + // We must always store the item at this point even if the asset hasn't finished uploading, in order + // to avoid a race condition when the appearance module retrieves the item to set the asset id in + // the AvatarAppearance structure. + item.AssetID = m_asset.FullID; + m_Scene.InventoryService.UpdateItem(item); + if (m_finished) { - DoCreateItem(callbackID); + StoreAssetForItemUpdate(item); } else { - m_createItem = true; //set flag so the inventory item is created when upload is complete - m_createItemCallback = callbackID; +// m_log.DebugFormat( +// "[ASSET XFER UPLOADER]: Holding update inventory item request {0} for {1} pending completion of asset xfer for transaction {2}", +// item.Name, remoteClient.Name, transactionID); + + m_updateItem = true; + m_updateItemData = item; } } } + /// + /// Store the asset for the given item. + /// + /// + private void StoreAssetForItemUpdate(InventoryItemBase item) + { +// m_log.DebugFormat( +// "[ASSET XFER UPLOADER]: Storing asset {0} for earlier item update for {1} for {2}", +// m_asset.FullID, item.Name, ourClient.Name); + + m_Scene.AssetService.Store(m_asset); + } + private void DoCreateItem(uint callbackID) { m_Scene.AssetService.Store(m_asset); diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index bb63bcd..0cadd83 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -211,6 +211,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // Process the visual params, this may change height as well if (visualParams != null) { +// string[] visualParamsStrings = new string[visualParams.Length]; +// for (int i = 0; i < visualParams.Length; i++) +// visualParamsStrings[i] = visualParams[i].ToString(); +// m_log.DebugFormat( +// "[AVFACTORY]: Setting visual params for {0} to {1}", +// client.Name, string.Join(", ", visualParamsStrings)); + float oldHeight = sp.Appearance.AvatarHeight; changed = sp.Appearance.SetVisualParams(visualParams); @@ -418,6 +425,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory // m_log.WarnFormat("[AVFACTORY] avatar {0} save appearance",agentid); + // This could take awhile since it needs to pull inventory + // We need to do it at the point of save so that there is a sufficient delay for any upload of new body part/shape + // assets and item asset id changes to complete. + // I don't think we need to worry about doing this within m_setAppearanceLock since the queueing avoids + // multiple save requests. + SetAppearanceAssets(sp.UUID, sp.Appearance); + m_scene.AvatarService.SetAppearance(agentid, sp.Appearance); } @@ -504,9 +518,6 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory avatAppearance.GetAssetsFrom(sp.Appearance); - // This could take awhile since it needs to pull inventory - SetAppearanceAssets(sp.UUID, ref avatAppearance); - lock (m_setAppearanceLock) { // Update only those fields that we have changed. This is important because the viewer @@ -540,7 +551,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory return true; } - private void SetAppearanceAssets(UUID userID, ref AvatarAppearance appearance) + private void SetAppearanceAssets(UUID userID, AvatarAppearance appearance) { IInventoryService invService = m_scene.InventoryService; -- cgit v1.1 From c14c4bc1ec5f381aa754068caf460c95e4539b17 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 24 Sep 2011 01:39:37 +0100 Subject: Don't try and resolve user account for authorization if the agent has come in via hypergrid. If a user account isn't available, this just passes on the name given by the agent instead. I'm not sure this is particularly useful since I believe that agent names could be faked in this context - it might be no more useful than a viewer agent string. In fact, there might even be an argument that passing on this name provides a false expectation of authenticity. However, I will apply for now. Patch applied from http://opensimulator.org/mantis/view.php?id=5696 Thanks Michelle Argus. --- .../Authorization/RemoteAuthorizationServiceConnector.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs index 003324f..86c0099 100644 --- a/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs +++ b/OpenSim/Region/CoreModules/ServiceConnectorsOut/Authorization/RemoteAuthorizationServiceConnector.cs @@ -141,11 +141,21 @@ namespace OpenSim.Region.CoreModules.ServiceConnectorsOut.Authorization if (scene != null) { + string mail = String.Empty; + UserAccount account = scene.UserAccountService.GetUserAccount(UUID.Zero, new UUID(userID)); + //if account not found, we assume its a foreign visitor from HG, else use account data... + if (account != null) + { + mail = account.Email; + firstName = account.FirstName; + lastName = account.LastName; + } + isAuthorized = IsAuthorizedForRegion( - userID, firstName, lastName, account.Email, scene.RegionInfo.RegionName, regionID, out message); + userID, firstName, lastName, mail, scene.RegionInfo.RegionName, regionID, out message); } else { -- cgit v1.1 From 39d7945efc8daa6e5cd0f4728b499e7a624526cd Mon Sep 17 00:00:00 2001 From: Kevin Houlihan & Michelle Argus Date: Wed, 21 Sep 2011 22:46:14 +0100 Subject: Added a setting to [Startup] section of config that will allow the simulator to start up with no regions configured. I added the boolean config setting "allow_regionless", defaulting to false. If set to true, opensim will start up ok if no region configurations are found in the specified region_info_source. It will not ask the user to create a region. --- .../CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs index ed3e516..6f83948 100644 --- a/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/LoadImageURL/LoadImageURLModule.cs @@ -112,10 +112,13 @@ namespace OpenSim.Region.CoreModules.Scripting.LoadImageURL public void PostInitialise() { - m_textureManager = m_scene.RequestModuleInterface(); - if (m_textureManager != null) + if (m_scene != null) { - m_textureManager.RegisterRender(GetContentType(), this); + m_textureManager = m_scene.RequestModuleInterface(); + if (m_textureManager != null) + { + m_textureManager.RegisterRender(GetContentType(), this); + } } } -- cgit v1.1 From e742cffe15d3e50841908d7babc2e4c4a7630635 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Fri, 30 Sep 2011 01:19:22 +0100 Subject: Add Enabled switch in new [Attachments] section in OpenSimDefaults.ini to allow attachments to be temporarily turned off. This is for debugging purposes. Defaults to Attachments Enabled --- .../Avatar/Attachments/AttachmentsModule.cs | 56 ++++++++++++++++++++-- .../InventoryAccess/InventoryAccessModule.cs | 1 - 2 files changed, 53 insertions(+), 4 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index b965d75..8757251 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -48,25 +48,42 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments private Scene m_scene; private IDialogModule m_dialogModule; + + /// + /// Are attachments enabled? + /// + public bool Enabled { get; private set; } public string Name { get { return "Attachments Module"; } } public Type ReplaceableInterface { get { return null; } } - public void Initialise(IConfigSource source) {} + public void Initialise(IConfigSource source) + { + IConfig config = source.Configs["Attachments"]; + if (config != null) + Enabled = config.GetBoolean("Enabled", true); + else + Enabled = true; + } public void AddRegion(Scene scene) { m_scene = scene; m_dialogModule = m_scene.RequestModuleInterface(); m_scene.RegisterModuleInterface(this); - m_scene.EventManager.OnNewClient += SubscribeToClientEvents; + + if (Enabled) + m_scene.EventManager.OnNewClient += SubscribeToClientEvents; + // TODO: Should probably be subscribing to CloseClient too, but this doesn't yet give us IClientAPI } public void RemoveRegion(Scene scene) { m_scene.UnregisterModuleInterface(this); - m_scene.EventManager.OnNewClient -= SubscribeToClientEvents; + + if (Enabled) + m_scene.EventManager.OnNewClient -= SubscribeToClientEvents; } public void RegionLoaded(Scene scene) {} @@ -102,6 +119,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// public void RezAttachments(IScenePresence sp) { + if (!Enabled) + return; + if (null == sp.Appearance) { m_log.WarnFormat("[ATTACHMENTS MODULE]: Appearance has not been initialized for agent {0}", sp.UUID); @@ -145,6 +165,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { // m_log.DebugFormat("[ATTACHMENTS MODULE]: Saving changed attachments for {0}", sp.Name); + if (!Enabled) + return; + foreach (SceneObjectGroup grp in sp.GetAttachments()) { // if (grp.HasGroupChanged) // Resizer scripts? @@ -163,6 +186,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // "[ATTACHMENTS MODULE]: Deleting attachments from scene {0} for {1}, silent = {2}", // m_scene.RegionInfo.RegionName, sp.Name, silent); + if (!Enabled) + return; + foreach (SceneObjectGroup sop in sp.GetAttachments()) { sop.Scene.DeleteSceneObject(sop, silent); @@ -184,6 +210,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", // objectLocalID, remoteClient.Name, AttachmentPt, silent); + if (!Enabled) + return; + try { ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); @@ -232,6 +261,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent) { + if (!Enabled) + return false; + ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); if (sp == null) @@ -331,6 +363,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header, RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects) { + if (!Enabled) + return; + ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); if (sp == null) @@ -354,6 +389,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { + if (!Enabled) + return null; + // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", // (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); @@ -373,6 +411,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt) { + if (!Enabled) + return null; + // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: RezSingleAttachmentFromInventory to point {0} from item {1} for {2}", // (AttachmentPoint)AttachmentPt, itemID, sp.Name); @@ -535,6 +576,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient) { + if (!Enabled) + return; + ScenePresence presence; if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) { @@ -554,6 +598,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient) { + if (!Enabled) + return; + // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", // remoteClient.Name, soLocalId); @@ -669,6 +716,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void UpdateAttachmentPosition(SceneObjectGroup sog, Vector3 pos) { + if (!Enabled) + return; + // First we save the // attachment point information, then we update the relative // positioning. Then we have to mark the object as NOT an diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 03238d9..54b422b 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs @@ -150,7 +150,6 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess { if (!m_Enabled) return; - } #endregion -- cgit v1.1 From 246443773ae52420092b483603d0e1daf9b87f00 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Sat, 1 Oct 2011 00:15:30 +0100 Subject: minor: remove clutter null check from pass in config to AvatarFactoryModule.Initialize() This is never null --- .../CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 0cadd83..d4e1736 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -64,15 +64,12 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory scene.RegisterModuleInterface(this); scene.EventManager.OnNewClient += NewClient; - if (config != null) + IConfig sconfig = config.Configs["Startup"]; + if (sconfig != null) { - IConfig sconfig = config.Configs["Startup"]; - if (sconfig != null) - { - m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime))); - m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime))); - // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime); - } + m_savetime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSave",Convert.ToString(m_savetime))); + m_sendtime = Convert.ToInt32(sconfig.GetString("DelayBeforeAppearanceSend",Convert.ToString(m_sendtime))); + // m_log.InfoFormat("[AVFACTORY] configured for {0} save and {1} send",m_savetime,m_sendtime); } if (m_scene == null) -- cgit v1.1 From e77c919290e166f19e77f3ef040418dd39f2f5bd Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Mon, 3 Oct 2011 11:55:54 -0700 Subject: Remove usage of Linden packet types from inside Attachments Module and interface --- .../Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 8757251..48695a4 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -360,8 +360,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments public void RezMultipleAttachmentsFromInventory( IClientAPI remoteClient, - RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header, - RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects) + List> rezlist) { if (!Enabled) return; @@ -380,9 +379,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); - foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects) + foreach (KeyValuePair rez in rezlist) { - RezSingleAttachmentFromInventory(sp, obj.ItemID, obj.AttachmentPt); + RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value); } } } @@ -941,4 +940,4 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return item; } } -} \ No newline at end of file +} -- cgit v1.1 From 460946ad62b682c7a942751f192ca9e96b662f0e Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Mon, 3 Oct 2011 16:44:32 -0700 Subject: Removed redundant code in AttachmentsModule and simplified interfaces which converted back and forth between ScenePresence and IClientAPI. More to be done still. --- .../Avatar/Attachments/AttachmentsModule.cs | 158 +++++++++------------ .../Attachments/Tests/AttachmentsModuleTests.cs | 10 +- 2 files changed, 73 insertions(+), 95 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 48695a4..78b9afc 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -152,7 +152,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (sp.PresenceType == PresenceType.Npc) RezSingleAttachmentFromInventoryInternal(sp, UUID.Zero, attach.AssetID, p); else - RezSingleAttachmentFromInventory(sp.ControllingClient, attach.ItemID, p); + RezSingleAttachmentFromInventory(sp, attach.ItemID, p); } catch (Exception e) { @@ -204,7 +204,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// /// - public void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) + private void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) { // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", @@ -258,25 +258,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace); } } - - public bool AttachObject(IClientAPI remoteClient, SceneObjectGroup group, uint AttachmentPt, bool silent) - { - if (!Enabled) - return false; - - ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); - - if (sp == null) - { - m_log.ErrorFormat( - "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId); - return false; - } - - return AttachObject(sp, group, AttachmentPt, silent); - } - private bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) + public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) { lock (sp.AttachmentsSyncLock) { @@ -356,29 +339,31 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } return true; + } + + private void RezMultipleAttachmentsFromInventory(IClientAPI remoteClient, List> rezlist) + { + if (!Enabled) + return; + + ScenePresence sp; + if (m_scene.TryGetScenePresence(remoteClient.AgentId, out sp)) + RezMultipleAttachmentsFromInventory(sp, rezlist); + else + m_log.ErrorFormat( + "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()", + remoteClient.Name, remoteClient.AgentId); + return; } - public void RezMultipleAttachmentsFromInventory( - IClientAPI remoteClient, - List> rezlist) + public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List> rezlist) { if (!Enabled) - return; - - ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); - - if (sp == null) - { - m_log.ErrorFormat( - "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()", - remoteClient.Name, remoteClient.AgentId); - return; - } - + return; + +// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); lock (sp.AttachmentsSyncLock) { -// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); - foreach (KeyValuePair rez in rezlist) { RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value); @@ -386,7 +371,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } } - public ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) + private ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) { if (!Enabled) return null; @@ -408,7 +393,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt); } - public ISceneEntity RezSingleAttachmentFromInventory(ScenePresence sp, UUID itemID, uint AttachmentPt) + public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) { if (!Enabled) return null; @@ -593,23 +578,33 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments DetachSingleAttachmentToInv(itemID, presence); } } + } + + private void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient) + { + if (!Enabled) + return; + + ScenePresence sp; + if (m_scene.TryGetScenePresence(remoteClient.AgentId, out sp)) + DetachSingleAttachmentToGround(sp, soLocalId); } - public void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient) + public void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId) { if (!Enabled) return; // m_log.DebugFormat( // "[ATTACHMENTS MODULE]: DetachSingleAttachmentToGround() for {0}, object {1}", -// remoteClient.Name, soLocalId); +// sp.UUID, soLocalId); SceneObjectGroup so = m_scene.GetGroupByPrim(soLocalId); if (so == null) return; - if (so.AttachedAvatar != remoteClient.AgentId) + if (so.AttachedAvatar != sp.UUID) return; UUID inventoryID = so.GetFromItemID(); @@ -618,57 +613,40 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // "[ATTACHMENTS MODULE]: In DetachSingleAttachmentToGround(), object is {0} {1}, associated item is {2}", // so.Name, so.LocalId, inventoryID); - ScenePresence presence; - if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) + lock (sp.AttachmentsSyncLock) { - lock (presence.AttachmentsSyncLock) - { - if (!m_scene.Permissions.CanRezObject( - so.PrimCount, remoteClient.AgentId, presence.AbsolutePosition)) - return; - - bool changed = presence.Appearance.DetachAttachment(inventoryID); - if (changed && m_scene.AvatarFactory != null) - m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); - - presence.RemoveAttachment(so); - DetachSceneObjectToGround(so, presence); - - List uuids = new List(); - uuids.Add(inventoryID); - m_scene.InventoryService.DeleteItems(remoteClient.AgentId, uuids); - remoteClient.SendRemoveInventoryItem(inventoryID); - } - - m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); + if (!m_scene.Permissions.CanRezObject( + so.PrimCount, sp.UUID, sp.AbsolutePosition)) + return; + + bool changed = sp.Appearance.DetachAttachment(inventoryID); + if (changed && m_scene.AvatarFactory != null) + m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); + + sp.RemoveAttachment(so); + + SceneObjectPart rootPart = so.RootPart; + rootPart.FromItemID = UUID.Zero; + so.AbsolutePosition = sp.AbsolutePosition; + so.AttachedAvatar = UUID.Zero; + rootPart.SetParentLocalId(0); + so.ClearPartAttachmentData(); + rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim); + so.HasGroupChanged = true; + rootPart.Rezzed = DateTime.Now; + rootPart.RemFlag(PrimFlags.TemporaryOnRez); + so.AttachToBackup(); + m_scene.EventManager.TriggerParcelPrimCountTainted(); + rootPart.ScheduleFullUpdate(); + rootPart.ClearUndoState(); + + List uuids = new List(); + uuids.Add(inventoryID); + m_scene.InventoryService.DeleteItems(sp.UUID, uuids); + sp.ControllingClient.SendRemoveInventoryItem(inventoryID); } - } - /// - /// Detach the given scene object to the ground. - /// - /// - /// The caller has to take care of all the other work in updating avatar appearance, inventory, etc. - /// - /// The scene object to detach. - /// The scene presence from which the scene object is being detached. - private void DetachSceneObjectToGround(SceneObjectGroup so, ScenePresence sp) - { - SceneObjectPart rootPart = so.RootPart; - - rootPart.FromItemID = UUID.Zero; - so.AbsolutePosition = sp.AbsolutePosition; - so.AttachedAvatar = UUID.Zero; - rootPart.SetParentLocalId(0); - so.ClearPartAttachmentData(); - rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim); - so.HasGroupChanged = true; - rootPart.Rezzed = DateTime.Now; - rootPart.RemFlag(PrimFlags.TemporaryOnRez); - so.AttachToBackup(); - m_scene.EventManager.TriggerParcelPrimCountTainted(); - rootPart.ScheduleFullUpdate(); - rootPart.ClearUndoState(); + m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); } // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index ff3358f..832c6eb 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -106,7 +106,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, attName).ParentGroup; - m_attMod.AttachObject(m_presence.ControllingClient, so, (uint)AttachmentPoint.Chest, false); + m_attMod.AttachObject(m_presence, so, (uint)AttachmentPoint.Chest, false); // Check status on scene presence Assert.That(m_presence.HasAttachments(), Is.True); @@ -140,7 +140,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); m_attMod.RezSingleAttachmentFromInventory( - m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); + m_presence, attItemId, (uint)AttachmentPoint.Chest); // Check scene presence status Assert.That(m_presence.HasAttachments(), Is.True); @@ -174,8 +174,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); ISceneEntity so = m_attMod.RezSingleAttachmentFromInventory( - m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); - m_attMod.DetachSingleAttachmentToGround(so.LocalId, m_presence.ControllingClient); + m_presence, attItemId, (uint)AttachmentPoint.Chest); + m_attMod.DetachSingleAttachmentToGround(m_presence, so.LocalId); // Check scene presence status Assert.That(m_presence.HasAttachments(), Is.False); @@ -208,7 +208,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests scene, attName, attItemId, attAssetId, m_presence.UUID, InventoryType.Object); m_attMod.RezSingleAttachmentFromInventory( - m_presence.ControllingClient, attItemId, (uint)AttachmentPoint.Chest); + m_presence, attItemId, (uint)AttachmentPoint.Chest); m_attMod.DetachSingleAttachmentToInv(attItemId, m_presence.ControllingClient); // Check status on scene presence -- cgit v1.1 From 92c88121c72386f85472c6cf4891eca8b62b9867 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Tue, 4 Oct 2011 14:40:39 -0700 Subject: Removed all refs to IClientAPI from IAttachmentsModule. Separated client handlers for attachments to call public interface and rearranged module file into sections --- .../Avatar/Attachments/AttachmentsModule.cs | 734 +++++++++++---------- .../Attachments/Tests/AttachmentsModuleTests.cs | 2 +- 2 files changed, 375 insertions(+), 361 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs index 78b9afc..f893eb3 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/AttachmentsModule.cs @@ -44,6 +44,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments [Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "AttachmentsModule")] public class AttachmentsModule : IAttachmentsModule, INonSharedRegionModule { + #region INonSharedRegionModule private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); private Scene m_scene; @@ -92,26 +93,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { RemoveRegion(m_scene); } - - public void SubscribeToClientEvents(IClientAPI client) - { - client.OnRezSingleAttachmentFromInv += RezSingleAttachmentFromInventory; - client.OnRezMultipleAttachmentsFromInv += RezMultipleAttachmentsFromInventory; - client.OnObjectAttach += AttachObject; - client.OnObjectDetach += DetachObject; - client.OnDetachAttachmentIntoInv += DetachSingleAttachmentToInv; - client.OnObjectDrop += DetachSingleAttachmentToGround; - } - - public void UnsubscribeFromClientEvents(IClientAPI client) - { - client.OnRezSingleAttachmentFromInv -= RezSingleAttachmentFromInventory; - client.OnRezMultipleAttachmentsFromInv -= RezMultipleAttachmentsFromInventory; - client.OnObjectAttach -= AttachObject; - client.OnObjectDetach -= DetachObject; - client.OnDetachAttachmentIntoInv -= DetachSingleAttachmentToInv; - client.OnObjectDrop -= DetachSingleAttachmentToGround; - } + + #endregion + + #region IAttachmentsModule /// /// RezAttachments. This should only be called upon login on the first region. @@ -174,7 +159,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // { grp.IsAttachment = false; grp.AbsolutePosition = grp.RootPart.AttachedPos; - UpdateKnownItem(sp.ControllingClient, grp); + UpdateKnownItem(sp, grp); grp.IsAttachment = true; // } } @@ -197,68 +182,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments sp.ClearAttachments(); } - /// - /// Called by client - /// - /// - /// - /// - /// - private void AttachObject(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) - { -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", -// objectLocalID, remoteClient.Name, AttachmentPt, silent); - - if (!Enabled) - return; - - try - { - ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); - - if (sp == null) - { - m_log.ErrorFormat( - "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId); - return; - } - - // If we can't take it, we can't attach it! - SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID); - if (part == null) - return; - - if (!m_scene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId)) - { - remoteClient.SendAgentAlertMessage( - "You don't have sufficient permissions to attach this object", false); - - return; - } - - // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should - // be removed when that functionality is implemented in opensim - AttachmentPt &= 0x7f; - - // Calls attach with a Zero position - if (AttachObject(sp, part.ParentGroup, AttachmentPt, false)) - { - m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); - - // Save avatar attachment information - m_log.Debug( - "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId - + ", AttachmentPoint: " + AttachmentPt); - - } - } - catch (Exception e) - { - m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace); - } - } - public bool AttachObject(IScenePresence sp, SceneObjectGroup group, uint attachmentPt, bool silent) { lock (sp.AttachmentsSyncLock) @@ -320,7 +243,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments UUID oldAttachmentItemID = attachments[0].GetFromItemID(); if (oldAttachmentItemID != UUID.Zero) - DetachSingleAttachmentToInv(oldAttachmentItemID, sp); + DetachSingleAttachmentToInvInternal(sp, oldAttachmentItemID); else m_log.WarnFormat( "[ATTACHMENTS MODULE]: When detaching existing attachment {0} {1} at point {2} to make way for {3} {4} for {5}, couldn't find the associated item ID to adjust inventory attachment record!", @@ -330,7 +253,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments // Add the new attachment to inventory if we don't already have it. UUID newAttachmentItemID = group.GetFromItemID(); if (newAttachmentItemID == UUID.Zero) - newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp.ControllingClient, group).ID; + newAttachmentItemID = AddSceneObjectAsNewAttachmentInInv(sp, group).ID; ShowAttachInUserInventory(sp, attachmentPt, newAttachmentItemID, group); } @@ -339,58 +262,6 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments } return true; - } - - private void RezMultipleAttachmentsFromInventory(IClientAPI remoteClient, List> rezlist) - { - if (!Enabled) - return; - - ScenePresence sp; - if (m_scene.TryGetScenePresence(remoteClient.AgentId, out sp)) - RezMultipleAttachmentsFromInventory(sp, rezlist); - else - m_log.ErrorFormat( - "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()", - remoteClient.Name, remoteClient.AgentId); - return; - } - - public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List> rezlist) - { - if (!Enabled) - return; - -// m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); - lock (sp.AttachmentsSyncLock) - { - foreach (KeyValuePair rez in rezlist) - { - RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value); - } - } - } - - private ISceneEntity RezSingleAttachmentFromInventory(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) - { - if (!Enabled) - return null; - -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", -// (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); - - ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); - - if (sp == null) - { - m_log.ErrorFormat( - "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()", - remoteClient.Name, remoteClient.AgentId); - return null; - } - - return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt); } public ISceneEntity RezSingleAttachmentFromInventory(IScenePresence sp, UUID itemID, uint AttachmentPt) @@ -435,159 +306,24 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments SceneObjectGroup att = RezSingleAttachmentFromInventoryInternal(sp, itemID, UUID.Zero, AttachmentPt); if (att == null) - DetachSingleAttachmentToInv(itemID, sp.ControllingClient); + DetachSingleAttachmentToInv(sp, itemID); return att; } - private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( - IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) - { - IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); - if (invAccess != null) - { - lock (sp.AttachmentsSyncLock) - { - 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 - { - 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; - - // 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); - - 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 null; - } - - /// - /// Update the user inventory to reflect an attachment - /// - /// - /// - /// - /// - private void ShowAttachInUserInventory( - IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) - { -// m_log.DebugFormat( -// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", -// att.Name, sp.Name, AttachmentPt, itemID); - - if (UUID.Zero == itemID) - { - m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID."); - return; - } - - if (0 == AttachmentPt) - { - m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error attachment point."); - return; - } - - InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); - item = m_scene.InventoryService.GetItem(item); - bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); - if (changed && m_scene.AvatarFactory != null) - m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); - } - - public void DetachObject(uint objectLocalID, IClientAPI remoteClient) - { -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: DetachObject() for object {0} on {1}", objectLocalID, remoteClient.Name); - - SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); - if (group != null) - { - DetachSingleAttachmentToInv(group.GetFromItemID(), remoteClient); - } - } - - public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient) + public void RezMultipleAttachmentsFromInventory(IScenePresence sp, List> rezlist) { if (!Enabled) return; - ScenePresence presence; - if (m_scene.TryGetScenePresence(remoteClient.AgentId, out presence)) + // m_log.DebugFormat("[ATTACHMENTS MODULE]: Rezzing multiple attachments from inventory for {0}", sp.Name); + lock (sp.AttachmentsSyncLock) { - lock (presence.AttachmentsSyncLock) + foreach (KeyValuePair rez in rezlist) { - // Save avatar attachment information - m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + remoteClient.AgentId + ", ItemID: " + itemID); - - bool changed = presence.Appearance.DetachAttachment(itemID); - if (changed && m_scene.AvatarFactory != null) - m_scene.AvatarFactory.QueueAppearanceSave(remoteClient.AgentId); - - DetachSingleAttachmentToInv(itemID, presence); + RezSingleAttachmentFromInventory(sp, rez.Key, rez.Value); } } - } - - private void DetachSingleAttachmentToGround(uint soLocalId, IClientAPI remoteClient) - { - if (!Enabled) - return; - - ScenePresence sp; - if (m_scene.TryGetScenePresence(remoteClient.AgentId, out sp)) - DetachSingleAttachmentToGround(sp, soLocalId); } public void DetachSingleAttachmentToGround(IScenePresence sp, uint soLocalId) @@ -617,27 +353,27 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments { if (!m_scene.Permissions.CanRezObject( so.PrimCount, sp.UUID, sp.AbsolutePosition)) - return; - + return; + bool changed = sp.Appearance.DetachAttachment(inventoryID); if (changed && m_scene.AvatarFactory != null) - m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); - - sp.RemoveAttachment(so); - - SceneObjectPart rootPart = so.RootPart; - rootPart.FromItemID = UUID.Zero; - so.AbsolutePosition = sp.AbsolutePosition; - so.AttachedAvatar = UUID.Zero; - rootPart.SetParentLocalId(0); - so.ClearPartAttachmentData(); - rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim); - so.HasGroupChanged = true; - rootPart.Rezzed = DateTime.Now; - rootPart.RemFlag(PrimFlags.TemporaryOnRez); - so.AttachToBackup(); - m_scene.EventManager.TriggerParcelPrimCountTainted(); - rootPart.ScheduleFullUpdate(); + m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); + + sp.RemoveAttachment(so); + + SceneObjectPart rootPart = so.RootPart; + rootPart.FromItemID = UUID.Zero; + so.AbsolutePosition = sp.AbsolutePosition; + so.AttachedAvatar = UUID.Zero; + rootPart.SetParentLocalId(0); + so.ClearPartAttachmentData(); + rootPart.ApplyPhysics(rootPart.GetEffectiveObjectFlags(), rootPart.VolumeDetectActive, m_scene.m_physicalPrim); + so.HasGroupChanged = true; + rootPart.Rezzed = DateTime.Now; + rootPart.RemFlag(PrimFlags.TemporaryOnRez); + so.AttachToBackup(); + m_scene.EventManager.TriggerParcelPrimCountTainted(); + rootPart.ScheduleFullUpdate(); rootPart.ClearUndoState(); List uuids = new List(); @@ -648,46 +384,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.EventManager.TriggerOnAttach(so.LocalId, so.UUID, UUID.Zero); } - - // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. - // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? - private void DetachSingleAttachmentToInv(UUID itemID, IScenePresence sp) - { -// m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); - - if (itemID == UUID.Zero) // If this happened, someone made a mistake.... - return; - - // We can NOT use the dictionries here, as we are looking - // for an entity by the fromAssetID, which is NOT the prim UUID - EntityBase[] detachEntities = m_scene.GetEntities(); - SceneObjectGroup group; + public void DetachSingleAttachmentToInv(IScenePresence sp, UUID itemID) + { lock (sp.AttachmentsSyncLock) { - foreach (EntityBase entity in detachEntities) - { - if (entity is SceneObjectGroup) - { - group = (SceneObjectGroup)entity; - if (group.GetFromItemID() == itemID) - { - m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); - sp.RemoveAttachment(group); - - // Prepare sog for storage - group.AttachedAvatar = UUID.Zero; - group.RootPart.SetParentLocalId(0); - group.IsAttachment = false; - group.AbsolutePosition = group.RootPart.AttachedPos; + // Save avatar attachment information + m_log.Debug("[ATTACHMENTS MODULE]: Detaching from UserID: " + sp.UUID + ", ItemID: " + itemID); - UpdateKnownItem(sp.ControllingClient, group); - m_scene.DeleteSceneObject(group, false); + bool changed = sp.Appearance.DetachAttachment(itemID); + if (changed && m_scene.AvatarFactory != null) + m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); - return; - } - } - } + DetachSingleAttachmentToInvInternal(sp, itemID); } } @@ -709,7 +418,37 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments sog.AttachmentPoint = attachmentPoint; sog.HasGroupChanged = true; } - + + #endregion + + #region AttachmentModule private methods + + // This is public but is not part of the IAttachmentsModule interface. + // RegionCombiner module needs to poke at it to deliver client events. + // This breaks the encapsulation of the module and should get fixed somehow. + public void SubscribeToClientEvents(IClientAPI client) + { + client.OnRezSingleAttachmentFromInv += Client_OnRezSingleAttachmentFromInv; + client.OnRezMultipleAttachmentsFromInv += Client_OnRezMultipleAttachmentsFromInv; + client.OnObjectAttach += Client_OnObjectAttach; + client.OnObjectDetach += Client_OnObjectDetach; + client.OnDetachAttachmentIntoInv += Client_OnDetachAttachmentIntoInv; + client.OnObjectDrop += Client_OnObjectDrop; + } + + // This is public but is not part of the IAttachmentsModule interface. + // RegionCombiner module needs to poke at it to deliver client events. + // This breaks the encapsulation of the module and should get fixed somehow. + public void UnsubscribeFromClientEvents(IClientAPI client) + { + client.OnRezSingleAttachmentFromInv -= Client_OnRezSingleAttachmentFromInv; + client.OnRezMultipleAttachmentsFromInv -= Client_OnRezMultipleAttachmentsFromInv; + client.OnObjectAttach -= Client_OnObjectAttach; + client.OnObjectDetach -= Client_OnObjectDetach; + client.OnDetachAttachmentIntoInv -= Client_OnDetachAttachmentIntoInv; + client.OnObjectDrop -= Client_OnObjectDrop; + } + /// /// Update the attachment asset for the new sog details if they have changed. /// @@ -717,9 +456,9 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// This is essential for preserving attachment attributes such as permission. Unlike normal scene objects, /// these details are not stored on the region. /// - /// + /// /// - private void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp) + private void UpdateKnownItem(IScenePresence sp, SceneObjectGroup grp) { if (grp.HasGroupChanged || grp.ContainsScripts()) { @@ -729,7 +468,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); - InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), remoteClient.AgentId); + InventoryItemBase item = new InventoryItemBase(grp.GetFromItemID(), sp.UUID); item = m_scene.InventoryService.GetItem(item); if (item != null) @@ -739,7 +478,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments grp.GetPartDescription(grp.LocalId), (sbyte)AssetType.Object, Utils.StringToBytes(sceneObjectXml), - remoteClient.AgentId); + sp.UUID); m_scene.AssetService.Store(asset); item.AssetID = asset.FullID; @@ -751,8 +490,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments m_scene.InventoryService.UpdateItem(item); // this gets called when the agent logs off! - if (remoteClient != null) - remoteClient.SendInventoryItemCreateUpdate(item, 0); + if (sp.ControllingClient != null) + sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0); } } else @@ -761,8 +500,8 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments "[ATTACHMENTS MODULE]: Don't need to update asset for unchanged attachment {0}, attachpoint {1}", grp.UUID, grp.AttachmentPoint); } - } - + } + /// /// Attach this scene object to the given avatar. /// @@ -776,19 +515,19 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// private void AttachToAgent( - IScenePresence avatar, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) + IScenePresence sp, SceneObjectGroup so, uint attachmentpoint, Vector3 attachOffset, bool silent) { -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", -// so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); - + // m_log.DebugFormat( + // "[ATTACHMENTS MODULE]: Adding attachment {0} to avatar {1} in pt {2} pos {3} {4}", + // so.Name, avatar.Name, attachmentpoint, attachOffset, so.RootPart.AttachedPos); + so.DetachFromBackup(); // Remove from database and parcel prim count m_scene.DeleteFromStorage(so.UUID); m_scene.EventManager.TriggerParcelPrimCountTainted(); - so.AttachedAvatar = avatar.UUID; + so.AttachedAvatar = sp.UUID; if (so.RootPart.PhysActor != null) { @@ -799,10 +538,10 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments so.AbsolutePosition = attachOffset; so.RootPart.AttachedPos = attachOffset; so.IsAttachment = true; - so.RootPart.SetParentLocalId(avatar.LocalId); + so.RootPart.SetParentLocalId(sp.LocalId); so.AttachmentPoint = attachmentpoint; - avatar.AddAttachment(so); + sp.AddAttachment(so); if (!silent) { @@ -818,7 +557,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments so.IsSelected = false; // fudge.... so.ScheduleGroupForFullUpdate(); } - + // In case it is later dropped again, don't let // it get cleaned up so.RootPart.RemFlag(PrimFlags.TemporaryOnRez); @@ -830,11 +569,11 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments /// /// /// The user inventory item created that holds the attachment. - private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IClientAPI remoteClient, SceneObjectGroup grp) + private InventoryItemBase AddSceneObjectAsNewAttachmentInInv(IScenePresence sp, SceneObjectGroup grp) { -// m_log.DebugFormat( -// "[ATTACHMENTS MODULE]: Called AddSceneObjectAsAttachment for object {0} {1} for {2}", -// grp.Name, grp.LocalId, remoteClient.Name); + // 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) @@ -863,14 +602,14 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments grp.GetPartDescription(grp.LocalId), (sbyte)AssetType.Object, Utils.StringToBytes(sceneObjectXml), - remoteClient.AgentId); + sp.UUID); m_scene.AssetService.Store(asset); InventoryItemBase item = new InventoryItemBase(); item.CreatorId = grp.RootPart.CreatorID.ToString(); item.CreatorData = grp.RootPart.CreatorData; - item.Owner = remoteClient.AgentId; + item.Owner = sp.UUID; item.ID = UUID.Random(); item.AssetID = asset.FullID; item.Description = asset.Description; @@ -878,13 +617,13 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments item.AssetType = asset.Type; item.InvType = (int)InventoryType.Object; - InventoryFolderBase folder = m_scene.InventoryService.GetFolderForType(remoteClient.AgentId, AssetType.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 ((remoteClient.AgentId != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions()) + if ((sp.UUID != grp.RootPart.OwnerID) && m_scene.Permissions.PropagatePermissions()) { item.BasePermissions = grp.RootPart.NextOwnerMask; item.CurrentPermissions = grp.RootPart.NextOwnerMask; @@ -907,15 +646,290 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments if (m_scene.AddInventoryItem(item)) { - remoteClient.SendInventoryItemCreateUpdate(item, 0); + sp.ControllingClient.SendInventoryItemCreateUpdate(item, 0); } else { if (m_dialogModule != null) - m_dialogModule.SendAlertToUser(remoteClient, "Operation failed"); + m_dialogModule.SendAlertToUser(sp.ControllingClient, "Operation failed"); } return item; } + + // What makes this method odd and unique is it tries to detach using an UUID.... Yay for standards. + // To LocalId or UUID, *THAT* is the question. How now Brown UUID?? + private void DetachSingleAttachmentToInvInternal(IScenePresence sp, UUID itemID) + { + // m_log.DebugFormat("[ATTACHMENTS MODULE]: Detaching item {0} to inventory for {1}", itemID, sp.Name); + + if (itemID == UUID.Zero) // If this happened, someone made a mistake.... + return; + + // We can NOT use the dictionries here, as we are looking + // for an entity by the fromAssetID, which is NOT the prim UUID + EntityBase[] detachEntities = m_scene.GetEntities(); + SceneObjectGroup group; + + lock (sp.AttachmentsSyncLock) + { + foreach (EntityBase entity in detachEntities) + { + if (entity is SceneObjectGroup) + { + group = (SceneObjectGroup)entity; + if (group.GetFromItemID() == itemID) + { + m_scene.EventManager.TriggerOnAttach(group.LocalId, itemID, UUID.Zero); + sp.RemoveAttachment(group); + + // Prepare sog for storage + group.AttachedAvatar = UUID.Zero; + group.RootPart.SetParentLocalId(0); + group.IsAttachment = false; + group.AbsolutePosition = group.RootPart.AttachedPos; + + UpdateKnownItem(sp, group); + m_scene.DeleteSceneObject(group, false); + + return; + } + } + } + } + } + + private SceneObjectGroup RezSingleAttachmentFromInventoryInternal( + IScenePresence sp, UUID itemID, UUID assetID, uint attachmentPt) + { + IInventoryAccessModule invAccess = m_scene.RequestModuleInterface(); + if (invAccess != null) + { + lock (sp.AttachmentsSyncLock) + { + 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 + { + 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; + + // 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); + + 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 null; + } + + /// + /// Update the user inventory to reflect an attachment + /// + /// + /// + /// + /// + private void ShowAttachInUserInventory(IScenePresence sp, uint AttachmentPt, UUID itemID, SceneObjectGroup att) + { + // m_log.DebugFormat( + // "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}", + // att.Name, sp.Name, AttachmentPt, itemID); + + if (UUID.Zero == itemID) + { + m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error inventory item ID."); + return; + } + + if (0 == AttachmentPt) + { + m_log.Error("[ATTACHMENTS MODULE]: Unable to save attachment. Error attachment point."); + return; + } + + InventoryItemBase item = new InventoryItemBase(itemID, sp.UUID); + item = m_scene.InventoryService.GetItem(item); + bool changed = sp.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID); + if (changed && m_scene.AvatarFactory != null) + m_scene.AvatarFactory.QueueAppearanceSave(sp.UUID); + } + + #endregion + + #region Client Event Handlers + + private ISceneEntity Client_OnRezSingleAttachmentFromInv(IClientAPI remoteClient, UUID itemID, uint AttachmentPt) + { + if (!Enabled) + return null; + + // m_log.DebugFormat( + // "[ATTACHMENTS MODULE]: Rezzing attachment to point {0} from item {1} for {2}", + // (AttachmentPoint)AttachmentPt, itemID, remoteClient.Name); + + ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); + + if (sp == null) + { + m_log.ErrorFormat( + "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezSingleAttachmentFromInventory()", + remoteClient.Name, remoteClient.AgentId); + return null; + } + + return RezSingleAttachmentFromInventory(sp, itemID, AttachmentPt); + } + + private void Client_OnRezMultipleAttachmentsFromInv(IClientAPI remoteClient, List> rezlist) + { + if (!Enabled) + return; + + ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); + if (sp != null) + RezMultipleAttachmentsFromInventory(sp, rezlist); + else + m_log.ErrorFormat( + "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1} in RezMultipleAttachmentsFromInventory()", + remoteClient.Name, remoteClient.AgentId); + } + + private void Client_OnObjectAttach(IClientAPI remoteClient, uint objectLocalID, uint AttachmentPt, bool silent) + { + // m_log.DebugFormat( + // "[ATTACHMENTS MODULE]: Attaching object local id {0} to {1} point {2} from ground (silent = {3})", + // objectLocalID, remoteClient.Name, AttachmentPt, silent); + + if (!Enabled) + return; + + try + { + ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); + + if (sp == null) + { + m_log.ErrorFormat( + "[ATTACHMENTS MODULE]: Could not find presence for client {0} {1}", remoteClient.Name, remoteClient.AgentId); + return; + } + + // If we can't take it, we can't attach it! + SceneObjectPart part = m_scene.GetSceneObjectPart(objectLocalID); + if (part == null) + return; + + if (!m_scene.Permissions.CanTakeObject(part.UUID, remoteClient.AgentId)) + { + remoteClient.SendAgentAlertMessage( + "You don't have sufficient permissions to attach this object", false); + + return; + } + + // TODO: this short circuits multiple attachments functionality in LL viewer 2.1+ and should + // be removed when that functionality is implemented in opensim + AttachmentPt &= 0x7f; + + // Calls attach with a Zero position + if (AttachObject(sp, part.ParentGroup, AttachmentPt, false)) + { + m_scene.EventManager.TriggerOnAttach(objectLocalID, part.ParentGroup.GetFromItemID(), remoteClient.AgentId); + + // Save avatar attachment information + m_log.Debug( + "[ATTACHMENTS MODULE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + + ", AttachmentPoint: " + AttachmentPt); + + } + } + catch (Exception e) + { + m_log.ErrorFormat("[ATTACHMENTS MODULE]: exception upon Attach Object {0}{1}", e.Message, e.StackTrace); + } + } + + private void Client_OnObjectDetach(uint objectLocalID, IClientAPI remoteClient) + { + if (!Enabled) + return; + + ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); + SceneObjectGroup group = m_scene.GetGroupByPrim(objectLocalID); + if (sp != null && group != null) + DetachSingleAttachmentToInv(sp, group.GetFromItemID()); + } + + private void Client_OnDetachAttachmentIntoInv(UUID itemID, IClientAPI remoteClient) + { + if (!Enabled) + return; + + ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); + if (sp != null) + DetachSingleAttachmentToInv(sp, itemID); + } + + private void Client_OnObjectDrop(uint soLocalId, IClientAPI remoteClient) + { + if (!Enabled) + return; + + ScenePresence sp = m_scene.GetScenePresence(remoteClient.AgentId); + if (sp != null) + DetachSingleAttachmentToGround(sp, soLocalId); + } + + #endregion } } diff --git a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs index 832c6eb..86cfb32 100644 --- a/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs +++ b/OpenSim/Region/CoreModules/Avatar/Attachments/Tests/AttachmentsModuleTests.cs @@ -209,7 +209,7 @@ namespace OpenSim.Region.CoreModules.Avatar.Attachments.Tests m_attMod.RezSingleAttachmentFromInventory( m_presence, attItemId, (uint)AttachmentPoint.Chest); - m_attMod.DetachSingleAttachmentToInv(attItemId, m_presence.ControllingClient); + m_attMod.DetachSingleAttachmentToInv(m_presence, attItemId); // Check status on scene presence Assert.That(m_presence.HasAttachments(), Is.False); -- cgit v1.1