diff options
Diffstat (limited to '')
14 files changed, 410 insertions, 211 deletions
diff --git a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs index 0271738..f56d17d 100644 --- a/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs +++ b/OpenSim/Region/CoreModules/Agent/AssetTransaction/AgentAssetsTransactions.cs | |||
@@ -33,6 +33,7 @@ using OpenSim.Framework; | |||
33 | 33 | ||
34 | using OpenSim.Region.Framework.Scenes; | 34 | using OpenSim.Region.Framework.Scenes; |
35 | using OpenSim.Services.Interfaces; | 35 | using OpenSim.Services.Interfaces; |
36 | using OpenSim.Region.Framework.Interfaces; | ||
36 | 37 | ||
37 | namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | 38 | namespace OpenSim.Region.CoreModules.Agent.AssetTransaction |
38 | { | 39 | { |
@@ -119,6 +120,14 @@ namespace OpenSim.Region.CoreModules.Agent.AssetTransaction | |||
119 | } | 120 | } |
120 | else | 121 | else |
121 | { | 122 | { |
123 | // Check if the xfer is a terrain xfer | ||
124 | IEstateModule estateModule = m_Scene.RequestModuleInterface<IEstateModule>(); | ||
125 | if (estateModule != null) | ||
126 | { | ||
127 | if (estateModule.IsTerrainXfer(xferID)) | ||
128 | return; | ||
129 | } | ||
130 | |||
122 | m_log.ErrorFormat( | 131 | m_log.ErrorFormat( |
123 | "[AGENT ASSET TRANSACTIONS]: Could not find uploader for xfer id {0}, packet id {1}, data length {2}", | 132 | "[AGENT ASSET TRANSACTIONS]: Could not find uploader for xfer id {0}, packet id {1}, data length {2}", |
124 | xferID, packetID, data.Length); | 133 | xferID, packetID, data.Length); |
diff --git a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs index 2116605..ff87ece 100644 --- a/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs +++ b/OpenSim/Region/CoreModules/Avatar/Friends/FriendsRequestHandler.cs | |||
@@ -42,14 +42,22 @@ using log4net; | |||
42 | 42 | ||
43 | namespace OpenSim.Region.CoreModules.Avatar.Friends | 43 | namespace OpenSim.Region.CoreModules.Avatar.Friends |
44 | { | 44 | { |
45 | public class FriendsRequestHandler : BaseStreamHandler | 45 | public class FriendsRequestHandler : BaseStreamHandlerBasicDOSProtector |
46 | { | 46 | { |
47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | 48 | ||
49 | private FriendsModule m_FriendsModule; | 49 | private FriendsModule m_FriendsModule; |
50 | 50 | ||
51 | public FriendsRequestHandler(FriendsModule fmodule) | 51 | public FriendsRequestHandler(FriendsModule fmodule) |
52 | : base("POST", "/friends") | 52 | : base("POST", "/friends", new BasicDosProtectorOptions() |
53 | { | ||
54 | AllowXForwardedFor = true, | ||
55 | ForgetTimeSpan = TimeSpan.FromMinutes(2), | ||
56 | MaxRequestsInTimeframe = 20, | ||
57 | ReportingName = "FRIENDSDOSPROTECTOR", | ||
58 | RequestTimeSpan = TimeSpan.FromSeconds(5), | ||
59 | ThrottledAction = BasicDOSProtector.ThrottleAction.DoThrottledMethod | ||
60 | }) | ||
53 | { | 61 | { |
54 | m_FriendsModule = fmodule; | 62 | m_FriendsModule = fmodule; |
55 | } | 63 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 0ec9575..831922e 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -757,64 +757,29 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
757 | 757 | ||
758 | SceneObjectGroup group = null; | 758 | SceneObjectGroup group = null; |
759 | 759 | ||
760 | string xmlData = Utils.BytesToString(rezAsset.Data); | 760 | List<SceneObjectGroup> objlist; |
761 | List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(); | 761 | List<Vector3> veclist; |
762 | List<Vector3> veclist = new List<Vector3>(); | 762 | Vector3 bbox; |
763 | float offsetHeight; | ||
763 | byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); | 764 | byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); |
764 | Vector3 pos; | 765 | Vector3 pos; |
765 | 766 | ||
766 | XmlDocument doc = new XmlDocument(); | 767 | bool single = m_Scene.GetObjectsToRez(rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight); |
767 | doc.LoadXml(xmlData); | ||
768 | XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); | ||
769 | if (e == null || attachment) // Single | ||
770 | { | ||
771 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
772 | |||
773 | objlist.Add(g); | ||
774 | veclist.Add(Vector3.Zero); | ||
775 | 768 | ||
776 | float offsetHeight = 0; | 769 | if (single) |
770 | { | ||
777 | pos = m_Scene.GetNewRezLocation( | 771 | pos = m_Scene.GetNewRezLocation( |
778 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, | 772 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, |
779 | BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); | 773 | BypassRayCast, bRayEndIsIntersection, true, bbox, false); |
780 | pos.Z += offsetHeight; | 774 | pos.Z += offsetHeight; |
781 | } | 775 | } |
782 | else | 776 | else |
783 | { | 777 | { |
784 | XmlElement coll = (XmlElement)e; | ||
785 | float bx = Convert.ToSingle(coll.GetAttribute("x")); | ||
786 | float by = Convert.ToSingle(coll.GetAttribute("y")); | ||
787 | float bz = Convert.ToSingle(coll.GetAttribute("z")); | ||
788 | Vector3 bbox = new Vector3(bx, by, bz); | ||
789 | |||
790 | pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, | 778 | pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, |
791 | RayTargetID, Quaternion.Identity, | 779 | RayTargetID, Quaternion.Identity, |
792 | BypassRayCast, bRayEndIsIntersection, true, | 780 | BypassRayCast, bRayEndIsIntersection, true, |
793 | bbox, false); | 781 | bbox, false); |
794 | |||
795 | pos -= bbox / 2; | 782 | pos -= bbox / 2; |
796 | |||
797 | XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); | ||
798 | foreach (XmlNode n in groups) | ||
799 | { | ||
800 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); | ||
801 | |||
802 | objlist.Add(g); | ||
803 | XmlElement el = (XmlElement)n; | ||
804 | |||
805 | string rawX = el.GetAttribute("offsetx"); | ||
806 | string rawY = el.GetAttribute("offsety"); | ||
807 | string rawZ = el.GetAttribute("offsetz"); | ||
808 | // | ||
809 | // m_log.DebugFormat( | ||
810 | // "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>", | ||
811 | // g.Name, rawX, rawY, rawZ); | ||
812 | |||
813 | float x = Convert.ToSingle(rawX); | ||
814 | float y = Convert.ToSingle(rawY); | ||
815 | float z = Convert.ToSingle(rawZ); | ||
816 | veclist.Add(new Vector3(x, y, z)); | ||
817 | } | ||
818 | } | 783 | } |
819 | 784 | ||
820 | if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment)) | 785 | if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment)) |
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs index 42db1cf..17387da 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateManagementModule.cs | |||
@@ -829,26 +829,23 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
829 | 829 | ||
830 | private void AbortTerrainXferHandler(IClientAPI remoteClient, ulong XferID) | 830 | private void AbortTerrainXferHandler(IClientAPI remoteClient, ulong XferID) |
831 | { | 831 | { |
832 | if (TerrainUploader != null) | 832 | lock (this) |
833 | { | 833 | { |
834 | lock (TerrainUploader) | 834 | if ((TerrainUploader != null) && (XferID == TerrainUploader.XferID)) |
835 | { | 835 | { |
836 | if (XferID == TerrainUploader.XferID) | 836 | remoteClient.OnXferReceive -= TerrainUploader.XferReceive; |
837 | { | 837 | remoteClient.OnAbortXfer -= AbortTerrainXferHandler; |
838 | remoteClient.OnXferReceive -= TerrainUploader.XferReceive; | 838 | TerrainUploader.TerrainUploadDone -= HandleTerrainApplication; |
839 | remoteClient.OnAbortXfer -= AbortTerrainXferHandler; | ||
840 | TerrainUploader.TerrainUploadDone -= HandleTerrainApplication; | ||
841 | 839 | ||
842 | TerrainUploader = null; | 840 | TerrainUploader = null; |
843 | remoteClient.SendAlertMessage("Terrain Upload aborted by the client"); | 841 | remoteClient.SendAlertMessage("Terrain Upload aborted by the client"); |
844 | } | ||
845 | } | 842 | } |
846 | } | 843 | } |
847 | |||
848 | } | 844 | } |
845 | |||
849 | private void HandleTerrainApplication(string filename, byte[] terrainData, IClientAPI remoteClient) | 846 | private void HandleTerrainApplication(string filename, byte[] terrainData, IClientAPI remoteClient) |
850 | { | 847 | { |
851 | lock (TerrainUploader) | 848 | lock (this) |
852 | { | 849 | { |
853 | remoteClient.OnXferReceive -= TerrainUploader.XferReceive; | 850 | remoteClient.OnXferReceive -= TerrainUploader.XferReceive; |
854 | remoteClient.OnAbortXfer -= AbortTerrainXferHandler; | 851 | remoteClient.OnAbortXfer -= AbortTerrainXferHandler; |
@@ -907,22 +904,32 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
907 | 904 | ||
908 | private void handleUploadTerrain(IClientAPI remote_client, string clientFileName) | 905 | private void handleUploadTerrain(IClientAPI remote_client, string clientFileName) |
909 | { | 906 | { |
910 | if (TerrainUploader == null) | 907 | lock (this) |
911 | { | 908 | { |
912 | 909 | if (TerrainUploader == null) | |
913 | TerrainUploader = new EstateTerrainXferHandler(remote_client, clientFileName); | ||
914 | lock (TerrainUploader) | ||
915 | { | 910 | { |
911 | m_log.DebugFormat("Starting to receive uploaded terrain"); | ||
912 | TerrainUploader = new EstateTerrainXferHandler(remote_client, clientFileName); | ||
916 | remote_client.OnXferReceive += TerrainUploader.XferReceive; | 913 | remote_client.OnXferReceive += TerrainUploader.XferReceive; |
917 | remote_client.OnAbortXfer += AbortTerrainXferHandler; | 914 | remote_client.OnAbortXfer += AbortTerrainXferHandler; |
918 | TerrainUploader.TerrainUploadDone += HandleTerrainApplication; | 915 | TerrainUploader.TerrainUploadDone += HandleTerrainApplication; |
916 | TerrainUploader.RequestStartXfer(remote_client); | ||
917 | } | ||
918 | else | ||
919 | { | ||
920 | remote_client.SendAlertMessage("Another Terrain Upload is in progress. Please wait your turn!"); | ||
919 | } | 921 | } |
920 | TerrainUploader.RequestStartXfer(remote_client); | ||
921 | |||
922 | } | 922 | } |
923 | else | 923 | } |
924 | |||
925 | public bool IsTerrainXfer(ulong xferID) | ||
926 | { | ||
927 | lock (this) | ||
924 | { | 928 | { |
925 | remote_client.SendAlertMessage("Another Terrain Upload is in progress. Please wait your turn!"); | 929 | if (TerrainUploader == null) |
930 | return false; | ||
931 | else | ||
932 | return TerrainUploader.XferID == xferID; | ||
926 | } | 933 | } |
927 | } | 934 | } |
928 | 935 | ||
diff --git a/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs b/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs index b8d8b10..2d74eaf 100644 --- a/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs +++ b/OpenSim/Region/CoreModules/World/Estate/EstateTerrainXferHandler.cs | |||
@@ -78,7 +78,10 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
78 | /// <param name="data"></param> | 78 | /// <param name="data"></param> |
79 | public void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) | 79 | public void XferReceive(IClientAPI remoteClient, ulong xferID, uint packetID, byte[] data) |
80 | { | 80 | { |
81 | if (mXferID == xferID) | 81 | if (mXferID != xferID) |
82 | return; | ||
83 | |||
84 | lock (this) | ||
82 | { | 85 | { |
83 | if (m_asset.Data.Length > 1) | 86 | if (m_asset.Data.Length > 1) |
84 | { | 87 | { |
@@ -99,7 +102,6 @@ namespace OpenSim.Region.CoreModules.World.Estate | |||
99 | if ((packetID & 0x80000000) != 0) | 102 | if ((packetID & 0x80000000) != 0) |
100 | { | 103 | { |
101 | SendCompleteMessage(remoteClient); | 104 | SendCompleteMessage(remoteClient); |
102 | |||
103 | } | 105 | } |
104 | } | 106 | } |
105 | } | 107 | } |
diff --git a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs index c985ca2..8383f4e 100644 --- a/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs +++ b/OpenSim/Region/CoreModules/World/WorldMap/WorldMapModule.cs | |||
@@ -165,7 +165,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
165 | regionimage = regionimage.Replace("-", ""); | 165 | regionimage = regionimage.Replace("-", ""); |
166 | m_log.Info("[WORLD MAP]: JPEG Map location: " + m_scene.RegionInfo.ServerURI + "index.php?method=" + regionimage); | 166 | m_log.Info("[WORLD MAP]: JPEG Map location: " + m_scene.RegionInfo.ServerURI + "index.php?method=" + regionimage); |
167 | 167 | ||
168 | MainServer.Instance.AddHTTPHandler(regionimage, OnHTTPGetMapImage); | 168 | MainServer.Instance.AddHTTPHandler(regionimage, |
169 | new GenericHTTPDOSProtector(OnHTTPGetMapImage, OnHTTPThrottled, new BasicDosProtectorOptions() | ||
170 | { | ||
171 | AllowXForwardedFor = false, | ||
172 | ForgetTimeSpan = TimeSpan.FromMinutes(2), | ||
173 | MaxRequestsInTimeframe = 4, | ||
174 | ReportingName = "MAPDOSPROTECTOR", | ||
175 | RequestTimeSpan = TimeSpan.FromSeconds(10), | ||
176 | ThrottledAction = BasicDOSProtector.ThrottleAction.DoThrottledMethod | ||
177 | }).Process); | ||
169 | MainServer.Instance.AddLLSDHandler( | 178 | MainServer.Instance.AddLLSDHandler( |
170 | "/MAP/MapItems/" + m_scene.RegionInfo.RegionHandle.ToString(), HandleRemoteMapItemRequest); | 179 | "/MAP/MapItems/" + m_scene.RegionInfo.RegionHandle.ToString(), HandleRemoteMapItemRequest); |
171 | 180 | ||
@@ -1081,6 +1090,16 @@ namespace OpenSim.Region.CoreModules.World.WorldMap | |||
1081 | block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); | 1090 | block.Y = (ushort)(r.RegionLocY / Constants.RegionSize); |
1082 | } | 1091 | } |
1083 | 1092 | ||
1093 | public Hashtable OnHTTPThrottled(Hashtable keysvals) | ||
1094 | { | ||
1095 | Hashtable reply = new Hashtable(); | ||
1096 | int statuscode = 500; | ||
1097 | reply["str_response_string"] = ""; | ||
1098 | reply["int_response_code"] = statuscode; | ||
1099 | reply["content_type"] = "text/plain"; | ||
1100 | return reply; | ||
1101 | } | ||
1102 | |||
1084 | public Hashtable OnHTTPGetMapImage(Hashtable keysvals) | 1103 | public Hashtable OnHTTPGetMapImage(Hashtable keysvals) |
1085 | { | 1104 | { |
1086 | m_log.Debug("[WORLD MAP]: Sending map image jpeg"); | 1105 | m_log.Debug("[WORLD MAP]: Sending map image jpeg"); |
diff --git a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs index 150193d..9ffda51 100644 --- a/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs +++ b/OpenSim/Region/Framework/Interfaces/IEntityInventory.cs | |||
@@ -234,15 +234,17 @@ namespace OpenSim.Region.Framework.Interfaces | |||
234 | List<TaskInventoryItem> GetInventoryItems(InventoryType type); | 234 | List<TaskInventoryItem> GetInventoryItems(InventoryType type); |
235 | 235 | ||
236 | /// <summary> | 236 | /// <summary> |
237 | /// Get the scene object referenced by an inventory item. | 237 | /// Get the scene object(s) referenced by an inventory item. |
238 | /// </summary> | 238 | /// </summary> |
239 | /// | 239 | /// |
240 | /// This is returned in a 'rez ready' state. That is, name, description, permissions and other details have | 240 | /// This is returned in a 'rez ready' state. That is, name, description, permissions and other details have |
241 | /// been adjusted to reflect the part and item from which it originates. | 241 | /// been adjusted to reflect the part and item from which it originates. |
242 | /// | 242 | /// |
243 | /// <param name="item"></param> | 243 | /// <param name="item">Inventory item</param> |
244 | /// <returns>The scene object. Null if the scene object asset couldn't be found</returns> | 244 | /// <param name="objlist">The scene objects</param> |
245 | SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item); | 245 | /// <param name="veclist">Relative offsets for each object</param> |
246 | /// <returns>true = success, false = the scene object asset couldn't be found</returns> | ||
247 | bool GetRezReadySceneObjects(TaskInventoryItem item, out List<SceneObjectGroup> objlist, out List<Vector3> veclist); | ||
246 | 248 | ||
247 | /// <summary> | 249 | /// <summary> |
248 | /// Update an existing inventory item. | 250 | /// Update an existing inventory item. |
diff --git a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs index d49b24e..944c66b 100644 --- a/OpenSim/Region/Framework/Interfaces/IEstateModule.cs +++ b/OpenSim/Region/Framework/Interfaces/IEstateModule.cs | |||
@@ -54,5 +54,10 @@ namespace OpenSim.Region.Framework.Interfaces | |||
54 | 54 | ||
55 | void setEstateTerrainBaseTexture(int level, UUID texture); | 55 | void setEstateTerrainBaseTexture(int level, UUID texture); |
56 | void setEstateTerrainTextureHeights(int corner, float lowValue, float highValue); | 56 | void setEstateTerrainTextureHeights(int corner, float lowValue, float highValue); |
57 | |||
58 | /// <summary> | ||
59 | /// Returns whether the transfer ID is being used for a terrain transfer. | ||
60 | /// </summary> | ||
61 | bool IsTerrainXfer(ulong xferID); | ||
57 | } | 62 | } |
58 | } | 63 | } |
diff --git a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs index 4bebbe8..65536db 100644 --- a/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs +++ b/OpenSim/Region/Framework/Scenes/Scene.Inventory.cs | |||
@@ -31,6 +31,7 @@ using System.Collections; | |||
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Text; | 32 | using System.Text; |
33 | using System.Timers; | 33 | using System.Timers; |
34 | using System.Xml; | ||
34 | using OpenMetaverse; | 35 | using OpenMetaverse; |
35 | using OpenMetaverse.Packets; | 36 | using OpenMetaverse.Packets; |
36 | using log4net; | 37 | using log4net; |
@@ -2135,6 +2136,69 @@ namespace OpenSim.Region.Framework.Scenes | |||
2135 | } | 2136 | } |
2136 | 2137 | ||
2137 | /// <summary> | 2138 | /// <summary> |
2139 | /// Returns the list of Scene Objects in an asset. | ||
2140 | /// </summary> | ||
2141 | /// <remarks> | ||
2142 | /// Returns one object if the asset is a regular object, and multiple objects for a coalesced object. | ||
2143 | /// </remarks> | ||
2144 | /// <param name="assetData">Asset data</param> | ||
2145 | /// <param name="attachment">Whether the item is an attachment</param> | ||
2146 | /// <param name="objlist">The objects included in the asset</param> | ||
2147 | /// <param name="veclist">Relative positions of the objects</param> | ||
2148 | /// <param name="bbox">Bounding box of all the objects</param> | ||
2149 | /// <param name="offsetHeight">Offset in the Z axis from the centre of the bounding box | ||
2150 | /// to the centre of the root prim (relevant only when returning a single object)</param> | ||
2151 | /// <returns>true = returning a single object; false = multiple objects</returns> | ||
2152 | public bool GetObjectsToRez(byte[] assetData, bool attachment, out List<SceneObjectGroup> objlist, out List<Vector3> veclist, | ||
2153 | out Vector3 bbox, out float offsetHeight) | ||
2154 | { | ||
2155 | objlist = new List<SceneObjectGroup>(); | ||
2156 | veclist = new List<Vector3>(); | ||
2157 | |||
2158 | XmlDocument doc = new XmlDocument(); | ||
2159 | string xmlData = Utils.BytesToString(assetData); | ||
2160 | doc.LoadXml(xmlData); | ||
2161 | XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); | ||
2162 | |||
2163 | if (e == null || attachment) // Single | ||
2164 | { | ||
2165 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
2166 | objlist.Add(g); | ||
2167 | veclist.Add(new Vector3(0, 0, 0)); | ||
2168 | bbox = g.GetAxisAlignedBoundingBox(out offsetHeight); | ||
2169 | return true; | ||
2170 | } | ||
2171 | else | ||
2172 | { | ||
2173 | XmlElement coll = (XmlElement)e; | ||
2174 | float bx = Convert.ToSingle(coll.GetAttribute("x")); | ||
2175 | float by = Convert.ToSingle(coll.GetAttribute("y")); | ||
2176 | float bz = Convert.ToSingle(coll.GetAttribute("z")); | ||
2177 | bbox = new Vector3(bx, by, bz); | ||
2178 | offsetHeight = 0; | ||
2179 | |||
2180 | XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); | ||
2181 | foreach (XmlNode n in groups) | ||
2182 | { | ||
2183 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); | ||
2184 | objlist.Add(g); | ||
2185 | |||
2186 | XmlElement el = (XmlElement)n; | ||
2187 | string rawX = el.GetAttribute("offsetx"); | ||
2188 | string rawY = el.GetAttribute("offsety"); | ||
2189 | string rawZ = el.GetAttribute("offsetz"); | ||
2190 | |||
2191 | float x = Convert.ToSingle(rawX); | ||
2192 | float y = Convert.ToSingle(rawY); | ||
2193 | float z = Convert.ToSingle(rawZ); | ||
2194 | veclist.Add(new Vector3(x, y, z)); | ||
2195 | } | ||
2196 | } | ||
2197 | |||
2198 | return false; | ||
2199 | } | ||
2200 | |||
2201 | /// <summary> | ||
2138 | /// Event Handler Rez an object into a scene | 2202 | /// Event Handler Rez an object into a scene |
2139 | /// Calls the non-void event handler | 2203 | /// Calls the non-void event handler |
2140 | /// </summary> | 2204 | /// </summary> |
@@ -2209,19 +2273,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
2209 | /// will be used if it exists.</param> | 2273 | /// will be used if it exists.</param> |
2210 | /// <param name="vel">The velocity of the rezzed object.</param> | 2274 | /// <param name="vel">The velocity of the rezzed object.</param> |
2211 | /// <param name="param"></param> | 2275 | /// <param name="param"></param> |
2212 | /// <returns>The SceneObjectGroup rezzed or null if rez was unsuccessful</returns> | 2276 | /// <returns>The SceneObjectGroup(s) rezzed, or null if rez was unsuccessful</returns> |
2213 | public virtual SceneObjectGroup RezObject( | 2277 | public virtual List<SceneObjectGroup> RezObject( |
2214 | SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion? rot, Vector3 vel, int param) | 2278 | SceneObjectPart sourcePart, TaskInventoryItem item, Vector3 pos, Quaternion? rot, Vector3 vel, int param) |
2215 | { | 2279 | { |
2216 | if (null == item) | 2280 | if (null == item) |
2217 | return null; | 2281 | return null; |
2282 | |||
2283 | List<SceneObjectGroup> objlist; | ||
2284 | List<Vector3> veclist; | ||
2218 | 2285 | ||
2219 | SceneObjectGroup group = sourcePart.Inventory.GetRezReadySceneObject(item); | 2286 | bool success = sourcePart.Inventory.GetRezReadySceneObjects(item, out objlist, out veclist); |
2220 | 2287 | if (!success) | |
2221 | if (null == group) | ||
2222 | return null; | 2288 | return null; |
2223 | 2289 | ||
2224 | if (!Permissions.CanRezObject(group.PrimCount, item.OwnerID, pos)) | 2290 | int totalPrims = 0; |
2291 | foreach (SceneObjectGroup group in objlist) | ||
2292 | totalPrims += group.PrimCount; | ||
2293 | |||
2294 | if (!Permissions.CanRezObject(totalPrims, item.OwnerID, pos)) | ||
2225 | return null; | 2295 | return null; |
2226 | 2296 | ||
2227 | if (!Permissions.BypassPermissions()) | 2297 | if (!Permissions.BypassPermissions()) |
@@ -2230,23 +2300,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
2230 | sourcePart.Inventory.RemoveInventoryItem(item.ItemID); | 2300 | sourcePart.Inventory.RemoveInventoryItem(item.ItemID); |
2231 | } | 2301 | } |
2232 | 2302 | ||
2233 | 2303 | for (int i = 0; i < objlist.Count; i++) | |
2234 | if (group.IsAttachment == false && group.RootPart.Shape.State != 0) | ||
2235 | { | 2304 | { |
2236 | group.RootPart.AttachedPos = group.AbsolutePosition; | 2305 | SceneObjectGroup group = objlist[i]; |
2237 | group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint; | 2306 | Vector3 curpos = pos + veclist[i]; |
2307 | |||
2308 | if (group.IsAttachment == false && group.RootPart.Shape.State != 0) | ||
2309 | { | ||
2310 | group.RootPart.AttachedPos = group.AbsolutePosition; | ||
2311 | group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint; | ||
2312 | } | ||
2313 | |||
2314 | group.FromPartID = sourcePart.UUID; | ||
2315 | AddNewSceneObject(group, true, curpos, rot, vel); | ||
2316 | |||
2317 | // We can only call this after adding the scene object, since the scene object references the scene | ||
2318 | // to find out if scripts should be activated at all. | ||
2319 | group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); | ||
2320 | |||
2321 | group.ScheduleGroupForFullUpdate(); | ||
2238 | } | 2322 | } |
2239 | 2323 | ||
2240 | group.FromPartID = sourcePart.UUID; | 2324 | return objlist; |
2241 | AddNewSceneObject(group, true, pos, rot, vel); | ||
2242 | |||
2243 | // We can only call this after adding the scene object, since the scene object references the scene | ||
2244 | // to find out if scripts should be activated at all. | ||
2245 | group.CreateScriptInstances(param, true, DefaultScriptEngine, 3); | ||
2246 | |||
2247 | group.ScheduleGroupForFullUpdate(); | ||
2248 | |||
2249 | return group; | ||
2250 | } | 2325 | } |
2251 | 2326 | ||
2252 | public virtual bool returnObjects(SceneObjectGroup[] returnobjects, | 2327 | public virtual bool returnObjects(SceneObjectGroup[] returnobjects, |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 3f223a3..380e402 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -733,8 +733,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
733 | 733 | ||
734 | return items; | 734 | return items; |
735 | } | 735 | } |
736 | 736 | ||
737 | public SceneObjectGroup GetRezReadySceneObject(TaskInventoryItem item) | 737 | public bool GetRezReadySceneObjects(TaskInventoryItem item, out List<SceneObjectGroup> objlist, out List<Vector3> veclist) |
738 | { | 738 | { |
739 | AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); | 739 | AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); |
740 | 740 | ||
@@ -743,66 +743,75 @@ namespace OpenSim.Region.Framework.Scenes | |||
743 | m_log.WarnFormat( | 743 | m_log.WarnFormat( |
744 | "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}", | 744 | "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}", |
745 | item.AssetID, item.Name, m_part.Name); | 745 | item.AssetID, item.Name, m_part.Name); |
746 | return null; | 746 | objlist = null; |
747 | veclist = null; | ||
748 | return false; | ||
747 | } | 749 | } |
748 | 750 | ||
749 | string xmlData = Utils.BytesToString(rezAsset.Data); | 751 | Vector3 bbox; |
750 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | 752 | float offsetHeight; |
751 | 753 | ||
752 | group.ResetIDs(); | 754 | bool single = m_part.ParentGroup.Scene.GetObjectsToRez(rezAsset.Data, false, out objlist, out veclist, out bbox, out offsetHeight); |
753 | 755 | ||
754 | SceneObjectPart rootPart = group.GetPart(group.UUID); | 756 | for (int i = 0; i < objlist.Count; i++) |
757 | { | ||
758 | SceneObjectGroup group = objlist[i]; | ||
755 | 759 | ||
756 | // Since renaming the item in the inventory does not affect the name stored | 760 | group.ResetIDs(); |
757 | // in the serialization, transfer the correct name from the inventory to the | ||
758 | // object itself before we rez. | ||
759 | rootPart.Name = item.Name; | ||
760 | rootPart.Description = item.Description; | ||
761 | 761 | ||
762 | SceneObjectPart[] partList = group.Parts; | 762 | SceneObjectPart rootPart = group.GetPart(group.UUID); |
763 | 763 | ||
764 | group.SetGroup(m_part.GroupID, null); | 764 | // Since renaming the item in the inventory does not affect the name stored |
765 | // in the serialization, transfer the correct name from the inventory to the | ||
766 | // object itself before we rez. | ||
767 | rootPart.Name = item.Name; | ||
768 | rootPart.Description = item.Description; | ||
765 | 769 | ||
766 | // TODO: Remove magic number badness | 770 | SceneObjectPart[] partList = group.Parts; |
767 | if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number | 771 | |
768 | { | 772 | group.SetGroup(m_part.GroupID, null); |
769 | if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions()) | 773 | |
774 | // TODO: Remove magic number badness | ||
775 | if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number | ||
770 | { | 776 | { |
771 | foreach (SceneObjectPart part in partList) | 777 | if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions()) |
772 | { | 778 | { |
773 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) | 779 | foreach (SceneObjectPart part in partList) |
774 | part.EveryoneMask = item.EveryonePermissions; | 780 | { |
775 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) | 781 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) |
776 | part.NextOwnerMask = item.NextPermissions; | 782 | part.EveryoneMask = item.EveryonePermissions; |
777 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) | 783 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) |
778 | part.GroupMask = item.GroupPermissions; | 784 | part.NextOwnerMask = item.NextPermissions; |
785 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) | ||
786 | part.GroupMask = item.GroupPermissions; | ||
787 | } | ||
788 | |||
789 | group.ApplyNextOwnerPermissions(); | ||
779 | } | 790 | } |
780 | |||
781 | group.ApplyNextOwnerPermissions(); | ||
782 | } | 791 | } |
783 | } | ||
784 | 792 | ||
785 | foreach (SceneObjectPart part in partList) | 793 | foreach (SceneObjectPart part in partList) |
786 | { | ||
787 | // TODO: Remove magic number badness | ||
788 | if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number | ||
789 | { | 794 | { |
790 | part.LastOwnerID = part.OwnerID; | 795 | // TODO: Remove magic number badness |
791 | part.OwnerID = item.OwnerID; | 796 | if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & 16) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) // Magic number |
792 | part.Inventory.ChangeInventoryOwner(item.OwnerID); | 797 | { |
798 | part.LastOwnerID = part.OwnerID; | ||
799 | part.OwnerID = item.OwnerID; | ||
800 | part.Inventory.ChangeInventoryOwner(item.OwnerID); | ||
801 | } | ||
802 | |||
803 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) | ||
804 | part.EveryoneMask = item.EveryonePermissions; | ||
805 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) | ||
806 | part.NextOwnerMask = item.NextPermissions; | ||
807 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) | ||
808 | part.GroupMask = item.GroupPermissions; | ||
793 | } | 809 | } |
794 | 810 | ||
795 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) | 811 | rootPart.TrimPermissions(); |
796 | part.EveryoneMask = item.EveryonePermissions; | ||
797 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) | ||
798 | part.NextOwnerMask = item.NextPermissions; | ||
799 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) | ||
800 | part.GroupMask = item.GroupPermissions; | ||
801 | } | 812 | } |
802 | 813 | ||
803 | rootPart.TrimPermissions(); | 814 | return true; |
804 | |||
805 | return group; | ||
806 | } | 815 | } |
807 | 816 | ||
808 | /// <summary> | 817 | /// <summary> |
diff --git a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs index d744a14..d09d3ad 100644 --- a/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs +++ b/OpenSim/Region/OptionalModules/Avatar/XmlRpcGroups/GroupsModule.cs | |||
@@ -39,6 +39,7 @@ using OpenSim.Framework.Communications; | |||
39 | using OpenSim.Region.Framework.Interfaces; | 39 | using OpenSim.Region.Framework.Interfaces; |
40 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
41 | using OpenSim.Services.Interfaces; | 41 | using OpenSim.Services.Interfaces; |
42 | using System.Text; | ||
42 | using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; | 43 | using DirFindFlags = OpenMetaverse.DirectoryManager.DirFindFlags; |
43 | 44 | ||
44 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | 45 | namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups |
@@ -421,44 +422,75 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
421 | string Subject = im.message.Substring(0, im.message.IndexOf('|')); | 422 | string Subject = im.message.Substring(0, im.message.IndexOf('|')); |
422 | string Message = im.message.Substring(Subject.Length + 1); | 423 | string Message = im.message.Substring(Subject.Length + 1); |
423 | 424 | ||
425 | InventoryItemBase item = null; | ||
426 | bool hasAttachment = false; | ||
427 | UUID itemID = UUID.Zero; //Assignment to quiet compiler | ||
428 | UUID ownerID = UUID.Zero; //Assignment to quiet compiler | ||
424 | byte[] bucket; | 429 | byte[] bucket; |
425 | 430 | ||
426 | if ((im.binaryBucket.Length == 1) && (im.binaryBucket[0] == 0)) | 431 | if (im.binaryBucket.Length >= 1 && im.binaryBucket[0] > 0) |
427 | { | ||
428 | bucket = new byte[19]; | ||
429 | bucket[0] = 0; //dunno | ||
430 | bucket[1] = 0; //dunno | ||
431 | GroupID.ToBytes(bucket, 2); | ||
432 | bucket[18] = 0; //dunno | ||
433 | } | ||
434 | else | ||
435 | { | 432 | { |
436 | string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); | 433 | string binBucket = OpenMetaverse.Utils.BytesToString(im.binaryBucket); |
437 | binBucket = binBucket.Remove(0, 14).Trim(); | 434 | binBucket = binBucket.Remove(0, 14).Trim(); |
438 | if (m_debugEnabled) | 435 | |
436 | OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); | ||
437 | if (binBucketOSD is OSD) | ||
439 | { | 438 | { |
440 | m_log.WarnFormat("I don't understand a group notice binary bucket of: {0}", binBucket); | 439 | OSDMap binBucketMap = (OSDMap)binBucketOSD; |
440 | |||
441 | itemID = binBucketMap["item_id"].AsUUID(); | ||
442 | ownerID = binBucketMap["owner_id"].AsUUID(); | ||
441 | 443 | ||
442 | OSDMap binBucketOSD = (OSDMap)OSDParser.DeserializeLLSDXml(binBucket); | 444 | //Attempt to get the details of the attached item. |
443 | 445 | //If sender doesn't own the attachment, the item | |
444 | foreach (string key in binBucketOSD.Keys) | 446 | //variable will be set to null and attachment will |
447 | //not be included with the group notice. | ||
448 | Scene scene = (Scene)remoteClient.Scene; | ||
449 | item = new InventoryItemBase(itemID, ownerID); | ||
450 | item = scene.InventoryService.GetItem(item); | ||
451 | |||
452 | if (item != null) | ||
445 | { | 453 | { |
446 | if (binBucketOSD.ContainsKey(key)) | 454 | //Got item details so include the attachment. |
447 | { | 455 | hasAttachment = true; |
448 | m_log.WarnFormat("{0}: {1}", key, binBucketOSD[key].ToString()); | ||
449 | } | ||
450 | } | 456 | } |
451 | } | 457 | } |
452 | 458 | else | |
453 | // treat as if no attachment | 459 | { |
460 | m_log.DebugFormat("[Groups]: Received OSD with unexpected type: {0}", binBucketOSD.GetType()); | ||
461 | } | ||
462 | } | ||
463 | |||
464 | if (hasAttachment) | ||
465 | { | ||
466 | //Bucket contains information about attachment. | ||
467 | // | ||
468 | //Byte offset and description of bucket data: | ||
469 | //0: 1 byte indicating if attachment is present | ||
470 | //1: 1 byte indicating the type of attachment | ||
471 | //2: 16 bytes - Group UUID | ||
472 | //18: 16 bytes - UUID of the attachment owner | ||
473 | //34: 16 bytes - UUID of the attachment | ||
474 | //50: variable - Name of the attachment | ||
475 | //??: NUL byte to terminate the attachment name | ||
476 | byte[] name = Encoding.UTF8.GetBytes(item.Name); | ||
477 | bucket = new byte[51 + name.Length];//3 bytes, 3 UUIDs, and name | ||
478 | bucket[0] = 1; //Has attachment flag | ||
479 | bucket[1] = (byte)item.InvType; //Type of Attachment | ||
480 | GroupID.ToBytes(bucket, 2); | ||
481 | ownerID.ToBytes(bucket, 18); | ||
482 | itemID.ToBytes(bucket, 34); | ||
483 | name.CopyTo(bucket, 50); | ||
484 | } | ||
485 | else | ||
486 | { | ||
454 | bucket = new byte[19]; | 487 | bucket = new byte[19]; |
455 | bucket[0] = 0; //dunno | 488 | bucket[0] = 0; //Has attachment flag |
456 | bucket[1] = 0; //dunno | 489 | bucket[1] = 0; //Type of attachment |
457 | GroupID.ToBytes(bucket, 2); | 490 | GroupID.ToBytes(bucket, 2); |
458 | bucket[18] = 0; //dunno | 491 | bucket[18] = 0; //NUL terminate name of attachment |
459 | } | 492 | } |
460 | 493 | ||
461 | |||
462 | m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); | 494 | m_groupData.AddGroupNotice(GetRequestingAgentID(remoteClient), GroupID, NoticeID, im.fromAgentName, Subject, Message, bucket); |
463 | if (OnNewGroupNotice != null) | 495 | if (OnNewGroupNotice != null) |
464 | { | 496 | { |
@@ -483,7 +515,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
483 | 515 | ||
484 | if (member.AcceptNotices) | 516 | if (member.AcceptNotices) |
485 | { | 517 | { |
486 | // Build notice IIM | 518 | // Build notice IM |
487 | GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); | 519 | GridInstantMessage msg = CreateGroupNoticeIM(UUID.Zero, NoticeID, (byte)OpenMetaverse.InstantMessageDialog.GroupNotice); |
488 | 520 | ||
489 | msg.toAgentID = member.AgentID.Guid; | 521 | msg.toAgentID = member.AgentID.Guid; |
@@ -492,10 +524,40 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
492 | } | 524 | } |
493 | } | 525 | } |
494 | } | 526 | } |
495 | 527 | ||
528 | if (im.dialog == (byte)InstantMessageDialog.GroupNoticeInventoryAccepted) | ||
529 | { | ||
530 | //Is bucket large enough to hold UUID of the attachment? | ||
531 | if (im.binaryBucket.Length < 16) | ||
532 | return; | ||
533 | |||
534 | UUID noticeID = new UUID(im.imSessionID); | ||
535 | |||
536 | GroupNoticeInfo notice = m_groupData.GetGroupNotice(GetRequestingAgentID(remoteClient), noticeID); | ||
537 | if (notice != null) | ||
538 | { | ||
539 | UUID giver = new UUID(notice.BinaryBucket, 18); | ||
540 | UUID attachmentUUID = new UUID(notice.BinaryBucket, 34); | ||
541 | |||
542 | if (m_debugEnabled) | ||
543 | m_log.DebugFormat("[Groups]: Giving inventory from {0} to {1}", giver, remoteClient.AgentId); | ||
544 | |||
545 | InventoryItemBase itemCopy = ((Scene)(remoteClient.Scene)).GiveInventoryItem(remoteClient.AgentId, | ||
546 | giver, attachmentUUID); | ||
547 | |||
548 | if (itemCopy == null) | ||
549 | { | ||
550 | remoteClient.SendAgentAlertMessage("Can't find item to give. Nothing given.", false); | ||
551 | return; | ||
552 | } | ||
553 | |||
554 | remoteClient.SendInventoryItemCreateUpdate(itemCopy, 0); | ||
555 | } | ||
556 | } | ||
557 | |||
496 | // Interop, received special 210 code for ejecting a group member | 558 | // Interop, received special 210 code for ejecting a group member |
497 | // this only works within the comms servers domain, and won't work hypergrid | 559 | // this only works within the comms servers domain, and won't work hypergrid |
498 | // TODO:FIXME: Use a presense server of some kind to find out where the | 560 | // TODO:FIXME: Use a presence server of some kind to find out where the |
499 | // client actually is, and try contacting that region directly to notify them, | 561 | // client actually is, and try contacting that region directly to notify them, |
500 | // or provide the notification via xmlrpc update queue | 562 | // or provide the notification via xmlrpc update queue |
501 | if ((im.dialog == 210)) | 563 | if ((im.dialog == 210)) |
@@ -873,26 +935,10 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
873 | 935 | ||
874 | if (data != null) | 936 | if (data != null) |
875 | { | 937 | { |
876 | GroupRecord groupInfo = m_groupData.GetGroupRecord(GetRequestingAgentID(remoteClient), data.GroupID, null); | 938 | GridInstantMessage msg = CreateGroupNoticeIM(remoteClient.AgentId, groupNoticeID, (byte)InstantMessageDialog.GroupNoticeRequested); |
877 | |||
878 | GridInstantMessage msg = new GridInstantMessage(); | ||
879 | msg.imSessionID = UUID.Zero.Guid; | ||
880 | msg.fromAgentID = data.GroupID.Guid; | ||
881 | msg.toAgentID = GetRequestingAgentID(remoteClient).Guid; | ||
882 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); | ||
883 | msg.fromAgentName = "Group Notice : " + groupInfo == null ? "Unknown" : groupInfo.GroupName; | ||
884 | msg.message = data.noticeData.Subject + "|" + data.Message; | ||
885 | msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNoticeRequested; | ||
886 | msg.fromGroup = true; | ||
887 | msg.offline = (byte)0; | ||
888 | msg.ParentEstateID = 0; | ||
889 | msg.Position = Vector3.Zero; | ||
890 | msg.RegionID = UUID.Zero.Guid; | ||
891 | msg.binaryBucket = data.BinaryBucket; | ||
892 | 939 | ||
893 | OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); | 940 | OutgoingInstantMessage(msg, GetRequestingAgentID(remoteClient)); |
894 | } | 941 | } |
895 | |||
896 | } | 942 | } |
897 | 943 | ||
898 | public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) | 944 | public GridInstantMessage CreateGroupNoticeIM(UUID agentID, UUID groupNoticeID, byte dialog) |
@@ -900,10 +946,11 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
900 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); | 946 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: {0} called", System.Reflection.MethodBase.GetCurrentMethod().Name); |
901 | 947 | ||
902 | GridInstantMessage msg = new GridInstantMessage(); | 948 | GridInstantMessage msg = new GridInstantMessage(); |
903 | msg.imSessionID = UUID.Zero.Guid; | 949 | byte[] bucket; |
950 | |||
951 | msg.imSessionID = groupNoticeID.Guid; | ||
904 | msg.toAgentID = agentID.Guid; | 952 | msg.toAgentID = agentID.Guid; |
905 | msg.dialog = dialog; | 953 | msg.dialog = dialog; |
906 | // msg.dialog = (byte)OpenMetaverse.InstantMessageDialog.GroupNotice; | ||
907 | msg.fromGroup = true; | 954 | msg.fromGroup = true; |
908 | msg.offline = (byte)0; | 955 | msg.offline = (byte)0; |
909 | msg.ParentEstateID = 0; | 956 | msg.ParentEstateID = 0; |
@@ -917,13 +964,38 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
917 | msg.timestamp = info.noticeData.Timestamp; | 964 | msg.timestamp = info.noticeData.Timestamp; |
918 | msg.fromAgentName = info.noticeData.FromName; | 965 | msg.fromAgentName = info.noticeData.FromName; |
919 | msg.message = info.noticeData.Subject + "|" + info.Message; | 966 | msg.message = info.noticeData.Subject + "|" + info.Message; |
920 | msg.binaryBucket = info.BinaryBucket; | 967 | |
968 | if (info.BinaryBucket[0] > 0) | ||
969 | { | ||
970 | //32 is due to not needing space for two of the UUIDs. | ||
971 | //(Don't need UUID of attachment or its owner in IM) | ||
972 | //50 offset gets us to start of attachment name. | ||
973 | //We are skipping the attachment flag, type, and | ||
974 | //the three UUID fields at the start of the bucket. | ||
975 | bucket = new byte[info.BinaryBucket.Length-32]; | ||
976 | bucket[0] = 1; //Has attachment | ||
977 | bucket[1] = info.BinaryBucket[1]; | ||
978 | Array.Copy(info.BinaryBucket, 50, | ||
979 | bucket, 18, info.BinaryBucket.Length-50); | ||
980 | } | ||
981 | else | ||
982 | { | ||
983 | bucket = new byte[19]; | ||
984 | bucket[0] = 0; //No attachment | ||
985 | bucket[1] = 0; //Attachment type | ||
986 | bucket[18] = 0; //NUL terminate name | ||
987 | } | ||
988 | |||
989 | info.GroupID.ToBytes(bucket, 2); | ||
990 | msg.binaryBucket = bucket; | ||
921 | } | 991 | } |
922 | else | 992 | else |
923 | { | 993 | { |
924 | if (m_debugEnabled) m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID); | 994 | if (m_debugEnabled) |
995 | m_log.DebugFormat("[GROUPS]: Group Notice {0} not found, composing empty message.", groupNoticeID); | ||
996 | |||
925 | msg.fromAgentID = UUID.Zero.Guid; | 997 | msg.fromAgentID = UUID.Zero.Guid; |
926 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); ; | 998 | msg.timestamp = (uint)Util.UnixTimeSinceEpoch(); |
927 | msg.fromAgentName = string.Empty; | 999 | msg.fromAgentName = string.Empty; |
928 | msg.message = string.Empty; | 1000 | msg.message = string.Empty; |
929 | msg.binaryBucket = new byte[0]; | 1001 | msg.binaryBucket = new byte[0]; |
@@ -1047,7 +1119,7 @@ namespace OpenSim.Region.OptionalModules.Avatar.XmlRpcGroups | |||
1047 | // Message to ejector | 1119 | // Message to ejector |
1048 | // Interop, received special 210 code for ejecting a group member | 1120 | // Interop, received special 210 code for ejecting a group member |
1049 | // this only works within the comms servers domain, and won't work hypergrid | 1121 | // this only works within the comms servers domain, and won't work hypergrid |
1050 | // TODO:FIXME: Use a presense server of some kind to find out where the | 1122 | // TODO:FIXME: Use a presence server of some kind to find out where the |
1051 | // client actually is, and try contacting that region directly to notify them, | 1123 | // client actually is, and try contacting that region directly to notify them, |
1052 | // or provide the notification via xmlrpc update queue | 1124 | // or provide the notification via xmlrpc update queue |
1053 | 1125 | ||
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs index f0d17d3..7b98f9d 100644 --- a/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSDynamics.cs | |||
@@ -1125,7 +1125,19 @@ namespace OpenSim.Region.Physics.BulletSPlugin | |||
1125 | { | 1125 | { |
1126 | // If body is already heigher, use its height as target height | 1126 | // If body is already heigher, use its height as target height |
1127 | if (VehiclePosition.Z > m_VhoverTargetHeight) | 1127 | if (VehiclePosition.Z > m_VhoverTargetHeight) |
1128 | { | ||
1128 | m_VhoverTargetHeight = VehiclePosition.Z; | 1129 | m_VhoverTargetHeight = VehiclePosition.Z; |
1130 | |||
1131 | // A 'misfeature' of this flag is that if the vehicle is above it's hover height, | ||
1132 | // the vehicle's buoyancy goes away. This is an SL bug that got used by so many | ||
1133 | // scripts that it could not be changed. | ||
1134 | // So, if above the height, reapply gravity if buoyancy had it turned off. | ||
1135 | if (m_VehicleBuoyancy != 0) | ||
1136 | { | ||
1137 | Vector3 appliedGravity = ControllingPrim.ComputeGravity(ControllingPrim.Buoyancy) * m_vehicleMass; | ||
1138 | VehicleAddForce(appliedGravity); | ||
1139 | } | ||
1140 | } | ||
1129 | } | 1141 | } |
1130 | 1142 | ||
1131 | if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) | 1143 | if ((m_flags & VehicleFlag.LOCK_HOVER_HEIGHT) != 0) |
diff --git a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs index c4807c4..c016eed 100755 --- a/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs +++ b/OpenSim/Region/Physics/BulletSPlugin/BSTerrainManager.cs | |||
@@ -354,6 +354,8 @@ public sealed class BSTerrainManager : IDisposable | |||
354 | // Return a new position that is over known terrain if the position is outside our terrain. | 354 | // Return a new position that is over known terrain if the position is outside our terrain. |
355 | public Vector3 ClampPositionIntoKnownTerrain(Vector3 pPos) | 355 | public Vector3 ClampPositionIntoKnownTerrain(Vector3 pPos) |
356 | { | 356 | { |
357 | float edgeEpsilon = 0.1f; | ||
358 | |||
357 | Vector3 ret = pPos; | 359 | Vector3 ret = pPos; |
358 | 360 | ||
359 | // First, base addresses are never negative so correct for that possible problem. | 361 | // First, base addresses are never negative so correct for that possible problem. |
@@ -378,10 +380,19 @@ public sealed class BSTerrainManager : IDisposable | |||
378 | // NOTE that GetTerrainPhysicalAtXYZ will set 'terrainBaseXYZ' to the base of the unfound region. | 380 | // NOTE that GetTerrainPhysicalAtXYZ will set 'terrainBaseXYZ' to the base of the unfound region. |
379 | 381 | ||
380 | // Must be off the top of a region. Find an adjacent region to move into. | 382 | // Must be off the top of a region. Find an adjacent region to move into. |
383 | // The returned terrain is always 'lower'. That is, closer to <0,0>. | ||
381 | Vector3 adjacentTerrainBase = FindAdjacentTerrainBase(terrainBaseXYZ); | 384 | Vector3 adjacentTerrainBase = FindAdjacentTerrainBase(terrainBaseXYZ); |
382 | 385 | ||
383 | ret.X = Math.Min(ret.X, adjacentTerrainBase.X + (ret.X % DefaultRegionSize.X)); | 386 | if (adjacentTerrainBase.X < terrainBaseXYZ.X) |
384 | ret.Y = Math.Min(ret.Y, adjacentTerrainBase.Y + (ret.X % DefaultRegionSize.Y)); | 387 | { |
388 | // moving down into a new region in the X dimension. New position will be the max in the new base. | ||
389 | ret.X = adjacentTerrainBase.X + DefaultRegionSize.X - edgeEpsilon; | ||
390 | } | ||
391 | if (adjacentTerrainBase.Y < terrainBaseXYZ.Y) | ||
392 | { | ||
393 | // moving down into a new region in the X dimension. New position will be the max in the new base. | ||
394 | ret.Y = adjacentTerrainBase.Y + DefaultRegionSize.Y - edgeEpsilon; | ||
395 | } | ||
385 | DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,findingAdjacentRegion,adjacentRegBase={1},oldPos={2},newPos={3}", | 396 | DetailLog("{0},BSTerrainManager.ClampPositionToKnownTerrain,findingAdjacentRegion,adjacentRegBase={1},oldPos={2},newPos={3}", |
386 | BSScene.DetailLogZero, adjacentTerrainBase, pPos, ret); | 397 | BSScene.DetailLogZero, adjacentTerrainBase, pPos, ret); |
387 | 398 | ||
diff --git a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs index 2ac0805..e03cf17 100644 --- a/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs +++ b/OpenSim/Region/ScriptEngine/Shared/Api/Implementation/LSL_Api.cs | |||
@@ -2970,37 +2970,40 @@ namespace OpenSim.Region.ScriptEngine.Shared.Api | |||
2970 | // need the magnitude later | 2970 | // need the magnitude later |
2971 | // float velmag = (float)Util.GetMagnitude(llvel); | 2971 | // float velmag = (float)Util.GetMagnitude(llvel); |
2972 | 2972 | ||
2973 | SceneObjectGroup new_group = World.RezObject(m_host, item, pos, rot, vel, param); | 2973 | List<SceneObjectGroup> new_groups = World.RezObject(m_host, item, pos, rot, vel, param); |
2974 | 2974 | ||
2975 | // If either of these are null, then there was an unknown error. | 2975 | // If either of these are null, then there was an unknown error. |
2976 | if (new_group == null) | 2976 | if (new_groups == null) |
2977 | return; | 2977 | return; |
2978 | 2978 | ||
2979 | // objects rezzed with this method are die_at_edge by default. | 2979 | foreach (SceneObjectGroup group in new_groups) |
2980 | new_group.RootPart.SetDieAtEdge(true); | 2980 | { |
2981 | // objects rezzed with this method are die_at_edge by default. | ||
2982 | group.RootPart.SetDieAtEdge(true); | ||
2981 | 2983 | ||
2982 | new_group.ResumeScripts(); | 2984 | group.ResumeScripts(); |
2983 | 2985 | ||
2984 | m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams( | 2986 | m_ScriptEngine.PostObjectEvent(m_host.LocalId, new EventParams( |
2985 | "object_rez", new Object[] { | 2987 | "object_rez", new Object[] { |
2986 | new LSL_String( | 2988 | new LSL_String( |
2987 | new_group.RootPart.UUID.ToString()) }, | 2989 | group.RootPart.UUID.ToString()) }, |
2988 | new DetectParams[0])); | 2990 | new DetectParams[0])); |
2989 | 2991 | ||
2990 | float groupmass = new_group.GetMass(); | 2992 | float groupmass = group.GetMass(); |
2991 | 2993 | ||
2992 | PhysicsActor pa = new_group.RootPart.PhysActor; | 2994 | PhysicsActor pa = group.RootPart.PhysActor; |
2993 | 2995 | ||
2994 | //Recoil. | 2996 | //Recoil. |
2995 | if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) | 2997 | if (pa != null && pa.IsPhysical && (Vector3)vel != Vector3.Zero) |
2996 | { | ||
2997 | Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; | ||
2998 | if (recoil != Vector3.Zero) | ||
2999 | { | 2998 | { |
3000 | llApplyImpulse(recoil, 0); | 2999 | Vector3 recoil = -vel * groupmass * m_recoilScaleFactor; |
3000 | if (recoil != Vector3.Zero) | ||
3001 | { | ||
3002 | llApplyImpulse(recoil, 0); | ||
3003 | } | ||
3001 | } | 3004 | } |
3005 | // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) | ||
3002 | } | 3006 | } |
3003 | // Variable script delay? (see (http://wiki.secondlife.com/wiki/LSL_Delay) | ||
3004 | }); | 3007 | }); |
3005 | 3008 | ||
3006 | //ScriptSleep((int)((groupmass * velmag) / 10)); | 3009 | //ScriptSleep((int)((groupmass * velmag) / 10)); |