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