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.cs674
1 files changed, 427 insertions, 247 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 1177378..9412e09 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -48,6 +48,8 @@ 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
52 private Dictionary<UUID, ArrayList> m_scriptErrors = new Dictionary<UUID, ArrayList>();
51 53
52 /// <value> 54 /// <value>
53 /// The part to which the inventory belongs. 55 /// The part to which the inventory belongs.
@@ -84,7 +86,9 @@ namespace OpenSim.Region.Framework.Scenes
84 /// </value> 86 /// </value>
85 protected internal TaskInventoryDictionary Items 87 protected internal TaskInventoryDictionary Items
86 { 88 {
87 get { return m_items; } 89 get {
90 return m_items;
91 }
88 set 92 set
89 { 93 {
90 m_items = value; 94 m_items = value;
@@ -120,39 +124,45 @@ namespace OpenSim.Region.Framework.Scenes
120 /// <param name="linkNum">Link number for the part</param> 124 /// <param name="linkNum">Link number for the part</param>
121 public void ResetInventoryIDs() 125 public void ResetInventoryIDs()
122 { 126 {
123 if (null == m_part || null == m_part.ParentGroup) 127 m_items.LockItemsForWrite(true);
124 return; 128
125 129 if (Items.Count == 0)
126 lock (m_items)
127 { 130 {
128 if (0 == m_items.Count) 131 m_items.LockItemsForWrite(false);
129 return; 132 return;
133 }
130 134
131 IList<TaskInventoryItem> items = GetInventoryItems(); 135 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
132 m_items.Clear(); 136 Items.Clear();
133 137
134 foreach (TaskInventoryItem item in items) 138 foreach (TaskInventoryItem item in items)
135 { 139 {
136 item.ResetIDs(m_part.UUID); 140 item.ResetIDs(m_part.UUID);
137 m_items.Add(item.ItemID, item); 141 Items.Add(item.ItemID, item);
138 }
139 } 142 }
143 m_items.LockItemsForWrite(false);
140 } 144 }
141 145
142 public void ResetObjectID() 146 public void ResetObjectID()
143 { 147 {
144 lock (Items) 148 m_items.LockItemsForWrite(true);
149
150 if (Items.Count == 0)
145 { 151 {
146 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 152 m_items.LockItemsForWrite(false);
147 Items.Clear(); 153 return;
148 154 }
149 foreach (TaskInventoryItem item in items) 155
150 { 156 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
151 item.ParentPartID = m_part.UUID; 157 Items.Clear();
152 item.ParentID = m_part.UUID; 158
153 Items.Add(item.ItemID, item); 159 foreach (TaskInventoryItem item in items)
154 } 160 {
161 item.ParentPartID = m_part.UUID;
162 item.ParentID = m_part.UUID;
163 Items.Add(item.ItemID, item);
155 } 164 }
165 m_items.LockItemsForWrite(false);
156 } 166 }
157 167
158 /// <summary> 168 /// <summary>
@@ -161,12 +171,11 @@ namespace OpenSim.Region.Framework.Scenes
161 /// <param name="ownerId"></param> 171 /// <param name="ownerId"></param>
162 public void ChangeInventoryOwner(UUID ownerId) 172 public void ChangeInventoryOwner(UUID ownerId)
163 { 173 {
164 lock (Items) 174 m_items.LockItemsForWrite(true);
175 if (0 == Items.Count)
165 { 176 {
166 if (0 == Items.Count) 177 m_items.LockItemsForWrite(false);
167 { 178 return;
168 return;
169 }
170 } 179 }
171 180
172 HasInventoryChanged = true; 181 HasInventoryChanged = true;
@@ -180,6 +189,7 @@ namespace OpenSim.Region.Framework.Scenes
180 item.OwnerID = ownerId; 189 item.OwnerID = ownerId;
181 } 190 }
182 } 191 }
192 m_items.LockItemsForWrite(false);
183 } 193 }
184 194
185 /// <summary> 195 /// <summary>
@@ -188,12 +198,11 @@ namespace OpenSim.Region.Framework.Scenes
188 /// <param name="groupID"></param> 198 /// <param name="groupID"></param>
189 public void ChangeInventoryGroup(UUID groupID) 199 public void ChangeInventoryGroup(UUID groupID)
190 { 200 {
191 lock (Items) 201 m_items.LockItemsForWrite(true);
202 if (0 == Items.Count)
192 { 203 {
193 if (0 == Items.Count) 204 m_items.LockItemsForWrite(false);
194 { 205 return;
195 return;
196 }
197 } 206 }
198 207
199 // Don't let this set the HasGroupChanged flag for attachments 208 // Don't let this set the HasGroupChanged flag for attachments
@@ -205,12 +214,15 @@ namespace OpenSim.Region.Framework.Scenes
205 m_part.ParentGroup.HasGroupChanged = true; 214 m_part.ParentGroup.HasGroupChanged = true;
206 } 215 }
207 216
208 List<TaskInventoryItem> items = GetInventoryItems(); 217 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
209 foreach (TaskInventoryItem item in items) 218 foreach (TaskInventoryItem item in items)
210 { 219 {
211 if (groupID != item.GroupID) 220 if (groupID != item.GroupID)
221 {
212 item.GroupID = groupID; 222 item.GroupID = groupID;
223 }
213 } 224 }
225 m_items.LockItemsForWrite(false);
214 } 226 }
215 227
216 /// <summary> 228 /// <summary>
@@ -218,9 +230,14 @@ namespace OpenSim.Region.Framework.Scenes
218 /// </summary> 230 /// </summary>
219 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 231 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
220 { 232 {
221 List<TaskInventoryItem> scripts = GetInventoryScripts(); 233 Items.LockItemsForRead(true);
222 foreach (TaskInventoryItem item in scripts) 234 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
223 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 235 Items.LockItemsForRead(false);
236 foreach (TaskInventoryItem item in items)
237 {
238 if ((int)InventoryType.LSL == item.InvType)
239 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
240 }
224 } 241 }
225 242
226 public ArrayList GetScriptErrors(UUID itemID) 243 public ArrayList GetScriptErrors(UUID itemID)
@@ -253,9 +270,18 @@ namespace OpenSim.Region.Framework.Scenes
253 /// </param> 270 /// </param>
254 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 271 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
255 { 272 {
256 List<TaskInventoryItem> scripts = GetInventoryScripts(); 273 Items.LockItemsForRead(true);
257 foreach (TaskInventoryItem item in scripts) 274 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
258 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); 275 Items.LockItemsForRead(false);
276
277 foreach (TaskInventoryItem item in items)
278 {
279 if ((int)InventoryType.LSL == item.InvType)
280 {
281 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
282 m_part.RemoveScriptEvents(item.ItemID);
283 }
284 }
259 } 285 }
260 286
261 /// <summary> 287 /// <summary>
@@ -271,7 +297,10 @@ namespace OpenSim.Region.Framework.Scenes
271 // item.Name, item.ItemID, Name, UUID); 297 // item.Name, item.ItemID, Name, UUID);
272 298
273 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) 299 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID))
300 {
301 StoreScriptError(item.ItemID, "no permission");
274 return; 302 return;
303 }
275 304
276 m_part.AddFlag(PrimFlags.Scripted); 305 m_part.AddFlag(PrimFlags.Scripted);
277 306
@@ -280,14 +309,13 @@ namespace OpenSim.Region.Framework.Scenes
280 if (stateSource == 2 && // Prim crossing 309 if (stateSource == 2 && // Prim crossing
281 m_part.ParentGroup.Scene.m_trustBinaries) 310 m_part.ParentGroup.Scene.m_trustBinaries)
282 { 311 {
283 lock (m_items) 312 m_items.LockItemsForWrite(true);
284 { 313 m_items[item.ItemID].PermsMask = 0;
285 m_items[item.ItemID].PermsMask = 0; 314 m_items[item.ItemID].PermsGranter = UUID.Zero;
286 m_items[item.ItemID].PermsGranter = UUID.Zero; 315 m_items.LockItemsForWrite(false);
287 }
288
289 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 316 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
290 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 317 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
318 StoreScriptErrors(item.ItemID, null);
291 m_part.ParentGroup.AddActiveScriptCount(1); 319 m_part.ParentGroup.AddActiveScriptCount(1);
292 m_part.ScheduleFullUpdate(); 320 m_part.ScheduleFullUpdate();
293 return; 321 return;
@@ -296,6 +324,8 @@ namespace OpenSim.Region.Framework.Scenes
296 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); 324 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
297 if (null == asset) 325 if (null == asset)
298 { 326 {
327 string msg = String.Format("asset ID {0} could not be found", item.AssetID);
328 StoreScriptError(item.ItemID, msg);
299 m_log.ErrorFormat( 329 m_log.ErrorFormat(
300 "[PRIM INVENTORY]: " + 330 "[PRIM INVENTORY]: " +
301 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", 331 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
@@ -307,15 +337,17 @@ namespace OpenSim.Region.Framework.Scenes
307 if (m_part.ParentGroup.m_savedScriptState != null) 337 if (m_part.ParentGroup.m_savedScriptState != null)
308 RestoreSavedScriptState(item.OldItemID, item.ItemID); 338 RestoreSavedScriptState(item.OldItemID, item.ItemID);
309 339
310 lock (m_items) 340 m_items.LockItemsForWrite(true);
311 { 341
312 m_items[item.ItemID].PermsMask = 0; 342 m_items[item.ItemID].PermsMask = 0;
313 m_items[item.ItemID].PermsGranter = UUID.Zero; 343 m_items[item.ItemID].PermsGranter = UUID.Zero;
314 } 344
345 m_items.LockItemsForWrite(false);
315 346
316 string script = Utils.BytesToString(asset.Data); 347 string script = Utils.BytesToString(asset.Data);
317 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 348 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
318 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 349 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
350 StoreScriptErrors(item.ItemID, null);
319 m_part.ParentGroup.AddActiveScriptCount(1); 351 m_part.ParentGroup.AddActiveScriptCount(1);
320 m_part.ScheduleFullUpdate(); 352 m_part.ScheduleFullUpdate();
321 } 353 }
@@ -379,21 +411,145 @@ namespace OpenSim.Region.Framework.Scenes
379 411
380 /// <summary> 412 /// <summary>
381 /// Start a script which is in this prim's inventory. 413 /// Start a script which is in this prim's inventory.
414 /// Some processing may occur in the background, but this routine returns asap.
382 /// </summary> 415 /// </summary>
383 /// <param name="itemId"> 416 /// <param name="itemId">
384 /// A <see cref="UUID"/> 417 /// A <see cref="UUID"/>
385 /// </param> 418 /// </param>
386 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 419 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
387 { 420 {
388 TaskInventoryItem item = GetInventoryItem(itemId); 421 lock (m_scriptErrors)
389 if (item != null) 422 {
390 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 423 // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion
424 m_scriptErrors.Remove(itemId);
425 }
426 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
427 }
428
429 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
430 {
431 m_items.LockItemsForRead(true);
432 if (m_items.ContainsKey(itemId))
433 {
434 if (m_items.ContainsKey(itemId))
435 {
436 m_items.LockItemsForRead(false);
437 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
438 }
439 else
440 {
441 m_items.LockItemsForRead(false);
442 string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID,
443 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
444 StoreScriptError(itemId, msg);
445 m_log.ErrorFormat(
446 "[PRIM INVENTORY]: " +
447 "Couldn't start script with ID {0} since it {1}", itemId, msg);
448 }
449 }
391 else 450 else
451 {
452 m_items.LockItemsForRead(false);
453 string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID);
454 StoreScriptError(itemId, msg);
392 m_log.ErrorFormat( 455 m_log.ErrorFormat(
393 "[PRIM INVENTORY]: " + 456 "[PRIM INVENTORY]: " +
394 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 457 "Couldn't start script with ID {0} since it {1}", itemId, msg);
395 itemId, m_part.Name, m_part.UUID, 458 }
396 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 459
460 }
461
462 /// <summary>
463 /// Start a script which is in this prim's inventory and return any compilation error messages.
464 /// </summary>
465 /// <param name="itemId">
466 /// A <see cref="UUID"/>
467 /// </param>
468 public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
469 {
470 ArrayList errors;
471
472 // Indicate to CreateScriptInstanceInternal() we want it to
473 // post any compilation/loading error messages
474 lock (m_scriptErrors)
475 {
476 m_scriptErrors[itemId] = null;
477 }
478
479 // Perform compilation/loading
480 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
481
482 // Wait for and retrieve any errors
483 lock (m_scriptErrors)
484 {
485 while ((errors = m_scriptErrors[itemId]) == null)
486 {
487 if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
488 {
489 m_log.ErrorFormat(
490 "[PRIM INVENTORY]: " +
491 "timedout waiting for script {0} errors", itemId);
492 errors = m_scriptErrors[itemId];
493 if (errors == null)
494 {
495 errors = new ArrayList(1);
496 errors.Add("timedout waiting for errors");
497 }
498 break;
499 }
500 }
501 m_scriptErrors.Remove(itemId);
502 }
503 return errors;
504 }
505
506 // Signal to CreateScriptInstanceEr() that compilation/loading is complete
507 private void StoreScriptErrors(UUID itemId, ArrayList errors)
508 {
509 lock (m_scriptErrors)
510 {
511 // If compilation/loading initiated via CreateScriptInstance(),
512 // it does not want the errors, so just get out
513 if (!m_scriptErrors.ContainsKey(itemId))
514 {
515 return;
516 }
517
518 // Initiated via CreateScriptInstanceEr(), if we know what the
519 // errors are, save them and wake CreateScriptInstanceEr().
520 if (errors != null)
521 {
522 m_scriptErrors[itemId] = errors;
523 System.Threading.Monitor.PulseAll(m_scriptErrors);
524 return;
525 }
526 }
527
528 // Initiated via CreateScriptInstanceEr() but we don't know what
529 // the errors are yet, so retrieve them from the script engine.
530 // This may involve some waiting internal to GetScriptErrors().
531 errors = GetScriptErrors(itemId);
532
533 // Get a default non-null value to indicate success.
534 if (errors == null)
535 {
536 errors = new ArrayList();
537 }
538
539 // Post to CreateScriptInstanceEr() and wake it up
540 lock (m_scriptErrors)
541 {
542 m_scriptErrors[itemId] = errors;
543 System.Threading.Monitor.PulseAll(m_scriptErrors);
544 }
545 }
546
547 // Like StoreScriptErrors(), but just posts a single string message
548 private void StoreScriptError(UUID itemId, string message)
549 {
550 ArrayList errors = new ArrayList(1);
551 errors.Add(message);
552 StoreScriptErrors(itemId, errors);
397 } 553 }
398 554
399 /// <summary> 555 /// <summary>
@@ -406,15 +562,7 @@ namespace OpenSim.Region.Framework.Scenes
406 /// </param> 562 /// </param>
407 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 563 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
408 { 564 {
409 bool scriptPresent = false; 565 if (m_items.ContainsKey(itemId))
410
411 lock (m_items)
412 {
413 if (m_items.ContainsKey(itemId))
414 scriptPresent = true;
415 }
416
417 if (scriptPresent)
418 { 566 {
419 if (!sceneObjectBeingDeleted) 567 if (!sceneObjectBeingDeleted)
420 m_part.RemoveScriptEvents(itemId); 568 m_part.RemoveScriptEvents(itemId);
@@ -439,14 +587,16 @@ namespace OpenSim.Region.Framework.Scenes
439 /// <returns></returns> 587 /// <returns></returns>
440 private bool InventoryContainsName(string name) 588 private bool InventoryContainsName(string name)
441 { 589 {
442 lock (m_items) 590 m_items.LockItemsForRead(true);
591 foreach (TaskInventoryItem item in m_items.Values)
443 { 592 {
444 foreach (TaskInventoryItem item in m_items.Values) 593 if (item.Name == name)
445 { 594 {
446 if (item.Name == name) 595 m_items.LockItemsForRead(false);
447 return true; 596 return true;
448 } 597 }
449 } 598 }
599 m_items.LockItemsForRead(false);
450 return false; 600 return false;
451 } 601 }
452 602
@@ -488,8 +638,9 @@ namespace OpenSim.Region.Framework.Scenes
488 /// <param name="item"></param> 638 /// <param name="item"></param>
489 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 639 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
490 { 640 {
491 List<TaskInventoryItem> il = GetInventoryItems(); 641 m_items.LockItemsForRead(true);
492 642 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
643 m_items.LockItemsForRead(false);
493 foreach (TaskInventoryItem i in il) 644 foreach (TaskInventoryItem i in il)
494 { 645 {
495 if (i.Name == item.Name) 646 if (i.Name == item.Name)
@@ -527,14 +678,14 @@ namespace OpenSim.Region.Framework.Scenes
527 item.Name = name; 678 item.Name = name;
528 item.GroupID = m_part.GroupID; 679 item.GroupID = m_part.GroupID;
529 680
530 lock (m_items) 681 m_items.LockItemsForWrite(true);
531 m_items.Add(item.ItemID, item); 682 m_items.Add(item.ItemID, item);
532 683 m_items.LockItemsForWrite(false);
533 if (allowedDrop) 684 if (allowedDrop)
534 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 685 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
535 else 686 else
536 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 687 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
537 688
538 m_inventorySerial++; 689 m_inventorySerial++;
539 //m_inventorySerial += 2; 690 //m_inventorySerial += 2;
540 HasInventoryChanged = true; 691 HasInventoryChanged = true;
@@ -550,15 +701,15 @@ namespace OpenSim.Region.Framework.Scenes
550 /// <param name="items"></param> 701 /// <param name="items"></param>
551 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 702 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
552 { 703 {
553 lock (m_items) 704 m_items.LockItemsForWrite(true);
705 foreach (TaskInventoryItem item in items)
554 { 706 {
555 foreach (TaskInventoryItem item in items) 707 m_items.Add(item.ItemID, item);
556 { 708// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
557 m_items.Add(item.ItemID, item);
558// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
559 }
560 m_inventorySerial++;
561 } 709 }
710 m_items.LockItemsForWrite(false);
711
712 m_inventorySerial++;
562 } 713 }
563 714
564 /// <summary> 715 /// <summary>
@@ -569,10 +720,9 @@ namespace OpenSim.Region.Framework.Scenes
569 public TaskInventoryItem GetInventoryItem(UUID itemId) 720 public TaskInventoryItem GetInventoryItem(UUID itemId)
570 { 721 {
571 TaskInventoryItem item; 722 TaskInventoryItem item;
572 723 m_items.LockItemsForRead(true);
573 lock (m_items) 724 m_items.TryGetValue(itemId, out item);
574 m_items.TryGetValue(itemId, out item); 725 m_items.LockItemsForRead(false);
575
576 return item; 726 return item;
577 } 727 }
578 728
@@ -588,15 +738,16 @@ namespace OpenSim.Region.Framework.Scenes
588 { 738 {
589 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); 739 IList<TaskInventoryItem> items = new List<TaskInventoryItem>();
590 740
591 lock (m_items) 741 m_items.LockItemsForRead(true);
742
743 foreach (TaskInventoryItem item in m_items.Values)
592 { 744 {
593 foreach (TaskInventoryItem item in m_items.Values) 745 if (item.Name == name)
594 { 746 items.Add(item);
595 if (item.Name == name)
596 items.Add(item);
597 }
598 } 747 }
599 748
749 m_items.LockItemsForRead(false);
750
600 return items; 751 return items;
601 } 752 }
602 753
@@ -679,9 +830,9 @@ namespace OpenSim.Region.Framework.Scenes
679 830
680 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) 831 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged)
681 { 832 {
682 TaskInventoryItem it = GetInventoryItem(item.ItemID); 833 m_items.LockItemsForWrite(true);
683 if (it != null)
684 834
835 if (m_items.ContainsKey(item.ItemID))
685 { 836 {
686 item.ParentID = m_part.UUID; 837 item.ParentID = m_part.UUID;
687 item.ParentPartID = m_part.UUID; 838 item.ParentPartID = m_part.UUID;
@@ -693,14 +844,10 @@ namespace OpenSim.Region.Framework.Scenes
693 item.GroupID = m_part.GroupID; 844 item.GroupID = m_part.GroupID;
694 845
695 if (item.AssetID == UUID.Zero) 846 if (item.AssetID == UUID.Zero)
696 item.AssetID = it.AssetID; 847 item.AssetID = m_items[item.ItemID].AssetID;
697
698 lock (m_items)
699 {
700 m_items[item.ItemID] = item;
701 m_inventorySerial++;
702 }
703 848
849 m_items[item.ItemID] = item;
850 m_inventorySerial++;
704 if (fireScriptEvents) 851 if (fireScriptEvents)
705 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 852 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
706 if (considerChanged) 853 if (considerChanged)
@@ -708,6 +855,7 @@ namespace OpenSim.Region.Framework.Scenes
708 HasInventoryChanged = true; 855 HasInventoryChanged = true;
709 m_part.ParentGroup.HasGroupChanged = true; 856 m_part.ParentGroup.HasGroupChanged = true;
710 } 857 }
858 m_items.LockItemsForWrite(false);
711 return true; 859 return true;
712 } 860 }
713 else 861 else
@@ -718,8 +866,9 @@ namespace OpenSim.Region.Framework.Scenes
718 item.ItemID, m_part.Name, m_part.UUID, 866 item.ItemID, m_part.Name, m_part.UUID,
719 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 867 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
720 } 868 }
721 return false; 869 m_items.LockItemsForWrite(false);
722 870
871 return false;
723 } 872 }
724 873
725 /// <summary> 874 /// <summary>
@@ -730,37 +879,53 @@ namespace OpenSim.Region.Framework.Scenes
730 /// in this prim's inventory.</returns> 879 /// in this prim's inventory.</returns>
731 public int RemoveInventoryItem(UUID itemID) 880 public int RemoveInventoryItem(UUID itemID)
732 { 881 {
733 TaskInventoryItem item = GetInventoryItem(itemID); 882 m_items.LockItemsForRead(true);
734 if (item != null) 883
884 if (m_items.ContainsKey(itemID))
735 { 885 {
736 int type = m_items[itemID].InvType; 886 int type = m_items[itemID].InvType;
887 m_items.LockItemsForRead(false);
737 if (type == 10) // Script 888 if (type == 10) // Script
738 { 889 {
739 m_part.RemoveScriptEvents(itemID);
740 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 890 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
741 } 891 }
892 m_items.LockItemsForWrite(true);
742 m_items.Remove(itemID); 893 m_items.Remove(itemID);
894 m_items.LockItemsForWrite(false);
743 m_inventorySerial++; 895 m_inventorySerial++;
744 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 896 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
745 897
746 HasInventoryChanged = true; 898 HasInventoryChanged = true;
747 m_part.ParentGroup.HasGroupChanged = true; 899 m_part.ParentGroup.HasGroupChanged = true;
748 900
749 if (!ContainsScripts()) 901 int scriptcount = 0;
902 m_items.LockItemsForRead(true);
903 foreach (TaskInventoryItem item in m_items.Values)
904 {
905 if (item.Type == 10)
906 {
907 scriptcount++;
908 }
909 }
910 m_items.LockItemsForRead(false);
911
912
913 if (scriptcount <= 0)
914 {
750 m_part.RemFlag(PrimFlags.Scripted); 915 m_part.RemFlag(PrimFlags.Scripted);
916 }
751 917
752 m_part.ScheduleFullUpdate(); 918 m_part.ScheduleFullUpdate();
753 919
754 return type; 920 return type;
755
756 } 921 }
757 else 922 else
758 { 923 {
924 m_items.LockItemsForRead(false);
759 m_log.ErrorFormat( 925 m_log.ErrorFormat(
760 "[PRIM INVENTORY]: " + 926 "[PRIM INVENTORY]: " +
761 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 927 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
762 itemID, m_part.Name, m_part.UUID, 928 itemID, m_part.Name, m_part.UUID);
763 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
764 } 929 }
765 930
766 return -1; 931 return -1;
@@ -789,73 +954,83 @@ namespace OpenSim.Region.Framework.Scenes
789 954
790 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 955 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
791 956
792 lock (m_items) 957 Items.LockItemsForRead(true);
958
959 if (m_inventorySerial == 0) // No inventory
793 { 960 {
794 if (m_inventorySerial == 0) // No inventory 961 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
795 { 962 Items.LockItemsForRead(false);
796 client.SendTaskInventory(m_part.UUID, 0, new byte[0]); 963 return;
797 return; 964 }
798 }
799 965
800 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, 966 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
801 Util.StringToBytes256(m_inventoryFileName)); 967 Util.StringToBytes256(m_inventoryFileName));
802 968
803 if (!changed) 969 if (!changed)
970 {
971 if (m_inventoryFileData.Length > 2)
804 { 972 {
805 if (m_inventoryFileData.Length > 2) 973 xferManager.AddNewFile(m_inventoryFileName,
806 { 974 m_inventoryFileData);
807 xferManager.AddNewFile(m_inventoryFileName, 975 Items.LockItemsForRead(false);
808 m_inventoryFileData); 976 return;
809 return;
810 }
811 } 977 }
978 }
812 979
813 foreach (TaskInventoryItem item in m_items.Values) 980 bool includeAssets = false;
814 { 981 if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId))
815 UUID ownerID = item.OwnerID; 982 includeAssets = true;
816 uint everyoneMask = 0; 983
817 uint baseMask = item.BasePermissions; 984 foreach (TaskInventoryItem item in m_items.Values)
818 uint ownerMask = item.CurrentPermissions; 985 {
819 uint groupMask = item.GroupPermissions; 986 UUID ownerID = item.OwnerID;
987 uint everyoneMask = 0;
988 uint baseMask = item.BasePermissions;
989 uint ownerMask = item.CurrentPermissions;
990 uint groupMask = item.GroupPermissions;
820 991
821 invString.AddItemStart(); 992 invString.AddItemStart();
822 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 993 invString.AddNameValueLine("item_id", item.ItemID.ToString());
823 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 994 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
824 995
825 invString.AddPermissionsStart(); 996 invString.AddPermissionsStart();
826 997
827 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 998 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
828 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 999 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
829 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); 1000 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
830 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); 1001 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
831 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); 1002 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
832 1003
833 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 1004 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
834 invString.AddNameValueLine("owner_id", ownerID.ToString()); 1005 invString.AddNameValueLine("owner_id", ownerID.ToString());
835 1006
836 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 1007 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
837 1008
838 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 1009 invString.AddNameValueLine("group_id", item.GroupID.ToString());
839 invString.AddSectionEnd(); 1010 invString.AddSectionEnd();
840 1011
1012 if (includeAssets)
841 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 1013 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
842 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); 1014 else
843 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); 1015 invString.AddNameValueLine("asset_id", UUID.Zero.ToString());
844 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); 1016 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
1017 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
1018 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
845 1019
846 invString.AddSaleStart(); 1020 invString.AddSaleStart();
847 invString.AddNameValueLine("sale_type", "not"); 1021 invString.AddNameValueLine("sale_type", "not");
848 invString.AddNameValueLine("sale_price", "0"); 1022 invString.AddNameValueLine("sale_price", "0");
849 invString.AddSectionEnd(); 1023 invString.AddSectionEnd();
850 1024
851 invString.AddNameValueLine("name", item.Name + "|"); 1025 invString.AddNameValueLine("name", item.Name + "|");
852 invString.AddNameValueLine("desc", item.Description + "|"); 1026 invString.AddNameValueLine("desc", item.Description + "|");
853 1027
854 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 1028 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
855 invString.AddSectionEnd(); 1029 invString.AddSectionEnd();
856 }
857 } 1030 }
858 1031
1032 Items.LockItemsForRead(false);
1033
859 m_inventoryFileData = Utils.StringToBytes(invString.BuildString); 1034 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
860 1035
861 if (m_inventoryFileData.Length > 2) 1036 if (m_inventoryFileData.Length > 2)
@@ -872,10 +1047,11 @@ namespace OpenSim.Region.Framework.Scenes
872 { 1047 {
873 if (HasInventoryChanged) 1048 if (HasInventoryChanged)
874 { 1049 {
875 HasInventoryChanged = false; 1050 Items.LockItemsForRead(true);
876 List<TaskInventoryItem> items = GetInventoryItems(); 1051 datastore.StorePrimInventory(m_part.UUID, Items.Values);
877 datastore.StorePrimInventory(m_part.UUID, items); 1052 Items.LockItemsForRead(false);
878 1053
1054 HasInventoryChanged = false;
879 } 1055 }
880 } 1056 }
881 1057
@@ -942,89 +1118,75 @@ namespace OpenSim.Region.Framework.Scenes
942 { 1118 {
943 uint mask=0x7fffffff; 1119 uint mask=0x7fffffff;
944 1120
945 lock (m_items) 1121 foreach (TaskInventoryItem item in m_items.Values)
946 { 1122 {
947 foreach (TaskInventoryItem item in m_items.Values) 1123 if (item.InvType != (int)InventoryType.Object)
948 { 1124 {
949 if (item.InvType != (int)InventoryType.Object) 1125 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
950 { 1126 mask &= ~((uint)PermissionMask.Copy >> 13);
951 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1127 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
952 mask &= ~((uint)PermissionMask.Copy >> 13); 1128 mask &= ~((uint)PermissionMask.Transfer >> 13);
953 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1129 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
954 mask &= ~((uint)PermissionMask.Transfer >> 13); 1130 mask &= ~((uint)PermissionMask.Modify >> 13);
955 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
956 mask &= ~((uint)PermissionMask.Modify >> 13);
957 }
958 else
959 {
960 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
961 mask &= ~((uint)PermissionMask.Copy >> 13);
962 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
963 mask &= ~((uint)PermissionMask.Transfer >> 13);
964 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
965 mask &= ~((uint)PermissionMask.Modify >> 13);
966 }
967
968 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
969 mask &= ~(uint)PermissionMask.Copy;
970 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
971 mask &= ~(uint)PermissionMask.Transfer;
972 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
973 mask &= ~(uint)PermissionMask.Modify;
974 } 1131 }
1132 else
1133 {
1134 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1135 mask &= ~((uint)PermissionMask.Copy >> 13);
1136 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1137 mask &= ~((uint)PermissionMask.Transfer >> 13);
1138 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1139 mask &= ~((uint)PermissionMask.Modify >> 13);
1140 }
1141
1142 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1143 mask &= ~(uint)PermissionMask.Copy;
1144 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1145 mask &= ~(uint)PermissionMask.Transfer;
1146 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1147 mask &= ~(uint)PermissionMask.Modify;
975 } 1148 }
976
977 return mask; 1149 return mask;
978 } 1150 }
979 1151
980 public void ApplyNextOwnerPermissions() 1152 public void ApplyNextOwnerPermissions()
981 { 1153 {
982 lock (m_items) 1154 foreach (TaskInventoryItem item in m_items.Values)
983 { 1155 {
984 foreach (TaskInventoryItem item in m_items.Values) 1156 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
985 { 1157 {
986 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 1158 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
987 { 1159 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
988 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1160 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
989 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 1161 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
990 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1162 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
991 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 1163 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
992 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
993 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
994 }
995 item.CurrentPermissions &= item.NextPermissions;
996 item.BasePermissions &= item.NextPermissions;
997 item.EveryonePermissions &= item.NextPermissions;
998 item.OwnerChanged = true;
999 } 1164 }
1165 item.OwnerChanged = true;
1166 item.CurrentPermissions &= item.NextPermissions;
1167 item.BasePermissions &= item.NextPermissions;
1168 item.EveryonePermissions &= item.NextPermissions;
1000 } 1169 }
1001 } 1170 }
1002 1171
1003 public void ApplyGodPermissions(uint perms) 1172 public void ApplyGodPermissions(uint perms)
1004 { 1173 {
1005 lock (m_items) 1174 foreach (TaskInventoryItem item in m_items.Values)
1006 { 1175 {
1007 foreach (TaskInventoryItem item in m_items.Values) 1176 item.CurrentPermissions = perms;
1008 { 1177 item.BasePermissions = perms;
1009 item.CurrentPermissions = perms;
1010 item.BasePermissions = perms;
1011 }
1012 } 1178 }
1013 } 1179 }
1014 1180
1015 public bool ContainsScripts() 1181 public bool ContainsScripts()
1016 { 1182 {
1017 lock (m_items) 1183 foreach (TaskInventoryItem item in m_items.Values)
1018 { 1184 {
1019 foreach (TaskInventoryItem item in m_items.Values) 1185 if (item.InvType == (int)InventoryType.LSL)
1020 { 1186 {
1021 if (item.InvType == (int)InventoryType.LSL) 1187 return true;
1022 {
1023 return true;
1024 }
1025 } 1188 }
1026 } 1189 }
1027
1028 return false; 1190 return false;
1029 } 1191 }
1030 1192
@@ -1032,11 +1194,8 @@ namespace OpenSim.Region.Framework.Scenes
1032 { 1194 {
1033 List<UUID> ret = new List<UUID>(); 1195 List<UUID> ret = new List<UUID>();
1034 1196
1035 lock (m_items) 1197 foreach (TaskInventoryItem item in m_items.Values)
1036 { 1198 ret.Add(item.ItemID);
1037 foreach (TaskInventoryItem item in m_items.Values)
1038 ret.Add(item.ItemID);
1039 }
1040 1199
1041 return ret; 1200 return ret;
1042 } 1201 }
@@ -1067,31 +1226,46 @@ namespace OpenSim.Region.Framework.Scenes
1067 1226
1068 public Dictionary<UUID, string> GetScriptStates() 1227 public Dictionary<UUID, string> GetScriptStates()
1069 { 1228 {
1229 return GetScriptStates(false);
1230 }
1231
1232 public Dictionary<UUID, string> GetScriptStates(bool oldIDs)
1233 {
1070 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); 1234 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
1071 1235
1072 Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); 1236 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
1073 if (engines == null) // No engine at all 1237 if (engines == null) // No engine at all
1074 return ret; 1238 return ret;
1075 1239
1076 List<TaskInventoryItem> scripts = GetInventoryScripts(); 1240 Items.LockItemsForRead(true);
1077 1241 foreach (TaskInventoryItem item in m_items.Values)
1078 foreach (TaskInventoryItem item in scripts)
1079 { 1242 {
1080 foreach (IScriptModule e in engines) 1243 if (item.InvType == (int)InventoryType.LSL)
1081 { 1244 {
1082 if (e != null) 1245 foreach (IScriptModule e in engines)
1083 { 1246 {
1084 string n = e.GetXMLState(item.ItemID); 1247 if (e != null)
1085 if (n != String.Empty)
1086 { 1248 {
1087 if (!ret.ContainsKey(item.ItemID)) 1249 string n = e.GetXMLState(item.ItemID);
1088 ret[item.ItemID] = n; 1250 if (n != String.Empty)
1089 break; 1251 {
1252 if (oldIDs)
1253 {
1254 if (!ret.ContainsKey(item.OldItemID))
1255 ret[item.OldItemID] = n;
1256 }
1257 else
1258 {
1259 if (!ret.ContainsKey(item.ItemID))
1260 ret[item.ItemID] = n;
1261 }
1262 break;
1263 }
1090 } 1264 }
1091 } 1265 }
1092 } 1266 }
1093 } 1267 }
1094 1268 Items.LockItemsForRead(false);
1095 return ret; 1269 return ret;
1096 } 1270 }
1097 1271
@@ -1101,21 +1275,27 @@ namespace OpenSim.Region.Framework.Scenes
1101 if (engines == null) 1275 if (engines == null)
1102 return; 1276 return;
1103 1277
1104 List<TaskInventoryItem> scripts = GetInventoryScripts();
1105 1278
1106 foreach (TaskInventoryItem item in scripts) 1279 Items.LockItemsForRead(true);
1280
1281 foreach (TaskInventoryItem item in m_items.Values)
1107 { 1282 {
1108 foreach (IScriptModule engine in engines) 1283 if (item.InvType == (int)InventoryType.LSL)
1109 { 1284 {
1110 if (engine != null) 1285 foreach (IScriptModule engine in engines)
1111 { 1286 {
1112 if (item.OwnerChanged) 1287 if (engine != null)
1113 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); 1288 {
1114 item.OwnerChanged = false; 1289 if (item.OwnerChanged)
1115 engine.ResumeScript(item.ItemID); 1290 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
1291 item.OwnerChanged = false;
1292 engine.ResumeScript(item.ItemID);
1293 }
1116 } 1294 }
1117 } 1295 }
1118 } 1296 }
1297
1298 Items.LockItemsForRead(false);
1119 } 1299 }
1120 } 1300 }
1121} 1301}