aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region
diff options
context:
space:
mode:
authorJustin Clarke Casey2008-12-17 16:11:03 +0000
committerJustin Clarke Casey2008-12-17 16:11:03 +0000
commitb4680f653dbc1c6f712898af79c4ea22bca3f678 (patch)
tree8482ca109db6d7e4b51221f0631c483a4a2d0fef /OpenSim/Region
parent* Adding some locks to XEngine's m_PrimObjects which were prone to 'the colle... (diff)
downloadopensim-SC-b4680f653dbc1c6f712898af79c4ea22bca3f678.zip
opensim-SC-b4680f653dbc1c6f712898af79c4ea22bca3f678.tar.gz
opensim-SC-b4680f653dbc1c6f712898af79c4ea22bca3f678.tar.bz2
opensim-SC-b4680f653dbc1c6f712898af79c4ea22bca3f678.tar.xz
* Implement 'Save Object Back to My Inventory'. On the Linden client this is in the Tools menu available when editing an object
* This facility allows you to save changes to an object that you've rezzed into a region back into their original inventory item without having to take a copy of the rezzed object.
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs2
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs17
-rw-r--r--OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs2
-rw-r--r--OpenSim/Region/Environment/Scenes/AsyncSceneObjectGroupDeleter.cs10
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.Inventory.cs170
-rw-r--r--OpenSim/Region/Environment/Scenes/Scene.cs9
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs13
-rw-r--r--OpenSim/Region/Environment/Scenes/SceneObjectPart.cs49
8 files changed, 186 insertions, 86 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 9fb3c55..e34c8ec 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -7286,7 +7286,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
7286 } 7286 }
7287 7287
7288 public void SendAgentOnline(UUID[] agentIDs) 7288 public void SendAgentOnline(UUID[] agentIDs)
7289 { 7289 {
7290 OnlineNotificationPacket onp = new OnlineNotificationPacket(); 7290 OnlineNotificationPacket onp = new OnlineNotificationPacket();
7291 OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[agentIDs.Length]; 7291 OnlineNotificationPacket.AgentBlockBlock[] onpb = new OnlineNotificationPacket.AgentBlockBlock[agentIDs.Length];
7292 for (int i = 0; i < agentIDs.Length; i++) 7292 for (int i = 0; i < agentIDs.Length; i++)
diff --git a/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs b/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs
index 5bdf32c..e4ed9fa 100644
--- a/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/Friends/FriendsModule.cs
@@ -124,6 +124,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Friends
124 if (!m_scenes.ContainsKey(scene.RegionInfo.RegionHandle)) 124 if (!m_scenes.ContainsKey(scene.RegionInfo.RegionHandle))
125 m_scenes[scene.RegionInfo.RegionHandle] = scene; 125 m_scenes[scene.RegionInfo.RegionHandle] = scene;
126 } 126 }
127
127 scene.EventManager.OnNewClient += OnNewClient; 128 scene.EventManager.OnNewClient += OnNewClient;
128 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage; 129 scene.EventManager.OnIncomingInstantMessage += OnGridInstantMessage;
129 scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel; 130 scene.EventManager.OnAvatarEnteringNewParcel += AvatarEnteringParcel;
@@ -157,6 +158,11 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Friends
157 158
158 #endregion 159 #endregion
159 160
161 /// <summary>
162 /// Receive presence information changes about clients in other regions.
163 /// </summary>
164 /// <param name="req"></param>
165 /// <returns></returns>
160 public XmlRpcResponse processPresenceUpdateBulk(XmlRpcRequest req) 166 public XmlRpcResponse processPresenceUpdateBulk(XmlRpcRequest req)
161 { 167 {
162 Hashtable requestData = (Hashtable)req.Params[0]; 168 Hashtable requestData = (Hashtable)req.Params[0];
@@ -171,6 +177,7 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Friends
171 lock (m_rootAgents) 177 lock (m_rootAgents)
172 { 178 {
173 List<ScenePresence> friendsHere = new List<ScenePresence>(); 179 List<ScenePresence> friendsHere = new List<ScenePresence>();
180
174 try 181 try
175 { 182 {
176 UUID agentID = new UUID((string)requestData["agentID"]); 183 UUID agentID = new UUID((string)requestData["agentID"]);
@@ -728,6 +735,12 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Friends
728 if (destAgent != null) destAgent.ControllingClient.SendDeclineCallingCard(transactionID); 735 if (destAgent != null) destAgent.ControllingClient.SendDeclineCallingCard(transactionID);
729 } 736 }
730 737
738 /// <summary>
739 /// Send presence information about a client to other clients in both this region and others.
740 /// </summary>
741 /// <param name="client"></param>
742 /// <param name="friendList"></param>
743 /// <param name="iAmOnline"></param>
731 private void SendPresenceState(IClientAPI client, List<FriendListItem> friendList, bool iAmOnline) 744 private void SendPresenceState(IClientAPI client, List<FriendListItem> friendList, bool iAmOnline)
732 { 745 {
733 m_log.DebugFormat("[FRIEND]: {0} logged {1}; sending presence updates", client.Name, iAmOnline ? "in" : "out"); 746 m_log.DebugFormat("[FRIEND]: {0} logged {1}; sending presence updates", client.Name, iAmOnline ? "in" : "out");
@@ -756,8 +769,6 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Friends
756 } 769 }
757 } 770 }
758 771
759
760
761 // we now have a list of "interesting" friends (which we have to find out on-/offline state for), 772 // we now have a list of "interesting" friends (which we have to find out on-/offline state for),
762 // friends we want to send our online state to (if *they* are online, too), and 773 // friends we want to send our online state to (if *they* are online, too), and
763 // friends we want to receive online state for (currently unknown whether online or not) 774 // friends we want to receive online state for (currently unknown whether online or not)
@@ -799,8 +810,10 @@ namespace OpenSim.Region.Environment.Modules.Avatar.Friends
799 friendIDsToReceiveFromOnline.Add(uuid); 810 friendIDsToReceiveFromOnline.Add(uuid);
800 } 811 }
801 } 812 }
813
802 m_log.DebugFormat("[FRIEND]: Sending {0} offline and {1} online friends to {2}", 814 m_log.DebugFormat("[FRIEND]: Sending {0} offline and {1} online friends to {2}",
803 friendIDsToReceiveFromOffline.Count, friendIDsToReceiveFromOnline.Count, client.Name); 815 friendIDsToReceiveFromOffline.Count, friendIDsToReceiveFromOnline.Count, client.Name);
816
804 if (friendIDsToReceiveFromOffline.Count > 0) client.SendAgentOffline(friendIDsToReceiveFromOffline.ToArray()); 817 if (friendIDsToReceiveFromOffline.Count > 0) client.SendAgentOffline(friendIDsToReceiveFromOffline.ToArray());
805 if (friendIDsToReceiveFromOnline.Count > 0) client.SendAgentOnline(friendIDsToReceiveFromOnline.ToArray()); 818 if (friendIDsToReceiveFromOnline.Count > 0) client.SendAgentOnline(friendIDsToReceiveFromOnline.ToArray());
806 819
diff --git a/OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs b/OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs
index e2ca975..36f5965 100644
--- a/OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs
+++ b/OpenSim/Region/Environment/Modules/World/Permissions/PermissionsModule.cs
@@ -1106,7 +1106,6 @@ namespace OpenSim.Region.Environment.Modules.World.Permissions
1106 // the administrator object permissions to take effect. 1106 // the administrator object permissions to take effect.
1107 // UUID objectOwner = task.OwnerID; 1107 // UUID objectOwner = task.OwnerID;
1108 1108
1109
1110 if ((task.RootPart.EveryoneMask & PERM_COPY) != 0) 1109 if ((task.RootPart.EveryoneMask & PERM_COPY) != 0)
1111 permission = true; 1110 permission = true;
1112 1111
@@ -1120,6 +1119,7 @@ namespace OpenSim.Region.Environment.Modules.World.Permissions
1120 if ((task.GetEffectivePermissions() & PERM_COPY) == 0) 1119 if ((task.GetEffectivePermissions() & PERM_COPY) == 0)
1121 permission = false; 1120 permission = false;
1122 } 1121 }
1122
1123 return permission; 1123 return permission;
1124 } 1124 }
1125 1125
diff --git a/OpenSim/Region/Environment/Scenes/AsyncSceneObjectGroupDeleter.cs b/OpenSim/Region/Environment/Scenes/AsyncSceneObjectGroupDeleter.cs
index 03b3977..1429452 100644
--- a/OpenSim/Region/Environment/Scenes/AsyncSceneObjectGroupDeleter.cs
+++ b/OpenSim/Region/Environment/Scenes/AsyncSceneObjectGroupDeleter.cs
@@ -110,7 +110,7 @@ namespace OpenSim.Region.Environment.Scenes
110 110
111 while (InventoryDeQueueAndDelete()) 111 while (InventoryDeQueueAndDelete())
112 { 112 {
113 m_log.Debug("[SCENE]: Returned item successfully to inventory, continuing..."); 113 m_log.Debug("[SCENE]: Sent item successfully to inventory, continuing...");
114 } 114 }
115 } 115 }
116 116
@@ -130,7 +130,7 @@ namespace OpenSim.Region.Environment.Scenes
130 if (left > 0) 130 if (left > 0)
131 { 131 {
132 m_log.DebugFormat( 132 m_log.DebugFormat(
133 "[SCENE]: Sending deleted object to user's inventory, {0} item(s) remaining.", left); 133 "[SCENE]: Sending object to user's inventory, {0} item(s) remaining.", left);
134 134
135 x = m_inventoryDeletes.Dequeue(); 135 x = m_inventoryDeletes.Dequeue();
136 136
@@ -142,7 +142,7 @@ namespace OpenSim.Region.Environment.Scenes
142 } 142 }
143 catch (Exception e) 143 catch (Exception e)
144 { 144 {
145 m_log.DebugFormat("Exception background deleting object: " + e); 145 m_log.DebugFormat("Exception background sending object: " + e);
146 } 146 }
147 147
148 return true; 148 return true;
@@ -154,11 +154,11 @@ namespace OpenSim.Region.Environment.Scenes
154 // We can't put the object group details in here since the root part may have disappeared (which is where these sit). 154 // We can't put the object group details in here since the root part may have disappeared (which is where these sit).
155 // FIXME: This needs to be fixed. 155 // FIXME: This needs to be fixed.
156 m_log.ErrorFormat( 156 m_log.ErrorFormat(
157 "[SCENE]: Queued deletion of scene object to agent {0} {1} failed: {2}", 157 "[SCENE]: Queued sending of scene object to agent {0} {1} failed: {2}",
158 (x != null ? x.remoteClient.Name : "unavailable"), (x != null ? x.remoteClient.AgentId.ToString() : "unavailable"), e.ToString()); 158 (x != null ? x.remoteClient.Name : "unavailable"), (x != null ? x.remoteClient.AgentId.ToString() : "unavailable"), e.ToString());
159 } 159 }
160 160
161 m_log.Debug("[SCENE]: No objects left in inventory delete queue."); 161 m_log.Debug("[SCENE]: No objects left in inventory send queue.");
162 return false; 162 return false;
163 } 163 }
164 } 164 }
diff --git a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
index 7c518c4..c1decaa 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.Inventory.cs
@@ -1686,7 +1686,15 @@ namespace OpenSim.Region.Environment.Scenes
1686 bool permissionToTake = false; 1686 bool permissionToTake = false;
1687 bool permissionToDelete = false; 1687 bool permissionToDelete = false;
1688 1688
1689 if (action == DeRezAction.TakeCopy) 1689 if (action == DeRezAction.SaveToExistingUserInventoryItem)
1690 {
1691 if (grp.OwnerID == remoteClient.AgentId && grp.RootPart.FromUserInventoryItemID != UUID.Zero)
1692 {
1693 permissionToTake = true;
1694 permissionToDelete = false;
1695 }
1696 }
1697 else if (action == DeRezAction.TakeCopy)
1690 { 1698 {
1691 permissionToTake = 1699 permissionToTake =
1692 Permissions.CanTakeCopyObject( 1700 Permissions.CanTakeCopyObject(
@@ -1726,6 +1734,7 @@ namespace OpenSim.Region.Environment.Scenes
1726 grp.UUID, 1734 grp.UUID,
1727 remoteClient.AgentId); 1735 remoteClient.AgentId);
1728 permissionToDelete = permissionToTake; 1736 permissionToDelete = permissionToTake;
1737
1729 if (permissionToDelete) 1738 if (permissionToDelete)
1730 { 1739 {
1731 AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return"); 1740 AddReturn(grp.OwnerID, grp.Name, grp.AbsolutePosition, "parcel owner return");
@@ -1737,6 +1746,12 @@ namespace OpenSim.Region.Environment.Scenes
1737 permissionToDelete = true; 1746 permissionToDelete = true;
1738 } 1747 }
1739 } 1748 }
1749 else
1750 {
1751 m_log.DebugFormat(
1752 "[AGENT INVENTORY]: Ignoring unexpected derez action {0} for {1}", action, remoteClient.Name);
1753 return;
1754 }
1740 1755
1741 if (permissionToTake) 1756 if (permissionToTake)
1742 { 1757 {
@@ -1769,13 +1784,11 @@ namespace OpenSim.Region.Environment.Scenes
1769 1784
1770 if (remoteClient == null) 1785 if (remoteClient == null)
1771 { 1786 {
1772 userInfo = CommsManager.UserProfileCacheService.GetUserDetails( 1787 userInfo = CommsManager.UserProfileCacheService.GetUserDetails(objectGroup.RootPart.OwnerID);
1773 objectGroup.RootPart.OwnerID);
1774 } 1788 }
1775 else 1789 else
1776 { 1790 {
1777 userInfo = CommsManager.UserProfileCacheService.GetUserDetails( 1791 userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
1778 remoteClient.AgentId);
1779 } 1792 }
1780 1793
1781 if (userInfo != null) 1794 if (userInfo != null)
@@ -1785,8 +1798,8 @@ namespace OpenSim.Region.Environment.Scenes
1785 // If we're returning someone's item, it goes back to the 1798 // If we're returning someone's item, it goes back to the
1786 // owner's Lost And Found folder. 1799 // owner's Lost And Found folder.
1787 1800
1788 if (folderID == UUID.Zero || (action == DeRezAction.Delete && 1801 if (folderID == UUID.Zero
1789 objectGroup.OwnerID != remoteClient.AgentId)) 1802 || (action == DeRezAction.Delete && objectGroup.OwnerID != remoteClient.AgentId))
1790 { 1803 {
1791 InventoryFolderBase folder = 1804 InventoryFolderBase folder =
1792 userInfo.FindFolderForType( 1805 userInfo.FindFolderForType(
@@ -1811,6 +1824,21 @@ namespace OpenSim.Region.Environment.Scenes
1811 } 1824 }
1812 } 1825 }
1813 1826
1827 InventoryItemBase item = null;
1828
1829 if (DeRezAction.SaveToExistingUserInventoryItem == action)
1830 {
1831 item = userInfo.RootFolder.FindItem(objectGroup.RootPart.FromUserInventoryItemID);
1832
1833 if (null == item)
1834 {
1835 m_log.DebugFormat(
1836 "[AGENT INVENTORY]: Object {0} {1} scheduled for save to inventory has already been deleted.",
1837 objectGroup.Name, objectGroup.UUID);
1838 return UUID.Zero;
1839 }
1840 }
1841
1814 AssetBase asset = CreateAsset( 1842 AssetBase asset = CreateAsset(
1815 objectGroup.GetPartName(objectGroup.RootPart.LocalId), 1843 objectGroup.GetPartName(objectGroup.RootPart.LocalId),
1816 objectGroup.GetPartDescription(objectGroup.RootPart.LocalId), 1844 objectGroup.GetPartDescription(objectGroup.RootPart.LocalId),
@@ -1818,65 +1846,74 @@ namespace OpenSim.Region.Environment.Scenes
1818 Utils.StringToBytes(sceneObjectXml)); 1846 Utils.StringToBytes(sceneObjectXml));
1819 AssetCache.AddAsset(asset); 1847 AssetCache.AddAsset(asset);
1820 assetID = asset.FullID; 1848 assetID = asset.FullID;
1821
1822 InventoryItemBase item = new InventoryItemBase();
1823 item.Creator = objectGroup.RootPart.CreatorID;
1824
1825 if (action == DeRezAction.TakeCopy || action == DeRezAction.Take)
1826 item.Owner = remoteClient.AgentId;
1827 else // Delete / Return
1828 item.Owner = objectGroup.OwnerID;
1829
1830 item.ID = UUID.Random();
1831 item.AssetID = asset.FullID;
1832 item.Description = asset.Description;
1833 item.Name = asset.Name;
1834 item.AssetType = asset.Type;
1835 item.InvType = (int)InventoryType.Object;
1836 item.Folder = folderID;
1837 1849
1838 if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && Permissions.PropagatePermissions()) 1850 if (DeRezAction.SaveToExistingUserInventoryItem == action)
1839 { 1851 {
1840 uint perms=objectGroup.GetEffectivePermissions(); 1852 item.AssetID = asset.FullID;
1841 uint nextPerms=(perms & 7) << 13; 1853 userInfo.UpdateItem(item);
1842 if ((nextPerms & (uint)PermissionMask.Copy) == 0)
1843 perms &= ~(uint)PermissionMask.Copy;
1844 if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
1845 perms &= ~(uint)PermissionMask.Transfer;
1846 if ((nextPerms & (uint)PermissionMask.Modify) == 0)
1847 perms &= ~(uint)PermissionMask.Modify;
1848
1849 item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask;
1850 item.CurrentPermissions = item.BasePermissions;
1851 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
1852 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask;
1853 item.GroupPermissions = objectGroup.RootPart.GroupMask & objectGroup.RootPart.NextOwnerMask;
1854 item.CurrentPermissions |= 8; // Slam!
1855 } 1854 }
1856 else 1855 else
1857 { 1856 {
1858 item.BasePermissions = objectGroup.GetEffectivePermissions(); 1857 item = new InventoryItemBase();
1859 item.CurrentPermissions = objectGroup.GetEffectivePermissions(); 1858 item.Creator = objectGroup.RootPart.CreatorID;
1860 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
1861 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
1862 item.GroupPermissions = objectGroup.RootPart.GroupMask;
1863 }
1864 1859
1865 // TODO: add the new fields (Flags, Sale info, etc) 1860 if (action == DeRezAction.TakeCopy || action == DeRezAction.Take)
1866 item.CreationDate = Util.UnixTimeSinceEpoch(); 1861 item.Owner = remoteClient.AgentId;
1862 else // Delete / Return
1863 item.Owner = objectGroup.OwnerID;
1867 1864
1868 userInfo.AddItem(item); 1865 item.ID = UUID.Random();
1869 if (remoteClient != null && item.Owner == remoteClient.AgentId) 1866 item.AssetID = asset.FullID;
1870 { 1867 item.Description = asset.Description;
1871 remoteClient.SendInventoryItemCreateUpdate(item); 1868 item.Name = asset.Name;
1872 } 1869 item.AssetType = asset.Type;
1873 else 1870 item.InvType = (int)InventoryType.Object;
1874 { 1871 item.Folder = folderID;
1875 ScenePresence notifyUser = GetScenePresence(item.Owner); 1872
1876 if (notifyUser != null) 1873 if (remoteClient != null && (remoteClient.AgentId != objectGroup.RootPart.OwnerID) && Permissions.PropagatePermissions())
1874 {
1875 uint perms=objectGroup.GetEffectivePermissions();
1876 uint nextPerms=(perms & 7) << 13;
1877 if ((nextPerms & (uint)PermissionMask.Copy) == 0)
1878 perms &= ~(uint)PermissionMask.Copy;
1879 if ((nextPerms & (uint)PermissionMask.Transfer) == 0)
1880 perms &= ~(uint)PermissionMask.Transfer;
1881 if ((nextPerms & (uint)PermissionMask.Modify) == 0)
1882 perms &= ~(uint)PermissionMask.Modify;
1883
1884 item.BasePermissions = perms & objectGroup.RootPart.NextOwnerMask;
1885 item.CurrentPermissions = item.BasePermissions;
1886 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
1887 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask & objectGroup.RootPart.NextOwnerMask;
1888 item.GroupPermissions = objectGroup.RootPart.GroupMask & objectGroup.RootPart.NextOwnerMask;
1889 item.CurrentPermissions |= 8; // Slam!
1890 }
1891 else
1892 {
1893 item.BasePermissions = objectGroup.GetEffectivePermissions();
1894 item.CurrentPermissions = objectGroup.GetEffectivePermissions();
1895 item.NextPermissions = objectGroup.RootPart.NextOwnerMask;
1896 item.EveryOnePermissions = objectGroup.RootPart.EveryoneMask;
1897 item.GroupPermissions = objectGroup.RootPart.GroupMask;
1898 }
1899
1900 // TODO: add the new fields (Flags, Sale info, etc)
1901 item.CreationDate = Util.UnixTimeSinceEpoch();
1902
1903 userInfo.AddItem(item);
1904
1905 if (remoteClient != null && item.Owner == remoteClient.AgentId)
1877 { 1906 {
1878 notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item); 1907 remoteClient.SendInventoryItemCreateUpdate(item);
1879 } 1908 }
1909 else
1910 {
1911 ScenePresence notifyUser = GetScenePresence(item.Owner);
1912 if (notifyUser != null)
1913 {
1914 notifyUser.ControllingClient.SendInventoryItemCreateUpdate(item);
1915 }
1916 }
1880 } 1917 }
1881 } 1918 }
1882 1919
@@ -2093,7 +2130,7 @@ namespace OpenSim.Region.Environment.Scenes
2093 CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId); 2130 CachedUserInfo userInfo = CommsManager.UserProfileCacheService.GetUserDetails(remoteClient.AgentId);
2094 if (userInfo != null) 2131 if (userInfo != null)
2095 { 2132 {
2096 if (userInfo.RootFolder != null) 2133 if (userInfo.HasReceivedInventory)
2097 { 2134 {
2098 InventoryItemBase item = userInfo.RootFolder.FindItem(itemID); 2135 InventoryItemBase item = userInfo.RootFolder.FindItem(itemID);
2099 2136
@@ -2103,8 +2140,21 @@ namespace OpenSim.Region.Environment.Scenes
2103 2140
2104 if (rezAsset != null) 2141 if (rezAsset != null)
2105 { 2142 {
2143 UUID itemId = UUID.Zero;
2144
2145 // If we have permission to copy then link the rezzed object back to the user inventory
2146 // item that it came from. This allows us to enable 'save object to inventory'
2147 if (!Permissions.BypassPermissions())
2148 {
2149 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == (uint)PermissionMask.Copy)
2150 {
2151 itemId = item.ID;
2152 }
2153 }
2154
2106 string xmlData = Utils.BytesToString(rezAsset.Data); 2155 string xmlData = Utils.BytesToString(rezAsset.Data);
2107 SceneObjectGroup group = new SceneObjectGroup(xmlData, true); 2156 SceneObjectGroup group = new SceneObjectGroup(itemId, xmlData, true);
2157
2108 if (!Permissions.CanRezObject( 2158 if (!Permissions.CanRezObject(
2109 group.Children.Count, remoteClient.AgentId, pos) 2159 group.Children.Count, remoteClient.AgentId, pos)
2110 && !attachment) 2160 && !attachment)
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs
index 5502f97..6831885 100644
--- a/OpenSim/Region/Environment/Scenes/Scene.cs
+++ b/OpenSim/Region/Environment/Scenes/Scene.cs
@@ -3480,28 +3480,19 @@ namespace OpenSim.Region.Environment.Scenes
3480 3480
3481 public virtual void StoreAddFriendship(UUID ownerID, UUID friendID, uint perms) 3481 public virtual void StoreAddFriendship(UUID ownerID, UUID friendID, uint perms)
3482 { 3482 {
3483 // TODO: m_sceneGridService.DoStuff;
3484 m_sceneGridService.AddNewUserFriend(ownerID, friendID, perms); 3483 m_sceneGridService.AddNewUserFriend(ownerID, friendID, perms);
3485 } 3484 }
3486 3485
3487 public virtual void StoreUpdateFriendship(UUID ownerID, UUID friendID, uint perms) 3486 public virtual void StoreUpdateFriendship(UUID ownerID, UUID friendID, uint perms)
3488 { 3487 {
3489 // TODO: m_sceneGridService.DoStuff;
3490 m_sceneGridService.UpdateUserFriendPerms(ownerID, friendID, perms); 3488 m_sceneGridService.UpdateUserFriendPerms(ownerID, friendID, perms);
3491 } 3489 }
3492 3490
3493 public virtual void StoreRemoveFriendship(UUID ownerID, UUID ExfriendID) 3491 public virtual void StoreRemoveFriendship(UUID ownerID, UUID ExfriendID)
3494 { 3492 {
3495 // TODO: m_sceneGridService.DoStuff;
3496 m_sceneGridService.RemoveUserFriend(ownerID, ExfriendID); 3493 m_sceneGridService.RemoveUserFriend(ownerID, ExfriendID);
3497 } 3494 }
3498 3495
3499 public virtual List<FriendListItem> StoreGetFriendsForUser(UUID ownerID)
3500 {
3501 // TODO: m_sceneGridService.DoStuff;
3502 return m_sceneGridService.GetUserFriendList(ownerID);
3503 }
3504
3505 public void AddPacketStats(int inPackets, int outPackets, int unAckedBytes) 3496 public void AddPacketStats(int inPackets, int outPackets, int unAckedBytes)
3506 { 3497 {
3507 m_statsReporter.AddInPackets(inPackets); 3498 m_statsReporter.AddInPackets(inPackets);
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
index cc99929..5456282 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectGroup.cs
@@ -401,16 +401,25 @@ namespace OpenSim.Region.Environment.Scenes
401 { 401 {
402 SetRootPart(part); 402 SetRootPart(part);
403 } 403 }
404
405 public SceneObjectGroup(string xmlData, bool isOriginalXmlFormat)
406 : this(UUID.Zero, xmlData, isOriginalXmlFormat)
407 {
408 }
404 409
405 /// <summary> 410 /// <summary>
406 /// Create an object using serialized data in OpenSim's original xml format. 411 /// Create an object using serialized data in OpenSim's original xml format.
407 /// </summary> 412 /// </summary>
413 /// <param name="fromUserInventoryItemID">
414 /// If applicable, the user inventory item id from which this object was rezzed. If not applicable then this
415 /// should be UUID.Zero
416 /// </param>
408 /// <param name="xmlData"></param> 417 /// <param name="xmlData"></param>
409 /// <param name="isOriginalXmlFormat"> 418 /// <param name="isOriginalXmlFormat">
410 /// This parameter only exists to separate the two different xml constructors. In the future, versions should 419 /// This parameter only exists to separate the two different xml constructors. In the future, versions should
411 /// be specified within the xml itself. 420 /// be specified within the xml itself.
412 /// </param> 421 /// </param>
413 public SceneObjectGroup(string xmlData, bool isOriginalXmlFormat) 422 public SceneObjectGroup(UUID fromUserInventoryItemID, string xmlData, bool isOriginalXmlFormat)
414 { 423 {
415 if (!isOriginalXmlFormat) 424 if (!isOriginalXmlFormat)
416 throw new Exception("This constructor must specify the xml is in OpenSim's original format"); 425 throw new Exception("This constructor must specify the xml is in OpenSim's original format");
@@ -430,7 +439,7 @@ namespace OpenSim.Region.Environment.Scenes
430 reader.Read(); 439 reader.Read();
431 reader.ReadStartElement("SceneObjectGroup"); 440 reader.ReadStartElement("SceneObjectGroup");
432 reader.ReadStartElement("RootPart"); 441 reader.ReadStartElement("RootPart");
433 SetRootPart(SceneObjectPart.FromXml(reader)); 442 SetRootPart(SceneObjectPart.FromXml(fromUserInventoryItemID, reader));
434 443
435 reader.ReadEndElement(); 444 reader.ReadEndElement();
436 445
diff --git a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
index 10a37ee..3547cd4 100644
--- a/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
+++ b/OpenSim/Region/Environment/Scenes/SceneObjectPart.cs
@@ -116,30 +116,55 @@ namespace OpenSim.Region.Environment.Scenes
116 // for SL compatibility it should be persisted though (set sound / displaytext / particlesystem, kill script) 116 // for SL compatibility it should be persisted though (set sound / displaytext / particlesystem, kill script)
117 [XmlIgnore] 117 [XmlIgnore]
118 public UUID Sound; 118 public UUID Sound;
119
119 [XmlIgnore] 120 [XmlIgnore]
120 public byte SoundFlags; 121 public byte SoundFlags;
122
121 [XmlIgnore] 123 [XmlIgnore]
122 public double SoundGain; 124 public double SoundGain;
125
123 [XmlIgnore] 126 [XmlIgnore]
124 public double SoundRadius; 127 public double SoundRadius;
128
125 [XmlIgnore] 129 [XmlIgnore]
126 public uint TimeStampFull = 0; 130 public uint TimeStampFull = 0;
131
127 [XmlIgnore] 132 [XmlIgnore]
128 public uint TimeStampLastActivity = 0; // Will be used for AutoReturn 133 public uint TimeStampLastActivity = 0; // Will be used for AutoReturn
134
129 [XmlIgnore] 135 [XmlIgnore]
130 public uint TimeStampTerse = 0; 136 public uint TimeStampTerse = 0;
137
131 [XmlIgnore] 138 [XmlIgnore]
132 public UUID FromAssetID = UUID.Zero; 139 public UUID FromAssetID = UUID.Zero;
140
141 /// <value>
142 /// The UUID of the user inventory item from which this object was rezzed if this is a root part.
143 /// If UUID.Zero then either this is not a root part or there is no connection with a user inventory item.
144 /// </value>
145 private UUID m_fromUserInventoryItemID = UUID.Zero;
146
147 [XmlIgnore]
148 public UUID FromUserInventoryItemID
149 {
150 get { return m_fromUserInventoryItemID; }
151 }
152
133 [XmlIgnore] 153 [XmlIgnore]
134 public bool IsAttachment = false; 154 public bool IsAttachment = false;
155
135 [XmlIgnore] 156 [XmlIgnore]
136 public scriptEvents AggregateScriptEvents = 0; 157 public scriptEvents AggregateScriptEvents = 0;
158
137 [XmlIgnore] 159 [XmlIgnore]
138 public UUID AttachedAvatar = UUID.Zero; 160 public UUID AttachedAvatar = UUID.Zero;
161
139 [XmlIgnore] 162 [XmlIgnore]
140 public Vector3 AttachedPos = Vector3.Zero; 163 public Vector3 AttachedPos = Vector3.Zero;
164
141 [XmlIgnore] 165 [XmlIgnore]
142 public uint AttachmentPoint = (byte)0; 166 public uint AttachmentPoint = (byte)0;
167
143 [XmlIgnore] 168 [XmlIgnore]
144 public PhysicsVector RotationAxis = new PhysicsVector(1f,1f,1f); 169 public PhysicsVector RotationAxis = new PhysicsVector(1f,1f,1f);
145 170
@@ -1428,15 +1453,27 @@ if (m_shape != null) {
1428 /// <summary> 1453 /// <summary>
1429 /// Restore this part from the serialized xml representation. 1454 /// Restore this part from the serialized xml representation.
1430 /// </summary> 1455 /// </summary>
1456 /// <param name="xmlReader"></param>
1431 /// <returns></returns> 1457 /// <returns></returns>
1432 public static SceneObjectPart FromXml(XmlReader xmlReader) 1458 public static SceneObjectPart FromXml(XmlReader xmlReader)
1433 { 1459 {
1434 // It's not necessary to persist this 1460 return FromXml(UUID.Zero, xmlReader);
1435
1436 XmlSerializer serializer = new XmlSerializer(typeof (SceneObjectPart));
1437 SceneObjectPart newobject = (SceneObjectPart) serializer.Deserialize(xmlReader);
1438 return newobject;
1439 } 1461 }
1462
1463 /// <summary>
1464 /// Restore this part from the serialized xml representation.
1465 /// </summary>
1466 /// <param name="fromUserInventoryItemId">The inventory id from which this part came, if applicable</param>
1467 /// <param name="xmlReader"></param>
1468 /// <returns></returns>
1469 public static SceneObjectPart FromXml(UUID fromUserInventoryItemId, XmlReader xmlReader)
1470 {
1471 XmlSerializer serializer = new XmlSerializer(typeof (SceneObjectPart));
1472 SceneObjectPart part = (SceneObjectPart)serializer.Deserialize(xmlReader);
1473 part.m_fromUserInventoryItemID = fromUserInventoryItemId;
1474
1475 return part;
1476 }
1440 1477
1441 public UUID GetAvatarOnSitTarget() 1478 public UUID GetAvatarOnSitTarget()
1442 { 1479 {
@@ -1603,7 +1640,7 @@ if (m_shape != null) {
1603 public void GetProperties(IClientAPI client) 1640 public void GetProperties(IClientAPI client)
1604 { 1641 {
1605 client.SendObjectPropertiesReply( 1642 client.SendObjectPropertiesReply(
1606 UUID.Zero, (ulong)_creationDate, _creatorID, UUID.Zero, UUID.Zero, 1643 m_fromUserInventoryItemID, (ulong)_creationDate, _creatorID, UUID.Zero, UUID.Zero,
1607 _groupID, (short)InventorySerial, _lastOwnerID, UUID, _ownerID, 1644 _groupID, (short)InventorySerial, _lastOwnerID, UUID, _ownerID,
1608 ParentGroup.RootPart.TouchName, new byte[0], ParentGroup.RootPart.SitName, Name, Description, 1645 ParentGroup.RootPart.TouchName, new byte[0], ParentGroup.RootPart.SitName, Name, Description,
1609 ParentGroup.RootPart._ownerMask, ParentGroup.RootPart._nextOwnerMask, ParentGroup.RootPart._groupMask, ParentGroup.RootPart._everyoneMask, 1646 ParentGroup.RootPart._ownerMask, ParentGroup.RootPart._nextOwnerMask, ParentGroup.RootPart._groupMask, ParentGroup.RootPart._everyoneMask,