diff options
author | Melanie | 2010-10-07 01:13:17 +0200 |
---|---|---|
committer | Melanie | 2010-10-07 01:13:17 +0200 |
commit | 2db0ac74c72f18d1bceb15b8a368777e42b366c0 (patch) | |
tree | 874f9c1eaa17855e0dd6f07ea50efa0326647a16 | |
parent | Plumb the path for multiple object deletes (diff) | |
download | opensim-SC-2db0ac74c72f18d1bceb15b8a368777e42b366c0.zip opensim-SC-2db0ac74c72f18d1bceb15b8a368777e42b366c0.tar.gz opensim-SC-2db0ac74c72f18d1bceb15b8a368777e42b366c0.tar.bz2 opensim-SC-2db0ac74c72f18d1bceb15b8a368777e42b366c0.tar.xz |
Implement taking of coalesced objects.
WARNING!!!!!
You can TAKE them, but you can't REZ them again. Only the first of the contained
objects will rez, the rest is inaccessible until rezzing them is implemented.
Also, rotations are not explicitly stored. This MAY work. Or not.
Diffstat (limited to '')
4 files changed, 276 insertions, 207 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 9ccf5a0..753aada 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 | ||
@@ -191,11 +192,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
191 | public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, | 192 | public virtual UUID DeleteToInventory(DeRezAction action, UUID folderID, |
192 | List<SceneObjectGroup> objectGroups, IClientAPI remoteClient) | 193 | List<SceneObjectGroup> objectGroups, IClientAPI remoteClient) |
193 | { | 194 | { |
194 | // HACK: This is only working for lists containing a single item! | ||
195 | // It's just a hack to make this WIP compile and run. Nothing | ||
196 | // currently calls this with multiple items. | ||
197 | UUID ret = UUID.Zero; | 195 | UUID ret = UUID.Zero; |
198 | 196 | ||
197 | // The following code groups the SOG's by owner. No objects | ||
198 | // belonging to different people can be coalesced, for obvious | ||
199 | // reasons. | ||
199 | Dictionary<UUID, List<SceneObjectGroup>> deletes = | 200 | Dictionary<UUID, List<SceneObjectGroup>> deletes = |
200 | new Dictionary<UUID, List<SceneObjectGroup>>(); | 201 | new Dictionary<UUID, List<SceneObjectGroup>>(); |
201 | 202 | ||
@@ -207,266 +208,328 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
207 | deletes[g.OwnerID].Add(g); | 208 | deletes[g.OwnerID].Add(g); |
208 | } | 209 | } |
209 | 210 | ||
210 | foreach (List<SceneObjectGroup> objlist in deletes.Values) | 211 | // This is pethod scoped and will be returned. It will be the |
211 | ret = DeleteToInventory(action, folderID, objlist, remoteClient); | 212 | // last created asset id |
213 | UUID assetID = UUID.Zero; | ||
212 | 214 | ||
213 | return ret; | 215 | // Each iteration is really a separate asset being created, |
214 | } | 216 | // with distinct destinations as well. |
217 | foreach (List<SceneObjectGroup> objlist in deletes.Values) | ||
218 | { | ||
219 | Dictionary<UUID, string> xmlStrings = | ||
220 | new Dictionary<UUID, string>(); | ||
215 | 221 | ||
216 | private UUID DeleteToInventory(DeRezAction action, UUID folderID, | 222 | foreach (SceneObjectGroup objectGroup in objlist) |
217 | SceneObjectGroup objectGroup, IClientAPI remoteClient) | 223 | { |
218 | { | 224 | Vector3 inventoryStoredPosition = new Vector3 |
219 | UUID assetID = UUID.Zero; | 225 | (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) |
226 | ? 250 | ||
227 | : objectGroup.AbsolutePosition.X) | ||
228 | , | ||
229 | (objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) | ||
230 | ? 250 | ||
231 | : objectGroup.AbsolutePosition.X, | ||
232 | objectGroup.AbsolutePosition.Z); | ||
220 | 233 | ||
221 | Vector3 inventoryStoredPosition = new Vector3 | 234 | Vector3 originalPosition = objectGroup.AbsolutePosition; |
222 | (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) | ||
223 | ? 250 | ||
224 | : objectGroup.AbsolutePosition.X) | ||
225 | , | ||
226 | (objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) | ||
227 | ? 250 | ||
228 | : objectGroup.AbsolutePosition.X, | ||
229 | objectGroup.AbsolutePosition.Z); | ||
230 | 235 | ||
231 | Vector3 originalPosition = objectGroup.AbsolutePosition; | 236 | // Restore attachment data after trip through the sim |
237 | if (objectGroup.RootPart.AttachPoint > 0) | ||
238 | inventoryStoredPosition = objectGroup.RootPart.AttachOffset; | ||
239 | objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint; | ||
232 | 240 | ||
233 | // Restore attachment data after trip through the sim | 241 | objectGroup.AbsolutePosition = inventoryStoredPosition; |
234 | if (objectGroup.RootPart.AttachPoint > 0) | ||
235 | inventoryStoredPosition = objectGroup.RootPart.AttachOffset; | ||
236 | objectGroup.RootPart.Shape.State = objectGroup.RootPart.AttachPoint; | ||
237 | 242 | ||
238 | objectGroup.AbsolutePosition = inventoryStoredPosition; | 243 | // Make sure all bits but the ones we want are clear |
244 | // on take. | ||
245 | // This will be applied to the current perms, so | ||
246 | // it will do what we want. | ||
247 | objectGroup.RootPart.NextOwnerMask &= | ||
248 | ((uint)PermissionMask.Copy | | ||
249 | (uint)PermissionMask.Transfer | | ||
250 | (uint)PermissionMask.Modify); | ||
251 | objectGroup.RootPart.NextOwnerMask |= | ||
252 | (uint)PermissionMask.Move; | ||
239 | 253 | ||
240 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); | 254 | string sceneObjectXml = SceneObjectSerializer.ToOriginalXmlFormat(objectGroup); |
241 | 255 | ||
242 | objectGroup.AbsolutePosition = originalPosition; | 256 | objectGroup.AbsolutePosition = originalPosition; |
243 | 257 | ||
244 | // Get the user info of the item destination | 258 | xmlStrings[objectGroup.UUID] = sceneObjectXml; |
245 | // | 259 | } |
246 | UUID userID = UUID.Zero; | ||
247 | 260 | ||
248 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || | 261 | string itemXml; |
249 | action == DeRezAction.SaveToExistingUserInventoryItem) | ||
250 | { | ||
251 | // Take or take copy require a taker | ||
252 | // Saving changes requires a local user | ||
253 | // | ||
254 | if (remoteClient == null) | ||
255 | return UUID.Zero; | ||
256 | 262 | ||
257 | userID = remoteClient.AgentId; | 263 | if (objlist.Count > 1) |
258 | } | 264 | { |
259 | else | 265 | float minX, minY, minZ; |
260 | { | 266 | float maxX, maxY, maxZ; |
261 | // All returns / deletes go to the object owner | ||
262 | // | ||
263 | 267 | ||
264 | userID = objectGroup.RootPart.OwnerID; | 268 | Vector3[] offsets = m_Scene.GetCombinedBoundingBox(objlist, |
265 | } | 269 | out minX, out maxX, out minY, out maxY, |
270 | out minZ, out maxZ); | ||
266 | 271 | ||
267 | if (userID == UUID.Zero) // Can't proceed | 272 | // CreateWrapper |
268 | { | 273 | XmlDocument itemDoc = new XmlDocument(); |
269 | return UUID.Zero; | 274 | XmlElement root = itemDoc.CreateElement("", "CoalescedObject", ""); |
270 | } | 275 | itemDoc.AppendChild(root); |
271 | 276 | ||
272 | // If we're returning someone's item, it goes back to the | 277 | // Embed the offsets into the group XML |
273 | // owner's Lost And Found folder. | 278 | for ( int i = 0 ; i < objlist.Count ; i++ ) |
274 | // Delete is treated like return in this case | 279 | { |
275 | // Deleting your own items makes them go to trash | 280 | XmlDocument doc = new XmlDocument(); |
276 | // | 281 | SceneObjectGroup g = objlist[i]; |
282 | doc.LoadXml(xmlStrings[g.UUID]); | ||
283 | XmlElement e = (XmlElement)doc.SelectSingleNode("/SceneObjectGroup"); | ||
284 | e.SetAttribute("offsetx", offsets[i].X.ToString()); | ||
285 | e.SetAttribute("offsety", offsets[i].Y.ToString()); | ||
286 | e.SetAttribute("offsetz", offsets[i].Z.ToString()); | ||
277 | 287 | ||
278 | InventoryFolderBase folder = null; | 288 | XmlNode objectNode = itemDoc.ImportNode(e, true); |
279 | InventoryItemBase item = null; | 289 | root.AppendChild(objectNode); |
290 | } | ||
280 | 291 | ||
281 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | 292 | float sizeX = maxX - minX; |
282 | { | 293 | float sizeY = maxY - minY; |
283 | item = new InventoryItemBase(objectGroup.RootPart.FromUserInventoryItemID, userID); | 294 | float sizeZ = maxZ - minZ; |
284 | item = m_Scene.InventoryService.GetItem(item); | ||
285 | 295 | ||
286 | //item = userInfo.RootFolder.FindItem( | 296 | root.SetAttribute("x", sizeX.ToString()); |
287 | // objectGroup.RootPart.FromUserInventoryItemID); | 297 | root.SetAttribute("y", sizeY.ToString()); |
298 | root.SetAttribute("z", sizeZ.ToString()); | ||
288 | 299 | ||
289 | if (null == item) | 300 | itemXml = itemDoc.InnerXml; |
301 | } | ||
302 | else | ||
290 | { | 303 | { |
291 | m_log.DebugFormat( | 304 | itemXml = xmlStrings[objlist[0].UUID]; |
292 | "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", | ||
293 | objectGroup.Name, objectGroup.UUID); | ||
294 | return UUID.Zero; | ||
295 | } | 305 | } |
296 | } | 306 | |
297 | else | 307 | // Get the user info of the item destination |
298 | { | ||
299 | // Folder magic | ||
300 | // | 308 | // |
301 | if (action == DeRezAction.Delete) | 309 | UUID userID = UUID.Zero; |
310 | |||
311 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy || | ||
312 | action == DeRezAction.SaveToExistingUserInventoryItem) | ||
302 | { | 313 | { |
303 | // Deleting someone else's item | 314 | // Take or take copy require a taker |
315 | // Saving changes requires a local user | ||
304 | // | 316 | // |
305 | if (remoteClient == null || | 317 | if (remoteClient == null) |
306 | objectGroup.OwnerID != remoteClient.AgentId) | 318 | return UUID.Zero; |
307 | { | ||
308 | 319 | ||
309 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | 320 | userID = remoteClient.AgentId; |
310 | } | ||
311 | else | ||
312 | { | ||
313 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); | ||
314 | } | ||
315 | } | 321 | } |
316 | else if (action == DeRezAction.Return) | 322 | else |
317 | { | 323 | { |
318 | 324 | // All returns / deletes go to the object owner | |
319 | // Dump to lost + found unconditionally | ||
320 | // | 325 | // |
321 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | 326 | |
327 | userID = objlist[0].RootPart.OwnerID; | ||
322 | } | 328 | } |
323 | 329 | ||
324 | if (folderID == UUID.Zero && folder == null) | 330 | if (userID == UUID.Zero) // Can't proceed |
325 | { | 331 | { |
326 | if (action == DeRezAction.Delete) | 332 | return UUID.Zero; |
333 | } | ||
334 | |||
335 | // If we're returning someone's item, it goes back to the | ||
336 | // owner's Lost And Found folder. | ||
337 | // Delete is treated like return in this case | ||
338 | // Deleting your own items makes them go to trash | ||
339 | // | ||
340 | |||
341 | InventoryFolderBase folder = null; | ||
342 | InventoryItemBase item = null; | ||
343 | |||
344 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | ||
345 | { | ||
346 | item = new InventoryItemBase(objlist[0].RootPart.FromUserInventoryItemID, userID); | ||
347 | item = m_Scene.InventoryService.GetItem(item); | ||
348 | |||
349 | //item = userInfo.RootFolder.FindItem( | ||
350 | // objectGroup.RootPart.FromUserInventoryItemID); | ||
351 | |||
352 | if (null == item) | ||
327 | { | 353 | { |
328 | // Deletes go to trash by default | 354 | m_log.DebugFormat( |
329 | // | 355 | "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.", |
330 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); | 356 | objlist[0].Name, objlist[0].UUID); |
357 | return UUID.Zero; | ||
331 | } | 358 | } |
332 | else | 359 | } |
360 | else | ||
361 | { | ||
362 | // Folder magic | ||
363 | // | ||
364 | if (action == DeRezAction.Delete) | ||
333 | { | 365 | { |
366 | // Deleting someone else's item | ||
367 | // | ||
334 | if (remoteClient == null || | 368 | if (remoteClient == null || |
335 | objectGroup.OwnerID != remoteClient.AgentId) | 369 | objlist[0].OwnerID != remoteClient.AgentId) |
336 | { | 370 | { |
337 | // Taking copy of another person's item. Take to | 371 | |
338 | // Objects folder. | 372 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); |
339 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object); | ||
340 | } | 373 | } |
341 | else | 374 | else |
342 | { | 375 | { |
343 | // Catch all. Use lost & found | 376 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); |
377 | } | ||
378 | } | ||
379 | else if (action == DeRezAction.Return) | ||
380 | { | ||
381 | |||
382 | // Dump to lost + found unconditionally | ||
383 | // | ||
384 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | ||
385 | } | ||
386 | |||
387 | if (folderID == UUID.Zero && folder == null) | ||
388 | { | ||
389 | if (action == DeRezAction.Delete) | ||
390 | { | ||
391 | // Deletes go to trash by default | ||
344 | // | 392 | // |
393 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); | ||
394 | } | ||
395 | else | ||
396 | { | ||
397 | if (remoteClient == null || | ||
398 | objlist[0].OwnerID != remoteClient.AgentId) | ||
399 | { | ||
400 | // Taking copy of another person's item. Take to | ||
401 | // Objects folder. | ||
402 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object); | ||
403 | } | ||
404 | else | ||
405 | { | ||
406 | // Catch all. Use lost & found | ||
407 | // | ||
345 | 408 | ||
346 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | 409 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); |
410 | } | ||
347 | } | 411 | } |
348 | } | 412 | } |
349 | } | ||
350 | 413 | ||
351 | // Override and put into where it came from, if it came | 414 | // Override and put into where it came from, if it came |
352 | // from anywhere in inventory | 415 | // from anywhere in inventory |
353 | // | 416 | // |
354 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) | 417 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) |
355 | { | ||
356 | if (objectGroup.RootPart.FromFolderID != UUID.Zero) | ||
357 | { | 418 | { |
358 | InventoryFolderBase f = new InventoryFolderBase(objectGroup.RootPart.FromFolderID, userID); | 419 | if (objlist[0].RootPart.FromFolderID != UUID.Zero) |
359 | folder = m_Scene.InventoryService.GetFolder(f); | 420 | { |
421 | InventoryFolderBase f = new InventoryFolderBase(objlist[0].RootPart.FromFolderID, userID); | ||
422 | folder = m_Scene.InventoryService.GetFolder(f); | ||
423 | } | ||
360 | } | 424 | } |
361 | } | ||
362 | |||
363 | if (folder == null) // None of the above | ||
364 | { | ||
365 | folder = new InventoryFolderBase(folderID); | ||
366 | 425 | ||
367 | if (folder == null) // Nowhere to put it | 426 | if (folder == null) // None of the above |
368 | { | 427 | { |
369 | return UUID.Zero; | 428 | folder = new InventoryFolderBase(folderID); |
370 | } | ||
371 | } | ||
372 | 429 | ||
373 | item = new InventoryItemBase(); | 430 | if (folder == null) // Nowhere to put it |
374 | item.CreatorId = objectGroup.RootPart.CreatorID.ToString(); | 431 | { |
375 | item.ID = UUID.Random(); | 432 | return UUID.Zero; |
376 | item.InvType = (int)InventoryType.Object; | 433 | } |
377 | item.Folder = folder.ID; | 434 | } |
378 | item.Owner = userID; | ||
379 | } | ||
380 | 435 | ||
381 | AssetBase asset = CreateAsset( | 436 | item = new InventoryItemBase(); |
382 | objectGroup.GetPartName(objectGroup.RootPart.LocalId), | 437 | // Can't know creator is the same, so null it in inventory |
383 | objectGroup.GetPartDescription(objectGroup.RootPart.LocalId), | 438 | if (objlist.Count > 1) |
384 | (sbyte)AssetType.Object, | 439 | item.CreatorId = UUID.Zero.ToString(); |
385 | Utils.StringToBytes(sceneObjectXml), | 440 | else |
386 | objectGroup.OwnerID.ToString()); | 441 | item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); |
387 | m_Scene.AssetService.Store(asset); | 442 | item.ID = UUID.Random(); |
388 | assetID = asset.FullID; | 443 | item.InvType = (int)InventoryType.Object; |
444 | item.Folder = folder.ID; | ||
445 | item.Owner = userID; | ||
446 | if (objlist.Count > 1) | ||
447 | item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; | ||
448 | } | ||
389 | 449 | ||
390 | if (DeRezAction.SaveToExistingUserInventoryItem == action) | 450 | AssetBase asset = CreateAsset( |
391 | { | 451 | objlist[0].GetPartName(objlist[0].RootPart.LocalId), |
392 | item.AssetID = asset.FullID; | 452 | objlist[0].GetPartDescription(objlist[0].RootPart.LocalId), |
393 | m_Scene.InventoryService.UpdateItem(item); | 453 | (sbyte)AssetType.Object, |
394 | } | 454 | Utils.StringToBytes(itemXml), |
395 | else | 455 | objlist[0].OwnerID.ToString()); |
396 | { | 456 | m_Scene.AssetService.Store(asset); |
397 | item.AssetID = asset.FullID; | 457 | assetID = asset.FullID; |
398 | 458 | ||
399 | if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) | 459 | if (DeRezAction.SaveToExistingUserInventoryItem == action) |
400 | { | 460 | { |
401 | uint perms = objectGroup.GetEffectivePermissions(); | 461 | item.AssetID = asset.FullID; |
402 | uint nextPerms = (perms & 7) << 13; | 462 | m_Scene.InventoryService.UpdateItem(item); |
403 | if ((nextPerms & (uint)PermissionMask.Copy) == 0) | ||
404 | perms &= ~(uint)PermissionMask.Copy; | ||
405 | if ((nextPerms & (uint)PermissionMask.Transfer) == 0) | ||
406 | perms &= ~(uint)PermissionMask.Transfer; | ||
407 | if ((nextPerms & (uint)PermissionMask.Modify) == 0) | ||
408 | perms &= ~(uint)PermissionMask.Modify; | ||
409 | |||
410 | // Make sure all bits but the ones we want are clear | ||
411 | // on take. | ||
412 | // This will be applied to the current perms, so | ||
413 | // it will do what we want. | ||
414 | objectGroup.RootPart.NextOwnerMask &= | ||
415 | ((uint)PermissionMask.Copy | | ||
416 | (uint)PermissionMask.Transfer | | ||
417 | (uint)PermissionMask.Modify); | ||
418 | objectGroup.RootPart.NextOwnerMask |= | ||
419 | (uint)PermissionMask.Move; | ||
420 | |||
421 | item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask; | ||
422 | item.CurrentPermissions = item.BasePermissions; | ||
423 | item.NextPermissions = objectGroup.RootPart.NextOwnerMask; | ||
424 | item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask; | ||
425 | item.GroupPermissions = objectGroup.RootPart.GroupMask & objectGroup.RootPart.NextOwnerMask; | ||
426 | |||
427 | // Magic number badness. Maybe this deserves an enum. | ||
428 | // bit 4 (16) is the "Slam" bit, it means treat as passed | ||
429 | // and apply next owner perms on rez | ||
430 | item.CurrentPermissions |= 16; // Slam! | ||
431 | } | 463 | } |
432 | else | 464 | else |
433 | { | 465 | { |
434 | item.BasePermissions = objectGroup.GetEffectivePermissions(); | 466 | item.AssetID = asset.FullID; |
435 | item.CurrentPermissions = objectGroup.GetEffectivePermissions(); | 467 | |
436 | item.NextPermissions = objectGroup.RootPart.NextOwnerMask; | 468 | uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; |
437 | item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask; | 469 | foreach (SceneObjectGroup grp in objlist) |
438 | item.GroupPermissions = objectGroup.RootPart.GroupMask; | 470 | effectivePerms &= grp.GetEffectivePermissions(); |
471 | effectivePerms |= (uint)PermissionMask.Move; | ||
472 | |||
473 | if (remoteClient != null && (remoteClient.AgentId != objlist[0].RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) | ||
474 | { | ||
475 | uint perms = effectivePerms; | ||
476 | uint nextPerms = (perms & 7) << 13; | ||
477 | if ((nextPerms & (uint)PermissionMask.Copy) == 0) | ||
478 | perms &= ~(uint)PermissionMask.Copy; | ||
479 | if ((nextPerms & (uint)PermissionMask.Transfer) == 0) | ||
480 | perms &= ~(uint)PermissionMask.Transfer; | ||
481 | if ((nextPerms & (uint)PermissionMask.Modify) == 0) | ||
482 | perms &= ~(uint)PermissionMask.Modify; | ||
483 | |||
484 | item.BasePermissions = perms & objlist[0].RootPart.NextOwnerMask; | ||
485 | item.CurrentPermissions = item.BasePermissions; | ||
486 | item.NextPermissions = perms & objlist[0].RootPart.NextOwnerMask; | ||
487 | item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & objlist[0].RootPart.NextOwnerMask; | ||
488 | item.GroupPermissions = objlist[0].RootPart.GroupMask & objlist[0].RootPart.NextOwnerMask; | ||
489 | |||
490 | // Magic number badness. Maybe this deserves an enum. | ||
491 | // bit 4 (16) is the "Slam" bit, it means treat as passed | ||
492 | // and apply next owner perms on rez | ||
493 | item.CurrentPermissions |= 16; // Slam! | ||
494 | } | ||
495 | else | ||
496 | { | ||
497 | item.BasePermissions = effectivePerms; | ||
498 | item.CurrentPermissions = effectivePerms; | ||
499 | item.NextPermissions = objlist[0].RootPart.NextOwnerMask & effectivePerms; | ||
500 | item.EveryOnePermissions = objlist[0].RootPart.EveryoneMask & effectivePerms; | ||
501 | item.GroupPermissions = objlist[0].RootPart.GroupMask & effectivePerms; | ||
439 | 502 | ||
440 | item.CurrentPermissions &= | 503 | item.CurrentPermissions &= |
441 | ((uint)PermissionMask.Copy | | 504 | ((uint)PermissionMask.Copy | |
442 | (uint)PermissionMask.Transfer | | 505 | (uint)PermissionMask.Transfer | |
443 | (uint)PermissionMask.Modify | | 506 | (uint)PermissionMask.Modify | |
444 | (uint)PermissionMask.Move | | 507 | (uint)PermissionMask.Move | |
445 | 7); // Preserve folded permissions | 508 | 7); // Preserve folded permissions |
446 | } | 509 | } |
447 | 510 | ||
448 | // TODO: add the new fields (Flags, Sale info, etc) | 511 | // TODO: add the new fields (Flags, Sale info, etc) |
449 | item.CreationDate = Util.UnixTimeSinceEpoch(); | 512 | item.CreationDate = Util.UnixTimeSinceEpoch(); |
450 | item.Description = asset.Description; | 513 | item.Description = asset.Description; |
451 | item.Name = asset.Name; | 514 | item.Name = asset.Name; |
452 | item.AssetType = asset.Type; | 515 | item.AssetType = asset.Type; |
453 | 516 | ||
454 | m_Scene.AddInventoryItem(item); | 517 | m_Scene.AddInventoryItem(item); |
455 | 518 | ||
456 | if (remoteClient != null && item.Owner == remoteClient.AgentId) | 519 | if (remoteClient != null && item.Owner == remoteClient.AgentId) |
457 | { | ||
458 | remoteClient.SendInventoryItemCreateUpdate(item, 0); | ||
459 | } | ||
460 | else | ||
461 | { | ||
462 | ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner); | ||
463 | if (notifyUser != null) | ||
464 | { | 520 | { |
465 | notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0); | 521 | remoteClient.SendInventoryItemCreateUpdate(item, 0); |
522 | } | ||
523 | else | ||
524 | { | ||
525 | ScenePresence notifyUser = m_Scene.GetScenePresence(item.Owner); | ||
526 | if (notifyUser != null) | ||
527 | { | ||
528 | notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item, 0); | ||
529 | } | ||
466 | } | 530 | } |
467 | } | 531 | } |
468 | } | 532 | } |
469 | |||
470 | return assetID; | 533 | return assetID; |
471 | } | 534 | } |
472 | 535 | ||
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 bcc439c..76e160d 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.cs | |||
@@ -5063,8 +5063,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
5063 | { | 5063 | { |
5064 | float ominX, ominY, ominZ, omaxX, omaxY, omaxZ; | 5064 | float ominX, ominY, ominZ, omaxX, omaxY, omaxZ; |
5065 | 5065 | ||
5066 | Vector3 vec = g.AbsolutePosition; | ||
5067 | |||
5066 | g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ); | 5068 | g.GetAxisAlignedBoundingBoxRaw(out ominX, out omaxX, out ominY, out omaxY, out ominZ, out omaxZ); |
5067 | 5069 | ||
5070 | ominX += vec.X; | ||
5071 | omaxX += vec.X; | ||
5072 | ominY += vec.Y; | ||
5073 | omaxY += vec.Y; | ||
5074 | ominZ += vec.Z; | ||
5075 | omaxZ += vec.Z; | ||
5076 | |||
5068 | if (minX > ominX) | 5077 | if (minX > ominX) |
5069 | minX = ominX; | 5078 | minX = ominX; |
5070 | if (minY > ominY) | 5079 | if (minY > ominY) |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs index a6d89cf..9a7d560 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectGroup.cs | |||
@@ -1569,8 +1569,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1569 | ILandObject parcel = m_scene.LandChannel.GetLandObject( | 1569 | ILandObject parcel = m_scene.LandChannel.GetLandObject( |
1570 | m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y); | 1570 | m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y); |
1571 | 1571 | ||
1572 | List<uint> returns = new List<uint>(); | ||
1573 | |||
1574 | if (parcel != null && parcel.LandData != null && | 1572 | if (parcel != null && parcel.LandData != null && |
1575 | parcel.LandData.OtherCleanTime != 0) | 1573 | parcel.LandData.OtherCleanTime != 0) |
1576 | { | 1574 | { |
@@ -1584,15 +1582,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1584 | DetachFromBackup(); | 1582 | DetachFromBackup(); |
1585 | m_log.InfoFormat("[SCENE]: Returning object {0} due to parcel auto return", RootPart.UUID.ToString()); | 1583 | m_log.InfoFormat("[SCENE]: Returning object {0} due to parcel auto return", RootPart.UUID.ToString()); |
1586 | m_scene.AddReturn(OwnerID, Name, AbsolutePosition, "parcel auto return"); | 1584 | m_scene.AddReturn(OwnerID, Name, AbsolutePosition, "parcel auto return"); |
1587 | returns.Add(RootPart.LocalId); | 1585 | m_scene.DeRezObjects(null, new List<uint>() { RootPart.LocalId }, UUID.Zero, |
1586 | DeRezAction.Return, UUID.Zero); | ||
1588 | 1587 | ||
1589 | return; | 1588 | return; |
1590 | } | 1589 | } |
1591 | } | 1590 | } |
1592 | } | 1591 | } |
1593 | 1592 | ||
1594 | m_scene.DeRezObjects(null, returns, UUID.Zero, | ||
1595 | DeRezAction.Return, UUID.Zero); | ||
1596 | } | 1593 | } |
1597 | 1594 | ||
1598 | if (HasGroupChanged) | 1595 | if (HasGroupChanged) |