diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/Scene.Inventory.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | 440 |
1 files changed, 350 insertions, 90 deletions
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index b838177..edb881f 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -106,12 +106,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
106 | engine.StartProcessing(); | 106 | engine.StartProcessing(); |
107 | } | 107 | } |
108 | 108 | ||
109 | public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item) | 109 | public void AddUploadedInventoryItem(UUID agentID, InventoryItemBase item, uint cost) |
110 | { | 110 | { |
111 | IMoneyModule money = RequestModuleInterface<IMoneyModule>(); | 111 | IMoneyModule money = RequestModuleInterface<IMoneyModule>(); |
112 | if (money != null) | 112 | if (money != null) |
113 | { | 113 | { |
114 | money.ApplyUploadCharge(agentID, money.UploadCharge, "Asset upload"); | 114 | money.ApplyUploadCharge(agentID, (int)cost, "Asset upload"); |
115 | } | 115 | } |
116 | 116 | ||
117 | AddInventoryItem(item); | 117 | AddInventoryItem(item); |
@@ -182,7 +182,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
182 | return false; | 182 | return false; |
183 | } | 183 | } |
184 | } | 184 | } |
185 | 185 | ||
186 | if (InventoryService.AddItem(item)) | 186 | if (InventoryService.AddItem(item)) |
187 | { | 187 | { |
188 | int userlevel = 0; | 188 | int userlevel = 0; |
@@ -338,8 +338,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
338 | 338 | ||
339 | // Update item with new asset | 339 | // Update item with new asset |
340 | item.AssetID = asset.FullID; | 340 | item.AssetID = asset.FullID; |
341 | if (group.UpdateInventoryItem(item)) | 341 | group.UpdateInventoryItem(item); |
342 | remoteClient.SendAlertMessage("Script saved"); | ||
343 | 342 | ||
344 | part.SendPropertiesToClient(remoteClient); | 343 | part.SendPropertiesToClient(remoteClient); |
345 | 344 | ||
@@ -350,12 +349,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
350 | { | 349 | { |
351 | // Needs to determine which engine was running it and use that | 350 | // Needs to determine which engine was running it and use that |
352 | // | 351 | // |
353 | part.Inventory.CreateScriptInstance(item.ItemID, 0, false, DefaultScriptEngine, 0); | 352 | errors = part.Inventory.CreateScriptInstanceEr(item.ItemID, 0, false, DefaultScriptEngine, 1); |
354 | errors = part.Inventory.GetScriptErrors(item.ItemID); | ||
355 | } | ||
356 | else | ||
357 | { | ||
358 | remoteClient.SendAlertMessage("Script saved"); | ||
359 | } | 353 | } |
360 | 354 | ||
361 | // Tell anyone managing scripts that a script has been reloaded/changed | 355 | // Tell anyone managing scripts that a script has been reloaded/changed |
@@ -421,6 +415,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
421 | if (item.Owner != remoteClient.AgentId) | 415 | if (item.Owner != remoteClient.AgentId) |
422 | return; | 416 | return; |
423 | 417 | ||
418 | item.Flags = (item.Flags & ~(uint)255) | (itemUpd.Flags & (uint)255); | ||
424 | item.Name = itemUpd.Name; | 419 | item.Name = itemUpd.Name; |
425 | item.Description = itemUpd.Description; | 420 | item.Description = itemUpd.Description; |
426 | 421 | ||
@@ -889,6 +884,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
889 | if (newName == String.Empty) | 884 | if (newName == String.Empty) |
890 | newName = item.Name; | 885 | newName = item.Name; |
891 | 886 | ||
887 | AssetBase asset = AssetService.Get(item.AssetID.ToString()); | ||
888 | |||
889 | if (asset != null) | ||
890 | { | ||
891 | if (newName != String.Empty) | ||
892 | { | ||
893 | asset.Name = newName; | ||
894 | } | ||
895 | else | ||
896 | { | ||
897 | newName = item.Name; | ||
898 | } | ||
899 | |||
900 | |||
892 | if (remoteClient.AgentId == oldAgentID | 901 | if (remoteClient.AgentId == oldAgentID |
893 | || (LibraryService != null | 902 | || (LibraryService != null |
894 | && LibraryService.LibraryRootFolder != null | 903 | && LibraryService.LibraryRootFolder != null |
@@ -915,6 +924,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
915 | } | 924 | } |
916 | } | 925 | } |
917 | } | 926 | } |
927 | else | ||
928 | { | ||
929 | m_log.ErrorFormat( | ||
930 | "[AGENT INVENTORY]: Could not copy item {0} since asset {1} could not be found", | ||
931 | item.Name, item.AssetID); | ||
932 | } | ||
933 | } | ||
918 | 934 | ||
919 | /// <summary> | 935 | /// <summary> |
920 | /// Create a new asset data structure. | 936 | /// Create a new asset data structure. |
@@ -929,6 +945,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
929 | } | 945 | } |
930 | 946 | ||
931 | /// <summary> | 947 | /// <summary> |
948 | /// Move an item within the agent's inventory, and leave a copy (used in making a new outfit) | ||
949 | /// </summary> | ||
950 | public void MoveInventoryItemsLeaveCopy(IClientAPI remoteClient, List<InventoryItemBase> items, UUID destfolder) | ||
951 | { | ||
952 | List<InventoryItemBase> moveitems = new List<InventoryItemBase>(); | ||
953 | foreach (InventoryItemBase b in items) | ||
954 | { | ||
955 | CopyInventoryItem(remoteClient, 0, remoteClient.AgentId, b.ID, b.Folder, null); | ||
956 | InventoryItemBase n = InventoryService.GetItem(b); | ||
957 | n.Folder = destfolder; | ||
958 | moveitems.Add(n); | ||
959 | remoteClient.SendInventoryItemCreateUpdate(n, 0); | ||
960 | } | ||
961 | |||
962 | MoveInventoryItem(remoteClient, moveitems); | ||
963 | } | ||
964 | |||
965 | /// <summary> | ||
932 | /// Move an item within the agent's inventory. | 966 | /// Move an item within the agent's inventory. |
933 | /// </summary> | 967 | /// </summary> |
934 | /// <param name="remoteClient"></param> | 968 | /// <param name="remoteClient"></param> |
@@ -1015,7 +1049,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1015 | item.BasePermissions = baseMask; | 1049 | item.BasePermissions = baseMask; |
1016 | item.CreationDate = creationDate; | 1050 | item.CreationDate = creationDate; |
1017 | 1051 | ||
1018 | if (AddInventoryItem(item, assetUpload)) | 1052 | // special AnimationSet case |
1053 | if (item.InvType == (int)CustomInventoryType.AnimationSet) | ||
1054 | AnimationSet.enforceItemPermitions(item,true); | ||
1055 | |||
1056 | if (AddInventoryItem(item)) | ||
1019 | { | 1057 | { |
1020 | remoteClient.SendInventoryItemCreateUpdate(item, callbackID); | 1058 | remoteClient.SendInventoryItemCreateUpdate(item, callbackID); |
1021 | } | 1059 | } |
@@ -1327,6 +1365,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
1327 | { | 1365 | { |
1328 | SceneObjectPart part = GetSceneObjectPart(primLocalId); | 1366 | SceneObjectPart part = GetSceneObjectPart(primLocalId); |
1329 | 1367 | ||
1368 | // Can't move a null item | ||
1369 | if (itemId == UUID.Zero) | ||
1370 | return; | ||
1371 | |||
1330 | if (null == part) | 1372 | if (null == part) |
1331 | { | 1373 | { |
1332 | m_log.WarnFormat( | 1374 | m_log.WarnFormat( |
@@ -1437,21 +1479,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
1437 | return; | 1479 | return; |
1438 | } | 1480 | } |
1439 | 1481 | ||
1440 | if (part.OwnerID != destPart.OwnerID) | 1482 | // Can't transfer this |
1483 | // | ||
1484 | if (part.OwnerID != destPart.OwnerID && (srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1485 | return; | ||
1486 | |||
1487 | bool overrideNoMod = false; | ||
1488 | if ((part.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) != 0) | ||
1489 | overrideNoMod = true; | ||
1490 | |||
1491 | if (part.OwnerID != destPart.OwnerID && (destPart.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0) | ||
1441 | { | 1492 | { |
1442 | // Source must have transfer permissions | 1493 | // object cannot copy items to an object owned by a different owner |
1443 | if ((srcTaskItem.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | 1494 | // unless llAllowInventoryDrop has been called |
1444 | return; | ||
1445 | 1495 | ||
1446 | // Object cannot copy items to an object owned by a different owner | 1496 | return; |
1447 | // unless llAllowInventoryDrop has been called on the destination | ||
1448 | if ((destPart.GetEffectiveObjectFlags() & (uint)PrimFlags.AllowInventoryDrop) == 0) | ||
1449 | return; | ||
1450 | } | 1497 | } |
1451 | 1498 | ||
1452 | // must have both move and modify permission to put an item in an object | 1499 | // must have both move and modify permission to put an item in an object |
1453 | if ((part.OwnerMask & ((uint)PermissionMask.Move | (uint)PermissionMask.Modify)) == 0) | 1500 | if (((part.OwnerMask & (uint)PermissionMask.Modify) == 0) && (!overrideNoMod)) |
1501 | { | ||
1454 | return; | 1502 | return; |
1503 | } | ||
1455 | 1504 | ||
1456 | TaskInventoryItem destTaskItem = new TaskInventoryItem(); | 1505 | TaskInventoryItem destTaskItem = new TaskInventoryItem(); |
1457 | 1506 | ||
@@ -1507,10 +1556,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
1507 | 1556 | ||
1508 | public UUID MoveTaskInventoryItems(UUID destID, string category, SceneObjectPart host, List<UUID> items) | 1557 | public UUID MoveTaskInventoryItems(UUID destID, string category, SceneObjectPart host, List<UUID> items) |
1509 | { | 1558 | { |
1559 | |||
1510 | ScenePresence avatar; | 1560 | ScenePresence avatar; |
1511 | IClientAPI remoteClient = null; | 1561 | IClientAPI remoteClient = null; |
1512 | if (TryGetScenePresence(destID, out avatar)) | 1562 | if (TryGetScenePresence(destID, out avatar)) |
1513 | remoteClient = avatar.ControllingClient; | 1563 | remoteClient = avatar.ControllingClient; |
1564 | // ???? | ||
1565 | SceneObjectPart destPart = GetSceneObjectPart(destID); | ||
1566 | if (destPart != null) // Move into a prim | ||
1567 | { | ||
1568 | foreach(UUID itemID in items) | ||
1569 | MoveTaskInventoryItem(destID, host, itemID); | ||
1570 | return destID; // Prim folder ID == prim ID | ||
1571 | } | ||
1572 | // /???? | ||
1514 | 1573 | ||
1515 | InventoryFolderBase rootFolder = InventoryService.GetRootFolder(destID); | 1574 | InventoryFolderBase rootFolder = InventoryService.GetRootFolder(destID); |
1516 | 1575 | ||
@@ -1696,12 +1755,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
1696 | AgentTransactionsModule.HandleTaskItemUpdateFromTransaction( | 1755 | AgentTransactionsModule.HandleTaskItemUpdateFromTransaction( |
1697 | remoteClient, part, transactionID, currentItem); | 1756 | remoteClient, part, transactionID, currentItem); |
1698 | 1757 | ||
1699 | if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) | 1758 | // if ((InventoryType)itemInfo.InvType == InventoryType.Notecard) |
1700 | remoteClient.SendAlertMessage("Notecard saved"); | 1759 | // remoteClient.SendAgentAlertMessage("Notecard saved", false); |
1701 | else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) | 1760 | // else if ((InventoryType)itemInfo.InvType == InventoryType.LSL) |
1702 | remoteClient.SendAlertMessage("Script saved"); | 1761 | // remoteClient.SendAgentAlertMessage("Script saved", false); |
1703 | else | 1762 | // else |
1704 | remoteClient.SendAlertMessage("Item saved"); | 1763 | // remoteClient.SendAgentAlertMessage("Item saved", false); |
1705 | } | 1764 | } |
1706 | 1765 | ||
1707 | // Base ALWAYS has move | 1766 | // Base ALWAYS has move |
@@ -2075,7 +2134,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
2075 | // build a list of eligible objects | 2134 | // build a list of eligible objects |
2076 | List<uint> deleteIDs = new List<uint>(); | 2135 | List<uint> deleteIDs = new List<uint>(); |
2077 | List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>(); | 2136 | List<SceneObjectGroup> deleteGroups = new List<SceneObjectGroup>(); |
2078 | 2137 | List<SceneObjectGroup> takeGroups = new List<SceneObjectGroup>(); | |
2138 | |||
2079 | // Start with true for both, then remove the flags if objects | 2139 | // Start with true for both, then remove the flags if objects |
2080 | // that we can't derez are part of the selection | 2140 | // that we can't derez are part of the selection |
2081 | bool permissionToTake = true; | 2141 | bool permissionToTake = true; |
@@ -2084,14 +2144,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
2084 | 2144 | ||
2085 | foreach (uint localID in localIDs) | 2145 | foreach (uint localID in localIDs) |
2086 | { | 2146 | { |
2147 | |||
2148 | |||
2087 | // Invalid id | 2149 | // Invalid id |
2088 | SceneObjectPart part = GetSceneObjectPart(localID); | 2150 | SceneObjectPart part = GetSceneObjectPart(localID); |
2089 | if (part == null) | 2151 | if (part == null) |
2152 | { | ||
2153 | //Client still thinks the object exists, kill it | ||
2154 | deleteIDs.Add(localID); | ||
2090 | continue; | 2155 | continue; |
2156 | } | ||
2091 | 2157 | ||
2092 | // Already deleted by someone else | 2158 | // Already deleted by someone else |
2093 | if (part.ParentGroup.IsDeleted) | 2159 | if (part.ParentGroup.IsDeleted) |
2160 | { | ||
2161 | //Client still thinks the object exists, kill it | ||
2162 | deleteIDs.Add(localID); | ||
2094 | continue; | 2163 | continue; |
2164 | } | ||
2095 | 2165 | ||
2096 | // Can't delete child prims | 2166 | // Can't delete child prims |
2097 | if (part != part.ParentGroup.RootPart) | 2167 | if (part != part.ParentGroup.RootPart) |
@@ -2099,9 +2169,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
2099 | 2169 | ||
2100 | SceneObjectGroup grp = part.ParentGroup; | 2170 | SceneObjectGroup grp = part.ParentGroup; |
2101 | 2171 | ||
2102 | deleteIDs.Add(localID); | ||
2103 | deleteGroups.Add(grp); | ||
2104 | |||
2105 | // If child prims have invalid perms, fix them | 2172 | // If child prims have invalid perms, fix them |
2106 | grp.AdjustChildPrimPermissions(false); | 2173 | grp.AdjustChildPrimPermissions(false); |
2107 | 2174 | ||
@@ -2121,87 +2188,191 @@ namespace OpenSim.Region.Framework.Scenes | |||
2121 | } | 2188 | } |
2122 | else | 2189 | else |
2123 | { | 2190 | { |
2124 | if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId)) | 2191 | if (action == DeRezAction.TakeCopy) |
2192 | { | ||
2193 | if (!Permissions.CanTakeCopyObject(grp.UUID, remoteClient.AgentId)) | ||
2194 | permissionToTakeCopy = false; | ||
2195 | } | ||
2196 | else | ||
2197 | { | ||
2125 | permissionToTakeCopy = false; | 2198 | permissionToTakeCopy = false; |
2126 | 2199 | } | |
2127 | if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId)) | 2200 | if (!Permissions.CanTakeObject(grp.UUID, remoteClient.AgentId)) |
2128 | permissionToTake = false; | 2201 | permissionToTake = false; |
2129 | 2202 | ||
2130 | if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId)) | 2203 | if (!Permissions.CanDeleteObject(grp.UUID, remoteClient.AgentId)) |
2131 | permissionToDelete = false; | 2204 | permissionToDelete = false; |
2132 | } | 2205 | } |
2133 | } | ||
2134 | 2206 | ||
2135 | // Handle god perms | 2207 | // Handle god perms |
2136 | if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId)) | 2208 | if ((remoteClient != null) && Permissions.IsGod(remoteClient.AgentId)) |
2137 | { | ||
2138 | permissionToTake = true; | ||
2139 | permissionToTakeCopy = true; | ||
2140 | permissionToDelete = true; | ||
2141 | } | ||
2142 | |||
2143 | // If we're re-saving, we don't even want to delete | ||
2144 | if (action == DeRezAction.SaveToExistingUserInventoryItem) | ||
2145 | permissionToDelete = false; | ||
2146 | |||
2147 | // if we want to take a copy, we also don't want to delete | ||
2148 | // Note: after this point, the permissionToTakeCopy flag | ||
2149 | // becomes irrelevant. It already includes the permissionToTake | ||
2150 | // permission and after excluding no copy items here, we can | ||
2151 | // just use that. | ||
2152 | if (action == DeRezAction.TakeCopy) | ||
2153 | { | ||
2154 | // If we don't have permission, stop right here | ||
2155 | if (!permissionToTakeCopy) | ||
2156 | { | 2209 | { |
2157 | remoteClient.SendAlertMessage("You don't have permission to take the object"); | 2210 | permissionToTake = true; |
2158 | return; | 2211 | permissionToTakeCopy = true; |
2212 | permissionToDelete = true; | ||
2159 | } | 2213 | } |
2160 | 2214 | ||
2161 | permissionToTake = true; | 2215 | // If we're re-saving, we don't even want to delete |
2162 | // Don't delete | 2216 | if (action == DeRezAction.SaveToExistingUserInventoryItem) |
2163 | permissionToDelete = false; | 2217 | permissionToDelete = false; |
2164 | } | ||
2165 | 2218 | ||
2166 | if (action == DeRezAction.Return) | 2219 | // if we want to take a copy, we also don't want to delete |
2167 | { | 2220 | // Note: after this point, the permissionToTakeCopy flag |
2168 | if (remoteClient != null) | 2221 | // becomes irrelevant. It already includes the permissionToTake |
2222 | // permission and after excluding no copy items here, we can | ||
2223 | // just use that. | ||
2224 | if (action == DeRezAction.TakeCopy) | ||
2169 | { | 2225 | { |
2170 | if (Permissions.CanReturnObjects( | 2226 | // If we don't have permission, stop right here |
2171 | null, | 2227 | if (!permissionToTakeCopy) |
2172 | remoteClient.AgentId, | ||
2173 | deleteGroups)) | ||
2174 | { | 2228 | { |
2175 | permissionToTake = true; | 2229 | remoteClient.SendAlertMessage("You don't have permission to take the object"); |
2176 | permissionToDelete = true; | 2230 | return; |
2231 | } | ||
2177 | 2232 | ||
2178 | foreach (SceneObjectGroup g in deleteGroups) | 2233 | permissionToTake = true; |
2234 | // Don't delete | ||
2235 | permissionToDelete = false; | ||
2236 | } | ||
2237 | |||
2238 | if (action == DeRezAction.Return) | ||
2239 | { | ||
2240 | if (remoteClient != null) | ||
2241 | { | ||
2242 | if (Permissions.CanReturnObjects( | ||
2243 | null, | ||
2244 | remoteClient.AgentId, | ||
2245 | new List<SceneObjectGroup>() {grp})) | ||
2179 | { | 2246 | { |
2180 | AddReturn(g.OwnerID == g.GroupID ? g.LastOwnerID : g.OwnerID, g.Name, g.AbsolutePosition, "parcel owner return"); | 2247 | permissionToTake = true; |
2248 | permissionToDelete = true; | ||
2249 | |||
2250 | AddReturn(grp.OwnerID == grp.GroupID ? grp.LastOwnerID : grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return"); | ||
2181 | } | 2251 | } |
2182 | } | 2252 | } |
2253 | else // Auto return passes through here with null agent | ||
2254 | { | ||
2255 | permissionToTake = true; | ||
2256 | permissionToDelete = true; | ||
2257 | } | ||
2183 | } | 2258 | } |
2184 | else // Auto return passes through here with null agent | 2259 | |
2260 | if (permissionToTake && (!permissionToDelete)) | ||
2261 | takeGroups.Add(grp); | ||
2262 | |||
2263 | if (permissionToDelete) | ||
2185 | { | 2264 | { |
2186 | permissionToTake = true; | 2265 | if (permissionToTake) |
2187 | permissionToDelete = true; | 2266 | deleteGroups.Add(grp); |
2267 | deleteIDs.Add(grp.LocalId); | ||
2188 | } | 2268 | } |
2189 | } | 2269 | } |
2190 | 2270 | ||
2191 | // OK, we're done with permissions. Let's check if any part of the code prevents the objects from being deleted | 2271 | SendKillObject(deleteIDs); |
2192 | bool canDelete = EventManager.TriggerDeRezRequested(remoteClient, deleteGroups, action); | ||
2193 | 2272 | ||
2194 | if (permissionToTake && (action != DeRezAction.Delete || this.m_useTrashOnDelete)) | 2273 | if (deleteGroups.Count > 0) |
2195 | { | 2274 | { |
2275 | foreach (SceneObjectGroup g in deleteGroups) | ||
2276 | deleteIDs.Remove(g.LocalId); | ||
2277 | |||
2196 | m_asyncSceneObjectDeleter.DeleteToInventory( | 2278 | m_asyncSceneObjectDeleter.DeleteToInventory( |
2197 | action, destinationID, deleteGroups, remoteClient, | 2279 | action, destinationID, deleteGroups, remoteClient, |
2198 | permissionToDelete && canDelete); | 2280 | true); |
2199 | } | 2281 | } |
2200 | else if (permissionToDelete && canDelete) | 2282 | if (takeGroups.Count > 0) |
2283 | { | ||
2284 | m_asyncSceneObjectDeleter.DeleteToInventory( | ||
2285 | action, destinationID, takeGroups, remoteClient, | ||
2286 | false); | ||
2287 | } | ||
2288 | if (deleteIDs.Count > 0) | ||
2201 | { | 2289 | { |
2202 | foreach (SceneObjectGroup g in deleteGroups) | 2290 | foreach (SceneObjectGroup g in deleteGroups) |
2203 | DeleteSceneObject(g, false); | 2291 | DeleteSceneObject(g, true); |
2292 | } | ||
2293 | } | ||
2294 | |||
2295 | public UUID attachObjectAssetStore(IClientAPI remoteClient, SceneObjectGroup grp, UUID AgentId, out UUID itemID) | ||
2296 | { | ||
2297 | itemID = UUID.Zero; | ||
2298 | if (grp != null) | ||
2299 | { | ||
2300 | Vector3 inventoryStoredPosition = new Vector3( | ||
2301 | Math.Min(grp.AbsolutePosition.X, RegionInfo.RegionSizeX - 6), | ||
2302 | Math.Min(grp.AbsolutePosition.Y, RegionInfo.RegionSizeY - 6), | ||
2303 | grp.AbsolutePosition.Z); | ||
2304 | |||
2305 | Vector3 originalPosition = grp.AbsolutePosition; | ||
2306 | |||
2307 | grp.AbsolutePosition = inventoryStoredPosition; | ||
2308 | |||
2309 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(grp); | ||
2310 | |||
2311 | grp.AbsolutePosition = originalPosition; | ||
2312 | |||
2313 | AssetBase asset = CreateAsset( | ||
2314 | grp.GetPartName(grp.LocalId), | ||
2315 | grp.GetPartDescription(grp.LocalId), | ||
2316 | (sbyte)AssetType.Object, | ||
2317 | Utils.StringToBytes(sceneObjectXml), | ||
2318 | remoteClient.AgentId); | ||
2319 | AssetService.Store(asset); | ||
2320 | |||
2321 | InventoryItemBase item = new InventoryItemBase(); | ||
2322 | item.CreatorId = grp.RootPart.CreatorID.ToString(); | ||
2323 | item.CreatorData = grp.RootPart.CreatorData; | ||
2324 | item.Owner = remoteClient.AgentId; | ||
2325 | item.ID = UUID.Random(); | ||
2326 | item.AssetID = asset.FullID; | ||
2327 | item.Description = asset.Description; | ||
2328 | item.Name = asset.Name; | ||
2329 | item.AssetType = asset.Type; | ||
2330 | item.InvType = (int)InventoryType.Object; | ||
2331 | |||
2332 | InventoryFolderBase folder = InventoryService.GetFolderForType(remoteClient.AgentId, FolderType.Object); | ||
2333 | if (folder != null) | ||
2334 | item.Folder = folder.ID; | ||
2335 | else // oopsies | ||
2336 | item.Folder = UUID.Zero; | ||
2337 | |||
2338 | // Set up base perms properly | ||
2339 | uint permsBase = (uint)(PermissionMask.Move | PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify); | ||
2340 | permsBase &= grp.RootPart.BaseMask; | ||
2341 | permsBase |= (uint)PermissionMask.Move; | ||
2342 | |||
2343 | // Make sure we don't lock it | ||
2344 | grp.RootPart.NextOwnerMask |= (uint)PermissionMask.Move; | ||
2345 | |||
2346 | if ((remoteClient.AgentId != grp.RootPart.OwnerID) && Permissions.PropagatePermissions()) | ||
2347 | { | ||
2348 | item.BasePermissions = permsBase & grp.RootPart.NextOwnerMask; | ||
2349 | item.CurrentPermissions = permsBase & grp.RootPart.NextOwnerMask; | ||
2350 | item.NextPermissions = permsBase & grp.RootPart.NextOwnerMask; | ||
2351 | item.EveryOnePermissions = permsBase & grp.RootPart.EveryoneMask & grp.RootPart.NextOwnerMask; | ||
2352 | item.GroupPermissions = permsBase & grp.RootPart.GroupMask & grp.RootPart.NextOwnerMask; | ||
2353 | } | ||
2354 | else | ||
2355 | { | ||
2356 | item.BasePermissions = permsBase; | ||
2357 | item.CurrentPermissions = permsBase & grp.RootPart.OwnerMask; | ||
2358 | item.NextPermissions = permsBase & grp.RootPart.NextOwnerMask; | ||
2359 | item.EveryOnePermissions = permsBase & grp.RootPart.EveryoneMask; | ||
2360 | item.GroupPermissions = permsBase & grp.RootPart.GroupMask; | ||
2361 | } | ||
2362 | item.CreationDate = Util.UnixTimeSinceEpoch(); | ||
2363 | |||
2364 | // sets itemID so client can show item as 'attached' in inventory | ||
2365 | grp.FromItemID = item.ID; | ||
2366 | |||
2367 | if (AddInventoryItem(item)) | ||
2368 | remoteClient.SendInventoryItemCreateUpdate(item, 0); | ||
2369 | else | ||
2370 | m_dialogModule.SendAlertToUser(remoteClient, "Operation failed"); | ||
2371 | |||
2372 | itemID = item.ID; | ||
2373 | return item.AssetID; | ||
2204 | } | 2374 | } |
2375 | return UUID.Zero; | ||
2205 | } | 2376 | } |
2206 | 2377 | ||
2207 | /// <summary> | 2378 | /// <summary> |
@@ -2254,7 +2425,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2254 | Util.LogFailedXML("[AGENT INVENTORY]:", xmlData); | 2425 | Util.LogFailedXML("[AGENT INVENTORY]:", xmlData); |
2255 | g = null; | 2426 | g = null; |
2256 | } | 2427 | } |
2257 | 2428 | ||
2258 | if (g != null) | 2429 | if (g != null) |
2259 | { | 2430 | { |
2260 | objlist.Add(g); | 2431 | objlist.Add(g); |
@@ -2265,7 +2436,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2265 | return true; | 2436 | return true; |
2266 | } | 2437 | } |
2267 | else | 2438 | else |
2268 | { | 2439 | { |
2269 | XmlDocument doc = new XmlDocument(); | 2440 | XmlDocument doc = new XmlDocument(); |
2270 | doc.LoadXml(xmlData); | 2441 | doc.LoadXml(xmlData); |
2271 | XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); | 2442 | XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); |
@@ -2371,7 +2542,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2371 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, | 2542 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, |
2372 | BypassRayCast, bRayEndIsIntersection, true, scale, false); | 2543 | BypassRayCast, bRayEndIsIntersection, true, scale, false); |
2373 | 2544 | ||
2374 | RezObject(part, item, pos, null, Vector3.Zero, 0); | 2545 | RezObject(part, item, pos, null, Vector3.Zero, 0, false); |
2375 | } | 2546 | } |
2376 | } | 2547 | } |
2377 | 2548 | ||
@@ -2387,15 +2558,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
2387 | /// <param name="param"></param> | 2558 | /// <param name="param"></param> |
2388 | /// <returns>The SceneObjectGroup(s) rezzed, or null if rez was unsuccessful</returns> | 2559 | /// <returns>The SceneObjectGroup(s) rezzed, or null if rez was unsuccessful</returns> |
2389 | public virtual List<SceneObjectGroup> RezObject( | 2560 | public virtual List<SceneObjectGroup> RezObject( |
2390 | SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion? rot, Vector3 vel, int param) | 2561 | SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion? rot, Vector3 vel, int param, bool atRoot) |
2391 | { | 2562 | { |
2392 | if (null == item) | 2563 | if (null == item) |
2393 | return null; | 2564 | return null; |
2394 | 2565 | ||
2395 | List<SceneObjectGroup> objlist; | 2566 | List<SceneObjectGroup> objlist; |
2396 | List<Vector3> veclist; | 2567 | List<Vector3> veclist; |
2397 | 2568 | Vector3 bbox; | |
2398 | bool success = sourcePart.Inventory.GetRezReadySceneObjects(item, out objlist, out veclist); | 2569 | float offsetHeight; |
2570 | |||
2571 | bool success = sourcePart.Inventory.GetRezReadySceneObjects(item, out objlist, out veclist,out bbox, out offsetHeight); | ||
2572 | |||
2399 | if (!success) | 2573 | if (!success) |
2400 | return null; | 2574 | return null; |
2401 | 2575 | ||
@@ -2412,10 +2586,69 @@ namespace OpenSim.Region.Framework.Scenes | |||
2412 | sourcePart.Inventory.RemoveInventoryItem(item.ItemID); | 2586 | sourcePart.Inventory.RemoveInventoryItem(item.ItemID); |
2413 | } | 2587 | } |
2414 | 2588 | ||
2589 | SceneObjectGroup sog; | ||
2590 | |||
2591 | bool fixrot = false; | ||
2592 | Quaternion netRot = Quaternion.Identity; | ||
2593 | |||
2594 | // position adjust | ||
2595 | if (totalPrims > 1) // nothing to do on a single prim | ||
2596 | { | ||
2597 | if (objlist.Count == 1) | ||
2598 | { | ||
2599 | // current object position is root position | ||
2600 | if(!atRoot) | ||
2601 | { | ||
2602 | sog = objlist[0]; | ||
2603 | Quaternion orot; | ||
2604 | if (rot == null) | ||
2605 | orot = sog.RootPart.GetWorldRotation(); | ||
2606 | else | ||
2607 | orot = rot.Value; | ||
2608 | // possible should be bbox, but geometric center looks better | ||
2609 | Vector3 off = sog.GetGeometricCenter(); | ||
2610 | // Vector3 off = bbox * 0.5f; | ||
2611 | off *= orot; | ||
2612 | pos -= off; | ||
2613 | } | ||
2614 | } | ||
2615 | else | ||
2616 | { | ||
2617 | //veclist[] are relative to bbox corner with min X,Y and Z | ||
2618 | // rez at root, and rot will be referenced to first object in list | ||
2619 | if (rot == null) | ||
2620 | { | ||
2621 | // use original rotations | ||
2622 | if (atRoot) | ||
2623 | pos -= veclist[0]; | ||
2624 | else | ||
2625 | pos -= bbox / 2; | ||
2626 | } | ||
2627 | else | ||
2628 | { | ||
2629 | fixrot = true; | ||
2630 | sog = objlist[0]; | ||
2631 | netRot = Quaternion.Conjugate(sog.RootPart.GetWorldRotation()); | ||
2632 | netRot = netRot * rot.Value; | ||
2633 | Vector3 off; | ||
2634 | if (atRoot) | ||
2635 | off = veclist[0]; | ||
2636 | else | ||
2637 | off = bbox / 2; | ||
2638 | off *= netRot; | ||
2639 | pos -= off; | ||
2640 | } | ||
2641 | } | ||
2642 | } | ||
2643 | |||
2415 | for (int i = 0; i < objlist.Count; i++) | 2644 | for (int i = 0; i < objlist.Count; i++) |
2416 | { | 2645 | { |
2417 | SceneObjectGroup group = objlist[i]; | 2646 | SceneObjectGroup group = objlist[i]; |
2418 | Vector3 curpos = pos + veclist[i]; | 2647 | Vector3 curpos; |
2648 | if(fixrot) | ||
2649 | curpos = pos + veclist[i] * netRot; | ||
2650 | else | ||
2651 | curpos = pos + veclist[i]; | ||
2419 | 2652 | ||
2420 | if (group.IsAttachment == false && group.RootPart.Shape.State != 0) | 2653 | if (group.IsAttachment == false && group.RootPart.Shape.State != 0) |
2421 | { | 2654 | { |
@@ -2424,7 +2657,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
2424 | } | 2657 | } |
2425 | 2658 | ||
2426 | group.FromPartID = sourcePart.UUID; | 2659 | group.FromPartID = sourcePart.UUID; |
2427 | AddNewSceneObject(group, true, curpos, rot, vel); | 2660 | if( i == 0) |
2661 | AddNewSceneObject(group, true, curpos, rot, vel); | ||
2662 | else | ||
2663 | { | ||
2664 | Quaternion crot = objlist[i].RootPart.GetWorldRotation(); | ||
2665 | if (fixrot) | ||
2666 | { | ||
2667 | crot *= netRot; | ||
2668 | } | ||
2669 | AddNewSceneObject(group, true, curpos, crot, vel); | ||
2670 | } | ||
2428 | 2671 | ||
2429 | // We can only call this after adding the scene object, since the scene object references the scene | 2672 | // We can only call this after adding the scene object, since the scene object references the scene |
2430 | // to find out if scripts should be activated at all. | 2673 | // to find out if scripts should be activated at all. |
@@ -2455,6 +2698,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2455 | 2698 | ||
2456 | public void SetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID, bool running) | 2699 | public void SetScriptRunning(IClientAPI controllingClient, UUID objectID, UUID itemID, bool running) |
2457 | { | 2700 | { |
2701 | if (!Permissions.CanEditScript(itemID, objectID, controllingClient.AgentId)) | ||
2702 | return; | ||
2703 | |||
2458 | SceneObjectPart part = GetSceneObjectPart(objectID); | 2704 | SceneObjectPart part = GetSceneObjectPart(objectID); |
2459 | if (part == null) | 2705 | if (part == null) |
2460 | return; | 2706 | return; |
@@ -2511,7 +2757,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
2511 | } | 2757 | } |
2512 | else | 2758 | else |
2513 | { | 2759 | { |
2514 | if (!Permissions.CanEditObject(sog.UUID, remoteClient.AgentId)) | 2760 | if (!Permissions.IsGod(remoteClient.AgentId) && sog.OwnerID != remoteClient.AgentId) |
2761 | continue; | ||
2762 | |||
2763 | if (!Permissions.CanTransferObject(sog.UUID, groupID)) | ||
2515 | continue; | 2764 | continue; |
2516 | 2765 | ||
2517 | if (sog.GroupID != groupID) | 2766 | if (sog.GroupID != groupID) |
@@ -2622,7 +2871,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
2622 | return; | 2871 | return; |
2623 | } | 2872 | } |
2624 | 2873 | ||
2874 | bool oldUsePhysics = (root.Flags & PrimFlags.Physics) != 0; | ||
2625 | m_sceneGraph.LinkObjects(root, children); | 2875 | m_sceneGraph.LinkObjects(root, children); |
2876 | |||
2877 | ScenePresence sp; | ||
2878 | if (TryGetScenePresence(agentId, out sp)) | ||
2879 | { | ||
2880 | root.SendPropertiesToClient(sp.ControllingClient); | ||
2881 | if (oldUsePhysics && (root.Flags & PrimFlags.Physics) == 0) | ||
2882 | { | ||
2883 | sp.ControllingClient.SendAlertMessage("Object physics canceled"); | ||
2884 | } | ||
2885 | } | ||
2626 | } | 2886 | } |
2627 | 2887 | ||
2628 | private string PermissionString(uint permissions) | 2888 | private string PermissionString(uint permissions) |