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.cs750
1 files changed, 482 insertions, 268 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 004e20c..2ee8c07 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
@@ -120,39 +126,45 @@ namespace OpenSim.Region.Framework.Scenes
120 /// <param name="linkNum">Link number for the part</param> 126 /// <param name="linkNum">Link number for the part</param>
121 public void ResetInventoryIDs() 127 public void ResetInventoryIDs()
122 { 128 {
123 if (null == m_part || null == m_part.ParentGroup) 129 m_items.LockItemsForWrite(true);
124 return; 130
125 131 if (Items.Count == 0)
126 lock (m_items)
127 { 132 {
128 if (0 == m_items.Count) 133 m_items.LockItemsForWrite(false);
129 return; 134 return;
135 }
130 136
131 IList<TaskInventoryItem> items = GetInventoryItems(); 137 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
132 m_items.Clear(); 138 Items.Clear();
133 139
134 foreach (TaskInventoryItem item in items) 140 foreach (TaskInventoryItem item in items)
135 { 141 {
136 item.ResetIDs(m_part.UUID); 142 item.ResetIDs(m_part.UUID);
137 m_items.Add(item.ItemID, item); 143 Items.Add(item.ItemID, item);
138 }
139 } 144 }
145 m_items.LockItemsForWrite(false);
140 } 146 }
141 147
142 public void ResetObjectID() 148 public void ResetObjectID()
143 { 149 {
144 lock (Items) 150 m_items.LockItemsForWrite(true);
151
152 if (Items.Count == 0)
145 { 153 {
146 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 154 m_items.LockItemsForWrite(false);
147 Items.Clear(); 155 return;
148
149 foreach (TaskInventoryItem item in items)
150 {
151 item.ParentPartID = m_part.UUID;
152 item.ParentID = m_part.UUID;
153 Items.Add(item.ItemID, item);
154 }
155 } 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 m_items.LockItemsForWrite(false);
156 } 168 }
157 169
158 /// <summary> 170 /// <summary>
@@ -161,12 +173,11 @@ namespace OpenSim.Region.Framework.Scenes
161 /// <param name="ownerId"></param> 173 /// <param name="ownerId"></param>
162 public void ChangeInventoryOwner(UUID ownerId) 174 public void ChangeInventoryOwner(UUID ownerId)
163 { 175 {
164 lock (Items) 176 m_items.LockItemsForWrite(true);
177 if (0 == Items.Count)
165 { 178 {
166 if (0 == Items.Count) 179 m_items.LockItemsForWrite(false);
167 { 180 return;
168 return;
169 }
170 } 181 }
171 182
172 HasInventoryChanged = true; 183 HasInventoryChanged = true;
@@ -180,6 +191,7 @@ namespace OpenSim.Region.Framework.Scenes
180 item.OwnerID = ownerId; 191 item.OwnerID = ownerId;
181 } 192 }
182 } 193 }
194 m_items.LockItemsForWrite(false);
183 } 195 }
184 196
185 /// <summary> 197 /// <summary>
@@ -188,12 +200,11 @@ namespace OpenSim.Region.Framework.Scenes
188 /// <param name="groupID"></param> 200 /// <param name="groupID"></param>
189 public void ChangeInventoryGroup(UUID groupID) 201 public void ChangeInventoryGroup(UUID groupID)
190 { 202 {
191 lock (Items) 203 m_items.LockItemsForWrite(true);
204 if (0 == Items.Count)
192 { 205 {
193 if (0 == Items.Count) 206 m_items.LockItemsForWrite(false);
194 { 207 return;
195 return;
196 }
197 } 208 }
198 209
199 // Don't let this set the HasGroupChanged flag for attachments 210 // Don't let this set the HasGroupChanged flag for attachments
@@ -205,12 +216,45 @@ namespace OpenSim.Region.Framework.Scenes
205 m_part.ParentGroup.HasGroupChanged = true; 216 m_part.ParentGroup.HasGroupChanged = true;
206 } 217 }
207 218
208 List<TaskInventoryItem> items = GetInventoryItems(); 219 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
209 foreach (TaskInventoryItem item in items) 220 foreach (TaskInventoryItem item in items)
210 { 221 {
211 if (groupID != item.GroupID) 222 if (groupID != item.GroupID)
223 {
212 item.GroupID = groupID; 224 item.GroupID = groupID;
225 }
213 } 226 }
227 m_items.LockItemsForWrite(false);
228 }
229
230 private void QueryScriptStates()
231 {
232 if (m_part == null || m_part.ParentGroup == null)
233 return;
234
235 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
236 if (engines == null) // No engine at all
237 return;
238
239 Items.LockItemsForRead(true);
240 foreach (TaskInventoryItem item in Items.Values)
241 {
242 if (item.InvType == (int)InventoryType.LSL)
243 {
244 foreach (IScriptModule e in engines)
245 {
246 bool running;
247
248 if (e.HasScript(item.ItemID, out running))
249 {
250 item.ScriptRunning = running;
251 break;
252 }
253 }
254 }
255 }
256
257 Items.LockItemsForRead(false);
214 } 258 }
215 259
216 /// <summary> 260 /// <summary>
@@ -218,9 +262,14 @@ namespace OpenSim.Region.Framework.Scenes
218 /// </summary> 262 /// </summary>
219 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 263 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
220 { 264 {
221 List<TaskInventoryItem> scripts = GetInventoryScripts(); 265 Items.LockItemsForRead(true);
222 foreach (TaskInventoryItem item in scripts) 266 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
223 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 267 Items.LockItemsForRead(false);
268 foreach (TaskInventoryItem item in items)
269 {
270 if ((int)InventoryType.LSL == item.InvType)
271 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
272 }
224 } 273 }
225 274
226 public ArrayList GetScriptErrors(UUID itemID) 275 public ArrayList GetScriptErrors(UUID itemID)
@@ -253,9 +302,18 @@ namespace OpenSim.Region.Framework.Scenes
253 /// </param> 302 /// </param>
254 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 303 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
255 { 304 {
256 List<TaskInventoryItem> scripts = GetInventoryScripts(); 305 Items.LockItemsForRead(true);
257 foreach (TaskInventoryItem item in scripts) 306 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
258 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); 307 Items.LockItemsForRead(false);
308
309 foreach (TaskInventoryItem item in items)
310 {
311 if ((int)InventoryType.LSL == item.InvType)
312 {
313 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
314 m_part.RemoveScriptEvents(item.ItemID);
315 }
316 }
259 } 317 }
260 318
261 /// <summary> 319 /// <summary>
@@ -271,7 +329,10 @@ namespace OpenSim.Region.Framework.Scenes
271 // item.Name, item.ItemID, Name, UUID); 329 // item.Name, item.ItemID, Name, UUID);
272 330
273 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) 331 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID))
332 {
333 StoreScriptError(item.ItemID, "no permission");
274 return; 334 return;
335 }
275 336
276 m_part.AddFlag(PrimFlags.Scripted); 337 m_part.AddFlag(PrimFlags.Scripted);
277 338
@@ -280,14 +341,13 @@ namespace OpenSim.Region.Framework.Scenes
280 if (stateSource == 2 && // Prim crossing 341 if (stateSource == 2 && // Prim crossing
281 m_part.ParentGroup.Scene.m_trustBinaries) 342 m_part.ParentGroup.Scene.m_trustBinaries)
282 { 343 {
283 lock (m_items) 344 m_items.LockItemsForWrite(true);
284 { 345 m_items[item.ItemID].PermsMask = 0;
285 m_items[item.ItemID].PermsMask = 0; 346 m_items[item.ItemID].PermsGranter = UUID.Zero;
286 m_items[item.ItemID].PermsGranter = UUID.Zero; 347 m_items.LockItemsForWrite(false);
287 }
288
289 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 348 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
290 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 349 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
350 StoreScriptErrors(item.ItemID, null);
291 m_part.ParentGroup.AddActiveScriptCount(1); 351 m_part.ParentGroup.AddActiveScriptCount(1);
292 m_part.ScheduleFullUpdate(); 352 m_part.ScheduleFullUpdate();
293 return; 353 return;
@@ -296,6 +356,8 @@ namespace OpenSim.Region.Framework.Scenes
296 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); 356 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
297 if (null == asset) 357 if (null == asset)
298 { 358 {
359 string msg = String.Format("asset ID {0} could not be found", item.AssetID);
360 StoreScriptError(item.ItemID, msg);
299 m_log.ErrorFormat( 361 m_log.ErrorFormat(
300 "[PRIM INVENTORY]: " + 362 "[PRIM INVENTORY]: " +
301 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", 363 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
@@ -307,15 +369,20 @@ namespace OpenSim.Region.Framework.Scenes
307 if (m_part.ParentGroup.m_savedScriptState != null) 369 if (m_part.ParentGroup.m_savedScriptState != null)
308 RestoreSavedScriptState(item.OldItemID, item.ItemID); 370 RestoreSavedScriptState(item.OldItemID, item.ItemID);
309 371
310 lock (m_items) 372 m_items.LockItemsForWrite(true);
311 { 373
312 m_items[item.ItemID].PermsMask = 0; 374 m_items[item.ItemID].PermsMask = 0;
313 m_items[item.ItemID].PermsGranter = UUID.Zero; 375 m_items[item.ItemID].PermsGranter = UUID.Zero;
314 } 376
377 m_items.LockItemsForWrite(false);
315 378
316 string script = Utils.BytesToString(asset.Data); 379 string script = Utils.BytesToString(asset.Data);
317 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 380 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
318 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 381 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
382 StoreScriptErrors(item.ItemID, null);
383 if (!item.ScriptRunning)
384 m_part.ParentGroup.Scene.EventManager.TriggerStopScript(
385 m_part.LocalId, item.ItemID);
319 m_part.ParentGroup.AddActiveScriptCount(1); 386 m_part.ParentGroup.AddActiveScriptCount(1);
320 m_part.ScheduleFullUpdate(); 387 m_part.ScheduleFullUpdate();
321 } 388 }
@@ -379,21 +446,145 @@ namespace OpenSim.Region.Framework.Scenes
379 446
380 /// <summary> 447 /// <summary>
381 /// Start a script which is in this prim's inventory. 448 /// Start a script which is in this prim's inventory.
449 /// Some processing may occur in the background, but this routine returns asap.
382 /// </summary> 450 /// </summary>
383 /// <param name="itemId"> 451 /// <param name="itemId">
384 /// A <see cref="UUID"/> 452 /// A <see cref="UUID"/>
385 /// </param> 453 /// </param>
386 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 454 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
387 { 455 {
388 TaskInventoryItem item = GetInventoryItem(itemId); 456 lock (m_scriptErrors)
389 if (item != null) 457 {
390 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 458 // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion
459 m_scriptErrors.Remove(itemId);
460 }
461 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
462 }
463
464 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
465 {
466 m_items.LockItemsForRead(true);
467 if (m_items.ContainsKey(itemId))
468 {
469 if (m_items.ContainsKey(itemId))
470 {
471 m_items.LockItemsForRead(false);
472 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
473 }
474 else
475 {
476 m_items.LockItemsForRead(false);
477 string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID,
478 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
479 StoreScriptError(itemId, msg);
480 m_log.ErrorFormat(
481 "[PRIM INVENTORY]: " +
482 "Couldn't start script with ID {0} since it {1}", itemId, msg);
483 }
484 }
391 else 485 else
486 {
487 m_items.LockItemsForRead(false);
488 string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID);
489 StoreScriptError(itemId, msg);
392 m_log.ErrorFormat( 490 m_log.ErrorFormat(
393 "[PRIM INVENTORY]: " + 491 "[PRIM INVENTORY]: " +
394 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 492 "Couldn't start script with ID {0} since it {1}", itemId, msg);
395 itemId, m_part.Name, m_part.UUID, 493 }
396 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 494
495 }
496
497 /// <summary>
498 /// Start a script which is in this prim's inventory and return any compilation error messages.
499 /// </summary>
500 /// <param name="itemId">
501 /// A <see cref="UUID"/>
502 /// </param>
503 public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
504 {
505 ArrayList errors;
506
507 // Indicate to CreateScriptInstanceInternal() we want it to
508 // post any compilation/loading error messages
509 lock (m_scriptErrors)
510 {
511 m_scriptErrors[itemId] = null;
512 }
513
514 // Perform compilation/loading
515 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
516
517 // Wait for and retrieve any errors
518 lock (m_scriptErrors)
519 {
520 while ((errors = m_scriptErrors[itemId]) == null)
521 {
522 if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
523 {
524 m_log.ErrorFormat(
525 "[PRIM INVENTORY]: " +
526 "timedout waiting for script {0} errors", itemId);
527 errors = m_scriptErrors[itemId];
528 if (errors == null)
529 {
530 errors = new ArrayList(1);
531 errors.Add("timedout waiting for errors");
532 }
533 break;
534 }
535 }
536 m_scriptErrors.Remove(itemId);
537 }
538 return errors;
539 }
540
541 // Signal to CreateScriptInstanceEr() that compilation/loading is complete
542 private void StoreScriptErrors(UUID itemId, ArrayList errors)
543 {
544 lock (m_scriptErrors)
545 {
546 // If compilation/loading initiated via CreateScriptInstance(),
547 // it does not want the errors, so just get out
548 if (!m_scriptErrors.ContainsKey(itemId))
549 {
550 return;
551 }
552
553 // Initiated via CreateScriptInstanceEr(), if we know what the
554 // errors are, save them and wake CreateScriptInstanceEr().
555 if (errors != null)
556 {
557 m_scriptErrors[itemId] = errors;
558 System.Threading.Monitor.PulseAll(m_scriptErrors);
559 return;
560 }
561 }
562
563 // Initiated via CreateScriptInstanceEr() but we don't know what
564 // the errors are yet, so retrieve them from the script engine.
565 // This may involve some waiting internal to GetScriptErrors().
566 errors = GetScriptErrors(itemId);
567
568 // Get a default non-null value to indicate success.
569 if (errors == null)
570 {
571 errors = new ArrayList();
572 }
573
574 // Post to CreateScriptInstanceEr() and wake it up
575 lock (m_scriptErrors)
576 {
577 m_scriptErrors[itemId] = errors;
578 System.Threading.Monitor.PulseAll(m_scriptErrors);
579 }
580 }
581
582 // Like StoreScriptErrors(), but just posts a single string message
583 private void StoreScriptError(UUID itemId, string message)
584 {
585 ArrayList errors = new ArrayList(1);
586 errors.Add(message);
587 StoreScriptErrors(itemId, errors);
397 } 588 }
398 589
399 /// <summary> 590 /// <summary>
@@ -406,15 +597,7 @@ namespace OpenSim.Region.Framework.Scenes
406 /// </param> 597 /// </param>
407 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 598 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
408 { 599 {
409 bool scriptPresent = false; 600 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 { 601 {
419 if (!sceneObjectBeingDeleted) 602 if (!sceneObjectBeingDeleted)
420 m_part.RemoveScriptEvents(itemId); 603 m_part.RemoveScriptEvents(itemId);
@@ -439,14 +622,16 @@ namespace OpenSim.Region.Framework.Scenes
439 /// <returns></returns> 622 /// <returns></returns>
440 private bool InventoryContainsName(string name) 623 private bool InventoryContainsName(string name)
441 { 624 {
442 lock (m_items) 625 m_items.LockItemsForRead(true);
626 foreach (TaskInventoryItem item in m_items.Values)
443 { 627 {
444 foreach (TaskInventoryItem item in m_items.Values) 628 if (item.Name == name)
445 { 629 {
446 if (item.Name == name) 630 m_items.LockItemsForRead(false);
447 return true; 631 return true;
448 } 632 }
449 } 633 }
634 m_items.LockItemsForRead(false);
450 return false; 635 return false;
451 } 636 }
452 637
@@ -488,8 +673,9 @@ namespace OpenSim.Region.Framework.Scenes
488 /// <param name="item"></param> 673 /// <param name="item"></param>
489 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 674 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
490 { 675 {
491 List<TaskInventoryItem> il = GetInventoryItems(); 676 m_items.LockItemsForRead(true);
492 677 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
678 m_items.LockItemsForRead(false);
493 foreach (TaskInventoryItem i in il) 679 foreach (TaskInventoryItem i in il)
494 { 680 {
495 if (i.Name == item.Name) 681 if (i.Name == item.Name)
@@ -527,14 +713,14 @@ namespace OpenSim.Region.Framework.Scenes
527 item.Name = name; 713 item.Name = name;
528 item.GroupID = m_part.GroupID; 714 item.GroupID = m_part.GroupID;
529 715
530 lock (m_items) 716 m_items.LockItemsForWrite(true);
531 m_items.Add(item.ItemID, item); 717 m_items.Add(item.ItemID, item);
532 718 m_items.LockItemsForWrite(false);
533 if (allowedDrop) 719 if (allowedDrop)
534 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 720 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
535 else 721 else
536 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 722 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
537 723
538 m_inventorySerial++; 724 m_inventorySerial++;
539 //m_inventorySerial += 2; 725 //m_inventorySerial += 2;
540 HasInventoryChanged = true; 726 HasInventoryChanged = true;
@@ -550,15 +736,15 @@ namespace OpenSim.Region.Framework.Scenes
550 /// <param name="items"></param> 736 /// <param name="items"></param>
551 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 737 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
552 { 738 {
553 lock (m_items) 739 m_items.LockItemsForWrite(true);
740 foreach (TaskInventoryItem item in items)
554 { 741 {
555 foreach (TaskInventoryItem item in items) 742 m_items.Add(item.ItemID, item);
556 { 743// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
557 m_items.Add(item.ItemID, item);
558// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
559 }
560 m_inventorySerial++;
561 } 744 }
745 m_items.LockItemsForWrite(false);
746
747 m_inventorySerial++;
562 } 748 }
563 749
564 /// <summary> 750 /// <summary>
@@ -569,10 +755,9 @@ namespace OpenSim.Region.Framework.Scenes
569 public TaskInventoryItem GetInventoryItem(UUID itemId) 755 public TaskInventoryItem GetInventoryItem(UUID itemId)
570 { 756 {
571 TaskInventoryItem item; 757 TaskInventoryItem item;
572 758 m_items.LockItemsForRead(true);
573 lock (m_items) 759 m_items.TryGetValue(itemId, out item);
574 m_items.TryGetValue(itemId, out item); 760 m_items.LockItemsForRead(false);
575
576 return item; 761 return item;
577 } 762 }
578 763
@@ -588,15 +773,16 @@ namespace OpenSim.Region.Framework.Scenes
588 { 773 {
589 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); 774 IList<TaskInventoryItem> items = new List<TaskInventoryItem>();
590 775
591 lock (m_items) 776 m_items.LockItemsForRead(true);
777
778 foreach (TaskInventoryItem item in m_items.Values)
592 { 779 {
593 foreach (TaskInventoryItem item in m_items.Values) 780 if (item.Name == name)
594 { 781 items.Add(item);
595 if (item.Name == name)
596 items.Add(item);
597 }
598 } 782 }
599 783
784 m_items.LockItemsForRead(false);
785
600 return items; 786 return items;
601 } 787 }
602 788
@@ -689,9 +875,9 @@ namespace OpenSim.Region.Framework.Scenes
689 875
690 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) 876 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged)
691 { 877 {
692 TaskInventoryItem it = GetInventoryItem(item.ItemID); 878 m_items.LockItemsForWrite(true);
693 if (it != null)
694 879
880 if (m_items.ContainsKey(item.ItemID))
695 { 881 {
696 item.ParentID = m_part.UUID; 882 item.ParentID = m_part.UUID;
697 item.ParentPartID = m_part.UUID; 883 item.ParentPartID = m_part.UUID;
@@ -702,14 +888,10 @@ namespace OpenSim.Region.Framework.Scenes
702 item.GroupID = m_part.GroupID; 888 item.GroupID = m_part.GroupID;
703 889
704 if (item.AssetID == UUID.Zero) 890 if (item.AssetID == UUID.Zero)
705 item.AssetID = it.AssetID; 891 item.AssetID = m_items[item.ItemID].AssetID;
706
707 lock (m_items)
708 {
709 m_items[item.ItemID] = item;
710 m_inventorySerial++;
711 }
712 892
893 m_items[item.ItemID] = item;
894 m_inventorySerial++;
713 if (fireScriptEvents) 895 if (fireScriptEvents)
714 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 896 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
715 if (considerChanged) 897 if (considerChanged)
@@ -717,6 +899,7 @@ namespace OpenSim.Region.Framework.Scenes
717 HasInventoryChanged = true; 899 HasInventoryChanged = true;
718 m_part.ParentGroup.HasGroupChanged = true; 900 m_part.ParentGroup.HasGroupChanged = true;
719 } 901 }
902 m_items.LockItemsForWrite(false);
720 return true; 903 return true;
721 } 904 }
722 else 905 else
@@ -727,8 +910,9 @@ namespace OpenSim.Region.Framework.Scenes
727 item.ItemID, m_part.Name, m_part.UUID, 910 item.ItemID, m_part.Name, m_part.UUID,
728 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 911 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
729 } 912 }
730 return false; 913 m_items.LockItemsForWrite(false);
731 914
915 return false;
732 } 916 }
733 917
734 /// <summary> 918 /// <summary>
@@ -739,107 +923,68 @@ namespace OpenSim.Region.Framework.Scenes
739 /// in this prim's inventory.</returns> 923 /// in this prim's inventory.</returns>
740 public int RemoveInventoryItem(UUID itemID) 924 public int RemoveInventoryItem(UUID itemID)
741 { 925 {
742 TaskInventoryItem item = GetInventoryItem(itemID); 926 m_items.LockItemsForRead(true);
743 if (item != null) 927
928 if (m_items.ContainsKey(itemID))
744 { 929 {
745 int type = m_items[itemID].InvType; 930 int type = m_items[itemID].InvType;
931 m_items.LockItemsForRead(false);
746 if (type == 10) // Script 932 if (type == 10) // Script
747 { 933 {
748 m_part.RemoveScriptEvents(itemID);
749 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 934 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
750 } 935 }
936 m_items.LockItemsForWrite(true);
751 m_items.Remove(itemID); 937 m_items.Remove(itemID);
938 m_items.LockItemsForWrite(false);
752 m_inventorySerial++; 939 m_inventorySerial++;
753 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 940 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
754 941
755 HasInventoryChanged = true; 942 HasInventoryChanged = true;
756 m_part.ParentGroup.HasGroupChanged = true; 943 m_part.ParentGroup.HasGroupChanged = true;
757 944
758 if (!ContainsScripts()) 945 int scriptcount = 0;
946 m_items.LockItemsForRead(true);
947 foreach (TaskInventoryItem item in m_items.Values)
948 {
949 if (item.Type == 10)
950 {
951 scriptcount++;
952 }
953 }
954 m_items.LockItemsForRead(false);
955
956
957 if (scriptcount <= 0)
958 {
759 m_part.RemFlag(PrimFlags.Scripted); 959 m_part.RemFlag(PrimFlags.Scripted);
960 }
760 961
761 m_part.ScheduleFullUpdate(); 962 m_part.ScheduleFullUpdate();
762 963
763 return type; 964 return type;
764
765 } 965 }
766 else 966 else
767 { 967 {
968 m_items.LockItemsForRead(false);
768 m_log.ErrorFormat( 969 m_log.ErrorFormat(
769 "[PRIM INVENTORY]: " + 970 "[PRIM INVENTORY]: " +
770 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 971 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
771 itemID, m_part.Name, m_part.UUID, 972 itemID, m_part.Name, m_part.UUID);
772 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
773 } 973 }
774 974
775 return -1; 975 return -1;
776 } 976 }
777 977
778 private bool CreateInventoryFile() 978 private bool CreateInventoryFileName()
779 { 979 {
780 if (m_inventoryFileName == String.Empty || 980 if (m_inventoryFileName == String.Empty ||
781 m_inventoryFileNameSerial < m_inventorySerial) 981 m_inventoryFileNameSerial < m_inventorySerial)
782 { 982 {
783 // Something changed, we need to create a new file
784 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; 983 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
785 m_inventoryFileNameSerial = m_inventorySerial; 984 m_inventoryFileNameSerial = m_inventorySerial;
786
787 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
788
789 lock (m_items)
790 {
791 foreach (TaskInventoryItem item in m_items.Values)
792 {
793 UUID ownerID = item.OwnerID;
794 uint everyoneMask = 0;
795 uint baseMask = item.BasePermissions;
796 uint ownerMask = item.CurrentPermissions;
797 uint groupMask = item.GroupPermissions;
798
799 invString.AddItemStart();
800 invString.AddNameValueLine("item_id", item.ItemID.ToString());
801 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
802
803 invString.AddPermissionsStart();
804
805 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
806 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
807 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
808 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
809 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
810
811 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
812 invString.AddNameValueLine("owner_id", ownerID.ToString());
813
814 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
815
816 invString.AddNameValueLine("group_id", item.GroupID.ToString());
817 invString.AddSectionEnd();
818
819 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
820 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
821 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
822 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
823
824 invString.AddSaleStart();
825 invString.AddNameValueLine("sale_type", "not");
826 invString.AddNameValueLine("sale_price", "0");
827 invString.AddSectionEnd();
828
829 invString.AddNameValueLine("name", item.Name + "|");
830 invString.AddNameValueLine("desc", item.Description + "|");
831
832 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
833 invString.AddSectionEnd();
834 }
835 }
836
837 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
838
839 return true; 985 return true;
840 } 986 }
841 987
842 // No need to recreate, the existing file is fine
843 return false; 988 return false;
844 } 989 }
845 990
@@ -849,26 +994,99 @@ namespace OpenSim.Region.Framework.Scenes
849 /// <param name="xferManager"></param> 994 /// <param name="xferManager"></param>
850 public void RequestInventoryFile(IClientAPI client, IXfer xferManager) 995 public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
851 { 996 {
852 bool changed = CreateInventoryFile(); 997 bool changed = CreateInventoryFileName();
998
999 bool includeAssets = false;
1000 if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId))
1001 includeAssets = true;
1002
1003 if (m_inventoryPrivileged != includeAssets)
1004 changed = true;
1005
1006 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
1007
1008 Items.LockItemsForRead(true);
853 1009
854 if (m_inventorySerial == 0) // No inventory 1010 if (m_inventorySerial == 0) // No inventory
855 { 1011 {
856 client.SendTaskInventory(m_part.UUID, 0, new byte[0]); 1012 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1013 Items.LockItemsForRead(false);
857 return; 1014 return;
858 } 1015 }
859 1016
860 // In principle, we should only do the rest if the inventory changed; 1017 if (!changed)
861 // by sending m_inventorySerial to the client, it ought to know 1018 {
862 // that nothing changed and that it doesn't need to request the file. 1019 if (m_inventoryFileData.Length > 2)
863 // Unfortunately, it doesn't look like the client optimizes this; 1020 {
864 // the client seems to always come back and request the Xfer, 1021 xferManager.AddNewFile(m_inventoryFileName,
865 // no matter what value m_inventorySerial has. 1022 m_inventoryFileData);
1023 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
1024 Util.StringToBytes256(m_inventoryFileName));
1025
1026 Items.LockItemsForRead(false);
1027 return;
1028 }
1029 }
1030
1031 m_inventoryPrivileged = includeAssets;
1032
1033 foreach (TaskInventoryItem item in m_items.Values)
1034 {
1035 UUID ownerID = item.OwnerID;
1036 uint everyoneMask = 0;
1037 uint baseMask = item.BasePermissions;
1038 uint ownerMask = item.CurrentPermissions;
1039 uint groupMask = item.GroupPermissions;
1040
1041 invString.AddItemStart();
1042 invString.AddNameValueLine("item_id", item.ItemID.ToString());
1043 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
1044
1045 invString.AddPermissionsStart();
1046
1047 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
1048 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
1049 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
1050 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
1051 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
1052
1053 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
1054 invString.AddNameValueLine("owner_id", ownerID.ToString());
1055
1056 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
1057
1058 invString.AddNameValueLine("group_id", item.GroupID.ToString());
1059 invString.AddSectionEnd();
1060
1061 if (includeAssets)
1062 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
1063 else
1064 invString.AddNameValueLine("asset_id", UUID.Zero.ToString());
1065 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
1066 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
1067 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
1068
1069 invString.AddSaleStart();
1070 invString.AddNameValueLine("sale_type", "not");
1071 invString.AddNameValueLine("sale_price", "0");
1072 invString.AddSectionEnd();
1073
1074 invString.AddNameValueLine("name", item.Name + "|");
1075 invString.AddNameValueLine("desc", item.Description + "|");
1076
1077 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
1078 invString.AddSectionEnd();
1079 }
1080
1081 Items.LockItemsForRead(false);
1082
1083 m_inventoryFileData = Utils.StringToBytes(invString.BuildString);
866 1084
867 if (m_inventoryFileData.Length > 2) 1085 if (m_inventoryFileData.Length > 2)
868 // Add the file for Xfer 1086 {
869 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); 1087 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
1088 }
870 1089
871 // Tell the client we're ready to Xfer the file
872 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, 1090 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
873 Util.StringToBytes256(m_inventoryFileName)); 1091 Util.StringToBytes256(m_inventoryFileName));
874 } 1092 }
@@ -881,10 +1099,11 @@ namespace OpenSim.Region.Framework.Scenes
881 { 1099 {
882 if (HasInventoryChanged) 1100 if (HasInventoryChanged)
883 { 1101 {
884 HasInventoryChanged = false; 1102 Items.LockItemsForRead(true);
885 List<TaskInventoryItem> items = GetInventoryItems(); 1103 datastore.StorePrimInventory(m_part.UUID, Items.Values);
886 datastore.StorePrimInventory(m_part.UUID, items); 1104 Items.LockItemsForRead(false);
887 1105
1106 HasInventoryChanged = false;
888 } 1107 }
889 } 1108 }
890 1109
@@ -951,80 +1170,61 @@ namespace OpenSim.Region.Framework.Scenes
951 { 1170 {
952 uint mask=0x7fffffff; 1171 uint mask=0x7fffffff;
953 1172
954 lock (m_items) 1173 foreach (TaskInventoryItem item in m_items.Values)
955 { 1174 {
956 foreach (TaskInventoryItem item in m_items.Values) 1175 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
1176 mask &= ~((uint)PermissionMask.Copy >> 13);
1177 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
1178 mask &= ~((uint)PermissionMask.Transfer >> 13);
1179 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
1180 mask &= ~((uint)PermissionMask.Modify >> 13);
1181
1182 if (item.InvType == (int)InventoryType.Object)
957 { 1183 {
958 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1184 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
959 mask &= ~((uint)PermissionMask.Copy >> 13); 1185 mask &= ~((uint)PermissionMask.Copy >> 13);
960 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1186 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
961 mask &= ~((uint)PermissionMask.Transfer >> 13); 1187 mask &= ~((uint)PermissionMask.Transfer >> 13);
962 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 1188 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
963 mask &= ~((uint)PermissionMask.Modify >> 13); 1189 mask &= ~((uint)PermissionMask.Modify >> 13);
964
965 if (item.InvType != (int)InventoryType.Object)
966 {
967 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
968 mask &= ~((uint)PermissionMask.Copy >> 13);
969 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
970 mask &= ~((uint)PermissionMask.Transfer >> 13);
971 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
972 mask &= ~((uint)PermissionMask.Modify >> 13);
973 }
974 else
975 {
976 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
977 mask &= ~((uint)PermissionMask.Copy >> 13);
978 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
979 mask &= ~((uint)PermissionMask.Transfer >> 13);
980 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
981 mask &= ~((uint)PermissionMask.Modify >> 13);
982 }
983
984 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
985 mask &= ~(uint)PermissionMask.Copy;
986 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
987 mask &= ~(uint)PermissionMask.Transfer;
988 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
989 mask &= ~(uint)PermissionMask.Modify;
990 } 1190 }
1191
1192 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1193 mask &= ~(uint)PermissionMask.Copy;
1194 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1195 mask &= ~(uint)PermissionMask.Transfer;
1196 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1197 mask &= ~(uint)PermissionMask.Modify;
991 } 1198 }
992
993 return mask; 1199 return mask;
994 } 1200 }
995 1201
996 public void ApplyNextOwnerPermissions() 1202 public void ApplyNextOwnerPermissions()
997 { 1203 {
998 lock (m_items) 1204 foreach (TaskInventoryItem item in m_items.Values)
999 { 1205 {
1000 foreach (TaskInventoryItem item in m_items.Values) 1206 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
1001 { 1207 {
1002 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 1208 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
1003 { 1209 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
1004 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1210 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
1005 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 1211 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
1006 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1212 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1007 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 1213 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1008 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
1009 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
1010 }
1011 item.CurrentPermissions &= item.NextPermissions;
1012 item.BasePermissions &= item.NextPermissions;
1013 item.EveryonePermissions &= item.NextPermissions;
1014 item.OwnerChanged = true;
1015 } 1214 }
1215 item.OwnerChanged = true;
1216 item.CurrentPermissions &= item.NextPermissions;
1217 item.BasePermissions &= item.NextPermissions;
1218 item.EveryonePermissions &= item.NextPermissions;
1016 } 1219 }
1017 } 1220 }
1018 1221
1019 public void ApplyGodPermissions(uint perms) 1222 public void ApplyGodPermissions(uint perms)
1020 { 1223 {
1021 lock (m_items) 1224 foreach (TaskInventoryItem item in m_items.Values)
1022 { 1225 {
1023 foreach (TaskInventoryItem item in m_items.Values) 1226 item.CurrentPermissions = perms;
1024 { 1227 item.BasePermissions = perms;
1025 item.CurrentPermissions = perms;
1026 item.BasePermissions = perms;
1027 }
1028 } 1228 }
1029 m_inventorySerial++; 1229 m_inventorySerial++;
1030 HasInventoryChanged = true; 1230 HasInventoryChanged = true;
@@ -1032,17 +1232,13 @@ namespace OpenSim.Region.Framework.Scenes
1032 1232
1033 public bool ContainsScripts() 1233 public bool ContainsScripts()
1034 { 1234 {
1035 lock (m_items) 1235 foreach (TaskInventoryItem item in m_items.Values)
1036 { 1236 {
1037 foreach (TaskInventoryItem item in m_items.Values) 1237 if (item.InvType == (int)InventoryType.LSL)
1038 { 1238 {
1039 if (item.InvType == (int)InventoryType.LSL) 1239 return true;
1040 {
1041 return true;
1042 }
1043 } 1240 }
1044 } 1241 }
1045
1046 return false; 1242 return false;
1047 } 1243 }
1048 1244
@@ -1050,11 +1246,8 @@ namespace OpenSim.Region.Framework.Scenes
1050 { 1246 {
1051 List<UUID> ret = new List<UUID>(); 1247 List<UUID> ret = new List<UUID>();
1052 1248
1053 lock (m_items) 1249 foreach (TaskInventoryItem item in m_items.Values)
1054 { 1250 ret.Add(item.ItemID);
1055 foreach (TaskInventoryItem item in m_items.Values)
1056 ret.Add(item.ItemID);
1057 }
1058 1251
1059 return ret; 1252 return ret;
1060 } 1253 }
@@ -1085,31 +1278,46 @@ namespace OpenSim.Region.Framework.Scenes
1085 1278
1086 public Dictionary<UUID, string> GetScriptStates() 1279 public Dictionary<UUID, string> GetScriptStates()
1087 { 1280 {
1281 return GetScriptStates(false);
1282 }
1283
1284 public Dictionary<UUID, string> GetScriptStates(bool oldIDs)
1285 {
1088 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); 1286 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
1089 1287
1090 Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); 1288 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
1091 if (engines == null) // No engine at all 1289 if (engines == null) // No engine at all
1092 return ret; 1290 return ret;
1093 1291
1094 List<TaskInventoryItem> scripts = GetInventoryScripts(); 1292 Items.LockItemsForRead(true);
1095 1293 foreach (TaskInventoryItem item in m_items.Values)
1096 foreach (TaskInventoryItem item in scripts)
1097 { 1294 {
1098 foreach (IScriptModule e in engines) 1295 if (item.InvType == (int)InventoryType.LSL)
1099 { 1296 {
1100 if (e != null) 1297 foreach (IScriptModule e in engines)
1101 { 1298 {
1102 string n = e.GetXMLState(item.ItemID); 1299 if (e != null)
1103 if (n != String.Empty)
1104 { 1300 {
1105 if (!ret.ContainsKey(item.ItemID)) 1301 string n = e.GetXMLState(item.ItemID);
1106 ret[item.ItemID] = n; 1302 if (n != String.Empty)
1107 break; 1303 {
1304 if (oldIDs)
1305 {
1306 if (!ret.ContainsKey(item.OldItemID))
1307 ret[item.OldItemID] = n;
1308 }
1309 else
1310 {
1311 if (!ret.ContainsKey(item.ItemID))
1312 ret[item.ItemID] = n;
1313 }
1314 break;
1315 }
1108 } 1316 }
1109 } 1317 }
1110 } 1318 }
1111 } 1319 }
1112 1320 Items.LockItemsForRead(false);
1113 return ret; 1321 return ret;
1114 } 1322 }
1115 1323
@@ -1119,21 +1327,27 @@ namespace OpenSim.Region.Framework.Scenes
1119 if (engines == null) 1327 if (engines == null)
1120 return; 1328 return;
1121 1329
1122 List<TaskInventoryItem> scripts = GetInventoryScripts();
1123 1330
1124 foreach (TaskInventoryItem item in scripts) 1331 Items.LockItemsForRead(true);
1332
1333 foreach (TaskInventoryItem item in m_items.Values)
1125 { 1334 {
1126 foreach (IScriptModule engine in engines) 1335 if (item.InvType == (int)InventoryType.LSL)
1127 { 1336 {
1128 if (engine != null) 1337 foreach (IScriptModule engine in engines)
1129 { 1338 {
1130 if (item.OwnerChanged) 1339 if (engine != null)
1131 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); 1340 {
1132 item.OwnerChanged = false; 1341 if (item.OwnerChanged)
1133 engine.ResumeScript(item.ItemID); 1342 engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER });
1343 item.OwnerChanged = false;
1344 engine.ResumeScript(item.ItemID);
1345 }
1134 } 1346 }
1135 } 1347 }
1136 } 1348 }
1349
1350 Items.LockItemsForRead(false);
1137 } 1351 }
1138 } 1352 }
1139} 1353}