aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorAdam Frisby2008-07-06 02:27:10 +0000
committerAdam Frisby2008-07-06 02:27:10 +0000
commit55dda821805a9fb94996c46594a03ba719d8f32b (patch)
tree38862f567a08d7a45f8fbd2456165fcbce5ef2fb /OpenSim/Region
parentalters a problem path cut angle for the cylinder prim profile (diff)
downloadopensim-SC-55dda821805a9fb94996c46594a03ba719d8f32b.zip
opensim-SC-55dda821805a9fb94996c46594a03ba719d8f32b.tar.gz
opensim-SC-55dda821805a9fb94996c46594a03ba719d8f32b.tar.bz2
opensim-SC-55dda821805a9fb94996c46594a03ba719d8f32b.tar.xz
* Moves sending items to inventory via a delete into a seperate thread (this thread can be expanded to support all sends to inventory from inworld easily enough). Thread is temporary and only exists while items are being returned.
* This should remove the "lag" caused by deleting many objects. * Patch brought to you by Joshua Nightshade's bitching at me to fix it.
Diffstat (limited to 'OpenSim/Region')
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.Inventory.cs264
1 files changed, 172 insertions, 92 deletions
diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
index 513d40d..36ca51b 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
@@ -29,6 +29,7 @@ using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Reflection; 30using System.Reflection;
31using System.Text; 31using System.Text;
32using System.Timers;
32using libsecondlife; 33using libsecondlife;
33using libsecondlife.Packets; 34using libsecondlife.Packets;
34using log4net; 35using log4net;
@@ -38,8 +39,20 @@ using OpenSim.Region.Environment.Interfaces;
38 39
39namespace OpenSim.Region.Environment.Scenes 40namespace OpenSim.Region.Environment.Scenes
40{ 41{
42 class DeleteToInventoryHolder
43 {
44 public DeRezObjectPacket DeRezPacket;
45 public EntityBase selectedEnt;
46 public IClientAPI remoteClient;
47 public SceneObjectGroup objectGroup;
48 public LLUUID folderID;
49 }
50
41 public partial class Scene 51 public partial class Scene
42 { 52 {
53 private Timer m_inventoryTicker;
54 private readonly Queue<DeleteToInventoryHolder> m_inventoryDeletes = new Queue<DeleteToInventoryHolder>();
55
43 private static readonly ILog m_log 56 private static readonly ILog m_log
44 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 57 = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
45 58
@@ -1395,7 +1408,7 @@ namespace OpenSim.Region.Environment.Scenes
1395 /// Called when an object is removed from the environment into inventory. 1408 /// Called when an object is removed from the environment into inventory.
1396 /// </summary> 1409 /// </summary>
1397 /// <param name="packet"></param> 1410 /// <param name="packet"></param>
1398 /// <param name="simClient"></param> 1411 /// <param name="remoteClient"></param>
1399 public virtual void DeRezObject(Packet packet, IClientAPI remoteClient) 1412 public virtual void DeRezObject(Packet packet, IClientAPI remoteClient)
1400 { 1413 {
1401 DeRezObjectPacket DeRezPacket = (DeRezObjectPacket) packet; 1414 DeRezObjectPacket DeRezPacket = (DeRezObjectPacket) packet;
@@ -1453,12 +1466,84 @@ namespace OpenSim.Region.Environment.Scenes
1453 1466
1454 if (permissionToTake) 1467 if (permissionToTake)
1455 { 1468 {
1456 string sceneObjectXml = objectGroup.ToXmlString(); 1469 if (m_inventoryTicker != null)
1470 {
1471 m_inventoryTicker.Stop();
1472 }
1473 else
1474 {
1475 m_inventoryTicker = new Timer(2000);
1476 m_inventoryTicker.AutoReset = false;
1477 m_inventoryTicker.Elapsed += InventoryRunDeleteTimer;
1478 }
1457 1479
1458 CachedUserInfo userInfo = 1480 lock(m_inventoryDeletes)
1459 CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
1460 if (userInfo != null)
1461 { 1481 {
1482 DeleteToInventoryHolder dtis = new DeleteToInventoryHolder();
1483 dtis.DeRezPacket = DeRezPacket;
1484 dtis.folderID = folderID;
1485 dtis.objectGroup = objectGroup;
1486 dtis.remoteClient = remoteClient;
1487 dtis.selectedEnt = selectedEnt;
1488
1489 m_inventoryDeletes.Enqueue(dtis);
1490 }
1491
1492 m_inventoryTicker.Start();
1493
1494 // Visually remove it, even if it isnt really gone yet.
1495 objectGroup.FakeDeleteGroup();
1496 }
1497 else if (permissionToDelete)
1498 {
1499 DeleteSceneObject(objectGroup);
1500 }
1501 }
1502 }
1503 }
1504
1505 void InventoryRunDeleteTimer(object sender, ElapsedEventArgs e)
1506 {
1507 m_log.Info("Starting inventory send loop");
1508 while (InventoryDeQueueAndDelete() == true)
1509 {
1510 m_log.Info("Returned item successfully, continuing...");
1511 }
1512 }
1513
1514 private bool InventoryDeQueueAndDelete()
1515 {
1516 DeleteToInventoryHolder x;
1517 try
1518 {
1519 lock (m_inventoryDeletes)
1520 {
1521 int left = m_inventoryDeletes.Count;
1522 if (left > 0)
1523 {
1524 m_log.InfoFormat("Sending deleted object to user's inventory, {0} item(s) remaining.", left);
1525 x = m_inventoryDeletes.Dequeue();
1526 DeleteToInventory(x.DeRezPacket, x.selectedEnt, x.remoteClient, x.objectGroup, x.folderID);
1527 return true;
1528 }
1529 }
1530 } catch(Exception e)
1531 {
1532 m_log.Error(e.ToString());
1533 }
1534
1535 m_log.Info("No objects left in inventory delete queue.");
1536 return false;
1537 }
1538
1539 private void DeleteToInventory(DeRezObjectPacket DeRezPacket, EntityBase selectedEnt, IClientAPI remoteClient, SceneObjectGroup objectGroup, LLUUID folderID)
1540 {
1541 string sceneObjectXml = objectGroup.ToXmlString();
1542
1543 CachedUserInfo userInfo =
1544 CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
1545 if (userInfo != null)
1546 {
1462// string searchFolder = ""; 1547// string searchFolder = "";
1463 1548
1464// if (DeRezPacket.AgentBlock.Destination == 6) 1549// if (DeRezPacket.AgentBlock.Destination == 6)
@@ -1466,103 +1551,98 @@ namespace OpenSim.Region.Environment.Scenes
1466// else if (DeRezPacket.AgentBlock.Destination == 9) 1551// else if (DeRezPacket.AgentBlock.Destination == 9)
1467// searchFolder = "Lost And Found"; 1552// searchFolder = "Lost And Found";
1468 1553
1469 // If we're deleting someone else's item, it goes back to their deleted items folder 1554 // If we're deleting someone else's item, it goes back to their deleted items folder
1470 // If we're returning someone's item, it goes back to the owner's Lost And Found folder. 1555 // If we're returning someone's item, it goes back to the owner's Lost And Found folder.
1471 1556
1472 if (DeRezPacket.AgentBlock.DestinationID == LLUUID.Zero || (DeRezPacket.AgentBlock.Destination == 6 && objectGroup.OwnerID != remoteClient.AgentId)) 1557 if (DeRezPacket.AgentBlock.DestinationID == LLUUID.Zero || (DeRezPacket.AgentBlock.Destination == 6 && objectGroup.OwnerID != remoteClient.AgentId))
1473 { 1558 {
1474 List<InventoryFolderBase> subrootfolders = userInfo.RootFolder.RequestListOfFolders(); 1559 List<InventoryFolderBase> subrootfolders = userInfo.RootFolder.RequestListOfFolders();
1475 foreach (InventoryFolderBase flder in subrootfolders) 1560 foreach (InventoryFolderBase flder in subrootfolders)
1476 { 1561 {
1477 if (flder.Name == "Lost And Found") 1562 if (flder.Name == "Lost And Found")
1478 { 1563 {
1479 folderID = flder.ID; 1564 folderID = flder.ID;
1480 break; 1565 break;
1481 } 1566 }
1482 } 1567 }
1483 1568
1484 if (folderID == LLUUID.Zero) 1569 if (folderID == LLUUID.Zero)
1485 { 1570 {
1486 folderID = userInfo.RootFolder.ID; 1571 folderID = userInfo.RootFolder.ID;
1487 } 1572 }
1488 //currently following code not used (or don't know of any case of destination being zero 1573 //currently following code not used (or don't know of any case of destination being zero
1489 } 1574 }
1490 else 1575 else
1491 { 1576 {
1492 folderID = DeRezPacket.AgentBlock.DestinationID; 1577 folderID = DeRezPacket.AgentBlock.DestinationID;
1493 } 1578 }
1494 1579
1495 AssetBase asset = CreateAsset( 1580 AssetBase asset = CreateAsset(
1496 ((SceneObjectGroup) selectedEnt).GetPartName(selectedEnt.LocalId), 1581 ((SceneObjectGroup) selectedEnt).GetPartName(selectedEnt.LocalId),
1497 ((SceneObjectGroup) selectedEnt).GetPartDescription(selectedEnt.LocalId), 1582 ((SceneObjectGroup) selectedEnt).GetPartDescription(selectedEnt.LocalId),
1498 (sbyte)AssetType.Object, 1583 (sbyte)AssetType.Object,
1499 Helpers.StringToField(sceneObjectXml)); 1584 Helpers.StringToField(sceneObjectXml));
1500 AssetCache.AddAsset(asset); 1585 AssetCache.AddAsset(asset);
1501
1502 InventoryItemBase item = new InventoryItemBase();
1503 item.Creator = objectGroup.RootPart.CreatorID;
1504
1505 if (DeRezPacket.AgentBlock.Destination == 1 || DeRezPacket.AgentBlock.Destination == 4)// Take / Copy
1506 item.Owner = remoteClient.AgentId;
1507 else // Delete / Return
1508 item.Owner = objectGroup.OwnerID;
1509
1510 item.ID = LLUUID.Random();
1511 item.AssetID = asset.FullID;
1512 item.Description = asset.Description;
1513 item.Name = asset.Name;
1514 item.AssetType = asset.Type;
1515 item.InvType = (int)InventoryType.Object;
1516 item.Folder = folderID;
1517 if ((remoteClient.AgentId != objectGroup.RootPart.OwnerID) && ExternalChecks.ExternalChecksPropagatePermissions())
1518 {
1519 uint perms=objectGroup.GetEffectivePermissions();
1520 uint nextPerms=(perms & 7) << 13;
1521 if ((nextPerms & (uint)PermissionMask.Copy) == 0)
1522 perms &= ~(uint)PermissionMask.Copy;
1523 if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
1524 perms &= ~(uint)PermissionMask.Transfer;
1525 if ((nextPerms & (uint)PermissionMask.Modify) == 0)
1526 perms &= ~(uint)PermissionMask.Modify;
1527
1528 item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask;
1529 item.CurrentPermissions = item.BasePermissions;
1530 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
1531 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask;
1532 item.CurrentPermissions |= 8; // Slam!
1533 }
1534 else
1535 {
1536 item.BasePermissions = objectGroup.GetEffectivePermissions();
1537 item.CurrentPermissions = objectGroup.GetEffectivePermissions();
1538 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
1539 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
1540 }
1541 1586
1542 // TODO: add the new fields (Flags, Sale info, etc) 1587 InventoryItemBase item = new InventoryItemBase();
1588 item.Creator = objectGroup.RootPart.CreatorID;
1543 1589
1544 userInfo.AddItem(item); 1590 if (DeRezPacket.AgentBlock.Destination == 1 || DeRezPacket.AgentBlock.Destination == 4)// Take / Copy
1545 if (item.Owner == remoteClient.AgentId) 1591 item.Owner = remoteClient.AgentId;
1546 { 1592 else // Delete / Return
1547 remoteClient.SendInventoryItemCreateUpdate(item); 1593 item.Owner = objectGroup.OwnerID;
1548 }
1549 else
1550 {
1551 ScenePresence notifyUser = GetScenePresence(item.Owner);
1552 if (notifyUser != null)
1553 {
1554 notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item);
1555 }
1556 }
1557 }
1558 }
1559 1594
1560 if (permissionToDelete) 1595 item.ID = LLUUID.Random();
1596 item.AssetID = asset.FullID;
1597 item.Description = asset.Description;
1598 item.Name = asset.Name;
1599 item.AssetType = asset.Type;
1600 item.InvType = (int)InventoryType.Object;
1601 item.Folder = folderID;
1602 if ((remoteClient.AgentId != objectGroup.RootPart.OwnerID) && ExternalChecks.ExternalChecksPropagatePermissions())
1603 {
1604 uint perms=objectGroup.GetEffectivePermissions();
1605 uint nextPerms=(perms & 7) << 13;
1606 if ((nextPerms & (uint)PermissionMask.Copy) == 0)
1607 perms &= ~(uint)PermissionMask.Copy;
1608 if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
1609 perms &= ~(uint)PermissionMask.Transfer;
1610 if ((nextPerms & (uint)PermissionMask.Modify) == 0)
1611 perms &= ~(uint)PermissionMask.Modify;
1612
1613 item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask;
1614 item.CurrentPermissions = item.BasePermissions;
1615 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
1616 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask;
1617 item.CurrentPermissions |= 8; // Slam!
1618 }
1619 else
1620 {
1621 item.BasePermissions = objectGroup.GetEffectivePermissions();
1622 item.CurrentPermissions = objectGroup.GetEffectivePermissions();
1623 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
1624 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
1625 }
1626
1627 // TODO: add the new fields (Flags, Sale info, etc)
1628
1629 userInfo.AddItem(item);
1630 if (item.Owner == remoteClient.AgentId)
1631 {
1632 remoteClient.SendInventoryItemCreateUpdate(item);
1633 }
1634 else
1635 {
1636 ScenePresence notifyUser = GetScenePresence(item.Owner);
1637 if (notifyUser != null)
1561 { 1638 {
1562 DeleteSceneObject(objectGroup); 1639 notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item);
1563 } 1640 }
1564 } 1641 }
1565 } 1642 }
1643
1644 // Finally remove the item, for reals this time.
1645 DeleteSceneObject(objectGroup);
1566 } 1646 }
1567 1647
1568 public void updateKnownAsset(IClientAPI remoteClient, SceneObjectGroup grp, LLUUID assetID, LLUUID agentID) 1648 public void updateKnownAsset(IClientAPI remoteClient, SceneObjectGroup grp, LLUUID assetID, LLUUID agentID)