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.cs553
1 files changed, 359 insertions, 194 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 53ddb5d..2de439b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -47,6 +47,8 @@ namespace OpenSim.Region.Framework.Scenes
47 47
48 private string m_inventoryFileName = String.Empty; 48 private string m_inventoryFileName = String.Empty;
49 private int m_inventoryFileNameSerial = 0; 49 private int m_inventoryFileNameSerial = 0;
50
51 private Dictionary<UUID, ArrayList> m_scriptErrors = new Dictionary<UUID, ArrayList>();
50 52
51 /// <value> 53 /// <value>
52 /// The part to which the inventory belongs. 54 /// The part to which the inventory belongs.
@@ -83,7 +85,9 @@ namespace OpenSim.Region.Framework.Scenes
83 /// </value> 85 /// </value>
84 protected internal TaskInventoryDictionary Items 86 protected internal TaskInventoryDictionary Items
85 { 87 {
86 get { return m_items; } 88 get {
89 return m_items;
90 }
87 set 91 set
88 { 92 {
89 m_items = value; 93 m_items = value;
@@ -119,25 +123,25 @@ namespace OpenSim.Region.Framework.Scenes
119 /// <param name="linkNum">Link number for the part</param> 123 /// <param name="linkNum">Link number for the part</param>
120 public void ResetInventoryIDs() 124 public void ResetInventoryIDs()
121 { 125 {
122 if (null == m_part || null == m_part.ParentGroup) 126 m_items.LockItemsForWrite(true);
123 return; 127
124 128 if (Items.Count == 0)
125 lock (m_items)
126 { 129 {
127 if (0 == m_items.Count) 130 m_items.LockItemsForWrite(false);
128 return; 131 return;
132 }
129 133
130 HasInventoryChanged = true; 134 HasInventoryChanged = true;
131 m_part.ParentGroup.HasGroupChanged = true; 135 m_part.ParentGroup.HasGroupChanged = true;
132 IList<TaskInventoryItem> items = GetInventoryItems(); 136 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
133 m_items.Clear(); 137 Items.Clear();
134 138
135 foreach (TaskInventoryItem item in items) 139 foreach (TaskInventoryItem item in items)
136 { 140 {
137 item.ResetIDs(m_part.UUID); 141 item.ResetIDs(m_part.UUID);
138 m_items.Add(item.ItemID, item); 142 Items.Add(item.ItemID, item);
139 }
140 } 143 }
144 m_items.LockItemsForWrite(false);
141 } 145 }
142 146
143 /// <summary> 147 /// <summary>
@@ -146,12 +150,11 @@ namespace OpenSim.Region.Framework.Scenes
146 /// <param name="ownerId"></param> 150 /// <param name="ownerId"></param>
147 public void ChangeInventoryOwner(UUID ownerId) 151 public void ChangeInventoryOwner(UUID ownerId)
148 { 152 {
149 lock (Items) 153 m_items.LockItemsForWrite(true);
154 if (0 == Items.Count)
150 { 155 {
151 if (0 == Items.Count) 156 m_items.LockItemsForWrite(false);
152 { 157 return;
153 return;
154 }
155 } 158 }
156 159
157 HasInventoryChanged = true; 160 HasInventoryChanged = true;
@@ -165,6 +168,7 @@ namespace OpenSim.Region.Framework.Scenes
165 item.OwnerID = ownerId; 168 item.OwnerID = ownerId;
166 } 169 }
167 } 170 }
171 m_items.LockItemsForWrite(false);
168 } 172 }
169 173
170 /// <summary> 174 /// <summary>
@@ -173,22 +177,24 @@ namespace OpenSim.Region.Framework.Scenes
173 /// <param name="groupID"></param> 177 /// <param name="groupID"></param>
174 public void ChangeInventoryGroup(UUID groupID) 178 public void ChangeInventoryGroup(UUID groupID)
175 { 179 {
176 lock (Items) 180 m_items.LockItemsForWrite(true);
181 if (0 == Items.Count)
177 { 182 {
178 if (0 == Items.Count) 183 m_items.LockItemsForWrite(false);
179 { 184 return;
180 return;
181 }
182 } 185 }
183 186
184 HasInventoryChanged = true; 187 HasInventoryChanged = true;
185 m_part.ParentGroup.HasGroupChanged = true; 188 m_part.ParentGroup.HasGroupChanged = true;
186 List<TaskInventoryItem> items = GetInventoryItems(); 189 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
187 foreach (TaskInventoryItem item in items) 190 foreach (TaskInventoryItem item in items)
188 { 191 {
189 if (groupID != item.GroupID) 192 if (groupID != item.GroupID)
193 {
190 item.GroupID = groupID; 194 item.GroupID = groupID;
195 }
191 } 196 }
197 m_items.LockItemsForWrite(false);
192 } 198 }
193 199
194 /// <summary> 200 /// <summary>
@@ -196,9 +202,14 @@ namespace OpenSim.Region.Framework.Scenes
196 /// </summary> 202 /// </summary>
197 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 203 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
198 { 204 {
199 List<TaskInventoryItem> scripts = GetInventoryScripts(); 205 Items.LockItemsForRead(true);
200 foreach (TaskInventoryItem item in scripts) 206 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
201 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 207 Items.LockItemsForRead(false);
208 foreach (TaskInventoryItem item in items)
209 {
210 if ((int)InventoryType.LSL == item.InvType)
211 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
212 }
202 } 213 }
203 214
204 public ArrayList GetScriptErrors(UUID itemID) 215 public ArrayList GetScriptErrors(UUID itemID)
@@ -231,9 +242,18 @@ namespace OpenSim.Region.Framework.Scenes
231 /// </param> 242 /// </param>
232 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 243 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
233 { 244 {
234 List<TaskInventoryItem> scripts = GetInventoryScripts(); 245 Items.LockItemsForRead(true);
235 foreach (TaskInventoryItem item in scripts) 246 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
236 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); 247 Items.LockItemsForRead(false);
248
249 foreach (TaskInventoryItem item in items)
250 {
251 if ((int)InventoryType.LSL == item.InvType)
252 {
253 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
254 m_part.RemoveScriptEvents(item.ItemID);
255 }
256 }
237 } 257 }
238 258
239 /// <summary> 259 /// <summary>
@@ -249,7 +269,10 @@ namespace OpenSim.Region.Framework.Scenes
249 // item.Name, item.ItemID, Name, UUID); 269 // item.Name, item.ItemID, Name, UUID);
250 270
251 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) 271 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID))
272 {
273 StoreScriptError(item.ItemID, "no permission");
252 return; 274 return;
275 }
253 276
254 m_part.AddFlag(PrimFlags.Scripted); 277 m_part.AddFlag(PrimFlags.Scripted);
255 278
@@ -258,14 +281,13 @@ namespace OpenSim.Region.Framework.Scenes
258 if (stateSource == 2 && // Prim crossing 281 if (stateSource == 2 && // Prim crossing
259 m_part.ParentGroup.Scene.m_trustBinaries) 282 m_part.ParentGroup.Scene.m_trustBinaries)
260 { 283 {
261 lock (m_items) 284 m_items.LockItemsForWrite(true);
262 { 285 m_items[item.ItemID].PermsMask = 0;
263 m_items[item.ItemID].PermsMask = 0; 286 m_items[item.ItemID].PermsGranter = UUID.Zero;
264 m_items[item.ItemID].PermsGranter = UUID.Zero; 287 m_items.LockItemsForWrite(false);
265 }
266
267 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 288 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
268 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 289 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
290 StoreScriptErrors(item.ItemID, null);
269 m_part.ParentGroup.AddActiveScriptCount(1); 291 m_part.ParentGroup.AddActiveScriptCount(1);
270 m_part.ScheduleFullUpdate(); 292 m_part.ScheduleFullUpdate();
271 return; 293 return;
@@ -274,6 +296,8 @@ namespace OpenSim.Region.Framework.Scenes
274 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); 296 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
275 if (null == asset) 297 if (null == asset)
276 { 298 {
299 string msg = String.Format("asset ID {0} could not be found", item.AssetID);
300 StoreScriptError(item.ItemID, msg);
277 m_log.ErrorFormat( 301 m_log.ErrorFormat(
278 "[PRIM INVENTORY]: " + 302 "[PRIM INVENTORY]: " +
279 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", 303 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
@@ -285,15 +309,17 @@ namespace OpenSim.Region.Framework.Scenes
285 if (m_part.ParentGroup.m_savedScriptState != null) 309 if (m_part.ParentGroup.m_savedScriptState != null)
286 RestoreSavedScriptState(item.OldItemID, item.ItemID); 310 RestoreSavedScriptState(item.OldItemID, item.ItemID);
287 311
288 lock (m_items) 312 m_items.LockItemsForWrite(true);
289 { 313
290 m_items[item.ItemID].PermsMask = 0; 314 m_items[item.ItemID].PermsMask = 0;
291 m_items[item.ItemID].PermsGranter = UUID.Zero; 315 m_items[item.ItemID].PermsGranter = UUID.Zero;
292 } 316
317 m_items.LockItemsForWrite(false);
293 318
294 string script = Utils.BytesToString(asset.Data); 319 string script = Utils.BytesToString(asset.Data);
295 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 320 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
296 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 321 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
322 StoreScriptErrors(item.ItemID, null);
297 m_part.ParentGroup.AddActiveScriptCount(1); 323 m_part.ParentGroup.AddActiveScriptCount(1);
298 m_part.ScheduleFullUpdate(); 324 m_part.ScheduleFullUpdate();
299 } 325 }
@@ -357,21 +383,145 @@ namespace OpenSim.Region.Framework.Scenes
357 383
358 /// <summary> 384 /// <summary>
359 /// Start a script which is in this prim's inventory. 385 /// Start a script which is in this prim's inventory.
386 /// Some processing may occur in the background, but this routine returns asap.
360 /// </summary> 387 /// </summary>
361 /// <param name="itemId"> 388 /// <param name="itemId">
362 /// A <see cref="UUID"/> 389 /// A <see cref="UUID"/>
363 /// </param> 390 /// </param>
364 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 391 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
365 { 392 {
366 TaskInventoryItem item = GetInventoryItem(itemId); 393 lock (m_scriptErrors)
367 if (item != null) 394 {
368 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 395 // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion
396 m_scriptErrors.Remove(itemId);
397 }
398 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
399 }
400
401 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
402 {
403 m_items.LockItemsForRead(true);
404 if (m_items.ContainsKey(itemId))
405 {
406 if (m_items.ContainsKey(itemId))
407 {
408 m_items.LockItemsForRead(false);
409 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
410 }
411 else
412 {
413 m_items.LockItemsForRead(false);
414 string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID,
415 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
416 StoreScriptError(itemId, msg);
417 m_log.ErrorFormat(
418 "[PRIM INVENTORY]: " +
419 "Couldn't start script with ID {0} since it {1}", itemId, msg);
420 }
421 }
369 else 422 else
423 {
424 m_items.LockItemsForRead(false);
425 string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID);
426 StoreScriptError(itemId, msg);
370 m_log.ErrorFormat( 427 m_log.ErrorFormat(
371 "[PRIM INVENTORY]: " + 428 "[PRIM INVENTORY]: " +
372 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 429 "Couldn't start script with ID {0} since it {1}", itemId, msg);
373 itemId, m_part.Name, m_part.UUID, 430 }
374 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 431
432 }
433
434 /// <summary>
435 /// Start a script which is in this prim's inventory and return any compilation error messages.
436 /// </summary>
437 /// <param name="itemId">
438 /// A <see cref="UUID"/>
439 /// </param>
440 public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
441 {
442 ArrayList errors;
443
444 // Indicate to CreateScriptInstanceInternal() we want it to
445 // post any compilation/loading error messages
446 lock (m_scriptErrors)
447 {
448 m_scriptErrors[itemId] = null;
449 }
450
451 // Perform compilation/loading
452 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
453
454 // Wait for and retrieve any errors
455 lock (m_scriptErrors)
456 {
457 while ((errors = m_scriptErrors[itemId]) == null)
458 {
459 if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
460 {
461 m_log.ErrorFormat(
462 "[PRIM INVENTORY]: " +
463 "timedout waiting for script {0} errors", itemId);
464 errors = m_scriptErrors[itemId];
465 if (errors == null)
466 {
467 errors = new ArrayList(1);
468 errors.Add("timedout waiting for errors");
469 }
470 break;
471 }
472 }
473 m_scriptErrors.Remove(itemId);
474 }
475 return errors;
476 }
477
478 // Signal to CreateScriptInstanceEr() that compilation/loading is complete
479 private void StoreScriptErrors(UUID itemId, ArrayList errors)
480 {
481 lock (m_scriptErrors)
482 {
483 // If compilation/loading initiated via CreateScriptInstance(),
484 // it does not want the errors, so just get out
485 if (!m_scriptErrors.ContainsKey(itemId))
486 {
487 return;
488 }
489
490 // Initiated via CreateScriptInstanceEr(), if we know what the
491 // errors are, save them and wake CreateScriptInstanceEr().
492 if (errors != null)
493 {
494 m_scriptErrors[itemId] = errors;
495 System.Threading.Monitor.PulseAll(m_scriptErrors);
496 return;
497 }
498 }
499
500 // Initiated via CreateScriptInstanceEr() but we don't know what
501 // the errors are yet, so retrieve them from the script engine.
502 // This may involve some waiting internal to GetScriptErrors().
503 errors = GetScriptErrors(itemId);
504
505 // Get a default non-null value to indicate success.
506 if (errors == null)
507 {
508 errors = new ArrayList();
509 }
510
511 // Post to CreateScriptInstanceEr() and wake it up
512 lock (m_scriptErrors)
513 {
514 m_scriptErrors[itemId] = errors;
515 System.Threading.Monitor.PulseAll(m_scriptErrors);
516 }
517 }
518
519 // Like StoreScriptErrors(), but just posts a single string message
520 private void StoreScriptError(UUID itemId, string message)
521 {
522 ArrayList errors = new ArrayList(1);
523 errors.Add(message);
524 StoreScriptErrors(itemId, errors);
375 } 525 }
376 526
377 /// <summary> 527 /// <summary>
@@ -384,15 +534,7 @@ namespace OpenSim.Region.Framework.Scenes
384 /// </param> 534 /// </param>
385 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 535 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
386 { 536 {
387 bool scriptPresent = false; 537 if (m_items.ContainsKey(itemId))
388
389 lock (m_items)
390 {
391 if (m_items.ContainsKey(itemId))
392 scriptPresent = true;
393 }
394
395 if (scriptPresent)
396 { 538 {
397 if (!sceneObjectBeingDeleted) 539 if (!sceneObjectBeingDeleted)
398 m_part.RemoveScriptEvents(itemId); 540 m_part.RemoveScriptEvents(itemId);
@@ -417,14 +559,16 @@ namespace OpenSim.Region.Framework.Scenes
417 /// <returns></returns> 559 /// <returns></returns>
418 private bool InventoryContainsName(string name) 560 private bool InventoryContainsName(string name)
419 { 561 {
420 lock (m_items) 562 m_items.LockItemsForRead(true);
563 foreach (TaskInventoryItem item in m_items.Values)
421 { 564 {
422 foreach (TaskInventoryItem item in m_items.Values) 565 if (item.Name == name)
423 { 566 {
424 if (item.Name == name) 567 m_items.LockItemsForRead(false);
425 return true; 568 return true;
426 } 569 }
427 } 570 }
571 m_items.LockItemsForRead(false);
428 return false; 572 return false;
429 } 573 }
430 574
@@ -466,8 +610,9 @@ namespace OpenSim.Region.Framework.Scenes
466 /// <param name="item"></param> 610 /// <param name="item"></param>
467 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 611 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
468 { 612 {
469 List<TaskInventoryItem> il = GetInventoryItems(); 613 m_items.LockItemsForRead(true);
470 614 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
615 m_items.LockItemsForRead(false);
471 foreach (TaskInventoryItem i in il) 616 foreach (TaskInventoryItem i in il)
472 { 617 {
473 if (i.Name == item.Name) 618 if (i.Name == item.Name)
@@ -505,14 +650,14 @@ namespace OpenSim.Region.Framework.Scenes
505 item.Name = name; 650 item.Name = name;
506 item.GroupID = m_part.GroupID; 651 item.GroupID = m_part.GroupID;
507 652
508 lock (m_items) 653 m_items.LockItemsForWrite(true);
509 m_items.Add(item.ItemID, item); 654 m_items.Add(item.ItemID, item);
510 655 m_items.LockItemsForWrite(false);
511 if (allowedDrop) 656 if (allowedDrop)
512 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 657 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
513 else 658 else
514 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 659 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
515 660
516 m_inventorySerial++; 661 m_inventorySerial++;
517 //m_inventorySerial += 2; 662 //m_inventorySerial += 2;
518 HasInventoryChanged = true; 663 HasInventoryChanged = true;
@@ -528,15 +673,15 @@ namespace OpenSim.Region.Framework.Scenes
528 /// <param name="items"></param> 673 /// <param name="items"></param>
529 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 674 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
530 { 675 {
531 lock (m_items) 676 m_items.LockItemsForWrite(true);
677 foreach (TaskInventoryItem item in items)
532 { 678 {
533 foreach (TaskInventoryItem item in items) 679 m_items.Add(item.ItemID, item);
534 { 680// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
535 m_items.Add(item.ItemID, item);
536// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
537 }
538 m_inventorySerial++;
539 } 681 }
682 m_items.LockItemsForWrite(false);
683
684 m_inventorySerial++;
540 } 685 }
541 686
542 /// <summary> 687 /// <summary>
@@ -547,10 +692,9 @@ namespace OpenSim.Region.Framework.Scenes
547 public TaskInventoryItem GetInventoryItem(UUID itemId) 692 public TaskInventoryItem GetInventoryItem(UUID itemId)
548 { 693 {
549 TaskInventoryItem item; 694 TaskInventoryItem item;
550 695 m_items.LockItemsForRead(true);
551 lock (m_items) 696 m_items.TryGetValue(itemId, out item);
552 m_items.TryGetValue(itemId, out item); 697 m_items.LockItemsForRead(false);
553
554 return item; 698 return item;
555 } 699 }
556 700
@@ -566,15 +710,16 @@ namespace OpenSim.Region.Framework.Scenes
566 { 710 {
567 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); 711 IList<TaskInventoryItem> items = new List<TaskInventoryItem>();
568 712
569 lock (m_items) 713 m_items.LockItemsForRead(true);
714
715 foreach (TaskInventoryItem item in m_items.Values)
570 { 716 {
571 foreach (TaskInventoryItem item in m_items.Values) 717 if (item.Name == name)
572 { 718 items.Add(item);
573 if (item.Name == name)
574 items.Add(item);
575 }
576 } 719 }
577 720
721 m_items.LockItemsForRead(false);
722
578 return items; 723 return items;
579 } 724 }
580 725
@@ -655,8 +800,9 @@ namespace OpenSim.Region.Framework.Scenes
655 800
656 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents) 801 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents)
657 { 802 {
658 TaskInventoryItem it = GetInventoryItem(item.ItemID); 803 m_items.LockItemsForWrite(true);
659 if (it != null) 804
805 if (m_items.ContainsKey(item.ItemID))
660 { 806 {
661 item.ParentID = m_part.UUID; 807 item.ParentID = m_part.UUID;
662 item.ParentPartID = m_part.UUID; 808 item.ParentPartID = m_part.UUID;
@@ -668,19 +814,15 @@ namespace OpenSim.Region.Framework.Scenes
668 item.GroupID = m_part.GroupID; 814 item.GroupID = m_part.GroupID;
669 815
670 if (item.AssetID == UUID.Zero) 816 if (item.AssetID == UUID.Zero)
671 item.AssetID = it.AssetID; 817 item.AssetID = m_items[item.ItemID].AssetID;
672
673 lock (m_items)
674 {
675 m_items[item.ItemID] = item;
676 m_inventorySerial++;
677 }
678 818
819 m_items[item.ItemID] = item;
820 m_inventorySerial++;
679 if (fireScriptEvents) 821 if (fireScriptEvents)
680 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 822 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
681
682 HasInventoryChanged = true; 823 HasInventoryChanged = true;
683 m_part.ParentGroup.HasGroupChanged = true; 824 m_part.ParentGroup.HasGroupChanged = true;
825 m_items.LockItemsForWrite(false);
684 return true; 826 return true;
685 } 827 }
686 else 828 else
@@ -691,8 +833,9 @@ namespace OpenSim.Region.Framework.Scenes
691 item.ItemID, m_part.Name, m_part.UUID, 833 item.ItemID, m_part.Name, m_part.UUID,
692 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 834 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
693 } 835 }
694 return false; 836 m_items.LockItemsForWrite(false);
695 837
838 return false;
696 } 839 }
697 840
698 /// <summary> 841 /// <summary>
@@ -703,37 +846,53 @@ namespace OpenSim.Region.Framework.Scenes
703 /// in this prim's inventory.</returns> 846 /// in this prim's inventory.</returns>
704 public int RemoveInventoryItem(UUID itemID) 847 public int RemoveInventoryItem(UUID itemID)
705 { 848 {
706 TaskInventoryItem item = GetInventoryItem(itemID); 849 m_items.LockItemsForRead(true);
707 if (item != null) 850
851 if (m_items.ContainsKey(itemID))
708 { 852 {
709 int type = m_items[itemID].InvType; 853 int type = m_items[itemID].InvType;
854 m_items.LockItemsForRead(false);
710 if (type == 10) // Script 855 if (type == 10) // Script
711 { 856 {
712 m_part.RemoveScriptEvents(itemID);
713 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 857 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
714 } 858 }
859 m_items.LockItemsForWrite(true);
715 m_items.Remove(itemID); 860 m_items.Remove(itemID);
861 m_items.LockItemsForWrite(false);
716 m_inventorySerial++; 862 m_inventorySerial++;
717 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 863 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
718 864
719 HasInventoryChanged = true; 865 HasInventoryChanged = true;
720 m_part.ParentGroup.HasGroupChanged = true; 866 m_part.ParentGroup.HasGroupChanged = true;
721 867
722 if (!ContainsScripts()) 868 int scriptcount = 0;
869 m_items.LockItemsForRead(true);
870 foreach (TaskInventoryItem item in m_items.Values)
871 {
872 if (item.Type == 10)
873 {
874 scriptcount++;
875 }
876 }
877 m_items.LockItemsForRead(false);
878
879
880 if (scriptcount <= 0)
881 {
723 m_part.RemFlag(PrimFlags.Scripted); 882 m_part.RemFlag(PrimFlags.Scripted);
883 }
724 884
725 m_part.ScheduleFullUpdate(); 885 m_part.ScheduleFullUpdate();
726 886
727 return type; 887 return type;
728
729 } 888 }
730 else 889 else
731 { 890 {
891 m_items.LockItemsForRead(false);
732 m_log.ErrorFormat( 892 m_log.ErrorFormat(
733 "[PRIM INVENTORY]: " + 893 "[PRIM INVENTORY]: " +
734 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 894 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
735 itemID, m_part.Name, m_part.UUID, 895 itemID, m_part.Name, m_part.UUID);
736 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
737 } 896 }
738 897
739 return -1; 898 return -1;
@@ -787,8 +946,9 @@ namespace OpenSim.Region.Framework.Scenes
787 // isn't available (such as drag from prim inventory to agent inventory) 946 // isn't available (such as drag from prim inventory to agent inventory)
788 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 947 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
789 948
790 List<TaskInventoryItem> items = GetInventoryItems(); 949 m_items.LockItemsForRead(true);
791 foreach (TaskInventoryItem item in items) 950
951 foreach (TaskInventoryItem item in m_items.Values)
792 { 952 {
793 UUID ownerID = item.OwnerID; 953 UUID ownerID = item.OwnerID;
794 uint everyoneMask = 0; 954 uint everyoneMask = 0;
@@ -832,6 +992,8 @@ namespace OpenSim.Region.Framework.Scenes
832 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 992 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
833 invString.AddSectionEnd(); 993 invString.AddSectionEnd();
834 } 994 }
995 int count = m_items.Count;
996 m_items.LockItemsForRead(false);
835 997
836 fileData = Utils.StringToBytes(invString.BuildString); 998 fileData = Utils.StringToBytes(invString.BuildString);
837 999
@@ -852,10 +1014,11 @@ namespace OpenSim.Region.Framework.Scenes
852 { 1014 {
853 if (HasInventoryChanged) 1015 if (HasInventoryChanged)
854 { 1016 {
855 HasInventoryChanged = false; 1017 Items.LockItemsForRead(true);
856 List<TaskInventoryItem> items = GetInventoryItems(); 1018 datastore.StorePrimInventory(m_part.UUID, Items.Values);
857 datastore.StorePrimInventory(m_part.UUID, items); 1019 Items.LockItemsForRead(false);
858 1020
1021 HasInventoryChanged = false;
859 } 1022 }
860 } 1023 }
861 1024
@@ -922,89 +1085,75 @@ namespace OpenSim.Region.Framework.Scenes
922 { 1085 {
923 uint mask=0x7fffffff; 1086 uint mask=0x7fffffff;
924 1087
925 lock (m_items) 1088 foreach (TaskInventoryItem item in m_items.Values)
926 { 1089 {
927 foreach (TaskInventoryItem item in m_items.Values) 1090 if (item.InvType != (int)InventoryType.Object)
928 { 1091 {
929 if (item.InvType != (int)InventoryType.Object) 1092 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
930 { 1093 mask &= ~((uint)PermissionMask.Copy >> 13);
931 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1094 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
932 mask &= ~((uint)PermissionMask.Copy >> 13); 1095 mask &= ~((uint)PermissionMask.Transfer >> 13);
933 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1096 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
934 mask &= ~((uint)PermissionMask.Transfer >> 13); 1097 mask &= ~((uint)PermissionMask.Modify >> 13);
935 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 1098 }
936 mask &= ~((uint)PermissionMask.Modify >> 13); 1099 else
937 } 1100 {
938 else 1101 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
939 { 1102 mask &= ~((uint)PermissionMask.Copy >> 13);
940 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1103 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
941 mask &= ~((uint)PermissionMask.Copy >> 13); 1104 mask &= ~((uint)PermissionMask.Transfer >> 13);
942 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1105 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
943 mask &= ~((uint)PermissionMask.Transfer >> 13); 1106 mask &= ~((uint)PermissionMask.Modify >> 13);
944 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
945 mask &= ~((uint)PermissionMask.Modify >> 13);
946 }
947
948 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
949 mask &= ~(uint)PermissionMask.Copy;
950 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
951 mask &= ~(uint)PermissionMask.Transfer;
952 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
953 mask &= ~(uint)PermissionMask.Modify;
954 } 1107 }
1108
1109 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1110 mask &= ~(uint)PermissionMask.Copy;
1111 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1112 mask &= ~(uint)PermissionMask.Transfer;
1113 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1114 mask &= ~(uint)PermissionMask.Modify;
955 } 1115 }
956
957 return mask; 1116 return mask;
958 } 1117 }
959 1118
960 public void ApplyNextOwnerPermissions() 1119 public void ApplyNextOwnerPermissions()
961 { 1120 {
962 lock (m_items) 1121 foreach (TaskInventoryItem item in m_items.Values)
963 { 1122 {
964 foreach (TaskInventoryItem item in m_items.Values) 1123 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
965 { 1124 {
966 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 1125 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
967 { 1126 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
968 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1127 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
969 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 1128 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
970 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1129 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
971 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 1130 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
972 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
973 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
974 }
975 item.CurrentPermissions &= item.NextPermissions;
976 item.BasePermissions &= item.NextPermissions;
977 item.EveryonePermissions &= item.NextPermissions;
978 item.OwnerChanged = true;
979 } 1131 }
1132 item.OwnerChanged = true;
1133 item.CurrentPermissions &= item.NextPermissions;
1134 item.BasePermissions &= item.NextPermissions;
1135 item.EveryonePermissions &= item.NextPermissions;
980 } 1136 }
981 } 1137 }
982 1138
983 public void ApplyGodPermissions(uint perms) 1139 public void ApplyGodPermissions(uint perms)
984 { 1140 {
985 lock (m_items) 1141 foreach (TaskInventoryItem item in m_items.Values)
986 { 1142 {
987 foreach (TaskInventoryItem item in m_items.Values) 1143 item.CurrentPermissions = perms;
988 { 1144 item.BasePermissions = perms;
989 item.CurrentPermissions = perms;
990 item.BasePermissions = perms;
991 }
992 } 1145 }
993 } 1146 }
994 1147
995 public bool ContainsScripts() 1148 public bool ContainsScripts()
996 { 1149 {
997 lock (m_items) 1150 foreach (TaskInventoryItem item in m_items.Values)
998 { 1151 {
999 foreach (TaskInventoryItem item in m_items.Values) 1152 if (item.InvType == (int)InventoryType.LSL)
1000 { 1153 {
1001 if (item.InvType == (int)InventoryType.LSL) 1154 return true;
1002 {
1003 return true;
1004 }
1005 } 1155 }
1006 } 1156 }
1007
1008 return false; 1157 return false;
1009 } 1158 }
1010 1159
@@ -1012,11 +1161,8 @@ namespace OpenSim.Region.Framework.Scenes
1012 { 1161 {
1013 List<UUID> ret = new List<UUID>(); 1162 List<UUID> ret = new List<UUID>();
1014 1163
1015 lock (m_items) 1164 foreach (TaskInventoryItem item in m_items.Values)
1016 { 1165 ret.Add(item.ItemID);
1017 foreach (TaskInventoryItem item in m_items.Values)
1018 ret.Add(item.ItemID);
1019 }
1020 1166
1021 return ret; 1167 return ret;
1022 } 1168 }
@@ -1047,31 +1193,44 @@ namespace OpenSim.Region.Framework.Scenes
1047 1193
1048 public Dictionary<UUID, string> GetScriptStates() 1194 public Dictionary<UUID, string> GetScriptStates()
1049 { 1195 {
1196 return GetScriptStates(false);
1197 }
1198
1199 public Dictionary<UUID, string> GetScriptStates(bool oldIDs)
1200 {
1050 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); 1201 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
1051 1202
1052 Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); 1203 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
1053 if (engines == null) // No engine at all 1204 if (engines == null) // No engine at all
1054 return ret; 1205 return ret;
1055 1206
1056 List<TaskInventoryItem> scripts = GetInventoryScripts(); 1207 foreach (TaskInventoryItem item in m_items.Values)
1057
1058 foreach (TaskInventoryItem item in scripts)
1059 { 1208 {
1060 foreach (IScriptModule e in engines) 1209 if (item.InvType == (int)InventoryType.LSL)
1061 { 1210 {
1062 if (e != null) 1211 foreach (IScriptModule e in engines)
1063 { 1212 {
1064 string n = e.GetXMLState(item.ItemID); 1213 if (e != null)
1065 if (n != String.Empty)
1066 { 1214 {
1067 if (!ret.ContainsKey(item.ItemID)) 1215 string n = e.GetXMLState(item.ItemID);
1068 ret[item.ItemID] = n; 1216 if (n != String.Empty)
1069 break; 1217 {
1218 if (oldIDs)
1219 {
1220 if (!ret.ContainsKey(item.OldItemID))
1221 ret[item.OldItemID] = n;
1222 }
1223 else
1224 {
1225 if (!ret.ContainsKey(item.ItemID))
1226 ret[item.ItemID] = n;
1227 }
1228 break;
1229 }
1070 } 1230 }
1071 } 1231 }
1072 } 1232 }
1073 } 1233 }
1074
1075 return ret; 1234 return ret;
1076 } 1235 }
1077 1236
@@ -1081,21 +1240,27 @@ namespace OpenSim.Region.Framework.Scenes
1081 if (engines == null) 1240 if (engines == null)
1082 return; 1241 return;
1083 1242
1084 List<TaskInventoryItem> scripts = GetInventoryScripts();
1085 1243
1086 foreach (TaskInventoryItem item in scripts) 1244 Items.LockItemsForRead(true);
1245
1246 foreach (TaskInventoryItem item in m_items.Values)
1087 { 1247 {
1088 foreach (IScriptModule engine in engines) 1248 if (item.InvType == (int)InventoryType.LSL)
1089 { 1249 {
1090 if (engine != null) 1250 foreach (IScriptModule engine in engines)
1091 { 1251 {
1092 if (item.OwnerChanged) 1252 if (engine != null)
1093 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); 1253 {
1094 item.OwnerChanged = false; 1254 if (item.OwnerChanged)
1095 engine.ResumeScript(item.ItemID); 1255 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
1256 item.OwnerChanged = false;
1257 engine.ResumeScript(item.ItemID);
1258 }
1096 } 1259 }
1097 } 1260 }
1098 } 1261 }
1262
1263 Items.LockItemsForRead(false);
1099 } 1264 }
1100 } 1265 }
1101} 1266}