aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.Inventory.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/Scene.Inventory.cs825
1 files changed, 96 insertions, 729 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
index 6c57d18..e6e414f 100644
--- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs
@@ -35,7 +35,6 @@ using OpenMetaverse;
35using OpenMetaverse.Packets; 35using OpenMetaverse.Packets;
36using log4net; 36using log4net;
37using OpenSim.Framework; 37using OpenSim.Framework;
38using OpenSim.Framework.Communications.Cache;
39using OpenSim.Region.Framework; 38using OpenSim.Region.Framework;
40using OpenSim.Region.Framework.Interfaces; 39using OpenSim.Region.Framework.Interfaces;
41using OpenSim.Region.Framework.Scenes.Serialization; 40using OpenSim.Region.Framework.Scenes.Serialization;
@@ -64,6 +63,7 @@ namespace OpenSim.Region.Framework.Scenes
64 if (group is SceneObjectGroup) 63 if (group is SceneObjectGroup)
65 { 64 {
66 ((SceneObjectGroup) group).CreateScriptInstances(0, false, DefaultScriptEngine, 0); 65 ((SceneObjectGroup) group).CreateScriptInstances(0, false, DefaultScriptEngine, 0);
66 ((SceneObjectGroup) group).ResumeScripts();
67 } 67 }
68 } 68 }
69 } 69 }
@@ -101,12 +101,6 @@ namespace OpenSim.Region.Framework.Scenes
101 { 101 {
102 userlevel = 1; 102 userlevel = 1;
103 } 103 }
104 // TODO: remove this cruft once MasterAvatar is fully deprecated
105 //
106 if (m_regInfo.MasterAvatarAssignedUUID == AgentID)
107 {
108 userlevel = 2;
109 }
110 EventManager.TriggerOnNewInventoryItemUploadComplete(AgentID, item.AssetID, item.Name, userlevel); 104 EventManager.TriggerOnNewInventoryItemUploadComplete(AgentID, item.AssetID, item.Name, userlevel);
111 } 105 }
112 else 106 else
@@ -132,70 +126,17 @@ namespace OpenSim.Region.Framework.Scenes
132 } 126 }
133 127
134 /// <summary> 128 /// <summary>
135 /// Capability originating call to update the asset of an item in an agent's inventory
136 /// </summary>
137 /// <param name="remoteClient"></param>
138 /// <param name="itemID"></param>
139 /// <param name="data"></param>
140 /// <returns></returns>
141 public virtual UUID CapsUpdateInventoryItemAsset(IClientAPI remoteClient, UUID itemID, byte[] data)
142 {
143 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
144 item = InventoryService.GetItem(item);
145
146 if (item != null)
147 {
148 if ((InventoryType)item.InvType == InventoryType.Notecard)
149 {
150 if (!Permissions.CanEditNotecard(itemID, UUID.Zero, remoteClient.AgentId))
151 {
152 remoteClient.SendAgentAlertMessage("Insufficient permissions to edit notecard", false);
153 return UUID.Zero;
154 }
155
156 remoteClient.SendAgentAlertMessage("Notecard saved", false);
157 }
158 else if ((InventoryType)item.InvType == InventoryType.LSL)
159 {
160 if (!Permissions.CanEditScript(itemID, UUID.Zero, remoteClient.AgentId))
161 {
162 remoteClient.SendAgentAlertMessage("Insufficient permissions to edit script", false);
163 return UUID.Zero;
164 }
165
166 remoteClient.SendAgentAlertMessage("Script saved", false);
167 }
168
169 AssetBase asset =
170 CreateAsset(item.Name, item.Description, (sbyte)item.AssetType, data);
171 item.AssetID = asset.FullID;
172 AssetService.Store(asset);
173
174 InventoryService.UpdateItem(item);
175
176 // remoteClient.SendInventoryItemCreateUpdate(item);
177 return (asset.FullID);
178 }
179 else
180 {
181 m_log.ErrorFormat(
182 "[AGENT INVENTORY]: Could not find item {0} for caps inventory update",
183 itemID);
184 }
185
186 return UUID.Zero;
187 }
188
189 /// <summary>
190 /// <see>CapsUpdatedInventoryItemAsset(IClientAPI, UUID, byte[])</see> 129 /// <see>CapsUpdatedInventoryItemAsset(IClientAPI, UUID, byte[])</see>
191 /// </summary> 130 /// </summary>
192 public UUID CapsUpdateInventoryItemAsset(UUID avatarId, UUID itemID, byte[] data) 131 public UUID CapsUpdateInventoryItemAsset(UUID avatarId, UUID itemID, byte[] data)
193 { 132 {
194 ScenePresence avatar; 133 ScenePresence avatar;
195 134
196 if (TryGetAvatar(avatarId, out avatar)) 135 if (TryGetScenePresence(avatarId, out avatar))
197 { 136 {
198 return CapsUpdateInventoryItemAsset(avatar.ControllingClient, itemID, data); 137 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
138 if (invAccess != null)
139 return invAccess.CapsUpdateInventoryItemAsset(avatar.ControllingClient, itemID, data);
199 } 140 }
200 else 141 else
201 { 142 {
@@ -251,7 +192,7 @@ namespace OpenSim.Region.Framework.Scenes
251 return new ArrayList(); 192 return new ArrayList();
252 } 193 }
253 194
254 AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data); 195 AssetBase asset = CreateAsset(item.Name, item.Description, (sbyte)AssetType.LSLText, data, remoteClient.AgentId);
255 AssetService.Store(asset); 196 AssetService.Store(asset);
256 197
257 if (isScriptRunning) 198 if (isScriptRunning)
@@ -261,7 +202,9 @@ namespace OpenSim.Region.Framework.Scenes
261 202
262 // Update item with new asset 203 // Update item with new asset
263 item.AssetID = asset.FullID; 204 item.AssetID = asset.FullID;
264 group.UpdateInventoryItem(item); 205 if (group.UpdateInventoryItem(item))
206 remoteClient.SendAgentAlertMessage("Notecard saved", false);
207
265 part.GetProperties(remoteClient); 208 part.GetProperties(remoteClient);
266 209
267 // Trigger rerunning of script (use TriggerRezScript event, see RezScript) 210 // Trigger rerunning of script (use TriggerRezScript event, see RezScript)
@@ -277,6 +220,7 @@ namespace OpenSim.Region.Framework.Scenes
277 { 220 {
278 remoteClient.SendAgentAlertMessage("Script saved", false); 221 remoteClient.SendAgentAlertMessage("Script saved", false);
279 } 222 }
223 part.ParentGroup.ResumeScripts();
280 return errors; 224 return errors;
281 } 225 }
282 226
@@ -288,7 +232,7 @@ namespace OpenSim.Region.Framework.Scenes
288 { 232 {
289 ScenePresence avatar; 233 ScenePresence avatar;
290 234
291 if (TryGetAvatar(avatarId, out avatar)) 235 if (TryGetScenePresence(avatarId, out avatar))
292 { 236 {
293 return CapsUpdateTaskInventoryScriptAsset( 237 return CapsUpdateTaskInventoryScriptAsset(
294 avatar.ControllingClient, itemId, primId, isScriptRunning, data); 238 avatar.ControllingClient, itemId, primId, isScriptRunning, data);
@@ -477,7 +421,11 @@ namespace OpenSim.Region.Framework.Scenes
477 itemCopy.SaleType = item.SaleType; 421 itemCopy.SaleType = item.SaleType;
478 422
479 if (InventoryService.AddItem(itemCopy)) 423 if (InventoryService.AddItem(itemCopy))
480 TransferInventoryAssets(itemCopy, senderId, recipient); 424 {
425 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
426 if (invAccess != null)
427 invAccess.TransferInventoryAssets(itemCopy, senderId, recipient);
428 }
481 429
482 if (!Permissions.BypassPermissions()) 430 if (!Permissions.BypassPermissions())
483 { 431 {
@@ -499,10 +447,6 @@ namespace OpenSim.Region.Framework.Scenes
499 447
500 } 448 }
501 449
502 protected virtual void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver)
503 {
504 }
505
506 /// <summary> 450 /// <summary>
507 /// Give an entire inventory folder from one user to another. The entire contents (including all descendent 451 /// Give an entire inventory folder from one user to another. The entire contents (including all descendent
508 /// folders) is given. 452 /// folders) is given.
@@ -530,7 +474,6 @@ namespace OpenSim.Region.Framework.Scenes
530 return null; 474 return null;
531 } 475 }
532 476
533
534 if (recipientParentFolderId == UUID.Zero) 477 if (recipientParentFolderId == UUID.Zero)
535 { 478 {
536 InventoryFolderBase recipientRootFolder = InventoryService.GetRootFolder(recipientId); 479 InventoryFolderBase recipientRootFolder = InventoryService.GetRootFolder(recipientId);
@@ -572,7 +515,9 @@ namespace OpenSim.Region.Framework.Scenes
572 "[AGENT INVENTORY]: CopyInventoryItem received by {0} with oldAgentID {1}, oldItemID {2}, new FolderID {3}, newName {4}", 515 "[AGENT INVENTORY]: CopyInventoryItem received by {0} with oldAgentID {1}, oldItemID {2}, new FolderID {3}, newName {4}",
573 remoteClient.AgentId, oldAgentID, oldItemID, newFolderID, newName); 516 remoteClient.AgentId, oldAgentID, oldItemID, newFolderID, newName);
574 517
575 InventoryItemBase item = CommsManager.UserProfileCacheService.LibraryRoot.FindItem(oldItemID); 518 InventoryItemBase item = null;
519 if (LibraryService != null && LibraryService.LibraryRootFolder != null)
520 item = LibraryService.LibraryRootFolder.FindItem(oldItemID);
576 521
577 if (item == null) 522 if (item == null)
578 { 523 {
@@ -626,15 +571,9 @@ namespace OpenSim.Region.Framework.Scenes
626 /// <summary> 571 /// <summary>
627 /// Create a new asset data structure. 572 /// Create a new asset data structure.
628 /// </summary> 573 /// </summary>
629 /// <param name="name"></param> 574 private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data, UUID creatorID)
630 /// <param name="description"></param>
631 /// <param name="invType"></param>
632 /// <param name="assetType"></param>
633 /// <param name="data"></param>
634 /// <returns></returns>
635 private AssetBase CreateAsset(string name, string description, sbyte assetType, byte[] data)
636 { 575 {
637 AssetBase asset = new AssetBase(UUID.Random(), name, assetType); 576 AssetBase asset = new AssetBase(UUID.Random(), name, assetType, creatorID.ToString());
638 asset.Description = description; 577 asset.Description = description;
639 asset.Data = (data == null) ? new byte[1] : data; 578 asset.Data = (data == null) ? new byte[1] : data;
640 579
@@ -744,13 +683,9 @@ namespace OpenSim.Region.Framework.Scenes
744 683
745 if (transactionID == UUID.Zero) 684 if (transactionID == UUID.Zero)
746 { 685 {
747 CachedUserInfo userInfo 686 ScenePresence presence;
748 = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); 687 if (TryGetScenePresence(remoteClient.AgentId, out presence))
749
750 if (userInfo != null)
751 { 688 {
752 ScenePresence presence;
753 TryGetAvatar(remoteClient.AgentId, out presence);
754 byte[] data = null; 689 byte[] data = null;
755 690
756 if (invType == (sbyte)InventoryType.Landmark && presence != null) 691 if (invType == (sbyte)InventoryType.Landmark && presence != null)
@@ -764,7 +699,7 @@ namespace OpenSim.Region.Framework.Scenes
764 data = Encoding.ASCII.GetBytes(strdata); 699 data = Encoding.ASCII.GetBytes(strdata);
765 } 700 }
766 701
767 AssetBase asset = CreateAsset(name, description, assetType, data); 702 AssetBase asset = CreateAsset(name, description, assetType, data, remoteClient.AgentId);
768 AssetService.Store(asset); 703 AssetService.Store(asset);
769 704
770 CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate); 705 CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), folderID, asset.Name, 0, callbackID, asset, invType, nextOwnerMask, creationDate);
@@ -772,7 +707,7 @@ namespace OpenSim.Region.Framework.Scenes
772 else 707 else
773 { 708 {
774 m_log.ErrorFormat( 709 m_log.ErrorFormat(
775 "userInfo for agent uuid {0} unexpectedly null in CreateNewInventoryItem", 710 "ScenePresence for agent uuid {0} unexpectedly not found in CreateNewInventoryItem",
776 remoteClient.AgentId); 711 remoteClient.AgentId);
777 } 712 }
778 } 713 }
@@ -788,6 +723,37 @@ namespace OpenSim.Region.Framework.Scenes
788 } 723 }
789 } 724 }
790 725
726 private void HandleLinkInventoryItem(IClientAPI remoteClient, UUID transActionID, UUID folderID,
727 uint callbackID, string description, string name,
728 sbyte invType, sbyte type, UUID olditemID)
729 {
730 m_log.DebugFormat("[AGENT INVENTORY]: Received request to create inventory item link {0} in folder {1} pointing to {2}", name, folderID, olditemID);
731
732 if (!Permissions.CanCreateUserInventory(invType, remoteClient.AgentId))
733 return;
734
735 ScenePresence presence;
736 if (TryGetScenePresence(remoteClient.AgentId, out presence))
737 {
738 byte[] data = null;
739
740 AssetBase asset = new AssetBase();
741 asset.FullID = olditemID;
742 asset.Type = type;
743 asset.Name = name;
744 asset.Description = description;
745
746 CreateNewInventoryItem(remoteClient, remoteClient.AgentId.ToString(), folderID, name, 0, callbackID, asset, invType, (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, (uint)PermissionMask.All, Util.UnixTimeSinceEpoch());
747
748 }
749 else
750 {
751 m_log.ErrorFormat(
752 "ScenePresence for agent uuid {0} unexpectedly not found in HandleLinkInventoryItem",
753 remoteClient.AgentId);
754 }
755 }
756
791 /// <summary> 757 /// <summary>
792 /// Remove an inventory item for the client's inventory 758 /// Remove an inventory item for the client's inventory
793 /// </summary> 759 /// </summary>
@@ -1011,7 +977,7 @@ namespace OpenSim.Region.Framework.Scenes
1011 { 977 {
1012 ScenePresence avatar; 978 ScenePresence avatar;
1013 979
1014 if (TryGetAvatar(avatarId, out avatar)) 980 if (TryGetScenePresence(avatarId, out avatar))
1015 { 981 {
1016 return MoveTaskInventoryItem(avatar.ControllingClient, folderId, part, itemId); 982 return MoveTaskInventoryItem(avatar.ControllingClient, folderId, part, itemId);
1017 } 983 }
@@ -1125,7 +1091,7 @@ namespace OpenSim.Region.Framework.Scenes
1125 1091
1126 ScenePresence avatar; 1092 ScenePresence avatar;
1127 1093
1128 if (TryGetAvatar(srcTaskItem.OwnerID, out avatar)) 1094 if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar))
1129 { 1095 {
1130 destPart.GetProperties(avatar.ControllingClient); 1096 destPart.GetProperties(avatar.ControllingClient);
1131 } 1097 }
@@ -1153,7 +1119,7 @@ namespace OpenSim.Region.Framework.Scenes
1153 } 1119 }
1154 1120
1155 ScenePresence avatar = null; 1121 ScenePresence avatar = null;
1156 if (TryGetAvatar(destID, out avatar)) 1122 if (TryGetScenePresence(destID, out avatar))
1157 { 1123 {
1158 //profile.SendInventoryDecendents(avatar.ControllingClient, 1124 //profile.SendInventoryDecendents(avatar.ControllingClient,
1159 // profile.RootFolder.ID, true, false); 1125 // profile.RootFolder.ID, true, false);
@@ -1169,15 +1135,21 @@ namespace OpenSim.Region.Framework.Scenes
1169 1135
1170 private void SendInventoryUpdate(IClientAPI client, InventoryFolderBase folder, bool fetchFolders, bool fetchItems) 1136 private void SendInventoryUpdate(IClientAPI client, InventoryFolderBase folder, bool fetchFolders, bool fetchItems)
1171 { 1137 {
1172 m_log.DebugFormat("[AGENT INVENTORY]: Send Inventory Folder {0} Update to {1} {2}", folder.Name, client.FirstName, client.LastName); 1138 if (folder == null)
1139 return;
1140
1141 // Fetch the folder contents
1173 InventoryCollection contents = InventoryService.GetFolderContent(client.AgentId, folder.ID); 1142 InventoryCollection contents = InventoryService.GetFolderContent(client.AgentId, folder.ID);
1174 InventoryFolderBase containingFolder = new InventoryFolderBase(); 1143
1175 containingFolder.ID = folder.ID; 1144 // Fetch the folder itself to get its current version
1176 containingFolder.Owner = client.AgentId; 1145 InventoryFolderBase containingFolder = new InventoryFolderBase(folder.ID, client.AgentId);
1177 containingFolder = InventoryService.GetFolder(containingFolder); 1146 containingFolder = InventoryService.GetFolder(containingFolder);
1178 int version = containingFolder.Version;
1179 1147
1180 client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, version, fetchFolders, fetchItems); 1148 //m_log.DebugFormat("[AGENT INVENTORY]: Sending inventory folder contents ({0} nodes) for \"{1}\" to {2} {3}",
1149 // contents.Folders.Count + contents.Items.Count, containingFolder.Name, client.FirstName, client.LastName);
1150
1151 if (containingFolder != null)
1152 client.SendInventoryFolderDetails(client.AgentId, folder.ID, contents.Items, contents.Folders, containingFolder.Version, fetchFolders, fetchItems);
1181 } 1153 }
1182 1154
1183 /// <summary> 1155 /// <summary>
@@ -1219,11 +1191,12 @@ namespace OpenSim.Region.Framework.Scenes
1219 item = InventoryService.GetItem(item); 1191 item = InventoryService.GetItem(item);
1220 1192
1221 // Try library 1193 // Try library
1222 if (null == item) 1194 if (null == item && LibraryService != null && LibraryService.LibraryRootFolder != null)
1223 { 1195 {
1224 item = CommsManager.UserProfileCacheService.LibraryRoot.FindItem(itemID); 1196 item = LibraryService.LibraryRootFolder.FindItem(itemID);
1225 } 1197 }
1226 1198
1199 // If we've found the item in the user's inventory or in the library
1227 if (item != null) 1200 if (item != null)
1228 { 1201 {
1229 part.ParentGroup.AddInventoryItem(remoteClient, primLocalID, item, copyID); 1202 part.ParentGroup.AddInventoryItem(remoteClient, primLocalID, item, copyID);
@@ -1258,7 +1231,10 @@ namespace OpenSim.Region.Framework.Scenes
1258 remoteClient, part, transactionID, currentItem); 1231 remoteClient, part, transactionID, currentItem);
1259 } 1232 }
1260 if (part.Inventory.UpdateInventoryItem(itemInfo)) 1233 if (part.Inventory.UpdateInventoryItem(itemInfo))
1234 {
1235 remoteClient.SendAgentAlertMessage("Notecard saved", false);
1261 part.GetProperties(remoteClient); 1236 part.GetProperties(remoteClient);
1237 }
1262 } 1238 }
1263 } 1239 }
1264 else 1240 else
@@ -1288,9 +1264,9 @@ namespace OpenSim.Region.Framework.Scenes
1288 1264
1289 // Try library 1265 // Try library
1290 // XXX clumsy, possibly should be one call 1266 // XXX clumsy, possibly should be one call
1291 if (null == item) 1267 if (null == item && LibraryService != null && LibraryService.LibraryRootFolder != null)
1292 { 1268 {
1293 item = CommsManager.UserProfileCacheService.LibraryRoot.FindItem(itemID); 1269 item = LibraryService.LibraryRootFolder.FindItem(itemID);
1294 } 1270 }
1295 1271
1296 if (item != null) 1272 if (item != null)
@@ -1310,6 +1286,7 @@ namespace OpenSim.Region.Framework.Scenes
1310 // "Rezzed script {0} into prim local ID {1} for user {2}", 1286 // "Rezzed script {0} into prim local ID {1} for user {2}",
1311 // item.inventoryName, localID, remoteClient.Name); 1287 // item.inventoryName, localID, remoteClient.Name);
1312 part.GetProperties(remoteClient); 1288 part.GetProperties(remoteClient);
1289 part.ParentGroup.ResumeScripts();
1313 } 1290 }
1314 else 1291 else
1315 { 1292 {
@@ -1347,7 +1324,9 @@ namespace OpenSim.Region.Framework.Scenes
1347 itemBase.InvType, part.UUID, remoteClient.AgentId)) 1324 itemBase.InvType, part.UUID, remoteClient.AgentId))
1348 return; 1325 return;
1349 1326
1350 AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType, Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}")); 1327 AssetBase asset = CreateAsset(itemBase.Name, itemBase.Description, (sbyte)itemBase.AssetType,
1328 Encoding.ASCII.GetBytes("default\n{\n state_entry()\n {\n llSay(0, \"Script running\");\n }\n}"),
1329 remoteClient.AgentId);
1351 AssetService.Store(asset); 1330 AssetService.Store(asset);
1352 1331
1353 TaskInventoryItem taskItem = new TaskInventoryItem(); 1332 TaskInventoryItem taskItem = new TaskInventoryItem();
@@ -1377,6 +1356,7 @@ namespace OpenSim.Region.Framework.Scenes
1377 part.GetProperties(remoteClient); 1356 part.GetProperties(remoteClient);
1378 1357
1379 part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0); 1358 part.Inventory.CreateScriptInstance(taskItem, 0, false, DefaultScriptEngine, 0);
1359 part.ParentGroup.ResumeScripts();
1380 } 1360 }
1381 } 1361 }
1382 1362
@@ -1480,9 +1460,11 @@ namespace OpenSim.Region.Framework.Scenes
1480 destPart.Inventory.CreateScriptInstance(destTaskItem, start_param, false, DefaultScriptEngine, 0); 1460 destPart.Inventory.CreateScriptInstance(destTaskItem, start_param, false, DefaultScriptEngine, 0);
1481 } 1461 }
1482 1462
1463 destPart.ParentGroup.ResumeScripts();
1464
1483 ScenePresence avatar; 1465 ScenePresence avatar;
1484 1466
1485 if (TryGetAvatar(srcTaskItem.OwnerID, out avatar)) 1467 if (TryGetScenePresence(srcTaskItem.OwnerID, out avatar))
1486 { 1468 {
1487 destPart.GetProperties(avatar.ControllingClient); 1469 destPart.GetProperties(avatar.ControllingClient);
1488 } 1470 }
@@ -1616,237 +1598,6 @@ namespace OpenSim.Region.Framework.Scenes
1616 } 1598 }
1617 } 1599 }
1618 1600
1619 /// <summary>
1620 /// Delete a scene object from a scene and place in the given avatar's inventory.
1621 /// Returns the UUID of the newly created asset.
1622 /// </summary>
1623 /// <param name="action"></param>
1624 /// <param name="folderID"></param>
1625 /// <param name="objectGroup"></param>
1626 /// <param name="remoteClient"> </param>
1627 public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID,
1628 SceneObjectGroup objectGroup, IClientAPI remoteClient)
1629 {
1630 UUID assetID = UUID.Zero;
1631
1632 Vector3 inventoryStoredPosition = new Vector3
1633 (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
1634 ? 250
1635 : objectGroup.AbsolutePosition.X)
1636 ,
1637 (objectGroup.AbsolutePosition.X > (int)Constants.RegionSize)
1638 ? 250
1639 : objectGroup.AbsolutePosition.X,
1640 objectGroup.AbsolutePosition.Z);
1641
1642 Vector3 originalPosition = objectGroup.AbsolutePosition;
1643
1644 objectGroup.AbsolutePosition = inventoryStoredPosition;
1645
1646 string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup);
1647
1648 objectGroup.AbsolutePosition = originalPosition;
1649
1650 // Get the user info of the item destination
1651 //
1652 UUID userID = UUID.Zero;
1653
1654 if (action == DeRezAction.Take || action == DeRezAction.TakeCopy ||
1655 action == DeRezAction.SaveToExistingUserInventoryItem)
1656 {
1657 // Take or take copy require a taker
1658 // Saving changes requires a local user
1659 //
1660 if (remoteClient == null)
1661 return UUID.Zero;
1662
1663 userID = remoteClient.AgentId;
1664 }
1665 else
1666 {
1667 // All returns / deletes go to the object owner
1668 //
1669
1670 userID = objectGroup.RootPart.OwnerID;
1671 }
1672
1673 if (userID == UUID.Zero) // Can't proceed
1674 {
1675 return UUID.Zero;
1676 }
1677
1678 // If we're returning someone's item, it goes back to the
1679 // owner's Lost And Found folder.
1680 // Delete is treated like return in this case
1681 // Deleting your own items makes them go to trash
1682 //
1683
1684 InventoryFolderBase folder = null;
1685 InventoryItemBase item = null;
1686
1687 if (DeRezAction.SaveToExistingUserInventoryItem == action)
1688 {
1689 item = new InventoryItemBase(objectGroup.RootPart.FromUserInventoryItemID, userID);
1690 item = InventoryService.GetItem(item);
1691
1692 //item = userInfo.RootFolder.FindItem(
1693 // objectGroup.RootPart.FromUserInventoryItemID);
1694
1695 if (null == item)
1696 {
1697 m_log.DebugFormat(
1698 "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.",
1699 objectGroup.Name, objectGroup.UUID);
1700 return UUID.Zero;
1701 }
1702 }
1703 else
1704 {
1705 // Folder magic
1706 //
1707 if (action == DeRezAction.Delete)
1708 {
1709 // Deleting someone else's item
1710 //
1711
1712
1713 if (remoteClient == null ||
1714 objectGroup.OwnerID != remoteClient.AgentId)
1715 {
1716 // Folder skeleton may not be loaded and we
1717 // have to wait for the inventory to find
1718 // the destination folder
1719 //
1720 folder = InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
1721 }
1722 else
1723 {
1724 // Assume inventory skeleton was loaded during login
1725 // and all folders can be found
1726 //
1727 folder = InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
1728 }
1729 }
1730 else if (action == DeRezAction.Return)
1731 {
1732
1733 // Dump to lost + found unconditionally
1734 //
1735 folder = InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
1736 }
1737
1738 if (folderID == UUID.Zero && folder == null)
1739 {
1740 if (action == DeRezAction.Delete)
1741 {
1742 // Deletes go to trash by default
1743 //
1744 folder = InventoryService.GetFolderForType(userID, AssetType.TrashFolder);
1745 }
1746 else
1747 {
1748 // Catch all. Use lost & found
1749 //
1750
1751 folder = InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder);
1752 }
1753 }
1754
1755 if (folder == null) // None of the above
1756 {
1757 //folder = userInfo.RootFolder.FindFolder(folderID);
1758 folder = new InventoryFolderBase(folderID);
1759
1760 if (folder == null) // Nowhere to put it
1761 {
1762 return UUID.Zero;
1763 }
1764 }
1765
1766 item = new InventoryItemBase();
1767 item.CreatorId = objectGroup.RootPart.CreatorID.ToString();
1768 item.ID = UUID.Random();
1769 item.InvType = (int)InventoryType.Object;
1770 item.Folder = folder.ID;
1771 item.Owner = userID;
1772 }
1773
1774 AssetBase asset = CreateAsset(
1775 objectGroup.GetPartName(objectGroup.RootPart.LocalId),
1776 objectGroup.GetPartDescription(objectGroup.RootPart.LocalId),
1777 (sbyte)AssetType.Object,
1778 Utils.StringToBytes(sceneObjectXml));
1779 AssetService.Store(asset);
1780 assetID = asset.FullID;
1781
1782 if (DeRezAction.SaveToExistingUserInventoryItem == action)
1783 {
1784 item.AssetID = asset.FullID;
1785 InventoryService.UpdateItem(item);
1786 }
1787 else
1788 {
1789 item.AssetID = asset.FullID;
1790
1791 if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && Permissions.PropagatePermissions())
1792 {
1793 uint perms=objectGroup.GetEffectivePermissions();
1794 uint nextPerms=(perms & 7) << 13;
1795 if ((nextPerms & (uint)PermissionMask.Copy) == 0)
1796 perms &= ~(uint)PermissionMask.Copy;
1797 if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
1798 perms &= ~(uint)PermissionMask.Transfer;
1799 if ((nextPerms & (uint)PermissionMask.Modify) == 0)
1800 perms &= ~(uint)PermissionMask.Modify;
1801
1802 item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask;
1803 item.CurrentPermissions = item.BasePermissions;
1804 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
1805 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask;
1806 item.GroupPermissions = objectGroup.RootPart.GroupMask & objectGroup.RootPart.NextOwnerMask;
1807 item.CurrentPermissions |= 8; // Slam!
1808 }
1809 else
1810 {
1811 uint ownerPerms = objectGroup.GetEffectivePermissions();
1812 if ((objectGroup.RootPart.OwnerMask & (uint)PermissionMask.Modify) != 0)
1813 ownerPerms |= (uint)PermissionMask.Modify;
1814
1815 item.BasePermissions = ownerPerms;
1816 item.CurrentPermissions = ownerPerms;
1817
1818 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
1819 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
1820 item.GroupPermissions = objectGroup.RootPart.GroupMask;
1821
1822 item.CurrentPermissions |= 8; // Slam!
1823 }
1824
1825 // TODO: add the new fields (Flags, Sale info, etc)
1826 item.CreationDate = Util.UnixTimeSinceEpoch();
1827 item.Description = asset.Description;
1828 item.Name = asset.Name;
1829 item.AssetType = asset.Type;
1830
1831 InventoryService.AddItem(item);
1832
1833 if (remoteClient != null && item.Owner == remoteClient.AgentId)
1834 {
1835 remoteClient.SendInventoryItemCreateUpdate(item, 0);
1836 }
1837 else
1838 {
1839 ScenePresence notifyUser = GetScenePresence(item.Owner);
1840 if (notifyUser != null)
1841 {
1842 notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0);
1843 }
1844 }
1845 }
1846
1847 return assetID;
1848 }
1849
1850 public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID) 1601 public void UpdateKnownItem(IClientAPI remoteClient, SceneObjectGroup grp, UUID itemID, UUID agentID)
1851 { 1602 {
1852 SceneObjectGroup objectGroup = grp; 1603 SceneObjectGroup objectGroup = grp;
@@ -1873,7 +1624,8 @@ namespace OpenSim.Region.Framework.Scenes
1873 objectGroup.GetPartName(objectGroup.LocalId), 1624 objectGroup.GetPartName(objectGroup.LocalId),
1874 objectGroup.GetPartDescription(objectGroup.LocalId), 1625 objectGroup.GetPartDescription(objectGroup.LocalId),
1875 (sbyte)AssetType.Object, 1626 (sbyte)AssetType.Object,
1876 Utils.StringToBytes(sceneObjectXml)); 1627 Utils.StringToBytes(sceneObjectXml),
1628 remoteClient.AgentId);
1877 AssetService.Store(asset); 1629 AssetService.Store(asset);
1878 1630
1879 item.AssetID = asset.FullID; 1631 item.AssetID = asset.FullID;
@@ -1920,7 +1672,8 @@ namespace OpenSim.Region.Framework.Scenes
1920 grp.GetPartName(grp.LocalId), 1672 grp.GetPartName(grp.LocalId),
1921 grp.GetPartDescription(grp.LocalId), 1673 grp.GetPartDescription(grp.LocalId),
1922 (sbyte)AssetType.Object, 1674 (sbyte)AssetType.Object,
1923 Utils.StringToBytes(sceneObjectXml)); 1675 Utils.StringToBytes(sceneObjectXml),
1676 remoteClient.AgentId);
1924 AssetService.Store(asset); 1677 AssetService.Store(asset);
1925 1678
1926 InventoryItemBase item = new InventoryItemBase(); 1679 InventoryItemBase item = new InventoryItemBase();
@@ -1987,225 +1740,11 @@ namespace OpenSim.Region.Framework.Scenes
1987 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, 1740 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
1988 bool RezSelected, bool RemoveItem, UUID fromTaskID) 1741 bool RezSelected, bool RemoveItem, UUID fromTaskID)
1989 { 1742 {
1990 RezObject( 1743 IInventoryAccessModule invAccess = RequestModuleInterface<IInventoryAccessModule>();
1991 remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, 1744 if (invAccess != null)
1992 RezSelected, RemoveItem, fromTaskID, false); 1745 invAccess.RezObject(
1993 } 1746 remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection,
1994 1747 RezSelected, RemoveItem, fromTaskID, false);
1995 /// <summary>
1996 /// Rez an object into the scene from the user's inventory
1997 /// </summary>
1998 /// <param name="remoteClient"></param>
1999 /// <param name="itemID"></param>
2000 /// <param name="RayEnd"></param>
2001 /// <param name="RayStart"></param>
2002 /// <param name="RayTargetID"></param>
2003 /// <param name="BypassRayCast"></param>
2004 /// <param name="RayEndIsIntersection"></param>
2005 /// <param name="RezSelected"></param>
2006 /// <param name="RemoveItem"></param>
2007 /// <param name="fromTaskID"></param>
2008 /// <param name="attachment"></param>
2009 /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful.</returns>
2010 public virtual SceneObjectGroup RezObject(IClientAPI remoteClient, UUID itemID, Vector3 RayEnd, Vector3 RayStart,
2011 UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection,
2012 bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment)
2013 {
2014 // Work out position details
2015 byte bRayEndIsIntersection = (byte)0;
2016
2017 if (RayEndIsIntersection)
2018 {
2019 bRayEndIsIntersection = (byte)1;
2020 }
2021 else
2022 {
2023 bRayEndIsIntersection = (byte)0;
2024 }
2025
2026 Vector3 scale = new Vector3(0.5f, 0.5f, 0.5f);
2027
2028
2029 Vector3 pos = GetNewRezLocation(
2030 RayStart, RayEnd, RayTargetID, Quaternion.Identity,
2031 BypassRayCast, bRayEndIsIntersection,true,scale, false);
2032
2033 // Rez object
2034 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
2035 item = InventoryService.GetItem(item);
2036
2037 if (item != null)
2038 {
2039 AssetBase rezAsset = AssetService.Get(item.AssetID.ToString());
2040
2041 if (rezAsset != null)
2042 {
2043 UUID itemId = UUID.Zero;
2044
2045 // If we have permission to copy then link the rezzed object back to the user inventory
2046 // item that it came from. This allows us to enable 'save object to inventory'
2047 if (!Permissions.BypassPermissions())
2048 {
2049 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy)
2050 {
2051 itemId = item.ID;
2052 }
2053 }
2054 else
2055 {
2056 // Brave new fullperm world
2057 //
2058 itemId = item.ID;
2059 }
2060
2061 string xmlData = Utils.BytesToString(rezAsset.Data);
2062 SceneObjectGroup group
2063 = SceneObjectSerializer.FromOriginalXmlFormat(itemId, xmlData);
2064
2065 if (!Permissions.CanRezObject(
2066 group.Children.Count, remoteClient.AgentId, pos)
2067 && !attachment)
2068 {
2069 // The client operates in no fail mode. It will
2070 // have already removed the item from the folder
2071 // if it's no copy.
2072 // Put it back if it's not an attachment
2073 //
2074 if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!attachment))
2075 remoteClient.SendBulkUpdateInventory(item);
2076 return null;
2077 }
2078
2079 group.ResetIDs();
2080
2081 if (attachment)
2082 {
2083 group.RootPart.ObjectFlags |= (uint)PrimFlags.Phantom;
2084 group.RootPart.IsAttachment = true;
2085 }
2086
2087 AddNewSceneObject(group, true);
2088
2089 // m_log.InfoFormat("ray end point for inventory rezz is {0} {1} {2} ", RayEnd.X, RayEnd.Y, RayEnd.Z);
2090 // if attachment we set it's asset id so object updates can reflect that
2091 // if not, we set it's position in world.
2092 if (!attachment)
2093 {
2094 float offsetHeight = 0;
2095 pos = GetNewRezLocation(
2096 RayStart, RayEnd, RayTargetID, Quaternion.Identity,
2097 BypassRayCast, bRayEndIsIntersection, true, group.GetAxisAlignedBoundingBox(out offsetHeight), false);
2098 pos.Z += offsetHeight;
2099 group.AbsolutePosition = pos;
2100 // m_log.InfoFormat("rezx point for inventory rezz is {0} {1} {2} and offsetheight was {3}", pos.X, pos.Y, pos.Z, offsetHeight);
2101
2102 }
2103 else
2104 {
2105 group.SetFromItemID(itemID);
2106 }
2107
2108 SceneObjectPart rootPart = null;
2109 try
2110 {
2111 rootPart = group.GetChildPart(group.UUID);
2112 }
2113 catch (NullReferenceException)
2114 {
2115 string isAttachment = "";
2116
2117 if (attachment)
2118 isAttachment = " Object was an attachment";
2119
2120 m_log.Error("[AGENT INVENTORY]: Error rezzing ItemID: " + itemID + " object has no rootpart." + isAttachment);
2121 }
2122
2123 // Since renaming the item in the inventory does not affect the name stored
2124 // in the serialization, transfer the correct name from the inventory to the
2125 // object itself before we rez.
2126 rootPart.Name = item.Name;
2127 rootPart.Description = item.Description;
2128
2129 List<SceneObjectPart> partList = new List<SceneObjectPart>(group.Children.Values);
2130
2131 group.SetGroup(remoteClient.ActiveGroupId, remoteClient);
2132 if (rootPart.OwnerID != item.Owner)
2133 {
2134 //Need to kill the for sale here
2135 rootPart.ObjectSaleType = 0;
2136 rootPart.SalePrice = 10;
2137
2138 if (Permissions.PropagatePermissions())
2139 {
2140 if ((item.CurrentPermissions & 8) != 0)
2141 {
2142 foreach (SceneObjectPart part in partList)
2143 {
2144 part.EveryoneMask = item.EveryOnePermissions;
2145 part.NextOwnerMask = item.NextPermissions;
2146 part.GroupMask = 0; // DO NOT propagate here
2147 }
2148 }
2149 group.ApplyNextOwnerPermissions();
2150 }
2151 }
2152
2153 foreach (SceneObjectPart part in partList)
2154 {
2155 if (part.OwnerID != item.Owner)
2156 {
2157 part.LastOwnerID = part.OwnerID;
2158 part.OwnerID = item.Owner;
2159 part.Inventory.ChangeInventoryOwner(item.Owner);
2160 }
2161 else if (((item.CurrentPermissions & 8) != 0) && (!attachment)) // Slam!
2162 {
2163 part.EveryoneMask = item.EveryOnePermissions;
2164 part.NextOwnerMask = item.NextPermissions;
2165
2166 part.GroupMask = 0; // DO NOT propagate here
2167 }
2168 }
2169
2170 rootPart.TrimPermissions();
2171
2172 if (!attachment)
2173 {
2174 if (group.RootPart.Shape.PCode == (byte)PCode.Prim)
2175 {
2176 group.ClearPartAttachmentData();
2177 }
2178 }
2179
2180 if (!attachment)
2181 {
2182 // Fire on_rez
2183 group.CreateScriptInstances(0, true, DefaultScriptEngine, 0);
2184
2185 rootPart.ScheduleFullUpdate();
2186 }
2187
2188 if (!Permissions.BypassPermissions())
2189 {
2190 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
2191 {
2192 // If this is done on attachments, no
2193 // copy ones will be lost, so avoid it
2194 //
2195 if (!attachment)
2196 {
2197 List<UUID> uuids = new List<UUID>();
2198 uuids.Add(item.ID);
2199 InventoryService.DeleteItems(item.Owner, uuids);
2200 }
2201 }
2202 }
2203
2204 return rootPart.ParentGroup;
2205 }
2206 }
2207
2208 return null;
2209 } 1748 }
2210 1749
2211 /// <summary> 1750 /// <summary>
@@ -2343,178 +1882,6 @@ namespace OpenSim.Region.Framework.Scenes
2343 EventManager.TriggerStopScript(part.LocalId, itemID); 1882 EventManager.TriggerStopScript(part.LocalId, itemID);
2344 } 1883 }
2345 1884
2346 internal void SendAttachEvent(uint localID, UUID itemID, UUID avatarID)
2347 {
2348 EventManager.TriggerOnAttach(localID, itemID, avatarID);
2349 }
2350
2351 /// <summary>
2352 /// Called when the client receives a request to rez a single attachment on to the avatar from inventory
2353 /// (RezSingleAttachmentFromInv packet).
2354 /// </summary>
2355 /// <param name="remoteClient"></param>
2356 /// <param name="itemID"></param>
2357 /// <param name="AttachmentPt"></param>
2358 /// <returns></returns>
2359 public UUID RezSingleAttachment(IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
2360 {
2361 m_log.DebugFormat("[USER INVENTORY]: Rezzing single attachment from item {0} for {1}", itemID, remoteClient.Name);
2362
2363 SceneObjectGroup att = m_sceneGraph.RezSingleAttachment(remoteClient, itemID, AttachmentPt);
2364
2365 if (att == null)
2366 {
2367 DetachSingleAttachmentToInv(itemID, remoteClient);
2368 return UUID.Zero;
2369 }
2370
2371 return RezSingleAttachment(att, remoteClient, itemID, AttachmentPt);
2372 }
2373
2374 /// <summary>
2375 /// Update the user inventory to reflect an attachment
2376 /// </summary>
2377 /// <param name="att"></param>
2378 /// <param name="remoteClient"></param>
2379 /// <param name="itemID"></param>
2380 /// <param name="AttachmentPt"></param>
2381 /// <returns></returns>
2382 public UUID RezSingleAttachment(SceneObjectGroup att, IClientAPI remoteClient, UUID itemID, uint AttachmentPt)
2383 {
2384 m_log.DebugFormat(
2385 "[USER INVENTORY]: Updating inventory of {0} to show attachment of {1} (item ID {2})",
2386 remoteClient.Name, att.Name, itemID);
2387
2388 if (!att.IsDeleted)
2389 AttachmentPt = att.RootPart.AttachmentPoint;
2390
2391 ScenePresence presence;
2392 if (TryGetAvatar(remoteClient.AgentId, out presence))
2393 {
2394 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
2395 item = InventoryService.GetItem(item);
2396
2397 presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/);
2398 }
2399 return att.UUID;
2400 }
2401
2402 public void RezMultipleAttachments(IClientAPI remoteClient, RezMultipleAttachmentsFromInvPacket.HeaderDataBlock header,
2403 RezMultipleAttachmentsFromInvPacket.ObjectDataBlock[] objects)
2404 {
2405 foreach (RezMultipleAttachmentsFromInvPacket.ObjectDataBlock obj in objects)
2406 {
2407 RezSingleAttachment(remoteClient, obj.ItemID, obj.AttachmentPt);
2408 }
2409 }
2410
2411 /// <summary>
2412 /// Attach an object.
2413 /// </summary>
2414 /// <param name="controllingClient"></param>
2415 /// <param name="localID"></param>
2416 /// <param name="attachPoint"></param>
2417 /// <param name="rot"></param>
2418 /// <param name="pos"></param>
2419 /// <param name="silent"></param>
2420 /// <returns>true if the object was successfully attached, false otherwise</returns>
2421 public bool AttachObject(IClientAPI controllingClient, uint localID, uint attachPoint, Quaternion rot, Vector3 pos, bool silent)
2422 {
2423 return m_sceneGraph.AttachObject(controllingClient, localID, attachPoint, rot, pos, silent);
2424 }
2425
2426 /// <summary>
2427 /// This registers the item as attached in a user's inventory
2428 /// </summary>
2429 /// <param name="remoteClient"></param>
2430 /// <param name="AttachmentPt"></param>
2431 /// <param name="itemID"></param>
2432 /// <param name="att"></param>
2433 public void AttachObject(IClientAPI remoteClient, uint AttachmentPt, UUID itemID, SceneObjectGroup att)
2434 {
2435// m_log.DebugFormat(
2436// "[USER INVENTORY]: Updating attachment {0} for {1} at {2} using item ID {3}",
2437// att.Name, remoteClient.Name, AttachmentPt, itemID);
2438
2439 if (UUID.Zero == itemID)
2440 {
2441 m_log.Error("[SCENE INVENTORY]: Unable to save attachment. Error inventory item ID.");
2442 return;
2443 }
2444
2445 if (0 == AttachmentPt)
2446 {
2447 m_log.Error("[SCENE INVENTORY]: Unable to save attachment. Error attachment point.");
2448 return;
2449 }
2450
2451 if (null == att.RootPart)
2452 {
2453 m_log.Error("[SCENE INVENTORY]: Unable to save attachment for a prim without the rootpart!");
2454 return;
2455 }
2456
2457 ScenePresence presence;
2458 if (TryGetAvatar(remoteClient.AgentId, out presence))
2459 {
2460 // XXYY!!
2461 InventoryItemBase item = new InventoryItemBase(itemID, remoteClient.AgentId);
2462 item = InventoryService.GetItem(item);
2463 presence.Appearance.SetAttachment((int)AttachmentPt, itemID, item.AssetID /*att.UUID*/);
2464
2465 if (m_AvatarFactory != null)
2466 m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
2467 }
2468 }
2469
2470 public void DetachSingleAttachmentToGround(UUID itemID, IClientAPI remoteClient)
2471 {
2472 SceneObjectPart part = GetSceneObjectPart(itemID);
2473 if (part == null || part.ParentGroup == null)
2474 return;
2475
2476 UUID inventoryID = part.ParentGroup.GetFromItemID();
2477
2478 ScenePresence presence;
2479 if (TryGetAvatar(remoteClient.AgentId, out presence))
2480 {
2481 if (!Permissions.CanRezObject(part.ParentGroup.Children.Count, remoteClient.AgentId, presence.AbsolutePosition))
2482 return;
2483
2484 presence.Appearance.DetachAttachment(itemID);
2485 IAvatarFactory ava = RequestModuleInterface<IAvatarFactory>();
2486 if (ava != null)
2487 {
2488 ava.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
2489 }
2490 part.ParentGroup.DetachToGround();
2491
2492 List<UUID> uuids = new List<UUID>();
2493 uuids.Add(inventoryID);
2494 InventoryService.DeleteItems(remoteClient.AgentId, uuids);
2495 remoteClient.SendRemoveInventoryItem(inventoryID);
2496 }
2497 SendAttachEvent(part.ParentGroup.LocalId, itemID, UUID.Zero);
2498 }
2499
2500 public void DetachSingleAttachmentToInv(UUID itemID, IClientAPI remoteClient)
2501 {
2502 ScenePresence presence;
2503 if (TryGetAvatar(remoteClient.AgentId, out presence))
2504 {
2505 presence.Appearance.DetachAttachment(itemID);
2506
2507 // Save avatar attachment information
2508 if (m_AvatarFactory != null)
2509 {
2510 m_log.Info("[SCENE]: Saving avatar attachment. AgentID: " + remoteClient.AgentId + ", ItemID: " + itemID);
2511 m_AvatarFactory.UpdateDatabase(remoteClient.AgentId, presence.Appearance);
2512 }
2513 }
2514
2515 m_sceneGraph.DetachSingleAttachmentToInv(itemID, remoteClient);
2516 }
2517
2518 public void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID) 1885 public void GetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID)
2519 { 1886 {
2520 EventManager.TriggerGetScriptRunning(controllingClient, objectID, itemID); 1887 EventManager.TriggerGetScriptRunning(controllingClient, objectID, itemID);