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.cs787
1 files changed, 476 insertions, 311 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 866311a..1dff088 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -48,6 +48,9 @@ namespace OpenSim.Region.Framework.Scenes
48 private string m_inventoryFileName = String.Empty; 48 private string m_inventoryFileName = String.Empty;
49 private byte[] m_inventoryFileData = new byte[0]; 49 private byte[] m_inventoryFileData = new byte[0];
50 private uint m_inventoryFileNameSerial = 0; 50 private uint m_inventoryFileNameSerial = 0;
51 private bool m_inventoryPrivileged = false;
52
53 private Dictionary<UUID, ArrayList> m_scriptErrors = new Dictionary<UUID, ArrayList>();
51 54
52 /// <value> 55 /// <value>
53 /// The part to which the inventory belongs. 56 /// The part to which the inventory belongs.
@@ -84,7 +87,9 @@ namespace OpenSim.Region.Framework.Scenes
84 /// </value> 87 /// </value>
85 protected internal TaskInventoryDictionary Items 88 protected internal TaskInventoryDictionary Items
86 { 89 {
87 get { return m_items; } 90 get {
91 return m_items;
92 }
88 set 93 set
89 { 94 {
90 m_items = value; 95 m_items = value;
@@ -124,38 +129,45 @@ namespace OpenSim.Region.Framework.Scenes
124 public void ResetInventoryIDs() 129 public void ResetInventoryIDs()
125 { 130 {
126 if (null == m_part) 131 if (null == m_part)
127 return; 132 m_items.LockItemsForWrite(true);
128 133
129 lock (m_items) 134 if (Items.Count == 0)
130 { 135 {
131 if (0 == m_items.Count) 136 m_items.LockItemsForWrite(false);
132 return; 137 return;
138 }
133 139
134 IList<TaskInventoryItem> items = GetInventoryItems(); 140 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
135 m_items.Clear(); 141 Items.Clear();
136 142
137 foreach (TaskInventoryItem item in items) 143 foreach (TaskInventoryItem item in items)
138 { 144 {
139 item.ResetIDs(m_part.UUID); 145 item.ResetIDs(m_part.UUID);
140 m_items.Add(item.ItemID, item); 146 Items.Add(item.ItemID, item);
141 }
142 } 147 }
148 m_items.LockItemsForWrite(false);
143 } 149 }
144 150
145 public void ResetObjectID() 151 public void ResetObjectID()
146 { 152 {
147 lock (Items) 153 m_items.LockItemsForWrite(true);
154
155 if (Items.Count == 0)
148 { 156 {
149 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 157 m_items.LockItemsForWrite(false);
150 Items.Clear(); 158 return;
151
152 foreach (TaskInventoryItem item in items)
153 {
154 item.ParentPartID = m_part.UUID;
155 item.ParentID = m_part.UUID;
156 Items.Add(item.ItemID, item);
157 }
158 } 159 }
160
161 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
162 Items.Clear();
163
164 foreach (TaskInventoryItem item in items)
165 {
166 item.ParentPartID = m_part.UUID;
167 item.ParentID = m_part.UUID;
168 Items.Add(item.ItemID, item);
169 }
170 m_items.LockItemsForWrite(false);
159 } 171 }
160 172
161 /// <summary> 173 /// <summary>
@@ -164,17 +176,14 @@ namespace OpenSim.Region.Framework.Scenes
164 /// <param name="ownerId"></param> 176 /// <param name="ownerId"></param>
165 public void ChangeInventoryOwner(UUID ownerId) 177 public void ChangeInventoryOwner(UUID ownerId)
166 { 178 {
167 lock (Items) 179 List<TaskInventoryItem> items = GetInventoryItems();
168 { 180
169 if (0 == Items.Count) 181 if (items.Count == 0)
170 { 182 return;
171 return;
172 }
173 }
174 183
184 m_items.LockItemsForWrite(true);
175 HasInventoryChanged = true; 185 HasInventoryChanged = true;
176 m_part.ParentGroup.HasGroupChanged = true; 186 m_part.ParentGroup.HasGroupChanged = true;
177 List<TaskInventoryItem> items = GetInventoryItems();
178 foreach (TaskInventoryItem item in items) 187 foreach (TaskInventoryItem item in items)
179 { 188 {
180 if (ownerId != item.OwnerID) 189 if (ownerId != item.OwnerID)
@@ -185,6 +194,7 @@ namespace OpenSim.Region.Framework.Scenes
185 item.PermsGranter = UUID.Zero; 194 item.PermsGranter = UUID.Zero;
186 item.OwnerChanged = true; 195 item.OwnerChanged = true;
187 } 196 }
197 m_items.LockItemsForWrite(false);
188 } 198 }
189 199
190 /// <summary> 200 /// <summary>
@@ -193,12 +203,11 @@ namespace OpenSim.Region.Framework.Scenes
193 /// <param name="groupID"></param> 203 /// <param name="groupID"></param>
194 public void ChangeInventoryGroup(UUID groupID) 204 public void ChangeInventoryGroup(UUID groupID)
195 { 205 {
196 lock (Items) 206 m_items.LockItemsForWrite(true);
207 if (0 == Items.Count)
197 { 208 {
198 if (0 == Items.Count) 209 m_items.LockItemsForWrite(false);
199 { 210 return;
200 return;
201 }
202 } 211 }
203 212
204 // Don't let this set the HasGroupChanged flag for attachments 213 // Don't let this set the HasGroupChanged flag for attachments
@@ -210,12 +219,15 @@ namespace OpenSim.Region.Framework.Scenes
210 m_part.ParentGroup.HasGroupChanged = true; 219 m_part.ParentGroup.HasGroupChanged = true;
211 } 220 }
212 221
213 List<TaskInventoryItem> items = GetInventoryItems(); 222 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
214 foreach (TaskInventoryItem item in items) 223 foreach (TaskInventoryItem item in items)
215 { 224 {
216 if (groupID != item.GroupID) 225 if (groupID != item.GroupID)
226 {
217 item.GroupID = groupID; 227 item.GroupID = groupID;
228 }
218 } 229 }
230 m_items.LockItemsForWrite(false);
219 } 231 }
220 232
221 private void QueryScriptStates() 233 private void QueryScriptStates()
@@ -227,25 +239,25 @@ namespace OpenSim.Region.Framework.Scenes
227 if (engines == null) // No engine at all 239 if (engines == null) // No engine at all
228 return; 240 return;
229 241
230 lock (Items) 242 Items.LockItemsForRead(true);
243 foreach (TaskInventoryItem item in Items.Values)
231 { 244 {
232 foreach (TaskInventoryItem item in Items.Values) 245 if (item.InvType == (int)InventoryType.LSL)
233 { 246 {
234 if (item.InvType == (int)InventoryType.LSL) 247 foreach (IScriptModule e in engines)
235 { 248 {
236 foreach (IScriptModule e in engines) 249 bool running;
237 {
238 bool running;
239 250
240 if (e.HasScript(item.ItemID, out running)) 251 if (e.HasScript(item.ItemID, out running))
241 { 252 {
242 item.ScriptRunning = running; 253 item.ScriptRunning = running;
243 break; 254 break;
244 }
245 } 255 }
246 } 256 }
247 } 257 }
248 } 258 }
259
260 Items.LockItemsForRead(false);
249 } 261 }
250 262
251 public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 263 public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
@@ -290,7 +302,10 @@ namespace OpenSim.Region.Framework.Scenes
290 { 302 {
291 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); 303 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
292 foreach (TaskInventoryItem item in scripts) 304 foreach (TaskInventoryItem item in scripts)
305 {
293 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); 306 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
307 m_part.RemoveScriptEvents(item.ItemID);
308 }
294 } 309 }
295 310
296 /// <summary> 311 /// <summary>
@@ -304,7 +319,10 @@ namespace OpenSim.Region.Framework.Scenes
304// item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); 319// item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName);
305 320
306 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) 321 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID))
322 {
323 StoreScriptError(item.ItemID, "no permission");
307 return false; 324 return false;
325 }
308 326
309 m_part.AddFlag(PrimFlags.Scripted); 327 m_part.AddFlag(PrimFlags.Scripted);
310 328
@@ -314,14 +332,13 @@ namespace OpenSim.Region.Framework.Scenes
314 if (stateSource == 2 && // Prim crossing 332 if (stateSource == 2 && // Prim crossing
315 m_part.ParentGroup.Scene.m_trustBinaries) 333 m_part.ParentGroup.Scene.m_trustBinaries)
316 { 334 {
317 lock (m_items) 335 m_items.LockItemsForWrite(true);
318 { 336 m_items[item.ItemID].PermsMask = 0;
319 m_items[item.ItemID].PermsMask = 0; 337 m_items[item.ItemID].PermsGranter = UUID.Zero;
320 m_items[item.ItemID].PermsGranter = UUID.Zero; 338 m_items.LockItemsForWrite(false);
321 }
322
323 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 339 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
324 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 340 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
341 StoreScriptErrors(item.ItemID, null);
325 m_part.ParentGroup.AddActiveScriptCount(1); 342 m_part.ParentGroup.AddActiveScriptCount(1);
326 m_part.ScheduleFullUpdate(); 343 m_part.ScheduleFullUpdate();
327 return true; 344 return true;
@@ -342,16 +359,25 @@ namespace OpenSim.Region.Framework.Scenes
342 if (m_part.ParentGroup.m_savedScriptState != null) 359 if (m_part.ParentGroup.m_savedScriptState != null)
343 item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); 360 item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID);
344 361
345 lock (m_items) 362 string msg = String.Format("asset ID {0} could not be found", item.AssetID);
346 { 363 StoreScriptError(item.ItemID, msg);
347 m_items[item.ItemID].OldItemID = item.OldItemID; 364 m_log.ErrorFormat(
348 m_items[item.ItemID].PermsMask = 0; 365 "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
349 m_items[item.ItemID].PermsGranter = UUID.Zero; 366 item.Name, item.ItemID, m_part.AbsolutePosition,
350 } 367 m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID);
368
369 m_items.LockItemsForWrite(true);
351 370
371 m_items[item.ItemID].OldItemID = item.OldItemID;
372 m_items[item.ItemID].PermsMask = 0;
373 m_items[item.ItemID].PermsGranter = UUID.Zero;
374
375 m_items.LockItemsForWrite(false);
376
352 string script = Utils.BytesToString(asset.Data); 377 string script = Utils.BytesToString(asset.Data);
353 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 378 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
354 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 379 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
380 StoreScriptErrors(item.ItemID, null);
355 if (!item.ScriptRunning) 381 if (!item.ScriptRunning)
356 m_part.ParentGroup.Scene.EventManager.TriggerStopScript( 382 m_part.ParentGroup.Scene.EventManager.TriggerStopScript(
357 m_part.LocalId, item.ItemID); 383 m_part.LocalId, item.ItemID);
@@ -424,22 +450,149 @@ namespace OpenSim.Region.Framework.Scenes
424 return stateID; 450 return stateID;
425 } 451 }
426 452
453 /// <summary>
454 /// Start a script which is in this prim's inventory.
455 /// Some processing may occur in the background, but this routine returns asap.
456 /// </summary>
457 /// <param name="itemId">
458 /// A <see cref="UUID"/>
459 /// </param>
427 public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 460 public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
428 { 461 {
429 TaskInventoryItem item = GetInventoryItem(itemId); 462 lock (m_scriptErrors)
430 if (item != null)
431 { 463 {
432 return CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 464 // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion
465 m_scriptErrors.Remove(itemId);
466 }
467 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
468 return true;
469 }
470
471 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
472 {
473 m_items.LockItemsForRead(true);
474 if (m_items.ContainsKey(itemId))
475 {
476 if (m_items.ContainsKey(itemId))
477 {
478 m_items.LockItemsForRead(false);
479 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
480 }
481 else
482 {
483 m_items.LockItemsForRead(false);
484 string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID,
485 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
486 StoreScriptError(itemId, msg);
487 m_log.ErrorFormat(
488 "[PRIM INVENTORY]: " +
489 "Couldn't start script with ID {0} since it {1}", itemId, msg);
490 }
433 } 491 }
434 else 492 else
435 { 493 {
494 m_items.LockItemsForRead(false);
495 string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID);
496 StoreScriptError(itemId, msg);
436 m_log.ErrorFormat( 497 m_log.ErrorFormat(
437 "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 498 "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
438 itemId, m_part.Name, m_part.UUID, 499 itemId, m_part.Name, m_part.UUID,
439 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 500 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
501 }
502
503 }
440 504
441 return false; 505 /// <summary>
506 /// Start a script which is in this prim's inventory and return any compilation error messages.
507 /// </summary>
508 /// <param name="itemId">
509 /// A <see cref="UUID"/>
510 /// </param>
511 public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
512 {
513 ArrayList errors;
514
515 // Indicate to CreateScriptInstanceInternal() we want it to
516 // post any compilation/loading error messages
517 lock (m_scriptErrors)
518 {
519 m_scriptErrors[itemId] = null;
520 }
521
522 // Perform compilation/loading
523 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
524
525 // Wait for and retrieve any errors
526 lock (m_scriptErrors)
527 {
528 while ((errors = m_scriptErrors[itemId]) == null)
529 {
530 if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
531 {
532 m_log.ErrorFormat(
533 "[PRIM INVENTORY]: " +
534 "timedout waiting for script {0} errors", itemId);
535 errors = m_scriptErrors[itemId];
536 if (errors == null)
537 {
538 errors = new ArrayList(1);
539 errors.Add("timedout waiting for errors");
540 }
541 break;
542 }
543 }
544 m_scriptErrors.Remove(itemId);
545 }
546 return errors;
547 }
548
549 // Signal to CreateScriptInstanceEr() that compilation/loading is complete
550 private void StoreScriptErrors(UUID itemId, ArrayList errors)
551 {
552 lock (m_scriptErrors)
553 {
554 // If compilation/loading initiated via CreateScriptInstance(),
555 // it does not want the errors, so just get out
556 if (!m_scriptErrors.ContainsKey(itemId))
557 {
558 return;
559 }
560
561 // Initiated via CreateScriptInstanceEr(), if we know what the
562 // errors are, save them and wake CreateScriptInstanceEr().
563 if (errors != null)
564 {
565 m_scriptErrors[itemId] = errors;
566 System.Threading.Monitor.PulseAll(m_scriptErrors);
567 return;
568 }
442 } 569 }
570
571 // Initiated via CreateScriptInstanceEr() but we don't know what
572 // the errors are yet, so retrieve them from the script engine.
573 // This may involve some waiting internal to GetScriptErrors().
574 errors = GetScriptErrors(itemId);
575
576 // Get a default non-null value to indicate success.
577 if (errors == null)
578 {
579 errors = new ArrayList();
580 }
581
582 // Post to CreateScriptInstanceEr() and wake it up
583 lock (m_scriptErrors)
584 {
585 m_scriptErrors[itemId] = errors;
586 System.Threading.Monitor.PulseAll(m_scriptErrors);
587 }
588 }
589
590 // Like StoreScriptErrors(), but just posts a single string message
591 private void StoreScriptError(UUID itemId, string message)
592 {
593 ArrayList errors = new ArrayList(1);
594 errors.Add(message);
595 StoreScriptErrors(itemId, errors);
443 } 596 }
444 597
445 /// <summary> 598 /// <summary>
@@ -452,15 +605,7 @@ namespace OpenSim.Region.Framework.Scenes
452 /// </param> 605 /// </param>
453 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 606 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
454 { 607 {
455 bool scriptPresent = false; 608 if (m_items.ContainsKey(itemId))
456
457 lock (m_items)
458 {
459 if (m_items.ContainsKey(itemId))
460 scriptPresent = true;
461 }
462
463 if (scriptPresent)
464 { 609 {
465 if (!sceneObjectBeingDeleted) 610 if (!sceneObjectBeingDeleted)
466 m_part.RemoveScriptEvents(itemId); 611 m_part.RemoveScriptEvents(itemId);
@@ -485,14 +630,16 @@ namespace OpenSim.Region.Framework.Scenes
485 /// <returns></returns> 630 /// <returns></returns>
486 private bool InventoryContainsName(string name) 631 private bool InventoryContainsName(string name)
487 { 632 {
488 lock (m_items) 633 m_items.LockItemsForRead(true);
634 foreach (TaskInventoryItem item in m_items.Values)
489 { 635 {
490 foreach (TaskInventoryItem item in m_items.Values) 636 if (item.Name == name)
491 { 637 {
492 if (item.Name == name) 638 m_items.LockItemsForRead(false);
493 return true; 639 return true;
494 } 640 }
495 } 641 }
642 m_items.LockItemsForRead(false);
496 return false; 643 return false;
497 } 644 }
498 645
@@ -534,8 +681,9 @@ namespace OpenSim.Region.Framework.Scenes
534 /// <param name="item"></param> 681 /// <param name="item"></param>
535 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 682 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
536 { 683 {
537 List<TaskInventoryItem> il = GetInventoryItems(); 684 m_items.LockItemsForRead(true);
538 685 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
686 m_items.LockItemsForRead(false);
539 foreach (TaskInventoryItem i in il) 687 foreach (TaskInventoryItem i in il)
540 { 688 {
541 if (i.Name == item.Name) 689 if (i.Name == item.Name)
@@ -573,14 +721,14 @@ namespace OpenSim.Region.Framework.Scenes
573 item.Name = name; 721 item.Name = name;
574 item.GroupID = m_part.GroupID; 722 item.GroupID = m_part.GroupID;
575 723
576 lock (m_items) 724 m_items.LockItemsForWrite(true);
577 m_items.Add(item.ItemID, item); 725 m_items.Add(item.ItemID, item);
578 726 m_items.LockItemsForWrite(false);
579 if (allowedDrop) 727 if (allowedDrop)
580 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 728 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
581 else 729 else
582 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 730 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
583 731
584 m_inventorySerial++; 732 m_inventorySerial++;
585 //m_inventorySerial += 2; 733 //m_inventorySerial += 2;
586 HasInventoryChanged = true; 734 HasInventoryChanged = true;
@@ -596,15 +744,15 @@ namespace OpenSim.Region.Framework.Scenes
596 /// <param name="items"></param> 744 /// <param name="items"></param>
597 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 745 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
598 { 746 {
599 lock (m_items) 747 m_items.LockItemsForWrite(true);
748 foreach (TaskInventoryItem item in items)
600 { 749 {
601 foreach (TaskInventoryItem item in items) 750 m_items.Add(item.ItemID, item);
602 { 751// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
603 m_items.Add(item.ItemID, item);
604// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
605 }
606 m_inventorySerial++;
607 } 752 }
753 m_items.LockItemsForWrite(false);
754
755 m_inventorySerial++;
608 } 756 }
609 757
610 /// <summary> 758 /// <summary>
@@ -615,23 +763,24 @@ namespace OpenSim.Region.Framework.Scenes
615 public TaskInventoryItem GetInventoryItem(UUID itemId) 763 public TaskInventoryItem GetInventoryItem(UUID itemId)
616 { 764 {
617 TaskInventoryItem item; 765 TaskInventoryItem item;
618 766 m_items.LockItemsForRead(true);
619 lock (m_items) 767 m_items.TryGetValue(itemId, out item);
620 m_items.TryGetValue(itemId, out item); 768 m_items.LockItemsForRead(false);
621
622 return item; 769 return item;
623 } 770 }
624 771
625 public TaskInventoryItem GetInventoryItem(string name) 772 public TaskInventoryItem GetInventoryItem(string name)
626 { 773 {
627 lock (m_items) 774 m_items.LockItemsForRead(true);
775 foreach (TaskInventoryItem item in m_items.Values)
628 { 776 {
629 foreach (TaskInventoryItem item in m_items.Values) 777 if (item.Name == name)
630 { 778 {
631 if (item.Name == name) 779 m_items.LockItemsForRead(false);
632 return item; 780 return item;
633 } 781 }
634 } 782 }
783 m_items.LockItemsForRead(false);
635 784
636 return null; 785 return null;
637 } 786 }
@@ -640,15 +789,16 @@ namespace OpenSim.Region.Framework.Scenes
640 { 789 {
641 List<TaskInventoryItem> items = new List<TaskInventoryItem>(); 790 List<TaskInventoryItem> items = new List<TaskInventoryItem>();
642 791
643 lock (m_items) 792 m_items.LockItemsForRead(true);
793
794 foreach (TaskInventoryItem item in m_items.Values)
644 { 795 {
645 foreach (TaskInventoryItem item in m_items.Values) 796 if (item.Name == name)
646 { 797 items.Add(item);
647 if (item.Name == name)
648 items.Add(item);
649 }
650 } 798 }
651 799
800 m_items.LockItemsForRead(false);
801
652 return items; 802 return items;
653 } 803 }
654 804
@@ -667,6 +817,10 @@ namespace OpenSim.Region.Framework.Scenes
667 string xmlData = Utils.BytesToString(rezAsset.Data); 817 string xmlData = Utils.BytesToString(rezAsset.Data);
668 SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); 818 SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
669 819
820 group.RootPart.AttachPoint = group.RootPart.Shape.State;
821 group.RootPart.AttachOffset = group.AbsolutePosition;
822 group.RootPart.AttachRotation = group.GroupRotation;
823
670 group.ResetIDs(); 824 group.ResetIDs();
671 825
672 SceneObjectPart rootPart = group.GetPart(group.UUID); 826 SceneObjectPart rootPart = group.GetPart(group.UUID);
@@ -741,8 +895,9 @@ namespace OpenSim.Region.Framework.Scenes
741 895
742 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) 896 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged)
743 { 897 {
744 TaskInventoryItem it = GetInventoryItem(item.ItemID); 898 m_items.LockItemsForWrite(true);
745 if (it != null) 899
900 if (m_items.ContainsKey(item.ItemID))
746 { 901 {
747// m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); 902// m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name);
748 903
@@ -755,14 +910,10 @@ namespace OpenSim.Region.Framework.Scenes
755 item.GroupID = m_part.GroupID; 910 item.GroupID = m_part.GroupID;
756 911
757 if (item.AssetID == UUID.Zero) 912 if (item.AssetID == UUID.Zero)
758 item.AssetID = it.AssetID; 913 item.AssetID = m_items[item.ItemID].AssetID;
759 914
760 lock (m_items) 915 m_items[item.ItemID] = item;
761 { 916 m_inventorySerial++;
762 m_items[item.ItemID] = item;
763 m_inventorySerial++;
764 }
765
766 if (fireScriptEvents) 917 if (fireScriptEvents)
767 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 918 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
768 919
@@ -771,7 +922,7 @@ namespace OpenSim.Region.Framework.Scenes
771 HasInventoryChanged = true; 922 HasInventoryChanged = true;
772 m_part.ParentGroup.HasGroupChanged = true; 923 m_part.ParentGroup.HasGroupChanged = true;
773 } 924 }
774 925 m_items.LockItemsForWrite(false);
775 return true; 926 return true;
776 } 927 }
777 else 928 else
@@ -782,8 +933,9 @@ namespace OpenSim.Region.Framework.Scenes
782 item.ItemID, m_part.Name, m_part.UUID, 933 item.ItemID, m_part.Name, m_part.UUID,
783 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 934 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
784 } 935 }
785 return false; 936 m_items.LockItemsForWrite(false);
786 937
938 return false;
787 } 939 }
788 940
789 /// <summary> 941 /// <summary>
@@ -794,43 +946,59 @@ namespace OpenSim.Region.Framework.Scenes
794 /// in this prim's inventory.</returns> 946 /// in this prim's inventory.</returns>
795 public int RemoveInventoryItem(UUID itemID) 947 public int RemoveInventoryItem(UUID itemID)
796 { 948 {
797 TaskInventoryItem item = GetInventoryItem(itemID); 949 m_items.LockItemsForRead(true);
798 if (item != null) 950
951 if (m_items.ContainsKey(itemID))
799 { 952 {
800 int type = m_items[itemID].InvType; 953 int type = m_items[itemID].InvType;
954 m_items.LockItemsForRead(false);
801 if (type == 10) // Script 955 if (type == 10) // Script
802 { 956 {
803 m_part.RemoveScriptEvents(itemID);
804 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 957 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
805 } 958 }
959 m_items.LockItemsForWrite(true);
806 m_items.Remove(itemID); 960 m_items.Remove(itemID);
961 m_items.LockItemsForWrite(false);
807 m_inventorySerial++; 962 m_inventorySerial++;
808 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 963 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
809 964
810 HasInventoryChanged = true; 965 HasInventoryChanged = true;
811 m_part.ParentGroup.HasGroupChanged = true; 966 m_part.ParentGroup.HasGroupChanged = true;
812 967
813 if (!ContainsScripts()) 968 int scriptcount = 0;
969 m_items.LockItemsForRead(true);
970 foreach (TaskInventoryItem item in m_items.Values)
971 {
972 if (item.Type == 10)
973 {
974 scriptcount++;
975 }
976 }
977 m_items.LockItemsForRead(false);
978
979
980 if (scriptcount <= 0)
981 {
814 m_part.RemFlag(PrimFlags.Scripted); 982 m_part.RemFlag(PrimFlags.Scripted);
983 }
815 984
816 m_part.ScheduleFullUpdate(); 985 m_part.ScheduleFullUpdate();
817 986
818 return type; 987 return type;
819
820 } 988 }
821 else 989 else
822 { 990 {
991 m_items.LockItemsForRead(false);
823 m_log.ErrorFormat( 992 m_log.ErrorFormat(
824 "[PRIM INVENTORY]: " + 993 "[PRIM INVENTORY]: " +
825 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 994 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
826 itemID, m_part.Name, m_part.UUID, 995 itemID, m_part.Name, m_part.UUID);
827 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
828 } 996 }
829 997
830 return -1; 998 return -1;
831 } 999 }
832 1000
833 private bool CreateInventoryFile() 1001 private bool CreateInventoryFileName()
834 { 1002 {
835// m_log.DebugFormat( 1003// m_log.DebugFormat(
836// "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", 1004// "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}",
@@ -839,70 +1007,12 @@ namespace OpenSim.Region.Framework.Scenes
839 if (m_inventoryFileName == String.Empty || 1007 if (m_inventoryFileName == String.Empty ||
840 m_inventoryFileNameSerial < m_inventorySerial) 1008 m_inventoryFileNameSerial < m_inventorySerial)
841 { 1009 {
842 // Something changed, we need to create a new file
843 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; 1010 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
844 m_inventoryFileNameSerial = m_inventorySerial; 1011 m_inventoryFileNameSerial = m_inventorySerial;
845 1012
846 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
847
848 lock (m_items)
849 {
850 foreach (TaskInventoryItem item in m_items.Values)
851 {
852// m_log.DebugFormat(
853// "[PRIM INVENTORY]: Adding item {0} {1} for serial {2} on prim {3} {4} {5}",
854// item.Name, item.ItemID, m_inventorySerial, m_part.Name, m_part.UUID, m_part.LocalId);
855
856 UUID ownerID = item.OwnerID;
857 uint everyoneMask = 0;
858 uint baseMask = item.BasePermissions;
859 uint ownerMask = item.CurrentPermissions;
860 uint groupMask = item.GroupPermissions;
861
862 invString.AddItemStart();
863 invString.AddNameValueLine("item_id", item.ItemID.ToString());
864 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
865
866 invString.AddPermissionsStart();
867
868 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
869 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
870 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
871 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
872 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
873
874 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
875 invString.AddNameValueLine("owner_id", ownerID.ToString());
876
877 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
878
879 invString.AddNameValueLine("group_id", item.GroupID.ToString());
880 invString.AddSectionEnd();
881
882 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
883 invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type));
884 invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType));
885 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
886
887 invString.AddSaleStart();
888 invString.AddNameValueLine("sale_type", "not");
889 invString.AddNameValueLine("sale_price", "0");
890 invString.AddSectionEnd();
891
892 invString.AddNameValueLine("name", item.Name + "|");
893 invString.AddNameValueLine("desc", item.Description + "|");
894
895 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
896 invString.AddSectionEnd();
897 }
898 }
899
900 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
901
902 return true; 1013 return true;
903 } 1014 }
904 1015
905 // No need to recreate, the existing file is fine
906 return false; 1016 return false;
907 } 1017 }
908 1018
@@ -912,43 +1022,110 @@ namespace OpenSim.Region.Framework.Scenes
912 /// <param name="xferManager"></param> 1022 /// <param name="xferManager"></param>
913 public void RequestInventoryFile(IClientAPI client, IXfer xferManager) 1023 public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
914 { 1024 {
915 lock (m_items) 1025 bool changed = CreateInventoryFileName();
916 {
917 // Don't send a inventory xfer name if there are no items. Doing so causes viewer 3 to crash when rezzing
918 // a new script if any previous deletion has left the prim inventory empty.
919 if (m_items.Count == 0) // No inventory
920 {
921// m_log.DebugFormat(
922// "[PRIM INVENTORY]: Not sending inventory data for part {0} {1} {2} for {3} since no items",
923// m_part.Name, m_part.LocalId, m_part.UUID, client.Name);
924 1026
925 client.SendTaskInventory(m_part.UUID, 0, new byte[0]); 1027 bool includeAssets = false;
926 return; 1028 if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId))
927 } 1029 includeAssets = true;
1030
1031 if (m_inventoryPrivileged != includeAssets)
1032 changed = true;
1033
1034 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
1035
1036 Items.LockItemsForRead(true);
1037
1038 if (m_inventorySerial == 0) // No inventory
1039 {
1040 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1041 Items.LockItemsForRead(false);
1042 return;
1043 }
928 1044
929 CreateInventoryFile(); 1045 if (m_items.Count == 0) // No inventory
1046 {
1047 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1048 Items.LockItemsForRead(false);
1049 return;
1050 }
930 1051
931 // In principle, we should only do the rest if the inventory changed; 1052 if (!changed)
932 // by sending m_inventorySerial to the client, it ought to know 1053 {
933 // that nothing changed and that it doesn't need to request the file.
934 // Unfortunately, it doesn't look like the client optimizes this;
935 // the client seems to always come back and request the Xfer,
936 // no matter what value m_inventorySerial has.
937 // FIXME: Could probably be > 0 here rather than > 2
938 if (m_inventoryFileData.Length > 2) 1054 if (m_inventoryFileData.Length > 2)
939 { 1055 {
940 // Add the file for Xfer 1056 xferManager.AddNewFile(m_inventoryFileName,
941 // m_log.DebugFormat( 1057 m_inventoryFileData);
942 // "[PRIM INVENTORY]: Adding inventory file {0} (length {1}) for transfer on {2} {3} {4}", 1058 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
943 // m_inventoryFileName, m_inventoryFileData.Length, m_part.Name, m_part.UUID, m_part.LocalId); 1059 Util.StringToBytes256(m_inventoryFileName));
944 1060
945 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); 1061 Items.LockItemsForRead(false);
1062 return;
946 } 1063 }
947
948 // Tell the client we're ready to Xfer the file
949 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
950 Util.StringToBytes256(m_inventoryFileName));
951 } 1064 }
1065
1066 m_inventoryPrivileged = includeAssets;
1067
1068 foreach (TaskInventoryItem item in m_items.Values)
1069 {
1070 UUID ownerID = item.OwnerID;
1071 uint everyoneMask = 0;
1072 uint baseMask = item.BasePermissions;
1073 uint ownerMask = item.CurrentPermissions;
1074 uint groupMask = item.GroupPermissions;
1075
1076 invString.AddItemStart();
1077 invString.AddNameValueLine("item_id", item.ItemID.ToString());
1078 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
1079
1080 invString.AddPermissionsStart();
1081
1082 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
1083 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
1084 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
1085 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
1086 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
1087
1088 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
1089 invString.AddNameValueLine("owner_id", ownerID.ToString());
1090
1091 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
1092
1093 invString.AddNameValueLine("group_id", item.GroupID.ToString());
1094 invString.AddSectionEnd();
1095
1096 if (includeAssets)
1097 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
1098 else
1099 invString.AddNameValueLine("asset_id", UUID.Zero.ToString());
1100 invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type));
1101 invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType));
1102 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
1103
1104 invString.AddSaleStart();
1105 invString.AddNameValueLine("sale_type", "not");
1106 invString.AddNameValueLine("sale_price", "0");
1107 invString.AddSectionEnd();
1108
1109 invString.AddNameValueLine("name", item.Name + "|");
1110 invString.AddNameValueLine("desc", item.Description + "|");
1111
1112 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
1113 invString.AddSectionEnd();
1114 }
1115
1116 Items.LockItemsForRead(false);
1117
1118 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
1119
1120 if (m_inventoryFileData.Length > 2)
1121 {
1122 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
1123 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
1124 Util.StringToBytes256(m_inventoryFileName));
1125 return;
1126 }
1127
1128 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
952 } 1129 }
953 1130
954 /// <summary> 1131 /// <summary>
@@ -957,13 +1134,19 @@ namespace OpenSim.Region.Framework.Scenes
957 /// <param name="datastore"></param> 1134 /// <param name="datastore"></param>
958 public void ProcessInventoryBackup(ISimulationDataService datastore) 1135 public void ProcessInventoryBackup(ISimulationDataService datastore)
959 { 1136 {
960 if (HasInventoryChanged) 1137// Removed this because linking will cause an immediate delete of the new
961 { 1138// child prim from the database and the subsequent storing of the prim sees
962 HasInventoryChanged = false; 1139// the inventory of it as unchanged and doesn't store it at all. The overhead
963 List<TaskInventoryItem> items = GetInventoryItems(); 1140// of storing prim inventory needlessly is much less than the aggravation
964 datastore.StorePrimInventory(m_part.UUID, items); 1141// of prim inventory loss.
1142// if (HasInventoryChanged)
1143// {
1144 Items.LockItemsForRead(true);
1145 datastore.StorePrimInventory(m_part.UUID, Items.Values);
1146 Items.LockItemsForRead(false);
965 1147
966 } 1148 HasInventoryChanged = false;
1149// }
967 } 1150 }
968 1151
969 public class InventoryStringBuilder 1152 public class InventoryStringBuilder
@@ -1029,87 +1212,63 @@ namespace OpenSim.Region.Framework.Scenes
1029 { 1212 {
1030 uint mask=0x7fffffff; 1213 uint mask=0x7fffffff;
1031 1214
1032 lock (m_items) 1215 foreach (TaskInventoryItem item in m_items.Values)
1033 { 1216 {
1034 foreach (TaskInventoryItem item in m_items.Values) 1217 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
1218 mask &= ~((uint)PermissionMask.Copy >> 13);
1219 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
1220 mask &= ~((uint)PermissionMask.Transfer >> 13);
1221 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
1222 mask &= ~((uint)PermissionMask.Modify >> 13);
1223
1224 if (item.InvType == (int)InventoryType.Object)
1035 { 1225 {
1036 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1226 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1037 mask &= ~((uint)PermissionMask.Copy >> 13); 1227 mask &= ~((uint)PermissionMask.Copy >> 13);
1038 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1228 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1039 mask &= ~((uint)PermissionMask.Transfer >> 13); 1229 mask &= ~((uint)PermissionMask.Transfer >> 13);
1040 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 1230 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1041 mask &= ~((uint)PermissionMask.Modify >> 13); 1231 mask &= ~((uint)PermissionMask.Modify >> 13);
1042
1043 if (item.InvType != (int)InventoryType.Object)
1044 {
1045 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
1046 mask &= ~((uint)PermissionMask.Copy >> 13);
1047 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
1048 mask &= ~((uint)PermissionMask.Transfer >> 13);
1049 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
1050 mask &= ~((uint)PermissionMask.Modify >> 13);
1051 }
1052 else
1053 {
1054 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1055 mask &= ~((uint)PermissionMask.Copy >> 13);
1056 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1057 mask &= ~((uint)PermissionMask.Transfer >> 13);
1058 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1059 mask &= ~((uint)PermissionMask.Modify >> 13);
1060 }
1061
1062 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1063 mask &= ~(uint)PermissionMask.Copy;
1064 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1065 mask &= ~(uint)PermissionMask.Transfer;
1066 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1067 mask &= ~(uint)PermissionMask.Modify;
1068 } 1232 }
1233
1234 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1235 mask &= ~(uint)PermissionMask.Copy;
1236 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1237 mask &= ~(uint)PermissionMask.Transfer;
1238 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1239 mask &= ~(uint)PermissionMask.Modify;
1069 } 1240 }
1070
1071 return mask; 1241 return mask;
1072 } 1242 }
1073 1243
1074 public void ApplyNextOwnerPermissions() 1244 public void ApplyNextOwnerPermissions()
1075 { 1245 {
1076 lock (m_items) 1246 foreach (TaskInventoryItem item in m_items.Values)
1077 { 1247 {
1078 foreach (TaskInventoryItem item in m_items.Values) 1248 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
1079 { 1249 {
1080// m_log.DebugFormat ( 1250 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1081// "[SCENE OBJECT PART INVENTORY]: Applying next permissions {0} to {1} in {2} with current {3}, base {4}, everyone {5}", 1251 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
1082// item.NextPermissions, item.Name, m_part.Name, item.CurrentPermissions, item.BasePermissions, item.EveryonePermissions); 1252 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1083 1253 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
1084 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 1254 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1085 { 1255 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1086 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1087 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
1088 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1089 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
1090 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1091 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1092 }
1093
1094 item.CurrentPermissions &= item.NextPermissions;
1095 item.BasePermissions &= item.NextPermissions;
1096 item.EveryonePermissions &= item.NextPermissions;
1097 item.OwnerChanged = true;
1098 item.PermsMask = 0;
1099 item.PermsGranter = UUID.Zero;
1100 } 1256 }
1257 item.CurrentPermissions &= item.NextPermissions;
1258 item.BasePermissions &= item.NextPermissions;
1259 item.EveryonePermissions &= item.NextPermissions;
1260 item.OwnerChanged = true;
1261 item.PermsMask = 0;
1262 item.PermsGranter = UUID.Zero;
1101 } 1263 }
1102 } 1264 }
1103 1265
1104 public void ApplyGodPermissions(uint perms) 1266 public void ApplyGodPermissions(uint perms)
1105 { 1267 {
1106 lock (m_items) 1268 foreach (TaskInventoryItem item in m_items.Values)
1107 { 1269 {
1108 foreach (TaskInventoryItem item in m_items.Values) 1270 item.CurrentPermissions = perms;
1109 { 1271 item.BasePermissions = perms;
1110 item.CurrentPermissions = perms;
1111 item.BasePermissions = perms;
1112 }
1113 } 1272 }
1114 1273
1115 m_inventorySerial++; 1274 m_inventorySerial++;
@@ -1122,14 +1281,11 @@ namespace OpenSim.Region.Framework.Scenes
1122 /// <returns></returns> 1281 /// <returns></returns>
1123 public bool ContainsScripts() 1282 public bool ContainsScripts()
1124 { 1283 {
1125 lock (m_items) 1284 foreach (TaskInventoryItem item in m_items.Values)
1126 { 1285 {
1127 foreach (TaskInventoryItem item in m_items.Values) 1286 if (item.InvType == (int)InventoryType.LSL)
1128 { 1287 {
1129 if (item.InvType == (int)InventoryType.LSL) 1288 return true;
1130 {
1131 return true;
1132 }
1133 } 1289 }
1134 } 1290 }
1135 1291
@@ -1143,17 +1299,15 @@ namespace OpenSim.Region.Framework.Scenes
1143 public int ScriptCount() 1299 public int ScriptCount()
1144 { 1300 {
1145 int count = 0; 1301 int count = 0;
1146 lock (m_items) 1302 Items.LockItemsForRead(true);
1303 foreach (TaskInventoryItem item in m_items.Values)
1147 { 1304 {
1148 foreach (TaskInventoryItem item in m_items.Values) 1305 if (item.InvType == (int)InventoryType.LSL)
1149 { 1306 {
1150 if (item.InvType == (int)InventoryType.LSL) 1307 count++;
1151 {
1152 count++;
1153 }
1154 } 1308 }
1155 } 1309 }
1156 1310 Items.LockItemsForRead(false);
1157 return count; 1311 return count;
1158 } 1312 }
1159 /// <summary> 1313 /// <summary>
@@ -1189,11 +1343,8 @@ namespace OpenSim.Region.Framework.Scenes
1189 { 1343 {
1190 List<UUID> ret = new List<UUID>(); 1344 List<UUID> ret = new List<UUID>();
1191 1345
1192 lock (m_items) 1346 foreach (TaskInventoryItem item in m_items.Values)
1193 { 1347 ret.Add(item.ItemID);
1194 foreach (TaskInventoryItem item in m_items.Values)
1195 ret.Add(item.ItemID);
1196 }
1197 1348
1198 return ret; 1349 return ret;
1199 } 1350 }
@@ -1202,8 +1353,9 @@ namespace OpenSim.Region.Framework.Scenes
1202 { 1353 {
1203 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1354 List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
1204 1355
1205 lock (m_items) 1356 Items.LockItemsForRead(true);
1206 ret = new List<TaskInventoryItem>(m_items.Values); 1357 ret = new List<TaskInventoryItem>(m_items.Values);
1358 Items.LockItemsForRead(false);
1207 1359
1208 return ret; 1360 return ret;
1209 } 1361 }
@@ -1212,18 +1364,24 @@ namespace OpenSim.Region.Framework.Scenes
1212 { 1364 {
1213 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1365 List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
1214 1366
1215 lock (m_items) 1367 Items.LockItemsForRead(true);
1216 { 1368
1217 foreach (TaskInventoryItem item in m_items.Values) 1369 foreach (TaskInventoryItem item in m_items.Values)
1218 if (item.InvType == (int)type) 1370 if (item.InvType == (int)type)
1219 ret.Add(item); 1371 ret.Add(item);
1220 } 1372
1373 Items.LockItemsForRead(false);
1221 1374
1222 return ret; 1375 return ret;
1223 } 1376 }
1224 1377
1225 public Dictionary<UUID, string> GetScriptStates() 1378 public Dictionary<UUID, string> GetScriptStates()
1226 { 1379 {
1380 return GetScriptStates(false);
1381 }
1382
1383 public Dictionary<UUID, string> GetScriptStates(bool oldIDs)
1384 {
1227 Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); 1385 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
1228 1386
1229 if (m_part.ParentGroup.Scene == null) // Group not in a scene 1387 if (m_part.ParentGroup.Scene == null) // Group not in a scene
@@ -1245,14 +1403,21 @@ namespace OpenSim.Region.Framework.Scenes
1245 string n = e.GetXMLState(item.ItemID); 1403 string n = e.GetXMLState(item.ItemID);
1246 if (n != String.Empty) 1404 if (n != String.Empty)
1247 { 1405 {
1248 if (!ret.ContainsKey(item.ItemID)) 1406 if (oldIDs)
1249 ret[item.ItemID] = n; 1407 {
1408 if (!ret.ContainsKey(item.OldItemID))
1409 ret[item.OldItemID] = n;
1410 }
1411 else
1412 {
1413 if (!ret.ContainsKey(item.ItemID))
1414 ret[item.ItemID] = n;
1415 }
1250 break; 1416 break;
1251 } 1417 }
1252 } 1418 }
1253 } 1419 }
1254 } 1420 }
1255
1256 return ret; 1421 return ret;
1257 } 1422 }
1258 1423