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.cs754
1 files changed, 484 insertions, 270 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 3281eab..1992956 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -48,6 +48,9 @@ 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 private bool m_inventoryPrivileged = false;
52
53 private Dictionary<UUID, ArrayList> m_scriptErrors = new Dictionary<UUID, ArrayList>();
51 54
52 /// <value> 55 /// <value>
53 /// The part to which the inventory belongs. 56 /// The part to which the inventory belongs.
@@ -84,11 +87,14 @@ namespace OpenSim.Region.Framework.Scenes
84 /// </value> 87 /// </value>
85 protected internal TaskInventoryDictionary Items 88 protected internal TaskInventoryDictionary Items
86 { 89 {
87 get { return m_items; } 90 get {
91 return m_items;
92 }
88 set 93 set
89 { 94 {
90 m_items = value; 95 m_items = value;
91 m_inventorySerial++; 96 m_inventorySerial++;
97 QueryScriptStates();
92 } 98 }
93 } 99 }
94 100
@@ -120,39 +126,45 @@ namespace OpenSim.Region.Framework.Scenes
120 /// <param name="linkNum">Link number for the part</param> 126 /// <param name="linkNum">Link number for the part</param>
121 public void ResetInventoryIDs() 127 public void ResetInventoryIDs()
122 { 128 {
123 if (null == m_part || null == m_part.ParentGroup) 129 m_items.LockItemsForWrite(true);
124 return; 130
125 131 if (Items.Count == 0)
126 lock (m_items)
127 { 132 {
128 if (0 == m_items.Count) 133 m_items.LockItemsForWrite(false);
129 return; 134 return;
135 }
130 136
131 IList<TaskInventoryItem> items = GetInventoryItems(); 137 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
132 m_items.Clear(); 138 Items.Clear();
133 139
134 foreach (TaskInventoryItem item in items) 140 foreach (TaskInventoryItem item in items)
135 { 141 {
136 item.ResetIDs(m_part.UUID); 142 item.ResetIDs(m_part.UUID);
137 m_items.Add(item.ItemID, item); 143 Items.Add(item.ItemID, item);
138 }
139 } 144 }
145 m_items.LockItemsForWrite(false);
140 } 146 }
141 147
142 public void ResetObjectID() 148 public void ResetObjectID()
143 { 149 {
144 lock (Items) 150 m_items.LockItemsForWrite(true);
151
152 if (Items.Count == 0)
145 { 153 {
146 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 154 m_items.LockItemsForWrite(false);
147 Items.Clear(); 155 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 } 156 }
157
158 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
159 Items.Clear();
160
161 foreach (TaskInventoryItem item in items)
162 {
163 item.ParentPartID = m_part.UUID;
164 item.ParentID = m_part.UUID;
165 Items.Add(item.ItemID, item);
166 }
167 m_items.LockItemsForWrite(false);
156 } 168 }
157 169
158 /// <summary> 170 /// <summary>
@@ -161,12 +173,11 @@ namespace OpenSim.Region.Framework.Scenes
161 /// <param name="ownerId"></param> 173 /// <param name="ownerId"></param>
162 public void ChangeInventoryOwner(UUID ownerId) 174 public void ChangeInventoryOwner(UUID ownerId)
163 { 175 {
164 lock (Items) 176 m_items.LockItemsForWrite(true);
177 if (0 == Items.Count)
165 { 178 {
166 if (0 == Items.Count) 179 m_items.LockItemsForWrite(false);
167 { 180 return;
168 return;
169 }
170 } 181 }
171 182
172 HasInventoryChanged = true; 183 HasInventoryChanged = true;
@@ -182,6 +193,7 @@ namespace OpenSim.Region.Framework.Scenes
182 item.PermsGranter = UUID.Zero; 193 item.PermsGranter = UUID.Zero;
183 item.OwnerChanged = true; 194 item.OwnerChanged = true;
184 } 195 }
196 m_items.LockItemsForWrite(false);
185 } 197 }
186 198
187 /// <summary> 199 /// <summary>
@@ -190,12 +202,11 @@ namespace OpenSim.Region.Framework.Scenes
190 /// <param name="groupID"></param> 202 /// <param name="groupID"></param>
191 public void ChangeInventoryGroup(UUID groupID) 203 public void ChangeInventoryGroup(UUID groupID)
192 { 204 {
193 lock (Items) 205 m_items.LockItemsForWrite(true);
206 if (0 == Items.Count)
194 { 207 {
195 if (0 == Items.Count) 208 m_items.LockItemsForWrite(false);
196 { 209 return;
197 return;
198 }
199 } 210 }
200 211
201 // Don't let this set the HasGroupChanged flag for attachments 212 // Don't let this set the HasGroupChanged flag for attachments
@@ -207,12 +218,45 @@ namespace OpenSim.Region.Framework.Scenes
207 m_part.ParentGroup.HasGroupChanged = true; 218 m_part.ParentGroup.HasGroupChanged = true;
208 } 219 }
209 220
210 List<TaskInventoryItem> items = GetInventoryItems(); 221 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
211 foreach (TaskInventoryItem item in items) 222 foreach (TaskInventoryItem item in items)
212 { 223 {
213 if (groupID != item.GroupID) 224 if (groupID != item.GroupID)
225 {
214 item.GroupID = groupID; 226 item.GroupID = groupID;
227 }
215 } 228 }
229 m_items.LockItemsForWrite(false);
230 }
231
232 private void QueryScriptStates()
233 {
234 if (m_part == null || m_part.ParentGroup == null)
235 return;
236
237 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
238 if (engines == null) // No engine at all
239 return;
240
241 Items.LockItemsForRead(true);
242 foreach (TaskInventoryItem item in Items.Values)
243 {
244 if (item.InvType == (int)InventoryType.LSL)
245 {
246 foreach (IScriptModule e in engines)
247 {
248 bool running;
249
250 if (e.HasScript(item.ItemID, out running))
251 {
252 item.ScriptRunning = running;
253 break;
254 }
255 }
256 }
257 }
258
259 Items.LockItemsForRead(false);
216 } 260 }
217 261
218 /// <summary> 262 /// <summary>
@@ -220,9 +264,14 @@ namespace OpenSim.Region.Framework.Scenes
220 /// </summary> 264 /// </summary>
221 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 265 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
222 { 266 {
223 List<TaskInventoryItem> scripts = GetInventoryScripts(); 267 Items.LockItemsForRead(true);
224 foreach (TaskInventoryItem item in scripts) 268 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
225 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 269 Items.LockItemsForRead(false);
270 foreach (TaskInventoryItem item in items)
271 {
272 if ((int)InventoryType.LSL == item.InvType)
273 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
274 }
226 } 275 }
227 276
228 public ArrayList GetScriptErrors(UUID itemID) 277 public ArrayList GetScriptErrors(UUID itemID)
@@ -255,9 +304,18 @@ namespace OpenSim.Region.Framework.Scenes
255 /// </param> 304 /// </param>
256 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 305 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
257 { 306 {
258 List<TaskInventoryItem> scripts = GetInventoryScripts(); 307 Items.LockItemsForRead(true);
259 foreach (TaskInventoryItem item in scripts) 308 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
260 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); 309 Items.LockItemsForRead(false);
310
311 foreach (TaskInventoryItem item in items)
312 {
313 if ((int)InventoryType.LSL == item.InvType)
314 {
315 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
316 m_part.RemoveScriptEvents(item.ItemID);
317 }
318 }
261 } 319 }
262 320
263 /// <summary> 321 /// <summary>
@@ -273,7 +331,10 @@ namespace OpenSim.Region.Framework.Scenes
273 // item.Name, item.ItemID, Name, UUID); 331 // item.Name, item.ItemID, Name, UUID);
274 332
275 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) 333 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID))
334 {
335 StoreScriptError(item.ItemID, "no permission");
276 return; 336 return;
337 }
277 338
278 m_part.AddFlag(PrimFlags.Scripted); 339 m_part.AddFlag(PrimFlags.Scripted);
279 340
@@ -282,14 +343,13 @@ namespace OpenSim.Region.Framework.Scenes
282 if (stateSource == 2 && // Prim crossing 343 if (stateSource == 2 && // Prim crossing
283 m_part.ParentGroup.Scene.m_trustBinaries) 344 m_part.ParentGroup.Scene.m_trustBinaries)
284 { 345 {
285 lock (m_items) 346 m_items.LockItemsForWrite(true);
286 { 347 m_items[item.ItemID].PermsMask = 0;
287 m_items[item.ItemID].PermsMask = 0; 348 m_items[item.ItemID].PermsGranter = UUID.Zero;
288 m_items[item.ItemID].PermsGranter = UUID.Zero; 349 m_items.LockItemsForWrite(false);
289 }
290
291 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 350 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
292 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 351 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
352 StoreScriptErrors(item.ItemID, null);
293 m_part.ParentGroup.AddActiveScriptCount(1); 353 m_part.ParentGroup.AddActiveScriptCount(1);
294 m_part.ScheduleFullUpdate(); 354 m_part.ScheduleFullUpdate();
295 return; 355 return;
@@ -298,6 +358,8 @@ namespace OpenSim.Region.Framework.Scenes
298 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); 358 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
299 if (null == asset) 359 if (null == asset)
300 { 360 {
361 string msg = String.Format("asset ID {0} could not be found", item.AssetID);
362 StoreScriptError(item.ItemID, msg);
301 m_log.ErrorFormat( 363 m_log.ErrorFormat(
302 "[PRIM INVENTORY]: " + 364 "[PRIM INVENTORY]: " +
303 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", 365 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
@@ -309,15 +371,20 @@ namespace OpenSim.Region.Framework.Scenes
309 if (m_part.ParentGroup.m_savedScriptState != null) 371 if (m_part.ParentGroup.m_savedScriptState != null)
310 RestoreSavedScriptState(item.OldItemID, item.ItemID); 372 RestoreSavedScriptState(item.OldItemID, item.ItemID);
311 373
312 lock (m_items) 374 m_items.LockItemsForWrite(true);
313 { 375
314 m_items[item.ItemID].PermsMask = 0; 376 m_items[item.ItemID].PermsMask = 0;
315 m_items[item.ItemID].PermsGranter = UUID.Zero; 377 m_items[item.ItemID].PermsGranter = UUID.Zero;
316 } 378
379 m_items.LockItemsForWrite(false);
317 380
318 string script = Utils.BytesToString(asset.Data); 381 string script = Utils.BytesToString(asset.Data);
319 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 382 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
320 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 383 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
384 StoreScriptErrors(item.ItemID, null);
385 if (!item.ScriptRunning)
386 m_part.ParentGroup.Scene.EventManager.TriggerStopScript(
387 m_part.LocalId, item.ItemID);
321 m_part.ParentGroup.AddActiveScriptCount(1); 388 m_part.ParentGroup.AddActiveScriptCount(1);
322 m_part.ScheduleFullUpdate(); 389 m_part.ScheduleFullUpdate();
323 } 390 }
@@ -381,21 +448,145 @@ namespace OpenSim.Region.Framework.Scenes
381 448
382 /// <summary> 449 /// <summary>
383 /// Start a script which is in this prim's inventory. 450 /// Start a script which is in this prim's inventory.
451 /// Some processing may occur in the background, but this routine returns asap.
384 /// </summary> 452 /// </summary>
385 /// <param name="itemId"> 453 /// <param name="itemId">
386 /// A <see cref="UUID"/> 454 /// A <see cref="UUID"/>
387 /// </param> 455 /// </param>
388 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 456 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
389 { 457 {
390 TaskInventoryItem item = GetInventoryItem(itemId); 458 lock (m_scriptErrors)
391 if (item != null) 459 {
392 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 460 // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion
461 m_scriptErrors.Remove(itemId);
462 }
463 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
464 }
465
466 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
467 {
468 m_items.LockItemsForRead(true);
469 if (m_items.ContainsKey(itemId))
470 {
471 if (m_items.ContainsKey(itemId))
472 {
473 m_items.LockItemsForRead(false);
474 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
475 }
476 else
477 {
478 m_items.LockItemsForRead(false);
479 string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID,
480 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
481 StoreScriptError(itemId, msg);
482 m_log.ErrorFormat(
483 "[PRIM INVENTORY]: " +
484 "Couldn't start script with ID {0} since it {1}", itemId, msg);
485 }
486 }
393 else 487 else
488 {
489 m_items.LockItemsForRead(false);
490 string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID);
491 StoreScriptError(itemId, msg);
394 m_log.ErrorFormat( 492 m_log.ErrorFormat(
395 "[PRIM INVENTORY]: " + 493 "[PRIM INVENTORY]: " +
396 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 494 "Couldn't start script with ID {0} since it {1}", itemId, msg);
397 itemId, m_part.Name, m_part.UUID, 495 }
398 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 496
497 }
498
499 /// <summary>
500 /// Start a script which is in this prim's inventory and return any compilation error messages.
501 /// </summary>
502 /// <param name="itemId">
503 /// A <see cref="UUID"/>
504 /// </param>
505 public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
506 {
507 ArrayList errors;
508
509 // Indicate to CreateScriptInstanceInternal() we want it to
510 // post any compilation/loading error messages
511 lock (m_scriptErrors)
512 {
513 m_scriptErrors[itemId] = null;
514 }
515
516 // Perform compilation/loading
517 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
518
519 // Wait for and retrieve any errors
520 lock (m_scriptErrors)
521 {
522 while ((errors = m_scriptErrors[itemId]) == null)
523 {
524 if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
525 {
526 m_log.ErrorFormat(
527 "[PRIM INVENTORY]: " +
528 "timedout waiting for script {0} errors", itemId);
529 errors = m_scriptErrors[itemId];
530 if (errors == null)
531 {
532 errors = new ArrayList(1);
533 errors.Add("timedout waiting for errors");
534 }
535 break;
536 }
537 }
538 m_scriptErrors.Remove(itemId);
539 }
540 return errors;
541 }
542
543 // Signal to CreateScriptInstanceEr() that compilation/loading is complete
544 private void StoreScriptErrors(UUID itemId, ArrayList errors)
545 {
546 lock (m_scriptErrors)
547 {
548 // If compilation/loading initiated via CreateScriptInstance(),
549 // it does not want the errors, so just get out
550 if (!m_scriptErrors.ContainsKey(itemId))
551 {
552 return;
553 }
554
555 // Initiated via CreateScriptInstanceEr(), if we know what the
556 // errors are, save them and wake CreateScriptInstanceEr().
557 if (errors != null)
558 {
559 m_scriptErrors[itemId] = errors;
560 System.Threading.Monitor.PulseAll(m_scriptErrors);
561 return;
562 }
563 }
564
565 // Initiated via CreateScriptInstanceEr() but we don't know what
566 // the errors are yet, so retrieve them from the script engine.
567 // This may involve some waiting internal to GetScriptErrors().
568 errors = GetScriptErrors(itemId);
569
570 // Get a default non-null value to indicate success.
571 if (errors == null)
572 {
573 errors = new ArrayList();
574 }
575
576 // Post to CreateScriptInstanceEr() and wake it up
577 lock (m_scriptErrors)
578 {
579 m_scriptErrors[itemId] = errors;
580 System.Threading.Monitor.PulseAll(m_scriptErrors);
581 }
582 }
583
584 // Like StoreScriptErrors(), but just posts a single string message
585 private void StoreScriptError(UUID itemId, string message)
586 {
587 ArrayList errors = new ArrayList(1);
588 errors.Add(message);
589 StoreScriptErrors(itemId, errors);
399 } 590 }
400 591
401 /// <summary> 592 /// <summary>
@@ -408,15 +599,7 @@ namespace OpenSim.Region.Framework.Scenes
408 /// </param> 599 /// </param>
409 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 600 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
410 { 601 {
411 bool scriptPresent = false; 602 if (m_items.ContainsKey(itemId))
412
413 lock (m_items)
414 {
415 if (m_items.ContainsKey(itemId))
416 scriptPresent = true;
417 }
418
419 if (scriptPresent)
420 { 603 {
421 if (!sceneObjectBeingDeleted) 604 if (!sceneObjectBeingDeleted)
422 m_part.RemoveScriptEvents(itemId); 605 m_part.RemoveScriptEvents(itemId);
@@ -441,14 +624,16 @@ namespace OpenSim.Region.Framework.Scenes
441 /// <returns></returns> 624 /// <returns></returns>
442 private bool InventoryContainsName(string name) 625 private bool InventoryContainsName(string name)
443 { 626 {
444 lock (m_items) 627 m_items.LockItemsForRead(true);
628 foreach (TaskInventoryItem item in m_items.Values)
445 { 629 {
446 foreach (TaskInventoryItem item in m_items.Values) 630 if (item.Name == name)
447 { 631 {
448 if (item.Name == name) 632 m_items.LockItemsForRead(false);
449 return true; 633 return true;
450 } 634 }
451 } 635 }
636 m_items.LockItemsForRead(false);
452 return false; 637 return false;
453 } 638 }
454 639
@@ -490,8 +675,9 @@ namespace OpenSim.Region.Framework.Scenes
490 /// <param name="item"></param> 675 /// <param name="item"></param>
491 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 676 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
492 { 677 {
493 List<TaskInventoryItem> il = GetInventoryItems(); 678 m_items.LockItemsForRead(true);
494 679 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
680 m_items.LockItemsForRead(false);
495 foreach (TaskInventoryItem i in il) 681 foreach (TaskInventoryItem i in il)
496 { 682 {
497 if (i.Name == item.Name) 683 if (i.Name == item.Name)
@@ -529,14 +715,14 @@ namespace OpenSim.Region.Framework.Scenes
529 item.Name = name; 715 item.Name = name;
530 item.GroupID = m_part.GroupID; 716 item.GroupID = m_part.GroupID;
531 717
532 lock (m_items) 718 m_items.LockItemsForWrite(true);
533 m_items.Add(item.ItemID, item); 719 m_items.Add(item.ItemID, item);
534 720 m_items.LockItemsForWrite(false);
535 if (allowedDrop) 721 if (allowedDrop)
536 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 722 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
537 else 723 else
538 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 724 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
539 725
540 m_inventorySerial++; 726 m_inventorySerial++;
541 //m_inventorySerial += 2; 727 //m_inventorySerial += 2;
542 HasInventoryChanged = true; 728 HasInventoryChanged = true;
@@ -552,15 +738,15 @@ namespace OpenSim.Region.Framework.Scenes
552 /// <param name="items"></param> 738 /// <param name="items"></param>
553 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 739 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
554 { 740 {
555 lock (m_items) 741 m_items.LockItemsForWrite(true);
742 foreach (TaskInventoryItem item in items)
556 { 743 {
557 foreach (TaskInventoryItem item in items) 744 m_items.Add(item.ItemID, item);
558 { 745// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
559 m_items.Add(item.ItemID, item);
560// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
561 }
562 m_inventorySerial++;
563 } 746 }
747 m_items.LockItemsForWrite(false);
748
749 m_inventorySerial++;
564 } 750 }
565 751
566 /// <summary> 752 /// <summary>
@@ -571,10 +757,9 @@ namespace OpenSim.Region.Framework.Scenes
571 public TaskInventoryItem GetInventoryItem(UUID itemId) 757 public TaskInventoryItem GetInventoryItem(UUID itemId)
572 { 758 {
573 TaskInventoryItem item; 759 TaskInventoryItem item;
574 760 m_items.LockItemsForRead(true);
575 lock (m_items) 761 m_items.TryGetValue(itemId, out item);
576 m_items.TryGetValue(itemId, out item); 762 m_items.LockItemsForRead(false);
577
578 return item; 763 return item;
579 } 764 }
580 765
@@ -590,15 +775,16 @@ namespace OpenSim.Region.Framework.Scenes
590 { 775 {
591 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); 776 IList<TaskInventoryItem> items = new List<TaskInventoryItem>();
592 777
593 lock (m_items) 778 m_items.LockItemsForRead(true);
779
780 foreach (TaskInventoryItem item in m_items.Values)
594 { 781 {
595 foreach (TaskInventoryItem item in m_items.Values) 782 if (item.Name == name)
596 { 783 items.Add(item);
597 if (item.Name == name)
598 items.Add(item);
599 }
600 } 784 }
601 785
786 m_items.LockItemsForRead(false);
787
602 return items; 788 return items;
603 } 789 }
604 790
@@ -691,9 +877,9 @@ namespace OpenSim.Region.Framework.Scenes
691 877
692 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) 878 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged)
693 { 879 {
694 TaskInventoryItem it = GetInventoryItem(item.ItemID); 880 m_items.LockItemsForWrite(true);
695 if (it != null)
696 881
882 if (m_items.ContainsKey(item.ItemID))
697 { 883 {
698 item.ParentID = m_part.UUID; 884 item.ParentID = m_part.UUID;
699 item.ParentPartID = m_part.UUID; 885 item.ParentPartID = m_part.UUID;
@@ -704,14 +890,10 @@ namespace OpenSim.Region.Framework.Scenes
704 item.GroupID = m_part.GroupID; 890 item.GroupID = m_part.GroupID;
705 891
706 if (item.AssetID == UUID.Zero) 892 if (item.AssetID == UUID.Zero)
707 item.AssetID = it.AssetID; 893 item.AssetID = m_items[item.ItemID].AssetID;
708
709 lock (m_items)
710 {
711 m_items[item.ItemID] = item;
712 m_inventorySerial++;
713 }
714 894
895 m_items[item.ItemID] = item;
896 m_inventorySerial++;
715 if (fireScriptEvents) 897 if (fireScriptEvents)
716 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 898 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
717 if (considerChanged) 899 if (considerChanged)
@@ -719,6 +901,7 @@ namespace OpenSim.Region.Framework.Scenes
719 HasInventoryChanged = true; 901 HasInventoryChanged = true;
720 m_part.ParentGroup.HasGroupChanged = true; 902 m_part.ParentGroup.HasGroupChanged = true;
721 } 903 }
904 m_items.LockItemsForWrite(false);
722 return true; 905 return true;
723 } 906 }
724 else 907 else
@@ -729,8 +912,9 @@ namespace OpenSim.Region.Framework.Scenes
729 item.ItemID, m_part.Name, m_part.UUID, 912 item.ItemID, m_part.Name, m_part.UUID,
730 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 913 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
731 } 914 }
732 return false; 915 m_items.LockItemsForWrite(false);
733 916
917 return false;
734 } 918 }
735 919
736 /// <summary> 920 /// <summary>
@@ -741,107 +925,68 @@ namespace OpenSim.Region.Framework.Scenes
741 /// in this prim's inventory.</returns> 925 /// in this prim's inventory.</returns>
742 public int RemoveInventoryItem(UUID itemID) 926 public int RemoveInventoryItem(UUID itemID)
743 { 927 {
744 TaskInventoryItem item = GetInventoryItem(itemID); 928 m_items.LockItemsForRead(true);
745 if (item != null) 929
930 if (m_items.ContainsKey(itemID))
746 { 931 {
747 int type = m_items[itemID].InvType; 932 int type = m_items[itemID].InvType;
933 m_items.LockItemsForRead(false);
748 if (type == 10) // Script 934 if (type == 10) // Script
749 { 935 {
750 m_part.RemoveScriptEvents(itemID);
751 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 936 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
752 } 937 }
938 m_items.LockItemsForWrite(true);
753 m_items.Remove(itemID); 939 m_items.Remove(itemID);
940 m_items.LockItemsForWrite(false);
754 m_inventorySerial++; 941 m_inventorySerial++;
755 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 942 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
756 943
757 HasInventoryChanged = true; 944 HasInventoryChanged = true;
758 m_part.ParentGroup.HasGroupChanged = true; 945 m_part.ParentGroup.HasGroupChanged = true;
759 946
760 if (!ContainsScripts()) 947 int scriptcount = 0;
948 m_items.LockItemsForRead(true);
949 foreach (TaskInventoryItem item in m_items.Values)
950 {
951 if (item.Type == 10)
952 {
953 scriptcount++;
954 }
955 }
956 m_items.LockItemsForRead(false);
957
958
959 if (scriptcount <= 0)
960 {
761 m_part.RemFlag(PrimFlags.Scripted); 961 m_part.RemFlag(PrimFlags.Scripted);
962 }
762 963
763 m_part.ScheduleFullUpdate(); 964 m_part.ScheduleFullUpdate();
764 965
765 return type; 966 return type;
766
767 } 967 }
768 else 968 else
769 { 969 {
970 m_items.LockItemsForRead(false);
770 m_log.ErrorFormat( 971 m_log.ErrorFormat(
771 "[PRIM INVENTORY]: " + 972 "[PRIM INVENTORY]: " +
772 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 973 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
773 itemID, m_part.Name, m_part.UUID, 974 itemID, m_part.Name, m_part.UUID);
774 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
775 } 975 }
776 976
777 return -1; 977 return -1;
778 } 978 }
779 979
780 private bool CreateInventoryFile() 980 private bool CreateInventoryFileName()
781 { 981 {
782 if (m_inventoryFileName == String.Empty || 982 if (m_inventoryFileName == String.Empty ||
783 m_inventoryFileNameSerial < m_inventorySerial) 983 m_inventoryFileNameSerial < m_inventorySerial)
784 { 984 {
785 // Something changed, we need to create a new file
786 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; 985 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
787 m_inventoryFileNameSerial = m_inventorySerial; 986 m_inventoryFileNameSerial = m_inventorySerial;
788
789 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
790
791 lock (m_items)
792 {
793 foreach (TaskInventoryItem item in m_items.Values)
794 {
795 UUID ownerID = item.OwnerID;
796 uint everyoneMask = 0;
797 uint baseMask = item.BasePermissions;
798 uint ownerMask = item.CurrentPermissions;
799 uint groupMask = item.GroupPermissions;
800
801 invString.AddItemStart();
802 invString.AddNameValueLine("item_id", item.ItemID.ToString());
803 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
804
805 invString.AddPermissionsStart();
806
807 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
808 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
809 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
810 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
811 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
812
813 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
814 invString.AddNameValueLine("owner_id", ownerID.ToString());
815
816 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
817
818 invString.AddNameValueLine("group_id", item.GroupID.ToString());
819 invString.AddSectionEnd();
820
821 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
822 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
823 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
824 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
825
826 invString.AddSaleStart();
827 invString.AddNameValueLine("sale_type", "not");
828 invString.AddNameValueLine("sale_price", "0");
829 invString.AddSectionEnd();
830
831 invString.AddNameValueLine("name", item.Name + "|");
832 invString.AddNameValueLine("desc", item.Description + "|");
833
834 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
835 invString.AddSectionEnd();
836 }
837 }
838
839 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
840
841 return true; 987 return true;
842 } 988 }
843 989
844 // No need to recreate, the existing file is fine
845 return false; 990 return false;
846 } 991 }
847 992
@@ -851,26 +996,99 @@ namespace OpenSim.Region.Framework.Scenes
851 /// <param name="xferManager"></param> 996 /// <param name="xferManager"></param>
852 public void RequestInventoryFile(IClientAPI client, IXfer xferManager) 997 public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
853 { 998 {
854 CreateInventoryFile(); 999 bool changed = CreateInventoryFileName();
1000
1001 bool includeAssets = false;
1002 if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId))
1003 includeAssets = true;
1004
1005 if (m_inventoryPrivileged != includeAssets)
1006 changed = true;
1007
1008 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
1009
1010 Items.LockItemsForRead(true);
855 1011
856 if (m_inventorySerial == 0) // No inventory 1012 if (m_inventorySerial == 0) // No inventory
857 { 1013 {
858 client.SendTaskInventory(m_part.UUID, 0, new byte[0]); 1014 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1015 Items.LockItemsForRead(false);
859 return; 1016 return;
860 } 1017 }
861 1018
862 // In principle, we should only do the rest if the inventory changed; 1019 if (!changed)
863 // by sending m_inventorySerial to the client, it ought to know 1020 {
864 // that nothing changed and that it doesn't need to request the file. 1021 if (m_inventoryFileData.Length > 2)
865 // Unfortunately, it doesn't look like the client optimizes this; 1022 {
866 // the client seems to always come back and request the Xfer, 1023 xferManager.AddNewFile(m_inventoryFileName,
867 // no matter what value m_inventorySerial has. 1024 m_inventoryFileData);
1025 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
1026 Util.StringToBytes256(m_inventoryFileName));
1027
1028 Items.LockItemsForRead(false);
1029 return;
1030 }
1031 }
1032
1033 m_inventoryPrivileged = includeAssets;
1034
1035 foreach (TaskInventoryItem item in m_items.Values)
1036 {
1037 UUID ownerID = item.OwnerID;
1038 uint everyoneMask = 0;
1039 uint baseMask = item.BasePermissions;
1040 uint ownerMask = item.CurrentPermissions;
1041 uint groupMask = item.GroupPermissions;
1042
1043 invString.AddItemStart();
1044 invString.AddNameValueLine("item_id", item.ItemID.ToString());
1045 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
1046
1047 invString.AddPermissionsStart();
1048
1049 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
1050 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
1051 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
1052 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
1053 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
1054
1055 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
1056 invString.AddNameValueLine("owner_id", ownerID.ToString());
1057
1058 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
1059
1060 invString.AddNameValueLine("group_id", item.GroupID.ToString());
1061 invString.AddSectionEnd();
1062
1063 if (includeAssets)
1064 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
1065 else
1066 invString.AddNameValueLine("asset_id", UUID.Zero.ToString());
1067 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
1068 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
1069 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
1070
1071 invString.AddSaleStart();
1072 invString.AddNameValueLine("sale_type", "not");
1073 invString.AddNameValueLine("sale_price", "0");
1074 invString.AddSectionEnd();
1075
1076 invString.AddNameValueLine("name", item.Name + "|");
1077 invString.AddNameValueLine("desc", item.Description + "|");
1078
1079 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
1080 invString.AddSectionEnd();
1081 }
1082
1083 Items.LockItemsForRead(false);
1084
1085 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
868 1086
869 if (m_inventoryFileData.Length > 2) 1087 if (m_inventoryFileData.Length > 2)
870 // Add the file for Xfer 1088 {
871 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); 1089 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
1090 }
872 1091
873 // Tell the client we're ready to Xfer the file
874 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, 1092 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
875 Util.StringToBytes256(m_inventoryFileName)); 1093 Util.StringToBytes256(m_inventoryFileName));
876 } 1094 }
@@ -883,10 +1101,11 @@ namespace OpenSim.Region.Framework.Scenes
883 { 1101 {
884 if (HasInventoryChanged) 1102 if (HasInventoryChanged)
885 { 1103 {
886 HasInventoryChanged = false; 1104 Items.LockItemsForRead(true);
887 List<TaskInventoryItem> items = GetInventoryItems(); 1105 datastore.StorePrimInventory(m_part.UUID, Items.Values);
888 datastore.StorePrimInventory(m_part.UUID, items); 1106 Items.LockItemsForRead(false);
889 1107
1108 HasInventoryChanged = false;
890 } 1109 }
891 } 1110 }
892 1111
@@ -953,82 +1172,63 @@ namespace OpenSim.Region.Framework.Scenes
953 { 1172 {
954 uint mask=0x7fffffff; 1173 uint mask=0x7fffffff;
955 1174
956 lock (m_items) 1175 foreach (TaskInventoryItem item in m_items.Values)
957 { 1176 {
958 foreach (TaskInventoryItem item in m_items.Values) 1177 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
1178 mask &= ~((uint)PermissionMask.Copy >> 13);
1179 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
1180 mask &= ~((uint)PermissionMask.Transfer >> 13);
1181 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
1182 mask &= ~((uint)PermissionMask.Modify >> 13);
1183
1184 if (item.InvType == (int)InventoryType.Object)
959 { 1185 {
960 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1186 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
961 mask &= ~((uint)PermissionMask.Copy >> 13); 1187 mask &= ~((uint)PermissionMask.Copy >> 13);
962 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1188 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
963 mask &= ~((uint)PermissionMask.Transfer >> 13); 1189 mask &= ~((uint)PermissionMask.Transfer >> 13);
964 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 1190 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
965 mask &= ~((uint)PermissionMask.Modify >> 13); 1191 mask &= ~((uint)PermissionMask.Modify >> 13);
966
967 if (item.InvType != (int)InventoryType.Object)
968 {
969 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
970 mask &= ~((uint)PermissionMask.Copy >> 13);
971 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
972 mask &= ~((uint)PermissionMask.Transfer >> 13);
973 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
974 mask &= ~((uint)PermissionMask.Modify >> 13);
975 }
976 else
977 {
978 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
979 mask &= ~((uint)PermissionMask.Copy >> 13);
980 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
981 mask &= ~((uint)PermissionMask.Transfer >> 13);
982 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
983 mask &= ~((uint)PermissionMask.Modify >> 13);
984 }
985
986 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
987 mask &= ~(uint)PermissionMask.Copy;
988 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
989 mask &= ~(uint)PermissionMask.Transfer;
990 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
991 mask &= ~(uint)PermissionMask.Modify;
992 } 1192 }
1193
1194 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1195 mask &= ~(uint)PermissionMask.Copy;
1196 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1197 mask &= ~(uint)PermissionMask.Transfer;
1198 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1199 mask &= ~(uint)PermissionMask.Modify;
993 } 1200 }
994
995 return mask; 1201 return mask;
996 } 1202 }
997 1203
998 public void ApplyNextOwnerPermissions() 1204 public void ApplyNextOwnerPermissions()
999 { 1205 {
1000 lock (m_items) 1206 foreach (TaskInventoryItem item in m_items.Values)
1001 { 1207 {
1002 foreach (TaskInventoryItem item in m_items.Values) 1208 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
1003 { 1209 {
1004 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 1210 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1005 { 1211 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
1006 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1212 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1007 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 1213 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
1008 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1214 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1009 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 1215 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1010 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1011 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1012 }
1013 item.CurrentPermissions &= item.NextPermissions;
1014 item.BasePermissions &= item.NextPermissions;
1015 item.EveryonePermissions &= item.NextPermissions;
1016 item.OwnerChanged = true;
1017 item.PermsMask = 0;
1018 item.PermsGranter = UUID.Zero;
1019 } 1216 }
1217 item.OwnerChanged = true;
1218 item.CurrentPermissions &= item.NextPermissions;
1219 item.BasePermissions &= item.NextPermissions;
1220 item.EveryonePermissions &= item.NextPermissions;
1221 item.PermsMask = 0;
1222 item.PermsGranter = UUID.Zero;
1020 } 1223 }
1021 } 1224 }
1022 1225
1023 public void ApplyGodPermissions(uint perms) 1226 public void ApplyGodPermissions(uint perms)
1024 { 1227 {
1025 lock (m_items) 1228 foreach (TaskInventoryItem item in m_items.Values)
1026 { 1229 {
1027 foreach (TaskInventoryItem item in m_items.Values) 1230 item.CurrentPermissions = perms;
1028 { 1231 item.BasePermissions = perms;
1029 item.CurrentPermissions = perms;
1030 item.BasePermissions = perms;
1031 }
1032 } 1232 }
1033 m_inventorySerial++; 1233 m_inventorySerial++;
1034 HasInventoryChanged = true; 1234 HasInventoryChanged = true;
@@ -1036,17 +1236,13 @@ namespace OpenSim.Region.Framework.Scenes
1036 1236
1037 public bool ContainsScripts() 1237 public bool ContainsScripts()
1038 { 1238 {
1039 lock (m_items) 1239 foreach (TaskInventoryItem item in m_items.Values)
1040 { 1240 {
1041 foreach (TaskInventoryItem item in m_items.Values) 1241 if (item.InvType == (int)InventoryType.LSL)
1042 { 1242 {
1043 if (item.InvType == (int)InventoryType.LSL) 1243 return true;
1044 {
1045 return true;
1046 }
1047 } 1244 }
1048 } 1245 }
1049
1050 return false; 1246 return false;
1051 } 1247 }
1052 1248
@@ -1054,11 +1250,8 @@ namespace OpenSim.Region.Framework.Scenes
1054 { 1250 {
1055 List<UUID> ret = new List<UUID>(); 1251 List<UUID> ret = new List<UUID>();
1056 1252
1057 lock (m_items) 1253 foreach (TaskInventoryItem item in m_items.Values)
1058 { 1254 ret.Add(item.ItemID);
1059 foreach (TaskInventoryItem item in m_items.Values)
1060 ret.Add(item.ItemID);
1061 }
1062 1255
1063 return ret; 1256 return ret;
1064 } 1257 }
@@ -1089,6 +1282,11 @@ namespace OpenSim.Region.Framework.Scenes
1089 1282
1090 public Dictionary<UUID, string> GetScriptStates() 1283 public Dictionary<UUID, string> GetScriptStates()
1091 { 1284 {
1285 return GetScriptStates(false);
1286 }
1287
1288 public Dictionary<UUID, string> GetScriptStates(bool oldIDs)
1289 {
1092 Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); 1290 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
1093 1291
1094 if (m_part.ParentGroup.Scene == null) // Group not in a scene 1292 if (m_part.ParentGroup.Scene == null) // Group not in a scene
@@ -1099,25 +1297,35 @@ namespace OpenSim.Region.Framework.Scenes
1099 if (engines == null) // No engine at all 1297 if (engines == null) // No engine at all
1100 return ret; 1298 return ret;
1101 1299
1102 List<TaskInventoryItem> scripts = GetInventoryScripts(); 1300 Items.LockItemsForRead(true);
1103 1301 foreach (TaskInventoryItem item in m_items.Values)
1104 foreach (TaskInventoryItem item in scripts)
1105 { 1302 {
1106 foreach (IScriptModule e in engines) 1303 if (item.InvType == (int)InventoryType.LSL)
1107 { 1304 {
1108 if (e != null) 1305 foreach (IScriptModule e in engines)
1109 { 1306 {
1110 string n = e.GetXMLState(item.ItemID); 1307 if (e != null)
1111 if (n != String.Empty)
1112 { 1308 {
1113 if (!ret.ContainsKey(item.ItemID)) 1309 string n = e.GetXMLState(item.ItemID);
1114 ret[item.ItemID] = n; 1310 if (n != String.Empty)
1115 break; 1311 {
1312 if (oldIDs)
1313 {
1314 if (!ret.ContainsKey(item.OldItemID))
1315 ret[item.OldItemID] = n;
1316 }
1317 else
1318 {
1319 if (!ret.ContainsKey(item.ItemID))
1320 ret[item.ItemID] = n;
1321 }
1322 break;
1323 }
1116 } 1324 }
1117 } 1325 }
1118 } 1326 }
1119 } 1327 }
1120 1328 Items.LockItemsForRead(false);
1121 return ret; 1329 return ret;
1122 } 1330 }
1123 1331
@@ -1127,21 +1335,27 @@ namespace OpenSim.Region.Framework.Scenes
1127 if (engines == null) 1335 if (engines == null)
1128 return; 1336 return;
1129 1337
1130 List<TaskInventoryItem> scripts = GetInventoryScripts();
1131 1338
1132 foreach (TaskInventoryItem item in scripts) 1339 Items.LockItemsForRead(true);
1340
1341 foreach (TaskInventoryItem item in m_items.Values)
1133 { 1342 {
1134 foreach (IScriptModule engine in engines) 1343 if (item.InvType == (int)InventoryType.LSL)
1135 { 1344 {
1136 if (engine != null) 1345 foreach (IScriptModule engine in engines)
1137 { 1346 {
1138 if (item.OwnerChanged) 1347 if (engine != null)
1139 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); 1348 {
1140 item.OwnerChanged = false; 1349 if (item.OwnerChanged)
1141 engine.ResumeScript(item.ItemID); 1350 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
1351 item.OwnerChanged = false;
1352 engine.ResumeScript(item.ItemID);
1353 }
1142 } 1354 }
1143 } 1355 }
1144 } 1356 }
1357
1358 Items.LockItemsForRead(false);
1145 } 1359 }
1146 } 1360 }
1147} 1361}