diff options
3 files changed, 274 insertions, 198 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 8d0c35a..88dff02 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -28,6 +28,7 @@ | |||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Net; | 30 | using System.Net; |
31 | using System.Xml; | ||
31 | using System.Reflection; | 32 | using System.Reflection; |
32 | using System.Threading; | 33 | using System.Threading; |
33 | 34 | ||
@@ -205,11 +206,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
205 | public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, | 206 | public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, |
206 | List<SceneObjectGroup> objectGroups, IClientAPI remoteClient) | 207 | List<SceneObjectGroup> objectGroups, IClientAPI remoteClient) |
207 | { | 208 | { |
208 | // HACK: This is only working for lists containing a single item! | ||
209 | // It's just a hack to make this WIP compile and run. Nothing | ||
210 | // currently calls this with multiple items. | ||
211 | UUID ret = UUID.Zero; | 209 | UUID ret = UUID.Zero; |
212 | 210 | ||
211 | // The following code groups the SOG's by owner. No objects | ||
212 | // belonging to different people can be coalesced, for obvious | ||
213 | // reasons. | ||
213 | Dictionary<UUID, List<SceneObjectGroup>> deletes = | 214 | Dictionary<UUID, List<SceneObjectGroup>> deletes = |
214 | new Dictionary<UUID, List<SceneObjectGroup>>(); | 215 | new Dictionary<UUID, List<SceneObjectGroup>>(); |
215 | 216 | ||
@@ -221,262 +222,328 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
221 | deletes[g.OwnerID].Add(g); | 222 | deletes[g.OwnerID].Add(g); |
222 | } | 223 | } |
223 | 224 | ||
225 | // This is pethod scoped and will be returned. It will be the | ||
226 | // last created asset id | ||
227 | UUID assetID = UUID.Zero; | ||
228 | |||
229 | // Each iteration is really a separate asset being created, | ||
230 | // with distinct destinations as well. | ||
224 | foreach (List<SceneObjectGroup> objlist in deletes.Values) | 231 | foreach (List<SceneObjectGroup> objlist in deletes.Values) |
225 | { | 232 | { |
226 | foreach (SceneObjectGroup g in objlist) | 233 | Dictionary<UUID, string> xmlStrings = |
227 | ret = DeleteToInventory(action, folderID, g, remoteClient); | 234 | new Dictionary<UUID, string>(); |
228 | } | ||
229 | |||
230 | return ret; | ||
231 | } | ||
232 | 235 | ||
233 | private UUID DeleteToInventory(DeRezAction action, UUID folderID, | 236 | foreach (SceneObjectGroup objectGroup in objlist) |
234 | SceneObjectGroup objectGroup, IClientAPI remoteClient) | 237 | { |
235 | { | 238 | Vector3 inventoryStoredPosition = new Vector3 |
236 | UUID assetID = UUID.Zero; | 239 | (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) |
240 | ? 250 | ||
241 | : objectGroup.AbsolutePosition.X) | ||
242 | , | ||
243 | (objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) | ||
244 | ? 250 | ||
245 | : objectGroup.AbsolutePosition.X, | ||
246 | objectGroup.AbsolutePosition.Z); | ||
237 | 247 | ||
238 | Vector3 inventoryStoredPosition = new Vector3 | 248 | Vector3 originalPosition = objectGroup.AbsolutePosition; |
239 | (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) | ||
240 | ? 250 | ||
241 | : objectGroup.AbsolutePosition.X) | ||
242 | , | ||
243 | (objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) | ||
244 | ? 250 | ||
245 | : objectGroup.AbsolutePosition.X, | ||
246 | objectGroup.AbsolutePosition.Z); | ||
247 | 249 | ||
248 | Vector3 originalPosition = objectGroup.AbsolutePosition; | 250 | // Restore attachment data after trip through the sim |
251 | if (objectGroup.RootPart.AttachPoint > 0) | ||
252 | inventoryStoredPosition = objectGroup.RootPart.AttachOffset; | ||
253 | objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint; | ||
249 | 254 | ||
250 | objectGroup.AbsolutePosition = inventoryStoredPosition; | 255 | objectGroup.AbsolutePosition = inventoryStoredPosition; |
251 | 256 | ||
252 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); | 257 | // Make sure all bits but the ones we want are clear |
258 | // on take. | ||
259 | // This will be applied to the current perms, so | ||
260 | // it will do what we want. | ||
261 | objectGroup.RootPart.NextOwnerMask &= | ||
262 | ((uint)PermissionMask.Copy | | ||
263 | (uint)PermissionMask.Transfer | | ||
264 | (uint)PermissionMask.Modify); | ||
265 | objectGroup.RootPart.NextOwnerMask |= | ||
266 | (uint)PermissionMask.Move; | ||
253 | 267 | ||
254 | objectGroup.AbsolutePosition = originalPosition; | 268 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); |
255 | 269 | ||
256 | // Get the user info of the item destination | 270 | objectGroup.AbsolutePosition = originalPosition; |
257 | // | ||
258 | UUID userID = UUID.Zero; | ||
259 | 271 | ||
260 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || | 272 | xmlStrings[objectGroup.UUID] = sceneObjectXml; |
261 | action == DeRezAction.SaveToExistingUserInventoryItem) | 273 | } |
262 | { | ||
263 | // Take or take copy require a taker | ||
264 | // Saving changes requires a local user | ||
265 | // | ||
266 | if (remoteClient == null) | ||
267 | return UUID.Zero; | ||
268 | 274 | ||
269 | userID = remoteClient.AgentId; | 275 | string itemXml; |
270 | } | ||
271 | else | ||
272 | { | ||
273 | // All returns / deletes go to the object owner | ||
274 | // | ||
275 | 276 | ||
276 | userID = objectGroup.RootPart.OwnerID; | 277 | if (objlist.Count > 1) |
277 | } | 278 | { |
279 | float minX, minY, minZ; | ||
280 | float maxX, maxY, maxZ; | ||
278 | 281 | ||
279 | if (userID == UUID.Zero) // Can't proceed | 282 | Vector3[] offsets = m_Scene.GetCombinedBoundingBox(objlist, |
280 | { | 283 | out minX, out maxX, out minY, out maxY, |
281 | return UUID.Zero; | 284 | out minZ, out maxZ); |
282 | } | ||
283 | 285 | ||
284 | // If we're returning someone's item, it goes back to the | 286 | // CreateWrapper |
285 | // owner's Lost And Found folder. | 287 | XmlDocument itemDoc = new XmlDocument(); |
286 | // Delete is treated like return in this case | 288 | XmlElement root = itemDoc.CreateElement("", "CoalescedObject", ""); |
287 | // Deleting your own items makes them go to trash | 289 | itemDoc.AppendChild(root); |
288 | // | ||
289 | 290 | ||
290 | InventoryFolderBase folder = null; | 291 | // Embed the offsets into the group XML |
291 | InventoryItemBase item = null; | 292 | for ( int i = 0 ; i < objlist.Count ; i++ ) |
293 | { | ||
294 | XmlDocument doc = new XmlDocument(); | ||
295 | SceneObjectGroup g = objlist[i]; | ||
296 | doc.LoadXml(xmlStrings[g.UUID]); | ||
297 | XmlElement e = (XmlElement)doc.SelectSingleNode("/SceneObjectGroup"); | ||
298 | e.SetAttribute("offsetx", offsets[i].X.ToString()); | ||
299 | e.SetAttribute("offsety", offsets[i].Y.ToString()); | ||
300 | e.SetAttribute("offsetz", offsets[i].Z.ToString()); | ||
301 | |||
302 | XmlNode objectNode = itemDoc.ImportNode(e, true); | ||
303 | root.AppendChild(objectNode); | ||
304 | } | ||
292 | 305 | ||
293 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | 306 | float sizeX = maxX - minX; |
294 | { | 307 | float sizeY = maxY - minY; |
295 | item = new InventoryItemBase(objectGroup.RootPart.FromUserInventoryItemID, userID); | 308 | float sizeZ = maxZ - minZ; |
296 | item = m_Scene.InventoryService.GetItem(item); | ||
297 | 309 | ||
298 | //item = userInfo.RootFolder.FindItem( | 310 | root.SetAttribute("x", sizeX.ToString()); |
299 | // objectGroup.RootPart.FromUserInventoryItemID); | 311 | root.SetAttribute("y", sizeY.ToString()); |
312 | root.SetAttribute("z", sizeZ.ToString()); | ||
300 | 313 | ||
301 | if (null == item) | 314 | itemXml = itemDoc.InnerXml; |
315 | } | ||
316 | else | ||
302 | { | 317 | { |
303 | m_log.DebugFormat( | 318 | itemXml = xmlStrings[objlist[0].UUID]; |
304 | "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", | ||
305 | objectGroup.Name, objectGroup.UUID); | ||
306 | return UUID.Zero; | ||
307 | } | 319 | } |
308 | } | 320 | |
309 | else | 321 | // Get the user info of the item destination |
310 | { | ||
311 | // Folder magic | ||
312 | // | 322 | // |
313 | if (action == DeRezAction.Delete) | 323 | UUID userID = UUID.Zero; |
324 | |||
325 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || | ||
326 | action == DeRezAction.SaveToExistingUserInventoryItem) | ||
314 | { | 327 | { |
315 | // Deleting someone else's item | 328 | // Take or take copy require a taker |
329 | // Saving changes requires a local user | ||
316 | // | 330 | // |
317 | if (remoteClient == null || | 331 | if (remoteClient == null) |
318 | objectGroup.OwnerID != remoteClient.AgentId) | 332 | return UUID.Zero; |
319 | { | ||
320 | 333 | ||
321 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | 334 | userID = remoteClient.AgentId; |
322 | } | ||
323 | else | ||
324 | { | ||
325 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); | ||
326 | } | ||
327 | } | 335 | } |
328 | else if (action == DeRezAction.Return) | 336 | else |
329 | { | 337 | { |
330 | 338 | // All returns / deletes go to the object owner | |
331 | // Dump to lost + found unconditionally | ||
332 | // | 339 | // |
333 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | 340 | |
341 | userID = objlist[0].RootPart.OwnerID; | ||
334 | } | 342 | } |
335 | 343 | ||
336 | if (folderID == UUID.Zero && folder == null) | 344 | if (userID == UUID.Zero) // Can't proceed |
337 | { | 345 | { |
338 | if (action == DeRezAction.Delete) | 346 | return UUID.Zero; |
347 | } | ||
348 | |||
349 | // If we're returning someone's item, it goes back to the | ||
350 | // owner's Lost And Found folder. | ||
351 | // Delete is treated like return in this case | ||
352 | // Deleting your own items makes them go to trash | ||
353 | // | ||
354 | |||
355 | InventoryFolderBase folder = null; | ||
356 | InventoryItemBase item = null; | ||
357 | |||
358 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | ||
359 | { | ||
360 | item = new InventoryItemBase(objlist[0].RootPart.FromUserInventoryItemID, userID); | ||
361 | item = m_Scene.InventoryService.GetItem(item); | ||
362 | |||
363 | //item = userInfo.RootFolder.FindItem( | ||
364 | // objectGroup.RootPart.FromUserInventoryItemID); | ||
365 | |||
366 | if (null == item) | ||
339 | { | 367 | { |
340 | // Deletes go to trash by default | 368 | m_log.DebugFormat( |
341 | // | 369 | "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", |
342 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); | 370 | objlist[0].Name, objlist[0].UUID); |
371 | return UUID.Zero; | ||
343 | } | 372 | } |
344 | else | 373 | } |
374 | else | ||
375 | { | ||
376 | // Folder magic | ||
377 | // | ||
378 | if (action == DeRezAction.Delete) | ||
345 | { | 379 | { |
380 | // Deleting someone else's item | ||
381 | // | ||
346 | if (remoteClient == null || | 382 | if (remoteClient == null || |
347 | objectGroup.OwnerID != remoteClient.AgentId) | 383 | objlist[0].OwnerID != remoteClient.AgentId) |
348 | { | 384 | { |
349 | // Taking copy of another person's item. Take to | 385 | |
350 | // Objects folder. | 386 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); |
351 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object); | ||
352 | } | 387 | } |
353 | else | 388 | else |
354 | { | 389 | { |
355 | // Catch all. Use lost & found | 390 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); |
391 | } | ||
392 | } | ||
393 | else if (action == DeRezAction.Return) | ||
394 | { | ||
395 | |||
396 | // Dump to lost + found unconditionally | ||
397 | // | ||
398 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | ||
399 | } | ||
400 | |||
401 | if (folderID == UUID.Zero && folder == null) | ||
402 | { | ||
403 | if (action == DeRezAction.Delete) | ||
404 | { | ||
405 | // Deletes go to trash by default | ||
356 | // | 406 | // |
407 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); | ||
408 | } | ||
409 | else | ||
410 | { | ||
411 | if (remoteClient == null || | ||
412 | objlist[0].OwnerID != remoteClient.AgentId) | ||
413 | { | ||
414 | // Taking copy of another person's item. Take to | ||
415 | // Objects folder. | ||
416 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object); | ||
417 | } | ||
418 | else | ||
419 | { | ||
420 | // Catch all. Use lost & found | ||
421 | // | ||
357 | 422 | ||
358 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | 423 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); |
424 | } | ||
359 | } | 425 | } |
360 | } | 426 | } |
361 | } | ||
362 | 427 | ||
363 | // Override and put into where it came from, if it came | 428 | // Override and put into where it came from, if it came |
364 | // from anywhere in inventory | 429 | // from anywhere in inventory |
365 | // | 430 | // |
366 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) | 431 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) |
367 | { | ||
368 | if (objectGroup.RootPart.FromFolderID != UUID.Zero) | ||
369 | { | 432 | { |
370 | InventoryFolderBase f = new InventoryFolderBase(objectGroup.RootPart.FromFolderID, userID); | 433 | if (objlist[0].RootPart.FromFolderID != UUID.Zero) |
371 | folder = m_Scene.InventoryService.GetFolder(f); | 434 | { |
435 | InventoryFolderBase f = new InventoryFolderBase(objlist[0].RootPart.FromFolderID, userID); | ||
436 | folder = m_Scene.InventoryService.GetFolder(f); | ||
437 | } | ||
372 | } | 438 | } |
373 | } | ||
374 | |||
375 | if (folder == null) // None of the above | ||
376 | { | ||
377 | folder = new InventoryFolderBase(folderID); | ||
378 | 439 | ||
379 | if (folder == null) // Nowhere to put it | 440 | if (folder == null) // None of the above |
380 | { | 441 | { |
381 | return UUID.Zero; | 442 | folder = new InventoryFolderBase(folderID); |
382 | } | ||
383 | } | ||
384 | 443 | ||
385 | item = new InventoryItemBase(); | 444 | if (folder == null) // Nowhere to put it |
386 | item.CreatorId = objectGroup.RootPart.CreatorID.ToString(); | 445 | { |
387 | item.CreatorData = objectGroup.RootPart.CreatorData; | 446 | return UUID.Zero; |
388 | item.ID = UUID.Random(); | 447 | } |
389 | item.InvType = (int)InventoryType.Object; | 448 | } |
390 | item.Folder = folder.ID; | ||
391 | item.Owner = userID; | ||
392 | } | ||
393 | 449 | ||
394 | AssetBase asset = CreateAsset( | 450 | item = new InventoryItemBase(); |
395 | objectGroup.GetPartName(objectGroup.RootPart.LocalId), | 451 | // Can't know creator is the same, so null it in inventory |
396 | objectGroup.GetPartDescription(objectGroup.RootPart.LocalId), | 452 | if (objlist.Count > 1) |
397 | (sbyte)AssetType.Object, | 453 | item.CreatorId = UUID.Zero.ToString(); |
398 | Utils.StringToBytes(sceneObjectXml), | 454 | else |
399 | objectGroup.OwnerID.ToString()); | 455 | item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); |
400 | m_Scene.AssetService.Store(asset); | 456 | item.ID = UUID.Random(); |
401 | assetID = asset.FullID; | 457 | item.InvType = (int)InventoryType.Object; |
458 | item.Folder = folder.ID; | ||
459 | item.Owner = userID; | ||
460 | if (objlist.Count > 1) | ||
461 | item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; | ||
462 | } | ||
402 | 463 | ||
403 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | 464 | AssetBase asset = CreateAsset( |
404 | { | 465 | objlist[0].GetPartName(objlist[0].RootPart.LocalId), |
405 | item.AssetID = asset.FullID; | 466 | objlist[0].GetPartDescription(objlist[0].RootPart.LocalId), |
406 | m_Scene.InventoryService.UpdateItem(item); | 467 | (sbyte)AssetType.Object, |
407 | } | 468 | Utils.StringToBytes(itemXml), |
408 | else | 469 | objlist[0].OwnerID.ToString()); |
409 | { | 470 | m_Scene.AssetService.Store(asset); |
410 | item.AssetID = asset.FullID; | 471 | assetID = asset.FullID; |
411 | 472 | ||
412 | if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) | 473 | if (DeRezAction.SaveToExistingUserInventoryItem == action) |
413 | { | 474 | { |
414 | uint perms = objectGroup.GetEffectivePermissions(); | 475 | item.AssetID = asset.FullID; |
415 | uint nextPerms = (perms & 7) << 13; | 476 | m_Scene.InventoryService.UpdateItem(item); |
416 | if ((nextPerms & (uint)PermissionMask.Copy) == 0) | ||
417 | perms &= ~(uint)PermissionMask.Copy; | ||
418 | if ((nextPerms & (uint)PermissionMask.Transfer) == 0) | ||
419 | perms &= ~(uint)PermissionMask.Transfer; | ||
420 | if ((nextPerms & (uint)PermissionMask.Modify) == 0) | ||
421 | perms &= ~(uint)PermissionMask.Modify; | ||
422 | |||
423 | // Make sure all bits but the ones we want are clear | ||
424 | // on take. | ||
425 | // This will be applied to the current perms, so | ||
426 | // it will do what we want. | ||
427 | objectGroup.RootPart.NextOwnerMask &= | ||
428 | ((uint)PermissionMask.Copy | | ||
429 | (uint)PermissionMask.Transfer | | ||
430 | (uint)PermissionMask.Modify); | ||
431 | objectGroup.RootPart.NextOwnerMask |= | ||
432 | (uint)PermissionMask.Move; | ||
433 | |||
434 | item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask; | ||
435 | item.CurrentPermissions = item.BasePermissions; | ||
436 | item.NextPermissions = objectGroup.RootPart.NextOwnerMask; | ||
437 | item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask; | ||
438 | item.GroupPermissions = objectGroup.RootPart.GroupMask & objectGroup.RootPart.NextOwnerMask; | ||
439 | |||
440 | item.Flags |= (uint)InventoryItemFlags.ObjectSlamPerm; | ||
441 | } | 477 | } |
442 | else | 478 | else |
443 | { | 479 | { |
444 | item.BasePermissions = objectGroup.GetEffectivePermissions(); | 480 | item.AssetID = asset.FullID; |
445 | item.CurrentPermissions = objectGroup.GetEffectivePermissions(); | ||
446 | item.NextPermissions = objectGroup.RootPart.NextOwnerMask; | ||
447 | item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask; | ||
448 | item.GroupPermissions = objectGroup.RootPart.GroupMask; | ||
449 | 481 | ||
450 | item.CurrentPermissions &= | 482 | uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; |
451 | ((uint)PermissionMask.Copy | | 483 | foreach (SceneObjectGroup grp in objlist) |
452 | (uint)PermissionMask.Transfer | | 484 | effectivePerms &= grp.GetEffectivePermissions(); |
453 | (uint)PermissionMask.Modify | | 485 | effectivePerms |= (uint)PermissionMask.Move; |
454 | (uint)PermissionMask.Move | | ||
455 | 7); // Preserve folded permissions | ||
456 | } | ||
457 | 486 | ||
458 | // TODO: add the new fields (Flags, Sale info, etc) | 487 | if (remoteClient != null && (remoteClient.AgentId != objlist[0].RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) |
459 | item.CreationDate = Util.UnixTimeSinceEpoch(); | 488 | { |
460 | item.Description = asset.Description; | 489 | uint perms = effectivePerms; |
461 | item.Name = asset.Name; | 490 | uint nextPerms = (perms & 7) << 13; |
462 | item.AssetType = asset.Type; | 491 | if ((nextPerms & (uint)PermissionMask.Copy) == 0) |
492 | perms &= ~(uint)PermissionMask.Copy; | ||
493 | if ((nextPerms & (uint)PermissionMask.Transfer) == 0) | ||
494 | perms &= ~(uint)PermissionMask.Transfer; | ||
495 | if ((nextPerms & (uint)PermissionMask.Modify) == 0) | ||
496 | perms &= ~(uint)PermissionMask.Modify; | ||
497 | |||
498 | item.BasePermissions = perms & objlist[0].RootPart.NextOwnerMask; | ||
499 | item.CurrentPermissions = item.BasePermissions; | ||
500 | item.NextPermissions = perms & objlist[0].RootPart.NextOwnerMask; | ||
501 | item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & objlist[0].RootPart.NextOwnerMask; | ||
502 | item.GroupPermissions = objlist[0].RootPart.GroupMask & objlist[0].RootPart.NextOwnerMask; | ||
503 | |||
504 | // Magic number badness. Maybe this deserves an enum. | ||
505 | // bit 4 (16) is the "Slam" bit, it means treat as passed | ||
506 | // and apply next owner perms on rez | ||
507 | item.CurrentPermissions |= 16; // Slam! | ||
508 | } | ||
509 | else | ||
510 | { | ||
511 | item.BasePermissions = effectivePerms; | ||
512 | item.CurrentPermissions = effectivePerms; | ||
513 | item.NextPermissions = objlist[0].RootPart.NextOwnerMask & effectivePerms; | ||
514 | item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & effectivePerms; | ||
515 | item.GroupPermissions = objlist[0].RootPart.GroupMask & effectivePerms; | ||
516 | |||
517 | item.CurrentPermissions &= | ||
518 | ((uint)PermissionMask.Copy | | ||
519 | (uint)PermissionMask.Transfer | | ||
520 | (uint)PermissionMask.Modify | | ||
521 | (uint)PermissionMask.Move | | ||
522 | 7); // Preserve folded permissions | ||
523 | } | ||
463 | 524 | ||
464 | m_Scene.AddInventoryItem(item); | 525 | // TODO: add the new fields (Flags, Sale info, etc) |
526 | item.CreationDate = Util.UnixTimeSinceEpoch(); | ||
527 | item.Description = asset.Description; | ||
528 | item.Name = asset.Name; | ||
529 | item.AssetType = asset.Type; | ||
465 | 530 | ||
466 | if (remoteClient != null && item.Owner == remoteClient.AgentId) | 531 | m_Scene.AddInventoryItem(item); |
467 | { | 532 | |
468 | remoteClient.SendInventoryItemCreateUpdate(item, 0); | 533 | if (remoteClient != null && item.Owner == remoteClient.AgentId) |
469 | } | ||
470 | else | ||
471 | { | ||
472 | ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner); | ||
473 | if (notifyUser != null) | ||
474 | { | 534 | { |
475 | notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0); | 535 | remoteClient.SendInventoryItemCreateUpdate(item, 0); |
536 | } | ||
537 | else | ||
538 | { | ||
539 | ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner); | ||
540 | if (notifyUser != null) | ||
541 | { | ||
542 | notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0); | ||
543 | } | ||
476 | } | 544 | } |
477 | } | 545 | } |
478 | } | 546 | } |
479 | |||
480 | return assetID; | 547 | return assetID; |
481 | } | 548 | } |
482 | 549 | ||
diff --git a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs index 64567db..8feb022 100644 --- a/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs +++ b/OpenSim/Region/Framework/Scenes/AsyncSceneObjectGroupDeleter.cs | |||
@@ -137,7 +137,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
137 | x = m_inventoryDeletes.Dequeue(); | 137 | x = m_inventoryDeletes.Dequeue(); |
138 | 138 | ||
139 | m_log.DebugFormat( | 139 | m_log.DebugFormat( |
140 | "[ASYNC DELETER]: Sending object to user's inventory, {0} item(s) remaining.", left); | 140 | "[ASYNC DELETER]: Sending object to user's inventory, action {1}, count {2}, {0} item(s) remaining.", left, x.action, x.objectGroups.Count); |
141 | 141 | ||
142 | try | 142 | try |
143 | { | 143 | { |
@@ -177,4 +177,4 @@ namespace OpenSim.Region.Framework.Scenes | |||
177 | return false; | 177 | return false; |
178 | } | 178 | } |
179 | } | 179 | } |
180 | } \ No newline at end of file | 180 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.cs b/OpenSim/Region/Framework/Scenes/Scene.cs index 353b7c2..35a798e 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -4865,8 +4865,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
4865 | { | 4865 | { |
4866 | float ominX, ominY, ominZ, omaxX, omaxY, omaxZ; | 4866 | float ominX, ominY, ominZ, omaxX, omaxY, omaxZ; |
4867 | 4867 | ||
4868 | Vector3 vec = g.AbsolutePosition; | ||
4869 | |||
4868 | g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ); | 4870 | g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ); |
4869 | 4871 | ||
4872 | ominX += vec.X; | ||
4873 | omaxX += vec.X; | ||
4874 | ominY += vec.Y; | ||
4875 | omaxY += vec.Y; | ||
4876 | ominZ += vec.Z; | ||
4877 | omaxZ += vec.Z; | ||
4878 | |||
4870 | if (minX > ominX) | 4879 | if (minX > ominX) |
4871 | minX = ominX; | 4880 | minX = ominX; |
4872 | if (minY > ominY) | 4881 | if (minY > ominY) |