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.cs768
1 files changed, 466 insertions, 302 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index db723fa..d04d87b 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -38,6 +38,7 @@ using OpenSim.Framework;
38using OpenSim.Region.Framework.Interfaces; 38using OpenSim.Region.Framework.Interfaces;
39using OpenSim.Region.Framework.Scenes.Scripting; 39using OpenSim.Region.Framework.Scenes.Scripting;
40using OpenSim.Region.Framework.Scenes.Serialization; 40using OpenSim.Region.Framework.Scenes.Serialization;
41using PermissionMask = OpenSim.Framework.PermissionMask;
41 42
42namespace OpenSim.Region.Framework.Scenes 43namespace OpenSim.Region.Framework.Scenes
43{ 44{
@@ -48,6 +49,9 @@ namespace OpenSim.Region.Framework.Scenes
48 private string m_inventoryFileName = String.Empty; 49 private string m_inventoryFileName = String.Empty;
49 private byte[] m_inventoryFileData = new byte[0]; 50 private byte[] m_inventoryFileData = new byte[0];
50 private uint m_inventoryFileNameSerial = 0; 51 private uint m_inventoryFileNameSerial = 0;
52 private bool m_inventoryPrivileged = false;
53
54 private Dictionary<UUID, ArrayList> m_scriptErrors = new Dictionary<UUID, ArrayList>();
51 55
52 /// <value> 56 /// <value>
53 /// The part to which the inventory belongs. 57 /// The part to which the inventory belongs.
@@ -84,7 +88,9 @@ namespace OpenSim.Region.Framework.Scenes
84 /// </value> 88 /// </value>
85 protected internal TaskInventoryDictionary Items 89 protected internal TaskInventoryDictionary Items
86 { 90 {
87 get { return m_items; } 91 get {
92 return m_items;
93 }
88 set 94 set
89 { 95 {
90 m_items = value; 96 m_items = value;
@@ -133,38 +139,45 @@ namespace OpenSim.Region.Framework.Scenes
133 public void ResetInventoryIDs() 139 public void ResetInventoryIDs()
134 { 140 {
135 if (null == m_part) 141 if (null == m_part)
136 return; 142 m_items.LockItemsForWrite(true);
137 143
138 lock (m_items) 144 if (Items.Count == 0)
139 { 145 {
140 if (0 == m_items.Count) 146 m_items.LockItemsForWrite(false);
141 return; 147 return;
148 }
142 149
143 IList<TaskInventoryItem> items = GetInventoryItems(); 150 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
144 m_items.Clear(); 151 Items.Clear();
145 152
146 foreach (TaskInventoryItem item in items) 153 foreach (TaskInventoryItem item in items)
147 { 154 {
148 item.ResetIDs(m_part.UUID); 155 item.ResetIDs(m_part.UUID);
149 m_items.Add(item.ItemID, item); 156 Items.Add(item.ItemID, item);
150 }
151 } 157 }
158 m_items.LockItemsForWrite(false);
152 } 159 }
153 160
154 public void ResetObjectID() 161 public void ResetObjectID()
155 { 162 {
156 lock (Items) 163 m_items.LockItemsForWrite(true);
164
165 if (Items.Count == 0)
157 { 166 {
158 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 167 m_items.LockItemsForWrite(false);
159 Items.Clear(); 168 return;
160
161 foreach (TaskInventoryItem item in items)
162 {
163 item.ParentPartID = m_part.UUID;
164 item.ParentID = m_part.UUID;
165 Items.Add(item.ItemID, item);
166 }
167 } 169 }
170
171 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
172 Items.Clear();
173
174 foreach (TaskInventoryItem item in items)
175 {
176 item.ParentPartID = m_part.UUID;
177 item.ParentID = m_part.UUID;
178 Items.Add(item.ItemID, item);
179 }
180 m_items.LockItemsForWrite(false);
168 } 181 }
169 182
170 /// <summary> 183 /// <summary>
@@ -173,17 +186,14 @@ namespace OpenSim.Region.Framework.Scenes
173 /// <param name="ownerId"></param> 186 /// <param name="ownerId"></param>
174 public void ChangeInventoryOwner(UUID ownerId) 187 public void ChangeInventoryOwner(UUID ownerId)
175 { 188 {
176 lock (Items) 189 List<TaskInventoryItem> items = GetInventoryItems();
177 { 190
178 if (0 == Items.Count) 191 if (items.Count == 0)
179 { 192 return;
180 return;
181 }
182 }
183 193
194 m_items.LockItemsForWrite(true);
184 HasInventoryChanged = true; 195 HasInventoryChanged = true;
185 m_part.ParentGroup.HasGroupChanged = true; 196 m_part.ParentGroup.HasGroupChanged = true;
186 List<TaskInventoryItem> items = GetInventoryItems();
187 foreach (TaskInventoryItem item in items) 197 foreach (TaskInventoryItem item in items)
188 { 198 {
189 if (ownerId != item.OwnerID) 199 if (ownerId != item.OwnerID)
@@ -194,6 +204,7 @@ namespace OpenSim.Region.Framework.Scenes
194 item.PermsGranter = UUID.Zero; 204 item.PermsGranter = UUID.Zero;
195 item.OwnerChanged = true; 205 item.OwnerChanged = true;
196 } 206 }
207 m_items.LockItemsForWrite(false);
197 } 208 }
198 209
199 /// <summary> 210 /// <summary>
@@ -202,12 +213,11 @@ namespace OpenSim.Region.Framework.Scenes
202 /// <param name="groupID"></param> 213 /// <param name="groupID"></param>
203 public void ChangeInventoryGroup(UUID groupID) 214 public void ChangeInventoryGroup(UUID groupID)
204 { 215 {
205 lock (Items) 216 m_items.LockItemsForWrite(true);
217 if (0 == Items.Count)
206 { 218 {
207 if (0 == Items.Count) 219 m_items.LockItemsForWrite(false);
208 { 220 return;
209 return;
210 }
211 } 221 }
212 222
213 // Don't let this set the HasGroupChanged flag for attachments 223 // Don't let this set the HasGroupChanged flag for attachments
@@ -219,12 +229,15 @@ namespace OpenSim.Region.Framework.Scenes
219 m_part.ParentGroup.HasGroupChanged = true; 229 m_part.ParentGroup.HasGroupChanged = true;
220 } 230 }
221 231
222 List<TaskInventoryItem> items = GetInventoryItems(); 232 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
223 foreach (TaskInventoryItem item in items) 233 foreach (TaskInventoryItem item in items)
224 { 234 {
225 if (groupID != item.GroupID) 235 if (groupID != item.GroupID)
236 {
226 item.GroupID = groupID; 237 item.GroupID = groupID;
238 }
227 } 239 }
240 m_items.LockItemsForWrite(false);
228 } 241 }
229 242
230 private void QueryScriptStates() 243 private void QueryScriptStates()
@@ -232,15 +245,18 @@ namespace OpenSim.Region.Framework.Scenes
232 if (m_part == null || m_part.ParentGroup == null || m_part.ParentGroup.Scene == null) 245 if (m_part == null || m_part.ParentGroup == null || m_part.ParentGroup.Scene == null)
233 return; 246 return;
234 247
235 lock (Items) 248 Items.LockItemsForRead(true);
249 foreach (TaskInventoryItem item in Items.Values)
236 { 250 {
237 foreach (TaskInventoryItem item in Items.Values) 251 if (item.InvType == (int)InventoryType.LSL)
238 { 252 {
239 bool running; 253 bool running;
240 if (TryGetScriptInstanceRunning(m_part.ParentGroup.Scene, item, out running)) 254 if (TryGetScriptInstanceRunning(m_part.ParentGroup.Scene, item, out running))
241 item.ScriptRunning = running; 255 item.ScriptRunning = running;
242 } 256 }
243 } 257 }
258
259 Items.LockItemsForRead(false);
244 } 260 }
245 261
246 public bool TryGetScriptInstanceRunning(UUID itemId, out bool running) 262 public bool TryGetScriptInstanceRunning(UUID itemId, out bool running)
@@ -317,7 +333,10 @@ namespace OpenSim.Region.Framework.Scenes
317 { 333 {
318 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); 334 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
319 foreach (TaskInventoryItem item in scripts) 335 foreach (TaskInventoryItem item in scripts)
336 {
320 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); 337 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
338 m_part.RemoveScriptEvents(item.ItemID);
339 }
321 } 340 }
322 341
323 /// <summary> 342 /// <summary>
@@ -339,7 +358,10 @@ namespace OpenSim.Region.Framework.Scenes
339// item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); 358// item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName);
340 359
341 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) 360 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID))
361 {
362 StoreScriptError(item.ItemID, "no permission");
342 return false; 363 return false;
364 }
343 365
344 m_part.AddFlag(PrimFlags.Scripted); 366 m_part.AddFlag(PrimFlags.Scripted);
345 367
@@ -349,14 +371,13 @@ namespace OpenSim.Region.Framework.Scenes
349 if (stateSource == 2 && // Prim crossing 371 if (stateSource == 2 && // Prim crossing
350 m_part.ParentGroup.Scene.m_trustBinaries) 372 m_part.ParentGroup.Scene.m_trustBinaries)
351 { 373 {
352 lock (m_items) 374 m_items.LockItemsForWrite(true);
353 { 375 m_items[item.ItemID].PermsMask = 0;
354 m_items[item.ItemID].PermsMask = 0; 376 m_items[item.ItemID].PermsGranter = UUID.Zero;
355 m_items[item.ItemID].PermsGranter = UUID.Zero; 377 m_items.LockItemsForWrite(false);
356 }
357
358 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 378 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
359 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 379 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
380 StoreScriptErrors(item.ItemID, null);
360 m_part.ParentGroup.AddActiveScriptCount(1); 381 m_part.ParentGroup.AddActiveScriptCount(1);
361 m_part.ScheduleFullUpdate(); 382 m_part.ScheduleFullUpdate();
362 return true; 383 return true;
@@ -365,6 +386,8 @@ namespace OpenSim.Region.Framework.Scenes
365 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); 386 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
366 if (null == asset) 387 if (null == asset)
367 { 388 {
389 string msg = String.Format("asset ID {0} could not be found", item.AssetID);
390 StoreScriptError(item.ItemID, msg);
368 m_log.ErrorFormat( 391 m_log.ErrorFormat(
369 "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", 392 "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
370 item.Name, item.ItemID, m_part.AbsolutePosition, 393 item.Name, item.ItemID, m_part.AbsolutePosition,
@@ -377,16 +400,18 @@ namespace OpenSim.Region.Framework.Scenes
377 if (m_part.ParentGroup.m_savedScriptState != null) 400 if (m_part.ParentGroup.m_savedScriptState != null)
378 item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); 401 item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID);
379 402
380 lock (m_items) 403 m_items.LockItemsForWrite(true);
381 { 404
382 m_items[item.ItemID].OldItemID = item.OldItemID; 405 m_items[item.ItemID].OldItemID = item.OldItemID;
383 m_items[item.ItemID].PermsMask = 0; 406 m_items[item.ItemID].PermsMask = 0;
384 m_items[item.ItemID].PermsGranter = UUID.Zero; 407 m_items[item.ItemID].PermsGranter = UUID.Zero;
385 }
386 408
409 m_items.LockItemsForWrite(false);
410
387 string script = Utils.BytesToString(asset.Data); 411 string script = Utils.BytesToString(asset.Data);
388 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 412 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
389 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 413 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
414 StoreScriptErrors(item.ItemID, null);
390 if (!item.ScriptRunning) 415 if (!item.ScriptRunning)
391 m_part.ParentGroup.Scene.EventManager.TriggerStopScript( 416 m_part.ParentGroup.Scene.EventManager.TriggerStopScript(
392 m_part.LocalId, item.ItemID); 417 m_part.LocalId, item.ItemID);
@@ -459,22 +484,149 @@ namespace OpenSim.Region.Framework.Scenes
459 return stateID; 484 return stateID;
460 } 485 }
461 486
487 /// <summary>
488 /// Start a script which is in this prim's inventory.
489 /// Some processing may occur in the background, but this routine returns asap.
490 /// </summary>
491 /// <param name="itemId">
492 /// A <see cref="UUID"/>
493 /// </param>
462 public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 494 public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
463 { 495 {
464 TaskInventoryItem item = GetInventoryItem(itemId); 496 lock (m_scriptErrors)
465 if (item != null)
466 { 497 {
467 return CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 498 // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion
499 m_scriptErrors.Remove(itemId);
500 }
501 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
502 return true;
503 }
504
505 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
506 {
507 m_items.LockItemsForRead(true);
508 if (m_items.ContainsKey(itemId))
509 {
510 if (m_items.ContainsKey(itemId))
511 {
512 m_items.LockItemsForRead(false);
513 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
514 }
515 else
516 {
517 m_items.LockItemsForRead(false);
518 string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID,
519 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
520 StoreScriptError(itemId, msg);
521 m_log.ErrorFormat(
522 "[PRIM INVENTORY]: " +
523 "Couldn't start script with ID {0} since it {1}", itemId, msg);
524 }
468 } 525 }
469 else 526 else
470 { 527 {
528 m_items.LockItemsForRead(false);
529 string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID);
530 StoreScriptError(itemId, msg);
471 m_log.ErrorFormat( 531 m_log.ErrorFormat(
472 "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 532 "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
473 itemId, m_part.Name, m_part.UUID, 533 itemId, m_part.Name, m_part.UUID,
474 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 534 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
535 }
536
537 }
475 538
476 return false; 539 /// <summary>
540 /// Start a script which is in this prim's inventory and return any compilation error messages.
541 /// </summary>
542 /// <param name="itemId">
543 /// A <see cref="UUID"/>
544 /// </param>
545 public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
546 {
547 ArrayList errors;
548
549 // Indicate to CreateScriptInstanceInternal() we want it to
550 // post any compilation/loading error messages
551 lock (m_scriptErrors)
552 {
553 m_scriptErrors[itemId] = null;
554 }
555
556 // Perform compilation/loading
557 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
558
559 // Wait for and retrieve any errors
560 lock (m_scriptErrors)
561 {
562 while ((errors = m_scriptErrors[itemId]) == null)
563 {
564 if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
565 {
566 m_log.ErrorFormat(
567 "[PRIM INVENTORY]: " +
568 "timedout waiting for script {0} errors", itemId);
569 errors = m_scriptErrors[itemId];
570 if (errors == null)
571 {
572 errors = new ArrayList(1);
573 errors.Add("timedout waiting for errors");
574 }
575 break;
576 }
577 }
578 m_scriptErrors.Remove(itemId);
477 } 579 }
580 return errors;
581 }
582
583 // Signal to CreateScriptInstanceEr() that compilation/loading is complete
584 private void StoreScriptErrors(UUID itemId, ArrayList errors)
585 {
586 lock (m_scriptErrors)
587 {
588 // If compilation/loading initiated via CreateScriptInstance(),
589 // it does not want the errors, so just get out
590 if (!m_scriptErrors.ContainsKey(itemId))
591 {
592 return;
593 }
594
595 // Initiated via CreateScriptInstanceEr(), if we know what the
596 // errors are, save them and wake CreateScriptInstanceEr().
597 if (errors != null)
598 {
599 m_scriptErrors[itemId] = errors;
600 System.Threading.Monitor.PulseAll(m_scriptErrors);
601 return;
602 }
603 }
604
605 // Initiated via CreateScriptInstanceEr() but we don't know what
606 // the errors are yet, so retrieve them from the script engine.
607 // This may involve some waiting internal to GetScriptErrors().
608 errors = GetScriptErrors(itemId);
609
610 // Get a default non-null value to indicate success.
611 if (errors == null)
612 {
613 errors = new ArrayList();
614 }
615
616 // Post to CreateScriptInstanceEr() and wake it up
617 lock (m_scriptErrors)
618 {
619 m_scriptErrors[itemId] = errors;
620 System.Threading.Monitor.PulseAll(m_scriptErrors);
621 }
622 }
623
624 // Like StoreScriptErrors(), but just posts a single string message
625 private void StoreScriptError(UUID itemId, string message)
626 {
627 ArrayList errors = new ArrayList(1);
628 errors.Add(message);
629 StoreScriptErrors(itemId, errors);
478 } 630 }
479 631
480 /// <summary> 632 /// <summary>
@@ -487,15 +639,7 @@ namespace OpenSim.Region.Framework.Scenes
487 /// </param> 639 /// </param>
488 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 640 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
489 { 641 {
490 bool scriptPresent = false; 642 if (m_items.ContainsKey(itemId))
491
492 lock (m_items)
493 {
494 if (m_items.ContainsKey(itemId))
495 scriptPresent = true;
496 }
497
498 if (scriptPresent)
499 { 643 {
500 if (!sceneObjectBeingDeleted) 644 if (!sceneObjectBeingDeleted)
501 m_part.RemoveScriptEvents(itemId); 645 m_part.RemoveScriptEvents(itemId);
@@ -565,14 +709,16 @@ namespace OpenSim.Region.Framework.Scenes
565 /// <returns></returns> 709 /// <returns></returns>
566 private bool InventoryContainsName(string name) 710 private bool InventoryContainsName(string name)
567 { 711 {
568 lock (m_items) 712 m_items.LockItemsForRead(true);
713 foreach (TaskInventoryItem item in m_items.Values)
569 { 714 {
570 foreach (TaskInventoryItem item in m_items.Values) 715 if (item.Name == name)
571 { 716 {
572 if (item.Name == name) 717 m_items.LockItemsForRead(false);
573 return true; 718 return true;
574 } 719 }
575 } 720 }
721 m_items.LockItemsForRead(false);
576 return false; 722 return false;
577 } 723 }
578 724
@@ -614,8 +760,9 @@ namespace OpenSim.Region.Framework.Scenes
614 /// <param name="item"></param> 760 /// <param name="item"></param>
615 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 761 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
616 { 762 {
617 List<TaskInventoryItem> il = GetInventoryItems(); 763 m_items.LockItemsForRead(true);
618 764 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
765 m_items.LockItemsForRead(false);
619 foreach (TaskInventoryItem i in il) 766 foreach (TaskInventoryItem i in il)
620 { 767 {
621 if (i.Name == item.Name) 768 if (i.Name == item.Name)
@@ -653,14 +800,14 @@ namespace OpenSim.Region.Framework.Scenes
653 item.Name = name; 800 item.Name = name;
654 item.GroupID = m_part.GroupID; 801 item.GroupID = m_part.GroupID;
655 802
656 lock (m_items) 803 m_items.LockItemsForWrite(true);
657 m_items.Add(item.ItemID, item); 804 m_items.Add(item.ItemID, item);
658 805 m_items.LockItemsForWrite(false);
659 if (allowedDrop) 806 if (allowedDrop)
660 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 807 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
661 else 808 else
662 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 809 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
663 810
664 m_inventorySerial++; 811 m_inventorySerial++;
665 //m_inventorySerial += 2; 812 //m_inventorySerial += 2;
666 HasInventoryChanged = true; 813 HasInventoryChanged = true;
@@ -676,15 +823,15 @@ namespace OpenSim.Region.Framework.Scenes
676 /// <param name="items"></param> 823 /// <param name="items"></param>
677 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 824 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
678 { 825 {
679 lock (m_items) 826 m_items.LockItemsForWrite(true);
827 foreach (TaskInventoryItem item in items)
680 { 828 {
681 foreach (TaskInventoryItem item in items) 829 m_items.Add(item.ItemID, item);
682 { 830// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
683 m_items.Add(item.ItemID, item);
684// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
685 }
686 m_inventorySerial++;
687 } 831 }
832 m_items.LockItemsForWrite(false);
833
834 m_inventorySerial++;
688 } 835 }
689 836
690 /// <summary> 837 /// <summary>
@@ -695,23 +842,24 @@ namespace OpenSim.Region.Framework.Scenes
695 public TaskInventoryItem GetInventoryItem(UUID itemId) 842 public TaskInventoryItem GetInventoryItem(UUID itemId)
696 { 843 {
697 TaskInventoryItem item; 844 TaskInventoryItem item;
698 845 m_items.LockItemsForRead(true);
699 lock (m_items) 846 m_items.TryGetValue(itemId, out item);
700 m_items.TryGetValue(itemId, out item); 847 m_items.LockItemsForRead(false);
701
702 return item; 848 return item;
703 } 849 }
704 850
705 public TaskInventoryItem GetInventoryItem(string name) 851 public TaskInventoryItem GetInventoryItem(string name)
706 { 852 {
707 lock (m_items) 853 m_items.LockItemsForRead(true);
854 foreach (TaskInventoryItem item in m_items.Values)
708 { 855 {
709 foreach (TaskInventoryItem item in m_items.Values) 856 if (item.Name == name)
710 { 857 {
711 if (item.Name == name) 858 m_items.LockItemsForRead(false);
712 return item; 859 return item;
713 } 860 }
714 } 861 }
862 m_items.LockItemsForRead(false);
715 863
716 return null; 864 return null;
717 } 865 }
@@ -720,15 +868,16 @@ namespace OpenSim.Region.Framework.Scenes
720 { 868 {
721 List<TaskInventoryItem> items = new List<TaskInventoryItem>(); 869 List<TaskInventoryItem> items = new List<TaskInventoryItem>();
722 870
723 lock (m_items) 871 m_items.LockItemsForRead(true);
872
873 foreach (TaskInventoryItem item in m_items.Values)
724 { 874 {
725 foreach (TaskInventoryItem item in m_items.Values) 875 if (item.Name == name)
726 { 876 items.Add(item);
727 if (item.Name == name)
728 items.Add(item);
729 }
730 } 877 }
731 878
879 m_items.LockItemsForRead(false);
880
732 return items; 881 return items;
733 } 882 }
734 883
@@ -747,6 +896,10 @@ namespace OpenSim.Region.Framework.Scenes
747 string xmlData = Utils.BytesToString(rezAsset.Data); 896 string xmlData = Utils.BytesToString(rezAsset.Data);
748 SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); 897 SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
749 898
899 group.RootPart.AttachPoint = group.RootPart.Shape.State;
900 group.RootPart.AttachOffset = group.AbsolutePosition;
901 group.RootPart.AttachRotation = group.GroupRotation;
902
750 group.ResetIDs(); 903 group.ResetIDs();
751 904
752 SceneObjectPart rootPart = group.GetPart(group.UUID); 905 SceneObjectPart rootPart = group.GetPart(group.UUID);
@@ -821,8 +974,9 @@ namespace OpenSim.Region.Framework.Scenes
821 974
822 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) 975 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged)
823 { 976 {
824 TaskInventoryItem it = GetInventoryItem(item.ItemID); 977 m_items.LockItemsForWrite(true);
825 if (it != null) 978
979 if (m_items.ContainsKey(item.ItemID))
826 { 980 {
827// m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); 981// m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name);
828 982
@@ -835,14 +989,10 @@ namespace OpenSim.Region.Framework.Scenes
835 item.GroupID = m_part.GroupID; 989 item.GroupID = m_part.GroupID;
836 990
837 if (item.AssetID == UUID.Zero) 991 if (item.AssetID == UUID.Zero)
838 item.AssetID = it.AssetID; 992 item.AssetID = m_items[item.ItemID].AssetID;
839 993
840 lock (m_items) 994 m_items[item.ItemID] = item;
841 { 995 m_inventorySerial++;
842 m_items[item.ItemID] = item;
843 m_inventorySerial++;
844 }
845
846 if (fireScriptEvents) 996 if (fireScriptEvents)
847 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 997 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
848 998
@@ -851,7 +1001,7 @@ namespace OpenSim.Region.Framework.Scenes
851 HasInventoryChanged = true; 1001 HasInventoryChanged = true;
852 m_part.ParentGroup.HasGroupChanged = true; 1002 m_part.ParentGroup.HasGroupChanged = true;
853 } 1003 }
854 1004 m_items.LockItemsForWrite(false);
855 return true; 1005 return true;
856 } 1006 }
857 else 1007 else
@@ -862,8 +1012,9 @@ namespace OpenSim.Region.Framework.Scenes
862 item.ItemID, m_part.Name, m_part.UUID, 1012 item.ItemID, m_part.Name, m_part.UUID,
863 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 1013 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
864 } 1014 }
865 return false; 1015 m_items.LockItemsForWrite(false);
866 1016
1017 return false;
867 } 1018 }
868 1019
869 /// <summary> 1020 /// <summary>
@@ -874,43 +1025,59 @@ namespace OpenSim.Region.Framework.Scenes
874 /// in this prim's inventory.</returns> 1025 /// in this prim's inventory.</returns>
875 public int RemoveInventoryItem(UUID itemID) 1026 public int RemoveInventoryItem(UUID itemID)
876 { 1027 {
877 TaskInventoryItem item = GetInventoryItem(itemID); 1028 m_items.LockItemsForRead(true);
878 if (item != null) 1029
1030 if (m_items.ContainsKey(itemID))
879 { 1031 {
880 int type = m_items[itemID].InvType; 1032 int type = m_items[itemID].InvType;
1033 m_items.LockItemsForRead(false);
881 if (type == 10) // Script 1034 if (type == 10) // Script
882 { 1035 {
883 m_part.RemoveScriptEvents(itemID);
884 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 1036 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
885 } 1037 }
1038 m_items.LockItemsForWrite(true);
886 m_items.Remove(itemID); 1039 m_items.Remove(itemID);
1040 m_items.LockItemsForWrite(false);
887 m_inventorySerial++; 1041 m_inventorySerial++;
888 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 1042 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
889 1043
890 HasInventoryChanged = true; 1044 HasInventoryChanged = true;
891 m_part.ParentGroup.HasGroupChanged = true; 1045 m_part.ParentGroup.HasGroupChanged = true;
892 1046
893 if (!ContainsScripts()) 1047 int scriptcount = 0;
1048 m_items.LockItemsForRead(true);
1049 foreach (TaskInventoryItem item in m_items.Values)
1050 {
1051 if (item.Type == 10)
1052 {
1053 scriptcount++;
1054 }
1055 }
1056 m_items.LockItemsForRead(false);
1057
1058
1059 if (scriptcount <= 0)
1060 {
894 m_part.RemFlag(PrimFlags.Scripted); 1061 m_part.RemFlag(PrimFlags.Scripted);
1062 }
895 1063
896 m_part.ScheduleFullUpdate(); 1064 m_part.ScheduleFullUpdate();
897 1065
898 return type; 1066 return type;
899
900 } 1067 }
901 else 1068 else
902 { 1069 {
1070 m_items.LockItemsForRead(false);
903 m_log.ErrorFormat( 1071 m_log.ErrorFormat(
904 "[PRIM INVENTORY]: " + 1072 "[PRIM INVENTORY]: " +
905 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 1073 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
906 itemID, m_part.Name, m_part.UUID, 1074 itemID, m_part.Name, m_part.UUID);
907 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
908 } 1075 }
909 1076
910 return -1; 1077 return -1;
911 } 1078 }
912 1079
913 private bool CreateInventoryFile() 1080 private bool CreateInventoryFileName()
914 { 1081 {
915// m_log.DebugFormat( 1082// m_log.DebugFormat(
916// "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", 1083// "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}",
@@ -919,70 +1086,12 @@ namespace OpenSim.Region.Framework.Scenes
919 if (m_inventoryFileName == String.Empty || 1086 if (m_inventoryFileName == String.Empty ||
920 m_inventoryFileNameSerial < m_inventorySerial) 1087 m_inventoryFileNameSerial < m_inventorySerial)
921 { 1088 {
922 // Something changed, we need to create a new file
923 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; 1089 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
924 m_inventoryFileNameSerial = m_inventorySerial; 1090 m_inventoryFileNameSerial = m_inventorySerial;
925 1091
926 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
927
928 lock (m_items)
929 {
930 foreach (TaskInventoryItem item in m_items.Values)
931 {
932// m_log.DebugFormat(
933// "[PRIM INVENTORY]: Adding item {0} {1} for serial {2} on prim {3} {4} {5}",
934// item.Name, item.ItemID, m_inventorySerial, m_part.Name, m_part.UUID, m_part.LocalId);
935
936 UUID ownerID = item.OwnerID;
937 uint everyoneMask = 0;
938 uint baseMask = item.BasePermissions;
939 uint ownerMask = item.CurrentPermissions;
940 uint groupMask = item.GroupPermissions;
941
942 invString.AddItemStart();
943 invString.AddNameValueLine("item_id", item.ItemID.ToString());
944 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
945
946 invString.AddPermissionsStart();
947
948 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
949 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
950 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
951 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
952 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
953
954 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
955 invString.AddNameValueLine("owner_id", ownerID.ToString());
956
957 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
958
959 invString.AddNameValueLine("group_id", item.GroupID.ToString());
960 invString.AddSectionEnd();
961
962 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
963 invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type));
964 invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType));
965 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
966
967 invString.AddSaleStart();
968 invString.AddNameValueLine("sale_type", "not");
969 invString.AddNameValueLine("sale_price", "0");
970 invString.AddSectionEnd();
971
972 invString.AddNameValueLine("name", item.Name + "|");
973 invString.AddNameValueLine("desc", item.Description + "|");
974
975 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
976 invString.AddSectionEnd();
977 }
978 }
979
980 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
981
982 return true; 1092 return true;
983 } 1093 }
984 1094
985 // No need to recreate, the existing file is fine
986 return false; 1095 return false;
987 } 1096 }
988 1097
@@ -992,43 +1101,110 @@ namespace OpenSim.Region.Framework.Scenes
992 /// <param name="xferManager"></param> 1101 /// <param name="xferManager"></param>
993 public void RequestInventoryFile(IClientAPI client, IXfer xferManager) 1102 public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
994 { 1103 {
995 lock (m_items) 1104 bool changed = CreateInventoryFileName();
996 {
997 // Don't send a inventory xfer name if there are no items. Doing so causes viewer 3 to crash when rezzing
998 // a new script if any previous deletion has left the prim inventory empty.
999 if (m_items.Count == 0) // No inventory
1000 {
1001// m_log.DebugFormat(
1002// "[PRIM INVENTORY]: Not sending inventory data for part {0} {1} {2} for {3} since no items",
1003// m_part.Name, m_part.LocalId, m_part.UUID, client.Name);
1004 1105
1005 client.SendTaskInventory(m_part.UUID, 0, new byte[0]); 1106 bool includeAssets = false;
1006 return; 1107 if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId))
1007 } 1108 includeAssets = true;
1109
1110 if (m_inventoryPrivileged != includeAssets)
1111 changed = true;
1112
1113 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
1114
1115 Items.LockItemsForRead(true);
1116
1117 if (m_inventorySerial == 0) // No inventory
1118 {
1119 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1120 Items.LockItemsForRead(false);
1121 return;
1122 }
1008 1123
1009 CreateInventoryFile(); 1124 if (m_items.Count == 0) // No inventory
1125 {
1126 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1127 Items.LockItemsForRead(false);
1128 return;
1129 }
1010 1130
1011 // In principle, we should only do the rest if the inventory changed; 1131 if (!changed)
1012 // by sending m_inventorySerial to the client, it ought to know 1132 {
1013 // that nothing changed and that it doesn't need to request the file.
1014 // Unfortunately, it doesn't look like the client optimizes this;
1015 // the client seems to always come back and request the Xfer,
1016 // no matter what value m_inventorySerial has.
1017 // FIXME: Could probably be > 0 here rather than > 2
1018 if (m_inventoryFileData.Length > 2) 1133 if (m_inventoryFileData.Length > 2)
1019 { 1134 {
1020 // Add the file for Xfer 1135 xferManager.AddNewFile(m_inventoryFileName,
1021 // m_log.DebugFormat( 1136 m_inventoryFileData);
1022 // "[PRIM INVENTORY]: Adding inventory file {0} (length {1}) for transfer on {2} {3} {4}", 1137 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
1023 // m_inventoryFileName, m_inventoryFileData.Length, m_part.Name, m_part.UUID, m_part.LocalId); 1138 Util.StringToBytes256(m_inventoryFileName));
1024 1139
1025 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); 1140 Items.LockItemsForRead(false);
1141 return;
1026 } 1142 }
1027
1028 // Tell the client we're ready to Xfer the file
1029 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
1030 Util.StringToBytes256(m_inventoryFileName));
1031 } 1143 }
1144
1145 m_inventoryPrivileged = includeAssets;
1146
1147 foreach (TaskInventoryItem item in m_items.Values)
1148 {
1149 UUID ownerID = item.OwnerID;
1150 uint everyoneMask = 0;
1151 uint baseMask = item.BasePermissions;
1152 uint ownerMask = item.CurrentPermissions;
1153 uint groupMask = item.GroupPermissions;
1154
1155 invString.AddItemStart();
1156 invString.AddNameValueLine("item_id", item.ItemID.ToString());
1157 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
1158
1159 invString.AddPermissionsStart();
1160
1161 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
1162 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
1163 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
1164 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
1165 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
1166
1167 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
1168 invString.AddNameValueLine("owner_id", ownerID.ToString());
1169
1170 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
1171
1172 invString.AddNameValueLine("group_id", item.GroupID.ToString());
1173 invString.AddSectionEnd();
1174
1175 if (includeAssets)
1176 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
1177 else
1178 invString.AddNameValueLine("asset_id", UUID.Zero.ToString());
1179 invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type));
1180 invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType));
1181 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
1182
1183 invString.AddSaleStart();
1184 invString.AddNameValueLine("sale_type", "not");
1185 invString.AddNameValueLine("sale_price", "0");
1186 invString.AddSectionEnd();
1187
1188 invString.AddNameValueLine("name", item.Name + "|");
1189 invString.AddNameValueLine("desc", item.Description + "|");
1190
1191 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
1192 invString.AddSectionEnd();
1193 }
1194
1195 Items.LockItemsForRead(false);
1196
1197 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
1198
1199 if (m_inventoryFileData.Length > 2)
1200 {
1201 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
1202 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
1203 Util.StringToBytes256(m_inventoryFileName));
1204 return;
1205 }
1206
1207 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1032 } 1208 }
1033 1209
1034 /// <summary> 1210 /// <summary>
@@ -1037,13 +1213,19 @@ namespace OpenSim.Region.Framework.Scenes
1037 /// <param name="datastore"></param> 1213 /// <param name="datastore"></param>
1038 public void ProcessInventoryBackup(ISimulationDataService datastore) 1214 public void ProcessInventoryBackup(ISimulationDataService datastore)
1039 { 1215 {
1040 if (HasInventoryChanged) 1216// Removed this because linking will cause an immediate delete of the new
1041 { 1217// child prim from the database and the subsequent storing of the prim sees
1042 HasInventoryChanged = false; 1218// the inventory of it as unchanged and doesn't store it at all. The overhead
1043 List<TaskInventoryItem> items = GetInventoryItems(); 1219// of storing prim inventory needlessly is much less than the aggravation
1044 datastore.StorePrimInventory(m_part.UUID, items); 1220// of prim inventory loss.
1221// if (HasInventoryChanged)
1222// {
1223 Items.LockItemsForRead(true);
1224 datastore.StorePrimInventory(m_part.UUID, Items.Values);
1225 Items.LockItemsForRead(false);
1045 1226
1046 } 1227 HasInventoryChanged = false;
1228// }
1047 } 1229 }
1048 1230
1049 public class InventoryStringBuilder 1231 public class InventoryStringBuilder
@@ -1109,87 +1291,63 @@ namespace OpenSim.Region.Framework.Scenes
1109 { 1291 {
1110 uint mask=0x7fffffff; 1292 uint mask=0x7fffffff;
1111 1293
1112 lock (m_items) 1294 foreach (TaskInventoryItem item in m_items.Values)
1113 { 1295 {
1114 foreach (TaskInventoryItem item in m_items.Values) 1296 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
1297 mask &= ~((uint)PermissionMask.Copy >> 13);
1298 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
1299 mask &= ~((uint)PermissionMask.Transfer >> 13);
1300 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
1301 mask &= ~((uint)PermissionMask.Modify >> 13);
1302
1303 if (item.InvType == (int)InventoryType.Object)
1115 { 1304 {
1116 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1305 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1117 mask &= ~((uint)PermissionMask.Copy >> 13); 1306 mask &= ~((uint)PermissionMask.Copy >> 13);
1118 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1307 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1119 mask &= ~((uint)PermissionMask.Transfer >> 13); 1308 mask &= ~((uint)PermissionMask.Transfer >> 13);
1120 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 1309 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1121 mask &= ~((uint)PermissionMask.Modify >> 13); 1310 mask &= ~((uint)PermissionMask.Modify >> 13);
1122
1123 if (item.InvType != (int)InventoryType.Object)
1124 {
1125 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
1126 mask &= ~((uint)PermissionMask.Copy >> 13);
1127 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
1128 mask &= ~((uint)PermissionMask.Transfer >> 13);
1129 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
1130 mask &= ~((uint)PermissionMask.Modify >> 13);
1131 }
1132 else
1133 {
1134 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1135 mask &= ~((uint)PermissionMask.Copy >> 13);
1136 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1137 mask &= ~((uint)PermissionMask.Transfer >> 13);
1138 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1139 mask &= ~((uint)PermissionMask.Modify >> 13);
1140 }
1141
1142 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1143 mask &= ~(uint)PermissionMask.Copy;
1144 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1145 mask &= ~(uint)PermissionMask.Transfer;
1146 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1147 mask &= ~(uint)PermissionMask.Modify;
1148 } 1311 }
1312
1313 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1314 mask &= ~(uint)PermissionMask.Copy;
1315 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1316 mask &= ~(uint)PermissionMask.Transfer;
1317 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1318 mask &= ~(uint)PermissionMask.Modify;
1149 } 1319 }
1150
1151 return mask; 1320 return mask;
1152 } 1321 }
1153 1322
1154 public void ApplyNextOwnerPermissions() 1323 public void ApplyNextOwnerPermissions()
1155 { 1324 {
1156 lock (m_items) 1325 foreach (TaskInventoryItem item in m_items.Values)
1157 { 1326 {
1158 foreach (TaskInventoryItem item in m_items.Values) 1327 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
1159 { 1328 {
1160// m_log.DebugFormat ( 1329 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1161// "[SCENE OBJECT PART INVENTORY]: Applying next permissions {0} to {1} in {2} with current {3}, base {4}, everyone {5}", 1330 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
1162// item.NextPermissions, item.Name, m_part.Name, item.CurrentPermissions, item.BasePermissions, item.EveryonePermissions); 1331 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1163 1332 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
1164 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 1333 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1165 { 1334 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1166 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1167 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
1168 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1169 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
1170 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1171 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1172 }
1173
1174 item.CurrentPermissions &= item.NextPermissions;
1175 item.BasePermissions &= item.NextPermissions;
1176 item.EveryonePermissions &= item.NextPermissions;
1177 item.OwnerChanged = true;
1178 item.PermsMask = 0;
1179 item.PermsGranter = UUID.Zero;
1180 } 1335 }
1336 item.CurrentPermissions &= item.NextPermissions;
1337 item.BasePermissions &= item.NextPermissions;
1338 item.EveryonePermissions &= item.NextPermissions;
1339 item.OwnerChanged = true;
1340 item.PermsMask = 0;
1341 item.PermsGranter = UUID.Zero;
1181 } 1342 }
1182 } 1343 }
1183 1344
1184 public void ApplyGodPermissions(uint perms) 1345 public void ApplyGodPermissions(uint perms)
1185 { 1346 {
1186 lock (m_items) 1347 foreach (TaskInventoryItem item in m_items.Values)
1187 { 1348 {
1188 foreach (TaskInventoryItem item in m_items.Values) 1349 item.CurrentPermissions = perms;
1189 { 1350 item.BasePermissions = perms;
1190 item.CurrentPermissions = perms;
1191 item.BasePermissions = perms;
1192 }
1193 } 1351 }
1194 1352
1195 m_inventorySerial++; 1353 m_inventorySerial++;
@@ -1202,14 +1360,11 @@ namespace OpenSim.Region.Framework.Scenes
1202 /// <returns></returns> 1360 /// <returns></returns>
1203 public bool ContainsScripts() 1361 public bool ContainsScripts()
1204 { 1362 {
1205 lock (m_items) 1363 foreach (TaskInventoryItem item in m_items.Values)
1206 { 1364 {
1207 foreach (TaskInventoryItem item in m_items.Values) 1365 if (item.InvType == (int)InventoryType.LSL)
1208 { 1366 {
1209 if (item.InvType == (int)InventoryType.LSL) 1367 return true;
1210 {
1211 return true;
1212 }
1213 } 1368 }
1214 } 1369 }
1215 1370
@@ -1223,17 +1378,15 @@ namespace OpenSim.Region.Framework.Scenes
1223 public int ScriptCount() 1378 public int ScriptCount()
1224 { 1379 {
1225 int count = 0; 1380 int count = 0;
1226 lock (m_items) 1381 Items.LockItemsForRead(true);
1382 foreach (TaskInventoryItem item in m_items.Values)
1227 { 1383 {
1228 foreach (TaskInventoryItem item in m_items.Values) 1384 if (item.InvType == (int)InventoryType.LSL)
1229 { 1385 {
1230 if (item.InvType == (int)InventoryType.LSL) 1386 count++;
1231 {
1232 count++;
1233 }
1234 } 1387 }
1235 } 1388 }
1236 1389 Items.LockItemsForRead(false);
1237 return count; 1390 return count;
1238 } 1391 }
1239 /// <summary> 1392 /// <summary>
@@ -1269,11 +1422,8 @@ namespace OpenSim.Region.Framework.Scenes
1269 { 1422 {
1270 List<UUID> ret = new List<UUID>(); 1423 List<UUID> ret = new List<UUID>();
1271 1424
1272 lock (m_items) 1425 foreach (TaskInventoryItem item in m_items.Values)
1273 { 1426 ret.Add(item.ItemID);
1274 foreach (TaskInventoryItem item in m_items.Values)
1275 ret.Add(item.ItemID);
1276 }
1277 1427
1278 return ret; 1428 return ret;
1279 } 1429 }
@@ -1282,8 +1432,9 @@ namespace OpenSim.Region.Framework.Scenes
1282 { 1432 {
1283 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1433 List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
1284 1434
1285 lock (m_items) 1435 Items.LockItemsForRead(true);
1286 ret = new List<TaskInventoryItem>(m_items.Values); 1436 ret = new List<TaskInventoryItem>(m_items.Values);
1437 Items.LockItemsForRead(false);
1287 1438
1288 return ret; 1439 return ret;
1289 } 1440 }
@@ -1292,18 +1443,24 @@ namespace OpenSim.Region.Framework.Scenes
1292 { 1443 {
1293 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1444 List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
1294 1445
1295 lock (m_items) 1446 Items.LockItemsForRead(true);
1296 { 1447
1297 foreach (TaskInventoryItem item in m_items.Values) 1448 foreach (TaskInventoryItem item in m_items.Values)
1298 if (item.InvType == (int)type) 1449 if (item.InvType == (int)type)
1299 ret.Add(item); 1450 ret.Add(item);
1300 } 1451
1452 Items.LockItemsForRead(false);
1301 1453
1302 return ret; 1454 return ret;
1303 } 1455 }
1304 1456
1305 public Dictionary<UUID, string> GetScriptStates() 1457 public Dictionary<UUID, string> GetScriptStates()
1306 { 1458 {
1459 return GetScriptStates(false);
1460 }
1461
1462 public Dictionary<UUID, string> GetScriptStates(bool oldIDs)
1463 {
1307 Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); 1464 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
1308 1465
1309 if (m_part.ParentGroup.Scene == null) // Group not in a scene 1466 if (m_part.ParentGroup.Scene == null) // Group not in a scene
@@ -1329,14 +1486,21 @@ namespace OpenSim.Region.Framework.Scenes
1329 string n = e.GetXMLState(item.ItemID); 1486 string n = e.GetXMLState(item.ItemID);
1330 if (n != String.Empty) 1487 if (n != String.Empty)
1331 { 1488 {
1332 if (!ret.ContainsKey(item.ItemID)) 1489 if (oldIDs)
1333 ret[item.ItemID] = n; 1490 {
1491 if (!ret.ContainsKey(item.OldItemID))
1492 ret[item.OldItemID] = n;
1493 }
1494 else
1495 {
1496 if (!ret.ContainsKey(item.ItemID))
1497 ret[item.ItemID] = n;
1498 }
1334 break; 1499 break;
1335 } 1500 }
1336 } 1501 }
1337 } 1502 }
1338 } 1503 }
1339
1340 return ret; 1504 return ret;
1341 } 1505 }
1342 1506