diff options
Diffstat (limited to 'OpenSim/Region/CoreModules/Framework/InventoryAccess')
5 files changed, 639 insertions, 295 deletions
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs index 7871eda..f54298c 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGAssetMapper.cs | |||
@@ -35,6 +35,7 @@ using System.Xml; | |||
35 | using log4net; | 35 | using log4net; |
36 | using OpenMetaverse; | 36 | using OpenMetaverse; |
37 | using OpenSim.Framework; | 37 | using OpenSim.Framework; |
38 | using OpenSim.Framework.Serialization.External; | ||
38 | 39 | ||
39 | using OpenSim.Region.Framework.Scenes; | 40 | using OpenSim.Region.Framework.Scenes; |
40 | using OpenSim.Region.Framework.Scenes.Serialization; | 41 | using OpenSim.Region.Framework.Scenes.Serialization; |
@@ -73,6 +74,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
73 | 74 | ||
74 | private AssetMetadata FetchMetadata(string url, UUID assetID) | 75 | private AssetMetadata FetchMetadata(string url, UUID assetID) |
75 | { | 76 | { |
77 | if (string.IsNullOrEmpty(url)) | ||
78 | return null; | ||
79 | |||
76 | if (!url.EndsWith("/") && !url.EndsWith("=")) | 80 | if (!url.EndsWith("/") && !url.EndsWith("=")) |
77 | url = url + "/"; | 81 | url = url + "/"; |
78 | 82 | ||
@@ -92,6 +96,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
92 | AssetBase asset = m_scene.AssetService.Get(assetID.ToString()); | 96 | AssetBase asset = m_scene.AssetService.Get(assetID.ToString()); |
93 | if (asset == null) | 97 | if (asset == null) |
94 | { | 98 | { |
99 | if (string.IsNullOrEmpty(url)) | ||
100 | return null; | ||
101 | |||
95 | if (!url.EndsWith("/") && !url.EndsWith("=")) | 102 | if (!url.EndsWith("/") && !url.EndsWith("=")) |
96 | url = url + "/"; | 103 | url = url + "/"; |
97 | 104 | ||
@@ -109,45 +116,47 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
109 | 116 | ||
110 | public bool PostAsset(string url, AssetBase asset) | 117 | public bool PostAsset(string url, AssetBase asset) |
111 | { | 118 | { |
112 | if (asset != null) | 119 | if (string.IsNullOrEmpty(url)) |
113 | { | 120 | return false; |
114 | if (!url.EndsWith("/") && !url.EndsWith("=")) | ||
115 | url = url + "/"; | ||
116 | 121 | ||
117 | bool success = true; | 122 | if (!url.EndsWith("/") && !url.EndsWith("=")) |
118 | // See long comment in AssetCache.AddAsset | 123 | url = url + "/"; |
119 | if (!asset.Temporary || asset.Local) | ||
120 | { | ||
121 | // We need to copy the asset into a new asset, because | ||
122 | // we need to set its ID to be URL+UUID, so that the | ||
123 | // HGAssetService dispatches it to the remote grid. | ||
124 | // It's not pretty, but the best that can be done while | ||
125 | // not having a global naming infrastructure | ||
126 | AssetBase asset1 = new AssetBase(asset.FullID, asset.Name, asset.Type, asset.Metadata.CreatorID); | ||
127 | Copy(asset, asset1); | ||
128 | asset1.ID = url + asset.ID; | ||
129 | |||
130 | AdjustIdentifiers(asset1.Metadata); | ||
131 | if (asset1.Metadata.Type == (sbyte)AssetType.Object) | ||
132 | asset1.Data = AdjustIdentifiers(asset.Data); | ||
133 | else | ||
134 | asset1.Data = asset.Data; | ||
135 | 124 | ||
136 | string id = m_scene.AssetService.Store(asset1); | 125 | if (asset == null) |
137 | if (id == string.Empty) | 126 | { |
138 | { | 127 | m_log.Warn("[HG ASSET MAPPER]: Tried to post asset to remote server, but asset not in local cache."); |
139 | m_log.DebugFormat("[HG ASSET MAPPER]: Asset server {0} did not accept {1}", url, asset.ID); | 128 | return false; |
140 | success = false; | ||
141 | } | ||
142 | else | ||
143 | m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url); | ||
144 | } | ||
145 | return success; | ||
146 | } | 129 | } |
130 | |||
131 | // See long comment in AssetCache.AddAsset | ||
132 | if (asset.Temporary || asset.Local) | ||
133 | return true; | ||
134 | |||
135 | // We need to copy the asset into a new asset, because | ||
136 | // we need to set its ID to be URL+UUID, so that the | ||
137 | // HGAssetService dispatches it to the remote grid. | ||
138 | // It's not pretty, but the best that can be done while | ||
139 | // not having a global naming infrastructure | ||
140 | AssetBase asset1 = new AssetBase(asset.FullID, asset.Name, asset.Type, asset.Metadata.CreatorID); | ||
141 | Copy(asset, asset1); | ||
142 | asset1.ID = url + asset.ID; | ||
143 | |||
144 | AdjustIdentifiers(asset1.Metadata); | ||
145 | if (asset1.Metadata.Type == (sbyte)AssetType.Object) | ||
146 | asset1.Data = AdjustIdentifiers(asset.Data); | ||
147 | else | 147 | else |
148 | m_log.Warn("[HG ASSET MAPPER]: Tried to post asset to remote server, but asset not in local cache."); | 148 | asset1.Data = asset.Data; |
149 | 149 | ||
150 | return false; | 150 | string id = m_scene.AssetService.Store(asset1); |
151 | if (String.IsNullOrEmpty(id)) | ||
152 | { | ||
153 | m_log.DebugFormat("[HG ASSET MAPPER]: Asset server {0} did not accept {1}", url, asset.ID); | ||
154 | return false; | ||
155 | } | ||
156 | else { | ||
157 | m_log.DebugFormat("[HG ASSET MAPPER]: Posted copy of asset {0} from local asset server to {1}", asset1.ID, url); | ||
158 | return true; | ||
159 | } | ||
151 | } | 160 | } |
152 | 161 | ||
153 | private void Copy(AssetBase from, AssetBase to) | 162 | private void Copy(AssetBase from, AssetBase to) |
@@ -165,7 +174,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
165 | 174 | ||
166 | private void AdjustIdentifiers(AssetMetadata meta) | 175 | private void AdjustIdentifiers(AssetMetadata meta) |
167 | { | 176 | { |
168 | if (meta.CreatorID != null && meta.CreatorID != string.Empty) | 177 | if (!string.IsNullOrEmpty(meta.CreatorID)) |
169 | { | 178 | { |
170 | UUID uuid = UUID.Zero; | 179 | UUID uuid = UUID.Zero; |
171 | UUID.TryParse(meta.CreatorID, out uuid); | 180 | UUID.TryParse(meta.CreatorID, out uuid); |
@@ -181,49 +190,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
181 | return Utils.StringToBytes(RewriteSOP(xml)); | 190 | return Utils.StringToBytes(RewriteSOP(xml)); |
182 | } | 191 | } |
183 | 192 | ||
184 | protected string RewriteSOP(string xml) | 193 | protected string RewriteSOP(string xmlData) |
185 | { | 194 | { |
186 | XmlDocument doc = new XmlDocument(); | 195 | // Console.WriteLine("Input XML [{0}]", xmlData); |
187 | doc.LoadXml(xml); | 196 | return ExternalRepresentationUtils.RewriteSOP(xmlData, m_scene.Name, m_HomeURI, m_scene.UserAccountService, m_scene.RegionInfo.ScopeID); |
188 | XmlNodeList sops = doc.GetElementsByTagName("SceneObjectPart"); | ||
189 | |||
190 | foreach (XmlNode sop in sops) | ||
191 | { | ||
192 | UserAccount creator = null; | ||
193 | bool hasCreatorData = false; | ||
194 | XmlNodeList nodes = sop.ChildNodes; | ||
195 | foreach (XmlNode node in nodes) | ||
196 | { | ||
197 | if (node.Name == "CreatorID") | ||
198 | { | ||
199 | UUID uuid = UUID.Zero; | ||
200 | UUID.TryParse(node.InnerText, out uuid); | ||
201 | creator = m_scene.UserAccountService.GetUserAccount(m_scene.RegionInfo.ScopeID, uuid); | ||
202 | } | ||
203 | if (node.Name == "CreatorData" && node.InnerText != null && node.InnerText != string.Empty) | ||
204 | hasCreatorData = true; | ||
205 | |||
206 | //if (node.Name == "OwnerID") | ||
207 | //{ | ||
208 | // UserAccount owner = GetUser(node.InnerText); | ||
209 | // if (owner != null) | ||
210 | // node.InnerText = m_ProfileServiceURL + "/" + node.InnerText + "/" + owner.FirstName + " " + owner.LastName; | ||
211 | //} | ||
212 | } | ||
213 | |||
214 | if (!hasCreatorData && creator != null) | ||
215 | { | ||
216 | XmlElement creatorData = doc.CreateElement("CreatorData"); | ||
217 | creatorData.InnerText = m_HomeURI + ";" + creator.FirstName + " " + creator.LastName; | ||
218 | sop.AppendChild(creatorData); | ||
219 | } | ||
220 | } | ||
221 | |||
222 | using (StringWriter wr = new StringWriter()) | ||
223 | { | ||
224 | doc.Save(wr); | ||
225 | return wr.ToString(); | ||
226 | } | ||
227 | 197 | ||
228 | } | 198 | } |
229 | 199 | ||
@@ -251,12 +221,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
251 | 221 | ||
252 | // The act of gathering UUIDs downloads some assets from the remote server | 222 | // The act of gathering UUIDs downloads some assets from the remote server |
253 | // but not all... | 223 | // but not all... |
254 | Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); | ||
255 | HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL); | 224 | HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, userAssetURL); |
256 | uuidGatherer.GatherAssetUuids(assetID, (AssetType)meta.Type, ids); | 225 | uuidGatherer.AddForInspection(assetID); |
257 | m_log.DebugFormat("[HG ASSET MAPPER]: Preparing to get {0} assets", ids.Count); | 226 | uuidGatherer.GatherAll(); |
227 | |||
228 | m_log.DebugFormat("[HG ASSET MAPPER]: Preparing to get {0} assets", uuidGatherer.GatheredUuids.Count); | ||
258 | bool success = true; | 229 | bool success = true; |
259 | foreach (UUID uuid in ids.Keys) | 230 | foreach (UUID uuid in uuidGatherer.GatheredUuids.Keys) |
260 | if (FetchAsset(userAssetURL, uuid) == null) | 231 | if (FetchAsset(userAssetURL, uuid) == null) |
261 | success = false; | 232 | success = false; |
262 | 233 | ||
@@ -267,39 +238,92 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
267 | m_log.DebugFormat("[HG ASSET MAPPER]: Successfully got item {0} from asset server {1}", assetID, userAssetURL); | 238 | m_log.DebugFormat("[HG ASSET MAPPER]: Successfully got item {0} from asset server {1}", assetID, userAssetURL); |
268 | } | 239 | } |
269 | 240 | ||
270 | |||
271 | public void Post(UUID assetID, UUID ownerID, string userAssetURL) | 241 | public void Post(UUID assetID, UUID ownerID, string userAssetURL) |
272 | { | 242 | { |
273 | // Post the item from the local AssetCache onto the remote asset server | 243 | m_log.DebugFormat("[HG ASSET MAPPER]: Starting to send asset {0} with children to asset server {1}", assetID, userAssetURL); |
274 | // and place an entry in m_assetMap | 244 | |
245 | // Find all the embedded assets | ||
275 | 246 | ||
276 | m_log.Debug("[HG ASSET MAPPER]: Posting object " + assetID + " to asset server " + userAssetURL); | ||
277 | AssetBase asset = m_scene.AssetService.Get(assetID.ToString()); | 247 | AssetBase asset = m_scene.AssetService.Get(assetID.ToString()); |
278 | if (asset != null) | 248 | if (asset == null) |
249 | { | ||
250 | m_log.DebugFormat("[HG ASSET MAPPER]: Something wrong with asset {0}, it could not be found", assetID); | ||
251 | return; | ||
252 | } | ||
253 | |||
254 | HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, string.Empty); | ||
255 | uuidGatherer.AddForInspection(asset.FullID); | ||
256 | uuidGatherer.GatherAll(); | ||
257 | |||
258 | // Check which assets already exist in the destination server | ||
259 | |||
260 | string url = userAssetURL; | ||
261 | if (!url.EndsWith("/") && !url.EndsWith("=")) | ||
262 | url = url + "/"; | ||
263 | |||
264 | string[] remoteAssetIDs = new string[uuidGatherer.GatheredUuids.Count]; | ||
265 | int i = 0; | ||
266 | foreach (UUID id in uuidGatherer.GatheredUuids.Keys) | ||
267 | remoteAssetIDs[i++] = url + id.ToString(); | ||
268 | |||
269 | bool[] exist = m_scene.AssetService.AssetsExist(remoteAssetIDs); | ||
270 | |||
271 | var existSet = new HashSet<string>(); | ||
272 | i = 0; | ||
273 | foreach (UUID id in uuidGatherer.GatheredUuids.Keys) | ||
274 | { | ||
275 | if (exist[i]) | ||
276 | existSet.Add(id.ToString()); | ||
277 | ++i; | ||
278 | } | ||
279 | |||
280 | // Send only those assets which don't already exist in the destination server | ||
281 | |||
282 | bool success = true; | ||
283 | |||
284 | foreach (UUID uuid in uuidGatherer.GatheredUuids.Keys) | ||
279 | { | 285 | { |
280 | Dictionary<UUID, AssetType> ids = new Dictionary<UUID, AssetType>(); | 286 | if (!existSet.Contains(uuid.ToString())) |
281 | HGUuidGatherer uuidGatherer = new HGUuidGatherer(m_scene.AssetService, string.Empty); | ||
282 | uuidGatherer.GatherAssetUuids(asset.FullID, (AssetType)asset.Type, ids); | ||
283 | bool success = false; | ||
284 | foreach (UUID uuid in ids.Keys) | ||
285 | { | 287 | { |
286 | asset = m_scene.AssetService.Get(uuid.ToString()); | 288 | asset = m_scene.AssetService.Get(uuid.ToString()); |
287 | if (asset == null) | 289 | if (asset == null) |
290 | { | ||
288 | m_log.DebugFormat("[HG ASSET MAPPER]: Could not find asset {0}", uuid); | 291 | m_log.DebugFormat("[HG ASSET MAPPER]: Could not find asset {0}", uuid); |
292 | } | ||
289 | else | 293 | else |
290 | success = PostAsset(userAssetURL, asset); | 294 | { |
295 | try | ||
296 | { | ||
297 | success &= PostAsset(userAssetURL, asset); | ||
298 | } | ||
299 | catch (Exception e) | ||
300 | { | ||
301 | m_log.Error( | ||
302 | string.Format( | ||
303 | "[HG ASSET MAPPER]: Failed to post asset {0} (type {1}, length {2}) referenced from {3} to {4} with exception ", | ||
304 | asset.ID, asset.Type, asset.Data.Length, assetID, userAssetURL), | ||
305 | e); | ||
306 | |||
307 | // For debugging purposes for now we will continue to throw the exception up the stack as was already happening. However, after | ||
308 | // debugging we may want to simply report the failure if we can tell this is due to a failure | ||
309 | // with a particular asset and not a destination network failure where all asset posts will fail (and | ||
310 | // generate large amounts of log spam). | ||
311 | throw e; | ||
312 | } | ||
313 | } | ||
291 | } | 314 | } |
292 | |||
293 | // maybe all pieces got there... | ||
294 | if (!success) | ||
295 | m_log.DebugFormat("[HG ASSET MAPPER]: Problems posting item {0} to asset server {1}", assetID, userAssetURL); | ||
296 | else | 315 | else |
297 | m_log.DebugFormat("[HG ASSET MAPPER]: Successfully posted item {0} to asset server {1}", assetID, userAssetURL); | 316 | { |
298 | 317 | m_log.DebugFormat( | |
318 | "[HG ASSET MAPPER]: Didn't post asset {0} referenced from {1} because it already exists in asset server {2}", | ||
319 | uuid, assetID, userAssetURL); | ||
320 | } | ||
299 | } | 321 | } |
300 | else | ||
301 | m_log.DebugFormat("[HG ASSET MAPPER]: Something wrong with asset {0}, it could not be found", assetID); | ||
302 | 322 | ||
323 | if (!success) | ||
324 | m_log.DebugFormat("[HG ASSET MAPPER]: Problems sending asset {0} with children to asset server {1}", assetID, userAssetURL); | ||
325 | else | ||
326 | m_log.DebugFormat("[HG ASSET MAPPER]: Successfully sent asset {0} with children to asset server {1}", assetID, userAssetURL); | ||
303 | } | 327 | } |
304 | 328 | ||
305 | #endregion | 329 | #endregion |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs index 964efda..582b267 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/HGInventoryAccessModule.cs | |||
@@ -62,6 +62,17 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
62 | private string m_ThisGatekeeper; | 62 | private string m_ThisGatekeeper; |
63 | private bool m_RestrictInventoryAccessAbroad; | 63 | private bool m_RestrictInventoryAccessAbroad; |
64 | 64 | ||
65 | private bool m_bypassPermissions = true; | ||
66 | |||
67 | // This simple check makes it possible to support grids in which all the simulators | ||
68 | // share all central services of the Robust server EXCEPT assets. In other words, | ||
69 | // grids where the simulators' assets are kept in one DB and the users' inventory assets | ||
70 | // are kept on another. When users rez items from inventory or take objects from world, | ||
71 | // an HG-like asset copy takes place between the 2 servers, the world asset server and | ||
72 | // the user's asset server. | ||
73 | private bool m_CheckSeparateAssets = false; | ||
74 | private string m_LocalAssetsURL = string.Empty; | ||
75 | |||
65 | // private bool m_Initialized = false; | 76 | // private bool m_Initialized = false; |
66 | 77 | ||
67 | #region INonSharedRegionModule | 78 | #region INonSharedRegionModule |
@@ -88,16 +99,26 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
88 | IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; | 99 | IConfig thisModuleConfig = source.Configs["HGInventoryAccessModule"]; |
89 | if (thisModuleConfig != null) | 100 | if (thisModuleConfig != null) |
90 | { | 101 | { |
91 | // legacy configuration [obsolete] | 102 | m_HomeURI = Util.GetConfigVarFromSections<string>(source, "HomeURI", |
92 | m_HomeURI = thisModuleConfig.GetString("ProfileServerURI", string.Empty); | 103 | new string[] { "Startup", "Hypergrid", "HGInventoryAccessModule" }, String.Empty); |
93 | // preferred | 104 | m_ThisGatekeeper = Util.GetConfigVarFromSections<string>(source, "GatekeeperURI", |
94 | m_HomeURI = thisModuleConfig.GetString("HomeURI", m_HomeURI); | 105 | new string[] { "Startup", "Hypergrid", "HGInventoryAccessModule" }, String.Empty); |
106 | // Legacy. Renove soon! | ||
107 | m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", m_ThisGatekeeper); | ||
108 | |||
95 | m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); | 109 | m_OutboundPermission = thisModuleConfig.GetBoolean("OutboundPermission", true); |
96 | m_ThisGatekeeper = thisModuleConfig.GetString("Gatekeeper", string.Empty); | ||
97 | m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", true); | 110 | m_RestrictInventoryAccessAbroad = thisModuleConfig.GetBoolean("RestrictInventoryAccessAbroad", true); |
111 | m_CheckSeparateAssets = thisModuleConfig.GetBoolean("CheckSeparateAssets", false); | ||
112 | m_LocalAssetsURL = thisModuleConfig.GetString("RegionHGAssetServerURI", string.Empty); | ||
113 | m_LocalAssetsURL = m_LocalAssetsURL.Trim(new char[] { '/' }); | ||
114 | |||
98 | } | 115 | } |
99 | else | 116 | else |
100 | m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); | 117 | m_log.Warn("[HG INVENTORY ACCESS MODULE]: HGInventoryAccessModule configs not found. ProfileServerURI not set!"); |
118 | |||
119 | m_bypassPermissions = !Util.GetConfigVarFromSections<bool>(source, "serverside_object_permissions", | ||
120 | new string[] { "Startup", "Permissions" }, true); | ||
121 | |||
101 | } | 122 | } |
102 | } | 123 | } |
103 | } | 124 | } |
@@ -109,9 +130,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
109 | 130 | ||
110 | base.AddRegion(scene); | 131 | base.AddRegion(scene); |
111 | m_assMapper = new HGAssetMapper(scene, m_HomeURI); | 132 | m_assMapper = new HGAssetMapper(scene, m_HomeURI); |
112 | scene.EventManager.OnNewInventoryItemUploadComplete += UploadInventoryItem; | 133 | scene.EventManager.OnNewInventoryItemUploadComplete += PostInventoryAsset; |
113 | scene.EventManager.OnTeleportStart += TeleportStart; | 134 | scene.EventManager.OnTeleportStart += TeleportStart; |
114 | scene.EventManager.OnTeleportFail += TeleportFail; | 135 | scene.EventManager.OnTeleportFail += TeleportFail; |
136 | |||
137 | // We're fgoing to enforce some stricter permissions if Outbound is false | ||
138 | scene.Permissions.OnTakeObject += CanTakeObject; | ||
139 | scene.Permissions.OnTakeCopyObject += CanTakeObject; | ||
140 | scene.Permissions.OnTransferUserInventory += OnTransferUserInventory; | ||
115 | } | 141 | } |
116 | 142 | ||
117 | #endregion | 143 | #endregion |
@@ -133,7 +159,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
133 | if (sp is ScenePresence) | 159 | if (sp is ScenePresence) |
134 | { | 160 | { |
135 | AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId); | 161 | AgentCircuitData aCircuit = ((ScenePresence)sp).Scene.AuthenticateHandler.GetAgentCircuitData(client.AgentId); |
136 | if ((aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) | 162 | if (aCircuit != null && (aCircuit.teleportFlags & (uint)Constants.TeleportFlags.ViaHGLogin) != 0) |
137 | { | 163 | { |
138 | if (m_RestrictInventoryAccessAbroad) | 164 | if (m_RestrictInventoryAccessAbroad) |
139 | { | 165 | { |
@@ -183,8 +209,11 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
183 | } | 209 | } |
184 | } | 210 | } |
185 | 211 | ||
186 | public void UploadInventoryItem(UUID avatarID, UUID assetID, string name, int userlevel) | 212 | public void PostInventoryAsset(UUID avatarID, AssetType type, UUID assetID, string name, int userlevel) |
187 | { | 213 | { |
214 | if (type == AssetType.Link) | ||
215 | return; | ||
216 | |||
188 | string userAssetServer = string.Empty; | 217 | string userAssetServer = string.Empty; |
189 | if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission) | 218 | if (IsForeignUser(avatarID, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission) |
190 | { | 219 | { |
@@ -219,18 +248,32 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
219 | { | 248 | { |
220 | UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data); | 249 | UUID newAssetID = base.CapsUpdateInventoryItemAsset(remoteClient, itemID, data); |
221 | 250 | ||
222 | UploadInventoryItem(remoteClient.AgentId, newAssetID, "", 0); | 251 | PostInventoryAsset(remoteClient.AgentId, AssetType.Unknown, newAssetID, "", 0); |
223 | 252 | ||
224 | return newAssetID; | 253 | return newAssetID; |
225 | } | 254 | } |
226 | 255 | ||
256 | /// | ||
257 | /// UpdateInventoryItemAsset | ||
258 | /// | ||
259 | public override bool UpdateInventoryItemAsset(UUID ownerID, InventoryItemBase item, AssetBase asset) | ||
260 | { | ||
261 | if (base.UpdateInventoryItemAsset(ownerID, item, asset)) | ||
262 | { | ||
263 | PostInventoryAsset(ownerID, (AssetType)asset.Type, asset.FullID, asset.Name, 0); | ||
264 | return true; | ||
265 | } | ||
266 | |||
267 | return false; | ||
268 | } | ||
269 | |||
227 | /// | 270 | /// |
228 | /// Used in DeleteToInventory | 271 | /// Used in DeleteToInventory |
229 | /// | 272 | /// |
230 | protected override void ExportAsset(UUID agentID, UUID assetID) | 273 | protected override void ExportAsset(UUID agentID, UUID assetID) |
231 | { | 274 | { |
232 | if (!assetID.Equals(UUID.Zero)) | 275 | if (!assetID.Equals(UUID.Zero)) |
233 | UploadInventoryItem(agentID, assetID, "", 0); | 276 | PostInventoryAsset(agentID, AssetType.Unknown, assetID, "", 0); |
234 | else | 277 | else |
235 | m_log.Debug("[HGScene]: Scene.Inventory did not create asset"); | 278 | m_log.Debug("[HGScene]: Scene.Inventory did not create asset"); |
236 | } | 279 | } |
@@ -242,7 +285,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
242 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, | 285 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, |
243 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) | 286 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) |
244 | { | 287 | { |
245 | m_log.DebugFormat("[HGScene] RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID); | 288 | m_log.DebugFormat("[HGScene]: RezObject itemID={0} fromTaskID={1}", itemID, fromTaskID); |
246 | 289 | ||
247 | //if (fromTaskID.Equals(UUID.Zero)) | 290 | //if (fromTaskID.Equals(UUID.Zero)) |
248 | //{ | 291 | //{ |
@@ -268,50 +311,98 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
268 | SceneObjectGroup sog = base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, | 311 | SceneObjectGroup sog = base.RezObject(remoteClient, itemID, RayEnd, RayStart, RayTargetID, BypassRayCast, RayEndIsIntersection, |
269 | RezSelected, RemoveItem, fromTaskID, attachment); | 312 | RezSelected, RemoveItem, fromTaskID, attachment); |
270 | 313 | ||
271 | if (sog == null) | ||
272 | remoteClient.SendAgentAlertMessage("Unable to rez: problem accessing inventory or locating assets", false); | ||
273 | |||
274 | return sog; | 314 | return sog; |
275 | 315 | ||
276 | } | 316 | } |
277 | 317 | ||
278 | public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver) | 318 | public override void TransferInventoryAssets(InventoryItemBase item, UUID sender, UUID receiver) |
279 | { | 319 | { |
280 | string userAssetServer = string.Empty; | 320 | string senderAssetServer = string.Empty; |
281 | if (IsForeignUser(sender, out userAssetServer) && userAssetServer != string.Empty) | 321 | string receiverAssetServer = string.Empty; |
282 | m_assMapper.Get(item.AssetID, sender, userAssetServer); | 322 | bool isForeignSender, isForeignReceiver; |
323 | isForeignSender = IsForeignUser(sender, out senderAssetServer); | ||
324 | isForeignReceiver = IsForeignUser(receiver, out receiverAssetServer); | ||
325 | |||
326 | // They're both local. Nothing to do. | ||
327 | if (!isForeignSender && !isForeignReceiver) | ||
328 | return; | ||
329 | |||
330 | // At least one of them is foreign. | ||
331 | // If both users have the same asset server, no need to transfer the asset | ||
332 | if (senderAssetServer.Equals(receiverAssetServer)) | ||
333 | { | ||
334 | m_log.DebugFormat("[HGScene]: Asset transfer between foreign users, but they have the same server. No transfer."); | ||
335 | return; | ||
336 | } | ||
337 | |||
338 | if (isForeignSender && senderAssetServer != string.Empty) | ||
339 | m_assMapper.Get(item.AssetID, sender, senderAssetServer); | ||
283 | 340 | ||
284 | if (IsForeignUser(receiver, out userAssetServer) && userAssetServer != string.Empty && m_OutboundPermission) | 341 | if (isForeignReceiver && receiverAssetServer != string.Empty && m_OutboundPermission) |
285 | m_assMapper.Post(item.AssetID, receiver, userAssetServer); | 342 | m_assMapper.Post(item.AssetID, receiver, receiverAssetServer); |
286 | } | 343 | } |
287 | 344 | ||
288 | public override bool IsForeignUser(UUID userID, out string assetServerURL) | 345 | public override bool IsForeignUser(UUID userID, out string assetServerURL) |
289 | { | 346 | { |
290 | assetServerURL = string.Empty; | 347 | assetServerURL = string.Empty; |
291 | 348 | ||
292 | if (UserManagementModule != null && !UserManagementModule.IsLocalGridUser(userID)) | 349 | if (UserManagementModule != null) |
293 | { // foreign | 350 | { |
294 | ScenePresence sp = null; | 351 | if (!m_CheckSeparateAssets) |
295 | if (m_Scene.TryGetScenePresence(userID, out sp)) | ||
296 | { | 352 | { |
297 | AgentCircuitData aCircuit = m_Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | 353 | if (!UserManagementModule.IsLocalGridUser(userID)) |
298 | if (aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) | 354 | { // foreign |
299 | { | 355 | ScenePresence sp = null; |
300 | assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString(); | 356 | if (m_Scene.TryGetScenePresence(userID, out sp)) |
301 | assetServerURL = assetServerURL.Trim(new char[] { '/' }); | 357 | { |
358 | AgentCircuitData aCircuit = m_Scene.AuthenticateHandler.GetAgentCircuitData(sp.ControllingClient.CircuitCode); | ||
359 | if (aCircuit != null && aCircuit.ServiceURLs != null && aCircuit.ServiceURLs.ContainsKey("AssetServerURI")) | ||
360 | { | ||
361 | assetServerURL = aCircuit.ServiceURLs["AssetServerURI"].ToString(); | ||
362 | assetServerURL = assetServerURL.Trim(new char[] { '/' }); | ||
363 | } | ||
364 | } | ||
365 | else | ||
366 | { | ||
367 | assetServerURL = UserManagementModule.GetUserServerURL(userID, "AssetServerURI"); | ||
368 | assetServerURL = assetServerURL.Trim(new char[] { '/' }); | ||
369 | } | ||
370 | return true; | ||
302 | } | 371 | } |
303 | } | 372 | } |
304 | else | 373 | else |
305 | { | 374 | { |
306 | assetServerURL = UserManagementModule.GetUserServerURL(userID, "AssetServerURI"); | 375 | if (IsLocalInventoryAssetsUser(userID, out assetServerURL)) |
307 | assetServerURL = assetServerURL.Trim(new char[] { '/' }); | 376 | { |
377 | m_log.DebugFormat("[HGScene]: user {0} has local assets {1}", userID, assetServerURL); | ||
378 | return false; | ||
379 | } | ||
380 | else | ||
381 | { | ||
382 | m_log.DebugFormat("[HGScene]: user {0} has foreign assets {1}", userID, assetServerURL); | ||
383 | return true; | ||
384 | } | ||
308 | } | 385 | } |
309 | return true; | ||
310 | } | 386 | } |
311 | |||
312 | return false; | 387 | return false; |
313 | } | 388 | } |
314 | 389 | ||
390 | private bool IsLocalInventoryAssetsUser(UUID uuid, out string assetsURL) | ||
391 | { | ||
392 | assetsURL = UserManagementModule.GetUserServerURL(uuid, "AssetServerURI"); | ||
393 | if (assetsURL == string.Empty) | ||
394 | { | ||
395 | AgentCircuitData agent = m_Scene.AuthenticateHandler.GetAgentCircuitData(uuid); | ||
396 | if (agent != null) | ||
397 | { | ||
398 | assetsURL = agent.ServiceURLs["AssetServerURI"].ToString(); | ||
399 | assetsURL = assetsURL.Trim(new char[] { '/' }); | ||
400 | } | ||
401 | } | ||
402 | return m_LocalAssetsURL.Equals(assetsURL); | ||
403 | } | ||
404 | |||
405 | |||
315 | protected override InventoryItemBase GetItem(UUID agentID, UUID itemID) | 406 | protected override InventoryItemBase GetItem(UUID agentID, UUID itemID) |
316 | { | 407 | { |
317 | InventoryItemBase item = base.GetItem(agentID, itemID); | 408 | InventoryItemBase item = base.GetItem(agentID, itemID); |
@@ -346,7 +437,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
346 | InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId); | 437 | InventoryFolderBase root = m_Scene.InventoryService.GetRootFolder(client.AgentId); |
347 | InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID); | 438 | InventoryCollection content = m_Scene.InventoryService.GetFolderContent(client.AgentId, root.ID); |
348 | 439 | ||
349 | inv.SendBulkUpdateInventory(content.Folders.ToArray(), content.Items.ToArray()); | 440 | List<InventoryFolderBase> keep = new List<InventoryFolderBase>(); |
441 | |||
442 | foreach (InventoryFolderBase f in content.Folders) | ||
443 | { | ||
444 | if (f.Name != "My Suitcase" && f.Name != "Current Outfit") | ||
445 | keep.Add(f); | ||
446 | } | ||
447 | |||
448 | inv.SendBulkUpdateInventory(keep.ToArray(), content.Items.ToArray()); | ||
350 | } | 449 | } |
351 | } | 450 | } |
352 | } | 451 | } |
@@ -379,7 +478,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
379 | 478 | ||
380 | foreach (InventoryFolderBase f in content.Folders) | 479 | foreach (InventoryFolderBase f in content.Folders) |
381 | { | 480 | { |
382 | if (f.Name != "My Suitcase") | 481 | if (f.Name != "My Suitcase" && f.Name != "Current Outfit") |
383 | { | 482 | { |
384 | f.Name = f.Name + " (Unavailable)"; | 483 | f.Name = f.Name + " (Unavailable)"; |
385 | keep.Add(f); | 484 | keep.Add(f); |
@@ -404,5 +503,36 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
404 | } | 503 | } |
405 | 504 | ||
406 | #endregion | 505 | #endregion |
506 | |||
507 | #region Permissions | ||
508 | |||
509 | private bool CanTakeObject(UUID objectID, UUID stealer, Scene scene) | ||
510 | { | ||
511 | if (m_bypassPermissions) return true; | ||
512 | |||
513 | if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(stealer)) | ||
514 | { | ||
515 | SceneObjectGroup sog = null; | ||
516 | if (m_Scene.TryGetSceneObjectGroup(objectID, out sog) && sog.OwnerID == stealer) | ||
517 | return true; | ||
518 | |||
519 | return false; | ||
520 | } | ||
521 | |||
522 | return true; | ||
523 | } | ||
524 | |||
525 | private bool OnTransferUserInventory(UUID itemID, UUID userID, UUID recipientID) | ||
526 | { | ||
527 | if (m_bypassPermissions) return true; | ||
528 | |||
529 | if (!m_OutboundPermission && !UserManagementModule.IsLocalGridUser(recipientID)) | ||
530 | return false; | ||
531 | |||
532 | return true; | ||
533 | } | ||
534 | |||
535 | |||
536 | #endregion | ||
407 | } | 537 | } |
408 | } \ No newline at end of file | 538 | } \ No newline at end of file |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs index 8b7c16e..5a9efb8 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/InventoryAccessModule.cs | |||
@@ -47,6 +47,7 @@ using OpenMetaverse; | |||
47 | using log4net; | 47 | using log4net; |
48 | using Nini.Config; | 48 | using Nini.Config; |
49 | using Mono.Addins; | 49 | using Mono.Addins; |
50 | using PermissionMask = OpenSim.Framework.PermissionMask; | ||
50 | 51 | ||
51 | namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | 52 | namespace OpenSim.Region.CoreModules.Framework.InventoryAccess |
52 | { | 53 | { |
@@ -202,7 +203,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
202 | m_Scene.AssetService.Store(asset); | 203 | m_Scene.AssetService.Store(asset); |
203 | m_Scene.CreateNewInventoryItem( | 204 | m_Scene.CreateNewInventoryItem( |
204 | remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, | 205 | remoteClient, remoteClient.AgentId.ToString(), string.Empty, folderID, |
205 | name, description, 0, callbackID, asset, invType, nextOwnerMask, creationDate); | 206 | name, description, 0, callbackID, asset.FullID, asset.Type, invType, nextOwnerMask, creationDate); |
206 | } | 207 | } |
207 | else | 208 | else |
208 | { | 209 | { |
@@ -259,7 +260,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
259 | return UUID.Zero; | 260 | return UUID.Zero; |
260 | } | 261 | } |
261 | 262 | ||
262 | remoteClient.SendAgentAlertMessage("Notecard saved", false); | 263 | remoteClient.SendAlertMessage("Notecard saved"); |
263 | } | 264 | } |
264 | else if ((InventoryType)item.InvType == InventoryType.LSL) | 265 | else if ((InventoryType)item.InvType == InventoryType.LSL) |
265 | { | 266 | { |
@@ -269,7 +270,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
269 | return UUID.Zero; | 270 | return UUID.Zero; |
270 | } | 271 | } |
271 | 272 | ||
272 | remoteClient.SendAgentAlertMessage("Script saved", false); | 273 | remoteClient.SendAlertMessage("Script saved"); |
273 | } | 274 | } |
274 | 275 | ||
275 | AssetBase asset = | 276 | AssetBase asset = |
@@ -291,7 +292,34 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
291 | 292 | ||
292 | return UUID.Zero; | 293 | return UUID.Zero; |
293 | } | 294 | } |
294 | 295 | ||
296 | public virtual bool UpdateInventoryItemAsset(UUID ownerID, InventoryItemBase item, AssetBase asset) | ||
297 | { | ||
298 | if (item != null && item.Owner == ownerID && asset != null) | ||
299 | { | ||
300 | // m_log.DebugFormat( | ||
301 | // "[INVENTORY ACCESS MODULE]: Updating item {0} {1} with new asset {2}", | ||
302 | // item.Name, item.ID, asset.ID); | ||
303 | |||
304 | item.AssetID = asset.FullID; | ||
305 | item.Description = asset.Description; | ||
306 | item.Name = asset.Name; | ||
307 | item.AssetType = asset.Type; | ||
308 | item.InvType = (int)InventoryType.Object; | ||
309 | |||
310 | m_Scene.AssetService.Store(asset); | ||
311 | m_Scene.InventoryService.UpdateItem(item); | ||
312 | |||
313 | return true; | ||
314 | } | ||
315 | else | ||
316 | { | ||
317 | m_log.ErrorFormat("[INVENTORY ACCESS MODULE]: Given invalid item for inventory update: {0}", | ||
318 | (item == null || asset == null? "null item or asset" : "wrong owner")); | ||
319 | return false; | ||
320 | } | ||
321 | } | ||
322 | |||
295 | public virtual List<InventoryItemBase> CopyToInventory( | 323 | public virtual List<InventoryItemBase> CopyToInventory( |
296 | DeRezAction action, UUID folderID, | 324 | DeRezAction action, UUID folderID, |
297 | List<SceneObjectGroup> objectGroups, IClientAPI remoteClient, bool asAttachment) | 325 | List<SceneObjectGroup> objectGroups, IClientAPI remoteClient, bool asAttachment) |
@@ -352,23 +380,32 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
352 | bool asAttachment) | 380 | bool asAttachment) |
353 | { | 381 | { |
354 | CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); | 382 | CoalescedSceneObjects coa = new CoalescedSceneObjects(UUID.Zero); |
355 | Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); | 383 | // Dictionary<UUID, Vector3> originalPositions = new Dictionary<UUID, Vector3>(); |
384 | |||
385 | Dictionary<SceneObjectGroup, KeyframeMotion> group2Keyframe = new Dictionary<SceneObjectGroup, KeyframeMotion>(); | ||
356 | 386 | ||
357 | foreach (SceneObjectGroup objectGroup in objlist) | 387 | foreach (SceneObjectGroup objectGroup in objlist) |
358 | { | 388 | { |
359 | Vector3 inventoryStoredPosition = new Vector3 | 389 | if (objectGroup.RootPart.KeyframeMotion != null) |
360 | (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) | 390 | { |
361 | ? 250 | 391 | objectGroup.RootPart.KeyframeMotion.Pause(); |
362 | : objectGroup.AbsolutePosition.X) | 392 | group2Keyframe.Add(objectGroup, objectGroup.RootPart.KeyframeMotion); |
363 | , | 393 | objectGroup.RootPart.KeyframeMotion = null; |
364 | (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize) | 394 | } |
365 | ? 250 | ||
366 | : objectGroup.AbsolutePosition.Y, | ||
367 | objectGroup.AbsolutePosition.Z); | ||
368 | |||
369 | originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; | ||
370 | 395 | ||
371 | objectGroup.AbsolutePosition = inventoryStoredPosition; | 396 | // Vector3 inventoryStoredPosition = new Vector3 |
397 | // (((objectGroup.AbsolutePosition.X > (int)Constants.RegionSize) | ||
398 | // ? 250 | ||
399 | // : objectGroup.AbsolutePosition.X) | ||
400 | // , | ||
401 | // (objectGroup.AbsolutePosition.Y > (int)Constants.RegionSize) | ||
402 | // ? 250 | ||
403 | // : objectGroup.AbsolutePosition.Y, | ||
404 | // objectGroup.AbsolutePosition.Z); | ||
405 | // | ||
406 | // originalPositions[objectGroup.UUID] = objectGroup.AbsolutePosition; | ||
407 | // | ||
408 | // objectGroup.AbsolutePosition = inventoryStoredPosition; | ||
372 | 409 | ||
373 | // Make sure all bits but the ones we want are clear | 410 | // Make sure all bits but the ones we want are clear |
374 | // on take. | 411 | // on take. |
@@ -377,7 +414,8 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
377 | objectGroup.RootPart.NextOwnerMask &= | 414 | objectGroup.RootPart.NextOwnerMask &= |
378 | ((uint)PermissionMask.Copy | | 415 | ((uint)PermissionMask.Copy | |
379 | (uint)PermissionMask.Transfer | | 416 | (uint)PermissionMask.Transfer | |
380 | (uint)PermissionMask.Modify); | 417 | (uint)PermissionMask.Modify | |
418 | (uint)PermissionMask.Export); | ||
381 | objectGroup.RootPart.NextOwnerMask |= | 419 | objectGroup.RootPart.NextOwnerMask |= |
382 | (uint)PermissionMask.Move; | 420 | (uint)PermissionMask.Move; |
383 | 421 | ||
@@ -395,9 +433,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
395 | else | 433 | else |
396 | itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment); | 434 | itemXml = SceneObjectSerializer.ToOriginalXmlFormat(objlist[0], !asAttachment); |
397 | 435 | ||
398 | // Restore the position of each group now that it has been stored to inventory. | 436 | // // Restore the position of each group now that it has been stored to inventory. |
399 | foreach (SceneObjectGroup objectGroup in objlist) | 437 | // foreach (SceneObjectGroup objectGroup in objlist) |
400 | objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; | 438 | // objectGroup.AbsolutePosition = originalPositions[objectGroup.UUID]; |
401 | 439 | ||
402 | InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); | 440 | InventoryItemBase item = CreateItemForObject(action, remoteClient, objlist[0], folderID); |
403 | 441 | ||
@@ -407,17 +445,28 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
407 | 445 | ||
408 | if (item == null) | 446 | if (item == null) |
409 | return null; | 447 | return null; |
448 | |||
449 | item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); | ||
450 | item.CreatorData = objlist[0].RootPart.CreatorData; | ||
410 | 451 | ||
411 | // Can't know creator is the same, so null it in inventory | ||
412 | if (objlist.Count > 1) | 452 | if (objlist.Count > 1) |
413 | { | 453 | { |
414 | item.CreatorId = UUID.Zero.ToString(); | ||
415 | item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; | 454 | item.Flags = (uint)InventoryItemFlags.ObjectHasMultipleItems; |
455 | |||
456 | // If the objects have different creators then don't specify a creator at all | ||
457 | foreach (SceneObjectGroup objectGroup in objlist) | ||
458 | { | ||
459 | if ((objectGroup.RootPart.CreatorID.ToString() != item.CreatorId) | ||
460 | || (objectGroup.RootPart.CreatorData.ToString() != item.CreatorData)) | ||
461 | { | ||
462 | item.CreatorId = UUID.Zero.ToString(); | ||
463 | item.CreatorData = string.Empty; | ||
464 | break; | ||
465 | } | ||
466 | } | ||
416 | } | 467 | } |
417 | else | 468 | else |
418 | { | 469 | { |
419 | item.CreatorId = objlist[0].RootPart.CreatorID.ToString(); | ||
420 | item.CreatorData = objlist[0].RootPart.CreatorData; | ||
421 | item.SaleType = objlist[0].RootPart.ObjectSaleType; | 470 | item.SaleType = objlist[0].RootPart.ObjectSaleType; |
422 | item.SalePrice = objlist[0].RootPart.SalePrice; | 471 | item.SalePrice = objlist[0].RootPart.SalePrice; |
423 | } | 472 | } |
@@ -438,13 +487,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
438 | } | 487 | } |
439 | else | 488 | else |
440 | { | 489 | { |
441 | AddPermissions(item, objlist[0], objlist, remoteClient); | ||
442 | |||
443 | item.CreationDate = Util.UnixTimeSinceEpoch(); | 490 | item.CreationDate = Util.UnixTimeSinceEpoch(); |
444 | item.Description = asset.Description; | 491 | item.Description = asset.Description; |
445 | item.Name = asset.Name; | 492 | item.Name = asset.Name; |
446 | item.AssetType = asset.Type; | 493 | item.AssetType = asset.Type; |
447 | 494 | ||
495 | AddPermissions(item, objlist[0], objlist, remoteClient); | ||
496 | |||
448 | m_Scene.AddInventoryItem(item); | 497 | m_Scene.AddInventoryItem(item); |
449 | 498 | ||
450 | if (remoteClient != null && item.Owner == remoteClient.AgentId) | 499 | if (remoteClient != null && item.Owner == remoteClient.AgentId) |
@@ -461,6 +510,13 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
461 | } | 510 | } |
462 | } | 511 | } |
463 | 512 | ||
513 | // Restore KeyframeMotion | ||
514 | foreach (SceneObjectGroup objectGroup in group2Keyframe.Keys) | ||
515 | { | ||
516 | objectGroup.RootPart.KeyframeMotion = group2Keyframe[objectGroup]; | ||
517 | objectGroup.RootPart.KeyframeMotion.Start(); | ||
518 | } | ||
519 | |||
464 | // This is a hook to do some per-asset post-processing for subclasses that need that | 520 | // This is a hook to do some per-asset post-processing for subclasses that need that |
465 | if (remoteClient != null) | 521 | if (remoteClient != null) |
466 | ExportAsset(remoteClient.AgentId, asset.FullID); | 522 | ExportAsset(remoteClient.AgentId, asset.FullID); |
@@ -485,49 +541,65 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
485 | InventoryItemBase item, SceneObjectGroup so, List<SceneObjectGroup> objsForEffectivePermissions, | 541 | InventoryItemBase item, SceneObjectGroup so, List<SceneObjectGroup> objsForEffectivePermissions, |
486 | IClientAPI remoteClient) | 542 | IClientAPI remoteClient) |
487 | { | 543 | { |
488 | uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move) | 7; | 544 | uint effectivePerms = (uint)(PermissionMask.Copy | PermissionMask.Transfer | PermissionMask.Modify | PermissionMask.Move | PermissionMask.Export) | 7; |
545 | uint allObjectsNextOwnerPerms = 0x7fffffff; | ||
546 | uint allObjectsEveryOnePerms = 0x7fffffff; | ||
547 | uint allObjectsGroupPerms = 0x7fffffff; | ||
548 | |||
489 | foreach (SceneObjectGroup grp in objsForEffectivePermissions) | 549 | foreach (SceneObjectGroup grp in objsForEffectivePermissions) |
550 | { | ||
490 | effectivePerms &= grp.GetEffectivePermissions(); | 551 | effectivePerms &= grp.GetEffectivePermissions(); |
552 | allObjectsNextOwnerPerms &= grp.RootPart.NextOwnerMask; | ||
553 | allObjectsEveryOnePerms &= grp.RootPart.EveryoneMask; | ||
554 | allObjectsGroupPerms &= grp.RootPart.GroupMask; | ||
555 | } | ||
491 | effectivePerms |= (uint)PermissionMask.Move; | 556 | effectivePerms |= (uint)PermissionMask.Move; |
492 | 557 | ||
558 | //PermissionsUtil.LogPermissions(item.Name, "Before AddPermissions", item.BasePermissions, item.CurrentPermissions, item.NextPermissions); | ||
559 | |||
493 | if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) | 560 | if (remoteClient != null && (remoteClient.AgentId != so.RootPart.OwnerID) && m_Scene.Permissions.PropagatePermissions()) |
494 | { | 561 | { |
562 | // Changing ownership, so apply the "Next Owner" permissions to all of the | ||
563 | // inventory item's permissions. | ||
564 | |||
495 | uint perms = effectivePerms; | 565 | uint perms = effectivePerms; |
496 | uint nextPerms = (perms & 7) << 13; | 566 | PermissionsUtil.ApplyFoldedPermissions(effectivePerms, ref perms); |
497 | if ((nextPerms & (uint)PermissionMask.Copy) == 0) | 567 | |
498 | perms &= ~(uint)PermissionMask.Copy; | 568 | item.BasePermissions = perms & allObjectsNextOwnerPerms; |
499 | if ((nextPerms & (uint)PermissionMask.Transfer) == 0) | ||
500 | perms &= ~(uint)PermissionMask.Transfer; | ||
501 | if ((nextPerms & (uint)PermissionMask.Modify) == 0) | ||
502 | perms &= ~(uint)PermissionMask.Modify; | ||
503 | |||
504 | item.BasePermissions = perms & so.RootPart.NextOwnerMask; | ||
505 | item.CurrentPermissions = item.BasePermissions; | 569 | item.CurrentPermissions = item.BasePermissions; |
506 | item.NextPermissions = perms & so.RootPart.NextOwnerMask; | 570 | item.NextPermissions = perms & allObjectsNextOwnerPerms; |
507 | item.EveryOnePermissions = so.RootPart.EveryoneMask & so.RootPart.NextOwnerMask; | 571 | item.EveryOnePermissions = allObjectsEveryOnePerms & allObjectsNextOwnerPerms; |
508 | item.GroupPermissions = so.RootPart.GroupMask & so.RootPart.NextOwnerMask; | 572 | item.GroupPermissions = allObjectsGroupPerms & allObjectsNextOwnerPerms; |
509 | 573 | ||
510 | // Magic number badness. Maybe this deserves an enum. | 574 | // apply next owner perms on rez |
511 | // bit 4 (16) is the "Slam" bit, it means treat as passed | 575 | item.CurrentPermissions |= SceneObjectGroup.SLAM; |
512 | // and apply next owner perms on rez | ||
513 | item.CurrentPermissions |= 16; // Slam! | ||
514 | } | 576 | } |
515 | else | 577 | else |
516 | { | 578 | { |
579 | // Not changing ownership. | ||
580 | // In this case we apply the permissions in the object's items ONLY to the inventory | ||
581 | // item's "Next Owner" permissions, but NOT to its "Current", "Base", etc. permissions. | ||
582 | // E.g., if the object contains a No-Transfer item then the item's "Next Owner" | ||
583 | // permissions are also No-Transfer. | ||
584 | PermissionsUtil.ApplyFoldedPermissions(effectivePerms, ref allObjectsNextOwnerPerms); | ||
585 | |||
517 | item.BasePermissions = effectivePerms; | 586 | item.BasePermissions = effectivePerms; |
518 | item.CurrentPermissions = effectivePerms; | 587 | item.CurrentPermissions = effectivePerms; |
519 | item.NextPermissions = so.RootPart.NextOwnerMask & effectivePerms; | 588 | item.NextPermissions = allObjectsNextOwnerPerms & effectivePerms; |
520 | item.EveryOnePermissions = so.RootPart.EveryoneMask & effectivePerms; | 589 | item.EveryOnePermissions = allObjectsEveryOnePerms & effectivePerms; |
521 | item.GroupPermissions = so.RootPart.GroupMask & effectivePerms; | 590 | item.GroupPermissions = allObjectsGroupPerms & effectivePerms; |
522 | 591 | ||
523 | item.CurrentPermissions &= | 592 | item.CurrentPermissions &= |
524 | ((uint)PermissionMask.Copy | | 593 | ((uint)PermissionMask.Copy | |
525 | (uint)PermissionMask.Transfer | | 594 | (uint)PermissionMask.Transfer | |
526 | (uint)PermissionMask.Modify | | 595 | (uint)PermissionMask.Modify | |
527 | (uint)PermissionMask.Move | | 596 | (uint)PermissionMask.Move | |
597 | (uint)PermissionMask.Export | | ||
528 | 7); // Preserve folded permissions | 598 | 7); // Preserve folded permissions |
529 | } | 599 | } |
530 | 600 | ||
601 | //PermissionsUtil.LogPermissions(item.Name, "After AddPermissions", item.BasePermissions, item.CurrentPermissions, item.NextPermissions); | ||
602 | |||
531 | return item; | 603 | return item; |
532 | } | 604 | } |
533 | 605 | ||
@@ -542,6 +614,10 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
542 | protected InventoryItemBase CreateItemForObject( | 614 | protected InventoryItemBase CreateItemForObject( |
543 | DeRezAction action, IClientAPI remoteClient, SceneObjectGroup so, UUID folderID) | 615 | DeRezAction action, IClientAPI remoteClient, SceneObjectGroup so, UUID folderID) |
544 | { | 616 | { |
617 | // m_log.DebugFormat( | ||
618 | // "[BASIC INVENTORY ACCESS MODULE]: Creating item for object {0} {1} for folder {2}, action {3}", | ||
619 | // so.Name, so.UUID, folderID, action); | ||
620 | // | ||
545 | // Get the user info of the item destination | 621 | // Get the user info of the item destination |
546 | // | 622 | // |
547 | UUID userID = UUID.Zero; | 623 | UUID userID = UUID.Zero; |
@@ -619,18 +695,18 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
619 | if (remoteClient == null || | 695 | if (remoteClient == null || |
620 | so.OwnerID != remoteClient.AgentId) | 696 | so.OwnerID != remoteClient.AgentId) |
621 | { | 697 | { |
622 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | 698 | folder = m_Scene.InventoryService.GetFolderForType(userID, FolderType.LostAndFound); |
623 | } | 699 | } |
624 | else | 700 | else |
625 | { | 701 | { |
626 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); | 702 | folder = m_Scene.InventoryService.GetFolderForType(userID, FolderType.Trash); |
627 | } | 703 | } |
628 | } | 704 | } |
629 | else if (action == DeRezAction.Return) | 705 | else if (action == DeRezAction.Return) |
630 | { | 706 | { |
631 | // Dump to lost + found unconditionally | 707 | // Dump to lost + found unconditionally |
632 | // | 708 | // |
633 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | 709 | folder = m_Scene.InventoryService.GetFolderForType(userID, FolderType.LostAndFound); |
634 | } | 710 | } |
635 | 711 | ||
636 | if (folderID == UUID.Zero && folder == null) | 712 | if (folderID == UUID.Zero && folder == null) |
@@ -639,21 +715,22 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
639 | { | 715 | { |
640 | // Deletes go to trash by default | 716 | // Deletes go to trash by default |
641 | // | 717 | // |
642 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.TrashFolder); | 718 | folder = m_Scene.InventoryService.GetFolderForType(userID, FolderType.Trash); |
643 | } | 719 | } |
644 | else | 720 | else |
645 | { | 721 | { |
646 | if (remoteClient == null || so.OwnerID != remoteClient.AgentId) | 722 | if (remoteClient == null || so.RootPart.OwnerID != remoteClient.AgentId) |
647 | { | 723 | { |
648 | // Taking copy of another person's item. Take to | 724 | // Taking copy of another person's item. Take to |
649 | // Objects folder. | 725 | // Objects folder. |
650 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.Object); | 726 | folder = m_Scene.InventoryService.GetFolderForType(userID, FolderType.Object); |
727 | so.FromFolderID = UUID.Zero; | ||
651 | } | 728 | } |
652 | else | 729 | else |
653 | { | 730 | { |
654 | // Catch all. Use lost & found | 731 | // Catch all. Use lost & found |
655 | // | 732 | // |
656 | folder = m_Scene.InventoryService.GetFolderForType(userID, AssetType.LostAndFoundFolder); | 733 | folder = m_Scene.InventoryService.GetFolderForType(userID, FolderType.LostAndFound); |
657 | } | 734 | } |
658 | } | 735 | } |
659 | } | 736 | } |
@@ -663,10 +740,16 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
663 | // | 740 | // |
664 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) | 741 | if (action == DeRezAction.Take || action == DeRezAction.TakeCopy) |
665 | { | 742 | { |
666 | if (so.FromFolderID != UUID.Zero && userID == remoteClient.AgentId) | 743 | if (so.FromFolderID != UUID.Zero && so.RootPart.OwnerID == remoteClient.AgentId) |
667 | { | 744 | { |
668 | InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID); | 745 | InventoryFolderBase f = new InventoryFolderBase(so.FromFolderID, userID); |
669 | folder = m_Scene.InventoryService.GetFolder(f); | 746 | folder = m_Scene.InventoryService.GetFolder(f); |
747 | |||
748 | if(folder.Type == 14 || folder.Type == 16) | ||
749 | { | ||
750 | // folder.Type = 6; | ||
751 | folder = m_Scene.InventoryService.GetFolderForType(userID, FolderType.Object); | ||
752 | } | ||
670 | } | 753 | } |
671 | } | 754 | } |
672 | 755 | ||
@@ -722,7 +805,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
722 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, | 805 | UUID RayTargetID, byte BypassRayCast, bool RayEndIsIntersection, |
723 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) | 806 | bool RezSelected, bool RemoveItem, UUID fromTaskID, bool attachment) |
724 | { | 807 | { |
725 | AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString()); | 808 | AssetBase rezAsset = m_Scene.AssetService.Get(assetID.ToString()); |
726 | 809 | ||
727 | if (rezAsset == null) | 810 | if (rezAsset == null) |
728 | { | 811 | { |
@@ -731,12 +814,14 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
731 | m_log.WarnFormat( | 814 | m_log.WarnFormat( |
732 | "[InventoryAccessModule]: Could not find asset {0} for item {1} {2} for {3} in RezObject()", | 815 | "[InventoryAccessModule]: Could not find asset {0} for item {1} {2} for {3} in RezObject()", |
733 | assetID, item.Name, item.ID, remoteClient.Name); | 816 | assetID, item.Name, item.ID, remoteClient.Name); |
817 | remoteClient.SendAgentAlertMessage(string.Format("Unable to rez: could not find asset {0} for item {1}.", assetID, item.Name), false); | ||
734 | } | 818 | } |
735 | else | 819 | else |
736 | { | 820 | { |
737 | m_log.WarnFormat( | 821 | m_log.WarnFormat( |
738 | "[INVENTORY ACCESS MODULE]: Could not find asset {0} for {1} in RezObject()", | 822 | "[INVENTORY ACCESS MODULE]: Could not find asset {0} for {1} in RezObject()", |
739 | assetID, remoteClient.Name); | 823 | assetID, remoteClient.Name); |
824 | remoteClient.SendAgentAlertMessage(string.Format("Unable to rez: could not find asset {0}.", assetID), false); | ||
740 | } | 825 | } |
741 | 826 | ||
742 | return null; | 827 | return null; |
@@ -744,67 +829,34 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
744 | 829 | ||
745 | SceneObjectGroup group = null; | 830 | SceneObjectGroup group = null; |
746 | 831 | ||
747 | string xmlData = Utils.BytesToString(rezAsset.Data); | 832 | List<SceneObjectGroup> objlist; |
748 | List<SceneObjectGroup> objlist = new List<SceneObjectGroup>(); | 833 | List<Vector3> veclist; |
749 | List<Vector3> veclist = new List<Vector3>(); | 834 | Vector3 bbox; |
835 | float offsetHeight; | ||
750 | byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); | 836 | byte bRayEndIsIntersection = (byte)(RayEndIsIntersection ? 1 : 0); |
751 | Vector3 pos; | 837 | Vector3 pos; |
752 | 838 | ||
753 | XmlDocument doc = new XmlDocument(); | 839 | bool single |
754 | doc.LoadXml(xmlData); | 840 | = m_Scene.GetObjectsToRez( |
755 | XmlElement e = (XmlElement)doc.SelectSingleNode("/CoalescedObject"); | 841 | rezAsset.Data, attachment, out objlist, out veclist, out bbox, out offsetHeight); |
756 | if (e == null || attachment) // Single | ||
757 | { | ||
758 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | ||
759 | |||
760 | objlist.Add(g); | ||
761 | veclist.Add(new Vector3(0, 0, 0)); | ||
762 | 842 | ||
763 | float offsetHeight = 0; | 843 | if (single) |
844 | { | ||
764 | pos = m_Scene.GetNewRezLocation( | 845 | pos = m_Scene.GetNewRezLocation( |
765 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, | 846 | RayStart, RayEnd, RayTargetID, Quaternion.Identity, |
766 | BypassRayCast, bRayEndIsIntersection, true, g.GetAxisAlignedBoundingBox(out offsetHeight), false); | 847 | BypassRayCast, bRayEndIsIntersection, true, bbox, false); |
767 | pos.Z += offsetHeight; | 848 | pos.Z += offsetHeight; |
768 | } | 849 | } |
769 | else | 850 | else |
770 | { | 851 | { |
771 | XmlElement coll = (XmlElement)e; | ||
772 | float bx = Convert.ToSingle(coll.GetAttribute("x")); | ||
773 | float by = Convert.ToSingle(coll.GetAttribute("y")); | ||
774 | float bz = Convert.ToSingle(coll.GetAttribute("z")); | ||
775 | Vector3 bbox = new Vector3(bx, by, bz); | ||
776 | |||
777 | pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, | 852 | pos = m_Scene.GetNewRezLocation(RayStart, RayEnd, |
778 | RayTargetID, Quaternion.Identity, | 853 | RayTargetID, Quaternion.Identity, |
779 | BypassRayCast, bRayEndIsIntersection, true, | 854 | BypassRayCast, bRayEndIsIntersection, true, |
780 | bbox, false); | 855 | bbox, false); |
781 | |||
782 | pos -= bbox / 2; | 856 | pos -= bbox / 2; |
783 | |||
784 | XmlNodeList groups = e.SelectNodes("SceneObjectGroup"); | ||
785 | foreach (XmlNode n in groups) | ||
786 | { | ||
787 | SceneObjectGroup g = SceneObjectSerializer.FromOriginalXmlFormat(n.OuterXml); | ||
788 | |||
789 | objlist.Add(g); | ||
790 | XmlElement el = (XmlElement)n; | ||
791 | |||
792 | string rawX = el.GetAttribute("offsetx"); | ||
793 | string rawY = el.GetAttribute("offsety"); | ||
794 | string rawZ = el.GetAttribute("offsetz"); | ||
795 | // | ||
796 | // m_log.DebugFormat( | ||
797 | // "[INVENTORY ACCESS MODULE]: Converting coalesced object {0} offset <{1}, {2}, {3}>", | ||
798 | // g.Name, rawX, rawY, rawZ); | ||
799 | |||
800 | float x = Convert.ToSingle(rawX); | ||
801 | float y = Convert.ToSingle(rawY); | ||
802 | float z = Convert.ToSingle(rawZ); | ||
803 | veclist.Add(new Vector3(x, y, z)); | ||
804 | } | ||
805 | } | 857 | } |
806 | 858 | ||
807 | if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, attachment)) | 859 | if (item != null && !DoPreRezWhenFromItem(remoteClient, item, objlist, pos, veclist, attachment)) |
808 | return null; | 860 | return null; |
809 | 861 | ||
810 | for (int i = 0; i < objlist.Count; i++) | 862 | for (int i = 0; i < objlist.Count; i++) |
@@ -823,11 +875,23 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
823 | m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3"); | 875 | m_log.Debug("[INVENTORY ACCESS MODULE]: Object has UUID.Zero! Position 3"); |
824 | } | 876 | } |
825 | 877 | ||
826 | foreach (SceneObjectPart part in group.Parts) | 878 | // if this was previously an attachment and is now being rezzed, |
879 | // save the old attachment info. | ||
880 | if (group.IsAttachment == false && group.RootPart.Shape.State != 0) | ||
827 | { | 881 | { |
828 | // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset. | 882 | group.RootPart.AttachedPos = group.AbsolutePosition; |
829 | part.LastOwnerID = part.OwnerID; | 883 | group.RootPart.Shape.LastAttachPoint = (byte)group.AttachmentPoint; |
830 | part.OwnerID = remoteClient.AgentId; | 884 | } |
885 | |||
886 | if (item == null) | ||
887 | { | ||
888 | // Change ownership. Normally this is done in DoPreRezWhenFromItem(), but in this case we must do it here. | ||
889 | foreach (SceneObjectPart part in group.Parts) | ||
890 | { | ||
891 | // Make the rezzer the owner, as this is not necessarily set correctly in the serialized asset. | ||
892 | part.LastOwnerID = part.OwnerID; | ||
893 | part.OwnerID = remoteClient.AgentId; | ||
894 | } | ||
831 | } | 895 | } |
832 | 896 | ||
833 | if (!attachment) | 897 | if (!attachment) |
@@ -855,7 +919,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
855 | // one full update during the attachment | 919 | // one full update during the attachment |
856 | // process causes some clients to fail to display the | 920 | // process causes some clients to fail to display the |
857 | // attachment properly. | 921 | // attachment properly. |
858 | m_Scene.AddNewSceneObject(group, true, false); | 922 | m_Scene.AddNewSceneObject(group, !attachment, false); |
859 | 923 | ||
860 | // if attachment we set it's asset id so object updates | 924 | // if attachment we set it's asset id so object updates |
861 | // can reflect that, if not, we set it's position in world. | 925 | // can reflect that, if not, we set it's position in world. |
@@ -902,10 +966,15 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
902 | /// <param name="item"></param> | 966 | /// <param name="item"></param> |
903 | /// <param name="objlist"></param> | 967 | /// <param name="objlist"></param> |
904 | /// <param name="pos"></param> | 968 | /// <param name="pos"></param> |
969 | /// <param name="veclist"> | ||
970 | /// List of vector position adjustments for a coalesced objects. For ordinary objects | ||
971 | /// this list will contain just Vector3.Zero. The order of adjustments must match the order of objlist | ||
972 | /// </param> | ||
905 | /// <param name="isAttachment"></param> | 973 | /// <param name="isAttachment"></param> |
906 | /// <returns>true if we can processed with rezzing, false if we need to abort</returns> | 974 | /// <returns>true if we can processed with rezzing, false if we need to abort</returns> |
907 | private bool DoPreRezWhenFromItem( | 975 | private bool DoPreRezWhenFromItem( |
908 | IClientAPI remoteClient, InventoryItemBase item, List<SceneObjectGroup> objlist, Vector3 pos, bool isAttachment) | 976 | IClientAPI remoteClient, InventoryItemBase item, List<SceneObjectGroup> objlist, |
977 | Vector3 pos, List<Vector3> veclist, bool isAttachment) | ||
909 | { | 978 | { |
910 | UUID fromUserInventoryItemId = UUID.Zero; | 979 | UUID fromUserInventoryItemId = UUID.Zero; |
911 | 980 | ||
@@ -928,28 +997,29 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
928 | } | 997 | } |
929 | } | 998 | } |
930 | 999 | ||
931 | int primcount = 0; | 1000 | for (int i = 0; i < objlist.Count; i++) |
932 | foreach (SceneObjectGroup g in objlist) | ||
933 | primcount += g.PrimCount; | ||
934 | |||
935 | if (!m_Scene.Permissions.CanRezObject( | ||
936 | primcount, remoteClient.AgentId, pos) | ||
937 | && !isAttachment) | ||
938 | { | 1001 | { |
939 | // The client operates in no fail mode. It will | 1002 | SceneObjectGroup g = objlist[i]; |
940 | // have already removed the item from the folder | ||
941 | // if it's no copy. | ||
942 | // Put it back if it's not an attachment | ||
943 | // | ||
944 | if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment)) | ||
945 | remoteClient.SendBulkUpdateInventory(item); | ||
946 | 1003 | ||
947 | ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y); | 1004 | if (!m_Scene.Permissions.CanRezObject( |
948 | remoteClient.SendAlertMessage(string.Format( | 1005 | g.PrimCount, remoteClient.AgentId, pos + veclist[i]) |
949 | "Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.", | 1006 | && !isAttachment) |
950 | item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.RegionInfo.RegionName)); | 1007 | { |
1008 | // The client operates in no fail mode. It will | ||
1009 | // have already removed the item from the folder | ||
1010 | // if it's no copy. | ||
1011 | // Put it back if it's not an attachment | ||
1012 | // | ||
1013 | if (((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) && (!isAttachment)) | ||
1014 | remoteClient.SendBulkUpdateInventory(item); | ||
951 | 1015 | ||
952 | return false; | 1016 | ILandObject land = m_Scene.LandChannel.GetLandObject(pos.X, pos.Y); |
1017 | remoteClient.SendAlertMessage(string.Format( | ||
1018 | "Can't rez object '{0}' at <{1:F3}, {2:F3}, {3:F3}> on parcel '{4}' in region {5}.", | ||
1019 | item.Name, pos.X, pos.Y, pos.Z, land != null ? land.LandData.Name : "Unknown", m_Scene.Name)); | ||
1020 | |||
1021 | return false; | ||
1022 | } | ||
953 | } | 1023 | } |
954 | 1024 | ||
955 | for (int i = 0; i < objlist.Count; i++) | 1025 | for (int i = 0; i < objlist.Count; i++) |
@@ -977,44 +1047,19 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
977 | // "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}", | 1047 | // "[INVENTORY ACCESS MODULE]: rootPart.OwnedID {0}, item.Owner {1}, item.CurrentPermissions {2:X}", |
978 | // rootPart.OwnerID, item.Owner, item.CurrentPermissions); | 1048 | // rootPart.OwnerID, item.Owner, item.CurrentPermissions); |
979 | 1049 | ||
980 | if ((rootPart.OwnerID != item.Owner) || | 1050 | if ((rootPart.OwnerID != item.Owner) || (item.CurrentPermissions & SceneObjectGroup.SLAM) != 0) |
981 | (item.CurrentPermissions & 16) != 0) | ||
982 | { | 1051 | { |
983 | //Need to kill the for sale here | 1052 | //Need to kill the for sale here |
984 | rootPart.ObjectSaleType = 0; | 1053 | rootPart.ObjectSaleType = 0; |
985 | rootPart.SalePrice = 10; | 1054 | rootPart.SalePrice = 10; |
986 | |||
987 | if (m_Scene.Permissions.PropagatePermissions()) | ||
988 | { | ||
989 | foreach (SceneObjectPart part in so.Parts) | ||
990 | { | ||
991 | if ((item.Flags & (uint)InventoryItemFlags.ObjectHasMultipleItems) == 0) | ||
992 | { | ||
993 | part.EveryoneMask = item.EveryOnePermissions; | ||
994 | part.NextOwnerMask = item.NextPermissions; | ||
995 | } | ||
996 | part.GroupMask = 0; // DO NOT propagate here | ||
997 | } | ||
998 | |||
999 | so.ApplyNextOwnerPermissions(); | ||
1000 | } | ||
1001 | } | 1055 | } |
1002 | 1056 | ||
1003 | foreach (SceneObjectPart part in so.Parts) | 1057 | foreach (SceneObjectPart part in so.Parts) |
1004 | { | 1058 | { |
1005 | part.FromUserInventoryItemID = fromUserInventoryItemId; | 1059 | part.FromUserInventoryItemID = fromUserInventoryItemId; |
1006 | 1060 | part.ApplyPermissionsOnRez(item, true, m_Scene); | |
1007 | if ((part.OwnerID != item.Owner) || | ||
1008 | (item.CurrentPermissions & 16) != 0) | ||
1009 | { | ||
1010 | part.Inventory.ChangeInventoryOwner(item.Owner); | ||
1011 | part.GroupMask = 0; // DO NOT propagate here | ||
1012 | } | ||
1013 | |||
1014 | part.EveryoneMask = item.EveryOnePermissions; | ||
1015 | part.NextOwnerMask = item.NextPermissions; | ||
1016 | } | 1061 | } |
1017 | 1062 | ||
1018 | rootPart.TrimPermissions(); | 1063 | rootPart.TrimPermissions(); |
1019 | 1064 | ||
1020 | if (isAttachment) | 1065 | if (isAttachment) |
@@ -1150,4 +1195,4 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess | |||
1150 | 1195 | ||
1151 | #endregion | 1196 | #endregion |
1152 | } | 1197 | } |
1153 | } \ No newline at end of file | 1198 | } |
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs new file mode 100644 index 0000000..007ff63 --- /dev/null +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/HGAssetMapperTests.cs | |||
@@ -0,0 +1,146 @@ | |||
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 OpenSimulator 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 | |||
28 | using System; | ||
29 | using System.Threading; | ||
30 | using System.Xml; | ||
31 | using Nini.Config; | ||
32 | using NUnit.Framework; | ||
33 | using OpenMetaverse; | ||
34 | using OpenSim.Framework; | ||
35 | using OpenSim.Region.CoreModules.Framework.InventoryAccess; | ||
36 | using OpenSim.Region.Framework.Scenes; | ||
37 | using OpenSim.Region.ScriptEngine.XEngine; | ||
38 | using OpenSim.Services.Interfaces; | ||
39 | using OpenSim.Tests.Common; | ||
40 | |||
41 | namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests | ||
42 | { | ||
43 | [TestFixture] | ||
44 | public class HGAssetMapperTests : OpenSimTestCase | ||
45 | { | ||
46 | [Test] | ||
47 | public void TestPostAssetRewrite() | ||
48 | { | ||
49 | TestHelpers.InMethod(); | ||
50 | // TestHelpers.EnableLogging(); | ||
51 | |||
52 | XEngine xengine = new OpenSim.Region.ScriptEngine.XEngine.XEngine(); | ||
53 | xengine.DebugLevel = 1; | ||
54 | |||
55 | IniConfigSource configSource = new IniConfigSource(); | ||
56 | |||
57 | IConfig startupConfig = configSource.AddConfig("Startup"); | ||
58 | startupConfig.Set("DefaultScriptEngine", "XEngine"); | ||
59 | |||
60 | IConfig xEngineConfig = configSource.AddConfig("XEngine"); | ||
61 | xEngineConfig.Set("Enabled", "true"); | ||
62 | xEngineConfig.Set("StartDelay", "0"); | ||
63 | xEngineConfig.Set("AppDomainLoading", "false"); | ||
64 | |||
65 | string homeUrl = "http://hg.HomeTestPostAssetRewriteGrid.com"; | ||
66 | string foreignUrl = "http://hg.ForeignTestPostAssetRewriteGrid.com"; | ||
67 | int soIdTail = 0x1; | ||
68 | UUID assetId = TestHelpers.ParseTail(0x10); | ||
69 | UUID userId = TestHelpers.ParseTail(0x100); | ||
70 | UUID sceneId = TestHelpers.ParseTail(0x1000); | ||
71 | string userFirstName = "TestPostAsset"; | ||
72 | string userLastName = "Rewrite"; | ||
73 | int soPartsCount = 3; | ||
74 | |||
75 | Scene scene = new SceneHelpers().SetupScene("TestPostAssetRewriteScene", sceneId, 1000, 1000, configSource); | ||
76 | SceneHelpers.SetupSceneModules(scene, configSource, xengine); | ||
77 | scene.StartScripts(); | ||
78 | |||
79 | HGAssetMapper hgam = new HGAssetMapper(scene, homeUrl); | ||
80 | UserAccount ua | ||
81 | = UserAccountHelpers.CreateUserWithInventory(scene, userFirstName, userLastName, userId, "password"); | ||
82 | |||
83 | SceneObjectGroup so = SceneHelpers.AddSceneObject(scene, soPartsCount, ua.PrincipalID, "part", soIdTail); | ||
84 | RezScript( | ||
85 | scene, so.UUID, "default { state_entry() { llSay(0, \"Hello World\"); } }", "item1", ua.PrincipalID); | ||
86 | |||
87 | AssetBase asset = AssetHelpers.CreateAsset(assetId, so); | ||
88 | asset.CreatorID = foreignUrl; | ||
89 | hgam.PostAsset(foreignUrl, asset); | ||
90 | |||
91 | // Check transformed asset. | ||
92 | AssetBase ncAssetGet = scene.AssetService.Get(assetId.ToString()); | ||
93 | Assert.AreEqual(foreignUrl, ncAssetGet.CreatorID); | ||
94 | string xmlData = Utils.BytesToString(ncAssetGet.Data); | ||
95 | XmlDocument ncAssetGetXmlDoc = new XmlDocument(); | ||
96 | ncAssetGetXmlDoc.LoadXml(xmlData); | ||
97 | |||
98 | // Console.WriteLine(ncAssetGetXmlDoc.OuterXml); | ||
99 | |||
100 | XmlNodeList creatorDataNodes = ncAssetGetXmlDoc.GetElementsByTagName("CreatorData"); | ||
101 | |||
102 | Assert.AreEqual(soPartsCount, creatorDataNodes.Count); | ||
103 | //Console.WriteLine("creatorDataNodes {0}", creatorDataNodes.Count); | ||
104 | |||
105 | foreach (XmlNode creatorDataNode in creatorDataNodes) | ||
106 | { | ||
107 | Assert.AreEqual( | ||
108 | string.Format("{0};{1} {2}", homeUrl, ua.FirstName, ua.LastName), creatorDataNode.InnerText); | ||
109 | } | ||
110 | |||
111 | // Check that saved script nodes have attributes | ||
112 | XmlNodeList savedScriptStateNodes = ncAssetGetXmlDoc.GetElementsByTagName("SavedScriptState"); | ||
113 | |||
114 | Assert.AreEqual(1, savedScriptStateNodes.Count); | ||
115 | Assert.AreEqual(1, savedScriptStateNodes[0].Attributes.Count); | ||
116 | XmlNode uuidAttribute = savedScriptStateNodes[0].Attributes.GetNamedItem("UUID"); | ||
117 | Assert.NotNull(uuidAttribute); | ||
118 | // XXX: To check the actual UUID attribute we would have to do some work to retreive the UUID of the task | ||
119 | // item created earlier. | ||
120 | } | ||
121 | |||
122 | private void RezScript(Scene scene, UUID soId, string script, string itemName, UUID userId) | ||
123 | { | ||
124 | InventoryItemBase itemTemplate = new InventoryItemBase(); | ||
125 | // itemTemplate.ID = itemId; | ||
126 | itemTemplate.Name = itemName; | ||
127 | itemTemplate.Folder = soId; | ||
128 | itemTemplate.InvType = (int)InventoryType.LSL; | ||
129 | |||
130 | // XXX: Ultimately it would be better to be able to directly manipulate the script engine to rez a script | ||
131 | // immediately for tests rather than chunter through it's threaded mechanisms. | ||
132 | AutoResetEvent chatEvent = new AutoResetEvent(false); | ||
133 | |||
134 | scene.EventManager.OnChatFromWorld += (s, c) => | ||
135 | { | ||
136 | // Console.WriteLine("Got chat [{0}]", c.Message); | ||
137 | chatEvent.Set(); | ||
138 | }; | ||
139 | |||
140 | scene.RezNewScript(userId, itemTemplate, script); | ||
141 | |||
142 | // Console.WriteLine("HERE"); | ||
143 | Assert.IsTrue(chatEvent.WaitOne(60000), "Chat event in HGAssetMapperTests.RezScript not received"); | ||
144 | } | ||
145 | } | ||
146 | } \ No newline at end of file | ||
diff --git a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs index ac25a93..1d91165 100644 --- a/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs +++ b/OpenSim/Region/CoreModules/Framework/InventoryAccess/Tests/InventoryAccessModuleTests.cs | |||
@@ -37,14 +37,12 @@ using OpenSim.Data; | |||
37 | using OpenSim.Framework; | 37 | using OpenSim.Framework; |
38 | using OpenSim.Framework.Serialization; | 38 | using OpenSim.Framework.Serialization; |
39 | using OpenSim.Framework.Serialization.External; | 39 | using OpenSim.Framework.Serialization.External; |
40 | using OpenSim.Framework.Communications; | ||
41 | using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; | 40 | using OpenSim.Region.CoreModules.Avatar.Inventory.Archiver; |
42 | using OpenSim.Region.CoreModules.Framework.InventoryAccess; | 41 | using OpenSim.Region.CoreModules.Framework.InventoryAccess; |
43 | using OpenSim.Region.Framework.Scenes; | 42 | using OpenSim.Region.Framework.Scenes; |
44 | using OpenSim.Region.Framework.Scenes.Serialization; | 43 | using OpenSim.Region.Framework.Scenes.Serialization; |
45 | using OpenSim.Services.Interfaces; | 44 | using OpenSim.Services.Interfaces; |
46 | using OpenSim.Tests.Common; | 45 | using OpenSim.Tests.Common; |
47 | using OpenSim.Tests.Common.Mock; | ||
48 | 46 | ||
49 | namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests | 47 | namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests |
50 | { | 48 | { |
@@ -109,8 +107,9 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests | |||
109 | item1.AssetID = asset1.FullID; | 107 | item1.AssetID = asset1.FullID; |
110 | item1.ID = item1Id; | 108 | item1.ID = item1Id; |
111 | InventoryFolderBase objsFolder | 109 | InventoryFolderBase objsFolder |
112 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, m_userId, "Objects")[0]; | 110 | = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0]; |
113 | item1.Folder = objsFolder.ID; | 111 | item1.Folder = objsFolder.ID; |
112 | item1.Flags |= (uint)InventoryItemFlags.ObjectHasMultipleItems; | ||
114 | m_scene.AddInventoryItem(item1); | 113 | m_scene.AddInventoryItem(item1); |
115 | 114 | ||
116 | SceneObjectGroup so | 115 | SceneObjectGroup so |
@@ -159,7 +158,7 @@ namespace OpenSim.Region.CoreModules.Framework.InventoryAccess.Tests | |||
159 | item1.AssetID = asset1.FullID; | 158 | item1.AssetID = asset1.FullID; |
160 | item1.ID = item1Id; | 159 | item1.ID = item1Id; |
161 | InventoryFolderBase objsFolder | 160 | InventoryFolderBase objsFolder |
162 | = InventoryArchiveUtils.FindFolderByPath(m_scene.InventoryService, m_userId, "Objects")[0]; | 161 | = InventoryArchiveUtils.FindFoldersByPath(m_scene.InventoryService, m_userId, "Objects")[0]; |
163 | item1.Folder = objsFolder.ID; | 162 | item1.Folder = objsFolder.ID; |
164 | m_scene.AddInventoryItem(item1); | 163 | m_scene.AddInventoryItem(item1); |
165 | 164 | ||