diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 973 |
1 files changed, 614 insertions, 359 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index ec39726..30f7151 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -26,6 +26,7 @@ | |||
26 | */ | 26 | */ |
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Text; | ||
29 | using System.Xml; | 30 | using System.Xml; |
30 | using System.IO; | 31 | using System.IO; |
31 | using System.Collections.Generic; | 32 | using System.Collections.Generic; |
@@ -46,10 +47,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
46 | { | 47 | { |
47 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 48 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
48 | 49 | ||
49 | private string m_inventoryFileName = String.Empty; | ||
50 | private byte[] m_inventoryFileData = new byte[0]; | 50 | private byte[] m_inventoryFileData = new byte[0]; |
51 | private byte[] m_inventoryFileNameBytes = new byte[0]; | ||
52 | private string m_inventoryFileName = ""; | ||
51 | private uint m_inventoryFileNameSerial = 0; | 53 | private uint m_inventoryFileNameSerial = 0; |
52 | 54 | private bool m_inventoryPrivileged = false; | |
55 | private object m_inventoryFileLock = new object(); | ||
56 | |||
57 | private Dictionary<UUID, ArrayList> m_scriptErrors = new Dictionary<UUID, ArrayList>(); | ||
58 | |||
53 | /// <value> | 59 | /// <value> |
54 | /// The part to which the inventory belongs. | 60 | /// The part to which the inventory belongs. |
55 | /// </value> | 61 | /// </value> |
@@ -70,7 +76,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
70 | /// Tracks whether inventory has changed since the last persistent backup | 76 | /// Tracks whether inventory has changed since the last persistent backup |
71 | /// </summary> | 77 | /// </summary> |
72 | internal bool HasInventoryChanged; | 78 | internal bool HasInventoryChanged; |
73 | 79 | ||
74 | /// <value> | 80 | /// <value> |
75 | /// Inventory serial number | 81 | /// Inventory serial number |
76 | /// </value> | 82 | /// </value> |
@@ -85,7 +91,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
85 | /// </value> | 91 | /// </value> |
86 | protected internal TaskInventoryDictionary Items | 92 | protected internal TaskInventoryDictionary Items |
87 | { | 93 | { |
88 | get { return m_items; } | 94 | get |
95 | { | ||
96 | return m_items; | ||
97 | } | ||
89 | set | 98 | set |
90 | { | 99 | { |
91 | m_items = value; | 100 | m_items = value; |
@@ -102,7 +111,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
102 | return m_items.Count; | 111 | return m_items.Count; |
103 | } | 112 | } |
104 | } | 113 | } |
105 | 114 | ||
106 | /// <summary> | 115 | /// <summary> |
107 | /// Constructor | 116 | /// Constructor |
108 | /// </summary> | 117 | /// </summary> |
@@ -133,39 +142,54 @@ namespace OpenSim.Region.Framework.Scenes | |||
133 | /// </remarks> | 142 | /// </remarks> |
134 | public void ResetInventoryIDs() | 143 | public void ResetInventoryIDs() |
135 | { | 144 | { |
136 | if (null == m_part) | 145 | if (m_part == null) |
137 | return; | 146 | return; |
138 | 147 | ||
139 | lock (m_items) | 148 | m_items.LockItemsForWrite(true); |
149 | if (m_items.Count == 0) | ||
140 | { | 150 | { |
141 | if (0 == m_items.Count) | 151 | m_items.LockItemsForWrite(false); |
142 | return; | 152 | return; |
153 | } | ||
143 | 154 | ||
144 | IList<TaskInventoryItem> items = GetInventoryItems(); | 155 | UUID partID = m_part.UUID; |
145 | m_items.Clear(); | 156 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(m_items.Values); |
157 | m_items.Clear(); | ||
146 | 158 | ||
147 | foreach (TaskInventoryItem item in items) | 159 | foreach (TaskInventoryItem item in items) |
148 | { | 160 | { |
149 | item.ResetIDs(m_part.UUID); | 161 | item.ResetIDs(partID); |
150 | m_items.Add(item.ItemID, item); | 162 | m_items.Add(item.ItemID, item); |
151 | } | ||
152 | } | 163 | } |
164 | m_inventorySerial++; | ||
165 | m_items.LockItemsForWrite(false); | ||
153 | } | 166 | } |
154 | 167 | ||
155 | public void ResetObjectID() | 168 | public void ResetObjectID() |
156 | { | 169 | { |
157 | lock (Items) | 170 | if (m_part == null) |
171 | return; | ||
172 | |||
173 | m_items.LockItemsForWrite(true); | ||
174 | |||
175 | if (m_items.Count == 0) | ||
158 | { | 176 | { |
159 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | 177 | m_items.LockItemsForWrite(false); |
160 | Items.Clear(); | 178 | return; |
161 | |||
162 | foreach (TaskInventoryItem item in items) | ||
163 | { | ||
164 | item.ParentPartID = m_part.UUID; | ||
165 | item.ParentID = m_part.UUID; | ||
166 | Items.Add(item.ItemID, item); | ||
167 | } | ||
168 | } | 179 | } |
180 | |||
181 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(m_items.Values); | ||
182 | m_items.Clear(); | ||
183 | |||
184 | UUID partID = m_part.UUID; | ||
185 | foreach (TaskInventoryItem item in items) | ||
186 | { | ||
187 | item.ParentPartID = partID; | ||
188 | item.ParentID = partID; | ||
189 | m_items.Add(item.ItemID, item); | ||
190 | } | ||
191 | m_inventorySerial++; | ||
192 | m_items.LockItemsForWrite(false); | ||
169 | } | 193 | } |
170 | 194 | ||
171 | /// <summary> | 195 | /// <summary> |
@@ -174,18 +198,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
174 | /// <param name="ownerId"></param> | 198 | /// <param name="ownerId"></param> |
175 | public void ChangeInventoryOwner(UUID ownerId) | 199 | public void ChangeInventoryOwner(UUID ownerId) |
176 | { | 200 | { |
177 | lock (Items) | 201 | if(m_part == null) |
202 | return; | ||
203 | |||
204 | m_items.LockItemsForWrite(true); | ||
205 | if (m_items.Count == 0) | ||
178 | { | 206 | { |
179 | if (0 == Items.Count) | 207 | m_items.LockItemsForWrite(false); |
180 | { | 208 | return; |
181 | return; | ||
182 | } | ||
183 | } | 209 | } |
184 | 210 | ||
185 | HasInventoryChanged = true; | 211 | foreach (TaskInventoryItem item in m_items.Values) |
186 | m_part.ParentGroup.HasGroupChanged = true; | ||
187 | List<TaskInventoryItem> items = GetInventoryItems(); | ||
188 | foreach (TaskInventoryItem item in items) | ||
189 | { | 212 | { |
190 | if (ownerId != item.OwnerID) | 213 | if (ownerId != item.OwnerID) |
191 | item.LastOwnerID = item.OwnerID; | 214 | item.LastOwnerID = item.OwnerID; |
@@ -195,6 +218,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
195 | item.PermsGranter = UUID.Zero; | 218 | item.PermsGranter = UUID.Zero; |
196 | item.OwnerChanged = true; | 219 | item.OwnerChanged = true; |
197 | } | 220 | } |
221 | HasInventoryChanged = true; | ||
222 | m_part.ParentGroup.HasGroupChanged = true; | ||
223 | m_inventorySerial++; | ||
224 | m_items.LockItemsForWrite(false); | ||
198 | } | 225 | } |
199 | 226 | ||
200 | /// <summary> | 227 | /// <summary> |
@@ -203,14 +230,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
203 | /// <param name="groupID"></param> | 230 | /// <param name="groupID"></param> |
204 | public void ChangeInventoryGroup(UUID groupID) | 231 | public void ChangeInventoryGroup(UUID groupID) |
205 | { | 232 | { |
206 | lock (Items) | 233 | if(m_part == null) |
234 | return; | ||
235 | |||
236 | m_items.LockItemsForWrite(true); | ||
237 | if (m_items.Count == 0) | ||
207 | { | 238 | { |
208 | if (0 == Items.Count) | 239 | m_items.LockItemsForWrite(false); |
209 | { | 240 | return; |
210 | return; | ||
211 | } | ||
212 | } | 241 | } |
213 | 242 | m_inventorySerial++; | |
214 | // Don't let this set the HasGroupChanged flag for attachments | 243 | // Don't let this set the HasGroupChanged flag for attachments |
215 | // as this happens during rez and we don't want a new asset | 244 | // as this happens during rez and we don't want a new asset |
216 | // for each attachment each time | 245 | // for each attachment each time |
@@ -220,12 +249,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
220 | m_part.ParentGroup.HasGroupChanged = true; | 249 | m_part.ParentGroup.HasGroupChanged = true; |
221 | } | 250 | } |
222 | 251 | ||
223 | List<TaskInventoryItem> items = GetInventoryItems(); | 252 | foreach (TaskInventoryItem item in m_items.Values) |
224 | foreach (TaskInventoryItem item in items) | 253 | item.GroupID = groupID; |
225 | { | 254 | |
226 | if (groupID != item.GroupID) | 255 | m_items.LockItemsForWrite(false); |
227 | item.GroupID = groupID; | ||
228 | } | ||
229 | } | 256 | } |
230 | 257 | ||
231 | private void QueryScriptStates() | 258 | private void QueryScriptStates() |
@@ -233,15 +260,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
233 | if (m_part == null || m_part.ParentGroup == null || m_part.ParentGroup.Scene == null) | 260 | if (m_part == null || m_part.ParentGroup == null || m_part.ParentGroup.Scene == null) |
234 | return; | 261 | return; |
235 | 262 | ||
236 | lock (Items) | 263 | m_items.LockItemsForRead(true); |
264 | foreach (TaskInventoryItem item in m_items.Values) | ||
237 | { | 265 | { |
238 | foreach (TaskInventoryItem item in Items.Values) | 266 | if (item.InvType == (int)InventoryType.LSL) |
239 | { | 267 | { |
240 | bool running; | 268 | bool running; |
241 | if (TryGetScriptInstanceRunning(m_part.ParentGroup.Scene, item, out running)) | 269 | if (TryGetScriptInstanceRunning(m_part.ParentGroup.Scene, item, out running)) |
242 | item.ScriptRunning = running; | 270 | item.ScriptRunning = running; |
243 | } | 271 | } |
244 | } | 272 | } |
273 | |||
274 | m_items.LockItemsForRead(false); | ||
245 | } | 275 | } |
246 | 276 | ||
247 | public bool TryGetScriptInstanceRunning(UUID itemId, out bool running) | 277 | public bool TryGetScriptInstanceRunning(UUID itemId, out bool running) |
@@ -318,7 +348,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
318 | { | 348 | { |
319 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); | 349 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); |
320 | foreach (TaskInventoryItem item in scripts) | 350 | foreach (TaskInventoryItem item in scripts) |
351 | { | ||
321 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); | 352 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); |
353 | m_part.RemoveScriptEvents(item.ItemID); | ||
354 | } | ||
322 | } | 355 | } |
323 | 356 | ||
324 | /// <summary> | 357 | /// <summary> |
@@ -326,7 +359,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
326 | /// </summary> | 359 | /// </summary> |
327 | public void StopScriptInstances() | 360 | public void StopScriptInstances() |
328 | { | 361 | { |
329 | GetInventoryItems(InventoryType.LSL).ForEach(i => StopScriptInstance(i)); | 362 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); |
363 | foreach (TaskInventoryItem item in scripts) | ||
364 | StopScriptInstance(item); | ||
330 | } | 365 | } |
331 | 366 | ||
332 | /// <summary> | 367 | /// <summary> |
@@ -339,8 +374,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
339 | // m_log.DebugFormat("[PRIM INVENTORY]: Starting script {0} {1} in prim {2} {3} in {4}", | 374 | // m_log.DebugFormat("[PRIM INVENTORY]: Starting script {0} {1} in prim {2} {3} in {4}", |
340 | // item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 375 | // item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
341 | 376 | ||
342 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) | 377 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item, m_part)) |
378 | { | ||
379 | StoreScriptError(item.ItemID, "no permission"); | ||
343 | return false; | 380 | return false; |
381 | } | ||
344 | 382 | ||
345 | m_part.AddFlag(PrimFlags.Scripted); | 383 | m_part.AddFlag(PrimFlags.Scripted); |
346 | 384 | ||
@@ -350,14 +388,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
350 | if (stateSource == 2 && // Prim crossing | 388 | if (stateSource == 2 && // Prim crossing |
351 | m_part.ParentGroup.Scene.m_trustBinaries) | 389 | m_part.ParentGroup.Scene.m_trustBinaries) |
352 | { | 390 | { |
353 | lock (m_items) | 391 | m_items.LockItemsForWrite(true); |
354 | { | 392 | m_items[item.ItemID].PermsMask = 0; |
355 | m_items[item.ItemID].PermsMask = 0; | 393 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
356 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 394 | m_items.LockItemsForWrite(false); |
357 | } | ||
358 | |||
359 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 395 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
360 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); | 396 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); |
397 | StoreScriptErrors(item.ItemID, null); | ||
361 | m_part.ParentGroup.AddActiveScriptCount(1); | 398 | m_part.ParentGroup.AddActiveScriptCount(1); |
362 | m_part.ScheduleFullUpdate(); | 399 | m_part.ScheduleFullUpdate(); |
363 | return true; | 400 | return true; |
@@ -366,9 +403,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
366 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); | 403 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); |
367 | if (null == asset) | 404 | if (null == asset) |
368 | { | 405 | { |
406 | string msg = String.Format("asset ID {0} could not be found", item.AssetID); | ||
407 | StoreScriptError(item.ItemID, msg); | ||
369 | m_log.ErrorFormat( | 408 | m_log.ErrorFormat( |
370 | "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", | 409 | "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", |
371 | item.Name, item.ItemID, m_part.AbsolutePosition, | 410 | item.Name, item.ItemID, m_part.AbsolutePosition, |
372 | m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); | 411 | m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); |
373 | 412 | ||
374 | return false; | 413 | return false; |
@@ -378,16 +417,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
378 | if (m_part.ParentGroup.m_savedScriptState != null) | 417 | if (m_part.ParentGroup.m_savedScriptState != null) |
379 | item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); | 418 | item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); |
380 | 419 | ||
381 | lock (m_items) | 420 | m_items.LockItemsForWrite(true); |
382 | { | 421 | |
383 | m_items[item.ItemID].OldItemID = item.OldItemID; | 422 | m_items[item.ItemID].OldItemID = item.OldItemID; |
384 | m_items[item.ItemID].PermsMask = 0; | 423 | m_items[item.ItemID].PermsMask = 0; |
385 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 424 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
386 | } | 425 | |
426 | m_items.LockItemsForWrite(false); | ||
387 | 427 | ||
388 | string script = Utils.BytesToString(asset.Data); | 428 | string script = Utils.BytesToString(asset.Data); |
389 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 429 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
390 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); | 430 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); |
431 | StoreScriptErrors(item.ItemID, null); | ||
391 | if (!item.ScriptRunning) | 432 | if (!item.ScriptRunning) |
392 | m_part.ParentGroup.Scene.EventManager.TriggerStopScript( | 433 | m_part.ParentGroup.Scene.EventManager.TriggerStopScript( |
393 | m_part.LocalId, item.ItemID); | 434 | m_part.LocalId, item.ItemID); |
@@ -401,7 +442,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
401 | private UUID RestoreSavedScriptState(UUID loadedID, UUID oldID, UUID newID) | 442 | private UUID RestoreSavedScriptState(UUID loadedID, UUID oldID, UUID newID) |
402 | { | 443 | { |
403 | // m_log.DebugFormat( | 444 | // m_log.DebugFormat( |
404 | // "[PRIM INVENTORY]: Restoring scripted state for item {0}, oldID {1}, loadedID {2}", | 445 | // "[PRIM INVENTORY]: Restoring scripted state for item {0}, oldID {1}, loadedID {2}", |
405 | // newID, oldID, loadedID); | 446 | // newID, oldID, loadedID); |
406 | 447 | ||
407 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); | 448 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); |
@@ -414,7 +455,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
414 | if (m_part.ParentGroup.m_savedScriptState.ContainsKey(stateID)) | 455 | if (m_part.ParentGroup.m_savedScriptState.ContainsKey(stateID)) |
415 | { | 456 | { |
416 | XmlDocument doc = new XmlDocument(); | 457 | XmlDocument doc = new XmlDocument(); |
417 | 458 | doc.XmlResolver=null; | |
418 | doc.LoadXml(m_part.ParentGroup.m_savedScriptState[stateID]); | 459 | doc.LoadXml(m_part.ParentGroup.m_savedScriptState[stateID]); |
419 | 460 | ||
420 | ////////// CRUFT WARNING /////////////////////////////////// | 461 | ////////// CRUFT WARNING /////////////////////////////////// |
@@ -450,7 +491,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
450 | 491 | ||
451 | m_part.ParentGroup.m_savedScriptState[stateID] = newDoc.OuterXml; | 492 | m_part.ParentGroup.m_savedScriptState[stateID] = newDoc.OuterXml; |
452 | } | 493 | } |
453 | 494 | ||
454 | foreach (IScriptModule e in engines) | 495 | foreach (IScriptModule e in engines) |
455 | { | 496 | { |
456 | if (e != null) | 497 | if (e != null) |
@@ -466,22 +507,138 @@ namespace OpenSim.Region.Framework.Scenes | |||
466 | return stateID; | 507 | return stateID; |
467 | } | 508 | } |
468 | 509 | ||
510 | /// <summary> | ||
511 | /// Start a script which is in this prim's inventory. | ||
512 | /// Some processing may occur in the background, but this routine returns asap. | ||
513 | /// </summary> | ||
514 | /// <param name="itemId"> | ||
515 | /// A <see cref="UUID"/> | ||
516 | /// </param> | ||
469 | public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | 517 | public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) |
470 | { | 518 | { |
471 | TaskInventoryItem item = GetInventoryItem(itemId); | 519 | lock (m_scriptErrors) |
472 | if (item != null) | 520 | { |
521 | // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion | ||
522 | m_scriptErrors.Remove(itemId); | ||
523 | } | ||
524 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
525 | return true; | ||
526 | } | ||
527 | |||
528 | private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
529 | { | ||
530 | m_items.LockItemsForRead(true); | ||
531 | |||
532 | if (m_items.ContainsKey(itemId)) | ||
473 | { | 533 | { |
474 | return CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | 534 | TaskInventoryItem it = m_items[itemId]; |
535 | m_items.LockItemsForRead(false); | ||
536 | |||
537 | CreateScriptInstance(it, startParam, postOnRez, engine, stateSource); | ||
475 | } | 538 | } |
476 | else | 539 | else |
477 | { | 540 | { |
478 | m_log.ErrorFormat( | 541 | m_items.LockItemsForRead(false); |
479 | "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", | 542 | string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID, |
480 | itemId, m_part.Name, m_part.UUID, | ||
481 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 543 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
544 | StoreScriptError(itemId, msg); | ||
545 | m_log.ErrorFormat( | ||
546 | "[PRIM INVENTORY]: " + | ||
547 | "Couldn't start script with ID {0} since it {1}", itemId, msg); | ||
548 | } | ||
549 | } | ||
482 | 550 | ||
483 | return false; | 551 | /// <summary> |
552 | /// Start a script which is in this prim's inventory and return any compilation error messages. | ||
553 | /// </summary> | ||
554 | /// <param name="itemId"> | ||
555 | /// A <see cref="UUID"/> | ||
556 | /// </param> | ||
557 | public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
558 | { | ||
559 | ArrayList errors; | ||
560 | |||
561 | // Indicate to CreateScriptInstanceInternal() we want it to | ||
562 | // post any compilation/loading error messages | ||
563 | lock (m_scriptErrors) | ||
564 | { | ||
565 | m_scriptErrors[itemId] = null; | ||
484 | } | 566 | } |
567 | |||
568 | // Perform compilation/loading | ||
569 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
570 | |||
571 | // Wait for and retrieve any errors | ||
572 | lock (m_scriptErrors) | ||
573 | { | ||
574 | while ((errors = m_scriptErrors[itemId]) == null) | ||
575 | { | ||
576 | if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000)) | ||
577 | { | ||
578 | m_log.ErrorFormat( | ||
579 | "[PRIM INVENTORY]: " + | ||
580 | "timedout waiting for script {0} errors", itemId); | ||
581 | errors = m_scriptErrors[itemId]; | ||
582 | if (errors == null) | ||
583 | { | ||
584 | errors = new ArrayList(1); | ||
585 | errors.Add("timedout waiting for errors"); | ||
586 | } | ||
587 | break; | ||
588 | } | ||
589 | } | ||
590 | m_scriptErrors.Remove(itemId); | ||
591 | } | ||
592 | return errors; | ||
593 | } | ||
594 | |||
595 | // Signal to CreateScriptInstanceEr() that compilation/loading is complete | ||
596 | private void StoreScriptErrors(UUID itemId, ArrayList errors) | ||
597 | { | ||
598 | lock (m_scriptErrors) | ||
599 | { | ||
600 | // If compilation/loading initiated via CreateScriptInstance(), | ||
601 | // it does not want the errors, so just get out | ||
602 | if (!m_scriptErrors.ContainsKey(itemId)) | ||
603 | { | ||
604 | return; | ||
605 | } | ||
606 | |||
607 | // Initiated via CreateScriptInstanceEr(), if we know what the | ||
608 | // errors are, save them and wake CreateScriptInstanceEr(). | ||
609 | if (errors != null) | ||
610 | { | ||
611 | m_scriptErrors[itemId] = errors; | ||
612 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
613 | return; | ||
614 | } | ||
615 | } | ||
616 | |||
617 | // Initiated via CreateScriptInstanceEr() but we don't know what | ||
618 | // the errors are yet, so retrieve them from the script engine. | ||
619 | // This may involve some waiting internal to GetScriptErrors(). | ||
620 | errors = GetScriptErrors(itemId); | ||
621 | |||
622 | // Get a default non-null value to indicate success. | ||
623 | if (errors == null) | ||
624 | { | ||
625 | errors = new ArrayList(); | ||
626 | } | ||
627 | |||
628 | // Post to CreateScriptInstanceEr() and wake it up | ||
629 | lock (m_scriptErrors) | ||
630 | { | ||
631 | m_scriptErrors[itemId] = errors; | ||
632 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
633 | } | ||
634 | } | ||
635 | |||
636 | // Like StoreScriptErrors(), but just posts a single string message | ||
637 | private void StoreScriptError(UUID itemId, string message) | ||
638 | { | ||
639 | ArrayList errors = new ArrayList(1); | ||
640 | errors.Add(message); | ||
641 | StoreScriptErrors(itemId, errors); | ||
485 | } | 642 | } |
486 | 643 | ||
487 | /// <summary> | 644 | /// <summary> |
@@ -494,19 +651,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
494 | /// </param> | 651 | /// </param> |
495 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) | 652 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) |
496 | { | 653 | { |
497 | bool scriptPresent = false; | 654 | if (m_items.ContainsKey(itemId)) |
498 | |||
499 | lock (m_items) | ||
500 | { | ||
501 | if (m_items.ContainsKey(itemId)) | ||
502 | scriptPresent = true; | ||
503 | } | ||
504 | |||
505 | if (scriptPresent) | ||
506 | { | 655 | { |
507 | if (!sceneObjectBeingDeleted) | 656 | if (!sceneObjectBeingDeleted) |
508 | m_part.RemoveScriptEvents(itemId); | 657 | m_part.RemoveScriptEvents(itemId); |
509 | 658 | ||
510 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemId); | 659 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemId); |
511 | m_part.ParentGroup.AddActiveScriptCount(-1); | 660 | m_part.ParentGroup.AddActiveScriptCount(-1); |
512 | } | 661 | } |
@@ -515,7 +664,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
515 | m_log.WarnFormat( | 664 | m_log.WarnFormat( |
516 | "[PRIM INVENTORY]: " + | 665 | "[PRIM INVENTORY]: " + |
517 | "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", | 666 | "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", |
518 | itemId, m_part.Name, m_part.UUID, | 667 | itemId, m_part.Name, m_part.UUID, |
519 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 668 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
520 | } | 669 | } |
521 | } | 670 | } |
@@ -544,7 +693,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
544 | m_log.WarnFormat( | 693 | m_log.WarnFormat( |
545 | "[PRIM INVENTORY]: " + | 694 | "[PRIM INVENTORY]: " + |
546 | "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", | 695 | "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", |
547 | itemId, m_part.Name, m_part.UUID, | 696 | itemId, m_part.Name, m_part.UUID, |
548 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 697 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
549 | } | 698 | } |
550 | } | 699 | } |
@@ -573,14 +722,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
573 | /// <returns></returns> | 722 | /// <returns></returns> |
574 | private bool InventoryContainsName(string name) | 723 | private bool InventoryContainsName(string name) |
575 | { | 724 | { |
576 | lock (m_items) | 725 | m_items.LockItemsForRead(true); |
726 | foreach (TaskInventoryItem item in m_items.Values) | ||
577 | { | 727 | { |
578 | foreach (TaskInventoryItem item in m_items.Values) | 728 | if (item.Name == name) |
579 | { | 729 | { |
580 | if (item.Name == name) | 730 | m_items.LockItemsForRead(false); |
581 | return true; | 731 | return true; |
582 | } | 732 | } |
583 | } | 733 | } |
734 | m_items.LockItemsForRead(false); | ||
584 | return false; | 735 | return false; |
585 | } | 736 | } |
586 | 737 | ||
@@ -622,8 +773,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
622 | /// <param name="item"></param> | 773 | /// <param name="item"></param> |
623 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) | 774 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) |
624 | { | 775 | { |
625 | List<TaskInventoryItem> il = GetInventoryItems(); | 776 | m_items.LockItemsForRead(true); |
626 | 777 | List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); | |
778 | m_items.LockItemsForRead(false); | ||
627 | foreach (TaskInventoryItem i in il) | 779 | foreach (TaskInventoryItem i in il) |
628 | { | 780 | { |
629 | if (i.Name == item.Name) | 781 | if (i.Name == item.Name) |
@@ -661,16 +813,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
661 | item.Name = name; | 813 | item.Name = name; |
662 | item.GroupID = m_part.GroupID; | 814 | item.GroupID = m_part.GroupID; |
663 | 815 | ||
664 | lock (m_items) | 816 | m_items.LockItemsForWrite(true); |
665 | m_items.Add(item.ItemID, item); | 817 | m_items.Add(item.ItemID, item); |
666 | 818 | m_items.LockItemsForWrite(false); | |
667 | if (allowedDrop) | 819 | if (allowedDrop) |
668 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); | 820 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); |
669 | else | 821 | else |
670 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 822 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
671 | 823 | ||
824 | m_part.AggregateInnerPerms(); | ||
672 | m_inventorySerial++; | 825 | m_inventorySerial++; |
673 | //m_inventorySerial += 2; | ||
674 | HasInventoryChanged = true; | 826 | HasInventoryChanged = true; |
675 | m_part.ParentGroup.HasGroupChanged = true; | 827 | m_part.ParentGroup.HasGroupChanged = true; |
676 | } | 828 | } |
@@ -684,15 +836,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
684 | /// <param name="items"></param> | 836 | /// <param name="items"></param> |
685 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) | 837 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) |
686 | { | 838 | { |
687 | lock (m_items) | 839 | m_items.LockItemsForWrite(true); |
840 | foreach (TaskInventoryItem item in items) | ||
688 | { | 841 | { |
689 | foreach (TaskInventoryItem item in items) | 842 | m_items.Add(item.ItemID, item); |
690 | { | 843 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
691 | m_items.Add(item.ItemID, item); | ||
692 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
693 | } | ||
694 | m_inventorySerial++; | ||
695 | } | 844 | } |
845 | m_items.LockItemsForWrite(false); | ||
846 | m_part.AggregateInnerPerms(); | ||
847 | m_inventorySerial++; | ||
696 | } | 848 | } |
697 | 849 | ||
698 | /// <summary> | 850 | /// <summary> |
@@ -703,23 +855,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
703 | public TaskInventoryItem GetInventoryItem(UUID itemId) | 855 | public TaskInventoryItem GetInventoryItem(UUID itemId) |
704 | { | 856 | { |
705 | TaskInventoryItem item; | 857 | TaskInventoryItem item; |
706 | 858 | m_items.LockItemsForRead(true); | |
707 | lock (m_items) | 859 | m_items.TryGetValue(itemId, out item); |
708 | m_items.TryGetValue(itemId, out item); | 860 | m_items.LockItemsForRead(false); |
709 | |||
710 | return item; | 861 | return item; |
711 | } | 862 | } |
712 | 863 | ||
713 | public TaskInventoryItem GetInventoryItem(string name) | 864 | public TaskInventoryItem GetInventoryItem(string name) |
714 | { | 865 | { |
715 | lock (m_items) | 866 | m_items.LockItemsForRead(true); |
867 | foreach (TaskInventoryItem item in m_items.Values) | ||
716 | { | 868 | { |
717 | foreach (TaskInventoryItem item in m_items.Values) | 869 | if (item.Name == name) |
718 | { | 870 | { |
719 | if (item.Name == name) | 871 | m_items.LockItemsForRead(false); |
720 | return item; | 872 | return item; |
721 | } | 873 | } |
722 | } | 874 | } |
875 | m_items.LockItemsForRead(false); | ||
723 | 876 | ||
724 | return null; | 877 | return null; |
725 | } | 878 | } |
@@ -728,41 +881,45 @@ namespace OpenSim.Region.Framework.Scenes | |||
728 | { | 881 | { |
729 | List<TaskInventoryItem> items = new List<TaskInventoryItem>(); | 882 | List<TaskInventoryItem> items = new List<TaskInventoryItem>(); |
730 | 883 | ||
731 | lock (m_items) | 884 | m_items.LockItemsForRead(true); |
885 | |||
886 | foreach (TaskInventoryItem item in m_items.Values) | ||
732 | { | 887 | { |
733 | foreach (TaskInventoryItem item in m_items.Values) | 888 | if (item.Name == name) |
734 | { | 889 | items.Add(item); |
735 | if (item.Name == name) | ||
736 | items.Add(item); | ||
737 | } | ||
738 | } | 890 | } |
739 | 891 | ||
892 | m_items.LockItemsForRead(false); | ||
893 | |||
740 | return items; | 894 | return items; |
741 | } | 895 | } |
742 | 896 | ||
743 | public bool GetRezReadySceneObjects(TaskInventoryItem item, out List<SceneObjectGroup> objlist, out List<Vector3> veclist) | 897 | public bool GetRezReadySceneObjects(TaskInventoryItem item, out List<SceneObjectGroup> objlist, out List<Vector3> veclist, out Vector3 bbox, out float offsetHeight) |
744 | { | 898 | { |
745 | AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); | 899 | AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); |
746 | 900 | ||
747 | if (null == rezAsset) | 901 | if (null == rezAsset) |
748 | { | 902 | { |
749 | m_log.WarnFormat( | 903 | m_log.WarnFormat( |
750 | "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}", | 904 | "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}", |
751 | item.AssetID, item.Name, m_part.Name); | 905 | item.AssetID, item.Name, m_part.Name); |
752 | objlist = null; | 906 | objlist = null; |
753 | veclist = null; | 907 | veclist = null; |
908 | bbox = Vector3.Zero; | ||
909 | offsetHeight = 0; | ||
754 | return false; | 910 | return false; |
755 | } | 911 | } |
756 | 912 | ||
757 | Vector3 bbox; | 913 | bool single = m_part.ParentGroup.Scene.GetObjectsToRez(rezAsset.Data, false, out objlist, out veclist, out bbox, out offsetHeight); |
758 | float offsetHeight; | ||
759 | |||
760 | m_part.ParentGroup.Scene.GetObjectsToRez(rezAsset.Data, false, out objlist, out veclist, out bbox, out offsetHeight); | ||
761 | 914 | ||
762 | for (int i = 0; i < objlist.Count; i++) | 915 | for (int i = 0; i < objlist.Count; i++) |
763 | { | 916 | { |
764 | SceneObjectGroup group = objlist[i]; | 917 | SceneObjectGroup group = objlist[i]; |
765 | 918 | /* | |
919 | group.RootPart.AttachPoint = group.RootPart.Shape.State; | ||
920 | group.RootPart.AttachedPos = group.AbsolutePosition; | ||
921 | group.RootPart.AttachRotation = group.GroupRotation; | ||
922 | */ | ||
766 | group.ResetIDs(); | 923 | group.ResetIDs(); |
767 | 924 | ||
768 | SceneObjectPart rootPart = group.GetPart(group.UUID); | 925 | SceneObjectPart rootPart = group.GetPart(group.UUID); |
@@ -771,12 +928,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
771 | // in the serialization, transfer the correct name from the inventory to the | 928 | // in the serialization, transfer the correct name from the inventory to the |
772 | // object itself before we rez. | 929 | // object itself before we rez. |
773 | // Only do these for the first object if we are rezzing a coalescence. | 930 | // Only do these for the first object if we are rezzing a coalescence. |
774 | if (i == 0) | 931 | // nahh dont mess with coalescence objects, |
932 | // the name in inventory can be change for inventory purpuses only | ||
933 | if (objlist.Count == 1) | ||
775 | { | 934 | { |
776 | rootPart.Name = item.Name; | 935 | rootPart.Name = item.Name; |
777 | rootPart.Description = item.Description; | 936 | rootPart.Description = item.Description; |
778 | } | 937 | } |
779 | 938 | /* reverted to old code till part.ApplyPermissionsOnRez is better reviewed/fixed | |
780 | group.SetGroup(m_part.GroupID, null); | 939 | group.SetGroup(m_part.GroupID, null); |
781 | 940 | ||
782 | foreach (SceneObjectPart part in group.Parts) | 941 | foreach (SceneObjectPart part in group.Parts) |
@@ -792,13 +951,55 @@ namespace OpenSim.Region.Framework.Scenes | |||
792 | 951 | ||
793 | part.ApplyPermissionsOnRez(dest, false, m_part.ParentGroup.Scene); | 952 | part.ApplyPermissionsOnRez(dest, false, m_part.ParentGroup.Scene); |
794 | } | 953 | } |
954 | */ | ||
955 | // old code start | ||
956 | SceneObjectPart[] partList = group.Parts; | ||
795 | 957 | ||
958 | group.SetGroup(m_part.GroupID, null); | ||
959 | |||
960 | if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & (uint)PermissionMask.Slam) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) | ||
961 | { | ||
962 | if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions()) | ||
963 | { | ||
964 | foreach (SceneObjectPart part in partList) | ||
965 | { | ||
966 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) | ||
967 | part.EveryoneMask = item.EveryonePermissions; | ||
968 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) | ||
969 | part.NextOwnerMask = item.NextPermissions; | ||
970 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) | ||
971 | part.GroupMask = item.GroupPermissions; | ||
972 | } | ||
973 | |||
974 | group.ApplyNextOwnerPermissions(); | ||
975 | } | ||
976 | } | ||
977 | |||
978 | foreach (SceneObjectPart part in partList) | ||
979 | { | ||
980 | if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & (uint)PermissionMask.Slam) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0) | ||
981 | { | ||
982 | if(part.GroupID != part.OwnerID) | ||
983 | part.LastOwnerID = part.OwnerID; | ||
984 | part.OwnerID = item.OwnerID; | ||
985 | part.Inventory.ChangeInventoryOwner(item.OwnerID); | ||
986 | } | ||
987 | |||
988 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0) | ||
989 | part.EveryoneMask = item.EveryonePermissions; | ||
990 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0) | ||
991 | part.NextOwnerMask = item.NextPermissions; | ||
992 | if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0) | ||
993 | part.GroupMask = item.GroupPermissions; | ||
994 | } | ||
995 | // old code end | ||
796 | rootPart.TrimPermissions(); | 996 | rootPart.TrimPermissions(); |
997 | group.InvalidateDeepEffectivePerms(); | ||
797 | } | 998 | } |
798 | 999 | ||
799 | return true; | 1000 | return true; |
800 | } | 1001 | } |
801 | 1002 | ||
802 | /// <summary> | 1003 | /// <summary> |
803 | /// Update an existing inventory item. | 1004 | /// Update an existing inventory item. |
804 | /// </summary> | 1005 | /// </summary> |
@@ -817,11 +1018,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
817 | 1018 | ||
818 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) | 1019 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) |
819 | { | 1020 | { |
820 | TaskInventoryItem it = GetInventoryItem(item.ItemID); | 1021 | m_items.LockItemsForWrite(true); |
821 | if (it != null) | 1022 | |
1023 | if (m_items.ContainsKey(item.ItemID)) | ||
822 | { | 1024 | { |
823 | // m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); | 1025 | // m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); |
824 | 1026 | ||
825 | item.ParentID = m_part.UUID; | 1027 | item.ParentID = m_part.UUID; |
826 | item.ParentPartID = m_part.UUID; | 1028 | item.ParentPartID = m_part.UUID; |
827 | 1029 | ||
@@ -830,24 +1032,26 @@ namespace OpenSim.Region.Framework.Scenes | |||
830 | if (item.GroupPermissions != (uint)PermissionMask.None) | 1032 | if (item.GroupPermissions != (uint)PermissionMask.None) |
831 | item.GroupID = m_part.GroupID; | 1033 | item.GroupID = m_part.GroupID; |
832 | 1034 | ||
1035 | if(item.OwnerID == UUID.Zero) // viewer to internal enconding of group owned | ||
1036 | item.OwnerID = item.GroupID; | ||
1037 | |||
833 | if (item.AssetID == UUID.Zero) | 1038 | if (item.AssetID == UUID.Zero) |
834 | item.AssetID = it.AssetID; | 1039 | item.AssetID = m_items[item.ItemID].AssetID; |
835 | 1040 | ||
836 | lock (m_items) | 1041 | m_items[item.ItemID] = item; |
837 | { | 1042 | |
838 | m_items[item.ItemID] = item; | 1043 | m_inventorySerial++; |
839 | m_inventorySerial++; | ||
840 | } | ||
841 | |||
842 | if (fireScriptEvents) | 1044 | if (fireScriptEvents) |
843 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 1045 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
844 | 1046 | ||
845 | if (considerChanged) | 1047 | if (considerChanged) |
846 | { | 1048 | { |
1049 | m_part.ParentGroup.InvalidateDeepEffectivePerms(); | ||
847 | HasInventoryChanged = true; | 1050 | HasInventoryChanged = true; |
848 | m_part.ParentGroup.HasGroupChanged = true; | 1051 | m_part.ParentGroup.HasGroupChanged = true; |
849 | } | 1052 | } |
850 | 1053 | m_items.LockItemsForWrite(false); | |
1054 | |||
851 | return true; | 1055 | return true; |
852 | } | 1056 | } |
853 | else | 1057 | else |
@@ -855,11 +1059,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
855 | m_log.ErrorFormat( | 1059 | m_log.ErrorFormat( |
856 | "[PRIM INVENTORY]: " + | 1060 | "[PRIM INVENTORY]: " + |
857 | "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", | 1061 | "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", |
858 | item.ItemID, m_part.Name, m_part.UUID, | 1062 | item.ItemID, m_part.Name, m_part.UUID, |
859 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 1063 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
860 | } | 1064 | } |
861 | return false; | 1065 | m_items.LockItemsForWrite(false); |
862 | 1066 | ||
1067 | return false; | ||
863 | } | 1068 | } |
864 | 1069 | ||
865 | /// <summary> | 1070 | /// <summary> |
@@ -870,160 +1075,194 @@ namespace OpenSim.Region.Framework.Scenes | |||
870 | /// in this prim's inventory.</returns> | 1075 | /// in this prim's inventory.</returns> |
871 | public int RemoveInventoryItem(UUID itemID) | 1076 | public int RemoveInventoryItem(UUID itemID) |
872 | { | 1077 | { |
873 | TaskInventoryItem item = GetInventoryItem(itemID); | 1078 | m_items.LockItemsForRead(true); |
874 | if (item != null) | 1079 | |
1080 | if (m_items.ContainsKey(itemID)) | ||
875 | { | 1081 | { |
876 | int type = m_items[itemID].InvType; | 1082 | int type = m_items[itemID].InvType; |
877 | if (type == 10) // Script | 1083 | m_items.LockItemsForRead(false); |
1084 | if (type == (int)InventoryType.LSL) // Script | ||
878 | { | 1085 | { |
879 | // route it through here, to handle script cleanup tasks | 1086 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); |
880 | RemoveScriptInstance(itemID, false); | ||
881 | } | 1087 | } |
1088 | m_items.LockItemsForWrite(true); | ||
882 | m_items.Remove(itemID); | 1089 | m_items.Remove(itemID); |
1090 | m_items.LockItemsForWrite(false); | ||
1091 | |||
1092 | m_part.ParentGroup.InvalidateDeepEffectivePerms(); | ||
1093 | |||
883 | m_inventorySerial++; | 1094 | m_inventorySerial++; |
884 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 1095 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
885 | 1096 | ||
886 | HasInventoryChanged = true; | 1097 | HasInventoryChanged = true; |
887 | m_part.ParentGroup.HasGroupChanged = true; | 1098 | m_part.ParentGroup.HasGroupChanged = true; |
888 | 1099 | ||
889 | if (!ContainsScripts()) | 1100 | int scriptcount = 0; |
1101 | m_items.LockItemsForRead(true); | ||
1102 | foreach (TaskInventoryItem item in m_items.Values) | ||
1103 | { | ||
1104 | if (item.Type == (int)InventoryType.LSL) | ||
1105 | { | ||
1106 | scriptcount++; | ||
1107 | } | ||
1108 | } | ||
1109 | m_items.LockItemsForRead(false); | ||
1110 | |||
1111 | |||
1112 | if (scriptcount <= 0) | ||
1113 | { | ||
890 | m_part.RemFlag(PrimFlags.Scripted); | 1114 | m_part.RemFlag(PrimFlags.Scripted); |
1115 | } | ||
891 | 1116 | ||
892 | m_part.ScheduleFullUpdate(); | 1117 | m_part.ScheduleFullUpdate(); |
893 | 1118 | ||
894 | return type; | 1119 | return type; |
895 | |||
896 | } | 1120 | } |
897 | else | 1121 | else |
898 | { | 1122 | { |
1123 | m_items.LockItemsForRead(false); | ||
899 | m_log.ErrorFormat( | 1124 | m_log.ErrorFormat( |
900 | "[PRIM INVENTORY]: " + | 1125 | "[PRIM INVENTORY]: " + |
901 | "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", | 1126 | "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", |
902 | itemID, m_part.Name, m_part.UUID, | 1127 | itemID, m_part.Name, m_part.UUID); |
903 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
904 | } | 1128 | } |
905 | 1129 | ||
906 | return -1; | 1130 | return -1; |
907 | } | 1131 | } |
908 | 1132 | ||
909 | private bool CreateInventoryFile() | ||
910 | { | ||
911 | // m_log.DebugFormat( | ||
912 | // "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", | ||
913 | // m_part.Name, m_part.UUID, m_part.LocalId, m_inventorySerial); | ||
914 | 1133 | ||
915 | if (m_inventoryFileName == String.Empty || | 1134 | /// <summary> |
916 | m_inventoryFileNameSerial < m_inventorySerial) | 1135 | /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client |
1136 | /// </summary> | ||
1137 | /// <param name="xferManager"></param> | ||
1138 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) | ||
1139 | { | ||
1140 | lock (m_inventoryFileLock) | ||
917 | { | 1141 | { |
918 | // Something changed, we need to create a new file | 1142 | bool changed = false; |
919 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; | ||
920 | m_inventoryFileNameSerial = m_inventorySerial; | ||
921 | 1143 | ||
922 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | 1144 | m_items.LockItemsForRead(true); |
923 | 1145 | ||
924 | lock (m_items) | 1146 | if (m_inventorySerial == 0) // No inventory |
925 | { | 1147 | { |
926 | foreach (TaskInventoryItem item in m_items.Values) | 1148 | m_items.LockItemsForRead(false); |
927 | { | 1149 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); |
928 | // m_log.DebugFormat( | 1150 | return; |
929 | // "[PRIM INVENTORY]: Adding item {0} {1} for serial {2} on prim {3} {4} {5}", | 1151 | } |
930 | // item.Name, item.ItemID, m_inventorySerial, m_part.Name, m_part.UUID, m_part.LocalId); | ||
931 | 1152 | ||
932 | UUID ownerID = item.OwnerID; | 1153 | if (m_items.Count == 0) // No inventory |
933 | uint everyoneMask = 0; | 1154 | { |
934 | uint baseMask = item.BasePermissions; | 1155 | m_items.LockItemsForRead(false); |
935 | uint ownerMask = item.CurrentPermissions; | 1156 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); |
936 | uint groupMask = item.GroupPermissions; | 1157 | return; |
1158 | } | ||
937 | 1159 | ||
938 | invString.AddItemStart(); | 1160 | if (m_inventoryFileNameSerial != m_inventorySerial) |
939 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | 1161 | { |
940 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | 1162 | m_inventoryFileNameSerial = m_inventorySerial; |
1163 | changed = true; | ||
1164 | } | ||
941 | 1165 | ||
942 | invString.AddPermissionsStart(); | 1166 | m_items.LockItemsForRead(false); |
943 | 1167 | ||
944 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | 1168 | if (m_inventoryFileData.Length < 2) |
945 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | 1169 | changed = true; |
946 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
947 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
948 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
949 | 1170 | ||
950 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | 1171 | bool includeAssets = false; |
951 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | 1172 | if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) |
1173 | includeAssets = true; | ||
952 | 1174 | ||
953 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | 1175 | if (m_inventoryPrivileged != includeAssets) |
1176 | changed = true; | ||
954 | 1177 | ||
955 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | 1178 | if (!changed) |
956 | invString.AddSectionEnd(); | 1179 | { |
1180 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | ||
1181 | client.SendTaskInventory(m_part.UUID, (short)m_inventoryFileNameSerial, | ||
1182 | m_inventoryFileNameBytes); | ||
957 | 1183 | ||
958 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | 1184 | return; |
959 | invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type)); | 1185 | } |
960 | invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType)); | ||
961 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
962 | 1186 | ||
963 | invString.AddSaleStart(); | 1187 | m_inventoryPrivileged = includeAssets; |
964 | invString.AddNameValueLine("sale_type", "not"); | ||
965 | invString.AddNameValueLine("sale_price", "0"); | ||
966 | invString.AddSectionEnd(); | ||
967 | 1188 | ||
968 | invString.AddNameValueLine("name", item.Name + "|"); | 1189 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); |
969 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
970 | 1190 | ||
971 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | 1191 | m_items.LockItemsForRead(true); |
972 | invString.AddSectionEnd(); | ||
973 | } | ||
974 | } | ||
975 | 1192 | ||
976 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | 1193 | foreach (TaskInventoryItem item in m_items.Values) |
1194 | { | ||
1195 | UUID ownerID = item.OwnerID; | ||
1196 | UUID groupID = item.GroupID; | ||
1197 | uint everyoneMask = item.EveryonePermissions; | ||
1198 | uint baseMask = item.BasePermissions; | ||
1199 | uint ownerMask = item.CurrentPermissions; | ||
1200 | uint groupMask = item.GroupPermissions; | ||
977 | 1201 | ||
978 | return true; | 1202 | invString.AddItemStart(); |
979 | } | 1203 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); |
1204 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
980 | 1205 | ||
981 | // No need to recreate, the existing file is fine | 1206 | invString.AddPermissionsStart(); |
982 | return false; | ||
983 | } | ||
984 | 1207 | ||
985 | /// <summary> | 1208 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); |
986 | /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client | 1209 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); |
987 | /// </summary> | 1210 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); |
988 | /// <param name="xferManager"></param> | 1211 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); |
989 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) | 1212 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); |
990 | { | ||
991 | lock (m_items) | ||
992 | { | ||
993 | // Don't send a inventory xfer name if there are no items. Doing so causes viewer 3 to crash when rezzing | ||
994 | // a new script if any previous deletion has left the prim inventory empty. | ||
995 | if (m_items.Count == 0) // No inventory | ||
996 | { | ||
997 | // m_log.DebugFormat( | ||
998 | // "[PRIM INVENTORY]: Not sending inventory data for part {0} {1} {2} for {3} since no items", | ||
999 | // m_part.Name, m_part.LocalId, m_part.UUID, client.Name); | ||
1000 | 1213 | ||
1001 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | 1214 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); |
1002 | return; | 1215 | |
1216 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
1217 | |||
1218 | invString.AddNameValueLine("group_id",groupID.ToString()); | ||
1219 | if(groupID != UUID.Zero && ownerID == groupID) | ||
1220 | { | ||
1221 | invString.AddNameValueLine("owner_id", UUID.Zero.ToString()); | ||
1222 | invString.AddNameValueLine("group_owned","1"); | ||
1223 | } | ||
1224 | else | ||
1225 | { | ||
1226 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
1227 | invString.AddNameValueLine("group_owned","0"); | ||
1228 | } | ||
1229 | |||
1230 | invString.AddSectionEnd(); | ||
1231 | |||
1232 | if (includeAssets) | ||
1233 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
1234 | else | ||
1235 | invString.AddNameValueLine("asset_id", UUID.Zero.ToString()); | ||
1236 | invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type)); | ||
1237 | invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType)); | ||
1238 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
1239 | |||
1240 | invString.AddSaleStart(); | ||
1241 | invString.AddNameValueLine("sale_type", "not"); | ||
1242 | invString.AddNameValueLine("sale_price", "0"); | ||
1243 | invString.AddSectionEnd(); | ||
1244 | |||
1245 | invString.AddNameValueLine("name", item.Name + "|"); | ||
1246 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
1247 | |||
1248 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
1249 | invString.AddSectionEnd(); | ||
1003 | } | 1250 | } |
1004 | 1251 | ||
1005 | CreateInventoryFile(); | 1252 | m_items.LockItemsForRead(false); |
1006 | 1253 | ||
1007 | // In principle, we should only do the rest if the inventory changed; | 1254 | m_inventoryFileData = Utils.StringToBytes(invString.GetString()); |
1008 | // by sending m_inventorySerial to the client, it ought to know | 1255 | |
1009 | // that nothing changed and that it doesn't need to request the file. | ||
1010 | // Unfortunately, it doesn't look like the client optimizes this; | ||
1011 | // the client seems to always come back and request the Xfer, | ||
1012 | // no matter what value m_inventorySerial has. | ||
1013 | // FIXME: Could probably be > 0 here rather than > 2 | ||
1014 | if (m_inventoryFileData.Length > 2) | 1256 | if (m_inventoryFileData.Length > 2) |
1015 | { | 1257 | { |
1016 | // Add the file for Xfer | 1258 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; |
1017 | // m_log.DebugFormat( | 1259 | m_inventoryFileNameBytes = Util.StringToBytes256(m_inventoryFileName); |
1018 | // "[PRIM INVENTORY]: Adding inventory file {0} (length {1}) for transfer on {2} {3} {4}", | ||
1019 | // m_inventoryFileName, m_inventoryFileData.Length, m_part.Name, m_part.UUID, m_part.LocalId); | ||
1020 | |||
1021 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | 1260 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); |
1261 | client.SendTaskInventory(m_part.UUID, (short)m_inventoryFileNameSerial,m_inventoryFileNameBytes); | ||
1262 | return; | ||
1022 | } | 1263 | } |
1023 | 1264 | ||
1024 | // Tell the client we're ready to Xfer the file | 1265 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); |
1025 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | ||
1026 | Util.StringToBytes256(m_inventoryFileName)); | ||
1027 | } | 1266 | } |
1028 | } | 1267 | } |
1029 | 1268 | ||
@@ -1033,67 +1272,80 @@ namespace OpenSim.Region.Framework.Scenes | |||
1033 | /// <param name="datastore"></param> | 1272 | /// <param name="datastore"></param> |
1034 | public void ProcessInventoryBackup(ISimulationDataService datastore) | 1273 | public void ProcessInventoryBackup(ISimulationDataService datastore) |
1035 | { | 1274 | { |
1036 | if (HasInventoryChanged) | 1275 | // Removed this because linking will cause an immediate delete of the new |
1037 | { | 1276 | // child prim from the database and the subsequent storing of the prim sees |
1277 | // the inventory of it as unchanged and doesn't store it at all. The overhead | ||
1278 | // of storing prim inventory needlessly is much less than the aggravation | ||
1279 | // of prim inventory loss. | ||
1280 | // if (HasInventoryChanged) | ||
1281 | // { | ||
1282 | m_items.LockItemsForRead(true); | ||
1283 | ICollection<TaskInventoryItem> itemsvalues = m_items.Values; | ||
1038 | HasInventoryChanged = false; | 1284 | HasInventoryChanged = false; |
1039 | List<TaskInventoryItem> items = GetInventoryItems(); | 1285 | m_items.LockItemsForRead(false); |
1040 | datastore.StorePrimInventory(m_part.UUID, items); | 1286 | try |
1041 | 1287 | { | |
1042 | } | 1288 | datastore.StorePrimInventory(m_part.UUID, itemsvalues); |
1289 | } | ||
1290 | catch {} | ||
1291 | // } | ||
1043 | } | 1292 | } |
1044 | 1293 | ||
1045 | public class InventoryStringBuilder | 1294 | public class InventoryStringBuilder |
1046 | { | 1295 | { |
1047 | public string BuildString = String.Empty; | 1296 | private StringBuilder BuildString = new StringBuilder(1024); |
1048 | 1297 | ||
1049 | public InventoryStringBuilder(UUID folderID, UUID parentID) | 1298 | public InventoryStringBuilder(UUID folderID, UUID parentID) |
1050 | { | 1299 | { |
1051 | BuildString += "\tinv_object\t0\n\t{\n"; | 1300 | BuildString.Append("\tinv_object\t0\n\t{\n"); |
1052 | AddNameValueLine("obj_id", folderID.ToString()); | 1301 | AddNameValueLine("obj_id", folderID.ToString()); |
1053 | AddNameValueLine("parent_id", parentID.ToString()); | 1302 | AddNameValueLine("parent_id", parentID.ToString()); |
1054 | AddNameValueLine("type", "category"); | 1303 | AddNameValueLine("type", "category"); |
1055 | AddNameValueLine("name", "Contents|"); | 1304 | AddNameValueLine("name", "Contents|\n\t}"); |
1056 | AddSectionEnd(); | ||
1057 | } | 1305 | } |
1058 | 1306 | ||
1059 | public void AddItemStart() | 1307 | public void AddItemStart() |
1060 | { | 1308 | { |
1061 | BuildString += "\tinv_item\t0\n"; | 1309 | BuildString.Append("\tinv_item\t0\n\t{\n"); |
1062 | AddSectionStart(); | ||
1063 | } | 1310 | } |
1064 | 1311 | ||
1065 | public void AddPermissionsStart() | 1312 | public void AddPermissionsStart() |
1066 | { | 1313 | { |
1067 | BuildString += "\tpermissions 0\n"; | 1314 | BuildString.Append("\tpermissions 0\n\t{\n"); |
1068 | AddSectionStart(); | ||
1069 | } | 1315 | } |
1070 | 1316 | ||
1071 | public void AddSaleStart() | 1317 | public void AddSaleStart() |
1072 | { | 1318 | { |
1073 | BuildString += "\tsale_info\t0\n"; | 1319 | BuildString.Append("\tsale_info\t0\n\t{\n"); |
1074 | AddSectionStart(); | ||
1075 | } | 1320 | } |
1076 | 1321 | ||
1077 | protected void AddSectionStart() | 1322 | protected void AddSectionStart() |
1078 | { | 1323 | { |
1079 | BuildString += "\t{\n"; | 1324 | BuildString.Append("\t{\n"); |
1080 | } | 1325 | } |
1081 | 1326 | ||
1082 | public void AddSectionEnd() | 1327 | public void AddSectionEnd() |
1083 | { | 1328 | { |
1084 | BuildString += "\t}\n"; | 1329 | BuildString.Append("\t}\n"); |
1085 | } | 1330 | } |
1086 | 1331 | ||
1087 | public void AddLine(string addLine) | 1332 | public void AddLine(string addLine) |
1088 | { | 1333 | { |
1089 | BuildString += addLine; | 1334 | BuildString.Append(addLine); |
1090 | } | 1335 | } |
1091 | 1336 | ||
1092 | public void AddNameValueLine(string name, string value) | 1337 | public void AddNameValueLine(string name, string value) |
1093 | { | 1338 | { |
1094 | BuildString += "\t\t"; | 1339 | BuildString.Append("\t\t"); |
1095 | BuildString += name + "\t"; | 1340 | BuildString.Append(name); |
1096 | BuildString += value + "\n"; | 1341 | BuildString.Append("\t"); |
1342 | BuildString.Append(value); | ||
1343 | BuildString.Append("\n"); | ||
1344 | } | ||
1345 | |||
1346 | public String GetString() | ||
1347 | { | ||
1348 | return BuildString.ToString(); | ||
1097 | } | 1349 | } |
1098 | 1350 | ||
1099 | public void Close() | 1351 | public void Close() |
@@ -1101,71 +1353,74 @@ namespace OpenSim.Region.Framework.Scenes | |||
1101 | } | 1353 | } |
1102 | } | 1354 | } |
1103 | 1355 | ||
1356 | public void AggregateInnerPerms(ref uint owner, ref uint group, ref uint everyone) | ||
1357 | { | ||
1358 | foreach (TaskInventoryItem item in m_items.Values) | ||
1359 | { | ||
1360 | if(item.InvType == (sbyte)InventoryType.Landmark) | ||
1361 | continue; | ||
1362 | owner &= item.CurrentPermissions; | ||
1363 | group &= item.GroupPermissions; | ||
1364 | everyone &= item.EveryonePermissions; | ||
1365 | } | ||
1366 | } | ||
1367 | |||
1104 | public uint MaskEffectivePermissions() | 1368 | public uint MaskEffectivePermissions() |
1105 | { | 1369 | { |
1370 | // used to propagate permissions restrictions outwards | ||
1371 | // Modify does not propagate outwards. | ||
1106 | uint mask=0x7fffffff; | 1372 | uint mask=0x7fffffff; |
1107 | 1373 | ||
1108 | lock (m_items) | 1374 | foreach (TaskInventoryItem item in m_items.Values) |
1109 | { | 1375 | { |
1110 | foreach (TaskInventoryItem item in m_items.Values) | 1376 | if(item.InvType == (sbyte)InventoryType.Landmark) |
1111 | { | 1377 | continue; |
1112 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | 1378 | |
1113 | mask &= ~((uint)PermissionMask.Copy >> 13); | 1379 | // apply current to normal permission bits |
1114 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | 1380 | uint newperms = item.CurrentPermissions; |
1115 | mask &= ~((uint)PermissionMask.Transfer >> 13); | 1381 | |
1116 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | 1382 | if ((newperms & (uint)PermissionMask.Copy) == 0) |
1117 | mask &= ~((uint)PermissionMask.Modify >> 13); | 1383 | mask &= ~(uint)PermissionMask.Copy; |
1118 | 1384 | if ((newperms & (uint)PermissionMask.Transfer) == 0) | |
1119 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | 1385 | mask &= ~(uint)PermissionMask.Transfer; |
1120 | mask &= ~(uint)PermissionMask.Copy; | 1386 | if ((newperms & (uint)PermissionMask.Export) == 0) |
1121 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | 1387 | mask &= ~((uint)PermissionMask.Export); |
1122 | mask &= ~(uint)PermissionMask.Transfer; | 1388 | |
1123 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | 1389 | // apply next owner restricted by current to folded bits |
1124 | mask &= ~(uint)PermissionMask.Modify; | 1390 | newperms &= item.NextPermissions; |
1125 | } | 1391 | |
1392 | if ((newperms & (uint)PermissionMask.Copy) == 0) | ||
1393 | mask &= ~((uint)PermissionMask.FoldedCopy); | ||
1394 | if ((newperms & (uint)PermissionMask.Transfer) == 0) | ||
1395 | mask &= ~((uint)PermissionMask.FoldedTransfer); | ||
1396 | if ((newperms & (uint)PermissionMask.Export) == 0) | ||
1397 | mask &= ~((uint)PermissionMask.FoldedExport); | ||
1398 | |||
1126 | } | 1399 | } |
1127 | |||
1128 | return mask; | 1400 | return mask; |
1129 | } | 1401 | } |
1130 | 1402 | ||
1131 | public void ApplyNextOwnerPermissions() | 1403 | public void ApplyNextOwnerPermissions() |
1132 | { | 1404 | { |
1133 | lock (m_items) | 1405 | foreach (TaskInventoryItem item in m_items.Values) |
1134 | { | 1406 | { |
1135 | foreach (TaskInventoryItem item in m_items.Values) | 1407 | item.CurrentPermissions &= item.NextPermissions; |
1136 | { | 1408 | item.BasePermissions &= item.NextPermissions; |
1137 | // m_log.DebugFormat ( | 1409 | item.EveryonePermissions &= item.NextPermissions; |
1138 | // "[SCENE OBJECT PART INVENTORY]: Applying next permissions {0} to {1} in {2} with current {3}, base {4}, everyone {5}", | 1410 | item.OwnerChanged = true; |
1139 | // item.NextPermissions, item.Name, m_part.Name, item.CurrentPermissions, item.BasePermissions, item.EveryonePermissions); | 1411 | item.PermsMask = 0; |
1140 | 1412 | item.PermsGranter = UUID.Zero; | |
1141 | if (item.InvType == (int)InventoryType.Object) | ||
1142 | { | ||
1143 | uint perms = item.CurrentPermissions; | ||
1144 | PermissionsUtil.ApplyFoldedPermissions(perms, ref perms); | ||
1145 | item.CurrentPermissions = perms; | ||
1146 | } | ||
1147 | |||
1148 | item.CurrentPermissions &= item.NextPermissions; | ||
1149 | item.BasePermissions &= item.NextPermissions; | ||
1150 | item.EveryonePermissions &= item.NextPermissions; | ||
1151 | item.OwnerChanged = true; | ||
1152 | item.PermsMask = 0; | ||
1153 | item.PermsGranter = UUID.Zero; | ||
1154 | } | ||
1155 | } | 1413 | } |
1156 | } | 1414 | } |
1157 | 1415 | ||
1158 | public void ApplyGodPermissions(uint perms) | 1416 | public void ApplyGodPermissions(uint perms) |
1159 | { | 1417 | { |
1160 | lock (m_items) | 1418 | foreach (TaskInventoryItem item in m_items.Values) |
1161 | { | 1419 | { |
1162 | foreach (TaskInventoryItem item in m_items.Values) | 1420 | item.CurrentPermissions = perms; |
1163 | { | 1421 | item.BasePermissions = perms; |
1164 | item.CurrentPermissions = perms; | ||
1165 | item.BasePermissions = perms; | ||
1166 | } | ||
1167 | } | 1422 | } |
1168 | 1423 | ||
1169 | m_inventorySerial++; | 1424 | m_inventorySerial++; |
1170 | HasInventoryChanged = true; | 1425 | HasInventoryChanged = true; |
1171 | } | 1426 | } |
@@ -1176,14 +1431,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1176 | /// <returns></returns> | 1431 | /// <returns></returns> |
1177 | public bool ContainsScripts() | 1432 | public bool ContainsScripts() |
1178 | { | 1433 | { |
1179 | lock (m_items) | 1434 | foreach (TaskInventoryItem item in m_items.Values) |
1180 | { | 1435 | { |
1181 | foreach (TaskInventoryItem item in m_items.Values) | 1436 | if (item.InvType == (int)InventoryType.LSL) |
1182 | { | 1437 | { |
1183 | if (item.InvType == (int)InventoryType.LSL) | 1438 | return true; |
1184 | { | ||
1185 | return true; | ||
1186 | } | ||
1187 | } | 1439 | } |
1188 | } | 1440 | } |
1189 | 1441 | ||
@@ -1197,17 +1449,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1197 | public int ScriptCount() | 1449 | public int ScriptCount() |
1198 | { | 1450 | { |
1199 | int count = 0; | 1451 | int count = 0; |
1200 | lock (m_items) | 1452 | m_items.LockItemsForRead(true); |
1453 | foreach (TaskInventoryItem item in m_items.Values) | ||
1201 | { | 1454 | { |
1202 | foreach (TaskInventoryItem item in m_items.Values) | 1455 | if (item.InvType == (int)InventoryType.LSL) |
1203 | { | 1456 | count++; |
1204 | if (item.InvType == (int)InventoryType.LSL) | ||
1205 | { | ||
1206 | count++; | ||
1207 | } | ||
1208 | } | ||
1209 | } | 1457 | } |
1210 | 1458 | m_items.LockItemsForRead(false); | |
1211 | return count; | 1459 | return count; |
1212 | } | 1460 | } |
1213 | /// <summary> | 1461 | /// <summary> |
@@ -1230,9 +1478,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1230 | if (engine != null) | 1478 | if (engine != null) |
1231 | { | 1479 | { |
1232 | if (engine.GetScriptState(item.ItemID)) | 1480 | if (engine.GetScriptState(item.ItemID)) |
1233 | { | ||
1234 | count++; | 1481 | count++; |
1235 | } | ||
1236 | } | 1482 | } |
1237 | } | 1483 | } |
1238 | } | 1484 | } |
@@ -1241,50 +1487,52 @@ namespace OpenSim.Region.Framework.Scenes | |||
1241 | 1487 | ||
1242 | public List<UUID> GetInventoryList() | 1488 | public List<UUID> GetInventoryList() |
1243 | { | 1489 | { |
1244 | List<UUID> ret = new List<UUID>(); | 1490 | m_items.LockItemsForRead(true); |
1245 | 1491 | ||
1246 | lock (m_items) | 1492 | List<UUID> ret = new List<UUID>(m_items.Count); |
1247 | { | 1493 | foreach (TaskInventoryItem item in m_items.Values) |
1248 | foreach (TaskInventoryItem item in m_items.Values) | 1494 | ret.Add(item.ItemID); |
1249 | ret.Add(item.ItemID); | ||
1250 | } | ||
1251 | 1495 | ||
1496 | m_items.LockItemsForRead(false); | ||
1252 | return ret; | 1497 | return ret; |
1253 | } | 1498 | } |
1254 | 1499 | ||
1255 | public List<TaskInventoryItem> GetInventoryItems() | 1500 | public List<TaskInventoryItem> GetInventoryItems() |
1256 | { | 1501 | { |
1257 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1502 | m_items.LockItemsForRead(true); |
1258 | 1503 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(m_items.Values); | |
1259 | lock (m_items) | 1504 | m_items.LockItemsForRead(false); |
1260 | ret = new List<TaskInventoryItem>(m_items.Values); | ||
1261 | 1505 | ||
1262 | return ret; | 1506 | return ret; |
1263 | } | 1507 | } |
1264 | 1508 | ||
1265 | public List<TaskInventoryItem> GetInventoryItems(InventoryType type) | 1509 | public List<TaskInventoryItem> GetInventoryItems(InventoryType type) |
1266 | { | 1510 | { |
1267 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1511 | m_items.LockItemsForRead(true); |
1268 | 1512 | ||
1269 | lock (m_items) | 1513 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(m_items.Count); |
1270 | { | 1514 | foreach (TaskInventoryItem item in m_items.Values) |
1271 | foreach (TaskInventoryItem item in m_items.Values) | 1515 | if (item.InvType == (int)type) |
1272 | if (item.InvType == (int)type) | 1516 | ret.Add(item); |
1273 | ret.Add(item); | ||
1274 | } | ||
1275 | 1517 | ||
1518 | m_items.LockItemsForRead(false); | ||
1276 | return ret; | 1519 | return ret; |
1277 | } | 1520 | } |
1278 | 1521 | ||
1279 | public Dictionary<UUID, string> GetScriptStates() | 1522 | public Dictionary<UUID, string> GetScriptStates() |
1280 | { | 1523 | { |
1281 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); | 1524 | return GetScriptStates(false); |
1282 | 1525 | } | |
1526 | |||
1527 | public Dictionary<UUID, string> GetScriptStates(bool oldIDs) | ||
1528 | { | ||
1529 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); | ||
1530 | |||
1283 | if (m_part.ParentGroup.Scene == null) // Group not in a scene | 1531 | if (m_part.ParentGroup.Scene == null) // Group not in a scene |
1284 | return ret; | 1532 | return ret; |
1285 | 1533 | ||
1286 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); | 1534 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); |
1287 | 1535 | ||
1288 | if (engines.Length == 0) // No engine at all | 1536 | if (engines.Length == 0) // No engine at all |
1289 | return ret; | 1537 | return ret; |
1290 | 1538 | ||
@@ -1303,17 +1551,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
1303 | string n = e.GetXMLState(item.ItemID); | 1551 | string n = e.GetXMLState(item.ItemID); |
1304 | if (n != String.Empty) | 1552 | if (n != String.Empty) |
1305 | { | 1553 | { |
1306 | if (!ret.ContainsKey(item.ItemID)) | 1554 | if (oldIDs) |
1307 | ret[item.ItemID] = n; | 1555 | { |
1556 | if (!ret.ContainsKey(item.OldItemID)) | ||
1557 | ret[item.OldItemID] = n; | ||
1558 | } | ||
1559 | else | ||
1560 | { | ||
1561 | if (!ret.ContainsKey(item.ItemID)) | ||
1562 | ret[item.ItemID] = n; | ||
1563 | } | ||
1308 | break; | 1564 | break; |
1309 | } | 1565 | } |
1310 | } | 1566 | } |
1311 | } | 1567 | } |
1312 | } | 1568 | } |
1313 | |||
1314 | return ret; | 1569 | return ret; |
1315 | } | 1570 | } |
1316 | 1571 | ||
1317 | public void ResumeScripts() | 1572 | public void ResumeScripts() |
1318 | { | 1573 | { |
1319 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); | 1574 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); |