aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
diff options
context:
space:
mode:
authoronefang2019-05-19 21:24:15 +1000
committeronefang2019-05-19 21:24:15 +1000
commit5e4d6cab00cb29cd088ab7b62ab13aff103b64cb (patch)
treea9fbc62df9eb2d1d9ba2698d8552eae71eca20d8 /OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
parentAdd a build script. (diff)
downloadopensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.zip
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.gz
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.bz2
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.xz
Dump OpenSim 0.9.0.1 into it's own branch.
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs973
1 files changed, 614 insertions, 359 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index ec39726..30f7151 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -26,6 +26,7 @@
26 */ 26 */
27 27
28using System; 28using System;
29using System.Text;
29using System.Xml; 30using System.Xml;
30using System.IO; 31using System.IO;
31using System.Collections.Generic; 32using System.Collections.Generic;
@@ -46,10 +47,15 @@ namespace OpenSim.Region.Framework.Scenes
46 { 47 {
47 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 48 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 49
49 private string m_inventoryFileName = String.Empty;
50 private byte[] m_inventoryFileData = new byte[0]; 50 private byte[] m_inventoryFileData = new byte[0];
51 private byte[] m_inventoryFileNameBytes = new byte[0];
52 private string m_inventoryFileName = "";
51 private uint m_inventoryFileNameSerial = 0; 53 private uint m_inventoryFileNameSerial = 0;
52 54 private bool m_inventoryPrivileged = false;
55 private object m_inventoryFileLock = new object();
56
57 private Dictionary<UUID, ArrayList> m_scriptErrors = new Dictionary<UUID, ArrayList>();
58
53 /// <value> 59 /// <value>
54 /// The part to which the inventory belongs. 60 /// The part to which the inventory belongs.
55 /// </value> 61 /// </value>
@@ -70,7 +76,7 @@ namespace OpenSim.Region.Framework.Scenes
70 /// Tracks whether inventory has changed since the last persistent backup 76 /// Tracks whether inventory has changed since the last persistent backup
71 /// </summary> 77 /// </summary>
72 internal bool HasInventoryChanged; 78 internal bool HasInventoryChanged;
73 79
74 /// <value> 80 /// <value>
75 /// Inventory serial number 81 /// Inventory serial number
76 /// </value> 82 /// </value>
@@ -85,7 +91,10 @@ namespace OpenSim.Region.Framework.Scenes
85 /// </value> 91 /// </value>
86 protected internal TaskInventoryDictionary Items 92 protected internal TaskInventoryDictionary Items
87 { 93 {
88 get { return m_items; } 94 get
95 {
96 return m_items;
97 }
89 set 98 set
90 { 99 {
91 m_items = value; 100 m_items = value;
@@ -102,7 +111,7 @@ namespace OpenSim.Region.Framework.Scenes
102 return m_items.Count; 111 return m_items.Count;
103 } 112 }
104 } 113 }
105 114
106 /// <summary> 115 /// <summary>
107 /// Constructor 116 /// Constructor
108 /// </summary> 117 /// </summary>
@@ -133,39 +142,54 @@ namespace OpenSim.Region.Framework.Scenes
133 /// </remarks> 142 /// </remarks>
134 public void ResetInventoryIDs() 143 public void ResetInventoryIDs()
135 { 144 {
136 if (null == m_part) 145 if (m_part == null)
137 return; 146 return;
138 147
139 lock (m_items) 148 m_items.LockItemsForWrite(true);
149 if (m_items.Count == 0)
140 { 150 {
141 if (0 == m_items.Count) 151 m_items.LockItemsForWrite(false);
142 return; 152 return;
153 }
143 154
144 IList<TaskInventoryItem> items = GetInventoryItems(); 155 UUID partID = m_part.UUID;
145 m_items.Clear(); 156 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(m_items.Values);
157 m_items.Clear();
146 158
147 foreach (TaskInventoryItem item in items) 159 foreach (TaskInventoryItem item in items)
148 { 160 {
149 item.ResetIDs(m_part.UUID); 161 item.ResetIDs(partID);
150 m_items.Add(item.ItemID, item); 162 m_items.Add(item.ItemID, item);
151 }
152 } 163 }
164 m_inventorySerial++;
165 m_items.LockItemsForWrite(false);
153 } 166 }
154 167
155 public void ResetObjectID() 168 public void ResetObjectID()
156 { 169 {
157 lock (Items) 170 if (m_part == null)
171 return;
172
173 m_items.LockItemsForWrite(true);
174
175 if (m_items.Count == 0)
158 { 176 {
159 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 177 m_items.LockItemsForWrite(false);
160 Items.Clear(); 178 return;
161
162 foreach (TaskInventoryItem item in items)
163 {
164 item.ParentPartID = m_part.UUID;
165 item.ParentID = m_part.UUID;
166 Items.Add(item.ItemID, item);
167 }
168 } 179 }
180
181 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(m_items.Values);
182 m_items.Clear();
183
184 UUID partID = m_part.UUID;
185 foreach (TaskInventoryItem item in items)
186 {
187 item.ParentPartID = partID;
188 item.ParentID = partID;
189 m_items.Add(item.ItemID, item);
190 }
191 m_inventorySerial++;
192 m_items.LockItemsForWrite(false);
169 } 193 }
170 194
171 /// <summary> 195 /// <summary>
@@ -174,18 +198,17 @@ namespace OpenSim.Region.Framework.Scenes
174 /// <param name="ownerId"></param> 198 /// <param name="ownerId"></param>
175 public void ChangeInventoryOwner(UUID ownerId) 199 public void ChangeInventoryOwner(UUID ownerId)
176 { 200 {
177 lock (Items) 201 if(m_part == null)
202 return;
203
204 m_items.LockItemsForWrite(true);
205 if (m_items.Count == 0)
178 { 206 {
179 if (0 == Items.Count) 207 m_items.LockItemsForWrite(false);
180 { 208 return;
181 return;
182 }
183 } 209 }
184 210
185 HasInventoryChanged = true; 211 foreach (TaskInventoryItem item in m_items.Values)
186 m_part.ParentGroup.HasGroupChanged = true;
187 List<TaskInventoryItem> items = GetInventoryItems();
188 foreach (TaskInventoryItem item in items)
189 { 212 {
190 if (ownerId != item.OwnerID) 213 if (ownerId != item.OwnerID)
191 item.LastOwnerID = item.OwnerID; 214 item.LastOwnerID = item.OwnerID;
@@ -195,6 +218,10 @@ namespace OpenSim.Region.Framework.Scenes
195 item.PermsGranter = UUID.Zero; 218 item.PermsGranter = UUID.Zero;
196 item.OwnerChanged = true; 219 item.OwnerChanged = true;
197 } 220 }
221 HasInventoryChanged = true;
222 m_part.ParentGroup.HasGroupChanged = true;
223 m_inventorySerial++;
224 m_items.LockItemsForWrite(false);
198 } 225 }
199 226
200 /// <summary> 227 /// <summary>
@@ -203,14 +230,16 @@ namespace OpenSim.Region.Framework.Scenes
203 /// <param name="groupID"></param> 230 /// <param name="groupID"></param>
204 public void ChangeInventoryGroup(UUID groupID) 231 public void ChangeInventoryGroup(UUID groupID)
205 { 232 {
206 lock (Items) 233 if(m_part == null)
234 return;
235
236 m_items.LockItemsForWrite(true);
237 if (m_items.Count == 0)
207 { 238 {
208 if (0 == Items.Count) 239 m_items.LockItemsForWrite(false);
209 { 240 return;
210 return;
211 }
212 } 241 }
213 242 m_inventorySerial++;
214 // Don't let this set the HasGroupChanged flag for attachments 243 // Don't let this set the HasGroupChanged flag for attachments
215 // as this happens during rez and we don't want a new asset 244 // as this happens during rez and we don't want a new asset
216 // for each attachment each time 245 // for each attachment each time
@@ -220,12 +249,10 @@ namespace OpenSim.Region.Framework.Scenes
220 m_part.ParentGroup.HasGroupChanged = true; 249 m_part.ParentGroup.HasGroupChanged = true;
221 } 250 }
222 251
223 List<TaskInventoryItem> items = GetInventoryItems(); 252 foreach (TaskInventoryItem item in m_items.Values)
224 foreach (TaskInventoryItem item in items) 253 item.GroupID = groupID;
225 { 254
226 if (groupID != item.GroupID) 255 m_items.LockItemsForWrite(false);
227 item.GroupID = groupID;
228 }
229 } 256 }
230 257
231 private void QueryScriptStates() 258 private void QueryScriptStates()
@@ -233,15 +260,18 @@ namespace OpenSim.Region.Framework.Scenes
233 if (m_part == null || m_part.ParentGroup == null || m_part.ParentGroup.Scene == null) 260 if (m_part == null || m_part.ParentGroup == null || m_part.ParentGroup.Scene == null)
234 return; 261 return;
235 262
236 lock (Items) 263 m_items.LockItemsForRead(true);
264 foreach (TaskInventoryItem item in m_items.Values)
237 { 265 {
238 foreach (TaskInventoryItem item in Items.Values) 266 if (item.InvType == (int)InventoryType.LSL)
239 { 267 {
240 bool running; 268 bool running;
241 if (TryGetScriptInstanceRunning(m_part.ParentGroup.Scene, item, out running)) 269 if (TryGetScriptInstanceRunning(m_part.ParentGroup.Scene, item, out running))
242 item.ScriptRunning = running; 270 item.ScriptRunning = running;
243 } 271 }
244 } 272 }
273
274 m_items.LockItemsForRead(false);
245 } 275 }
246 276
247 public bool TryGetScriptInstanceRunning(UUID itemId, out bool running) 277 public bool TryGetScriptInstanceRunning(UUID itemId, out bool running)
@@ -318,7 +348,10 @@ namespace OpenSim.Region.Framework.Scenes
318 { 348 {
319 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); 349 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
320 foreach (TaskInventoryItem item in scripts) 350 foreach (TaskInventoryItem item in scripts)
351 {
321 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); 352 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
353 m_part.RemoveScriptEvents(item.ItemID);
354 }
322 } 355 }
323 356
324 /// <summary> 357 /// <summary>
@@ -326,7 +359,9 @@ namespace OpenSim.Region.Framework.Scenes
326 /// </summary> 359 /// </summary>
327 public void StopScriptInstances() 360 public void StopScriptInstances()
328 { 361 {
329 GetInventoryItems(InventoryType.LSL).ForEach(i => StopScriptInstance(i)); 362 List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL);
363 foreach (TaskInventoryItem item in scripts)
364 StopScriptInstance(item);
330 } 365 }
331 366
332 /// <summary> 367 /// <summary>
@@ -339,8 +374,11 @@ namespace OpenSim.Region.Framework.Scenes
339// m_log.DebugFormat("[PRIM INVENTORY]: Starting script {0} {1} in prim {2} {3} in {4}", 374// m_log.DebugFormat("[PRIM INVENTORY]: Starting script {0} {1} in prim {2} {3} in {4}",
340// item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); 375// item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName);
341 376
342 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) 377 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item, m_part))
378 {
379 StoreScriptError(item.ItemID, "no permission");
343 return false; 380 return false;
381 }
344 382
345 m_part.AddFlag(PrimFlags.Scripted); 383 m_part.AddFlag(PrimFlags.Scripted);
346 384
@@ -350,14 +388,13 @@ namespace OpenSim.Region.Framework.Scenes
350 if (stateSource == 2 && // Prim crossing 388 if (stateSource == 2 && // Prim crossing
351 m_part.ParentGroup.Scene.m_trustBinaries) 389 m_part.ParentGroup.Scene.m_trustBinaries)
352 { 390 {
353 lock (m_items) 391 m_items.LockItemsForWrite(true);
354 { 392 m_items[item.ItemID].PermsMask = 0;
355 m_items[item.ItemID].PermsMask = 0; 393 m_items[item.ItemID].PermsGranter = UUID.Zero;
356 m_items[item.ItemID].PermsGranter = UUID.Zero; 394 m_items.LockItemsForWrite(false);
357 }
358
359 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 395 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
360 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 396 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
397 StoreScriptErrors(item.ItemID, null);
361 m_part.ParentGroup.AddActiveScriptCount(1); 398 m_part.ParentGroup.AddActiveScriptCount(1);
362 m_part.ScheduleFullUpdate(); 399 m_part.ScheduleFullUpdate();
363 return true; 400 return true;
@@ -366,9 +403,11 @@ namespace OpenSim.Region.Framework.Scenes
366 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); 403 AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
367 if (null == asset) 404 if (null == asset)
368 { 405 {
406 string msg = String.Format("asset ID {0} could not be found", item.AssetID);
407 StoreScriptError(item.ItemID, msg);
369 m_log.ErrorFormat( 408 m_log.ErrorFormat(
370 "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", 409 "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found",
371 item.Name, item.ItemID, m_part.AbsolutePosition, 410 item.Name, item.ItemID, m_part.AbsolutePosition,
372 m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); 411 m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID);
373 412
374 return false; 413 return false;
@@ -378,16 +417,18 @@ namespace OpenSim.Region.Framework.Scenes
378 if (m_part.ParentGroup.m_savedScriptState != null) 417 if (m_part.ParentGroup.m_savedScriptState != null)
379 item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); 418 item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID);
380 419
381 lock (m_items) 420 m_items.LockItemsForWrite(true);
382 { 421
383 m_items[item.ItemID].OldItemID = item.OldItemID; 422 m_items[item.ItemID].OldItemID = item.OldItemID;
384 m_items[item.ItemID].PermsMask = 0; 423 m_items[item.ItemID].PermsMask = 0;
385 m_items[item.ItemID].PermsGranter = UUID.Zero; 424 m_items[item.ItemID].PermsGranter = UUID.Zero;
386 } 425
426 m_items.LockItemsForWrite(false);
387 427
388 string script = Utils.BytesToString(asset.Data); 428 string script = Utils.BytesToString(asset.Data);
389 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 429 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
390 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 430 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
431 StoreScriptErrors(item.ItemID, null);
391 if (!item.ScriptRunning) 432 if (!item.ScriptRunning)
392 m_part.ParentGroup.Scene.EventManager.TriggerStopScript( 433 m_part.ParentGroup.Scene.EventManager.TriggerStopScript(
393 m_part.LocalId, item.ItemID); 434 m_part.LocalId, item.ItemID);
@@ -401,7 +442,7 @@ namespace OpenSim.Region.Framework.Scenes
401 private UUID RestoreSavedScriptState(UUID loadedID, UUID oldID, UUID newID) 442 private UUID RestoreSavedScriptState(UUID loadedID, UUID oldID, UUID newID)
402 { 443 {
403// m_log.DebugFormat( 444// m_log.DebugFormat(
404// "[PRIM INVENTORY]: Restoring scripted state for item {0}, oldID {1}, loadedID {2}", 445// "[PRIM INVENTORY]: Restoring scripted state for item {0}, oldID {1}, loadedID {2}",
405// newID, oldID, loadedID); 446// newID, oldID, loadedID);
406 447
407 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); 448 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
@@ -414,7 +455,7 @@ namespace OpenSim.Region.Framework.Scenes
414 if (m_part.ParentGroup.m_savedScriptState.ContainsKey(stateID)) 455 if (m_part.ParentGroup.m_savedScriptState.ContainsKey(stateID))
415 { 456 {
416 XmlDocument doc = new XmlDocument(); 457 XmlDocument doc = new XmlDocument();
417 458 doc.XmlResolver=null;
418 doc.LoadXml(m_part.ParentGroup.m_savedScriptState[stateID]); 459 doc.LoadXml(m_part.ParentGroup.m_savedScriptState[stateID]);
419 460
420 ////////// CRUFT WARNING /////////////////////////////////// 461 ////////// CRUFT WARNING ///////////////////////////////////
@@ -450,7 +491,7 @@ namespace OpenSim.Region.Framework.Scenes
450 491
451 m_part.ParentGroup.m_savedScriptState[stateID] = newDoc.OuterXml; 492 m_part.ParentGroup.m_savedScriptState[stateID] = newDoc.OuterXml;
452 } 493 }
453 494
454 foreach (IScriptModule e in engines) 495 foreach (IScriptModule e in engines)
455 { 496 {
456 if (e != null) 497 if (e != null)
@@ -466,22 +507,138 @@ namespace OpenSim.Region.Framework.Scenes
466 return stateID; 507 return stateID;
467 } 508 }
468 509
510 /// <summary>
511 /// Start a script which is in this prim's inventory.
512 /// Some processing may occur in the background, but this routine returns asap.
513 /// </summary>
514 /// <param name="itemId">
515 /// A <see cref="UUID"/>
516 /// </param>
469 public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 517 public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
470 { 518 {
471 TaskInventoryItem item = GetInventoryItem(itemId); 519 lock (m_scriptErrors)
472 if (item != null) 520 {
521 // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion
522 m_scriptErrors.Remove(itemId);
523 }
524 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
525 return true;
526 }
527
528 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
529 {
530 m_items.LockItemsForRead(true);
531
532 if (m_items.ContainsKey(itemId))
473 { 533 {
474 return CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 534 TaskInventoryItem it = m_items[itemId];
535 m_items.LockItemsForRead(false);
536
537 CreateScriptInstance(it, startParam, postOnRez, engine, stateSource);
475 } 538 }
476 else 539 else
477 { 540 {
478 m_log.ErrorFormat( 541 m_items.LockItemsForRead(false);
479 "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 542 string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID,
480 itemId, m_part.Name, m_part.UUID,
481 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 543 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
544 StoreScriptError(itemId, msg);
545 m_log.ErrorFormat(
546 "[PRIM INVENTORY]: " +
547 "Couldn't start script with ID {0} since it {1}", itemId, msg);
548 }
549 }
482 550
483 return false; 551 /// <summary>
552 /// Start a script which is in this prim's inventory and return any compilation error messages.
553 /// </summary>
554 /// <param name="itemId">
555 /// A <see cref="UUID"/>
556 /// </param>
557 public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
558 {
559 ArrayList errors;
560
561 // Indicate to CreateScriptInstanceInternal() we want it to
562 // post any compilation/loading error messages
563 lock (m_scriptErrors)
564 {
565 m_scriptErrors[itemId] = null;
484 } 566 }
567
568 // Perform compilation/loading
569 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
570
571 // Wait for and retrieve any errors
572 lock (m_scriptErrors)
573 {
574 while ((errors = m_scriptErrors[itemId]) == null)
575 {
576 if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
577 {
578 m_log.ErrorFormat(
579 "[PRIM INVENTORY]: " +
580 "timedout waiting for script {0} errors", itemId);
581 errors = m_scriptErrors[itemId];
582 if (errors == null)
583 {
584 errors = new ArrayList(1);
585 errors.Add("timedout waiting for errors");
586 }
587 break;
588 }
589 }
590 m_scriptErrors.Remove(itemId);
591 }
592 return errors;
593 }
594
595 // Signal to CreateScriptInstanceEr() that compilation/loading is complete
596 private void StoreScriptErrors(UUID itemId, ArrayList errors)
597 {
598 lock (m_scriptErrors)
599 {
600 // If compilation/loading initiated via CreateScriptInstance(),
601 // it does not want the errors, so just get out
602 if (!m_scriptErrors.ContainsKey(itemId))
603 {
604 return;
605 }
606
607 // Initiated via CreateScriptInstanceEr(), if we know what the
608 // errors are, save them and wake CreateScriptInstanceEr().
609 if (errors != null)
610 {
611 m_scriptErrors[itemId] = errors;
612 System.Threading.Monitor.PulseAll(m_scriptErrors);
613 return;
614 }
615 }
616
617 // Initiated via CreateScriptInstanceEr() but we don't know what
618 // the errors are yet, so retrieve them from the script engine.
619 // This may involve some waiting internal to GetScriptErrors().
620 errors = GetScriptErrors(itemId);
621
622 // Get a default non-null value to indicate success.
623 if (errors == null)
624 {
625 errors = new ArrayList();
626 }
627
628 // Post to CreateScriptInstanceEr() and wake it up
629 lock (m_scriptErrors)
630 {
631 m_scriptErrors[itemId] = errors;
632 System.Threading.Monitor.PulseAll(m_scriptErrors);
633 }
634 }
635
636 // Like StoreScriptErrors(), but just posts a single string message
637 private void StoreScriptError(UUID itemId, string message)
638 {
639 ArrayList errors = new ArrayList(1);
640 errors.Add(message);
641 StoreScriptErrors(itemId, errors);
485 } 642 }
486 643
487 /// <summary> 644 /// <summary>
@@ -494,19 +651,11 @@ namespace OpenSim.Region.Framework.Scenes
494 /// </param> 651 /// </param>
495 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 652 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
496 { 653 {
497 bool scriptPresent = false; 654 if (m_items.ContainsKey(itemId))
498
499 lock (m_items)
500 {
501 if (m_items.ContainsKey(itemId))
502 scriptPresent = true;
503 }
504
505 if (scriptPresent)
506 { 655 {
507 if (!sceneObjectBeingDeleted) 656 if (!sceneObjectBeingDeleted)
508 m_part.RemoveScriptEvents(itemId); 657 m_part.RemoveScriptEvents(itemId);
509 658
510 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemId); 659 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemId);
511 m_part.ParentGroup.AddActiveScriptCount(-1); 660 m_part.ParentGroup.AddActiveScriptCount(-1);
512 } 661 }
@@ -515,7 +664,7 @@ namespace OpenSim.Region.Framework.Scenes
515 m_log.WarnFormat( 664 m_log.WarnFormat(
516 "[PRIM INVENTORY]: " + 665 "[PRIM INVENTORY]: " +
517 "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 666 "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
518 itemId, m_part.Name, m_part.UUID, 667 itemId, m_part.Name, m_part.UUID,
519 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 668 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
520 } 669 }
521 } 670 }
@@ -544,7 +693,7 @@ namespace OpenSim.Region.Framework.Scenes
544 m_log.WarnFormat( 693 m_log.WarnFormat(
545 "[PRIM INVENTORY]: " + 694 "[PRIM INVENTORY]: " +
546 "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 695 "Couldn't stop script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}",
547 itemId, m_part.Name, m_part.UUID, 696 itemId, m_part.Name, m_part.UUID,
548 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 697 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
549 } 698 }
550 } 699 }
@@ -573,14 +722,16 @@ namespace OpenSim.Region.Framework.Scenes
573 /// <returns></returns> 722 /// <returns></returns>
574 private bool InventoryContainsName(string name) 723 private bool InventoryContainsName(string name)
575 { 724 {
576 lock (m_items) 725 m_items.LockItemsForRead(true);
726 foreach (TaskInventoryItem item in m_items.Values)
577 { 727 {
578 foreach (TaskInventoryItem item in m_items.Values) 728 if (item.Name == name)
579 { 729 {
580 if (item.Name == name) 730 m_items.LockItemsForRead(false);
581 return true; 731 return true;
582 } 732 }
583 } 733 }
734 m_items.LockItemsForRead(false);
584 return false; 735 return false;
585 } 736 }
586 737
@@ -622,8 +773,9 @@ namespace OpenSim.Region.Framework.Scenes
622 /// <param name="item"></param> 773 /// <param name="item"></param>
623 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 774 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
624 { 775 {
625 List<TaskInventoryItem> il = GetInventoryItems(); 776 m_items.LockItemsForRead(true);
626 777 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
778 m_items.LockItemsForRead(false);
627 foreach (TaskInventoryItem i in il) 779 foreach (TaskInventoryItem i in il)
628 { 780 {
629 if (i.Name == item.Name) 781 if (i.Name == item.Name)
@@ -661,16 +813,16 @@ namespace OpenSim.Region.Framework.Scenes
661 item.Name = name; 813 item.Name = name;
662 item.GroupID = m_part.GroupID; 814 item.GroupID = m_part.GroupID;
663 815
664 lock (m_items) 816 m_items.LockItemsForWrite(true);
665 m_items.Add(item.ItemID, item); 817 m_items.Add(item.ItemID, item);
666 818 m_items.LockItemsForWrite(false);
667 if (allowedDrop) 819 if (allowedDrop)
668 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 820 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
669 else 821 else
670 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 822 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
671 823
824 m_part.AggregateInnerPerms();
672 m_inventorySerial++; 825 m_inventorySerial++;
673 //m_inventorySerial += 2;
674 HasInventoryChanged = true; 826 HasInventoryChanged = true;
675 m_part.ParentGroup.HasGroupChanged = true; 827 m_part.ParentGroup.HasGroupChanged = true;
676 } 828 }
@@ -684,15 +836,15 @@ namespace OpenSim.Region.Framework.Scenes
684 /// <param name="items"></param> 836 /// <param name="items"></param>
685 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 837 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
686 { 838 {
687 lock (m_items) 839 m_items.LockItemsForWrite(true);
840 foreach (TaskInventoryItem item in items)
688 { 841 {
689 foreach (TaskInventoryItem item in items) 842 m_items.Add(item.ItemID, item);
690 { 843// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
691 m_items.Add(item.ItemID, item);
692// m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
693 }
694 m_inventorySerial++;
695 } 844 }
845 m_items.LockItemsForWrite(false);
846 m_part.AggregateInnerPerms();
847 m_inventorySerial++;
696 } 848 }
697 849
698 /// <summary> 850 /// <summary>
@@ -703,23 +855,24 @@ namespace OpenSim.Region.Framework.Scenes
703 public TaskInventoryItem GetInventoryItem(UUID itemId) 855 public TaskInventoryItem GetInventoryItem(UUID itemId)
704 { 856 {
705 TaskInventoryItem item; 857 TaskInventoryItem item;
706 858 m_items.LockItemsForRead(true);
707 lock (m_items) 859 m_items.TryGetValue(itemId, out item);
708 m_items.TryGetValue(itemId, out item); 860 m_items.LockItemsForRead(false);
709
710 return item; 861 return item;
711 } 862 }
712 863
713 public TaskInventoryItem GetInventoryItem(string name) 864 public TaskInventoryItem GetInventoryItem(string name)
714 { 865 {
715 lock (m_items) 866 m_items.LockItemsForRead(true);
867 foreach (TaskInventoryItem item in m_items.Values)
716 { 868 {
717 foreach (TaskInventoryItem item in m_items.Values) 869 if (item.Name == name)
718 { 870 {
719 if (item.Name == name) 871 m_items.LockItemsForRead(false);
720 return item; 872 return item;
721 } 873 }
722 } 874 }
875 m_items.LockItemsForRead(false);
723 876
724 return null; 877 return null;
725 } 878 }
@@ -728,41 +881,45 @@ namespace OpenSim.Region.Framework.Scenes
728 { 881 {
729 List<TaskInventoryItem> items = new List<TaskInventoryItem>(); 882 List<TaskInventoryItem> items = new List<TaskInventoryItem>();
730 883
731 lock (m_items) 884 m_items.LockItemsForRead(true);
885
886 foreach (TaskInventoryItem item in m_items.Values)
732 { 887 {
733 foreach (TaskInventoryItem item in m_items.Values) 888 if (item.Name == name)
734 { 889 items.Add(item);
735 if (item.Name == name)
736 items.Add(item);
737 }
738 } 890 }
739 891
892 m_items.LockItemsForRead(false);
893
740 return items; 894 return items;
741 } 895 }
742 896
743 public bool GetRezReadySceneObjects(TaskInventoryItem item, out List<SceneObjectGroup> objlist, out List<Vector3> veclist) 897 public bool GetRezReadySceneObjects(TaskInventoryItem item, out List<SceneObjectGroup> objlist, out List<Vector3> veclist, out Vector3 bbox, out float offsetHeight)
744 { 898 {
745 AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); 899 AssetBase rezAsset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString());
746 900
747 if (null == rezAsset) 901 if (null == rezAsset)
748 { 902 {
749 m_log.WarnFormat( 903 m_log.WarnFormat(
750 "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}", 904 "[PRIM INVENTORY]: Could not find asset {0} for inventory item {1} in {2}",
751 item.AssetID, item.Name, m_part.Name); 905 item.AssetID, item.Name, m_part.Name);
752 objlist = null; 906 objlist = null;
753 veclist = null; 907 veclist = null;
908 bbox = Vector3.Zero;
909 offsetHeight = 0;
754 return false; 910 return false;
755 } 911 }
756 912
757 Vector3 bbox; 913 bool single = m_part.ParentGroup.Scene.GetObjectsToRez(rezAsset.Data, false, out objlist, out veclist, out bbox, out offsetHeight);
758 float offsetHeight;
759
760 m_part.ParentGroup.Scene.GetObjectsToRez(rezAsset.Data, false, out objlist, out veclist, out bbox, out offsetHeight);
761 914
762 for (int i = 0; i < objlist.Count; i++) 915 for (int i = 0; i < objlist.Count; i++)
763 { 916 {
764 SceneObjectGroup group = objlist[i]; 917 SceneObjectGroup group = objlist[i];
765 918/*
919 group.RootPart.AttachPoint = group.RootPart.Shape.State;
920 group.RootPart.AttachedPos = group.AbsolutePosition;
921 group.RootPart.AttachRotation = group.GroupRotation;
922*/
766 group.ResetIDs(); 923 group.ResetIDs();
767 924
768 SceneObjectPart rootPart = group.GetPart(group.UUID); 925 SceneObjectPart rootPart = group.GetPart(group.UUID);
@@ -771,12 +928,14 @@ namespace OpenSim.Region.Framework.Scenes
771 // in the serialization, transfer the correct name from the inventory to the 928 // in the serialization, transfer the correct name from the inventory to the
772 // object itself before we rez. 929 // object itself before we rez.
773 // Only do these for the first object if we are rezzing a coalescence. 930 // Only do these for the first object if we are rezzing a coalescence.
774 if (i == 0) 931 // nahh dont mess with coalescence objects,
932 // the name in inventory can be change for inventory purpuses only
933 if (objlist.Count == 1)
775 { 934 {
776 rootPart.Name = item.Name; 935 rootPart.Name = item.Name;
777 rootPart.Description = item.Description; 936 rootPart.Description = item.Description;
778 } 937 }
779 938/* reverted to old code till part.ApplyPermissionsOnRez is better reviewed/fixed
780 group.SetGroup(m_part.GroupID, null); 939 group.SetGroup(m_part.GroupID, null);
781 940
782 foreach (SceneObjectPart part in group.Parts) 941 foreach (SceneObjectPart part in group.Parts)
@@ -792,13 +951,55 @@ namespace OpenSim.Region.Framework.Scenes
792 951
793 part.ApplyPermissionsOnRez(dest, false, m_part.ParentGroup.Scene); 952 part.ApplyPermissionsOnRez(dest, false, m_part.ParentGroup.Scene);
794 } 953 }
954*/
955// old code start
956 SceneObjectPart[] partList = group.Parts;
795 957
958 group.SetGroup(m_part.GroupID, null);
959
960 if ((rootPart.OwnerID != item.OwnerID) || (item.CurrentPermissions & (uint)PermissionMask.Slam) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
961 {
962 if (m_part.ParentGroup.Scene.Permissions.PropagatePermissions())
963 {
964 foreach (SceneObjectPart part in partList)
965 {
966 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
967 part.EveryoneMask = item.EveryonePermissions;
968 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
969 part.NextOwnerMask = item.NextPermissions;
970 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
971 part.GroupMask = item.GroupPermissions;
972 }
973
974 group.ApplyNextOwnerPermissions();
975 }
976 }
977
978 foreach (SceneObjectPart part in partList)
979 {
980 if ((part.OwnerID != item.OwnerID) || (item.CurrentPermissions & (uint)PermissionMask.Slam) != 0 || (item.Flags & (uint)InventoryItemFlags.ObjectSlamPerm) != 0)
981 {
982 if(part.GroupID != part.OwnerID)
983 part.LastOwnerID = part.OwnerID;
984 part.OwnerID = item.OwnerID;
985 part.Inventory.ChangeInventoryOwner(item.OwnerID);
986 }
987
988 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteEveryone) != 0)
989 part.EveryoneMask = item.EveryonePermissions;
990 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteNextOwner) != 0)
991 part.NextOwnerMask = item.NextPermissions;
992 if ((item.Flags & (uint)InventoryItemFlags.ObjectOverwriteGroup) != 0)
993 part.GroupMask = item.GroupPermissions;
994 }
995// old code end
796 rootPart.TrimPermissions(); 996 rootPart.TrimPermissions();
997 group.InvalidateDeepEffectivePerms();
797 } 998 }
798 999
799 return true; 1000 return true;
800 } 1001 }
801 1002
802 /// <summary> 1003 /// <summary>
803 /// Update an existing inventory item. 1004 /// Update an existing inventory item.
804 /// </summary> 1005 /// </summary>
@@ -817,11 +1018,12 @@ namespace OpenSim.Region.Framework.Scenes
817 1018
818 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) 1019 public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged)
819 { 1020 {
820 TaskInventoryItem it = GetInventoryItem(item.ItemID); 1021 m_items.LockItemsForWrite(true);
821 if (it != null) 1022
1023 if (m_items.ContainsKey(item.ItemID))
822 { 1024 {
823// m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); 1025// m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name);
824 1026
825 item.ParentID = m_part.UUID; 1027 item.ParentID = m_part.UUID;
826 item.ParentPartID = m_part.UUID; 1028 item.ParentPartID = m_part.UUID;
827 1029
@@ -830,24 +1032,26 @@ namespace OpenSim.Region.Framework.Scenes
830 if (item.GroupPermissions != (uint)PermissionMask.None) 1032 if (item.GroupPermissions != (uint)PermissionMask.None)
831 item.GroupID = m_part.GroupID; 1033 item.GroupID = m_part.GroupID;
832 1034
1035 if(item.OwnerID == UUID.Zero) // viewer to internal enconding of group owned
1036 item.OwnerID = item.GroupID;
1037
833 if (item.AssetID == UUID.Zero) 1038 if (item.AssetID == UUID.Zero)
834 item.AssetID = it.AssetID; 1039 item.AssetID = m_items[item.ItemID].AssetID;
835 1040
836 lock (m_items) 1041 m_items[item.ItemID] = item;
837 { 1042
838 m_items[item.ItemID] = item; 1043 m_inventorySerial++;
839 m_inventorySerial++;
840 }
841
842 if (fireScriptEvents) 1044 if (fireScriptEvents)
843 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 1045 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
844 1046
845 if (considerChanged) 1047 if (considerChanged)
846 { 1048 {
1049 m_part.ParentGroup.InvalidateDeepEffectivePerms();
847 HasInventoryChanged = true; 1050 HasInventoryChanged = true;
848 m_part.ParentGroup.HasGroupChanged = true; 1051 m_part.ParentGroup.HasGroupChanged = true;
849 } 1052 }
850 1053 m_items.LockItemsForWrite(false);
1054
851 return true; 1055 return true;
852 } 1056 }
853 else 1057 else
@@ -855,11 +1059,12 @@ namespace OpenSim.Region.Framework.Scenes
855 m_log.ErrorFormat( 1059 m_log.ErrorFormat(
856 "[PRIM INVENTORY]: " + 1060 "[PRIM INVENTORY]: " +
857 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 1061 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
858 item.ItemID, m_part.Name, m_part.UUID, 1062 item.ItemID, m_part.Name, m_part.UUID,
859 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 1063 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
860 } 1064 }
861 return false; 1065 m_items.LockItemsForWrite(false);
862 1066
1067 return false;
863 } 1068 }
864 1069
865 /// <summary> 1070 /// <summary>
@@ -870,160 +1075,194 @@ namespace OpenSim.Region.Framework.Scenes
870 /// in this prim's inventory.</returns> 1075 /// in this prim's inventory.</returns>
871 public int RemoveInventoryItem(UUID itemID) 1076 public int RemoveInventoryItem(UUID itemID)
872 { 1077 {
873 TaskInventoryItem item = GetInventoryItem(itemID); 1078 m_items.LockItemsForRead(true);
874 if (item != null) 1079
1080 if (m_items.ContainsKey(itemID))
875 { 1081 {
876 int type = m_items[itemID].InvType; 1082 int type = m_items[itemID].InvType;
877 if (type == 10) // Script 1083 m_items.LockItemsForRead(false);
1084 if (type == (int)InventoryType.LSL) // Script
878 { 1085 {
879 // route it through here, to handle script cleanup tasks 1086 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
880 RemoveScriptInstance(itemID, false);
881 } 1087 }
1088 m_items.LockItemsForWrite(true);
882 m_items.Remove(itemID); 1089 m_items.Remove(itemID);
1090 m_items.LockItemsForWrite(false);
1091
1092 m_part.ParentGroup.InvalidateDeepEffectivePerms();
1093
883 m_inventorySerial++; 1094 m_inventorySerial++;
884 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 1095 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
885 1096
886 HasInventoryChanged = true; 1097 HasInventoryChanged = true;
887 m_part.ParentGroup.HasGroupChanged = true; 1098 m_part.ParentGroup.HasGroupChanged = true;
888 1099
889 if (!ContainsScripts()) 1100 int scriptcount = 0;
1101 m_items.LockItemsForRead(true);
1102 foreach (TaskInventoryItem item in m_items.Values)
1103 {
1104 if (item.Type == (int)InventoryType.LSL)
1105 {
1106 scriptcount++;
1107 }
1108 }
1109 m_items.LockItemsForRead(false);
1110
1111
1112 if (scriptcount <= 0)
1113 {
890 m_part.RemFlag(PrimFlags.Scripted); 1114 m_part.RemFlag(PrimFlags.Scripted);
1115 }
891 1116
892 m_part.ScheduleFullUpdate(); 1117 m_part.ScheduleFullUpdate();
893 1118
894 return type; 1119 return type;
895
896 } 1120 }
897 else 1121 else
898 { 1122 {
1123 m_items.LockItemsForRead(false);
899 m_log.ErrorFormat( 1124 m_log.ErrorFormat(
900 "[PRIM INVENTORY]: " + 1125 "[PRIM INVENTORY]: " +
901 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", 1126 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
902 itemID, m_part.Name, m_part.UUID, 1127 itemID, m_part.Name, m_part.UUID);
903 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
904 } 1128 }
905 1129
906 return -1; 1130 return -1;
907 } 1131 }
908 1132
909 private bool CreateInventoryFile()
910 {
911// m_log.DebugFormat(
912// "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}",
913// m_part.Name, m_part.UUID, m_part.LocalId, m_inventorySerial);
914 1133
915 if (m_inventoryFileName == String.Empty || 1134 /// <summary>
916 m_inventoryFileNameSerial < m_inventorySerial) 1135 /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client
1136 /// </summary>
1137 /// <param name="xferManager"></param>
1138 public void RequestInventoryFile(IClientAPI client, IXfer xferManager)
1139 {
1140 lock (m_inventoryFileLock)
917 { 1141 {
918 // Something changed, we need to create a new file 1142 bool changed = false;
919 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
920 m_inventoryFileNameSerial = m_inventorySerial;
921 1143
922 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 1144 m_items.LockItemsForRead(true);
923 1145
924 lock (m_items) 1146 if (m_inventorySerial == 0) // No inventory
925 { 1147 {
926 foreach (TaskInventoryItem item in m_items.Values) 1148 m_items.LockItemsForRead(false);
927 { 1149 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
928// m_log.DebugFormat( 1150 return;
929// "[PRIM INVENTORY]: Adding item {0} {1} for serial {2} on prim {3} {4} {5}", 1151 }
930// item.Name, item.ItemID, m_inventorySerial, m_part.Name, m_part.UUID, m_part.LocalId);
931 1152
932 UUID ownerID = item.OwnerID; 1153 if (m_items.Count == 0) // No inventory
933 uint everyoneMask = 0; 1154 {
934 uint baseMask = item.BasePermissions; 1155 m_items.LockItemsForRead(false);
935 uint ownerMask = item.CurrentPermissions; 1156 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
936 uint groupMask = item.GroupPermissions; 1157 return;
1158 }
937 1159
938 invString.AddItemStart(); 1160 if (m_inventoryFileNameSerial != m_inventorySerial)
939 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 1161 {
940 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 1162 m_inventoryFileNameSerial = m_inventorySerial;
1163 changed = true;
1164 }
941 1165
942 invString.AddPermissionsStart(); 1166 m_items.LockItemsForRead(false);
943 1167
944 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 1168 if (m_inventoryFileData.Length < 2)
945 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 1169 changed = true;
946 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
947 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
948 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
949 1170
950 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 1171 bool includeAssets = false;
951 invString.AddNameValueLine("owner_id", ownerID.ToString()); 1172 if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId))
1173 includeAssets = true;
952 1174
953 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 1175 if (m_inventoryPrivileged != includeAssets)
1176 changed = true;
954 1177
955 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 1178 if (!changed)
956 invString.AddSectionEnd(); 1179 {
1180 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
1181 client.SendTaskInventory(m_part.UUID, (short)m_inventoryFileNameSerial,
1182 m_inventoryFileNameBytes);
957 1183
958 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 1184 return;
959 invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type)); 1185 }
960 invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType));
961 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
962 1186
963 invString.AddSaleStart(); 1187 m_inventoryPrivileged = includeAssets;
964 invString.AddNameValueLine("sale_type", "not");
965 invString.AddNameValueLine("sale_price", "0");
966 invString.AddSectionEnd();
967 1188
968 invString.AddNameValueLine("name", item.Name + "|"); 1189 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
969 invString.AddNameValueLine("desc", item.Description + "|");
970 1190
971 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 1191 m_items.LockItemsForRead(true);
972 invString.AddSectionEnd();
973 }
974 }
975 1192
976 m_inventoryFileData = Utils.StringToBytes(invString.BuildString); 1193 foreach (TaskInventoryItem item in m_items.Values)
1194 {
1195 UUID ownerID = item.OwnerID;
1196 UUID groupID = item.GroupID;
1197 uint everyoneMask = item.EveryonePermissions;
1198 uint baseMask = item.BasePermissions;
1199 uint ownerMask = item.CurrentPermissions;
1200 uint groupMask = item.GroupPermissions;
977 1201
978 return true; 1202 invString.AddItemStart();
979 } 1203 invString.AddNameValueLine("item_id", item.ItemID.ToString());
1204 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
980 1205
981 // No need to recreate, the existing file is fine 1206 invString.AddPermissionsStart();
982 return false;
983 }
984 1207
985 /// <summary> 1208 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
986 /// Serialize all the metadata for the items in this prim's inventory ready for sending to the client 1209 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
987 /// </summary> 1210 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
988 /// <param name="xferManager"></param> 1211 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
989 public void RequestInventoryFile(IClientAPI client, IXfer xferManager) 1212 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
990 {
991 lock (m_items)
992 {
993 // Don't send a inventory xfer name if there are no items. Doing so causes viewer 3 to crash when rezzing
994 // a new script if any previous deletion has left the prim inventory empty.
995 if (m_items.Count == 0) // No inventory
996 {
997// m_log.DebugFormat(
998// "[PRIM INVENTORY]: Not sending inventory data for part {0} {1} {2} for {3} since no items",
999// m_part.Name, m_part.LocalId, m_part.UUID, client.Name);
1000 1213
1001 client.SendTaskInventory(m_part.UUID, 0, new byte[0]); 1214 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
1002 return; 1215
1216 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
1217
1218 invString.AddNameValueLine("group_id",groupID.ToString());
1219 if(groupID != UUID.Zero && ownerID == groupID)
1220 {
1221 invString.AddNameValueLine("owner_id", UUID.Zero.ToString());
1222 invString.AddNameValueLine("group_owned","1");
1223 }
1224 else
1225 {
1226 invString.AddNameValueLine("owner_id", ownerID.ToString());
1227 invString.AddNameValueLine("group_owned","0");
1228 }
1229
1230 invString.AddSectionEnd();
1231
1232 if (includeAssets)
1233 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
1234 else
1235 invString.AddNameValueLine("asset_id", UUID.Zero.ToString());
1236 invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type));
1237 invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType));
1238 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
1239
1240 invString.AddSaleStart();
1241 invString.AddNameValueLine("sale_type", "not");
1242 invString.AddNameValueLine("sale_price", "0");
1243 invString.AddSectionEnd();
1244
1245 invString.AddNameValueLine("name", item.Name + "|");
1246 invString.AddNameValueLine("desc", item.Description + "|");
1247
1248 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
1249 invString.AddSectionEnd();
1003 } 1250 }
1004 1251
1005 CreateInventoryFile(); 1252 m_items.LockItemsForRead(false);
1006 1253
1007 // In principle, we should only do the rest if the inventory changed; 1254 m_inventoryFileData = Utils.StringToBytes(invString.GetString());
1008 // by sending m_inventorySerial to the client, it ought to know 1255
1009 // that nothing changed and that it doesn't need to request the file.
1010 // Unfortunately, it doesn't look like the client optimizes this;
1011 // the client seems to always come back and request the Xfer,
1012 // no matter what value m_inventorySerial has.
1013 // FIXME: Could probably be > 0 here rather than > 2
1014 if (m_inventoryFileData.Length > 2) 1256 if (m_inventoryFileData.Length > 2)
1015 { 1257 {
1016 // Add the file for Xfer 1258 m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp";
1017 // m_log.DebugFormat( 1259 m_inventoryFileNameBytes = Util.StringToBytes256(m_inventoryFileName);
1018 // "[PRIM INVENTORY]: Adding inventory file {0} (length {1}) for transfer on {2} {3} {4}",
1019 // m_inventoryFileName, m_inventoryFileData.Length, m_part.Name, m_part.UUID, m_part.LocalId);
1020
1021 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); 1260 xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData);
1261 client.SendTaskInventory(m_part.UUID, (short)m_inventoryFileNameSerial,m_inventoryFileNameBytes);
1262 return;
1022 } 1263 }
1023 1264
1024 // Tell the client we're ready to Xfer the file 1265 client.SendTaskInventory(m_part.UUID, 0, new byte[0]);
1025 client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial,
1026 Util.StringToBytes256(m_inventoryFileName));
1027 } 1266 }
1028 } 1267 }
1029 1268
@@ -1033,67 +1272,80 @@ namespace OpenSim.Region.Framework.Scenes
1033 /// <param name="datastore"></param> 1272 /// <param name="datastore"></param>
1034 public void ProcessInventoryBackup(ISimulationDataService datastore) 1273 public void ProcessInventoryBackup(ISimulationDataService datastore)
1035 { 1274 {
1036 if (HasInventoryChanged) 1275// Removed this because linking will cause an immediate delete of the new
1037 { 1276// child prim from the database and the subsequent storing of the prim sees
1277// the inventory of it as unchanged and doesn't store it at all. The overhead
1278// of storing prim inventory needlessly is much less than the aggravation
1279// of prim inventory loss.
1280// if (HasInventoryChanged)
1281// {
1282 m_items.LockItemsForRead(true);
1283 ICollection<TaskInventoryItem> itemsvalues = m_items.Values;
1038 HasInventoryChanged = false; 1284 HasInventoryChanged = false;
1039 List<TaskInventoryItem> items = GetInventoryItems(); 1285 m_items.LockItemsForRead(false);
1040 datastore.StorePrimInventory(m_part.UUID, items); 1286 try
1041 1287 {
1042 } 1288 datastore.StorePrimInventory(m_part.UUID, itemsvalues);
1289 }
1290 catch {}
1291// }
1043 } 1292 }
1044 1293
1045 public class InventoryStringBuilder 1294 public class InventoryStringBuilder
1046 { 1295 {
1047 public string BuildString = String.Empty; 1296 private StringBuilder BuildString = new StringBuilder(1024);
1048 1297
1049 public InventoryStringBuilder(UUID folderID, UUID parentID) 1298 public InventoryStringBuilder(UUID folderID, UUID parentID)
1050 { 1299 {
1051 BuildString += "\tinv_object\t0\n\t{\n"; 1300 BuildString.Append("\tinv_object\t0\n\t{\n");
1052 AddNameValueLine("obj_id", folderID.ToString()); 1301 AddNameValueLine("obj_id", folderID.ToString());
1053 AddNameValueLine("parent_id", parentID.ToString()); 1302 AddNameValueLine("parent_id", parentID.ToString());
1054 AddNameValueLine("type", "category"); 1303 AddNameValueLine("type", "category");
1055 AddNameValueLine("name", "Contents|"); 1304 AddNameValueLine("name", "Contents|\n\t}");
1056 AddSectionEnd();
1057 } 1305 }
1058 1306
1059 public void AddItemStart() 1307 public void AddItemStart()
1060 { 1308 {
1061 BuildString += "\tinv_item\t0\n"; 1309 BuildString.Append("\tinv_item\t0\n\t{\n");
1062 AddSectionStart();
1063 } 1310 }
1064 1311
1065 public void AddPermissionsStart() 1312 public void AddPermissionsStart()
1066 { 1313 {
1067 BuildString += "\tpermissions 0\n"; 1314 BuildString.Append("\tpermissions 0\n\t{\n");
1068 AddSectionStart();
1069 } 1315 }
1070 1316
1071 public void AddSaleStart() 1317 public void AddSaleStart()
1072 { 1318 {
1073 BuildString += "\tsale_info\t0\n"; 1319 BuildString.Append("\tsale_info\t0\n\t{\n");
1074 AddSectionStart();
1075 } 1320 }
1076 1321
1077 protected void AddSectionStart() 1322 protected void AddSectionStart()
1078 { 1323 {
1079 BuildString += "\t{\n"; 1324 BuildString.Append("\t{\n");
1080 } 1325 }
1081 1326
1082 public void AddSectionEnd() 1327 public void AddSectionEnd()
1083 { 1328 {
1084 BuildString += "\t}\n"; 1329 BuildString.Append("\t}\n");
1085 } 1330 }
1086 1331
1087 public void AddLine(string addLine) 1332 public void AddLine(string addLine)
1088 { 1333 {
1089 BuildString += addLine; 1334 BuildString.Append(addLine);
1090 } 1335 }
1091 1336
1092 public void AddNameValueLine(string name, string value) 1337 public void AddNameValueLine(string name, string value)
1093 { 1338 {
1094 BuildString += "\t\t"; 1339 BuildString.Append("\t\t");
1095 BuildString += name + "\t"; 1340 BuildString.Append(name);
1096 BuildString += value + "\n"; 1341 BuildString.Append("\t");
1342 BuildString.Append(value);
1343 BuildString.Append("\n");
1344 }
1345
1346 public String GetString()
1347 {
1348 return BuildString.ToString();
1097 } 1349 }
1098 1350
1099 public void Close() 1351 public void Close()
@@ -1101,71 +1353,74 @@ namespace OpenSim.Region.Framework.Scenes
1101 } 1353 }
1102 } 1354 }
1103 1355
1356 public void AggregateInnerPerms(ref uint owner, ref uint group, ref uint everyone)
1357 {
1358 foreach (TaskInventoryItem item in m_items.Values)
1359 {
1360 if(item.InvType == (sbyte)InventoryType.Landmark)
1361 continue;
1362 owner &= item.CurrentPermissions;
1363 group &= item.GroupPermissions;
1364 everyone &= item.EveryonePermissions;
1365 }
1366 }
1367
1104 public uint MaskEffectivePermissions() 1368 public uint MaskEffectivePermissions()
1105 { 1369 {
1370 // used to propagate permissions restrictions outwards
1371 // Modify does not propagate outwards.
1106 uint mask=0x7fffffff; 1372 uint mask=0x7fffffff;
1107 1373
1108 lock (m_items) 1374 foreach (TaskInventoryItem item in m_items.Values)
1109 { 1375 {
1110 foreach (TaskInventoryItem item in m_items.Values) 1376 if(item.InvType == (sbyte)InventoryType.Landmark)
1111 { 1377 continue;
1112 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1378
1113 mask &= ~((uint)PermissionMask.Copy >> 13); 1379 // apply current to normal permission bits
1114 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1380 uint newperms = item.CurrentPermissions;
1115 mask &= ~((uint)PermissionMask.Transfer >> 13); 1381
1116 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 1382 if ((newperms & (uint)PermissionMask.Copy) == 0)
1117 mask &= ~((uint)PermissionMask.Modify >> 13); 1383 mask &= ~(uint)PermissionMask.Copy;
1118 1384 if ((newperms & (uint)PermissionMask.Transfer) == 0)
1119 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) 1385 mask &= ~(uint)PermissionMask.Transfer;
1120 mask &= ~(uint)PermissionMask.Copy; 1386 if ((newperms & (uint)PermissionMask.Export) == 0)
1121 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) 1387 mask &= ~((uint)PermissionMask.Export);
1122 mask &= ~(uint)PermissionMask.Transfer; 1388
1123 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) 1389 // apply next owner restricted by current to folded bits
1124 mask &= ~(uint)PermissionMask.Modify; 1390 newperms &= item.NextPermissions;
1125 } 1391
1392 if ((newperms & (uint)PermissionMask.Copy) == 0)
1393 mask &= ~((uint)PermissionMask.FoldedCopy);
1394 if ((newperms & (uint)PermissionMask.Transfer) == 0)
1395 mask &= ~((uint)PermissionMask.FoldedTransfer);
1396 if ((newperms & (uint)PermissionMask.Export) == 0)
1397 mask &= ~((uint)PermissionMask.FoldedExport);
1398
1126 } 1399 }
1127
1128 return mask; 1400 return mask;
1129 } 1401 }
1130 1402
1131 public void ApplyNextOwnerPermissions() 1403 public void ApplyNextOwnerPermissions()
1132 { 1404 {
1133 lock (m_items) 1405 foreach (TaskInventoryItem item in m_items.Values)
1134 { 1406 {
1135 foreach (TaskInventoryItem item in m_items.Values) 1407 item.CurrentPermissions &= item.NextPermissions;
1136 { 1408 item.BasePermissions &= item.NextPermissions;
1137// m_log.DebugFormat ( 1409 item.EveryonePermissions &= item.NextPermissions;
1138// "[SCENE OBJECT PART INVENTORY]: Applying next permissions {0} to {1} in {2} with current {3}, base {4}, everyone {5}", 1410 item.OwnerChanged = true;
1139// item.NextPermissions, item.Name, m_part.Name, item.CurrentPermissions, item.BasePermissions, item.EveryonePermissions); 1411 item.PermsMask = 0;
1140 1412 item.PermsGranter = UUID.Zero;
1141 if (item.InvType == (int)InventoryType.Object)
1142 {
1143 uint perms = item.CurrentPermissions;
1144 PermissionsUtil.ApplyFoldedPermissions(perms, ref perms);
1145 item.CurrentPermissions = perms;
1146 }
1147
1148 item.CurrentPermissions &= item.NextPermissions;
1149 item.BasePermissions &= item.NextPermissions;
1150 item.EveryonePermissions &= item.NextPermissions;
1151 item.OwnerChanged = true;
1152 item.PermsMask = 0;
1153 item.PermsGranter = UUID.Zero;
1154 }
1155 } 1413 }
1156 } 1414 }
1157 1415
1158 public void ApplyGodPermissions(uint perms) 1416 public void ApplyGodPermissions(uint perms)
1159 { 1417 {
1160 lock (m_items) 1418 foreach (TaskInventoryItem item in m_items.Values)
1161 { 1419 {
1162 foreach (TaskInventoryItem item in m_items.Values) 1420 item.CurrentPermissions = perms;
1163 { 1421 item.BasePermissions = perms;
1164 item.CurrentPermissions = perms;
1165 item.BasePermissions = perms;
1166 }
1167 } 1422 }
1168 1423
1169 m_inventorySerial++; 1424 m_inventorySerial++;
1170 HasInventoryChanged = true; 1425 HasInventoryChanged = true;
1171 } 1426 }
@@ -1176,14 +1431,11 @@ namespace OpenSim.Region.Framework.Scenes
1176 /// <returns></returns> 1431 /// <returns></returns>
1177 public bool ContainsScripts() 1432 public bool ContainsScripts()
1178 { 1433 {
1179 lock (m_items) 1434 foreach (TaskInventoryItem item in m_items.Values)
1180 { 1435 {
1181 foreach (TaskInventoryItem item in m_items.Values) 1436 if (item.InvType == (int)InventoryType.LSL)
1182 { 1437 {
1183 if (item.InvType == (int)InventoryType.LSL) 1438 return true;
1184 {
1185 return true;
1186 }
1187 } 1439 }
1188 } 1440 }
1189 1441
@@ -1197,17 +1449,13 @@ namespace OpenSim.Region.Framework.Scenes
1197 public int ScriptCount() 1449 public int ScriptCount()
1198 { 1450 {
1199 int count = 0; 1451 int count = 0;
1200 lock (m_items) 1452 m_items.LockItemsForRead(true);
1453 foreach (TaskInventoryItem item in m_items.Values)
1201 { 1454 {
1202 foreach (TaskInventoryItem item in m_items.Values) 1455 if (item.InvType == (int)InventoryType.LSL)
1203 { 1456 count++;
1204 if (item.InvType == (int)InventoryType.LSL)
1205 {
1206 count++;
1207 }
1208 }
1209 } 1457 }
1210 1458 m_items.LockItemsForRead(false);
1211 return count; 1459 return count;
1212 } 1460 }
1213 /// <summary> 1461 /// <summary>
@@ -1230,9 +1478,7 @@ namespace OpenSim.Region.Framework.Scenes
1230 if (engine != null) 1478 if (engine != null)
1231 { 1479 {
1232 if (engine.GetScriptState(item.ItemID)) 1480 if (engine.GetScriptState(item.ItemID))
1233 {
1234 count++; 1481 count++;
1235 }
1236 } 1482 }
1237 } 1483 }
1238 } 1484 }
@@ -1241,50 +1487,52 @@ namespace OpenSim.Region.Framework.Scenes
1241 1487
1242 public List<UUID> GetInventoryList() 1488 public List<UUID> GetInventoryList()
1243 { 1489 {
1244 List<UUID> ret = new List<UUID>(); 1490 m_items.LockItemsForRead(true);
1245 1491
1246 lock (m_items) 1492 List<UUID> ret = new List<UUID>(m_items.Count);
1247 { 1493 foreach (TaskInventoryItem item in m_items.Values)
1248 foreach (TaskInventoryItem item in m_items.Values) 1494 ret.Add(item.ItemID);
1249 ret.Add(item.ItemID);
1250 }
1251 1495
1496 m_items.LockItemsForRead(false);
1252 return ret; 1497 return ret;
1253 } 1498 }
1254 1499
1255 public List<TaskInventoryItem> GetInventoryItems() 1500 public List<TaskInventoryItem> GetInventoryItems()
1256 { 1501 {
1257 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1502 m_items.LockItemsForRead(true);
1258 1503 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(m_items.Values);
1259 lock (m_items) 1504 m_items.LockItemsForRead(false);
1260 ret = new List<TaskInventoryItem>(m_items.Values);
1261 1505
1262 return ret; 1506 return ret;
1263 } 1507 }
1264 1508
1265 public List<TaskInventoryItem> GetInventoryItems(InventoryType type) 1509 public List<TaskInventoryItem> GetInventoryItems(InventoryType type)
1266 { 1510 {
1267 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); 1511 m_items.LockItemsForRead(true);
1268 1512
1269 lock (m_items) 1513 List<TaskInventoryItem> ret = new List<TaskInventoryItem>(m_items.Count);
1270 { 1514 foreach (TaskInventoryItem item in m_items.Values)
1271 foreach (TaskInventoryItem item in m_items.Values) 1515 if (item.InvType == (int)type)
1272 if (item.InvType == (int)type) 1516 ret.Add(item);
1273 ret.Add(item);
1274 }
1275 1517
1518 m_items.LockItemsForRead(false);
1276 return ret; 1519 return ret;
1277 } 1520 }
1278 1521
1279 public Dictionary<UUID, string> GetScriptStates() 1522 public Dictionary<UUID, string> GetScriptStates()
1280 { 1523 {
1281 Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); 1524 return GetScriptStates(false);
1282 1525 }
1526
1527 public Dictionary<UUID, string> GetScriptStates(bool oldIDs)
1528 {
1529 Dictionary<UUID, string> ret = new Dictionary<UUID, string>();
1530
1283 if (m_part.ParentGroup.Scene == null) // Group not in a scene 1531 if (m_part.ParentGroup.Scene == null) // Group not in a scene
1284 return ret; 1532 return ret;
1285 1533
1286 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); 1534 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();
1287 1535
1288 if (engines.Length == 0) // No engine at all 1536 if (engines.Length == 0) // No engine at all
1289 return ret; 1537 return ret;
1290 1538
@@ -1303,17 +1551,24 @@ namespace OpenSim.Region.Framework.Scenes
1303 string n = e.GetXMLState(item.ItemID); 1551 string n = e.GetXMLState(item.ItemID);
1304 if (n != String.Empty) 1552 if (n != String.Empty)
1305 { 1553 {
1306 if (!ret.ContainsKey(item.ItemID)) 1554 if (oldIDs)
1307 ret[item.ItemID] = n; 1555 {
1556 if (!ret.ContainsKey(item.OldItemID))
1557 ret[item.OldItemID] = n;
1558 }
1559 else
1560 {
1561 if (!ret.ContainsKey(item.ItemID))
1562 ret[item.ItemID] = n;
1563 }
1308 break; 1564 break;
1309 } 1565 }
1310 } 1566 }
1311 } 1567 }
1312 } 1568 }
1313
1314 return ret; 1569 return ret;
1315 } 1570 }
1316 1571
1317 public void ResumeScripts() 1572 public void ResumeScripts()
1318 { 1573 {
1319 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); 1574 IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>();