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