aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs711
1 files changed, 447 insertions, 264 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 39ebaef..3cfca4b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -48,6 +48,8 @@ namespace OpenSim.Region.Framework.Scenes
48 private string m_inventoryFileName = String.Empty; 48 private string m_inventoryFileName = String.Empty;
49 private byte[] m_inventoryFileData = new byte[0]; 49 private byte[] m_inventoryFileData = new byte[0];
50 private uint m_inventoryFileNameSerial = 0; 50 private uint m_inventoryFileNameSerial = 0;
51
52 private Dictionary<UUID, ArrayList> m_scriptErrors = new Dictionary<UUID, ArrayList>();
51 53
52 /// <value> 54 /// <value>
53 /// The part to which the inventory belongs. 55 /// The part to which the inventory belongs.
@@ -84,7 +86,9 @@ namespace OpenSim.Region.Framework.Scenes
84 /// </value> 86 /// </value>
85 protected internal TaskInventoryDictionary Items 87 protected internal TaskInventoryDictionary Items
86 { 88 {
87 get { return m_items; } 89 get {
90 return m_items;
91 }
88 set 92 set
89 { 93 {
90 m_items = value; 94 m_items = value;
@@ -120,39 +124,45 @@ namespace OpenSim.Region.Framework.Scenes
120 /// <param name="linkNum">Link number for the part</param> 124 /// <param name="linkNum">Link number for the part</param>
121 public void ResetInventoryIDs() 125 public void ResetInventoryIDs()
122 { 126 {
123 if (null == m_part || null == m_part.ParentGroup) 127 m_items.LockItemsForWrite(true);
124 return; 128
125 129 if (Items.Count == 0)
126 lock (m_items)
127 { 130 {
128 if (0 == m_items.Count) 131 m_items.LockItemsForWrite(false);
129 return; 132 return;
133 }
130 134
131 IList<TaskInventoryItem> items = GetInventoryItems(); 135 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
132 m_items.Clear(); 136 Items.Clear();
133 137
134 foreach (TaskInventoryItem item in items) 138 foreach (TaskInventoryItem item in items)
135 { 139 {
136 item.ResetIDs(m_part.UUID); 140 item.ResetIDs(m_part.UUID);
137 m_items.Add(item.ItemID, item); 141 Items.Add(item.ItemID, item);
138 }
139 } 142 }
143 m_items.LockItemsForWrite(false);
140 } 144 }
141 145
142 public void ResetObjectID() 146 public void ResetObjectID()
143 { 147 {
144 lock (Items) 148 m_items.LockItemsForWrite(true);
149
150 if (Items.Count == 0)
145 { 151 {
146 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 152 m_items.LockItemsForWrite(false);
147 Items.Clear(); 153 return;
148
149 foreach (TaskInventoryItem item in items)
150 {
151 item.ParentPartID = m_part.UUID;
152 item.ParentID = m_part.UUID;
153 Items.Add(item.ItemID, item);
154 }
155 } 154 }
155
156 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
157 Items.Clear();
158
159 foreach (TaskInventoryItem item in items)
160 {
161 item.ParentPartID = m_part.UUID;
162 item.ParentID = m_part.UUID;
163 Items.Add(item.ItemID, item);
164 }
165 m_items.LockItemsForWrite(false);
156 } 166 }
157 167
158 /// <summary> 168 /// <summary>
@@ -161,12 +171,11 @@ namespace OpenSim.Region.Framework.Scenes
161 /// <param name="ownerId"></param> 171 /// <param name="ownerId"></param>
162 public void ChangeInventoryOwner(UUID ownerId) 172 public void ChangeInventoryOwner(UUID ownerId)
163 { 173 {
164 lock (Items) 174 m_items.LockItemsForWrite(true);
175 if (0 == Items.Count)
165 { 176 {
166 if (0 == Items.Count) 177 m_items.LockItemsForWrite(false);
167 { 178 return;
168 return;
169 }
170 } 179 }
171 180
172 HasInventoryChanged = true; 181 HasInventoryChanged = true;
@@ -180,6 +189,7 @@ namespace OpenSim.Region.Framework.Scenes
180 item.OwnerID = ownerId; 189 item.OwnerID = ownerId;
181 } 190 }
182 } 191 }
192 m_items.LockItemsForWrite(false);
183 } 193 }
184 194
185 /// <summary> 195 /// <summary>
@@ -188,12 +198,11 @@ namespace OpenSim.Region.Framework.Scenes
188 /// <param name="groupID"></param> 198 /// <param name="groupID"></param>
189 public void ChangeInventoryGroup(UUID groupID) 199 public void ChangeInventoryGroup(UUID groupID)
190 { 200 {
191 lock (Items) 201 m_items.LockItemsForWrite(true);
202 if (0 == Items.Count)
192 { 203 {
193 if (0 == Items.Count) 204 m_items.LockItemsForWrite(false);
194 { 205 return;
195 return;
196 }
197 } 206 }
198 207
199 // Don't let this set the HasGroupChanged flag for attachments 208 // Don't let this set the HasGroupChanged flag for attachments
@@ -205,12 +214,15 @@ namespace OpenSim.Region.Framework.Scenes
205 m_part.ParentGroup.HasGroupChanged = true; 214 m_part.ParentGroup.HasGroupChanged = true;
206 } 215 }
207 216
208 List<TaskInventoryItem> items = GetInventoryItems(); 217 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
209 foreach (TaskInventoryItem item in items) 218 foreach (TaskInventoryItem item in items)
210 { 219 {
211 if (groupID != item.GroupID) 220 if (groupID != item.GroupID)
221 {
212 item.GroupID = groupID; 222 item.GroupID = groupID;
223 }
213 } 224 }
225 m_items.LockItemsForWrite(false);
214 } 226 }
215 227
216 /// <summary> 228 /// <summary>
@@ -218,9 +230,14 @@ namespace OpenSim.Region.Framework.Scenes
218 /// </summary> 230 /// </summary>
219 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 231 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
220 { 232 {
221 List<TaskInventoryItem> scripts = GetInventoryScripts(); 233 Items.LockItemsForRead(true);
222 foreach (TaskInventoryItem item in scripts) 234 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
223 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 235 Items.LockItemsForRead(false);
236 foreach (TaskInventoryItem item in items)
237 {
238 if ((int)InventoryType.LSL == item.InvType)
239 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
240 }
224 } 241 }
225 242
226 public ArrayList GetScriptErrors(UUID itemID) 243 public ArrayList GetScriptErrors(UUID itemID)
@@ -253,9 +270,18 @@ namespace OpenSim.Region.Framework.Scenes
253 /// </param> 270 /// </param>
254 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 271 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
255 { 272 {
256 List<TaskInventoryItem> scripts = GetInventoryScripts(); 273 Items.LockItemsForRead(true);
257 foreach (TaskInventoryItem item in scripts) 274 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
258 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); 275 Items.LockItemsForRead(false);
276
277 foreach (TaskInventoryItem item in items)
278 {
279 if ((int)InventoryType.LSL == item.InvType)
280 {
281 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
282 m_part.RemoveScriptEvents(item.ItemID);
283 }
284 }
259 } 285 }
260 286
261 /// <summary> 287 /// <summary>
@@ -271,7 +297,10 @@ namespace OpenSim.Region.Framework.Scenes
271 // item.Name, item.ItemID, Name, UUID); 297 // item.Name, item.ItemID, Name, UUID);
272 298
273 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) 299 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID))
300 {
301 StoreScriptError(item.ItemID, "no permission");
274 return; 302 return;
303 }
275 304
276 m_part.AddFlag(PrimFlags.Scripted); 305 m_part.AddFlag(PrimFlags.Scripted);
277 306
@@ -280,14 +309,13 @@ namespace OpenSim.Region.Framework.Scenes
280 if (stateSource == 2 && // Prim crossing 309 if (stateSource == 2 && // Prim crossing
281 m_part.ParentGroup.Scene.m_trustBinaries) 310 m_part.ParentGroup.Scene.m_trustBinaries)
282 { 311 {
283 lock (m_items) 312 m_items.LockItemsForWrite(true);
284 { 313 m_items[item.ItemID].PermsMask = 0;
285 m_items[item.ItemID].PermsMask = 0; 314 m_items[item.ItemID].PermsGranter = UUID.Zero;
286 m_items[item.ItemID].PermsGranter = UUID.Zero; 315 m_items.LockItemsForWrite(false);
287 }
288
289 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 316 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
290 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 317 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
318 StoreScriptErrors(item.ItemID, null);
291 m_part.ParentGroup.AddActiveScriptCount(1); 319 m_part.ParentGroup.AddActiveScriptCount(1);
292 m_part.ScheduleFullUpdate(); 320 m_part.ScheduleFullUpdate();
293 return; 321 return;
@@ -296,6 +324,8 @@ namespace OpenSim.Region.Framework.Scenes
296 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); 324 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
297 if (null == asset) 325 if (null == asset)
298 { 326 {
327 string msg = String.Format("asset ID {0} could not be found", item.AssetID);
328 StoreScriptError(item.ItemID, msg);
299 m_log.ErrorFormat( 329 m_log.ErrorFormat(
300 "[PRIM INVENTORY]: " + 330 "[PRIM INVENTORY]: " +
301 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", 331 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
@@ -307,15 +337,17 @@ namespace OpenSim.Region.Framework.Scenes
307 if (m_part.ParentGroup.m_savedScriptState != null) 337 if (m_part.ParentGroup.m_savedScriptState != null)
308 RestoreSavedScriptState(item.OldItemID, item.ItemID); 338 RestoreSavedScriptState(item.OldItemID, item.ItemID);
309 339
310 lock (m_items) 340 m_items.LockItemsForWrite(true);
311 { 341
312 m_items[item.ItemID].PermsMask = 0; 342 m_items[item.ItemID].PermsMask = 0;
313 m_items[item.ItemID].PermsGranter = UUID.Zero; 343 m_items[item.ItemID].PermsGranter = UUID.Zero;
314 } 344
345 m_items.LockItemsForWrite(false);
315 346
316 string script = Utils.BytesToString(asset.Data); 347 string script = Utils.BytesToString(asset.Data);
317 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 348 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
318 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 349 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
350 StoreScriptErrors(item.ItemID, null);
319 m_part.ParentGroup.AddActiveScriptCount(1); 351 m_part.ParentGroup.AddActiveScriptCount(1);
320 m_part.ScheduleFullUpdate(); 352 m_part.ScheduleFullUpdate();
321 } 353 }
@@ -379,21 +411,145 @@ namespace OpenSim.Region.Framework.Scenes
379 411
380 /// <summary> 412 /// <summary>
381 /// Start a script which is in this prim's inventory. 413 /// Start a script which is in this prim's inventory.
414 /// Some processing may occur in the background, but this routine returns asap.
382 /// </summary> 415 /// </summary>
383 /// <param name="itemId"> 416 /// <param name="itemId">
384 /// A <see cref="UUID"/> 417 /// A <see cref="UUID"/>
385 /// </param> 418 /// </param>
386 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 419 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
387 { 420 {
388 TaskInventoryItem item = GetInventoryItem(itemId); 421 lock (m_scriptErrors)
389 if (item != null) 422 {
390 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 423 // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion
424 m_scriptErrors.Remove(itemId);
425 }
426 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
427 }
428
429 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
430 {
431 m_items.LockItemsForRead(true);
432 if (m_items.ContainsKey(itemId))
433 {
434 if (m_items.ContainsKey(itemId))
435 {
436 m_items.LockItemsForRead(false);
437 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
438 }
439 else
440 {
441 m_items.LockItemsForRead(false);
442 string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID,
443 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
444 StoreScriptError(itemId, msg);
445 m_log.ErrorFormat(
446 "[PRIM INVENTORY]: " +
447 "Couldn't start script with ID {0} since it {1}", itemId, msg);
448 }
449 }
391 else 450 else
451 {
452 m_items.LockItemsForRead(false);
453 string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID);
454 StoreScriptError(itemId, msg);
392 m_log.ErrorFormat( 455 m_log.ErrorFormat(
393 "[PRIM INVENTORY]: " + 456 "[PRIM INVENTORY]: " +
394 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 457 "Couldn't start script with ID {0} since it {1}", itemId, msg);
395 itemId, m_part.Name, m_part.UUID, 458 }
396 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 459
460 }
461
462 /// <summary>
463 /// Start a script which is in this prim's inventory and return any compilation error messages.
464 /// </summary>
465 /// <param name="itemId">
466 /// A <see cref="UUID"/>
467 /// </param>
468 public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
469 {
470 ArrayList errors;
471
472 // Indicate to CreateScriptInstanceInternal() we want it to
473 // post any compilation/loading error messages
474 lock (m_scriptErrors)
475 {
476 m_scriptErrors[itemId] = null;
477 }
478
479 // Perform compilation/loading
480 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
481
482 // Wait for and retrieve any errors
483 lock (m_scriptErrors)
484 {
485 while ((errors = m_scriptErrors[itemId]) == null)
486 {
487 if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
488 {
489 m_log.ErrorFormat(
490 "[PRIM INVENTORY]: " +
491 "timedout waiting for script {0} errors", itemId);
492 errors = m_scriptErrors[itemId];
493 if (errors == null)
494 {
495 errors = new ArrayList(1);
496 errors.Add("timedout waiting for errors");
497 }
498 break;
499 }
500 }
501 m_scriptErrors.Remove(itemId);
502 }
503 return errors;
504 }
505
506 // Signal to CreateScriptInstanceEr() that compilation/loading is complete
507 private void StoreScriptErrors(UUID itemId, ArrayList errors)
508 {
509 lock (m_scriptErrors)
510 {
511 // If compilation/loading initiated via CreateScriptInstance(),
512 // it does not want the errors, so just get out
513 if (!m_scriptErrors.ContainsKey(itemId))
514 {
515 return;
516 }
517
518 // Initiated via CreateScriptInstanceEr(), if we know what the
519 // errors are, save them and wake CreateScriptInstanceEr().
520 if (errors != null)
521 {
522 m_scriptErrors[itemId] = errors;
523 System.Threading.Monitor.PulseAll(m_scriptErrors);
524 return;
525 }
526 }
527
528 // Initiated via CreateScriptInstanceEr() but we don't know what
529 // the errors are yet, so retrieve them from the script engine.
530 // This may involve some waiting internal to GetScriptErrors().
531 errors = GetScriptErrors(itemId);
532
533 // Get a default non-null value to indicate success.
534 if (errors == null)
535 {
536 errors = new ArrayList();
537 }
538
539 // Post to CreateScriptInstanceEr() and wake it up
540 lock (m_scriptErrors)
541 {
542 m_scriptErrors[itemId] = errors;
543 System.Threading.Monitor.PulseAll(m_scriptErrors);
544 }
545 }
546
547 // Like StoreScriptErrors(), but just posts a single string message
548 private void StoreScriptError(UUID itemId, string message)
549 {
550 ArrayList errors = new ArrayList(1);
551 errors.Add(message);
552 StoreScriptErrors(itemId, errors);
397 } 553 }
398 554
399 /// <summary> 555 /// <summary>
@@ -406,15 +562,7 @@ namespace OpenSim.Region.Framework.Scenes
406 /// </param> 562 /// </param>
407 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 563 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
408 { 564 {
409 bool scriptPresent = false; 565 if (m_items.ContainsKey(itemId))
410
411 lock (m_items)
412 {
413 if (m_items.ContainsKey(itemId))
414 scriptPresent = true;
415 }
416
417 if (scriptPresent)
418 { 566 {
419 if (!sceneObjectBeingDeleted) 567 if (!sceneObjectBeingDeleted)
420 m_part.RemoveScriptEvents(itemId); 568 m_part.RemoveScriptEvents(itemId);
@@ -439,14 +587,16 @@ namespace OpenSim.Region.Framework.Scenes
439 /// <returns></returns> 587 /// <returns></returns>
440 private bool InventoryContainsName(string name) 588 private bool InventoryContainsName(string name)
441 { 589 {
442 lock (m_items) 590 m_items.LockItemsForRead(true);
591 foreach (TaskInventoryItem item in m_items.Values)
443 { 592 {
444 foreach (TaskInventoryItem item in m_items.Values) 593 if (item.Name == name)
445 { 594 {
446 if (item.Name == name) 595 m_items.LockItemsForRead(false);
447 return true; 596 return true;
448 } 597 }
449 } 598 }
599 m_items.LockItemsForRead(false);
450 return false; 600 return false;
451 } 601 }
452 602
@@ -488,8 +638,9 @@ namespace OpenSim.Region.Framework.Scenes
488 /// <param name="item"></param> 638 /// <param name="item"></param>
489 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 639 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
490 { 640 {
491 List<TaskInventoryItem> il = GetInventoryItems(); 641 m_items.LockItemsForRead(true);
492 642 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
643 m_items.LockItemsForRead(false);
493 foreach (TaskInventoryItem i in il) 644 foreach (TaskInventoryItem i in il)
494 { 645 {
495 if (i.Name == item.Name) 646 if (i.Name == item.Name)
@@ -527,14 +678,14 @@ namespace OpenSim.Region.Framework.Scenes
527 item.Name = name; 678 item.Name = name;
528 item.GroupID = m_part.GroupID; 679 item.GroupID = m_part.GroupID;
529 680
530 lock (m_items) 681 m_items.LockItemsForWrite(true);
531 m_items.Add(item.ItemID, item); 682 m_items.Add(item.ItemID, item);
532 683 m_items.LockItemsForWrite(false);
533 if (allowedDrop) 684 if (allowedDrop)
534 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 685 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
535 else 686 else
536 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 687 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
537 688
538 m_inventorySerial++; 689 m_inventorySerial++;
539 //m_inventorySerial += 2; 690 //m_inventorySerial += 2;
540 HasInventoryChanged = true; 691 HasInventoryChanged = true;
@@ -550,15 +701,15 @@ namespace OpenSim.Region.Framework.Scenes
550 /// <param name="items"></param> 701 /// <param name="items"></param>
551 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 702 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
552 { 703 {
553 lock (m_items) 704 m_items.LockItemsForWrite(true);
705 foreach (TaskInventoryItem item in items)
554 { 706 {
555 foreach (TaskInventoryItem item in items) 707 m_items.Add(item.ItemID, item);
556 { 708// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
557 m_items.Add(item.ItemID, item);
558// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
559 }
560 m_inventorySerial++;
561 } 709 }
710 m_items.LockItemsForWrite(false);
711
712 m_inventorySerial++;
562 } 713 }
563 714
564 /// <summary> 715 /// <summary>
@@ -569,10 +720,9 @@ namespace OpenSim.Region.Framework.Scenes
569 public TaskInventoryItem GetInventoryItem(UUID itemId) 720 public TaskInventoryItem GetInventoryItem(UUID itemId)
570 { 721 {
571 TaskInventoryItem item; 722 TaskInventoryItem item;
572 723 m_items.LockItemsForRead(true);
573 lock (m_items) 724 m_items.TryGetValue(itemId, out item);
574 m_items.TryGetValue(itemId, out item); 725 m_items.LockItemsForRead(false);
575
576 return item; 726 return item;
577 } 727 }
578 728
@@ -588,15 +738,16 @@ namespace OpenSim.Region.Framework.Scenes
588 { 738 {
589 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); 739 IList<TaskInventoryItem> items = new List<TaskInventoryItem>();
590 740
591 lock (m_items) 741 m_items.LockItemsForRead(true);
742
743 foreach (TaskInventoryItem item in m_items.Values)
592 { 744 {
593 foreach (TaskInventoryItem item in m_items.Values) 745 if (item.Name == name)
594 { 746 items.Add(item);
595 if (item.Name == name)
596 items.Add(item);
597 }
598 } 747 }
599 748
749 m_items.LockItemsForRead(false);
750
600 return items; 751 return items;
601 } 752 }
602 753
@@ -679,9 +830,9 @@ namespace OpenSim.Region.Framework.Scenes
679 830
680 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) 831 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged)
681 { 832 {
682 TaskInventoryItem it = GetInventoryItem(item.ItemID); 833 m_items.LockItemsForWrite(true);
683 if (it != null)
684 834
835 if (m_items.ContainsKey(item.ItemID))
685 { 836 {
686 item.ParentID = m_part.UUID; 837 item.ParentID = m_part.UUID;
687 item.ParentPartID = m_part.UUID; 838 item.ParentPartID = m_part.UUID;
@@ -693,14 +844,10 @@ namespace OpenSim.Region.Framework.Scenes
693 item.GroupID = m_part.GroupID; 844 item.GroupID = m_part.GroupID;
694 845
695 if (item.AssetID == UUID.Zero) 846 if (item.AssetID == UUID.Zero)
696 item.AssetID = it.AssetID; 847 item.AssetID = m_items[item.ItemID].AssetID;
697
698 lock (m_items)
699 {
700 m_items[item.ItemID] = item;
701 m_inventorySerial++;
702 }
703 848
849 m_items[item.ItemID] = item;
850 m_inventorySerial++;
704 if (fireScriptEvents) 851 if (fireScriptEvents)
705 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 852 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
706 if (considerChanged) 853 if (considerChanged)
@@ -708,6 +855,7 @@ namespace OpenSim.Region.Framework.Scenes
708 HasInventoryChanged = true; 855 HasInventoryChanged = true;
709 m_part.ParentGroup.HasGroupChanged = true; 856 m_part.ParentGroup.HasGroupChanged = true;
710 } 857 }
858 m_items.LockItemsForWrite(false);
711 return true; 859 return true;
712 } 860 }
713 else 861 else
@@ -718,8 +866,9 @@ namespace OpenSim.Region.Framework.Scenes
718 item.ItemID, m_part.Name, m_part.UUID, 866 item.ItemID, m_part.Name, m_part.UUID,
719 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 867 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
720 } 868 }
721 return false; 869 m_items.LockItemsForWrite(false);
722 870
871 return false;
723 } 872 }
724 873
725 /// <summary> 874 /// <summary>
@@ -730,107 +879,68 @@ namespace OpenSim.Region.Framework.Scenes
730 /// in this prim's inventory.</returns> 879 /// in this prim's inventory.</returns>
731 public int RemoveInventoryItem(UUID itemID) 880 public int RemoveInventoryItem(UUID itemID)
732 { 881 {
733 TaskInventoryItem item = GetInventoryItem(itemID); 882 m_items.LockItemsForRead(true);
734 if (item != null) 883
884 if (m_items.ContainsKey(itemID))
735 { 885 {
736 int type = m_items[itemID].InvType; 886 int type = m_items[itemID].InvType;
887 m_items.LockItemsForRead(false);
737 if (type == 10) // Script 888 if (type == 10) // Script
738 { 889 {
739 m_part.RemoveScriptEvents(itemID);
740 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 890 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
741 } 891 }
892 m_items.LockItemsForWrite(true);
742 m_items.Remove(itemID); 893 m_items.Remove(itemID);
894 m_items.LockItemsForWrite(false);
743 m_inventorySerial++; 895 m_inventorySerial++;
744 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 896 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
745 897
746 HasInventoryChanged = true; 898 HasInventoryChanged = true;
747 m_part.ParentGroup.HasGroupChanged = true; 899 m_part.ParentGroup.HasGroupChanged = true;
748 900
749 if (!ContainsScripts()) 901 int scriptcount = 0;
902 m_items.LockItemsForRead(true);
903 foreach (TaskInventoryItem item in m_items.Values)
904 {
905 if (item.Type == 10)
906 {
907 scriptcount++;
908 }
909 }
910 m_items.LockItemsForRead(false);
911
912
913 if (scriptcount <= 0)
914 {
750 m_part.RemFlag(PrimFlags.Scripted); 915 m_part.RemFlag(PrimFlags.Scripted);
916 }
751 917
752 m_part.ScheduleFullUpdate(); 918 m_part.ScheduleFullUpdate();
753 919
754 return type; 920 return type;
755
756 } 921 }
757 else 922 else
758 { 923 {
924 m_items.LockItemsForRead(false);
759 m_log.ErrorFormat( 925 m_log.ErrorFormat(
760 "[PRIM INVENTORY]: " + 926 "[PRIM INVENTORY]: " +
761 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 927 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
762 itemID, m_part.Name, m_part.UUID, 928 itemID, m_part.Name, m_part.UUID);
763 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
764 } 929 }
765 930
766 return -1; 931 return -1;
767 } 932 }
768 933
769 private bool CreateInventoryFile() 934 private bool CreateInventoryFileName()
770 { 935 {
771 if (m_inventoryFileName == String.Empty || 936 if (m_inventoryFileName == String.Empty ||
772 m_inventoryFileNameSerial < m_inventorySerial) 937 m_inventoryFileNameSerial < m_inventorySerial)
773 { 938 {
774 // Something changed, we need to create a new file
775 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; 939 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
776 m_inventoryFileNameSerial = m_inventorySerial; 940 m_inventoryFileNameSerial = m_inventorySerial;
777
778 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
779
780 lock (m_items)
781 {
782 foreach (TaskInventoryItem item in m_items.Values)
783 {
784 UUID ownerID = item.OwnerID;
785 uint everyoneMask = 0;
786 uint baseMask = item.BasePermissions;
787 uint ownerMask = item.CurrentPermissions;
788 uint groupMask = item.GroupPermissions;
789
790 invString.AddItemStart();
791 invString.AddNameValueLine("item_id", item.ItemID.ToString());
792 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
793
794 invString.AddPermissionsStart();
795
796 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
797 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
798 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
799 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
800 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
801
802 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
803 invString.AddNameValueLine("owner_id", ownerID.ToString());
804
805 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
806
807 invString.AddNameValueLine("group_id", item.GroupID.ToString());
808 invString.AddSectionEnd();
809
810 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
811 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
812 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
813 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
814
815 invString.AddSaleStart();
816 invString.AddNameValueLine("sale_type", "not");
817 invString.AddNameValueLine("sale_price", "0");
818 invString.AddSectionEnd();
819
820 invString.AddNameValueLine("name", item.Name + "|");
821 invString.AddNameValueLine("desc", item.Description + "|");
822
823 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
824 invString.AddSectionEnd();
825 }
826 }
827
828 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
829
830 return true; 941 return true;
831 } 942 }
832 943
833 // No need to recreate, the existing file is fine
834 return false; 944 return false;
835 } 945 }
836 946
@@ -840,26 +950,94 @@ namespace OpenSim.Region.Framework.Scenes
840 /// <param name="xferManager"></param> 950 /// <param name="xferManager"></param>
841 public void RequestInventoryFile(IClientAPI client, IXfer xferManager) 951 public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
842 { 952 {
843 bool changed = CreateInventoryFile(); 953 bool changed = CreateInventoryFileName();
954
955 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
956
957 Items.LockItemsForRead(true);
844 958
845 if (m_inventorySerial == 0) // No inventory 959 if (m_inventorySerial == 0) // No inventory
846 { 960 {
847 client.SendTaskInventory(m_part.UUID, 0, new byte[0]); 961 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
962 Items.LockItemsForRead(false);
848 return; 963 return;
849 } 964 }
850 965
851 // In principle, we should only do the rest if the inventory changed; 966 if (!changed)
852 // by sending m_inventorySerial to the client, it ought to know 967 {
853 // that nothing changed and that it doesn't need to request the file. 968 if (m_inventoryFileData.Length > 2)
854 // Unfortunately, it doesn't look like the client optimizes this; 969 {
855 // the client seems to always come back and request the Xfer, 970 xferManager.AddNewFile(m_inventoryFileName,
856 // no matter what value m_inventorySerial has. 971 m_inventoryFileData);
972 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
973 Util.StringToBytes256(m_inventoryFileName));
974
975 Items.LockItemsForRead(false);
976 return;
977 }
978 }
979
980 bool includeAssets = false;
981 if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId))
982 includeAssets = true;
983
984 foreach (TaskInventoryItem item in m_items.Values)
985 {
986 UUID ownerID = item.OwnerID;
987 uint everyoneMask = 0;
988 uint baseMask = item.BasePermissions;
989 uint ownerMask = item.CurrentPermissions;
990 uint groupMask = item.GroupPermissions;
991
992 invString.AddItemStart();
993 invString.AddNameValueLine("item_id", item.ItemID.ToString());
994 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
995
996 invString.AddPermissionsStart();
997
998 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
999 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
1000 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
1001 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
1002 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
1003
1004 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
1005 invString.AddNameValueLine("owner_id", ownerID.ToString());
1006
1007 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
1008
1009 invString.AddNameValueLine("group_id", item.GroupID.ToString());
1010 invString.AddSectionEnd();
1011
1012 if (includeAssets)
1013 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
1014 else
1015 invString.AddNameValueLine("asset_id", UUID.Zero.ToString());
1016 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
1017 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
1018 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
1019
1020 invString.AddSaleStart();
1021 invString.AddNameValueLine("sale_type", "not");
1022 invString.AddNameValueLine("sale_price", "0");
1023 invString.AddSectionEnd();
1024
1025 invString.AddNameValueLine("name", item.Name + "|");
1026 invString.AddNameValueLine("desc", item.Description + "|");
1027
1028 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
1029 invString.AddSectionEnd();
1030 }
1031
1032 Items.LockItemsForRead(false);
1033
1034 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
857 1035
858 if (m_inventoryFileData.Length > 2) 1036 if (m_inventoryFileData.Length > 2)
859 // Add the file for Xfer 1037 {
860 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); 1038 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
1039 }
861 1040
862 // Tell the client we're ready to Xfer the file
863 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, 1041 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
864 Util.StringToBytes256(m_inventoryFileName)); 1042 Util.StringToBytes256(m_inventoryFileName));
865 } 1043 }
@@ -872,10 +1050,11 @@ namespace OpenSim.Region.Framework.Scenes
872 { 1050 {
873 if (HasInventoryChanged) 1051 if (HasInventoryChanged)
874 { 1052 {
875 HasInventoryChanged = false; 1053 Items.LockItemsForRead(true);
876 List<TaskInventoryItem> items = GetInventoryItems(); 1054 datastore.StorePrimInventory(m_part.UUID, Items.Values);
877 datastore.StorePrimInventory(m_part.UUID, items); 1055 Items.LockItemsForRead(false);
878 1056
1057 HasInventoryChanged = false;
879 } 1058 }
880 } 1059 }
881 1060
@@ -942,89 +1121,75 @@ namespace OpenSim.Region.Framework.Scenes
942 { 1121 {
943 uint mask=0x7fffffff; 1122 uint mask=0x7fffffff;
944 1123
945 lock (m_items) 1124 foreach (TaskInventoryItem item in m_items.Values)
946 { 1125 {
947 foreach (TaskInventoryItem item in m_items.Values) 1126 if (item.InvType != (int)InventoryType.Object)
948 { 1127 {
949 if (item.InvType != (int)InventoryType.Object) 1128 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
950 { 1129 mask &= ~((uint)PermissionMask.Copy >> 13);
951 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1130 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
952 mask &= ~((uint)PermissionMask.Copy >> 13); 1131 mask &= ~((uint)PermissionMask.Transfer >> 13);
953 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1132 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
954 mask &= ~((uint)PermissionMask.Transfer >> 13); 1133 mask &= ~((uint)PermissionMask.Modify >> 13);
955 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 1134 }
956 mask &= ~((uint)PermissionMask.Modify >> 13); 1135 else
957 } 1136 {
958 else 1137 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
959 { 1138 mask &= ~((uint)PermissionMask.Copy >> 13);
960 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1139 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
961 mask &= ~((uint)PermissionMask.Copy >> 13); 1140 mask &= ~((uint)PermissionMask.Transfer >> 13);
962 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1141 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
963 mask &= ~((uint)PermissionMask.Transfer >> 13); 1142 mask &= ~((uint)PermissionMask.Modify >> 13);
964 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
965 mask &= ~((uint)PermissionMask.Modify >> 13);
966 }
967
968 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
969 mask &= ~(uint)PermissionMask.Copy;
970 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
971 mask &= ~(uint)PermissionMask.Transfer;
972 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
973 mask &= ~(uint)PermissionMask.Modify;
974 } 1143 }
1144
1145 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1146 mask &= ~(uint)PermissionMask.Copy;
1147 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1148 mask &= ~(uint)PermissionMask.Transfer;
1149 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1150 mask &= ~(uint)PermissionMask.Modify;
975 } 1151 }
976
977 return mask; 1152 return mask;
978 } 1153 }
979 1154
980 public void ApplyNextOwnerPermissions() 1155 public void ApplyNextOwnerPermissions()
981 { 1156 {
982 lock (m_items) 1157 foreach (TaskInventoryItem item in m_items.Values)
983 { 1158 {
984 foreach (TaskInventoryItem item in m_items.Values) 1159 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
985 { 1160 {
986 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 1161 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
987 { 1162 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
988 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1163 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
989 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 1164 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
990 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1165 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
991 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 1166 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
992 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
993 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
994 }
995 item.CurrentPermissions &= item.NextPermissions;
996 item.BasePermissions &= item.NextPermissions;
997 item.EveryonePermissions &= item.NextPermissions;
998 item.OwnerChanged = true;
999 } 1167 }
1168 item.OwnerChanged = true;
1169 item.CurrentPermissions &= item.NextPermissions;
1170 item.BasePermissions &= item.NextPermissions;
1171 item.EveryonePermissions &= item.NextPermissions;
1000 } 1172 }
1001 } 1173 }
1002 1174
1003 public void ApplyGodPermissions(uint perms) 1175 public void ApplyGodPermissions(uint perms)
1004 { 1176 {
1005 lock (m_items) 1177 foreach (TaskInventoryItem item in m_items.Values)
1006 { 1178 {
1007 foreach (TaskInventoryItem item in m_items.Values) 1179 item.CurrentPermissions = perms;
1008 { 1180 item.BasePermissions = perms;
1009 item.CurrentPermissions = perms;
1010 item.BasePermissions = perms;
1011 }
1012 } 1181 }
1013 } 1182 }
1014 1183
1015 public bool ContainsScripts() 1184 public bool ContainsScripts()
1016 { 1185 {
1017 lock (m_items) 1186 foreach (TaskInventoryItem item in m_items.Values)
1018 { 1187 {
1019 foreach (TaskInventoryItem item in m_items.Values) 1188 if (item.InvType == (int)InventoryType.LSL)
1020 { 1189 {
1021 if (item.InvType == (int)InventoryType.LSL) 1190 return true;
1022 {
1023 return true;
1024 }
1025 } 1191 }
1026 } 1192 }
1027
1028 return false; 1193 return false;
1029 } 1194 }
1030 1195
@@ -1032,11 +1197,8 @@ namespace OpenSim.Region.Framework.Scenes
1032 { 1197 {
1033 List<UUID> ret = new List<UUID>(); 1198 List<UUID> ret = new List<UUID>();
1034 1199
1035 lock (m_items) 1200 foreach (TaskInventoryItem item in m_items.Values)
1036 { 1201 ret.Add(item.ItemID);
1037 foreach (TaskInventoryItem item in m_items.Values)
1038 ret.Add(item.ItemID);
1039 }
1040 1202
1041 return ret; 1203 return ret;
1042 } 1204 }
@@ -1067,31 +1229,46 @@ namespace OpenSim.Region.Framework.Scenes
1067 1229
1068 public Dictionary<UUID, string> GetScriptStates() 1230 public Dictionary<UUID, string> GetScriptStates()
1069 { 1231 {
1232 return GetScriptStates(false);
1233 }
1234
1235 public Dictionary<UUID, string> GetScriptStates(bool oldIDs)
1236 {
1070 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); 1237 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
1071 1238
1072 Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); 1239 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
1073 if (engines == null) // No engine at all 1240 if (engines == null) // No engine at all
1074 return ret; 1241 return ret;
1075 1242
1076 List<TaskInventoryItem> scripts = GetInventoryScripts(); 1243 Items.LockItemsForRead(true);
1077 1244 foreach (TaskInventoryItem item in m_items.Values)
1078 foreach (TaskInventoryItem item in scripts)
1079 { 1245 {
1080 foreach (IScriptModule e in engines) 1246 if (item.InvType == (int)InventoryType.LSL)
1081 { 1247 {
1082 if (e != null) 1248 foreach (IScriptModule e in engines)
1083 { 1249 {
1084 string n = e.GetXMLState(item.ItemID); 1250 if (e != null)
1085 if (n != String.Empty)
1086 { 1251 {
1087 if (!ret.ContainsKey(item.ItemID)) 1252 string n = e.GetXMLState(item.ItemID);
1088 ret[item.ItemID] = n; 1253 if (n != String.Empty)
1089 break; 1254 {
1255 if (oldIDs)
1256 {
1257 if (!ret.ContainsKey(item.OldItemID))
1258 ret[item.OldItemID] = n;
1259 }
1260 else
1261 {
1262 if (!ret.ContainsKey(item.ItemID))
1263 ret[item.ItemID] = n;
1264 }
1265 break;
1266 }
1090 } 1267 }
1091 } 1268 }
1092 } 1269 }
1093 } 1270 }
1094 1271 Items.LockItemsForRead(false);
1095 return ret; 1272 return ret;
1096 } 1273 }
1097 1274
@@ -1101,21 +1278,27 @@ namespace OpenSim.Region.Framework.Scenes
1101 if (engines == null) 1278 if (engines == null)
1102 return; 1279 return;
1103 1280
1104 List<TaskInventoryItem> scripts = GetInventoryScripts();
1105 1281
1106 foreach (TaskInventoryItem item in scripts) 1282 Items.LockItemsForRead(true);
1283
1284 foreach (TaskInventoryItem item in m_items.Values)
1107 { 1285 {
1108 foreach (IScriptModule engine in engines) 1286 if (item.InvType == (int)InventoryType.LSL)
1109 { 1287 {
1110 if (engine != null) 1288 foreach (IScriptModule engine in engines)
1111 { 1289 {
1112 if (item.OwnerChanged) 1290 if (engine != null)
1113 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); 1291 {
1114 item.OwnerChanged = false; 1292 if (item.OwnerChanged)
1115 engine.ResumeScript(item.ItemID); 1293 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
1294 item.OwnerChanged = false;
1295 engine.ResumeScript(item.ItemID);
1296 }
1116 } 1297 }
1117 } 1298 }
1118 } 1299 }
1300
1301 Items.LockItemsForRead(false);
1119 } 1302 }
1120 } 1303 }
1121} 1304}