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.cs550
1 files changed, 359 insertions, 191 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 4ae53a2..8b4f0ed 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -46,6 +46,8 @@ namespace OpenSim.Region.Framework.Scenes
46 46
47 private string m_inventoryFileName = String.Empty; 47 private string m_inventoryFileName = String.Empty;
48 private int m_inventoryFileNameSerial = 0; 48 private int m_inventoryFileNameSerial = 0;
49
50 private Dictionary<UUID, ArrayList> m_scriptErrors = new Dictionary<UUID, ArrayList>();
49 51
50 /// <value> 52 /// <value>
51 /// The part to which the inventory belongs. 53 /// The part to which the inventory belongs.
@@ -82,7 +84,9 @@ namespace OpenSim.Region.Framework.Scenes
82 /// </value> 84 /// </value>
83 protected internal TaskInventoryDictionary Items 85 protected internal TaskInventoryDictionary Items
84 { 86 {
85 get { return m_items; } 87 get {
88 return m_items;
89 }
86 set 90 set
87 { 91 {
88 m_items = value; 92 m_items = value;
@@ -118,22 +122,25 @@ namespace OpenSim.Region.Framework.Scenes
118 /// <param name="linkNum">Link number for the part</param> 122 /// <param name="linkNum">Link number for the part</param>
119 public void ResetInventoryIDs() 123 public void ResetInventoryIDs()
120 { 124 {
121 lock (m_items) 125 m_items.LockItemsForWrite(true);
126
127 if (0 == Items.Count)
122 { 128 {
123 if (0 == m_items.Count) 129 m_items.LockItemsForWrite(false);
124 return; 130 return;
131 }
125 132
126 HasInventoryChanged = true; 133 HasInventoryChanged = true;
127 m_part.ParentGroup.HasGroupChanged = true; 134 m_part.ParentGroup.HasGroupChanged = true;
128 IList<TaskInventoryItem> items = GetInventoryItems(); 135 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
129 m_items.Clear(); 136 Items.Clear();
130 137
131 foreach (TaskInventoryItem item in items) 138 foreach (TaskInventoryItem item in items)
132 { 139 {
133 item.ResetIDs(m_part.UUID); 140 item.ResetIDs(m_part.UUID);
134 m_items.Add(item.ItemID, item); 141 Items.Add(item.ItemID, item);
135 }
136 } 142 }
143 m_items.LockItemsForWrite(false);
137 } 144 }
138 145
139 /// <summary> 146 /// <summary>
@@ -142,12 +149,11 @@ namespace OpenSim.Region.Framework.Scenes
142 /// <param name="ownerId"></param> 149 /// <param name="ownerId"></param>
143 public void ChangeInventoryOwner(UUID ownerId) 150 public void ChangeInventoryOwner(UUID ownerId)
144 { 151 {
145 lock (Items) 152 m_items.LockItemsForWrite(true);
153 if (0 == Items.Count)
146 { 154 {
147 if (0 == Items.Count) 155 m_items.LockItemsForWrite(false);
148 { 156 return;
149 return;
150 }
151 } 157 }
152 158
153 HasInventoryChanged = true; 159 HasInventoryChanged = true;
@@ -161,6 +167,7 @@ namespace OpenSim.Region.Framework.Scenes
161 item.OwnerID = ownerId; 167 item.OwnerID = ownerId;
162 } 168 }
163 } 169 }
170 m_items.LockItemsForWrite(false);
164 } 171 }
165 172
166 /// <summary> 173 /// <summary>
@@ -169,22 +176,24 @@ namespace OpenSim.Region.Framework.Scenes
169 /// <param name="groupID"></param> 176 /// <param name="groupID"></param>
170 public void ChangeInventoryGroup(UUID groupID) 177 public void ChangeInventoryGroup(UUID groupID)
171 { 178 {
172 lock (Items) 179 m_items.LockItemsForWrite(true);
180 if (0 == Items.Count)
173 { 181 {
174 if (0 == Items.Count) 182 m_items.LockItemsForWrite(false);
175 { 183 return;
176 return;
177 }
178 } 184 }
179 185
180 HasInventoryChanged = true; 186 HasInventoryChanged = true;
181 m_part.ParentGroup.HasGroupChanged = true; 187 m_part.ParentGroup.HasGroupChanged = true;
182 List<TaskInventoryItem> items = GetInventoryItems(); 188 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
183 foreach (TaskInventoryItem item in items) 189 foreach (TaskInventoryItem item in items)
184 { 190 {
185 if (groupID != item.GroupID) 191 if (groupID != item.GroupID)
192 {
186 item.GroupID = groupID; 193 item.GroupID = groupID;
194 }
187 } 195 }
196 m_items.LockItemsForWrite(false);
188 } 197 }
189 198
190 /// <summary> 199 /// <summary>
@@ -192,9 +201,14 @@ namespace OpenSim.Region.Framework.Scenes
192 /// </summary> 201 /// </summary>
193 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 202 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
194 { 203 {
195 List<TaskInventoryItem> scripts = GetInventoryScripts(); 204 Items.LockItemsForRead(true);
196 foreach (TaskInventoryItem item in scripts) 205 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
197 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 206 Items.LockItemsForRead(false);
207 foreach (TaskInventoryItem item in items)
208 {
209 if ((int)InventoryType.LSL == item.InvType)
210 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
211 }
198 } 212 }
199 213
200 public ArrayList GetScriptErrors(UUID itemID) 214 public ArrayList GetScriptErrors(UUID itemID)
@@ -227,9 +241,18 @@ namespace OpenSim.Region.Framework.Scenes
227 /// </param> 241 /// </param>
228 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 242 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
229 { 243 {
230 List<TaskInventoryItem> scripts = GetInventoryScripts(); 244 Items.LockItemsForRead(true);
231 foreach (TaskInventoryItem item in scripts) 245 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
232 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); 246 Items.LockItemsForRead(false);
247
248 foreach (TaskInventoryItem item in items)
249 {
250 if ((int)InventoryType.LSL == item.InvType)
251 {
252 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
253 m_part.RemoveScriptEvents(item.ItemID);
254 }
255 }
233 } 256 }
234 257
235 /// <summary> 258 /// <summary>
@@ -245,7 +268,10 @@ namespace OpenSim.Region.Framework.Scenes
245 // item.Name, item.ItemID, Name, UUID); 268 // item.Name, item.ItemID, Name, UUID);
246 269
247 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) 270 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID))
271 {
272 StoreScriptError(item.ItemID, "no permission");
248 return; 273 return;
274 }
249 275
250 m_part.AddFlag(PrimFlags.Scripted); 276 m_part.AddFlag(PrimFlags.Scripted);
251 277
@@ -254,14 +280,13 @@ namespace OpenSim.Region.Framework.Scenes
254 if (stateSource == 1 && // Prim crossing 280 if (stateSource == 1 && // Prim crossing
255 m_part.ParentGroup.Scene.m_trustBinaries) 281 m_part.ParentGroup.Scene.m_trustBinaries)
256 { 282 {
257 lock (m_items) 283 m_items.LockItemsForWrite(true);
258 { 284 m_items[item.ItemID].PermsMask = 0;
259 m_items[item.ItemID].PermsMask = 0; 285 m_items[item.ItemID].PermsGranter = UUID.Zero;
260 m_items[item.ItemID].PermsGranter = UUID.Zero; 286 m_items.LockItemsForWrite(false);
261 }
262
263 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 287 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
264 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 288 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
289 StoreScriptErrors(item.ItemID, null);
265 m_part.ParentGroup.AddActiveScriptCount(1); 290 m_part.ParentGroup.AddActiveScriptCount(1);
266 m_part.ScheduleFullUpdate(); 291 m_part.ScheduleFullUpdate();
267 return; 292 return;
@@ -270,6 +295,8 @@ namespace OpenSim.Region.Framework.Scenes
270 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); 295 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
271 if (null == asset) 296 if (null == asset)
272 { 297 {
298 string msg = String.Format("asset ID {0} could not be found", item.AssetID);
299 StoreScriptError(item.ItemID, msg);
273 m_log.ErrorFormat( 300 m_log.ErrorFormat(
274 "[PRIM INVENTORY]: " + 301 "[PRIM INVENTORY]: " +
275 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", 302 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
@@ -281,15 +308,17 @@ namespace OpenSim.Region.Framework.Scenes
281 if (m_part.ParentGroup.m_savedScriptState != null) 308 if (m_part.ParentGroup.m_savedScriptState != null)
282 RestoreSavedScriptState(item.OldItemID, item.ItemID); 309 RestoreSavedScriptState(item.OldItemID, item.ItemID);
283 310
284 lock (m_items) 311 m_items.LockItemsForWrite(true);
285 { 312
286 m_items[item.ItemID].PermsMask = 0; 313 m_items[item.ItemID].PermsMask = 0;
287 m_items[item.ItemID].PermsGranter = UUID.Zero; 314 m_items[item.ItemID].PermsGranter = UUID.Zero;
288 } 315
316 m_items.LockItemsForWrite(false);
289 317
290 string script = Utils.BytesToString(asset.Data); 318 string script = Utils.BytesToString(asset.Data);
291 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 319 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
292 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 320 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
321 StoreScriptErrors(item.ItemID, null);
293 m_part.ParentGroup.AddActiveScriptCount(1); 322 m_part.ParentGroup.AddActiveScriptCount(1);
294 m_part.ScheduleFullUpdate(); 323 m_part.ScheduleFullUpdate();
295 } 324 }
@@ -353,21 +382,145 @@ namespace OpenSim.Region.Framework.Scenes
353 382
354 /// <summary> 383 /// <summary>
355 /// Start a script which is in this prim's inventory. 384 /// Start a script which is in this prim's inventory.
385 /// Some processing may occur in the background, but this routine returns asap.
356 /// </summary> 386 /// </summary>
357 /// <param name="itemId"> 387 /// <param name="itemId">
358 /// A <see cref="UUID"/> 388 /// A <see cref="UUID"/>
359 /// </param> 389 /// </param>
360 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 390 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
361 { 391 {
362 TaskInventoryItem item = GetInventoryItem(itemId); 392 lock (m_scriptErrors)
363 if (item != null) 393 {
364 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 394 // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion
395 m_scriptErrors.Remove(itemId);
396 }
397 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
398 }
399
400 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
401 {
402 m_items.LockItemsForRead(true);
403 if (m_items.ContainsKey(itemId))
404 {
405 if (m_items.ContainsKey(itemId))
406 {
407 m_items.LockItemsForRead(false);
408 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
409 }
410 else
411 {
412 m_items.LockItemsForRead(false);
413 string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID,
414 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
415 StoreScriptError(itemId, msg);
416 m_log.ErrorFormat(
417 "[PRIM INVENTORY]: " +
418 "Couldn't start script with ID {0} since it {1}", itemId, msg);
419 }
420 }
365 else 421 else
422 {
423 m_items.LockItemsForRead(false);
424 string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID);
425 StoreScriptError(itemId, msg);
366 m_log.ErrorFormat( 426 m_log.ErrorFormat(
367 "[PRIM INVENTORY]: " + 427 "[PRIM INVENTORY]: " +
368 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 428 "Couldn't start script with ID {0} since it {1}", itemId, msg);
369 itemId, m_part.Name, m_part.UUID, 429 }
370 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 430
431 }
432
433 /// <summary>
434 /// Start a script which is in this prim's inventory and return any compilation error messages.
435 /// </summary>
436 /// <param name="itemId">
437 /// A <see cref="UUID"/>
438 /// </param>
439 public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
440 {
441 ArrayList errors;
442
443 // Indicate to CreateScriptInstanceInternal() we want it to
444 // post any compilation/loading error messages
445 lock (m_scriptErrors)
446 {
447 m_scriptErrors[itemId] = null;
448 }
449
450 // Perform compilation/loading
451 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
452
453 // Wait for and retrieve any errors
454 lock (m_scriptErrors)
455 {
456 while ((errors = m_scriptErrors[itemId]) == null)
457 {
458 if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
459 {
460 m_log.ErrorFormat(
461 "[PRIM INVENTORY]: " +
462 "timedout waiting for script {0} errors", itemId);
463 errors = m_scriptErrors[itemId];
464 if (errors == null)
465 {
466 errors = new ArrayList(1);
467 errors.Add("timedout waiting for errors");
468 }
469 break;
470 }
471 }
472 m_scriptErrors.Remove(itemId);
473 }
474 return errors;
475 }
476
477 // Signal to CreateScriptInstanceEr() that compilation/loading is complete
478 private void StoreScriptErrors(UUID itemId, ArrayList errors)
479 {
480 lock (m_scriptErrors)
481 {
482 // If compilation/loading initiated via CreateScriptInstance(),
483 // it does not want the errors, so just get out
484 if (!m_scriptErrors.ContainsKey(itemId))
485 {
486 return;
487 }
488
489 // Initiated via CreateScriptInstanceEr(), if we know what the
490 // errors are, save them and wake CreateScriptInstanceEr().
491 if (errors != null)
492 {
493 m_scriptErrors[itemId] = errors;
494 System.Threading.Monitor.PulseAll(m_scriptErrors);
495 return;
496 }
497 }
498
499 // Initiated via CreateScriptInstanceEr() but we don't know what
500 // the errors are yet, so retrieve them from the script engine.
501 // This may involve some waiting internal to GetScriptErrors().
502 errors = GetScriptErrors(itemId);
503
504 // Get a default non-null value to indicate success.
505 if (errors == null)
506 {
507 errors = new ArrayList();
508 }
509
510 // Post to CreateScriptInstanceEr() and wake it up
511 lock (m_scriptErrors)
512 {
513 m_scriptErrors[itemId] = errors;
514 System.Threading.Monitor.PulseAll(m_scriptErrors);
515 }
516 }
517
518 // Like StoreScriptErrors(), but just posts a single string message
519 private void StoreScriptError(UUID itemId, string message)
520 {
521 ArrayList errors = new ArrayList(1);
522 errors.Add(message);
523 StoreScriptErrors(itemId, errors);
371 } 524 }
372 525
373 /// <summary> 526 /// <summary>
@@ -380,15 +533,7 @@ namespace OpenSim.Region.Framework.Scenes
380 /// </param> 533 /// </param>
381 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 534 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
382 { 535 {
383 bool scriptPresent = false; 536 if (m_items.ContainsKey(itemId))
384
385 lock (m_items)
386 {
387 if (m_items.ContainsKey(itemId))
388 scriptPresent = true;
389 }
390
391 if (scriptPresent)
392 { 537 {
393 if (!sceneObjectBeingDeleted) 538 if (!sceneObjectBeingDeleted)
394 m_part.RemoveScriptEvents(itemId); 539 m_part.RemoveScriptEvents(itemId);
@@ -413,14 +558,16 @@ namespace OpenSim.Region.Framework.Scenes
413 /// <returns></returns> 558 /// <returns></returns>
414 private bool InventoryContainsName(string name) 559 private bool InventoryContainsName(string name)
415 { 560 {
416 lock (m_items) 561 m_items.LockItemsForRead(true);
562 foreach (TaskInventoryItem item in m_items.Values)
417 { 563 {
418 foreach (TaskInventoryItem item in m_items.Values) 564 if (item.Name == name)
419 { 565 {
420 if (item.Name == name) 566 m_items.LockItemsForRead(false);
421 return true; 567 return true;
422 } 568 }
423 } 569 }
570 m_items.LockItemsForRead(false);
424 return false; 571 return false;
425 } 572 }
426 573
@@ -462,8 +609,9 @@ namespace OpenSim.Region.Framework.Scenes
462 /// <param name="item"></param> 609 /// <param name="item"></param>
463 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 610 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
464 { 611 {
465 List<TaskInventoryItem> il = GetInventoryItems(); 612 m_items.LockItemsForRead(true);
466 613 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
614 m_items.LockItemsForRead(false);
467 foreach (TaskInventoryItem i in il) 615 foreach (TaskInventoryItem i in il)
468 { 616 {
469 if (i.Name == item.Name) 617 if (i.Name == item.Name)
@@ -501,14 +649,14 @@ namespace OpenSim.Region.Framework.Scenes
501 item.Name = name; 649 item.Name = name;
502 item.GroupID = m_part.GroupID; 650 item.GroupID = m_part.GroupID;
503 651
504 lock (m_items) 652 m_items.LockItemsForWrite(true);
505 m_items.Add(item.ItemID, item); 653 m_items.Add(item.ItemID, item);
506 654 m_items.LockItemsForWrite(false);
507 if (allowedDrop) 655 if (allowedDrop)
508 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 656 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
509 else 657 else
510 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 658 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
511 659
512 m_inventorySerial++; 660 m_inventorySerial++;
513 //m_inventorySerial += 2; 661 //m_inventorySerial += 2;
514 HasInventoryChanged = true; 662 HasInventoryChanged = true;
@@ -524,15 +672,15 @@ namespace OpenSim.Region.Framework.Scenes
524 /// <param name="items"></param> 672 /// <param name="items"></param>
525 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 673 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
526 { 674 {
527 lock (m_items) 675 m_items.LockItemsForWrite(true);
676 foreach (TaskInventoryItem item in items)
528 { 677 {
529 foreach (TaskInventoryItem item in items) 678 m_items.Add(item.ItemID, item);
530 { 679// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
531 m_items.Add(item.ItemID, item);
532// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
533 }
534 m_inventorySerial++;
535 } 680 }
681 m_items.LockItemsForWrite(false);
682
683 m_inventorySerial++;
536 } 684 }
537 685
538 /// <summary> 686 /// <summary>
@@ -543,10 +691,9 @@ namespace OpenSim.Region.Framework.Scenes
543 public TaskInventoryItem GetInventoryItem(UUID itemId) 691 public TaskInventoryItem GetInventoryItem(UUID itemId)
544 { 692 {
545 TaskInventoryItem item; 693 TaskInventoryItem item;
546 694 m_items.LockItemsForRead(true);
547 lock (m_items) 695 m_items.TryGetValue(itemId, out item);
548 m_items.TryGetValue(itemId, out item); 696 m_items.LockItemsForRead(false);
549
550 return item; 697 return item;
551 } 698 }
552 699
@@ -562,15 +709,16 @@ namespace OpenSim.Region.Framework.Scenes
562 { 709 {
563 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); 710 IList<TaskInventoryItem> items = new List<TaskInventoryItem>();
564 711
565 lock (m_items) 712 m_items.LockItemsForRead(true);
713
714 foreach (TaskInventoryItem item in m_items.Values)
566 { 715 {
567 foreach (TaskInventoryItem item in m_items.Values) 716 if (item.Name == name)
568 { 717 items.Add(item);
569 if (item.Name == name)
570 items.Add(item);
571 }
572 } 718 }
573 719
720 m_items.LockItemsForRead(false);
721
574 return items; 722 return items;
575 } 723 }
576 724
@@ -587,8 +735,9 @@ namespace OpenSim.Region.Framework.Scenes
587 735
588 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents) 736 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents)
589 { 737 {
590 TaskInventoryItem it = GetInventoryItem(item.ItemID); 738 m_items.LockItemsForWrite(true);
591 if (it != null) 739
740 if (m_items.ContainsKey(item.ItemID))
592 { 741 {
593 item.ParentID = m_part.UUID; 742 item.ParentID = m_part.UUID;
594 item.ParentPartID = m_part.UUID; 743 item.ParentPartID = m_part.UUID;
@@ -600,19 +749,15 @@ namespace OpenSim.Region.Framework.Scenes
600 item.GroupID = m_part.GroupID; 749 item.GroupID = m_part.GroupID;
601 750
602 if (item.AssetID == UUID.Zero) 751 if (item.AssetID == UUID.Zero)
603 item.AssetID = it.AssetID; 752 item.AssetID = m_items[item.ItemID].AssetID;
604
605 lock (m_items)
606 {
607 m_items[item.ItemID] = item;
608 m_inventorySerial++;
609 }
610 753
754 m_items[item.ItemID] = item;
755 m_inventorySerial++;
611 if (fireScriptEvents) 756 if (fireScriptEvents)
612 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 757 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
613
614 HasInventoryChanged = true; 758 HasInventoryChanged = true;
615 m_part.ParentGroup.HasGroupChanged = true; 759 m_part.ParentGroup.HasGroupChanged = true;
760 m_items.LockItemsForWrite(false);
616 return true; 761 return true;
617 } 762 }
618 else 763 else
@@ -623,8 +768,9 @@ namespace OpenSim.Region.Framework.Scenes
623 item.ItemID, m_part.Name, m_part.UUID, 768 item.ItemID, m_part.Name, m_part.UUID,
624 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 769 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
625 } 770 }
626 return false; 771 m_items.LockItemsForWrite(false);
627 772
773 return false;
628 } 774 }
629 775
630 /// <summary> 776 /// <summary>
@@ -635,37 +781,53 @@ namespace OpenSim.Region.Framework.Scenes
635 /// in this prim's inventory.</returns> 781 /// in this prim's inventory.</returns>
636 public int RemoveInventoryItem(UUID itemID) 782 public int RemoveInventoryItem(UUID itemID)
637 { 783 {
638 TaskInventoryItem item = GetInventoryItem(itemID); 784 m_items.LockItemsForRead(true);
639 if (item != null) 785
786 if (m_items.ContainsKey(itemID))
640 { 787 {
641 int type = m_items[itemID].InvType; 788 int type = m_items[itemID].InvType;
789 m_items.LockItemsForRead(false);
642 if (type == 10) // Script 790 if (type == 10) // Script
643 { 791 {
644 m_part.RemoveScriptEvents(itemID);
645 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 792 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
646 } 793 }
794 m_items.LockItemsForWrite(true);
647 m_items.Remove(itemID); 795 m_items.Remove(itemID);
796 m_items.LockItemsForWrite(false);
648 m_inventorySerial++; 797 m_inventorySerial++;
649 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 798 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
650 799
651 HasInventoryChanged = true; 800 HasInventoryChanged = true;
652 m_part.ParentGroup.HasGroupChanged = true; 801 m_part.ParentGroup.HasGroupChanged = true;
653 802
654 if (!ContainsScripts()) 803 int scriptcount = 0;
804 m_items.LockItemsForRead(true);
805 foreach (TaskInventoryItem item in m_items.Values)
806 {
807 if (item.Type == 10)
808 {
809 scriptcount++;
810 }
811 }
812 m_items.LockItemsForRead(false);
813
814
815 if (scriptcount <= 0)
816 {
655 m_part.RemFlag(PrimFlags.Scripted); 817 m_part.RemFlag(PrimFlags.Scripted);
818 }
656 819
657 m_part.ScheduleFullUpdate(); 820 m_part.ScheduleFullUpdate();
658 821
659 return type; 822 return type;
660
661 } 823 }
662 else 824 else
663 { 825 {
826 m_items.LockItemsForRead(false);
664 m_log.ErrorFormat( 827 m_log.ErrorFormat(
665 "[PRIM INVENTORY]: " + 828 "[PRIM INVENTORY]: " +
666 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 829 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
667 itemID, m_part.Name, m_part.UUID, 830 itemID, m_part.Name, m_part.UUID);
668 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
669 } 831 }
670 832
671 return -1; 833 return -1;
@@ -719,8 +881,9 @@ namespace OpenSim.Region.Framework.Scenes
719 // isn't available (such as drag from prim inventory to agent inventory) 881 // isn't available (such as drag from prim inventory to agent inventory)
720 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 882 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
721 883
722 List<TaskInventoryItem> items = GetInventoryItems(); 884 m_items.LockItemsForRead(true);
723 foreach (TaskInventoryItem item in items) 885
886 foreach (TaskInventoryItem item in m_items.Values)
724 { 887 {
725 UUID ownerID = item.OwnerID; 888 UUID ownerID = item.OwnerID;
726 uint everyoneMask = 0; 889 uint everyoneMask = 0;
@@ -764,6 +927,8 @@ namespace OpenSim.Region.Framework.Scenes
764 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 927 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
765 invString.AddSectionEnd(); 928 invString.AddSectionEnd();
766 } 929 }
930 int count = m_items.Count;
931 m_items.LockItemsForRead(false);
767 932
768 fileData = Utils.StringToBytes(invString.BuildString); 933 fileData = Utils.StringToBytes(invString.BuildString);
769 934
@@ -784,10 +949,11 @@ namespace OpenSim.Region.Framework.Scenes
784 { 949 {
785 if (HasInventoryChanged) 950 if (HasInventoryChanged)
786 { 951 {
787 HasInventoryChanged = false; 952 Items.LockItemsForRead(true);
788 List<TaskInventoryItem> items = GetInventoryItems(); 953 datastore.StorePrimInventory(m_part.UUID, Items.Values);
789 datastore.StorePrimInventory(m_part.UUID, items); 954 Items.LockItemsForRead(false);
790 955
956 HasInventoryChanged = false;
791 } 957 }
792 } 958 }
793 959
@@ -854,89 +1020,75 @@ namespace OpenSim.Region.Framework.Scenes
854 { 1020 {
855 uint mask=0x7fffffff; 1021 uint mask=0x7fffffff;
856 1022
857 lock (m_items) 1023 foreach (TaskInventoryItem item in m_items.Values)
858 { 1024 {
859 foreach (TaskInventoryItem item in m_items.Values) 1025 if (item.InvType != (int)InventoryType.Object)
860 { 1026 {
861 if (item.InvType != (int)InventoryType.Object) 1027 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
862 { 1028 mask &= ~((uint)PermissionMask.Copy >> 13);
863 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1029 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
864 mask &= ~((uint)PermissionMask.Copy >> 13); 1030 mask &= ~((uint)PermissionMask.Transfer >> 13);
865 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1031 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
866 mask &= ~((uint)PermissionMask.Transfer >> 13); 1032 mask &= ~((uint)PermissionMask.Modify >> 13);
867 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
868 mask &= ~((uint)PermissionMask.Modify >> 13);
869 }
870 else
871 {
872 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
873 mask &= ~((uint)PermissionMask.Copy >> 13);
874 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
875 mask &= ~((uint)PermissionMask.Transfer >> 13);
876 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
877 mask &= ~((uint)PermissionMask.Modify >> 13);
878 }
879
880 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
881 mask &= ~(uint)PermissionMask.Copy;
882 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
883 mask &= ~(uint)PermissionMask.Transfer;
884 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
885 mask &= ~(uint)PermissionMask.Modify;
886 } 1033 }
1034 else
1035 {
1036 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1037 mask &= ~((uint)PermissionMask.Copy >> 13);
1038 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1039 mask &= ~((uint)PermissionMask.Transfer >> 13);
1040 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1041 mask &= ~((uint)PermissionMask.Modify >> 13);
1042 }
1043
1044 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1045 mask &= ~(uint)PermissionMask.Copy;
1046 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1047 mask &= ~(uint)PermissionMask.Transfer;
1048 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1049 mask &= ~(uint)PermissionMask.Modify;
887 } 1050 }
888
889 return mask; 1051 return mask;
890 } 1052 }
891 1053
892 public void ApplyNextOwnerPermissions() 1054 public void ApplyNextOwnerPermissions()
893 { 1055 {
894 lock (m_items) 1056 foreach (TaskInventoryItem item in m_items.Values)
895 { 1057 {
896 foreach (TaskInventoryItem item in m_items.Values) 1058 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
897 { 1059 {
898 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 1060 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
899 { 1061 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
900 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1062 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
901 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 1063 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
902 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1064 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
903 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 1065 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
904 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
905 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
906 }
907 item.CurrentPermissions &= item.NextPermissions;
908 item.BasePermissions &= item.NextPermissions;
909 item.EveryonePermissions &= item.NextPermissions;
910 item.OwnerChanged = true;
911 } 1066 }
1067 item.OwnerChanged = true;
1068 item.CurrentPermissions &= item.NextPermissions;
1069 item.BasePermissions &= item.NextPermissions;
1070 item.EveryonePermissions &= item.NextPermissions;
912 } 1071 }
913 } 1072 }
914 1073
915 public void ApplyGodPermissions(uint perms) 1074 public void ApplyGodPermissions(uint perms)
916 { 1075 {
917 lock (m_items) 1076 foreach (TaskInventoryItem item in m_items.Values)
918 { 1077 {
919 foreach (TaskInventoryItem item in m_items.Values) 1078 item.CurrentPermissions = perms;
920 { 1079 item.BasePermissions = perms;
921 item.CurrentPermissions = perms;
922 item.BasePermissions = perms;
923 }
924 } 1080 }
925 } 1081 }
926 1082
927 public bool ContainsScripts() 1083 public bool ContainsScripts()
928 { 1084 {
929 lock (m_items) 1085 foreach (TaskInventoryItem item in m_items.Values)
930 { 1086 {
931 foreach (TaskInventoryItem item in m_items.Values) 1087 if (item.InvType == (int)InventoryType.LSL)
932 { 1088 {
933 if (item.InvType == (int)InventoryType.LSL) 1089 return true;
934 {
935 return true;
936 }
937 } 1090 }
938 } 1091 }
939
940 return false; 1092 return false;
941 } 1093 }
942 1094
@@ -944,11 +1096,8 @@ namespace OpenSim.Region.Framework.Scenes
944 { 1096 {
945 List<UUID> ret = new List<UUID>(); 1097 List<UUID> ret = new List<UUID>();
946 1098
947 lock (m_items) 1099 foreach (TaskInventoryItem item in m_items.Values)
948 { 1100 ret.Add(item.ItemID);
949 foreach (TaskInventoryItem item in m_items.Values)
950 ret.Add(item.ItemID);
951 }
952 1101
953 return ret; 1102 return ret;
954 } 1103 }
@@ -979,31 +1128,44 @@ namespace OpenSim.Region.Framework.Scenes
979 1128
980 public Dictionary<UUID, string> GetScriptStates() 1129 public Dictionary<UUID, string> GetScriptStates()
981 { 1130 {
1131 return GetScriptStates(false);
1132 }
1133
1134 public Dictionary<UUID, string> GetScriptStates(bool oldIDs)
1135 {
982 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); 1136 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
983 1137
984 Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); 1138 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
985 if (engines == null) // No engine at all 1139 if (engines == null) // No engine at all
986 return ret; 1140 return ret;
987 1141
988 List<TaskInventoryItem> scripts = GetInventoryScripts(); 1142 foreach (TaskInventoryItem item in m_items.Values)
989
990 foreach (TaskInventoryItem item in scripts)
991 { 1143 {
992 foreach (IScriptModule e in engines) 1144 if (item.InvType == (int)InventoryType.LSL)
993 { 1145 {
994 if (e != null) 1146 foreach (IScriptModule e in engines)
995 { 1147 {
996 string n = e.GetXMLState(item.ItemID); 1148 if (e != null)
997 if (n != String.Empty)
998 { 1149 {
999 if (!ret.ContainsKey(item.ItemID)) 1150 string n = e.GetXMLState(item.ItemID);
1000 ret[item.ItemID] = n; 1151 if (n != String.Empty)
1001 break; 1152 {
1153 if (oldIDs)
1154 {
1155 if (!ret.ContainsKey(item.OldItemID))
1156 ret[item.OldItemID] = n;
1157 }
1158 else
1159 {
1160 if (!ret.ContainsKey(item.ItemID))
1161 ret[item.ItemID] = n;
1162 }
1163 break;
1164 }
1002 } 1165 }
1003 } 1166 }
1004 } 1167 }
1005 } 1168 }
1006
1007 return ret; 1169 return ret;
1008 } 1170 }
1009 1171
@@ -1013,21 +1175,27 @@ namespace OpenSim.Region.Framework.Scenes
1013 if (engines == null) 1175 if (engines == null)
1014 return; 1176 return;
1015 1177
1016 List<TaskInventoryItem> scripts = GetInventoryScripts();
1017 1178
1018 foreach (TaskInventoryItem item in scripts) 1179 Items.LockItemsForRead(true);
1180
1181 foreach (TaskInventoryItem item in m_items.Values)
1019 { 1182 {
1020 foreach (IScriptModule engine in engines) 1183 if (item.InvType == (int)InventoryType.LSL)
1021 { 1184 {
1022 if (engine != null) 1185 foreach (IScriptModule engine in engines)
1023 { 1186 {
1024 if (item.OwnerChanged) 1187 if (engine != null)
1025 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); 1188 {
1026 item.OwnerChanged = false; 1189 if (item.OwnerChanged)
1027 engine.ResumeScript(item.ItemID); 1190 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
1191 item.OwnerChanged = false;
1192 engine.ResumeScript(item.ItemID);
1193 }
1028 } 1194 }
1029 } 1195 }
1030 } 1196 }
1197
1198 Items.LockItemsForRead(false);
1031 } 1199 }
1032 1200
1033 } 1201 }