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.cs759
1 files changed, 488 insertions, 271 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 3b60f8c..56680df 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 156 }
149 foreach (TaskInventoryItem item in items) 157
150 { 158 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
151 item.ParentPartID = m_part.UUID; 159 Items.Clear();
152 item.ParentID = m_part.UUID; 160
153 Items.Add(item.ItemID, item); 161 foreach (TaskInventoryItem item in items)
154 } 162 {
163 item.ParentPartID = m_part.UUID;
164 item.ParentID = m_part.UUID;
165 Items.Add(item.ItemID, item);
155 } 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
@@ -617,6 +803,9 @@ namespace OpenSim.Region.Framework.Scenes
617 string xmlData = Utils.BytesToString(rezAsset.Data); 803 string xmlData = Utils.BytesToString(rezAsset.Data);
618 SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); 804 SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
619 805
806 group.RootPart.AttachPoint = group.RootPart.Shape.State;
807 group.RootPart.AttachOffset = group.AbsolutePosition;
808
620 group.ResetIDs(); 809 group.ResetIDs();
621 810
622 SceneObjectPart rootPart = group.GetChildPart(group.UUID); 811 SceneObjectPart rootPart = group.GetChildPart(group.UUID);
@@ -691,8 +880,9 @@ namespace OpenSim.Region.Framework.Scenes
691 880
692 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) 881 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged)
693 { 882 {
694 TaskInventoryItem it = GetInventoryItem(item.ItemID); 883 m_items.LockItemsForWrite(true);
695 if (it != null) 884
885 if (m_items.ContainsKey(item.ItemID))
696 { 886 {
697// m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); 887// m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name);
698 888
@@ -705,14 +895,10 @@ namespace OpenSim.Region.Framework.Scenes
705 item.GroupID = m_part.GroupID; 895 item.GroupID = m_part.GroupID;
706 896
707 if (item.AssetID == UUID.Zero) 897 if (item.AssetID == UUID.Zero)
708 item.AssetID = it.AssetID; 898 item.AssetID = m_items[item.ItemID].AssetID;
709 899
710 lock (m_items) 900 m_items[item.ItemID] = item;
711 { 901 m_inventorySerial++;
712 m_items[item.ItemID] = item;
713 m_inventorySerial++;
714 }
715
716 if (fireScriptEvents) 902 if (fireScriptEvents)
717 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 903 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
718 904
@@ -721,7 +907,7 @@ namespace OpenSim.Region.Framework.Scenes
721 HasInventoryChanged = true; 907 HasInventoryChanged = true;
722 m_part.ParentGroup.HasGroupChanged = true; 908 m_part.ParentGroup.HasGroupChanged = true;
723 } 909 }
724 910 m_items.LockItemsForWrite(false);
725 return true; 911 return true;
726 } 912 }
727 else 913 else
@@ -732,8 +918,9 @@ namespace OpenSim.Region.Framework.Scenes
732 item.ItemID, m_part.Name, m_part.UUID, 918 item.ItemID, m_part.Name, m_part.UUID,
733 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 919 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
734 } 920 }
735 return false; 921 m_items.LockItemsForWrite(false);
736 922
923 return false;
737 } 924 }
738 925
739 /// <summary> 926 /// <summary>
@@ -744,107 +931,68 @@ namespace OpenSim.Region.Framework.Scenes
744 /// in this prim's inventory.</returns> 931 /// in this prim's inventory.</returns>
745 public int RemoveInventoryItem(UUID itemID) 932 public int RemoveInventoryItem(UUID itemID)
746 { 933 {
747 TaskInventoryItem item = GetInventoryItem(itemID); 934 m_items.LockItemsForRead(true);
748 if (item != null) 935
936 if (m_items.ContainsKey(itemID))
749 { 937 {
750 int type = m_items[itemID].InvType; 938 int type = m_items[itemID].InvType;
939 m_items.LockItemsForRead(false);
751 if (type == 10) // Script 940 if (type == 10) // Script
752 { 941 {
753 m_part.RemoveScriptEvents(itemID);
754 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 942 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
755 } 943 }
944 m_items.LockItemsForWrite(true);
756 m_items.Remove(itemID); 945 m_items.Remove(itemID);
946 m_items.LockItemsForWrite(false);
757 m_inventorySerial++; 947 m_inventorySerial++;
758 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 948 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
759 949
760 HasInventoryChanged = true; 950 HasInventoryChanged = true;
761 m_part.ParentGroup.HasGroupChanged = true; 951 m_part.ParentGroup.HasGroupChanged = true;
762 952
763 if (!ContainsScripts()) 953 int scriptcount = 0;
954 m_items.LockItemsForRead(true);
955 foreach (TaskInventoryItem item in m_items.Values)
956 {
957 if (item.Type == 10)
958 {
959 scriptcount++;
960 }
961 }
962 m_items.LockItemsForRead(false);
963
964
965 if (scriptcount <= 0)
966 {
764 m_part.RemFlag(PrimFlags.Scripted); 967 m_part.RemFlag(PrimFlags.Scripted);
968 }
765 969
766 m_part.ScheduleFullUpdate(); 970 m_part.ScheduleFullUpdate();
767 971
768 return type; 972 return type;
769
770 } 973 }
771 else 974 else
772 { 975 {
976 m_items.LockItemsForRead(false);
773 m_log.ErrorFormat( 977 m_log.ErrorFormat(
774 "[PRIM INVENTORY]: " + 978 "[PRIM INVENTORY]: " +
775 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 979 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
776 itemID, m_part.Name, m_part.UUID, 980 itemID, m_part.Name, m_part.UUID);
777 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
778 } 981 }
779 982
780 return -1; 983 return -1;
781 } 984 }
782 985
783 private bool CreateInventoryFile() 986 private bool CreateInventoryFileName()
784 { 987 {
785 if (m_inventoryFileName == String.Empty || 988 if (m_inventoryFileName == String.Empty ||
786 m_inventoryFileNameSerial < m_inventorySerial) 989 m_inventoryFileNameSerial < m_inventorySerial)
787 { 990 {
788 // Something changed, we need to create a new file
789 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; 991 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
790 m_inventoryFileNameSerial = m_inventorySerial; 992 m_inventoryFileNameSerial = m_inventorySerial;
791
792 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
793
794 lock (m_items)
795 {
796 foreach (TaskInventoryItem item in m_items.Values)
797 {
798 UUID ownerID = item.OwnerID;
799 uint everyoneMask = 0;
800 uint baseMask = item.BasePermissions;
801 uint ownerMask = item.CurrentPermissions;
802 uint groupMask = item.GroupPermissions;
803
804 invString.AddItemStart();
805 invString.AddNameValueLine("item_id", item.ItemID.ToString());
806 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
807
808 invString.AddPermissionsStart();
809
810 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
811 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
812 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
813 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
814 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
815
816 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
817 invString.AddNameValueLine("owner_id", ownerID.ToString());
818
819 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
820
821 invString.AddNameValueLine("group_id", item.GroupID.ToString());
822 invString.AddSectionEnd();
823
824 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
825 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
826 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
827 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
828
829 invString.AddSaleStart();
830 invString.AddNameValueLine("sale_type", "not");
831 invString.AddNameValueLine("sale_price", "0");
832 invString.AddSectionEnd();
833
834 invString.AddNameValueLine("name", item.Name + "|");
835 invString.AddNameValueLine("desc", item.Description + "|");
836
837 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
838 invString.AddSectionEnd();
839 }
840 }
841
842 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
843
844 return true; 993 return true;
845 } 994 }
846 995
847 // No need to recreate, the existing file is fine
848 return false; 996 return false;
849 } 997 }
850 998
@@ -854,26 +1002,99 @@ namespace OpenSim.Region.Framework.Scenes
854 /// <param name="xferManager"></param> 1002 /// <param name="xferManager"></param>
855 public void RequestInventoryFile(IClientAPI client, IXfer xferManager) 1003 public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
856 { 1004 {
857 CreateInventoryFile(); 1005 bool changed = CreateInventoryFileName();
1006
1007 bool includeAssets = false;
1008 if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId))
1009 includeAssets = true;
1010
1011 if (m_inventoryPrivileged != includeAssets)
1012 changed = true;
1013
1014 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
1015
1016 Items.LockItemsForRead(true);
858 1017
859 if (m_inventorySerial == 0) // No inventory 1018 if (m_inventorySerial == 0) // No inventory
860 { 1019 {
861 client.SendTaskInventory(m_part.UUID, 0, new byte[0]); 1020 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1021 Items.LockItemsForRead(false);
862 return; 1022 return;
863 } 1023 }
864 1024
865 // In principle, we should only do the rest if the inventory changed; 1025 if (!changed)
866 // by sending m_inventorySerial to the client, it ought to know 1026 {
867 // that nothing changed and that it doesn't need to request the file. 1027 if (m_inventoryFileData.Length > 2)
868 // Unfortunately, it doesn't look like the client optimizes this; 1028 {
869 // the client seems to always come back and request the Xfer, 1029 xferManager.AddNewFile(m_inventoryFileName,
870 // no matter what value m_inventorySerial has. 1030 m_inventoryFileData);
1031 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
1032 Util.StringToBytes256(m_inventoryFileName));
1033
1034 Items.LockItemsForRead(false);
1035 return;
1036 }
1037 }
1038
1039 m_inventoryPrivileged = includeAssets;
1040
1041 foreach (TaskInventoryItem item in m_items.Values)
1042 {
1043 UUID ownerID = item.OwnerID;
1044 uint everyoneMask = 0;
1045 uint baseMask = item.BasePermissions;
1046 uint ownerMask = item.CurrentPermissions;
1047 uint groupMask = item.GroupPermissions;
1048
1049 invString.AddItemStart();
1050 invString.AddNameValueLine("item_id", item.ItemID.ToString());
1051 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
1052
1053 invString.AddPermissionsStart();
1054
1055 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
1056 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
1057 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
1058 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
1059 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
1060
1061 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
1062 invString.AddNameValueLine("owner_id", ownerID.ToString());
1063
1064 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
1065
1066 invString.AddNameValueLine("group_id", item.GroupID.ToString());
1067 invString.AddSectionEnd();
1068
1069 if (includeAssets)
1070 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
1071 else
1072 invString.AddNameValueLine("asset_id", UUID.Zero.ToString());
1073 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
1074 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
1075 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
1076
1077 invString.AddSaleStart();
1078 invString.AddNameValueLine("sale_type", "not");
1079 invString.AddNameValueLine("sale_price", "0");
1080 invString.AddSectionEnd();
1081
1082 invString.AddNameValueLine("name", item.Name + "|");
1083 invString.AddNameValueLine("desc", item.Description + "|");
1084
1085 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
1086 invString.AddSectionEnd();
1087 }
1088
1089 Items.LockItemsForRead(false);
1090
1091 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
871 1092
872 if (m_inventoryFileData.Length > 2) 1093 if (m_inventoryFileData.Length > 2)
873 // Add the file for Xfer 1094 {
874 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); 1095 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
1096 }
875 1097
876 // Tell the client we're ready to Xfer the file
877 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, 1098 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
878 Util.StringToBytes256(m_inventoryFileName)); 1099 Util.StringToBytes256(m_inventoryFileName));
879 } 1100 }
@@ -886,10 +1107,11 @@ namespace OpenSim.Region.Framework.Scenes
886 { 1107 {
887 if (HasInventoryChanged) 1108 if (HasInventoryChanged)
888 { 1109 {
889 HasInventoryChanged = false; 1110 Items.LockItemsForRead(true);
890 List<TaskInventoryItem> items = GetInventoryItems(); 1111 datastore.StorePrimInventory(m_part.UUID, Items.Values);
891 datastore.StorePrimInventory(m_part.UUID, items); 1112 Items.LockItemsForRead(false);
892 1113
1114 HasInventoryChanged = false;
893 } 1115 }
894 } 1116 }
895 1117
@@ -956,82 +1178,63 @@ namespace OpenSim.Region.Framework.Scenes
956 { 1178 {
957 uint mask=0x7fffffff; 1179 uint mask=0x7fffffff;
958 1180
959 lock (m_items) 1181 foreach (TaskInventoryItem item in m_items.Values)
960 { 1182 {
961 foreach (TaskInventoryItem item in m_items.Values) 1183 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
1184 mask &= ~((uint)PermissionMask.Copy >> 13);
1185 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
1186 mask &= ~((uint)PermissionMask.Transfer >> 13);
1187 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
1188 mask &= ~((uint)PermissionMask.Modify >> 13);
1189
1190 if (item.InvType == (int)InventoryType.Object)
962 { 1191 {
963 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1192 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
964 mask &= ~((uint)PermissionMask.Copy >> 13); 1193 mask &= ~((uint)PermissionMask.Copy >> 13);
965 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1194 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
966 mask &= ~((uint)PermissionMask.Transfer >> 13); 1195 mask &= ~((uint)PermissionMask.Transfer >> 13);
967 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 1196 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
968 mask &= ~((uint)PermissionMask.Modify >> 13); 1197 mask &= ~((uint)PermissionMask.Modify >> 13);
969
970 if (item.InvType != (int)InventoryType.Object)
971 {
972 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
973 mask &= ~((uint)PermissionMask.Copy >> 13);
974 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
975 mask &= ~((uint)PermissionMask.Transfer >> 13);
976 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
977 mask &= ~((uint)PermissionMask.Modify >> 13);
978 }
979 else
980 {
981 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
982 mask &= ~((uint)PermissionMask.Copy >> 13);
983 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
984 mask &= ~((uint)PermissionMask.Transfer >> 13);
985 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
986 mask &= ~((uint)PermissionMask.Modify >> 13);
987 }
988
989 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
990 mask &= ~(uint)PermissionMask.Copy;
991 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
992 mask &= ~(uint)PermissionMask.Transfer;
993 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
994 mask &= ~(uint)PermissionMask.Modify;
995 } 1198 }
1199
1200 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1201 mask &= ~(uint)PermissionMask.Copy;
1202 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1203 mask &= ~(uint)PermissionMask.Transfer;
1204 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1205 mask &= ~(uint)PermissionMask.Modify;
996 } 1206 }
997
998 return mask; 1207 return mask;
999 } 1208 }
1000 1209
1001 public void ApplyNextOwnerPermissions() 1210 public void ApplyNextOwnerPermissions()
1002 { 1211 {
1003 lock (m_items) 1212 foreach (TaskInventoryItem item in m_items.Values)
1004 { 1213 {
1005 foreach (TaskInventoryItem item in m_items.Values) 1214 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
1006 { 1215 {
1007 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 1216 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1008 { 1217 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
1009 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1218 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1010 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 1219 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
1011 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1220 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1012 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 1221 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1013 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1014 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1015 }
1016 item.CurrentPermissions &= item.NextPermissions;
1017 item.BasePermissions &= item.NextPermissions;
1018 item.EveryonePermissions &= item.NextPermissions;
1019 item.OwnerChanged = true;
1020 item.PermsMask = 0;
1021 item.PermsGranter = UUID.Zero;
1022 } 1222 }
1223 item.OwnerChanged = true;
1224 item.CurrentPermissions &= item.NextPermissions;
1225 item.BasePermissions &= item.NextPermissions;
1226 item.EveryonePermissions &= item.NextPermissions;
1227 item.PermsMask = 0;
1228 item.PermsGranter = UUID.Zero;
1023 } 1229 }
1024 } 1230 }
1025 1231
1026 public void ApplyGodPermissions(uint perms) 1232 public void ApplyGodPermissions(uint perms)
1027 { 1233 {
1028 lock (m_items) 1234 foreach (TaskInventoryItem item in m_items.Values)
1029 { 1235 {
1030 foreach (TaskInventoryItem item in m_items.Values) 1236 item.CurrentPermissions = perms;
1031 { 1237 item.BasePermissions = perms;
1032 item.CurrentPermissions = perms;
1033 item.BasePermissions = perms;
1034 }
1035 } 1238 }
1036 m_inventorySerial++; 1239 m_inventorySerial++;
1037 HasInventoryChanged = true; 1240 HasInventoryChanged = true;
@@ -1039,17 +1242,13 @@ namespace OpenSim.Region.Framework.Scenes
1039 1242
1040 public bool ContainsScripts() 1243 public bool ContainsScripts()
1041 { 1244 {
1042 lock (m_items) 1245 foreach (TaskInventoryItem item in m_items.Values)
1043 { 1246 {
1044 foreach (TaskInventoryItem item in m_items.Values) 1247 if (item.InvType == (int)InventoryType.LSL)
1045 { 1248 {
1046 if (item.InvType == (int)InventoryType.LSL) 1249 return true;
1047 {
1048 return true;
1049 }
1050 } 1250 }
1051 } 1251 }
1052
1053 return false; 1252 return false;
1054 } 1253 }
1055 1254
@@ -1057,11 +1256,8 @@ namespace OpenSim.Region.Framework.Scenes
1057 { 1256 {
1058 List<UUID> ret = new List<UUID>(); 1257 List<UUID> ret = new List<UUID>();
1059 1258
1060 lock (m_items) 1259 foreach (TaskInventoryItem item in m_items.Values)
1061 { 1260 ret.Add(item.ItemID);
1062 foreach (TaskInventoryItem item in m_items.Values)
1063 ret.Add(item.ItemID);
1064 }
1065 1261
1066 return ret; 1262 return ret;
1067 } 1263 }
@@ -1092,6 +1288,11 @@ namespace OpenSim.Region.Framework.Scenes
1092 1288
1093 public Dictionary<UUID, string> GetScriptStates() 1289 public Dictionary<UUID, string> GetScriptStates()
1094 { 1290 {
1291 return GetScriptStates(false);
1292 }
1293
1294 public Dictionary<UUID, string> GetScriptStates(bool oldIDs)
1295 {
1095 Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); 1296 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
1096 1297
1097 if (m_part.ParentGroup.Scene == null) // Group not in a scene 1298 if (m_part.ParentGroup.Scene == null) // Group not in a scene
@@ -1102,25 +1303,35 @@ namespace OpenSim.Region.Framework.Scenes
1102 if (engines == null) // No engine at all 1303 if (engines == null) // No engine at all
1103 return ret; 1304 return ret;
1104 1305
1105 List<TaskInventoryItem> scripts = GetInventoryScripts(); 1306 Items.LockItemsForRead(true);
1106 1307 foreach (TaskInventoryItem item in m_items.Values)
1107 foreach (TaskInventoryItem item in scripts)
1108 { 1308 {
1109 foreach (IScriptModule e in engines) 1309 if (item.InvType == (int)InventoryType.LSL)
1110 { 1310 {
1111 if (e != null) 1311 foreach (IScriptModule e in engines)
1112 { 1312 {
1113 string n = e.GetXMLState(item.ItemID); 1313 if (e != null)
1114 if (n != String.Empty)
1115 { 1314 {
1116 if (!ret.ContainsKey(item.ItemID)) 1315 string n = e.GetXMLState(item.ItemID);
1117 ret[item.ItemID] = n; 1316 if (n != String.Empty)
1118 break; 1317 {
1318 if (oldIDs)
1319 {
1320 if (!ret.ContainsKey(item.OldItemID))
1321 ret[item.OldItemID] = n;
1322 }
1323 else
1324 {
1325 if (!ret.ContainsKey(item.ItemID))
1326 ret[item.ItemID] = n;
1327 }
1328 break;
1329 }
1119 } 1330 }
1120 } 1331 }
1121 } 1332 }
1122 } 1333 }
1123 1334 Items.LockItemsForRead(false);
1124 return ret; 1335 return ret;
1125 } 1336 }
1126 1337
@@ -1130,21 +1341,27 @@ namespace OpenSim.Region.Framework.Scenes
1130 if (engines == null) 1341 if (engines == null)
1131 return; 1342 return;
1132 1343
1133 List<TaskInventoryItem> scripts = GetInventoryScripts();
1134 1344
1135 foreach (TaskInventoryItem item in scripts) 1345 Items.LockItemsForRead(true);
1346
1347 foreach (TaskInventoryItem item in m_items.Values)
1136 { 1348 {
1137 foreach (IScriptModule engine in engines) 1349 if (item.InvType == (int)InventoryType.LSL)
1138 { 1350 {
1139 if (engine != null) 1351 foreach (IScriptModule engine in engines)
1140 { 1352 {
1141 if (item.OwnerChanged) 1353 if (engine != null)
1142 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); 1354 {
1143 item.OwnerChanged = false; 1355 if (item.OwnerChanged)
1144 engine.ResumeScript(item.ItemID); 1356 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
1357 item.OwnerChanged = false;
1358 engine.ResumeScript(item.ItemID);
1359 }
1145 } 1360 }
1146 } 1361 }
1147 } 1362 }
1363
1364 Items.LockItemsForRead(false);
1148 } 1365 }
1149 } 1366 }
1150} 1367}