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 e08fa77..10931b7 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,22 +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 lock (m_items) 126 m_items.LockItemsForWrite(true);
127
128 if (0 == Items.Count)
123 { 129 {
124 if (0 == m_items.Count) 130 m_items.LockItemsForWrite(false);
125 return; 131 return;
132 }
126 133
127 HasInventoryChanged = true; 134 HasInventoryChanged = true;
128 m_part.ParentGroup.HasGroupChanged = true; 135 m_part.ParentGroup.HasGroupChanged = true;
129 IList<TaskInventoryItem> items = GetInventoryItems(); 136 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
130 m_items.Clear(); 137 Items.Clear();
131 138
132 foreach (TaskInventoryItem item in items) 139 foreach (TaskInventoryItem item in items)
133 { 140 {
134 item.ResetIDs(m_part.UUID); 141 item.ResetIDs(m_part.UUID);
135 m_items.Add(item.ItemID, item); 142 Items.Add(item.ItemID, item);
136 }
137 } 143 }
144 m_items.LockItemsForWrite(false);
138 } 145 }
139 146
140 /// <summary> 147 /// <summary>
@@ -143,12 +150,11 @@ namespace OpenSim.Region.Framework.Scenes
143 /// <param name="ownerId"></param> 150 /// <param name="ownerId"></param>
144 public void ChangeInventoryOwner(UUID ownerId) 151 public void ChangeInventoryOwner(UUID ownerId)
145 { 152 {
146 lock (Items) 153 m_items.LockItemsForWrite(true);
154 if (0 == Items.Count)
147 { 155 {
148 if (0 == Items.Count) 156 m_items.LockItemsForWrite(false);
149 { 157 return;
150 return;
151 }
152 } 158 }
153 159
154 HasInventoryChanged = true; 160 HasInventoryChanged = true;
@@ -162,6 +168,7 @@ namespace OpenSim.Region.Framework.Scenes
162 item.OwnerID = ownerId; 168 item.OwnerID = ownerId;
163 } 169 }
164 } 170 }
171 m_items.LockItemsForWrite(false);
165 } 172 }
166 173
167 /// <summary> 174 /// <summary>
@@ -170,22 +177,24 @@ namespace OpenSim.Region.Framework.Scenes
170 /// <param name="groupID"></param> 177 /// <param name="groupID"></param>
171 public void ChangeInventoryGroup(UUID groupID) 178 public void ChangeInventoryGroup(UUID groupID)
172 { 179 {
173 lock (Items) 180 m_items.LockItemsForWrite(true);
181 if (0 == Items.Count)
174 { 182 {
175 if (0 == Items.Count) 183 m_items.LockItemsForWrite(false);
176 { 184 return;
177 return;
178 }
179 } 185 }
180 186
181 HasInventoryChanged = true; 187 HasInventoryChanged = true;
182 m_part.ParentGroup.HasGroupChanged = true; 188 m_part.ParentGroup.HasGroupChanged = true;
183 List<TaskInventoryItem> items = GetInventoryItems(); 189 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
184 foreach (TaskInventoryItem item in items) 190 foreach (TaskInventoryItem item in items)
185 { 191 {
186 if (groupID != item.GroupID) 192 if (groupID != item.GroupID)
193 {
187 item.GroupID = groupID; 194 item.GroupID = groupID;
195 }
188 } 196 }
197 m_items.LockItemsForWrite(false);
189 } 198 }
190 199
191 /// <summary> 200 /// <summary>
@@ -193,9 +202,14 @@ namespace OpenSim.Region.Framework.Scenes
193 /// </summary> 202 /// </summary>
194 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 203 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
195 { 204 {
196 List<TaskInventoryItem> scripts = GetInventoryScripts(); 205 Items.LockItemsForRead(true);
197 foreach (TaskInventoryItem item in scripts) 206 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
198 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 }
199 } 213 }
200 214
201 public ArrayList GetScriptErrors(UUID itemID) 215 public ArrayList GetScriptErrors(UUID itemID)
@@ -228,9 +242,18 @@ namespace OpenSim.Region.Framework.Scenes
228 /// </param> 242 /// </param>
229 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 243 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
230 { 244 {
231 List<TaskInventoryItem> scripts = GetInventoryScripts(); 245 Items.LockItemsForRead(true);
232 foreach (TaskInventoryItem item in scripts) 246 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
233 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 }
234 } 257 }
235 258
236 /// <summary> 259 /// <summary>
@@ -246,7 +269,10 @@ namespace OpenSim.Region.Framework.Scenes
246 // item.Name, item.ItemID, Name, UUID); 269 // item.Name, item.ItemID, Name, UUID);
247 270
248 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");
249 return; 274 return;
275 }
250 276
251 m_part.AddFlag(PrimFlags.Scripted); 277 m_part.AddFlag(PrimFlags.Scripted);
252 278
@@ -255,14 +281,13 @@ namespace OpenSim.Region.Framework.Scenes
255 if (stateSource == 1 && // Prim crossing 281 if (stateSource == 1 && // Prim crossing
256 m_part.ParentGroup.Scene.m_trustBinaries) 282 m_part.ParentGroup.Scene.m_trustBinaries)
257 { 283 {
258 lock (m_items) 284 m_items.LockItemsForWrite(true);
259 { 285 m_items[item.ItemID].PermsMask = 0;
260 m_items[item.ItemID].PermsMask = 0; 286 m_items[item.ItemID].PermsGranter = UUID.Zero;
261 m_items[item.ItemID].PermsGranter = UUID.Zero; 287 m_items.LockItemsForWrite(false);
262 }
263
264 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 288 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
265 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);
266 m_part.ParentGroup.AddActiveScriptCount(1); 291 m_part.ParentGroup.AddActiveScriptCount(1);
267 m_part.ScheduleFullUpdate(); 292 m_part.ScheduleFullUpdate();
268 return; 293 return;
@@ -271,6 +296,8 @@ namespace OpenSim.Region.Framework.Scenes
271 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); 296 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
272 if (null == asset) 297 if (null == asset)
273 { 298 {
299 string msg = String.Format("asset ID {0} could not be found", item.AssetID);
300 StoreScriptError(item.ItemID, msg);
274 m_log.ErrorFormat( 301 m_log.ErrorFormat(
275 "[PRIM INVENTORY]: " + 302 "[PRIM INVENTORY]: " +
276 "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",
@@ -282,15 +309,17 @@ namespace OpenSim.Region.Framework.Scenes
282 if (m_part.ParentGroup.m_savedScriptState != null) 309 if (m_part.ParentGroup.m_savedScriptState != null)
283 RestoreSavedScriptState(item.OldItemID, item.ItemID); 310 RestoreSavedScriptState(item.OldItemID, item.ItemID);
284 311
285 lock (m_items) 312 m_items.LockItemsForWrite(true);
286 { 313
287 m_items[item.ItemID].PermsMask = 0; 314 m_items[item.ItemID].PermsMask = 0;
288 m_items[item.ItemID].PermsGranter = UUID.Zero; 315 m_items[item.ItemID].PermsGranter = UUID.Zero;
289 } 316
317 m_items.LockItemsForWrite(false);
290 318
291 string script = Utils.BytesToString(asset.Data); 319 string script = Utils.BytesToString(asset.Data);
292 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 320 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
293 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);
294 m_part.ParentGroup.AddActiveScriptCount(1); 323 m_part.ParentGroup.AddActiveScriptCount(1);
295 m_part.ScheduleFullUpdate(); 324 m_part.ScheduleFullUpdate();
296 } 325 }
@@ -354,21 +383,145 @@ namespace OpenSim.Region.Framework.Scenes
354 383
355 /// <summary> 384 /// <summary>
356 /// 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.
357 /// </summary> 387 /// </summary>
358 /// <param name="itemId"> 388 /// <param name="itemId">
359 /// A <see cref="UUID"/> 389 /// A <see cref="UUID"/>
360 /// </param> 390 /// </param>
361 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)
362 { 392 {
363 TaskInventoryItem item = GetInventoryItem(itemId); 393 lock (m_scriptErrors)
364 if (item != null) 394 {
365 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 }
366 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);
367 m_log.ErrorFormat( 427 m_log.ErrorFormat(
368 "[PRIM INVENTORY]: " + 428 "[PRIM INVENTORY]: " +
369 "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);
370 itemId, m_part.Name, m_part.UUID, 430 }
371 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);
372 } 525 }
373 526
374 /// <summary> 527 /// <summary>
@@ -381,15 +534,7 @@ namespace OpenSim.Region.Framework.Scenes
381 /// </param> 534 /// </param>
382 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 535 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
383 { 536 {
384 bool scriptPresent = false; 537 if (m_items.ContainsKey(itemId))
385
386 lock (m_items)
387 {
388 if (m_items.ContainsKey(itemId))
389 scriptPresent = true;
390 }
391
392 if (scriptPresent)
393 { 538 {
394 if (!sceneObjectBeingDeleted) 539 if (!sceneObjectBeingDeleted)
395 m_part.RemoveScriptEvents(itemId); 540 m_part.RemoveScriptEvents(itemId);
@@ -414,14 +559,16 @@ namespace OpenSim.Region.Framework.Scenes
414 /// <returns></returns> 559 /// <returns></returns>
415 private bool InventoryContainsName(string name) 560 private bool InventoryContainsName(string name)
416 { 561 {
417 lock (m_items) 562 m_items.LockItemsForRead(true);
563 foreach (TaskInventoryItem item in m_items.Values)
418 { 564 {
419 foreach (TaskInventoryItem item in m_items.Values) 565 if (item.Name == name)
420 { 566 {
421 if (item.Name == name) 567 m_items.LockItemsForRead(false);
422 return true; 568 return true;
423 } 569 }
424 } 570 }
571 m_items.LockItemsForRead(false);
425 return false; 572 return false;
426 } 573 }
427 574
@@ -463,8 +610,9 @@ namespace OpenSim.Region.Framework.Scenes
463 /// <param name="item"></param> 610 /// <param name="item"></param>
464 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 611 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
465 { 612 {
466 List<TaskInventoryItem> il = GetInventoryItems(); 613 m_items.LockItemsForRead(true);
467 614 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
615 m_items.LockItemsForRead(false);
468 foreach (TaskInventoryItem i in il) 616 foreach (TaskInventoryItem i in il)
469 { 617 {
470 if (i.Name == item.Name) 618 if (i.Name == item.Name)
@@ -502,14 +650,14 @@ namespace OpenSim.Region.Framework.Scenes
502 item.Name = name; 650 item.Name = name;
503 item.GroupID = m_part.GroupID; 651 item.GroupID = m_part.GroupID;
504 652
505 lock (m_items) 653 m_items.LockItemsForWrite(true);
506 m_items.Add(item.ItemID, item); 654 m_items.Add(item.ItemID, item);
507 655 m_items.LockItemsForWrite(false);
508 if (allowedDrop) 656 if (allowedDrop)
509 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 657 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
510 else 658 else
511 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 659 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
512 660
513 m_inventorySerial++; 661 m_inventorySerial++;
514 //m_inventorySerial += 2; 662 //m_inventorySerial += 2;
515 HasInventoryChanged = true; 663 HasInventoryChanged = true;
@@ -525,15 +673,15 @@ namespace OpenSim.Region.Framework.Scenes
525 /// <param name="items"></param> 673 /// <param name="items"></param>
526 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 674 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
527 { 675 {
528 lock (m_items) 676 m_items.LockItemsForWrite(true);
677 foreach (TaskInventoryItem item in items)
529 { 678 {
530 foreach (TaskInventoryItem item in items) 679 m_items.Add(item.ItemID, item);
531 { 680// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
532 m_items.Add(item.ItemID, item);
533// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
534 }
535 m_inventorySerial++;
536 } 681 }
682 m_items.LockItemsForWrite(false);
683
684 m_inventorySerial++;
537 } 685 }
538 686
539 /// <summary> 687 /// <summary>
@@ -544,10 +692,9 @@ namespace OpenSim.Region.Framework.Scenes
544 public TaskInventoryItem GetInventoryItem(UUID itemId) 692 public TaskInventoryItem GetInventoryItem(UUID itemId)
545 { 693 {
546 TaskInventoryItem item; 694 TaskInventoryItem item;
547 695 m_items.LockItemsForRead(true);
548 lock (m_items) 696 m_items.TryGetValue(itemId, out item);
549 m_items.TryGetValue(itemId, out item); 697 m_items.LockItemsForRead(false);
550
551 return item; 698 return item;
552 } 699 }
553 700
@@ -563,15 +710,16 @@ namespace OpenSim.Region.Framework.Scenes
563 { 710 {
564 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); 711 IList<TaskInventoryItem> items = new List<TaskInventoryItem>();
565 712
566 lock (m_items) 713 m_items.LockItemsForRead(true);
714
715 foreach (TaskInventoryItem item in m_items.Values)
567 { 716 {
568 foreach (TaskInventoryItem item in m_items.Values) 717 if (item.Name == name)
569 { 718 items.Add(item);
570 if (item.Name == name)
571 items.Add(item);
572 }
573 } 719 }
574 720
721 m_items.LockItemsForRead(false);
722
575 return items; 723 return items;
576 } 724 }
577 725
@@ -653,8 +801,9 @@ namespace OpenSim.Region.Framework.Scenes
653 801
654 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents) 802 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents)
655 { 803 {
656 TaskInventoryItem it = GetInventoryItem(item.ItemID); 804 m_items.LockItemsForWrite(true);
657 if (it != null) 805
806 if (m_items.ContainsKey(item.ItemID))
658 { 807 {
659 item.ParentID = m_part.UUID; 808 item.ParentID = m_part.UUID;
660 item.ParentPartID = m_part.UUID; 809 item.ParentPartID = m_part.UUID;
@@ -666,19 +815,15 @@ namespace OpenSim.Region.Framework.Scenes
666 item.GroupID = m_part.GroupID; 815 item.GroupID = m_part.GroupID;
667 816
668 if (item.AssetID == UUID.Zero) 817 if (item.AssetID == UUID.Zero)
669 item.AssetID = it.AssetID; 818 item.AssetID = m_items[item.ItemID].AssetID;
670
671 lock (m_items)
672 {
673 m_items[item.ItemID] = item;
674 m_inventorySerial++;
675 }
676 819
820 m_items[item.ItemID] = item;
821 m_inventorySerial++;
677 if (fireScriptEvents) 822 if (fireScriptEvents)
678 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 823 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
679
680 HasInventoryChanged = true; 824 HasInventoryChanged = true;
681 m_part.ParentGroup.HasGroupChanged = true; 825 m_part.ParentGroup.HasGroupChanged = true;
826 m_items.LockItemsForWrite(false);
682 return true; 827 return true;
683 } 828 }
684 else 829 else
@@ -689,8 +834,9 @@ namespace OpenSim.Region.Framework.Scenes
689 item.ItemID, m_part.Name, m_part.UUID, 834 item.ItemID, m_part.Name, m_part.UUID,
690 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 835 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
691 } 836 }
692 return false; 837 m_items.LockItemsForWrite(false);
693 838
839 return false;
694 } 840 }
695 841
696 /// <summary> 842 /// <summary>
@@ -701,37 +847,53 @@ namespace OpenSim.Region.Framework.Scenes
701 /// in this prim's inventory.</returns> 847 /// in this prim's inventory.</returns>
702 public int RemoveInventoryItem(UUID itemID) 848 public int RemoveInventoryItem(UUID itemID)
703 { 849 {
704 TaskInventoryItem item = GetInventoryItem(itemID); 850 m_items.LockItemsForRead(true);
705 if (item != null) 851
852 if (m_items.ContainsKey(itemID))
706 { 853 {
707 int type = m_items[itemID].InvType; 854 int type = m_items[itemID].InvType;
855 m_items.LockItemsForRead(false);
708 if (type == 10) // Script 856 if (type == 10) // Script
709 { 857 {
710 m_part.RemoveScriptEvents(itemID);
711 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 858 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
712 } 859 }
860 m_items.LockItemsForWrite(true);
713 m_items.Remove(itemID); 861 m_items.Remove(itemID);
862 m_items.LockItemsForWrite(false);
714 m_inventorySerial++; 863 m_inventorySerial++;
715 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 864 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
716 865
717 HasInventoryChanged = true; 866 HasInventoryChanged = true;
718 m_part.ParentGroup.HasGroupChanged = true; 867 m_part.ParentGroup.HasGroupChanged = true;
719 868
720 if (!ContainsScripts()) 869 int scriptcount = 0;
870 m_items.LockItemsForRead(true);
871 foreach (TaskInventoryItem item in m_items.Values)
872 {
873 if (item.Type == 10)
874 {
875 scriptcount++;
876 }
877 }
878 m_items.LockItemsForRead(false);
879
880
881 if (scriptcount <= 0)
882 {
721 m_part.RemFlag(PrimFlags.Scripted); 883 m_part.RemFlag(PrimFlags.Scripted);
884 }
722 885
723 m_part.ScheduleFullUpdate(); 886 m_part.ScheduleFullUpdate();
724 887
725 return type; 888 return type;
726
727 } 889 }
728 else 890 else
729 { 891 {
892 m_items.LockItemsForRead(false);
730 m_log.ErrorFormat( 893 m_log.ErrorFormat(
731 "[PRIM INVENTORY]: " + 894 "[PRIM INVENTORY]: " +
732 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 895 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
733 itemID, m_part.Name, m_part.UUID, 896 itemID, m_part.Name, m_part.UUID);
734 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
735 } 897 }
736 898
737 return -1; 899 return -1;
@@ -785,8 +947,9 @@ namespace OpenSim.Region.Framework.Scenes
785 // isn't available (such as drag from prim inventory to agent inventory) 947 // isn't available (such as drag from prim inventory to agent inventory)
786 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 948 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
787 949
788 List<TaskInventoryItem> items = GetInventoryItems(); 950 m_items.LockItemsForRead(true);
789 foreach (TaskInventoryItem item in items) 951
952 foreach (TaskInventoryItem item in m_items.Values)
790 { 953 {
791 UUID ownerID = item.OwnerID; 954 UUID ownerID = item.OwnerID;
792 uint everyoneMask = 0; 955 uint everyoneMask = 0;
@@ -830,6 +993,8 @@ namespace OpenSim.Region.Framework.Scenes
830 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 993 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
831 invString.AddSectionEnd(); 994 invString.AddSectionEnd();
832 } 995 }
996 int count = m_items.Count;
997 m_items.LockItemsForRead(false);
833 998
834 fileData = Utils.StringToBytes(invString.BuildString); 999 fileData = Utils.StringToBytes(invString.BuildString);
835 1000
@@ -850,10 +1015,11 @@ namespace OpenSim.Region.Framework.Scenes
850 { 1015 {
851 if (HasInventoryChanged) 1016 if (HasInventoryChanged)
852 { 1017 {
853 HasInventoryChanged = false; 1018 Items.LockItemsForRead(true);
854 List<TaskInventoryItem> items = GetInventoryItems(); 1019 datastore.StorePrimInventory(m_part.UUID, Items.Values);
855 datastore.StorePrimInventory(m_part.UUID, items); 1020 Items.LockItemsForRead(false);
856 1021
1022 HasInventoryChanged = false;
857 } 1023 }
858 } 1024 }
859 1025
@@ -920,89 +1086,75 @@ namespace OpenSim.Region.Framework.Scenes
920 { 1086 {
921 uint mask=0x7fffffff; 1087 uint mask=0x7fffffff;
922 1088
923 lock (m_items) 1089 foreach (TaskInventoryItem item in m_items.Values)
924 { 1090 {
925 foreach (TaskInventoryItem item in m_items.Values) 1091 if (item.InvType != (int)InventoryType.Object)
926 { 1092 {
927 if (item.InvType != (int)InventoryType.Object) 1093 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
928 { 1094 mask &= ~((uint)PermissionMask.Copy >> 13);
929 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1095 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
930 mask &= ~((uint)PermissionMask.Copy >> 13); 1096 mask &= ~((uint)PermissionMask.Transfer >> 13);
931 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1097 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
932 mask &= ~((uint)PermissionMask.Transfer >> 13); 1098 mask &= ~((uint)PermissionMask.Modify >> 13);
933 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 1099 }
934 mask &= ~((uint)PermissionMask.Modify >> 13); 1100 else
935 } 1101 {
936 else 1102 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
937 { 1103 mask &= ~((uint)PermissionMask.Copy >> 13);
938 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1104 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
939 mask &= ~((uint)PermissionMask.Copy >> 13); 1105 mask &= ~((uint)PermissionMask.Transfer >> 13);
940 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1106 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
941 mask &= ~((uint)PermissionMask.Transfer >> 13); 1107 mask &= ~((uint)PermissionMask.Modify >> 13);
942 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
943 mask &= ~((uint)PermissionMask.Modify >> 13);
944 }
945
946 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
947 mask &= ~(uint)PermissionMask.Copy;
948 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
949 mask &= ~(uint)PermissionMask.Transfer;
950 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
951 mask &= ~(uint)PermissionMask.Modify;
952 } 1108 }
1109
1110 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1111 mask &= ~(uint)PermissionMask.Copy;
1112 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1113 mask &= ~(uint)PermissionMask.Transfer;
1114 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1115 mask &= ~(uint)PermissionMask.Modify;
953 } 1116 }
954
955 return mask; 1117 return mask;
956 } 1118 }
957 1119
958 public void ApplyNextOwnerPermissions() 1120 public void ApplyNextOwnerPermissions()
959 { 1121 {
960 lock (m_items) 1122 foreach (TaskInventoryItem item in m_items.Values)
961 { 1123 {
962 foreach (TaskInventoryItem item in m_items.Values) 1124 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
963 { 1125 {
964 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 1126 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
965 { 1127 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
966 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1128 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
967 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 1129 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
968 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1130 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
969 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 1131 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
970 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
971 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
972 }
973 item.CurrentPermissions &= item.NextPermissions;
974 item.BasePermissions &= item.NextPermissions;
975 item.EveryonePermissions &= item.NextPermissions;
976 item.OwnerChanged = true;
977 } 1132 }
1133 item.OwnerChanged = true;
1134 item.CurrentPermissions &= item.NextPermissions;
1135 item.BasePermissions &= item.NextPermissions;
1136 item.EveryonePermissions &= item.NextPermissions;
978 } 1137 }
979 } 1138 }
980 1139
981 public void ApplyGodPermissions(uint perms) 1140 public void ApplyGodPermissions(uint perms)
982 { 1141 {
983 lock (m_items) 1142 foreach (TaskInventoryItem item in m_items.Values)
984 { 1143 {
985 foreach (TaskInventoryItem item in m_items.Values) 1144 item.CurrentPermissions = perms;
986 { 1145 item.BasePermissions = perms;
987 item.CurrentPermissions = perms;
988 item.BasePermissions = perms;
989 }
990 } 1146 }
991 } 1147 }
992 1148
993 public bool ContainsScripts() 1149 public bool ContainsScripts()
994 { 1150 {
995 lock (m_items) 1151 foreach (TaskInventoryItem item in m_items.Values)
996 { 1152 {
997 foreach (TaskInventoryItem item in m_items.Values) 1153 if (item.InvType == (int)InventoryType.LSL)
998 { 1154 {
999 if (item.InvType == (int)InventoryType.LSL) 1155 return true;
1000 {
1001 return true;
1002 }
1003 } 1156 }
1004 } 1157 }
1005
1006 return false; 1158 return false;
1007 } 1159 }
1008 1160
@@ -1010,11 +1162,8 @@ namespace OpenSim.Region.Framework.Scenes
1010 { 1162 {
1011 List<UUID> ret = new List<UUID>(); 1163 List<UUID> ret = new List<UUID>();
1012 1164
1013 lock (m_items) 1165 foreach (TaskInventoryItem item in m_items.Values)
1014 { 1166 ret.Add(item.ItemID);
1015 foreach (TaskInventoryItem item in m_items.Values)
1016 ret.Add(item.ItemID);
1017 }
1018 1167
1019 return ret; 1168 return ret;
1020 } 1169 }
@@ -1045,31 +1194,44 @@ namespace OpenSim.Region.Framework.Scenes
1045 1194
1046 public Dictionary<UUID, string> GetScriptStates() 1195 public Dictionary<UUID, string> GetScriptStates()
1047 { 1196 {
1197 return GetScriptStates(false);
1198 }
1199
1200 public Dictionary<UUID, string> GetScriptStates(bool oldIDs)
1201 {
1048 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); 1202 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
1049 1203
1050 Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); 1204 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
1051 if (engines == null) // No engine at all 1205 if (engines == null) // No engine at all
1052 return ret; 1206 return ret;
1053 1207
1054 List<TaskInventoryItem> scripts = GetInventoryScripts(); 1208 foreach (TaskInventoryItem item in m_items.Values)
1055
1056 foreach (TaskInventoryItem item in scripts)
1057 { 1209 {
1058 foreach (IScriptModule e in engines) 1210 if (item.InvType == (int)InventoryType.LSL)
1059 { 1211 {
1060 if (e != null) 1212 foreach (IScriptModule e in engines)
1061 { 1213 {
1062 string n = e.GetXMLState(item.ItemID); 1214 if (e != null)
1063 if (n != String.Empty)
1064 { 1215 {
1065 if (!ret.ContainsKey(item.ItemID)) 1216 string n = e.GetXMLState(item.ItemID);
1066 ret[item.ItemID] = n; 1217 if (n != String.Empty)
1067 break; 1218 {
1219 if (oldIDs)
1220 {
1221 if (!ret.ContainsKey(item.OldItemID))
1222 ret[item.OldItemID] = n;
1223 }
1224 else
1225 {
1226 if (!ret.ContainsKey(item.ItemID))
1227 ret[item.ItemID] = n;
1228 }
1229 break;
1230 }
1068 } 1231 }
1069 } 1232 }
1070 } 1233 }
1071 } 1234 }
1072
1073 return ret; 1235 return ret;
1074 } 1236 }
1075 1237
@@ -1079,21 +1241,27 @@ namespace OpenSim.Region.Framework.Scenes
1079 if (engines == null) 1241 if (engines == null)
1080 return; 1242 return;
1081 1243
1082 List<TaskInventoryItem> scripts = GetInventoryScripts();
1083 1244
1084 foreach (TaskInventoryItem item in scripts) 1245 Items.LockItemsForRead(true);
1246
1247 foreach (TaskInventoryItem item in m_items.Values)
1085 { 1248 {
1086 foreach (IScriptModule engine in engines) 1249 if (item.InvType == (int)InventoryType.LSL)
1087 { 1250 {
1088 if (engine != null) 1251 foreach (IScriptModule engine in engines)
1089 { 1252 {
1090 if (item.OwnerChanged) 1253 if (engine != null)
1091 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); 1254 {
1092 item.OwnerChanged = false; 1255 if (item.OwnerChanged)
1093 engine.ResumeScript(item.ItemID); 1256 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
1257 item.OwnerChanged = false;
1258 engine.ResumeScript(item.ItemID);
1259 }
1094 } 1260 }
1095 } 1261 }
1096 } 1262 }
1263
1264 Items.LockItemsForRead(false);
1097 } 1265 }
1098 } 1266 }
1099} \ No newline at end of file 1267} \ No newline at end of file