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.cs791
1 files changed, 492 insertions, 299 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 8810903..81477e7 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,11 +87,14 @@ 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;
91 m_inventorySerial++; 96 m_inventorySerial++;
97 QueryScriptStates();
92 } 98 }
93 } 99 }
94 100
@@ -123,38 +129,45 @@ namespace OpenSim.Region.Framework.Scenes
123 public void ResetInventoryIDs() 129 public void ResetInventoryIDs()
124 { 130 {
125 if (null == m_part) 131 if (null == m_part)
126 return; 132 m_items.LockItemsForWrite(true);
127 133
128 lock (m_items) 134 if (Items.Count == 0)
129 { 135 {
130 if (0 == m_items.Count) 136 m_items.LockItemsForWrite(false);
131 return; 137 return;
138 }
132 139
133 IList<TaskInventoryItem> items = GetInventoryItems(); 140 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
134 m_items.Clear(); 141 Items.Clear();
135 142
136 foreach (TaskInventoryItem item in items) 143 foreach (TaskInventoryItem item in items)
137 { 144 {
138 item.ResetIDs(m_part.UUID); 145 item.ResetIDs(m_part.UUID);
139 m_items.Add(item.ItemID, item); 146 Items.Add(item.ItemID, item);
140 }
141 } 147 }
148 m_items.LockItemsForWrite(false);
142 } 149 }
143 150
144 public void ResetObjectID() 151 public void ResetObjectID()
145 { 152 {
146 lock (Items) 153 m_items.LockItemsForWrite(true);
154
155 if (Items.Count == 0)
147 { 156 {
148 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 157 m_items.LockItemsForWrite(false);
149 Items.Clear(); 158 return;
150
151 foreach (TaskInventoryItem item in items)
152 {
153 item.ParentPartID = m_part.UUID;
154 item.ParentID = m_part.UUID;
155 Items.Add(item.ItemID, item);
156 }
157 } 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);
158 } 171 }
159 172
160 /// <summary> 173 /// <summary>
@@ -163,17 +176,14 @@ namespace OpenSim.Region.Framework.Scenes
163 /// <param name="ownerId"></param> 176 /// <param name="ownerId"></param>
164 public void ChangeInventoryOwner(UUID ownerId) 177 public void ChangeInventoryOwner(UUID ownerId)
165 { 178 {
166 lock (Items) 179 List<TaskInventoryItem> items = GetInventoryItems();
167 { 180
168 if (0 == Items.Count) 181 if (items.Count == 0)
169 { 182 return;
170 return;
171 }
172 }
173 183
184 m_items.LockItemsForWrite(true);
174 HasInventoryChanged = true; 185 HasInventoryChanged = true;
175 m_part.ParentGroup.HasGroupChanged = true; 186 m_part.ParentGroup.HasGroupChanged = true;
176 List<TaskInventoryItem> items = GetInventoryItems();
177 foreach (TaskInventoryItem item in items) 187 foreach (TaskInventoryItem item in items)
178 { 188 {
179 if (ownerId != item.OwnerID) 189 if (ownerId != item.OwnerID)
@@ -184,6 +194,7 @@ namespace OpenSim.Region.Framework.Scenes
184 item.PermsGranter = UUID.Zero; 194 item.PermsGranter = UUID.Zero;
185 item.OwnerChanged = true; 195 item.OwnerChanged = true;
186 } 196 }
197 m_items.LockItemsForWrite(false);
187 } 198 }
188 199
189 /// <summary> 200 /// <summary>
@@ -192,12 +203,11 @@ namespace OpenSim.Region.Framework.Scenes
192 /// <param name="groupID"></param> 203 /// <param name="groupID"></param>
193 public void ChangeInventoryGroup(UUID groupID) 204 public void ChangeInventoryGroup(UUID groupID)
194 { 205 {
195 lock (Items) 206 m_items.LockItemsForWrite(true);
207 if (0 == Items.Count)
196 { 208 {
197 if (0 == Items.Count) 209 m_items.LockItemsForWrite(false);
198 { 210 return;
199 return;
200 }
201 } 211 }
202 212
203 // Don't let this set the HasGroupChanged flag for attachments 213 // Don't let this set the HasGroupChanged flag for attachments
@@ -209,12 +219,45 @@ namespace OpenSim.Region.Framework.Scenes
209 m_part.ParentGroup.HasGroupChanged = true; 219 m_part.ParentGroup.HasGroupChanged = true;
210 } 220 }
211 221
212 List<TaskInventoryItem> items = GetInventoryItems(); 222 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
213 foreach (TaskInventoryItem item in items) 223 foreach (TaskInventoryItem item in items)
214 { 224 {
215 if (groupID != item.GroupID) 225 if (groupID != item.GroupID)
226 {
216 item.GroupID = groupID; 227 item.GroupID = groupID;
228 }
217 } 229 }
230 m_items.LockItemsForWrite(false);
231 }
232
233 private void QueryScriptStates()
234 {
235 if (m_part == null || m_part.ParentGroup == null)
236 return;
237
238 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
239 if (engines == null) // No engine at all
240 return;
241
242 Items.LockItemsForRead(true);
243 foreach (TaskInventoryItem item in Items.Values)
244 {
245 if (item.InvType == (int)InventoryType.LSL)
246 {
247 foreach (IScriptModule e in engines)
248 {
249 bool running;
250
251 if (e.HasScript(item.ItemID, out running))
252 {
253 item.ScriptRunning = running;
254 break;
255 }
256 }
257 }
258 }
259
260 Items.LockItemsForRead(false);
218 } 261 }
219 262
220 /// <summary> 263 /// <summary>
@@ -257,7 +300,10 @@ namespace OpenSim.Region.Framework.Scenes
257 { 300 {
258 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); 301 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
259 foreach (TaskInventoryItem item in scripts) 302 foreach (TaskInventoryItem item in scripts)
303 {
260 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); 304 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
305 m_part.RemoveScriptEvents(item.ItemID);
306 }
261 } 307 }
262 308
263 /// <summary> 309 /// <summary>
@@ -271,7 +317,10 @@ namespace OpenSim.Region.Framework.Scenes
271// item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); 317// item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName);
272 318
273 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) 319 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID))
320 {
321 StoreScriptError(item.ItemID, "no permission");
274 return; 322 return;
323 }
275 324
276 m_part.AddFlag(PrimFlags.Scripted); 325 m_part.AddFlag(PrimFlags.Scripted);
277 326
@@ -280,14 +329,13 @@ namespace OpenSim.Region.Framework.Scenes
280 if (stateSource == 2 && // Prim crossing 329 if (stateSource == 2 && // Prim crossing
281 m_part.ParentGroup.Scene.m_trustBinaries) 330 m_part.ParentGroup.Scene.m_trustBinaries)
282 { 331 {
283 lock (m_items) 332 m_items.LockItemsForWrite(true);
284 { 333 m_items[item.ItemID].PermsMask = 0;
285 m_items[item.ItemID].PermsMask = 0; 334 m_items[item.ItemID].PermsGranter = UUID.Zero;
286 m_items[item.ItemID].PermsGranter = UUID.Zero; 335 m_items.LockItemsForWrite(false);
287 }
288
289 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 336 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
290 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 337 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
338 StoreScriptErrors(item.ItemID, null);
291 m_part.ParentGroup.AddActiveScriptCount(1); 339 m_part.ParentGroup.AddActiveScriptCount(1);
292 m_part.ScheduleFullUpdate(); 340 m_part.ScheduleFullUpdate();
293 return; 341 return;
@@ -296,6 +344,8 @@ namespace OpenSim.Region.Framework.Scenes
296 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); 344 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
297 if (null == asset) 345 if (null == asset)
298 { 346 {
347 string msg = String.Format("asset ID {0} could not be found", item.AssetID);
348 StoreScriptError(item.ItemID, msg);
299 m_log.ErrorFormat( 349 m_log.ErrorFormat(
300 "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", 350 "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
301 item.Name, item.ItemID, m_part.AbsolutePosition, 351 item.Name, item.ItemID, m_part.AbsolutePosition,
@@ -306,16 +356,21 @@ namespace OpenSim.Region.Framework.Scenes
306 if (m_part.ParentGroup.m_savedScriptState != null) 356 if (m_part.ParentGroup.m_savedScriptState != null)
307 item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); 357 item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID);
308 358
309 lock (m_items) 359 m_items.LockItemsForWrite(true);
310 {
311 m_items[item.ItemID].OldItemID = item.OldItemID;
312 m_items[item.ItemID].PermsMask = 0;
313 m_items[item.ItemID].PermsGranter = UUID.Zero;
314 }
315 360
361 m_items[item.ItemID].OldItemID = item.OldItemID;
362 m_items[item.ItemID].PermsMask = 0;
363 m_items[item.ItemID].PermsGranter = UUID.Zero;
364
365 m_items.LockItemsForWrite(false);
366
316 string script = Utils.BytesToString(asset.Data); 367 string script = Utils.BytesToString(asset.Data);
317 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 368 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
318 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 369 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
370 StoreScriptErrors(item.ItemID, null);
371 if (!item.ScriptRunning)
372 m_part.ParentGroup.Scene.EventManager.TriggerStopScript(
373 m_part.LocalId, item.ItemID);
319 m_part.ParentGroup.AddActiveScriptCount(1); 374 m_part.ParentGroup.AddActiveScriptCount(1);
320 m_part.ScheduleFullUpdate(); 375 m_part.ScheduleFullUpdate();
321 } 376 }
@@ -386,20 +441,146 @@ namespace OpenSim.Region.Framework.Scenes
386 441
387 /// <summary> 442 /// <summary>
388 /// Start a script which is in this prim's inventory. 443 /// Start a script which is in this prim's inventory.
444 /// Some processing may occur in the background, but this routine returns asap.
389 /// </summary> 445 /// </summary>
390 /// <param name="itemId"> 446 /// <param name="itemId">
391 /// A <see cref="UUID"/> 447 /// A <see cref="UUID"/>
392 /// </param> 448 /// </param>
393 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 449 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
394 { 450 {
395 TaskInventoryItem item = GetInventoryItem(itemId); 451 lock (m_scriptErrors)
396 if (item != null) 452 {
397 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 453 // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion
454 m_scriptErrors.Remove(itemId);
455 }
456 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
457 }
458
459 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
460 {
461 m_items.LockItemsForRead(true);
462 if (m_items.ContainsKey(itemId))
463 {
464 if (m_items.ContainsKey(itemId))
465 {
466 m_items.LockItemsForRead(false);
467 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
468 }
469 else
470 {
471 m_items.LockItemsForRead(false);
472 string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID,
473 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
474 StoreScriptError(itemId, msg);
475 m_log.ErrorFormat(
476 "[PRIM INVENTORY]: " +
477 "Couldn't start script with ID {0} since it {1}", itemId, msg);
478 }
479 }
398 else 480 else
481 {
482 m_items.LockItemsForRead(false);
483 string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID);
484 StoreScriptError(itemId, msg);
399 m_log.ErrorFormat( 485 m_log.ErrorFormat(
400 "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 486 "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
401 itemId, m_part.Name, m_part.UUID, 487 itemId, m_part.Name, m_part.UUID,
402 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 488 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
489 }
490
491 }
492
493 /// <summary>
494 /// Start a script which is in this prim's inventory and return any compilation error messages.
495 /// </summary>
496 /// <param name="itemId">
497 /// A <see cref="UUID"/>
498 /// </param>
499 public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
500 {
501 ArrayList errors;
502
503 // Indicate to CreateScriptInstanceInternal() we want it to
504 // post any compilation/loading error messages
505 lock (m_scriptErrors)
506 {
507 m_scriptErrors[itemId] = null;
508 }
509
510 // Perform compilation/loading
511 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
512
513 // Wait for and retrieve any errors
514 lock (m_scriptErrors)
515 {
516 while ((errors = m_scriptErrors[itemId]) == null)
517 {
518 if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
519 {
520 m_log.ErrorFormat(
521 "[PRIM INVENTORY]: " +
522 "timedout waiting for script {0} errors", itemId);
523 errors = m_scriptErrors[itemId];
524 if (errors == null)
525 {
526 errors = new ArrayList(1);
527 errors.Add("timedout waiting for errors");
528 }
529 break;
530 }
531 }
532 m_scriptErrors.Remove(itemId);
533 }
534 return errors;
535 }
536
537 // Signal to CreateScriptInstanceEr() that compilation/loading is complete
538 private void StoreScriptErrors(UUID itemId, ArrayList errors)
539 {
540 lock (m_scriptErrors)
541 {
542 // If compilation/loading initiated via CreateScriptInstance(),
543 // it does not want the errors, so just get out
544 if (!m_scriptErrors.ContainsKey(itemId))
545 {
546 return;
547 }
548
549 // Initiated via CreateScriptInstanceEr(), if we know what the
550 // errors are, save them and wake CreateScriptInstanceEr().
551 if (errors != null)
552 {
553 m_scriptErrors[itemId] = errors;
554 System.Threading.Monitor.PulseAll(m_scriptErrors);
555 return;
556 }
557 }
558
559 // Initiated via CreateScriptInstanceEr() but we don't know what
560 // the errors are yet, so retrieve them from the script engine.
561 // This may involve some waiting internal to GetScriptErrors().
562 errors = GetScriptErrors(itemId);
563
564 // Get a default non-null value to indicate success.
565 if (errors == null)
566 {
567 errors = new ArrayList();
568 }
569
570 // Post to CreateScriptInstanceEr() and wake it up
571 lock (m_scriptErrors)
572 {
573 m_scriptErrors[itemId] = errors;
574 System.Threading.Monitor.PulseAll(m_scriptErrors);
575 }
576 }
577
578 // Like StoreScriptErrors(), but just posts a single string message
579 private void StoreScriptError(UUID itemId, string message)
580 {
581 ArrayList errors = new ArrayList(1);
582 errors.Add(message);
583 StoreScriptErrors(itemId, errors);
403 } 584 }
404 585
405 /// <summary> 586 /// <summary>
@@ -412,15 +593,7 @@ namespace OpenSim.Region.Framework.Scenes
412 /// </param> 593 /// </param>
413 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 594 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
414 { 595 {
415 bool scriptPresent = false; 596 if (m_items.ContainsKey(itemId))
416
417 lock (m_items)
418 {
419 if (m_items.ContainsKey(itemId))
420 scriptPresent = true;
421 }
422
423 if (scriptPresent)
424 { 597 {
425 if (!sceneObjectBeingDeleted) 598 if (!sceneObjectBeingDeleted)
426 m_part.RemoveScriptEvents(itemId); 599 m_part.RemoveScriptEvents(itemId);
@@ -445,14 +618,16 @@ namespace OpenSim.Region.Framework.Scenes
445 /// <returns></returns> 618 /// <returns></returns>
446 private bool InventoryContainsName(string name) 619 private bool InventoryContainsName(string name)
447 { 620 {
448 lock (m_items) 621 m_items.LockItemsForRead(true);
622 foreach (TaskInventoryItem item in m_items.Values)
449 { 623 {
450 foreach (TaskInventoryItem item in m_items.Values) 624 if (item.Name == name)
451 { 625 {
452 if (item.Name == name) 626 m_items.LockItemsForRead(false);
453 return true; 627 return true;
454 } 628 }
455 } 629 }
630 m_items.LockItemsForRead(false);
456 return false; 631 return false;
457 } 632 }
458 633
@@ -494,8 +669,9 @@ namespace OpenSim.Region.Framework.Scenes
494 /// <param name="item"></param> 669 /// <param name="item"></param>
495 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 670 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
496 { 671 {
497 List<TaskInventoryItem> il = GetInventoryItems(); 672 m_items.LockItemsForRead(true);
498 673 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
674 m_items.LockItemsForRead(false);
499 foreach (TaskInventoryItem i in il) 675 foreach (TaskInventoryItem i in il)
500 { 676 {
501 if (i.Name == item.Name) 677 if (i.Name == item.Name)
@@ -533,14 +709,14 @@ namespace OpenSim.Region.Framework.Scenes
533 item.Name = name; 709 item.Name = name;
534 item.GroupID = m_part.GroupID; 710 item.GroupID = m_part.GroupID;
535 711
536 lock (m_items) 712 m_items.LockItemsForWrite(true);
537 m_items.Add(item.ItemID, item); 713 m_items.Add(item.ItemID, item);
538 714 m_items.LockItemsForWrite(false);
539 if (allowedDrop) 715 if (allowedDrop)
540 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 716 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
541 else 717 else
542 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 718 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
543 719
544 m_inventorySerial++; 720 m_inventorySerial++;
545 //m_inventorySerial += 2; 721 //m_inventorySerial += 2;
546 HasInventoryChanged = true; 722 HasInventoryChanged = true;
@@ -556,15 +732,15 @@ namespace OpenSim.Region.Framework.Scenes
556 /// <param name="items"></param> 732 /// <param name="items"></param>
557 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 733 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
558 { 734 {
559 lock (m_items) 735 m_items.LockItemsForWrite(true);
736 foreach (TaskInventoryItem item in items)
560 { 737 {
561 foreach (TaskInventoryItem item in items) 738 m_items.Add(item.ItemID, item);
562 { 739// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
563 m_items.Add(item.ItemID, item);
564// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
565 }
566 m_inventorySerial++;
567 } 740 }
741 m_items.LockItemsForWrite(false);
742
743 m_inventorySerial++;
568 } 744 }
569 745
570 /// <summary> 746 /// <summary>
@@ -575,23 +751,24 @@ namespace OpenSim.Region.Framework.Scenes
575 public TaskInventoryItem GetInventoryItem(UUID itemId) 751 public TaskInventoryItem GetInventoryItem(UUID itemId)
576 { 752 {
577 TaskInventoryItem item; 753 TaskInventoryItem item;
578 754 m_items.LockItemsForRead(true);
579 lock (m_items) 755 m_items.TryGetValue(itemId, out item);
580 m_items.TryGetValue(itemId, out item); 756 m_items.LockItemsForRead(false);
581
582 return item; 757 return item;
583 } 758 }
584 759
585 public TaskInventoryItem GetInventoryItem(string name) 760 public TaskInventoryItem GetInventoryItem(string name)
586 { 761 {
587 lock (m_items) 762 m_items.LockItemsForRead(true);
763 foreach (TaskInventoryItem item in m_items.Values)
588 { 764 {
589 foreach (TaskInventoryItem item in m_items.Values) 765 if (item.Name == name)
590 { 766 {
591 if (item.Name == name) 767 m_items.LockItemsForRead(false);
592 return item; 768 return item;
593 } 769 }
594 } 770 }
771 m_items.LockItemsForRead(false);
595 772
596 return null; 773 return null;
597 } 774 }
@@ -600,15 +777,16 @@ namespace OpenSim.Region.Framework.Scenes
600 { 777 {
601 List<TaskInventoryItem> items = new List<TaskInventoryItem>(); 778 List<TaskInventoryItem> items = new List<TaskInventoryItem>();
602 779
603 lock (m_items) 780 m_items.LockItemsForRead(true);
781
782 foreach (TaskInventoryItem item in m_items.Values)
604 { 783 {
605 foreach (TaskInventoryItem item in m_items.Values) 784 if (item.Name == name)
606 { 785 items.Add(item);
607 if (item.Name == name)
608 items.Add(item);
609 }
610 } 786 }
611 787
788 m_items.LockItemsForRead(false);
789
612 return items; 790 return items;
613 } 791 }
614 792
@@ -627,6 +805,10 @@ namespace OpenSim.Region.Framework.Scenes
627 string xmlData = Utils.BytesToString(rezAsset.Data); 805 string xmlData = Utils.BytesToString(rezAsset.Data);
628 SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); 806 SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData);
629 807
808 group.RootPart.AttachPoint = group.RootPart.Shape.State;
809 group.RootPart.AttachOffset = group.AbsolutePosition;
810 group.RootPart.AttachRotation = group.GroupRotation;
811
630 group.ResetIDs(); 812 group.ResetIDs();
631 813
632 SceneObjectPart rootPart = group.GetPart(group.UUID); 814 SceneObjectPart rootPart = group.GetPart(group.UUID);
@@ -701,8 +883,9 @@ namespace OpenSim.Region.Framework.Scenes
701 883
702 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) 884 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged)
703 { 885 {
704 TaskInventoryItem it = GetInventoryItem(item.ItemID); 886 m_items.LockItemsForWrite(true);
705 if (it != null) 887
888 if (m_items.ContainsKey(item.ItemID))
706 { 889 {
707// m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); 890// m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name);
708 891
@@ -715,14 +898,10 @@ namespace OpenSim.Region.Framework.Scenes
715 item.GroupID = m_part.GroupID; 898 item.GroupID = m_part.GroupID;
716 899
717 if (item.AssetID == UUID.Zero) 900 if (item.AssetID == UUID.Zero)
718 item.AssetID = it.AssetID; 901 item.AssetID = m_items[item.ItemID].AssetID;
719 902
720 lock (m_items) 903 m_items[item.ItemID] = item;
721 { 904 m_inventorySerial++;
722 m_items[item.ItemID] = item;
723 m_inventorySerial++;
724 }
725
726 if (fireScriptEvents) 905 if (fireScriptEvents)
727 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 906 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
728 907
@@ -731,7 +910,7 @@ namespace OpenSim.Region.Framework.Scenes
731 HasInventoryChanged = true; 910 HasInventoryChanged = true;
732 m_part.ParentGroup.HasGroupChanged = true; 911 m_part.ParentGroup.HasGroupChanged = true;
733 } 912 }
734 913 m_items.LockItemsForWrite(false);
735 return true; 914 return true;
736 } 915 }
737 else 916 else
@@ -742,8 +921,9 @@ namespace OpenSim.Region.Framework.Scenes
742 item.ItemID, m_part.Name, m_part.UUID, 921 item.ItemID, m_part.Name, m_part.UUID,
743 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 922 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
744 } 923 }
745 return false; 924 m_items.LockItemsForWrite(false);
746 925
926 return false;
747 } 927 }
748 928
749 /// <summary> 929 /// <summary>
@@ -754,43 +934,59 @@ namespace OpenSim.Region.Framework.Scenes
754 /// in this prim's inventory.</returns> 934 /// in this prim's inventory.</returns>
755 public int RemoveInventoryItem(UUID itemID) 935 public int RemoveInventoryItem(UUID itemID)
756 { 936 {
757 TaskInventoryItem item = GetInventoryItem(itemID); 937 m_items.LockItemsForRead(true);
758 if (item != null) 938
939 if (m_items.ContainsKey(itemID))
759 { 940 {
760 int type = m_items[itemID].InvType; 941 int type = m_items[itemID].InvType;
942 m_items.LockItemsForRead(false);
761 if (type == 10) // Script 943 if (type == 10) // Script
762 { 944 {
763 m_part.RemoveScriptEvents(itemID);
764 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 945 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
765 } 946 }
947 m_items.LockItemsForWrite(true);
766 m_items.Remove(itemID); 948 m_items.Remove(itemID);
949 m_items.LockItemsForWrite(false);
767 m_inventorySerial++; 950 m_inventorySerial++;
768 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 951 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
769 952
770 HasInventoryChanged = true; 953 HasInventoryChanged = true;
771 m_part.ParentGroup.HasGroupChanged = true; 954 m_part.ParentGroup.HasGroupChanged = true;
772 955
773 if (!ContainsScripts()) 956 int scriptcount = 0;
957 m_items.LockItemsForRead(true);
958 foreach (TaskInventoryItem item in m_items.Values)
959 {
960 if (item.Type == 10)
961 {
962 scriptcount++;
963 }
964 }
965 m_items.LockItemsForRead(false);
966
967
968 if (scriptcount <= 0)
969 {
774 m_part.RemFlag(PrimFlags.Scripted); 970 m_part.RemFlag(PrimFlags.Scripted);
971 }
775 972
776 m_part.ScheduleFullUpdate(); 973 m_part.ScheduleFullUpdate();
777 974
778 return type; 975 return type;
779
780 } 976 }
781 else 977 else
782 { 978 {
979 m_items.LockItemsForRead(false);
783 m_log.ErrorFormat( 980 m_log.ErrorFormat(
784 "[PRIM INVENTORY]: " + 981 "[PRIM INVENTORY]: " +
785 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 982 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
786 itemID, m_part.Name, m_part.UUID, 983 itemID, m_part.Name, m_part.UUID);
787 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
788 } 984 }
789 985
790 return -1; 986 return -1;
791 } 987 }
792 988
793 private bool CreateInventoryFile() 989 private bool CreateInventoryFileName()
794 { 990 {
795// m_log.DebugFormat( 991// m_log.DebugFormat(
796// "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", 992// "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}",
@@ -799,116 +995,125 @@ namespace OpenSim.Region.Framework.Scenes
799 if (m_inventoryFileName == String.Empty || 995 if (m_inventoryFileName == String.Empty ||
800 m_inventoryFileNameSerial < m_inventorySerial) 996 m_inventoryFileNameSerial < m_inventorySerial)
801 { 997 {
802 // Something changed, we need to create a new file
803 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; 998 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
804 m_inventoryFileNameSerial = m_inventorySerial; 999 m_inventoryFileNameSerial = m_inventorySerial;
805 1000
806 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 1001 return true;
1002 }
1003
1004 return false;
1005 }
807 1006
808 lock (m_items) 1007 /// <summary>
1008 /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client
1009 /// </summary>
1010 /// <param name="xferManager"></param>
1011 public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
1012 {
1013 bool changed = CreateInventoryFileName();
1014
1015 bool includeAssets = false;
1016 if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId))
1017 includeAssets = true;
1018
1019 if (m_inventoryPrivileged != includeAssets)
1020 changed = true;
1021
1022 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
1023
1024 Items.LockItemsForRead(true);
1025
1026 if (m_inventorySerial == 0) // No inventory
1027 {
1028 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1029 Items.LockItemsForRead(false);
1030 return;
1031 }
1032
1033 if (m_items.Count == 0) // No inventory
1034 {
1035 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1036 Items.LockItemsForRead(false);
1037 return;
1038 }
1039
1040 if (!changed)
1041 {
1042 if (m_inventoryFileData.Length > 2)
809 { 1043 {
810 foreach (TaskInventoryItem item in m_items.Values) 1044 xferManager.AddNewFile(m_inventoryFileName,
811 { 1045 m_inventoryFileData);
812// m_log.DebugFormat( 1046 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
813// "[PRIM INVENTORY]: Adding item {0} {1} for serial {2} on prim {3} {4} {5}", 1047 Util.StringToBytes256(m_inventoryFileName));
814// item.Name, item.ItemID, m_inventorySerial, m_part.Name, m_part.UUID, m_part.LocalId);
815 1048
816 UUID ownerID = item.OwnerID; 1049 Items.LockItemsForRead(false);
817 uint everyoneMask = 0; 1050 return;
818 uint baseMask = item.BasePermissions; 1051 }
819 uint ownerMask = item.CurrentPermissions; 1052 }
820 uint groupMask = item.GroupPermissions;
821 1053
822 invString.AddItemStart(); 1054 m_inventoryPrivileged = includeAssets;
823 invString.AddNameValueLine("item_id", item.ItemID.ToString());
824 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
825 1055
826 invString.AddPermissionsStart(); 1056 foreach (TaskInventoryItem item in m_items.Values)
1057 {
1058 UUID ownerID = item.OwnerID;
1059 uint everyoneMask = 0;
1060 uint baseMask = item.BasePermissions;
1061 uint ownerMask = item.CurrentPermissions;
1062 uint groupMask = item.GroupPermissions;
827 1063
828 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 1064 invString.AddItemStart();
829 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 1065 invString.AddNameValueLine("item_id", item.ItemID.ToString());
830 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); 1066 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
831 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
832 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
833 1067
834 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 1068 invString.AddPermissionsStart();
835 invString.AddNameValueLine("owner_id", ownerID.ToString());
836 1069
837 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 1070 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
1071 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
1072 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
1073 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
1074 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
838 1075
839 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 1076 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
840 invString.AddSectionEnd(); 1077 invString.AddNameValueLine("owner_id", ownerID.ToString());
841 1078
842 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 1079 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
843 invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type));
844 invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType));
845 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
846 1080
847 invString.AddSaleStart(); 1081 invString.AddNameValueLine("group_id", item.GroupID.ToString());
848 invString.AddNameValueLine("sale_type", "not"); 1082 invString.AddSectionEnd();
849 invString.AddNameValueLine("sale_price", "0");
850 invString.AddSectionEnd();
851 1083
852 invString.AddNameValueLine("name", item.Name + "|"); 1084 if (includeAssets)
853 invString.AddNameValueLine("desc", item.Description + "|"); 1085 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
1086 else
1087 invString.AddNameValueLine("asset_id", UUID.Zero.ToString());
1088 invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type));
1089 invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType));
1090 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
854 1091
855 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 1092 invString.AddSaleStart();
856 invString.AddSectionEnd(); 1093 invString.AddNameValueLine("sale_type", "not");
857 } 1094 invString.AddNameValueLine("sale_price", "0");
858 } 1095 invString.AddSectionEnd();
859 1096
860 m_inventoryFileData = Utils.StringToBytes(invString.BuildString); 1097 invString.AddNameValueLine("name", item.Name + "|");
1098 invString.AddNameValueLine("desc", item.Description + "|");
861 1099
862 return true; 1100 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
1101 invString.AddSectionEnd();
863 } 1102 }
864 1103
865 // No need to recreate, the existing file is fine 1104 Items.LockItemsForRead(false);
866 return false;
867 }
868
869 /// <summary>
870 /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client
871 /// </summary>
872 /// <param name="xferManager"></param>
873 public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
874 {
875 lock (m_items)
876 {
877 // Don't send a inventory xfer name if there are no items. Doing so causes viewer 3 to crash when rezzing
878 // a new script if any previous deletion has left the prim inventory empty.
879 if (m_items.Count == 0) // No inventory
880 {
881// m_log.DebugFormat(
882// "[PRIM INVENTORY]: Not sending inventory data for part {0} {1} {2} for {3} since no items",
883// m_part.Name, m_part.LocalId, m_part.UUID, client.Name);
884 1105
885 client.SendTaskInventory(m_part.UUID, 0, new byte[0]); 1106 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
886 return;
887 }
888 1107
889 CreateInventoryFile(); 1108 if (m_inventoryFileData.Length > 2)
890 1109 {
891 // In principle, we should only do the rest if the inventory changed; 1110 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
892 // by sending m_inventorySerial to the client, it ought to know 1111 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
893 // that nothing changed and that it doesn't need to request the file. 1112 Util.StringToBytes256(m_inventoryFileName));
894 // Unfortunately, it doesn't look like the client optimizes this; 1113 return;
895 // the client seems to always come back and request the Xfer,
896 // no matter what value m_inventorySerial has.
897 // FIXME: Could probably be > 0 here rather than > 2
898 if (m_inventoryFileData.Length > 2)
899 {
900 // Add the file for Xfer
901 // m_log.DebugFormat(
902 // "[PRIM INVENTORY]: Adding inventory file {0} (length {1}) for transfer on {2} {3} {4}",
903 // m_inventoryFileName, m_inventoryFileData.Length, m_part.Name, m_part.UUID, m_part.LocalId);
904
905 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
906 }
907
908 // Tell the client we're ready to Xfer the file
909 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
910 Util.StringToBytes256(m_inventoryFileName));
911 } 1114 }
1115
1116 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
912 } 1117 }
913 1118
914 /// <summary> 1119 /// <summary>
@@ -917,13 +1122,19 @@ namespace OpenSim.Region.Framework.Scenes
917 /// <param name="datastore"></param> 1122 /// <param name="datastore"></param>
918 public void ProcessInventoryBackup(ISimulationDataService datastore) 1123 public void ProcessInventoryBackup(ISimulationDataService datastore)
919 { 1124 {
920 if (HasInventoryChanged) 1125// Removed this because linking will cause an immediate delete of the new
921 { 1126// child prim from the database and the subsequent storing of the prim sees
922 HasInventoryChanged = false; 1127// the inventory of it as unchanged and doesn't store it at all. The overhead
923 List<TaskInventoryItem> items = GetInventoryItems(); 1128// of storing prim inventory needlessly is much less than the aggravation
924 datastore.StorePrimInventory(m_part.UUID, items); 1129// of prim inventory loss.
1130// if (HasInventoryChanged)
1131// {
1132 Items.LockItemsForRead(true);
1133 datastore.StorePrimInventory(m_part.UUID, Items.Values);
1134 Items.LockItemsForRead(false);
925 1135
926 } 1136 HasInventoryChanged = false;
1137// }
927 } 1138 }
928 1139
929 public class InventoryStringBuilder 1140 public class InventoryStringBuilder
@@ -989,87 +1200,63 @@ namespace OpenSim.Region.Framework.Scenes
989 { 1200 {
990 uint mask=0x7fffffff; 1201 uint mask=0x7fffffff;
991 1202
992 lock (m_items) 1203 foreach (TaskInventoryItem item in m_items.Values)
993 { 1204 {
994 foreach (TaskInventoryItem item in m_items.Values) 1205 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
1206 mask &= ~((uint)PermissionMask.Copy >> 13);
1207 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
1208 mask &= ~((uint)PermissionMask.Transfer >> 13);
1209 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
1210 mask &= ~((uint)PermissionMask.Modify >> 13);
1211
1212 if (item.InvType == (int)InventoryType.Object)
995 { 1213 {
996 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1214 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
997 mask &= ~((uint)PermissionMask.Copy >> 13); 1215 mask &= ~((uint)PermissionMask.Copy >> 13);
998 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1216 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
999 mask &= ~((uint)PermissionMask.Transfer >> 13); 1217 mask &= ~((uint)PermissionMask.Transfer >> 13);
1000 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 1218 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1001 mask &= ~((uint)PermissionMask.Modify >> 13); 1219 mask &= ~((uint)PermissionMask.Modify >> 13);
1002
1003 if (item.InvType != (int)InventoryType.Object)
1004 {
1005 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
1006 mask &= ~((uint)PermissionMask.Copy >> 13);
1007 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
1008 mask &= ~((uint)PermissionMask.Transfer >> 13);
1009 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
1010 mask &= ~((uint)PermissionMask.Modify >> 13);
1011 }
1012 else
1013 {
1014 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1015 mask &= ~((uint)PermissionMask.Copy >> 13);
1016 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1017 mask &= ~((uint)PermissionMask.Transfer >> 13);
1018 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1019 mask &= ~((uint)PermissionMask.Modify >> 13);
1020 }
1021
1022 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1023 mask &= ~(uint)PermissionMask.Copy;
1024 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1025 mask &= ~(uint)PermissionMask.Transfer;
1026 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1027 mask &= ~(uint)PermissionMask.Modify;
1028 } 1220 }
1221
1222 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1223 mask &= ~(uint)PermissionMask.Copy;
1224 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1225 mask &= ~(uint)PermissionMask.Transfer;
1226 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1227 mask &= ~(uint)PermissionMask.Modify;
1029 } 1228 }
1030
1031 return mask; 1229 return mask;
1032 } 1230 }
1033 1231
1034 public void ApplyNextOwnerPermissions() 1232 public void ApplyNextOwnerPermissions()
1035 { 1233 {
1036 lock (m_items) 1234 foreach (TaskInventoryItem item in m_items.Values)
1037 { 1235 {
1038 foreach (TaskInventoryItem item in m_items.Values) 1236 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
1039 { 1237 {
1040// m_log.DebugFormat ( 1238 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1041// "[SCENE OBJECT PART INVENTORY]: Applying next permissions {0} to {1} in {2} with current {3}, base {4}, everyone {5}", 1239 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
1042// item.NextPermissions, item.Name, m_part.Name, item.CurrentPermissions, item.BasePermissions, item.EveryonePermissions); 1240 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1043 1241 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
1044 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 1242 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1045 { 1243 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1046 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1047 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
1048 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1049 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
1050 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1051 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1052 }
1053
1054 item.CurrentPermissions &= item.NextPermissions;
1055 item.BasePermissions &= item.NextPermissions;
1056 item.EveryonePermissions &= item.NextPermissions;
1057 item.OwnerChanged = true;
1058 item.PermsMask = 0;
1059 item.PermsGranter = UUID.Zero;
1060 } 1244 }
1245 item.CurrentPermissions &= item.NextPermissions;
1246 item.BasePermissions &= item.NextPermissions;
1247 item.EveryonePermissions &= item.NextPermissions;
1248 item.OwnerChanged = true;
1249 item.PermsMask = 0;
1250 item.PermsGranter = UUID.Zero;
1061 } 1251 }
1062 } 1252 }
1063 1253
1064 public void ApplyGodPermissions(uint perms) 1254 public void ApplyGodPermissions(uint perms)
1065 { 1255 {
1066 lock (m_items) 1256 foreach (TaskInventoryItem item in m_items.Values)
1067 { 1257 {
1068 foreach (TaskInventoryItem item in m_items.Values) 1258 item.CurrentPermissions = perms;
1069 { 1259 item.BasePermissions = perms;
1070 item.CurrentPermissions = perms;
1071 item.BasePermissions = perms;
1072 }
1073 } 1260 }
1074 1261
1075 m_inventorySerial++; 1262 m_inventorySerial++;
@@ -1082,14 +1269,11 @@ namespace OpenSim.Region.Framework.Scenes
1082 /// <returns></returns> 1269 /// <returns></returns>
1083 public bool ContainsScripts() 1270 public bool ContainsScripts()
1084 { 1271 {
1085 lock (m_items) 1272 foreach (TaskInventoryItem item in m_items.Values)
1086 { 1273 {
1087 foreach (TaskInventoryItem item in m_items.Values) 1274 if (item.InvType == (int)InventoryType.LSL)
1088 { 1275 {
1089 if (item.InvType == (int)InventoryType.LSL) 1276 return true;
1090 {
1091 return true;
1092 }
1093 } 1277 }
1094 } 1278 }
1095 1279
@@ -1103,17 +1287,15 @@ namespace OpenSim.Region.Framework.Scenes
1103 public int ScriptCount() 1287 public int ScriptCount()
1104 { 1288 {
1105 int count = 0; 1289 int count = 0;
1106 lock (m_items) 1290 Items.LockItemsForRead(true);
1291 foreach (TaskInventoryItem item in m_items.Values)
1107 { 1292 {
1108 foreach (TaskInventoryItem item in m_items.Values) 1293 if (item.InvType == (int)InventoryType.LSL)
1109 { 1294 {
1110 if (item.InvType == (int)InventoryType.LSL) 1295 count++;
1111 {
1112 count++;
1113 }
1114 } 1296 }
1115 } 1297 }
1116 1298 Items.LockItemsForRead(false);
1117 return count; 1299 return count;
1118 } 1300 }
1119 /// <summary> 1301 /// <summary>
@@ -1149,11 +1331,8 @@ namespace OpenSim.Region.Framework.Scenes
1149 { 1331 {
1150 List<UUID> ret = new List<UUID>(); 1332 List<UUID> ret = new List<UUID>();
1151 1333
1152 lock (m_items) 1334 foreach (TaskInventoryItem item in m_items.Values)
1153 { 1335 ret.Add(item.ItemID);
1154 foreach (TaskInventoryItem item in m_items.Values)
1155 ret.Add(item.ItemID);
1156 }
1157 1336
1158 return ret; 1337 return ret;
1159 } 1338 }
@@ -1162,8 +1341,9 @@ namespace OpenSim.Region.Framework.Scenes
1162 { 1341 {
1163 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1342 List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
1164 1343
1165 lock (m_items) 1344 Items.LockItemsForRead(true);
1166 ret = new List<TaskInventoryItem>(m_items.Values); 1345 ret = new List<TaskInventoryItem>(m_items.Values);
1346 Items.LockItemsForRead(false);
1167 1347
1168 return ret; 1348 return ret;
1169 } 1349 }
@@ -1172,18 +1352,24 @@ namespace OpenSim.Region.Framework.Scenes
1172 { 1352 {
1173 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1353 List<TaskInventoryItem> ret = new List<TaskInventoryItem>();
1174 1354
1175 lock (m_items) 1355 Items.LockItemsForRead(true);
1176 { 1356
1177 foreach (TaskInventoryItem item in m_items.Values) 1357 foreach (TaskInventoryItem item in m_items.Values)
1178 if (item.InvType == (int)type) 1358 if (item.InvType == (int)type)
1179 ret.Add(item); 1359 ret.Add(item);
1180 } 1360
1361 Items.LockItemsForRead(false);
1181 1362
1182 return ret; 1363 return ret;
1183 } 1364 }
1184 1365
1185 public Dictionary<UUID, string> GetScriptStates() 1366 public Dictionary<UUID, string> GetScriptStates()
1186 { 1367 {
1368 return GetScriptStates(false);
1369 }
1370
1371 public Dictionary<UUID, string> GetScriptStates(bool oldIDs)
1372 {
1187 Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); 1373 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
1188 1374
1189 if (m_part.ParentGroup.Scene == null) // Group not in a scene 1375 if (m_part.ParentGroup.Scene == null) // Group not in a scene
@@ -1205,14 +1391,21 @@ namespace OpenSim.Region.Framework.Scenes
1205 string n = e.GetXMLState(item.ItemID); 1391 string n = e.GetXMLState(item.ItemID);
1206 if (n != String.Empty) 1392 if (n != String.Empty)
1207 { 1393 {
1208 if (!ret.ContainsKey(item.ItemID)) 1394 if (oldIDs)
1209 ret[item.ItemID] = n; 1395 {
1396 if (!ret.ContainsKey(item.OldItemID))
1397 ret[item.OldItemID] = n;
1398 }
1399 else
1400 {
1401 if (!ret.ContainsKey(item.ItemID))
1402 ret[item.ItemID] = n;
1403 }
1210 break; 1404 break;
1211 } 1405 }
1212 } 1406 }
1213 } 1407 }
1214 } 1408 }
1215
1216 return ret; 1409 return ret;
1217 } 1410 }
1218 1411
@@ -1245,4 +1438,4 @@ namespace OpenSim.Region.Framework.Scenes
1245 } 1438 }
1246 } 1439 }
1247 } 1440 }
1248} \ No newline at end of file 1441}