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.cs731
1 files changed, 439 insertions, 292 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 3a8f168..5be71df 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 (Items) 125 m_items.LockItemsForWrite(true);
126
127 if (0 == Items.Count)
122 { 128 {
123 if (0 == 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 = new List<TaskInventoryItem>(Items.Values); 135 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
129 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 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,25 +149,25 @@ 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; 157 }
150 }
151 158
152 HasInventoryChanged = true; 159 HasInventoryChanged = true;
153 m_part.ParentGroup.HasGroupChanged = true; 160 m_part.ParentGroup.HasGroupChanged = true;
154 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 161 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
155 foreach (TaskInventoryItem item in items) 162 foreach (TaskInventoryItem item in items)
163 {
164 if (ownerId != item.OwnerID)
156 { 165 {
157 if (ownerId != item.OwnerID) 166 item.LastOwnerID = item.OwnerID;
158 { 167 item.OwnerID = ownerId;
159 item.LastOwnerID = item.OwnerID;
160 item.OwnerID = ownerId;
161 }
162 } 168 }
163 } 169 }
170 m_items.LockItemsForWrite(false);
164 } 171 }
165 172
166 /// <summary> 173 /// <summary>
@@ -169,24 +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; 184 }
177 }
178 185
179 HasInventoryChanged = true; 186 HasInventoryChanged = true;
180 m_part.ParentGroup.HasGroupChanged = true; 187 m_part.ParentGroup.HasGroupChanged = true;
181 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 188 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
182 foreach (TaskInventoryItem item in items) 189 foreach (TaskInventoryItem item in items)
190 {
191 if (groupID != item.GroupID)
183 { 192 {
184 if (groupID != item.GroupID) 193 item.GroupID = groupID;
185 {
186 item.GroupID = groupID;
187 }
188 } 194 }
189 } 195 }
196 m_items.LockItemsForWrite(false);
190 } 197 }
191 198
192 /// <summary> 199 /// <summary>
@@ -194,15 +201,15 @@ namespace OpenSim.Region.Framework.Scenes
194 /// </summary> 201 /// </summary>
195 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 202 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
196 { 203 {
197 lock (m_items) 204 Items.LockItemsForRead(true);
205 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
206 Items.LockItemsForRead(false);
207 foreach (TaskInventoryItem item in items)
198 { 208 {
199 foreach (TaskInventoryItem item in Items.Values) 209 if ((int)InventoryType.LSL == item.InvType)
200 { 210 {
201 if ((int)InventoryType.LSL == item.InvType) 211 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
202 { 212 Thread.Sleep(10); // workaround for Mono cpu utilization > 100% bug
203 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
204 Thread.Sleep(10); // workaround for Mono cpu utilization > 100% bug
205 }
206 } 213 }
207 } 214 }
208 } 215 }
@@ -237,16 +244,20 @@ namespace OpenSim.Region.Framework.Scenes
237 /// </param> 244 /// </param>
238 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 245 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
239 { 246 {
240 lock (Items) 247 Items.LockItemsForRead(true);
248 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
249 Items.LockItemsForRead(false);
250
251 foreach (TaskInventoryItem item in items)
241 { 252 {
242 foreach (TaskInventoryItem item in Items.Values) 253 if ((int)InventoryType.LSL == item.InvType)
243 { 254 {
244 if ((int)InventoryType.LSL == item.InvType) 255 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
245 { 256 m_part.RemoveScriptEvents(item.ItemID);
246 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
247 }
248 } 257 }
249 } 258 }
259
260
250 } 261 }
251 262
252 /// <summary> 263 /// <summary>
@@ -262,7 +273,10 @@ namespace OpenSim.Region.Framework.Scenes
262 // item.Name, item.ItemID, m_part.Name, m_part.UUID); 273 // item.Name, item.ItemID, m_part.Name, m_part.UUID);
263 274
264 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) 275 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID))
276 {
277 StoreScriptError(item.ItemID, "no permission");
265 return; 278 return;
279 }
266 280
267 m_part.AddFlag(PrimFlags.Scripted); 281 m_part.AddFlag(PrimFlags.Scripted);
268 282
@@ -271,14 +285,13 @@ namespace OpenSim.Region.Framework.Scenes
271 if (stateSource == 1 && // Prim crossing 285 if (stateSource == 1 && // Prim crossing
272 m_part.ParentGroup.Scene.m_trustBinaries) 286 m_part.ParentGroup.Scene.m_trustBinaries)
273 { 287 {
274 lock (m_items) 288 m_items.LockItemsForWrite(true);
275 { 289 m_items[item.ItemID].PermsMask = 0;
276 m_items[item.ItemID].PermsMask = 0; 290 m_items[item.ItemID].PermsGranter = UUID.Zero;
277 m_items[item.ItemID].PermsGranter = UUID.Zero; 291 m_items.LockItemsForWrite(false);
278 }
279
280 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 292 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
281 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 293 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
294 StoreScriptErrors(item.ItemID, null);
282 m_part.ParentGroup.AddActiveScriptCount(1); 295 m_part.ParentGroup.AddActiveScriptCount(1);
283 m_part.ScheduleFullUpdate(); 296 m_part.ScheduleFullUpdate();
284 return; 297 return;
@@ -287,6 +300,8 @@ namespace OpenSim.Region.Framework.Scenes
287 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); 300 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
288 if (null == asset) 301 if (null == asset)
289 { 302 {
303 string msg = String.Format("asset ID {0} could not be found", item.AssetID);
304 StoreScriptError(item.ItemID, msg);
290 m_log.ErrorFormat( 305 m_log.ErrorFormat(
291 "[PRIM INVENTORY]: " + 306 "[PRIM INVENTORY]: " +
292 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", 307 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
@@ -295,6 +310,24 @@ namespace OpenSim.Region.Framework.Scenes
295 } 310 }
296 else 311 else
297 { 312 {
313<<<<<<< HEAD:OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
314 if (m_part.ParentGroup.m_savedScriptState != null)
315 RestoreSavedScriptState(item.OldItemID, item.ItemID);
316
317 m_items.LockItemsForWrite(true);
318
319 m_items[item.ItemID].PermsMask = 0;
320 m_items[item.ItemID].PermsGranter = UUID.Zero;
321
322 m_items.LockItemsForWrite(false);
323
324 string script = Utils.BytesToString(asset.Data);
325 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
326 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
327 StoreScriptErrors(item.ItemID, null);
328 m_part.ParentGroup.AddActiveScriptCount(1);
329 m_part.ScheduleFullUpdate();
330=======
298 lock (m_items) 331 lock (m_items)
299 { 332 {
300 if (m_part.ParentGroup.m_savedScriptState != null) 333 if (m_part.ParentGroup.m_savedScriptState != null)
@@ -309,6 +342,7 @@ namespace OpenSim.Region.Framework.Scenes
309 m_part.ParentGroup.AddActiveScriptCount(1); 342 m_part.ParentGroup.AddActiveScriptCount(1);
310 m_part.ScheduleFullUpdate(); 343 m_part.ScheduleFullUpdate();
311 } 344 }
345>>>>>>> master:OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
312 } 346 }
313 } 347 }
314 } 348 }
@@ -370,27 +404,145 @@ namespace OpenSim.Region.Framework.Scenes
370 404
371 /// <summary> 405 /// <summary>
372 /// Start a script which is in this prim's inventory. 406 /// Start a script which is in this prim's inventory.
407 /// Some processing may occur in the background, but this routine returns asap.
373 /// </summary> 408 /// </summary>
374 /// <param name="itemId"> 409 /// <param name="itemId">
375 /// A <see cref="UUID"/> 410 /// A <see cref="UUID"/>
376 /// </param> 411 /// </param>
377 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 412 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
378 { 413 {
379 lock (m_items) 414 lock (m_scriptErrors)
415 {
416 // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion
417 m_scriptErrors.Remove(itemId);
418 }
419 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
420 }
421
422 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
423 {
424 m_items.LockItemsForRead(true);
425 if (m_items.ContainsKey(itemId))
380 { 426 {
381 if (m_items.ContainsKey(itemId)) 427 if (m_items.ContainsKey(itemId))
382 { 428 {
429 m_items.LockItemsForRead(false);
383 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); 430 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
384 } 431 }
385 else 432 else
386 { 433 {
434 m_items.LockItemsForRead(false);
435 string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID,
436 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
437 StoreScriptError(itemId, msg);
387 m_log.ErrorFormat( 438 m_log.ErrorFormat(
388 "[PRIM INVENTORY]: " + 439 "[PRIM INVENTORY]: " +
389 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 440 "Couldn't start script with ID {0} since it {1}", itemId, msg);
390 itemId, m_part.Name, m_part.UUID, 441 }
391 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 442 }
443 else
444 {
445 m_items.LockItemsForRead(false);
446 string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID);
447 StoreScriptError(itemId, msg);
448 m_log.ErrorFormat(
449 "[PRIM INVENTORY]: " +
450 "Couldn't start script with ID {0} since it {1}", itemId, msg);
451 }
452
453 }
454
455 /// <summary>
456 /// Start a script which is in this prim's inventory and return any compilation error messages.
457 /// </summary>
458 /// <param name="itemId">
459 /// A <see cref="UUID"/>
460 /// </param>
461 public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
462 {
463 ArrayList errors;
464
465 // Indicate to CreateScriptInstanceInternal() we want it to
466 // post any compilation/loading error messages
467 lock (m_scriptErrors)
468 {
469 m_scriptErrors[itemId] = null;
470 }
471
472 // Perform compilation/loading
473 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
474
475 // Wait for and retrieve any errors
476 lock (m_scriptErrors)
477 {
478 while ((errors = m_scriptErrors[itemId]) == null)
479 {
480 if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
481 {
482 m_log.ErrorFormat(
483 "[PRIM INVENTORY]: " +
484 "timedout waiting for script {0} errors", itemId);
485 errors = m_scriptErrors[itemId];
486 if (errors == null)
487 {
488 errors = new ArrayList(1);
489 errors.Add("timedout waiting for errors");
490 }
491 break;
492 }
392 } 493 }
494 m_scriptErrors.Remove(itemId);
393 } 495 }
496 return errors;
497 }
498
499 // Signal to CreateScriptInstanceEr() that compilation/loading is complete
500 private void StoreScriptErrors(UUID itemId, ArrayList errors)
501 {
502 lock (m_scriptErrors)
503 {
504 // If compilation/loading initiated via CreateScriptInstance(),
505 // it does not want the errors, so just get out
506 if (!m_scriptErrors.ContainsKey(itemId))
507 {
508 return;
509 }
510
511 // Initiated via CreateScriptInstanceEr(), if we know what the
512 // errors are, save them and wake CreateScriptInstanceEr().
513 if (errors != null)
514 {
515 m_scriptErrors[itemId] = errors;
516 System.Threading.Monitor.PulseAll(m_scriptErrors);
517 return;
518 }
519 }
520
521 // Initiated via CreateScriptInstanceEr() but we don't know what
522 // the errors are yet, so retrieve them from the script engine.
523 // This may involve some waiting internal to GetScriptErrors().
524 errors = GetScriptErrors(itemId);
525
526 // Get a default non-null value to indicate success.
527 if (errors == null)
528 {
529 errors = new ArrayList();
530 }
531
532 // Post to CreateScriptInstanceEr() and wake it up
533 lock (m_scriptErrors)
534 {
535 m_scriptErrors[itemId] = errors;
536 System.Threading.Monitor.PulseAll(m_scriptErrors);
537 }
538 }
539
540 // Like StoreScriptErrors(), but just posts a single string message
541 private void StoreScriptError(UUID itemId, string message)
542 {
543 ArrayList errors = new ArrayList(1);
544 errors.Add(message);
545 StoreScriptErrors(itemId, errors);
394 } 546 }
395 547
396 /// <summary> 548 /// <summary>
@@ -403,15 +555,7 @@ namespace OpenSim.Region.Framework.Scenes
403 /// </param> 555 /// </param>
404 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 556 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
405 { 557 {
406 bool scriptPresent = false; 558 if (m_items.ContainsKey(itemId))
407
408 lock (m_items)
409 {
410 if (m_items.ContainsKey(itemId))
411 scriptPresent = true;
412 }
413
414 if (scriptPresent)
415 { 559 {
416 if (!sceneObjectBeingDeleted) 560 if (!sceneObjectBeingDeleted)
417 m_part.RemoveScriptEvents(itemId); 561 m_part.RemoveScriptEvents(itemId);
@@ -437,11 +581,16 @@ namespace OpenSim.Region.Framework.Scenes
437 /// <returns></returns> 581 /// <returns></returns>
438 private bool InventoryContainsName(string name) 582 private bool InventoryContainsName(string name)
439 { 583 {
440 foreach (TaskInventoryItem item in Items.Values) 584 m_items.LockItemsForRead(true);
585 foreach (TaskInventoryItem item in m_items.Values)
441 { 586 {
442 if (item.Name == name) 587 if (item.Name == name)
588 {
589 m_items.LockItemsForRead(false);
443 return true; 590 return true;
591 }
444 } 592 }
593 m_items.LockItemsForRead(false);
445 return false; 594 return false;
446 } 595 }
447 596
@@ -483,13 +632,9 @@ namespace OpenSim.Region.Framework.Scenes
483 /// <param name="item"></param> 632 /// <param name="item"></param>
484 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 633 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
485 { 634 {
486 List<TaskInventoryItem> il; 635 m_items.LockItemsForRead(true);
487 636 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
488 lock (m_items) 637 m_items.LockItemsForRead(false);
489 {
490 il = new List<TaskInventoryItem>(m_items.Values);
491 }
492
493 foreach (TaskInventoryItem i in il) 638 foreach (TaskInventoryItem i in il)
494 { 639 {
495 if (i.Name == item.Name) 640 if (i.Name == item.Name)
@@ -527,15 +672,14 @@ namespace OpenSim.Region.Framework.Scenes
527 item.Name = name; 672 item.Name = name;
528 item.GroupID = m_part.GroupID; 673 item.GroupID = m_part.GroupID;
529 674
530 lock (m_items) 675 m_items.LockItemsForWrite(true);
531 { 676 m_items.Add(item.ItemID, item);
532 m_items.Add(item.ItemID, item); 677 m_items.LockItemsForWrite(false);
533
534 if (allowedDrop) 678 if (allowedDrop)
535 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 679 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
536 else 680 else
537 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 681 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
538 } 682
539 683
540 m_inventorySerial++; 684 m_inventorySerial++;
541 //m_inventorySerial += 2; 685 //m_inventorySerial += 2;
@@ -552,14 +696,13 @@ namespace OpenSim.Region.Framework.Scenes
552 /// <param name="items"></param> 696 /// <param name="items"></param>
553 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 697 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
554 { 698 {
555 lock (m_items) 699 m_items.LockItemsForWrite(true);
700 foreach (TaskInventoryItem item in items)
556 { 701 {
557 foreach (TaskInventoryItem item in items) 702 m_items.Add(item.ItemID, item);
558 { 703// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
559 m_items.Add(item.ItemID, item);
560// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
561 }
562 } 704 }
705 m_items.LockItemsForWrite(false);
563 706
564 m_inventorySerial++; 707 m_inventorySerial++;
565 } 708 }
@@ -572,10 +715,9 @@ namespace OpenSim.Region.Framework.Scenes
572 public TaskInventoryItem GetInventoryItem(UUID itemId) 715 public TaskInventoryItem GetInventoryItem(UUID itemId)
573 { 716 {
574 TaskInventoryItem item; 717 TaskInventoryItem item;
575 718 m_items.LockItemsForRead(true);
576 lock (m_items) 719 m_items.TryGetValue(itemId, out item);
577 m_items.TryGetValue(itemId, out item); 720 m_items.LockItemsForRead(false);
578
579 return item; 721 return item;
580 } 722 }
581 723
@@ -591,15 +733,16 @@ namespace OpenSim.Region.Framework.Scenes
591 { 733 {
592 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); 734 IList<TaskInventoryItem> items = new List<TaskInventoryItem>();
593 735
594 lock (m_items) 736 m_items.LockItemsForRead(true);
737
738 foreach (TaskInventoryItem item in m_items.Values)
595 { 739 {
596 foreach (TaskInventoryItem item in m_items.Values) 740 if (item.Name == name)
597 { 741 items.Add(item);
598 if (item.Name == name)
599 items.Add(item);
600 }
601 } 742 }
602 743
744 m_items.LockItemsForRead(false);
745
603 return items; 746 return items;
604 } 747 }
605 748
@@ -616,45 +759,54 @@ namespace OpenSim.Region.Framework.Scenes
616 759
617 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents) 760 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents)
618 { 761 {
619 lock(m_items) 762 m_items.LockItemsForWrite(true);
763
764 if (m_items.ContainsKey(item.ItemID))
620 { 765 {
621 if (m_items.ContainsKey(item.ItemID)) 766 item.ParentID = m_part.UUID;
767 item.ParentPartID = m_part.UUID;
768 item.Flags = m_items[item.ItemID].Flags;
769
770 // If group permissions have been set on, check that the groupID is up to date in case it has
771 // changed since permissions were last set.
772 if (item.GroupPermissions != (uint)PermissionMask.None)
773 item.GroupID = m_part.GroupID;
774
775 if (item.AssetID == UUID.Zero)
622 { 776 {
623 if (m_items.ContainsKey(item.ItemID)) 777 item.AssetID = m_items[item.ItemID].AssetID;
624 { 778 }
625 item.ParentID = m_part.UUID; 779 else if ((InventoryType)item.Type == InventoryType.Notecard)
626 item.ParentPartID = m_part.UUID; 780 {
627 item.Flags = m_items[item.ItemID].Flags; 781 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
628 782
629 // If group permissions have been set on, check that the groupID is up to date in case it has 783 if (presence != null)
630 // changed since permissions were last set.
631 if (item.GroupPermissions != (uint)PermissionMask.None)
632 item.GroupID = m_part.GroupID;
633
634 if (item.AssetID == UUID.Zero)
635 {
636 item.AssetID = m_items[item.ItemID].AssetID;
637 }
638 m_items[item.ItemID] = item;
639 m_inventorySerial++;
640 if (fireScriptEvents)
641 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
642 HasInventoryChanged = true;
643 m_part.ParentGroup.HasGroupChanged = true;
644 return true;
645 }
646 else
647 { 784 {
648 m_log.ErrorFormat( 785 presence.ControllingClient.SendAgentAlertMessage(
649 "[PRIM INVENTORY]: " + 786 "Notecard saved", false);
650 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
651 item.ItemID, m_part.Name, m_part.UUID,
652 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
653 } 787 }
654
655 } 788 }
656 return false; 789
790 m_items[item.ItemID] = item;
791 m_inventorySerial++;
792 if (fireScriptEvents)
793 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
794 HasInventoryChanged = true;
795 m_part.ParentGroup.HasGroupChanged = true;
796 m_items.LockItemsForWrite(false);
797 return true;
657 } 798 }
799 else
800 {
801 m_log.ErrorFormat(
802 "[PRIM INVENTORY]: " +
803 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
804 item.ItemID, m_part.Name, m_part.UUID,
805 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
806 }
807 m_items.LockItemsForWrite(false);
808
809 return false;
658 } 810 }
659 811
660 /// <summary> 812 /// <summary>
@@ -665,52 +817,53 @@ namespace OpenSim.Region.Framework.Scenes
665 /// in this prim's inventory.</returns> 817 /// in this prim's inventory.</returns>
666 public int RemoveInventoryItem(UUID itemID) 818 public int RemoveInventoryItem(UUID itemID)
667 { 819 {
668 lock (m_items) 820 m_items.LockItemsForRead(true);
821
822 if (m_items.ContainsKey(itemID))
669 { 823 {
670 if (m_items.ContainsKey(itemID)) 824 int type = m_items[itemID].InvType;
825 m_items.LockItemsForRead(false);
826 if (type == 10) // Script
671 { 827 {
672 int type = m_items[itemID].InvType; 828 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
673 if (type == 10) // Script 829 }
674 { 830 m_items.LockItemsForWrite(true);
675 m_part.RemoveScriptEvents(itemID); 831 m_items.Remove(itemID);
676 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 832 m_items.LockItemsForWrite(false);
677 } 833 m_inventorySerial++;
678 m_items.Remove(itemID); 834 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
679 m_inventorySerial++;
680 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
681
682 HasInventoryChanged = true;
683 m_part.ParentGroup.HasGroupChanged = true;
684 835
685 int scriptcount = 0; 836 HasInventoryChanged = true;
686 lock (m_items) 837 m_part.ParentGroup.HasGroupChanged = true;
687 {
688 foreach (TaskInventoryItem item in m_items.Values)
689 {
690 if (item.Type == 10)
691 {
692 scriptcount++;
693 }
694 }
695 }
696 838
697 if (scriptcount <= 0) 839 int scriptcount = 0;
840 m_items.LockItemsForRead(true);
841 foreach (TaskInventoryItem item in m_items.Values)
842 {
843 if (item.Type == 10)
698 { 844 {
699 m_part.RemFlag(PrimFlags.Scripted); 845 scriptcount++;
700 } 846 }
701
702 m_part.ScheduleFullUpdate();
703
704 return type;
705 } 847 }
706 else 848 m_items.LockItemsForRead(false);
849
850
851 if (scriptcount <= 0)
707 { 852 {
708 m_log.ErrorFormat( 853 m_part.RemFlag(PrimFlags.Scripted);
709 "[PRIM INVENTORY]: " +
710 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
711 itemID, m_part.Name, m_part.UUID,
712 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
713 } 854 }
855
856 m_part.ScheduleFullUpdate();
857
858 return type;
859 }
860 else
861 {
862 m_items.LockItemsForRead(false);
863 m_log.ErrorFormat(
864 "[PRIM INVENTORY]: " +
865 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
866 itemID, m_part.Name, m_part.UUID);
714 } 867 }
715 868
716 return -1; 869 return -1;
@@ -764,53 +917,54 @@ namespace OpenSim.Region.Framework.Scenes
764 // isn't available (such as drag from prim inventory to agent inventory) 917 // isn't available (such as drag from prim inventory to agent inventory)
765 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 918 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
766 919
767 lock (m_items) 920 m_items.LockItemsForRead(true);
921
922 foreach (TaskInventoryItem item in m_items.Values)
768 { 923 {
769 foreach (TaskInventoryItem item in m_items.Values) 924 UUID ownerID = item.OwnerID;
770 { 925 uint everyoneMask = 0;
771 UUID ownerID = item.OwnerID; 926 uint baseMask = item.BasePermissions;
772 uint everyoneMask = 0; 927 uint ownerMask = item.CurrentPermissions;
773 uint baseMask = item.BasePermissions; 928 uint groupMask = item.GroupPermissions;
774 uint ownerMask = item.CurrentPermissions;
775 uint groupMask = item.GroupPermissions;
776 929
777 invString.AddItemStart(); 930 invString.AddItemStart();
778 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 931 invString.AddNameValueLine("item_id", item.ItemID.ToString());
779 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 932 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
780 933
781 invString.AddPermissionsStart(); 934 invString.AddPermissionsStart();
782 935
783 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 936 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
784 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 937 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
785 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); 938 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
786 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); 939 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
787 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); 940 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
788 941
789 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 942 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
790 invString.AddNameValueLine("owner_id", ownerID.ToString()); 943 invString.AddNameValueLine("owner_id", ownerID.ToString());
791 944
792 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 945 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
793 946
794 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 947 invString.AddNameValueLine("group_id", item.GroupID.ToString());
795 invString.AddSectionEnd(); 948 invString.AddSectionEnd();
796 949
797 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 950 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
798 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); 951 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
799 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); 952 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
800 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); 953 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
801 954
802 invString.AddSaleStart(); 955 invString.AddSaleStart();
803 invString.AddNameValueLine("sale_type", "not"); 956 invString.AddNameValueLine("sale_type", "not");
804 invString.AddNameValueLine("sale_price", "0"); 957 invString.AddNameValueLine("sale_price", "0");
805 invString.AddSectionEnd(); 958 invString.AddSectionEnd();
806 959
807 invString.AddNameValueLine("name", item.Name + "|"); 960 invString.AddNameValueLine("name", item.Name + "|");
808 invString.AddNameValueLine("desc", item.Description + "|"); 961 invString.AddNameValueLine("desc", item.Description + "|");
809 962
810 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 963 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
811 invString.AddSectionEnd(); 964 invString.AddSectionEnd();
812 }
813 } 965 }
966 int count = m_items.Count;
967 m_items.LockItemsForRead(false);
814 968
815 fileData = Utils.StringToBytes(invString.BuildString); 969 fileData = Utils.StringToBytes(invString.BuildString);
816 970
@@ -831,10 +985,9 @@ namespace OpenSim.Region.Framework.Scenes
831 { 985 {
832 if (HasInventoryChanged) 986 if (HasInventoryChanged)
833 { 987 {
834 lock (Items) 988 Items.LockItemsForRead(true);
835 { 989 datastore.StorePrimInventory(m_part.UUID, Items.Values);
836 datastore.StorePrimInventory(m_part.UUID, Items.Values); 990 Items.LockItemsForRead(false);
837 }
838 991
839 HasInventoryChanged = false; 992 HasInventoryChanged = false;
840 } 993 }
@@ -903,90 +1056,76 @@ namespace OpenSim.Region.Framework.Scenes
903 { 1056 {
904 uint mask=0x7fffffff; 1057 uint mask=0x7fffffff;
905 1058
906 lock (m_items) 1059 foreach (TaskInventoryItem item in m_items.Values)
907 { 1060 {
908 foreach (TaskInventoryItem item in m_items.Values) 1061 if (item.InvType != (int)InventoryType.Object)
909 { 1062 {
910 if (item.InvType != (int)InventoryType.Object) 1063 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
911 { 1064 mask &= ~((uint)PermissionMask.Copy >> 13);
912 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1065 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
913 mask &= ~((uint)PermissionMask.Copy >> 13); 1066 mask &= ~((uint)PermissionMask.Transfer >> 13);
914 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1067 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
915 mask &= ~((uint)PermissionMask.Transfer >> 13); 1068 mask &= ~((uint)PermissionMask.Modify >> 13);
916 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 1069 }
917 mask &= ~((uint)PermissionMask.Modify >> 13); 1070 else
918 } 1071 {
919 else 1072 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
920 { 1073 mask &= ~((uint)PermissionMask.Copy >> 13);
921 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1074 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
922 mask &= ~((uint)PermissionMask.Copy >> 13); 1075 mask &= ~((uint)PermissionMask.Transfer >> 13);
923 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1076 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
924 mask &= ~((uint)PermissionMask.Transfer >> 13); 1077 mask &= ~((uint)PermissionMask.Modify >> 13);
925 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
926 mask &= ~((uint)PermissionMask.Modify >> 13);
927 }
928
929 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
930 mask &= ~(uint)PermissionMask.Copy;
931 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
932 mask &= ~(uint)PermissionMask.Transfer;
933 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
934 mask &= ~(uint)PermissionMask.Modify;
935 } 1078 }
1079
1080 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1081 mask &= ~(uint)PermissionMask.Copy;
1082 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1083 mask &= ~(uint)PermissionMask.Transfer;
1084 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1085 mask &= ~(uint)PermissionMask.Modify;
936 } 1086 }
937
938 return mask; 1087 return mask;
939 } 1088 }
940 1089
941 public void ApplyNextOwnerPermissions() 1090 public void ApplyNextOwnerPermissions()
942 { 1091 {
943 lock (m_items) 1092 foreach (TaskInventoryItem item in m_items.Values)
944 { 1093 {
945 foreach (TaskInventoryItem item in m_items.Values) 1094 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
946 { 1095 {
947 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 1096 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
948 { 1097 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
949 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1098 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
950 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 1099 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
951 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1100 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
952 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 1101 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
953 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) 1102 item.CurrentPermissions |= 8;
954 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
955 item.CurrentPermissions |= 8;
956 }
957 item.CurrentPermissions &= item.NextPermissions;
958 item.BasePermissions &= item.NextPermissions;
959 item.EveryonePermissions &= item.NextPermissions;
960 item.OwnerChanged = true;
961 } 1103 }
1104 item.OwnerChanged = true;
1105 item.CurrentPermissions &= item.NextPermissions;
1106 item.BasePermissions &= item.NextPermissions;
1107 item.EveryonePermissions &= item.NextPermissions;
962 } 1108 }
963 } 1109 }
964 1110
965 public void ApplyGodPermissions(uint perms) 1111 public void ApplyGodPermissions(uint perms)
966 { 1112 {
967 lock (m_items) 1113 foreach (TaskInventoryItem item in m_items.Values)
968 { 1114 {
969 foreach (TaskInventoryItem item in m_items.Values) 1115 item.CurrentPermissions = perms;
970 { 1116 item.BasePermissions = perms;
971 item.CurrentPermissions = perms;
972 item.BasePermissions = perms;
973 }
974 } 1117 }
975 } 1118 }
976 1119
977 public bool ContainsScripts() 1120 public bool ContainsScripts()
978 { 1121 {
979 lock (m_items) 1122 foreach (TaskInventoryItem item in m_items.Values)
980 { 1123 {
981 foreach (TaskInventoryItem item in m_items.Values) 1124 if (item.InvType == (int)InventoryType.LSL)
982 { 1125 {
983 if (item.InvType == (int)InventoryType.LSL) 1126 return true;
984 {
985 return true;
986 }
987 } 1127 }
988 } 1128 }
989
990 return false; 1129 return false;
991 } 1130 }
992 1131
@@ -994,46 +1133,52 @@ namespace OpenSim.Region.Framework.Scenes
994 { 1133 {
995 List<UUID> ret = new List<UUID>(); 1134 List<UUID> ret = new List<UUID>();
996 1135
997 lock (m_items) 1136 foreach (TaskInventoryItem item in m_items.Values)
998 { 1137 ret.Add(item.ItemID);
999 foreach (TaskInventoryItem item in m_items.Values)
1000 ret.Add(item.ItemID);
1001 }
1002 1138
1003 return ret; 1139 return ret;
1004 } 1140 }
1005 1141
1006 public Dictionary<UUID, string> GetScriptStates() 1142 public Dictionary<UUID, string> GetScriptStates()
1007 { 1143 {
1144 return GetScriptStates(false);
1145 }
1146
1147 public Dictionary<UUID, string> GetScriptStates(bool oldIDs)
1148 {
1008 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); 1149 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
1009 1150
1010 Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); 1151 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
1011 if (engines == null) // No engine at all 1152 if (engines == null) // No engine at all
1012 return ret; 1153 return ret;
1013 1154
1014 lock (m_items) 1155 foreach (TaskInventoryItem item in m_items.Values)
1015 { 1156 {
1016 foreach (TaskInventoryItem item in m_items.Values) 1157 if (item.InvType == (int)InventoryType.LSL)
1017 { 1158 {
1018 if (item.InvType == (int)InventoryType.LSL) 1159 foreach (IScriptModule e in engines)
1019 { 1160 {
1020 foreach (IScriptModule e in engines) 1161 if (e != null)
1021 { 1162 {
1022 if (e != null) 1163 string n = e.GetXMLState(item.ItemID);
1164 if (n != String.Empty)
1023 { 1165 {
1024 string n = e.GetXMLState(item.ItemID); 1166 if (oldIDs)
1025 if (n != String.Empty) 1167 {
1168 if (!ret.ContainsKey(item.OldItemID))
1169 ret[item.OldItemID] = n;
1170 }
1171 else
1026 { 1172 {
1027 if (!ret.ContainsKey(item.ItemID)) 1173 if (!ret.ContainsKey(item.ItemID))
1028 ret[item.ItemID] = n; 1174 ret[item.ItemID] = n;
1029 break;
1030 } 1175 }
1176 break;
1031 } 1177 }
1032 } 1178 }
1033 } 1179 }
1034 } 1180 }
1035 } 1181 }
1036
1037 return ret; 1182 return ret;
1038 } 1183 }
1039 1184
@@ -1043,25 +1188,27 @@ namespace OpenSim.Region.Framework.Scenes
1043 if (engines == null) 1188 if (engines == null)
1044 return; 1189 return;
1045 1190
1046 lock (m_items) 1191
1192 Items.LockItemsForRead(true);
1193
1194 foreach (TaskInventoryItem item in m_items.Values)
1047 { 1195 {
1048 foreach (TaskInventoryItem item in m_items.Values) 1196 if (item.InvType == (int)InventoryType.LSL)
1049 { 1197 {
1050 if (item.InvType == (int)InventoryType.LSL) 1198 foreach (IScriptModule engine in engines)
1051 { 1199 {
1052 foreach (IScriptModule engine in engines) 1200 if (engine != null)
1053 { 1201 {
1054 if (engine != null) 1202 if (item.OwnerChanged)
1055 { 1203 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
1056 if (item.OwnerChanged) 1204 item.OwnerChanged = false;
1057 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); 1205 engine.ResumeScript(item.ItemID);
1058 item.OwnerChanged = false;
1059 engine.ResumeScript(item.ItemID);
1060 }
1061 } 1206 }
1062 } 1207 }
1063 } 1208 }
1064 } 1209 }
1210
1211 Items.LockItemsForRead(false);
1065 } 1212 }
1066 } 1213 }
1067} 1214}