aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Scenes
diff options
context:
space:
mode:
authorMelanie Thielker2008-10-18 05:51:36 +0000
committerMelanie Thielker2008-10-18 05:51:36 +0000
commitefe3f3eb2a0a31b1da474974c7d8193c2b28e13f (patch)
treedf1d30ad2f9230ea4e8fbfd1e6368d539600c785 /OpenSim/Region/Environment/Scenes
parent* Fix an over compensation for bounciness on flat Primitive (diff)
downloadopensim-SC_OLD-efe3f3eb2a0a31b1da474974c7d8193c2b28e13f.zip
opensim-SC_OLD-efe3f3eb2a0a31b1da474974c7d8193c2b28e13f.tar.gz
opensim-SC_OLD-efe3f3eb2a0a31b1da474974c7d8193c2b28e13f.tar.bz2
opensim-SC_OLD-efe3f3eb2a0a31b1da474974c7d8193c2b28e13f.tar.xz
Megapatch. :) Fix skull attachment editing. Streamline Object terse updates.
Add rezzing time to objects. Add Object return and traffic fields to land database. Add plumbing for auto return. Implement auto return. Contains a migration. May contain nuts.
Diffstat (limited to 'OpenSim/Region/Environment/Scenes')
-rw-r--r--OpenSim/Region/Environment/Scenes/AsyncSceneObjectGroupDeleter.cs17
-rw-r--r--OpenSim/Region/Environment/Scenes/ReturnInfo.cs38
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.Inventory.cs202
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.cs49
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs72
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectPart.cs118
-rw-r--r--OpenSim/Region/Environment/Scenes/ScenePresence.cs2
7 files changed, 312 insertions, 186 deletions
diff --git a/OpenSim/Region/Environment/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Environment/Scenes/AsyncSceneObjectGroupDeleter.cs
index 21fa71b..bd81a6d 100644
--- a/OpenSim/Region/Environment/Scenes/AsyncSceneObjectGroupDeleter.cs
+++ b/OpenSim/Region/Environment/Scenes/AsyncSceneObjectGroupDeleter.cs
@@ -38,8 +38,7 @@ namespace OpenSim.Region.Environment.Scenes
38{ 38{
39 class DeleteToInventoryHolder 39 class DeleteToInventoryHolder
40 { 40 {
41 public DeRezObjectPacket DeRezPacket; 41 public int destination;
42 public EntityBase selectedEnt;
43 public IClientAPI remoteClient; 42 public IClientAPI remoteClient;
44 public SceneObjectGroup objectGroup; 43 public SceneObjectGroup objectGroup;
45 public UUID folderID; 44 public UUID folderID;
@@ -70,20 +69,19 @@ namespace OpenSim.Region.Environment.Scenes
70 /// <summary> 69 /// <summary>
71 /// Delete the given object from the scene 70 /// Delete the given object from the scene
72 /// </summary> 71 /// </summary>
73 public void DeleteToInventory( 72 public void DeleteToInventory(int destination, UUID folderID,
74 DeRezObjectPacket DeRezPacket, UUID folderID, SceneObjectGroup objectGroup, IClientAPI remoteClient, 73 SceneObjectGroup objectGroup, IClientAPI remoteClient,
75 EntityBase selectedEnt, bool permissionToDelete) 74 bool permissionToDelete)
76 { 75 {
77 m_inventoryTicker.Stop(); 76 m_inventoryTicker.Stop();
78 77
79 lock (m_inventoryDeletes) 78 lock (m_inventoryDeletes)
80 { 79 {
81 DeleteToInventoryHolder dtis = new DeleteToInventoryHolder(); 80 DeleteToInventoryHolder dtis = new DeleteToInventoryHolder();
82 dtis.DeRezPacket = DeRezPacket; 81 dtis.destination = destination;
83 dtis.folderID = folderID; 82 dtis.folderID = folderID;
84 dtis.objectGroup = objectGroup; 83 dtis.objectGroup = objectGroup;
85 dtis.remoteClient = remoteClient; 84 dtis.remoteClient = remoteClient;
86 dtis.selectedEnt = selectedEnt;
87 dtis.permissionToDelete = permissionToDelete; 85 dtis.permissionToDelete = permissionToDelete;
88 86
89 m_inventoryDeletes.Enqueue(dtis); 87 m_inventoryDeletes.Enqueue(dtis);
@@ -121,8 +119,9 @@ namespace OpenSim.Region.Environment.Scenes
121 "[SCENE]: Sending deleted object to user's inventory, {0} item(s) remaining.", left); 119 "[SCENE]: Sending deleted object to user's inventory, {0} item(s) remaining.", left);
122 120
123 x = m_inventoryDeletes.Dequeue(); 121 x = m_inventoryDeletes.Dequeue();
124 m_scene.DeleteToInventory( 122 m_scene.DeleteToInventory(x.destination,
125 x.DeRezPacket, x.selectedEnt, x.remoteClient, x.objectGroup, x.folderID, x.permissionToDelete); 123 x.folderID, x.objectGroup, x.remoteClient,
124 x.permissionToDelete);
126 125
127 return true; 126 return true;
128 } 127 }
diff --git a/OpenSim/Region/Environment/Scenes/ReturnInfo.cs b/OpenSim/Region/Environment/Scenes/ReturnInfo.cs
new file mode 100644
index 0000000..68c563d
--- /dev/null
+++ b/OpenSim/Region/Environment/Scenes/ReturnInfo.cs
@@ -0,0 +1,38 @@
1/*
2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the OpenSim Project nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28using OpenMetaverse;
29
30namespace OpenSim.Region.Environment.Scenes
31{
32 public struct ReturnInfo
33 {
34 public int count;
35 public Vector3 location;
36 public string objectName;
37 }
38}
diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
index 226f39a..b91eb83 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
@@ -1517,78 +1517,90 @@ namespace OpenSim.Region.Environment.Scenes
1517 /// </summary> 1517 /// </summary>
1518 /// <param name="packet"></param> 1518 /// <param name="packet"></param>
1519 /// <param name="remoteClient"></param> 1519 /// <param name="remoteClient"></param>
1520 public virtual void DeRezObject(Packet packet, IClientAPI remoteClient) 1520 public virtual void DeRezObject(IClientAPI remoteClient, uint localID,
1521 UUID groupID, byte destination, UUID destinationID)
1521 { 1522 {
1522 DeRezObjectPacket DeRezPacket = (DeRezObjectPacket) packet; 1523 SceneObjectPart part = GetSceneObjectPart(localID);
1524 if (part == null)
1525 return;
1523 1526
1524 UUID folderID = UUID.Zero; 1527 if (part.ParentGroup == null || part.ParentGroup.RootPart == null)
1528 return;
1525 1529
1526 foreach (DeRezObjectPacket.ObjectDataBlock Data in DeRezPacket.ObjectData) 1530 // Can't delete child prims
1527 { 1531 if (part != part.ParentGroup.RootPart)
1528// m_log.DebugFormat( 1532 return;
1529// "[AGENT INVENTORY]: Received request to derez {0} into folder {1}", 1533
1530// Data.ObjectLocalID, DeRezPacket.AgentBlock.DestinationID); 1534 SceneObjectGroup grp = part.ParentGroup;
1535
1536 bool permissionToTake = false;
1537 bool permissionToDelete = false;
1531 1538
1532 EntityBase selectedEnt = null; 1539 if (destination == 1) // Take Copy
1533 //m_log.Info("[CLIENT]: LocalID:" + Data.ObjectLocalID.ToString()); 1540 {
1541 permissionToTake =
1542 ExternalChecks.ExternalChecksCanTakeCopyObject(
1543 grp.UUID,
1544 remoteClient.AgentId);
1545 }
1546 else if (destination == 5) // God take copy
1547 {
1548 permissionToTake =
1549 ExternalChecks.ExternalChecksCanBeGodLike(
1550 remoteClient.AgentId);
1551 }
1552 else if (destination == 4) // Take
1553 {
1554 permissionToTake =
1555 ExternalChecks.ExternalChecksCanTakeObject(
1556 grp.UUID,
1557 remoteClient.AgentId);
1534 1558
1535 List<EntityBase> EntityList = GetEntities(); 1559 //If they can take, they can delete!
1560 permissionToDelete = permissionToTake;
1561 }
1536 1562
1537 foreach (EntityBase ent in EntityList) 1563 else if (destination == 6) //Delete
1564 {
1565 permissionToTake =
1566 ExternalChecks.ExternalChecksCanDeleteObject(
1567 grp.UUID,
1568 remoteClient.AgentId);
1569 permissionToDelete =
1570 ExternalChecks.ExternalChecksCanDeleteObject(
1571 grp.UUID,
1572 remoteClient.AgentId);
1573 }
1574 else if (destination == 9) //Return
1575 {
1576 if (remoteClient != null)
1538 { 1577 {
1539 if (ent.LocalId == Data.ObjectLocalID) 1578 permissionToTake =
1540 { 1579 ExternalChecks.ExternalChecksCanDeleteObject(
1541 selectedEnt = ent; 1580 grp.UUID,
1542 break; 1581 remoteClient.AgentId);
1543 } 1582 permissionToDelete =
1583 ExternalChecks.ExternalChecksCanDeleteObject(
1584 grp.UUID,
1585 remoteClient.AgentId);
1544 } 1586 }
1545 if (selectedEnt != null) 1587 else // Auto return passes through here with null agent
1546 { 1588 {
1547 bool permissionToTake = false; 1589 permissionToTake = true;
1548 bool permissionToDelete = false; 1590 permissionToDelete = true;
1549 if (DeRezPacket.AgentBlock.Destination == 1)// Take Copy
1550 {
1551 permissionToTake = ExternalChecks.ExternalChecksCanTakeCopyObject(((SceneObjectGroup)selectedEnt).UUID, remoteClient.AgentId);
1552 permissionToDelete = false; //Just taking copy!
1553
1554 }
1555 else if (DeRezPacket.AgentBlock.Destination == 5) //God take copy
1556 {
1557 permissionToTake = ExternalChecks.ExternalChecksCanBeGodLike(remoteClient.AgentId);
1558 permissionToDelete = false; //Just taking copy!
1559
1560 }
1561 else if (DeRezPacket.AgentBlock.Destination == 4) //Take
1562 {
1563 // Take
1564 permissionToTake = ExternalChecks.ExternalChecksCanTakeObject(((SceneObjectGroup)selectedEnt).UUID, remoteClient.AgentId);
1565 permissionToDelete = permissionToTake; //If they can take, they can delete!
1566 }
1567
1568 else if (DeRezPacket.AgentBlock.Destination == 6) //Delete
1569 {
1570 permissionToTake = ExternalChecks.ExternalChecksCanDeleteObject(((SceneObjectGroup)selectedEnt).UUID, remoteClient.AgentId);
1571 permissionToDelete = ExternalChecks.ExternalChecksCanDeleteObject(((SceneObjectGroup)selectedEnt).UUID, remoteClient.AgentId);
1572 }
1573 else if (DeRezPacket.AgentBlock.Destination == 9) //Return
1574 {
1575 permissionToTake = ExternalChecks.ExternalChecksCanDeleteObject(((SceneObjectGroup)selectedEnt).UUID, remoteClient.AgentId);
1576 permissionToDelete = ExternalChecks.ExternalChecksCanDeleteObject(((SceneObjectGroup)selectedEnt).UUID, remoteClient.AgentId);
1577 }
1578
1579 SceneObjectGroup objectGroup = (SceneObjectGroup)selectedEnt;
1580
1581 if (permissionToTake)
1582 {
1583 m_asyncSceneObjectDeleter.DeleteToInventory(
1584 DeRezPacket, folderID, objectGroup, remoteClient, selectedEnt, permissionToDelete);
1585 }
1586 else if (permissionToDelete)
1587 {
1588 DeleteSceneObject(objectGroup);
1589 }
1590 } 1591 }
1591 } 1592 }
1593
1594 if (permissionToTake)
1595 {
1596 m_asyncSceneObjectDeleter.DeleteToInventory(
1597 destination, destinationID, grp, remoteClient,
1598 permissionToDelete);
1599 }
1600 else if (permissionToDelete)
1601 {
1602 DeleteSceneObject(grp);
1603 }
1592 } 1604 }
1593 1605
1594 /// <summary> 1606 /// <summary>
@@ -1600,51 +1612,50 @@ namespace OpenSim.Region.Environment.Scenes
1600 /// <param name="objectGroup"></param> 1612 /// <param name="objectGroup"></param>
1601 /// <param name="folderID"></param> 1613 /// <param name="folderID"></param>
1602 /// <param name="permissionToDelete"></param> 1614 /// <param name="permissionToDelete"></param>
1603 public void DeleteToInventory(DeRezObjectPacket DeRezPacket, EntityBase selectedEnt, IClientAPI remoteClient, 1615 public void DeleteToInventory(int destination, UUID folderID,
1604 SceneObjectGroup objectGroup, UUID folderID, bool permissionToDelete) 1616 SceneObjectGroup objectGroup, IClientAPI remoteClient,
1617 bool permissionToDelete)
1605 { 1618 {
1606 string sceneObjectXml = objectGroup.ToXmlString(); 1619 string sceneObjectXml = objectGroup.ToXmlString();
1607 1620
1608 CachedUserInfo userInfo = 1621 CachedUserInfo userInfo =
1609 CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); 1622 CommsManager.UserProfileCacheService.GetUserDetails(
1610 if (userInfo != null) 1623 remoteClient.AgentId);
1611 {
1612// string searchFolder = "";
1613 1624
1614// if (DeRezPacket.AgentBlock.Destination == 6) 1625 if (remoteClient == null)
1615// searchFolder = "Trash"; 1626 {
1616// else if (DeRezPacket.AgentBlock.Destination == 9) 1627 userInfo = CommsManager.UserProfileCacheService.GetUserDetails(
1617// searchFolder = "Lost And Found"; 1628 objectGroup.RootPart.OwnerID);
1629 }
1630 else
1631 {
1632 userInfo = CommsManager.UserProfileCacheService.GetUserDetails(
1633 remoteClient.AgentId);
1634 }
1618 1635
1619 // If we're deleting someone else's item, it goes back to their deleted items folder 1636 if (userInfo != null)
1620 // If we're returning someone's item, it goes back to the owner's Lost And Found folder. 1637 {
1638 // If we're deleting someone else's item, it goes back to
1639 // their deleted items folder
1640 // If we're returning someone's item, it goes back to the
1641 // owner's Lost And Found folder.
1621 1642
1622 if (DeRezPacket.AgentBlock.DestinationID == UUID.Zero || (DeRezPacket.AgentBlock.Destination == 6 && objectGroup.OwnerID != remoteClient.AgentId)) 1643 if (folderID == UUID.Zero || (destination == 6 &&
1644 objectGroup.OwnerID != remoteClient.AgentId))
1623 { 1645 {
1624 List<InventoryFolderBase> subrootfolders = userInfo.RootFolder.RequestListOfFolders(); 1646 InventoryFolderBase folder =
1625 foreach (InventoryFolderBase flder in subrootfolders) 1647 userInfo.FindFolderForType(
1626 { 1648 (int)AssetType.LostAndFoundFolder);
1627 if (flder.Name == "Lost And Found")
1628 {
1629 folderID = flder.ID;
1630 break;
1631 }
1632 }
1633 1649
1634 if (folderID == UUID.Zero) 1650 if (folder != null)
1635 { 1651 folderID = folder.ID;
1652 else
1636 folderID = userInfo.RootFolder.ID; 1653 folderID = userInfo.RootFolder.ID;
1637 }
1638 //currently following code not used (or don't know of any case of destination being zero
1639 }
1640 else
1641 {
1642 folderID = DeRezPacket.AgentBlock.DestinationID;
1643 } 1654 }
1644 1655
1645 AssetBase asset = CreateAsset( 1656 AssetBase asset = CreateAsset(
1646 ((SceneObjectGroup) selectedEnt).GetPartName(selectedEnt.LocalId), 1657 objectGroup.GetPartName(objectGroup.RootPart.LocalId),
1647 ((SceneObjectGroup) selectedEnt).GetPartDescription(selectedEnt.LocalId), 1658 objectGroup.GetPartDescription(objectGroup.RootPart.LocalId),
1648 (sbyte)AssetType.Object, 1659 (sbyte)AssetType.Object,
1649 Utils.StringToBytes(sceneObjectXml)); 1660 Utils.StringToBytes(sceneObjectXml));
1650 AssetCache.AddAsset(asset); 1661 AssetCache.AddAsset(asset);
@@ -1652,7 +1663,8 @@ namespace OpenSim.Region.Environment.Scenes
1652 InventoryItemBase item = new InventoryItemBase(); 1663 InventoryItemBase item = new InventoryItemBase();
1653 item.Creator = objectGroup.RootPart.CreatorID; 1664 item.Creator = objectGroup.RootPart.CreatorID;
1654 1665
1655 if (DeRezPacket.AgentBlock.Destination == 1 || DeRezPacket.AgentBlock.Destination == 4)// Take / Copy 1666 if (destination == 1 ||
1667 destination == 4)// Take / Copy
1656 item.Owner = remoteClient.AgentId; 1668 item.Owner = remoteClient.AgentId;
1657 else // Delete / Return 1669 else // Delete / Return
1658 item.Owner = objectGroup.OwnerID; 1670 item.Owner = objectGroup.OwnerID;
@@ -1720,7 +1732,7 @@ namespace OpenSim.Region.Environment.Scenes
1720 { 1732 {
1721 if (!grp.HasGroupChanged) 1733 if (!grp.HasGroupChanged)
1722 { 1734 {
1723 m_log.InfoFormat("[ATTACHMENT] Detaching {0} which is unchanged", grp.UUID.ToString()); 1735 m_log.InfoFormat("[ATTACHMENT] Save request for {0} which is unchanged", grp.UUID.ToString());
1724 return; 1736 return;
1725 } 1737 }
1726 m_log.InfoFormat("[ATTACHMENT] Updating asset for attachment {0}, attachpoint {1}", grp.UUID.ToString(), grp.GetAttachmentPoint()); 1738 m_log.InfoFormat("[ATTACHMENT] Updating asset for attachment {0}, attachpoint {1}", grp.UUID.ToString(), grp.GetAttachmentPoint());
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index 299d0da..139281d 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -96,6 +96,8 @@ namespace OpenSim.Region.Environment.Scenes
96 private int m_incrementsof15seconds = 0; 96 private int m_incrementsof15seconds = 0;
97 private volatile bool m_backingup = false; 97 private volatile bool m_backingup = false;
98 98
99 private Dictionary<UUID, ReturnInfo> m_returns = new Dictionary<UUID, ReturnInfo>();
100
99 protected string m_simulatorVersion = "OpenSimulator Server"; 101 protected string m_simulatorVersion = "OpenSimulator Server";
100 102
101 protected ModuleLoader m_moduleLoader; 103 protected ModuleLoader m_moduleLoader;
@@ -929,8 +931,54 @@ namespace OpenSim.Region.Environment.Scenes
929 /// <returns></returns> 931 /// <returns></returns>
930 public void Backup() 932 public void Backup()
931 { 933 {
934 m_returns.Clear();
935
932 EventManager.TriggerOnBackup(m_storageManager.DataStore); 936 EventManager.TriggerOnBackup(m_storageManager.DataStore);
933 m_backingup = false; 937 m_backingup = false;
938
939 foreach (KeyValuePair<UUID, ReturnInfo> ret in m_returns)
940 {
941 UUID transaction = UUID.Random();
942
943 GridInstantMessage msg = new GridInstantMessage();
944 msg.fromAgentID = new Guid(UUID.Zero.ToString()); // From server
945 msg.fromAgentSession = new Guid(transaction.ToString());
946 msg.toAgentID = new Guid(ret.Key.ToString());
947 msg.imSessionID = new Guid(transaction.ToString());
948 msg.timestamp = (uint)Util.UnixTimeSinceEpoch();
949 msg.fromAgentName = "Server";
950 msg.dialog = (byte)19; // Object msg
951 msg.fromGroup = false;
952 msg.offline = (byte)1;
953 msg.ParentEstateID = RegionInfo.EstateSettings.ParentEstateID;
954 msg.Position = Vector3.Zero;
955 msg.RegionID = RegionInfo.RegionID.Guid;
956 msg.binaryBucket = new byte[0];
957 if (ret.Value.count > 1)
958 msg.message = string.Format("Your {0} objects were returned from {1} in region {2} due to parcel auto return", ret.Value.count, ret.Value.location.ToString(), RegionInfo.RegionName);
959 else
960 msg.message = string.Format("Your object {0} was returned from {1} in region {2} due to parcel auto return", ret.Value.objectName, ret.Value.location.ToString(), RegionInfo.RegionName);
961
962 TriggerGridInstantMessage(msg, InstantMessageReceiver.IMModule);
963 }
964 }
965
966 public void AddReturn(UUID agentID, string objectName, Vector3 location)
967 {
968 if (m_returns.ContainsKey(agentID))
969 {
970 ReturnInfo info = m_returns[agentID];
971 info.count++;
972 m_returns[agentID] = info;
973 }
974 else
975 {
976 ReturnInfo info = new ReturnInfo();
977 info.count = 1;
978 info.objectName = objectName;
979 info.location = location;
980 m_returns[agentID] = info;
981 }
934 } 982 }
935 983
936 #endregion 984 #endregion
@@ -2254,6 +2302,7 @@ namespace OpenSim.Region.Environment.Scenes
2254 client.OnUndo += m_innerScene.HandleUndo; 2302 client.OnUndo += m_innerScene.HandleUndo;
2255 client.OnObjectGroupRequest += m_innerScene.HandleObjectGroupUpdate; 2303 client.OnObjectGroupRequest += m_innerScene.HandleObjectGroupUpdate;
2256 client.OnParcelReturnObjectsRequest += LandChannel.ReturnObjectsInParcel; 2304 client.OnParcelReturnObjectsRequest += LandChannel.ReturnObjectsInParcel;
2305 client.OnParcelSetOtherCleanTime += LandChannel.SetParcelOtherCleanTime;
2257 client.OnObjectSaleInfo += ObjectSaleInfo; 2306 client.OnObjectSaleInfo += ObjectSaleInfo;
2258 client.OnScriptReset += ProcessScriptReset; 2307 client.OnScriptReset += ProcessScriptReset;
2259 client.OnGetScriptRunning += GetScriptRunning; 2308 client.OnGetScriptRunning += GetScriptRunning;
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
index 8c5afab..60cf061 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
@@ -99,6 +99,8 @@ namespace OpenSim.Region.Environment.Scenes
99 private Vector3 lastPhysGroupPos; 99 private Vector3 lastPhysGroupPos;
100 private Quaternion lastPhysGroupRot; 100 private Quaternion lastPhysGroupRot;
101 101
102 private bool m_isBackedUp = false;
103
102 /// <summary> 104 /// <summary>
103 /// The constituent parts of this group 105 /// The constituent parts of this group
104 /// </summary> 106 /// </summary>
@@ -120,7 +122,11 @@ namespace OpenSim.Region.Environment.Scenes
120 /// </summary> 122 /// </summary>
121 public override string Name 123 public override string Name
122 { 124 {
123 get { return RootPart.Name; } 125 get {
126 if (RootPart == null)
127 return "";
128 return RootPart.Name;
129 }
124 set { RootPart.Name = value; } 130 set { RootPart.Name = value; }
125 } 131 }
126 132
@@ -544,7 +550,9 @@ namespace OpenSim.Region.Environment.Scenes
544 //m_log.DebugFormat( 550 //m_log.DebugFormat(
545 // "[SCENE OBJECT GROUP]: Attaching object {0} {1} to scene presistence sweep", Name, UUID); 551 // "[SCENE OBJECT GROUP]: Attaching object {0} {1} to scene presistence sweep", Name, UUID);
546 552
547 m_scene.EventManager.OnBackup += ProcessBackup; 553 if (!m_isBackedUp)
554 m_scene.EventManager.OnBackup += ProcessBackup;
555 m_isBackedUp = true;
548 } 556 }
549 } 557 }
550 558
@@ -786,6 +794,7 @@ namespace OpenSim.Region.Environment.Scenes
786 SetAttachmentPoint((byte)0); 794 SetAttachmentPoint((byte)0);
787 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_scene.m_physicalPrim); 795 m_rootPart.ApplyPhysics(m_rootPart.GetEffectiveObjectFlags(), m_scene.m_physicalPrim);
788 HasGroupChanged = true; 796 HasGroupChanged = true;
797 RootPart.Rezzed = DateTime.Now;
789 AttachToBackup(); 798 AttachToBackup();
790 m_scene.EventManager.TriggerParcelPrimCountTainted(); 799 m_scene.EventManager.TriggerParcelPrimCountTainted();
791 m_rootPart.ScheduleFullUpdate(); 800 m_rootPart.ScheduleFullUpdate();
@@ -1000,6 +1009,8 @@ namespace OpenSim.Region.Environment.Scenes
1000 // that they don't happen, otherwise the deleted objects will reappear 1009 // that they don't happen, otherwise the deleted objects will reappear
1001 m_isDeleted = true; 1010 m_isDeleted = true;
1002 1011
1012 DetachFromBackup();
1013
1003 foreach (SceneObjectPart part in m_parts.Values) 1014 foreach (SceneObjectPart part in m_parts.Values)
1004 { 1015 {
1005 List<ScenePresence> avatars = Scene.GetScenePresences(); 1016 List<ScenePresence> avatars = Scene.GetScenePresences();
@@ -1149,6 +1160,28 @@ namespace OpenSim.Region.Environment.Scenes
1149 // any exception propogate upwards. 1160 // any exception propogate upwards.
1150 try 1161 try
1151 { 1162 {
1163 ILandObject parcel = m_scene.LandChannel.GetLandObject(
1164 m_rootPart.GroupPosition.X, m_rootPart.GroupPosition.Y);
1165
1166 if (parcel.landData.OtherCleanTime != 0)
1167 {
1168 if (parcel.landData.OwnerID != OwnerID &&
1169 (parcel.landData.GroupID != GroupID ||
1170 parcel.landData.GroupID == UUID.Zero))
1171 {
1172 if ((DateTime.Now - RootPart.Rezzed).TotalMinutes >
1173 parcel.landData.OtherCleanTime)
1174 {
1175 m_log.InfoFormat("[SCENE] Returning object {0} due to parcel auto return", RootPart.UUID.ToString());
1176 m_scene.AddReturn(OwnerID, Name, AbsolutePosition);
1177 m_scene.DeRezObject(null, RootPart.LocalId,
1178 RootPart.GroupID, 9, UUID.Zero);
1179
1180 return;
1181 }
1182 }
1183 }
1184
1152 if (HasGroupChanged) 1185 if (HasGroupChanged)
1153 { 1186 {
1154 // don't backup while it's selected or you're asking for changes mid stream. 1187 // don't backup while it's selected or you're asking for changes mid stream.
@@ -1226,35 +1259,6 @@ namespace OpenSim.Region.Environment.Scenes
1226 } 1259 }
1227 } 1260 }
1228 1261
1229 /// <summary>
1230 /// Send a terse update to the client for the given part
1231 /// </summary>
1232 /// <param name="remoteClient"></param>
1233 /// <param name="part"></param>
1234 internal void SendPartTerseUpdate(IClientAPI remoteClient, SceneObjectPart part)
1235 {
1236 SceneObjectPart rootPart = m_rootPart;
1237
1238 // TODO: that could by caused by some race condition with attachments on sim-crossing
1239 if (rootPart == null) return;
1240
1241 if (rootPart.UUID == part.UUID)
1242 {
1243 if (rootPart.IsAttachment)
1244 {
1245 part.SendTerseUpdateToClient(remoteClient, rootPart.AttachedPos);
1246 }
1247 else
1248 {
1249 part.SendTerseUpdateToClient(remoteClient, AbsolutePosition);
1250 }
1251 }
1252 else
1253 {
1254 part.SendTerseUpdateToClient(remoteClient);
1255 }
1256 }
1257
1258 #endregion 1262 #endregion
1259 1263
1260 #region Copying 1264 #region Copying
@@ -1920,6 +1924,8 @@ namespace OpenSim.Region.Environment.Scenes
1920 if (sendEvents) 1924 if (sendEvents)
1921 linkPart.TriggerScriptChangedEvent(Changed.LINK); 1925 linkPart.TriggerScriptChangedEvent(Changed.LINK);
1922 1926
1927 linkPart.Rezzed = RootPart.Rezzed;
1928
1923 HasGroupChanged = true; 1929 HasGroupChanged = true;
1924 ScheduleGroupForFullUpdate(); 1930 ScheduleGroupForFullUpdate();
1925 } 1931 }
@@ -1937,7 +1943,9 @@ namespace OpenSim.Region.Environment.Scenes
1937 /// <param name="objectGroup"></param> 1943 /// <param name="objectGroup"></param>
1938 public void DetachFromBackup() 1944 public void DetachFromBackup()
1939 { 1945 {
1940 m_scene.EventManager.OnBackup -= ProcessBackup; 1946 if (m_isBackedUp)
1947 m_scene.EventManager.OnBackup -= ProcessBackup;
1948 m_isBackedUp = false;
1941 } 1949 }
1942 1950
1943 private void LinkNonRootPart(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation) 1951 private void LinkNonRootPart(SceneObjectPart part, Vector3 oldGroupPosition, Quaternion oldGroupRotation)
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
index bf6025e..6c76d54 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
@@ -212,6 +212,7 @@ namespace OpenSim.Region.Environment.Scenes
212 // It's not necessary to persist this 212 // It's not necessary to persist this
213 m_TextureAnimation = new byte[0]; 213 m_TextureAnimation = new byte[0];
214 m_particleSystem = new byte[0]; 214 m_particleSystem = new byte[0];
215 Rezzed = DateTime.Now;
215 } 216 }
216 217
217 public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, UUID ownerID, uint localID, 218 public SceneObjectPart(ulong regionHandle, SceneObjectGroup parent, UUID ownerID, uint localID,
@@ -237,6 +238,7 @@ namespace OpenSim.Region.Environment.Scenes
237 m_regionHandle = regionHandle; 238 m_regionHandle = regionHandle;
238 m_parentGroup = parent; 239 m_parentGroup = parent;
239 240
241 Rezzed = DateTime.Now;
240 _creationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds; 242 _creationDate = (Int32) (DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
241 _ownerID = ownerID; 243 _ownerID = ownerID;
242 _creatorID = _ownerID; 244 _creatorID = _ownerID;
@@ -311,6 +313,8 @@ namespace OpenSim.Region.Environment.Scenes
311 RotationOffset = rotation; 313 RotationOffset = rotation;
312 ObjectFlags = flags; 314 ObjectFlags = flags;
313 315
316 Rezzed = DateTime.Now;
317
314 m_TextureAnimation = new byte[0]; 318 m_TextureAnimation = new byte[0];
315 m_particleSystem = new byte[0]; 319 m_particleSystem = new byte[0];
316 // Since we don't store script state, this is only a 'temporary' objectflag now 320 // Since we don't store script state, this is only a 'temporary' objectflag now
@@ -339,6 +343,7 @@ namespace OpenSim.Region.Environment.Scenes
339 */ 343 */
340 344
341 //System.Console.WriteLine("SceneObjectPart Deserialize END"); 345 //System.Console.WriteLine("SceneObjectPart Deserialize END");
346 Rezzed = DateTime.Now;
342 } 347 }
343 348
344 #endregion Constructors 349 #endregion Constructors
@@ -362,6 +367,7 @@ namespace OpenSim.Region.Environment.Scenes
362 private uint _nextOwnerMask = (uint)PermissionMask.All; 367 private uint _nextOwnerMask = (uint)PermissionMask.All;
363 private PrimFlags _flags = 0; 368 private PrimFlags _flags = 0;
364 private DateTime m_expires; 369 private DateTime m_expires;
370 private DateTime m_rezzed;
365 371
366 public UUID CreatorID { 372 public UUID CreatorID {
367 get 373 get
@@ -459,6 +465,13 @@ namespace OpenSim.Region.Environment.Scenes
459 set { m_expires = value; } 465 set { m_expires = value; }
460 } 466 }
461 467
468 [XmlIgnore]
469 public DateTime Rezzed
470 {
471 get { return m_rezzed; }
472 set { m_rezzed = value; }
473 }
474
462 /// <summary> 475 /// <summary>
463 /// The position of the entire group that this prim belongs to. 476 /// The position of the entire group that this prim belongs to.
464 /// </summary> 477 /// </summary>
@@ -1270,6 +1283,7 @@ if (m_shape != null) {
1270 dupe._objectSaleType = _objectSaleType; 1283 dupe._objectSaleType = _objectSaleType;
1271 dupe._salePrice = _salePrice; 1284 dupe._salePrice = _salePrice;
1272 dupe._category = _category; 1285 dupe._category = _category;
1286 dupe.m_rezzed = m_rezzed;
1273 1287
1274 dupe.TaskInventory = (TaskInventoryDictionary)dupe.TaskInventory.Clone(); 1288 dupe.TaskInventory = (TaskInventoryDictionary)dupe.TaskInventory.Clone();
1275 1289
@@ -2226,10 +2240,10 @@ if (m_shape != null) {
2226 /// Send a terse update to the client. 2240 /// Send a terse update to the client.
2227 /// </summary> 2241 /// </summary>
2228 /// <param name="remoteClient"></param> 2242 /// <param name="remoteClient"></param>
2229 public void SendTerseUpdate(IClientAPI remoteClient) 2243// public void SendTerseUpdate(IClientAPI remoteClient)
2230 { 2244// {
2231 m_parentGroup.SendPartTerseUpdate(remoteClient, this); 2245// SendTerseUpdateToClient(remoteClient);
2232 } 2246// }
2233 2247
2234 /// <summary> 2248 /// <summary>
2235 /// 2249 ///
@@ -2239,54 +2253,14 @@ if (m_shape != null) {
2239 List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences(); 2253 List<ScenePresence> avatars = m_parentGroup.Scene.GetScenePresences();
2240 for (int i = 0; i < avatars.Count; i++) 2254 for (int i = 0; i < avatars.Count; i++)
2241 { 2255 {
2242 m_parentGroup.SendPartTerseUpdate(avatars[i].ControllingClient, this); 2256 SendTerseUpdateToClient(avatars[i].ControllingClient);
2243 }
2244 }
2245
2246 public void SendTerseUpdateToClient(IClientAPI remoteClient)
2247 {
2248 Vector3 lPos;
2249 lPos = OffsetPosition;
2250 Quaternion mRot = RotationOffset;
2251 // TODO: I have no idea why we are making this check. This should be sorted out
2252 if ((ObjectFlags & (uint) PrimFlags.Physics) == 0)
2253 {
2254 remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity, RotationalVelocity, Shape.State, FromAssetID);
2255 }
2256 else
2257 {
2258 remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity,
2259 RotationalVelocity);
2260 //System.Console.WriteLine("LID: " + LocalID + " RVel:" + RotationalVelocity.ToString() + " TD: " + ((ushort)(m_parentGroup.Scene.TimeDilation * 500000f)).ToString() + ":" + m_parentGroup.Scene.TimeDilation.ToString());
2261 } 2257 }
2262 } 2258 }
2263 2259
2264 public void SendTerseUpdateToClient(IClientAPI remoteClient, Vector3 lPos) 2260// public void SendTerseUpdateToClient(IClientAPI remoteClient, Vector3 lPos)
2265 { 2261// {
2266 Quaternion mRot = RotationOffset; 2262// SendTerseUpdateToClient(remoteclient);
2267 //bool isattachment = IsAttachment; 2263// }
2268 //if (LocalId != ParentGroup.RootPart.LocalId)
2269 //isattachment = ParentGroup.RootPart.IsAttachment;
2270
2271 if (IsAttachment)
2272 {
2273 //m_log.Debug(AttachmentPoint.ToString());
2274 remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity, RotationalVelocity, (byte)((AttachmentPoint % 16) * 16 + (AttachmentPoint / 16)),FromAssetID);
2275 }
2276 else
2277 {
2278 if ((ObjectFlags & (uint)PrimFlags.Physics) == 0)
2279 {
2280 remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity, RotationalVelocity, Shape.State, FromAssetID);
2281 }
2282 else
2283 {
2284 remoteClient.SendPrimTerseUpdate(m_regionHandle, (ushort)(m_parentGroup.GetTimeDilation() * (float)ushort.MaxValue), LocalId, lPos, mRot, Velocity,
2285 RotationalVelocity);
2286 //System.Console.WriteLine("LID: " + LocalID + "RVel:" + RotationalVelocity.ToString() + " TD: " + ((ushort)(m_parentGroup.Scene.TimeDilation * 500000f)).ToString() + ":" + m_parentGroup.Scene.TimeDilation.ToString());
2287 }
2288 }
2289 }
2290 2264
2291 public void SetAttachmentPoint(uint AttachmentPoint) 2265 public void SetAttachmentPoint(uint AttachmentPoint)
2292 { 2266 {
@@ -3257,6 +3231,15 @@ if (m_shape != null) {
3257 PhysActor.Shape = m_shape; 3231 PhysActor.Shape = m_shape;
3258 } 3232 }
3259 3233
3234 // This is what makes vehicle trailers work
3235 // A script in a child prim re-issues
3236 // llSetPrimitiveParams(PRIM_TYPE) every few seconds. That
3237 // prevents autoreturn. This is not well known. It also works
3238 // in SL.
3239 //
3240 if (ParentGroup.RootPart != this)
3241 ParentGroup.RootPart.Rezzed = DateTime.Now;
3242
3260 ParentGroup.HasGroupChanged = true; 3243 ParentGroup.HasGroupChanged = true;
3261 ScheduleFullUpdate(); 3244 ScheduleFullUpdate();
3262 } 3245 }
@@ -3427,5 +3410,42 @@ if (m_shape != null) {
3427 } 3410 }
3428 3411
3429 #endregion Public Methods 3412 #endregion Public Methods
3413
3414 private byte GetAttachPointEncoded()
3415 {
3416 return (byte)((AttachmentPoint % 16) * 16 + (AttachmentPoint / 16));
3417 }
3418
3419 public void SendTerseUpdateToClient(IClientAPI remoteClient)
3420 {
3421 if (ParentGroup == null || ParentGroup.RootPart == null)
3422 return;
3423
3424 Vector3 lPos = OffsetPosition;
3425
3426 byte state = Shape.State;
3427 if (IsAttachment)
3428 {
3429 if (ParentGroup.RootPart != this)
3430 return;
3431
3432 lPos = ParentGroup.RootPart.AttachedPos;
3433 state = GetAttachPointEncoded();
3434 }
3435 else
3436 {
3437 if (ParentGroup.RootPart == this)
3438 lPos = AbsolutePosition;
3439 }
3440
3441 remoteClient.SendPrimTerseUpdate(m_regionHandle,
3442 (ushort)(m_parentGroup.GetTimeDilation() *
3443 (float)ushort.MaxValue), LocalId, lPos,
3444 RotationOffset, Velocity,
3445 RotationalVelocity, state, FromAssetID);
3446 }
3430 } 3447 }
3431} 3448}
3449
3450
3451
diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs
index 0fe2bdb..4517d11 100644
--- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs
@@ -640,7 +640,7 @@ namespace OpenSim.Region.Environment.Scenes
640// "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}", 640// "[SCENE PRESENCE]: Tersely updating prim {0}, {1} - part timestamp {2}",
641// part.Name, part.UUID, part.TimeStampTerse); 641// part.Name, part.UUID, part.TimeStampTerse);
642 642
643 part.SendTerseUpdate(ControllingClient); 643 part.SendTerseUpdateToClient(ControllingClient);
644 644
645 update.LastTerseUpdateTime = part.TimeStampTerse; 645 update.LastTerseUpdateTime = part.TimeStampTerse;
646 updateCount++; 646 updateCount++;