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.cs727
1 files changed, 417 insertions, 310 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
index 256e3b0..9b16281 100644
--- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs
@@ -47,6 +47,8 @@ namespace OpenSim.Region.Framework.Scenes
47 47
48 private string m_inventoryFileName = String.Empty; 48 private string m_inventoryFileName = String.Empty;
49 private int m_inventoryFileNameSerial = 0; 49 private int m_inventoryFileNameSerial = 0;
50
51 private Dictionary<UUID, ArrayList> m_scriptErrors = new Dictionary<UUID, ArrayList>();
50 52
51 /// <value> 53 /// <value>
52 /// The part to which the inventory belongs. 54 /// The part to which the inventory belongs.
@@ -83,7 +85,9 @@ namespace OpenSim.Region.Framework.Scenes
83 /// </value> 85 /// </value>
84 protected internal TaskInventoryDictionary Items 86 protected internal TaskInventoryDictionary Items
85 { 87 {
86 get { return m_items; } 88 get {
89 return m_items;
90 }
87 set 91 set
88 { 92 {
89 m_items = value; 93 m_items = value;
@@ -119,22 +123,25 @@ namespace OpenSim.Region.Framework.Scenes
119 /// <param name="linkNum">Link number for the part</param> 123 /// <param name="linkNum">Link number for the part</param>
120 public void ResetInventoryIDs() 124 public void ResetInventoryIDs()
121 { 125 {
122 lock (Items) 126 m_items.LockItemsForWrite(true);
127
128 if (0 == Items.Count)
123 { 129 {
124 if (0 == Items.Count) 130 m_items.LockItemsForWrite(false);
125 return; 131 return;
132 }
126 133
127 HasInventoryChanged = true; 134 HasInventoryChanged = true;
128 m_part.ParentGroup.HasGroupChanged = true; 135 m_part.ParentGroup.HasGroupChanged = true;
129 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 136 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
130 Items.Clear(); 137 Items.Clear();
131 138
132 foreach (TaskInventoryItem item in items) 139 foreach (TaskInventoryItem item in items)
133 { 140 {
134 item.ResetIDs(m_part.UUID); 141 item.ResetIDs(m_part.UUID);
135 Items.Add(item.ItemID, item); 142 Items.Add(item.ItemID, item);
136 }
137 } 143 }
144 m_items.LockItemsForWrite(false);
138 } 145 }
139 146
140 /// <summary> 147 /// <summary>
@@ -143,25 +150,25 @@ namespace OpenSim.Region.Framework.Scenes
143 /// <param name="ownerId"></param> 150 /// <param name="ownerId"></param>
144 public void ChangeInventoryOwner(UUID ownerId) 151 public void ChangeInventoryOwner(UUID ownerId)
145 { 152 {
146 lock (Items) 153 m_items.LockItemsForWrite(true);
154 if (0 == Items.Count)
147 { 155 {
148 if (0 == Items.Count) 156 m_items.LockItemsForWrite(false);
149 { 157 return;
150 return; 158 }
151 }
152 159
153 HasInventoryChanged = true; 160 HasInventoryChanged = true;
154 m_part.ParentGroup.HasGroupChanged = true; 161 m_part.ParentGroup.HasGroupChanged = true;
155 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 162 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
156 foreach (TaskInventoryItem item in items) 163 foreach (TaskInventoryItem item in items)
164 {
165 if (ownerId != item.OwnerID)
157 { 166 {
158 if (ownerId != item.OwnerID) 167 item.LastOwnerID = item.OwnerID;
159 { 168 item.OwnerID = ownerId;
160 item.LastOwnerID = item.OwnerID;
161 item.OwnerID = ownerId;
162 }
163 } 169 }
164 } 170 }
171 m_items.LockItemsForWrite(false);
165 } 172 }
166 173
167 /// <summary> 174 /// <summary>
@@ -170,24 +177,24 @@ namespace OpenSim.Region.Framework.Scenes
170 /// <param name="groupID"></param> 177 /// <param name="groupID"></param>
171 public void ChangeInventoryGroup(UUID groupID) 178 public void ChangeInventoryGroup(UUID groupID)
172 { 179 {
173 lock (Items) 180 m_items.LockItemsForWrite(true);
181 if (0 == Items.Count)
174 { 182 {
175 if (0 == Items.Count) 183 m_items.LockItemsForWrite(false);
176 { 184 return;
177 return; 185 }
178 }
179 186
180 HasInventoryChanged = true; 187 HasInventoryChanged = true;
181 m_part.ParentGroup.HasGroupChanged = true; 188 m_part.ParentGroup.HasGroupChanged = true;
182 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); 189 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
183 foreach (TaskInventoryItem item in items) 190 foreach (TaskInventoryItem item in items)
191 {
192 if (groupID != item.GroupID)
184 { 193 {
185 if (groupID != item.GroupID) 194 item.GroupID = groupID;
186 {
187 item.GroupID = groupID;
188 }
189 } 195 }
190 } 196 }
197 m_items.LockItemsForWrite(false);
191 } 198 }
192 199
193 /// <summary> 200 /// <summary>
@@ -195,10 +202,14 @@ namespace OpenSim.Region.Framework.Scenes
195 /// </summary> 202 /// </summary>
196 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) 203 public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource)
197 { 204 {
198 lock (m_items) 205 Items.LockItemsForRead(true);
206 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
207 Items.LockItemsForRead(false);
208 foreach (TaskInventoryItem item in items)
199 { 209 {
200 foreach (TaskInventoryItem item in Items.Values) 210 if ((int)InventoryType.LSL == item.InvType)
201 { 211 {
212 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
202 if ((int)InventoryType.LSL == item.InvType) 213 if ((int)InventoryType.LSL == item.InvType)
203 { 214 {
204 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); 215 CreateScriptInstance(item, startParam, postOnRez, engine, stateSource);
@@ -208,7 +219,7 @@ namespace OpenSim.Region.Framework.Scenes
208 } 219 }
209 } 220 }
210 221
211 public ArrayList GetScriptErrors(UUID itemID) 222 private ArrayList GetScriptErrors(UUID itemID)
212 { 223 {
213 ArrayList ret = new ArrayList(); 224 ArrayList ret = new ArrayList();
214 225
@@ -238,16 +249,20 @@ namespace OpenSim.Region.Framework.Scenes
238 /// </param> 249 /// </param>
239 public void RemoveScriptInstances(bool sceneObjectBeingDeleted) 250 public void RemoveScriptInstances(bool sceneObjectBeingDeleted)
240 { 251 {
241 lock (Items) 252 Items.LockItemsForRead(true);
253 IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values);
254 Items.LockItemsForRead(false);
255
256 foreach (TaskInventoryItem item in items)
242 { 257 {
243 foreach (TaskInventoryItem item in Items.Values) 258 if ((int)InventoryType.LSL == item.InvType)
244 { 259 {
245 if ((int)InventoryType.LSL == item.InvType) 260 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
246 { 261 m_part.RemoveScriptEvents(item.ItemID);
247 RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted);
248 }
249 } 262 }
250 } 263 }
264
265
251 } 266 }
252 267
253 /// <summary> 268 /// <summary>
@@ -263,7 +278,10 @@ namespace OpenSim.Region.Framework.Scenes
263 // item.Name, item.ItemID, m_part.Name, m_part.UUID); 278 // item.Name, item.ItemID, m_part.Name, m_part.UUID);
264 279
265 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) 280 if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID))
281 {
282 StoreScriptError(item.ItemID, "no permission");
266 return; 283 return;
284 }
267 285
268 m_part.AddFlag(PrimFlags.Scripted); 286 m_part.AddFlag(PrimFlags.Scripted);
269 287
@@ -272,49 +290,50 @@ namespace OpenSim.Region.Framework.Scenes
272 if (stateSource == 1 && // Prim crossing 290 if (stateSource == 1 && // Prim crossing
273 m_part.ParentGroup.Scene.m_trustBinaries) 291 m_part.ParentGroup.Scene.m_trustBinaries)
274 { 292 {
275 lock (m_items) 293 m_items.LockItemsForWrite(true);
276 { 294 m_items[item.ItemID].PermsMask = 0;
277 m_items[item.ItemID].PermsMask = 0; 295 m_items[item.ItemID].PermsGranter = UUID.Zero;
278 m_items[item.ItemID].PermsGranter = UUID.Zero; 296 m_items.LockItemsForWrite(false);
279 }
280
281 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 297 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
282 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); 298 m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource);
299 StoreScriptErrors(item.ItemID, null);
283 m_part.ParentGroup.AddActiveScriptCount(1); 300 m_part.ParentGroup.AddActiveScriptCount(1);
284 m_part.ScheduleFullUpdate(); 301 m_part.ScheduleFullUpdate();
285 return; 302 return;
286 } 303 }
287 304
288 m_part.ParentGroup.Scene.AssetService.Get( 305 m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString(), this, delegate(string id, object sender, AssetBase asset)
289 item.AssetID.ToString(), this, delegate(string id, object sender, AssetBase asset) 306 {
290 { 307 if (null == asset)
291 if (null == asset) 308 {
292 { 309 string msg = String.Format("asset ID {0} could not be found", item.AssetID);
293 m_log.ErrorFormat( 310 StoreScriptError(item.ItemID, msg);
294 "[PRIM INVENTORY]: " + 311 m_log.ErrorFormat(
295 "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", 312 "[PRIM INVENTORY]: " +
296 item.Name, item.ItemID, m_part.AbsolutePosition, 313 "Couldn't start script {0}, {1} at {2} in {3} since {4}",
297 m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); 314 item.Name, item.ItemID, m_part.AbsolutePosition,
298 } 315 m_part.ParentGroup.Scene.RegionInfo.RegionName, msg);
299 else 316 }
300 { 317 else
301 lock (m_items) 318 {
302 { 319 if (m_part.ParentGroup.m_savedScriptState != null)
303 if (m_part.ParentGroup.m_savedScriptState != null) 320 RestoreSavedScriptState(item.OldItemID, item.ItemID);
304 RestoreSavedScriptState(item.OldItemID, item.ItemID); 321 m_items.LockItemsForWrite(true);
305 322 m_items[item.ItemID].PermsMask = 0;
306 m_items[item.ItemID].PermsMask = 0; 323 m_items[item.ItemID].PermsGranter = UUID.Zero;
307 m_items[item.ItemID].PermsGranter = UUID.Zero; 324 m_items.LockItemsForWrite(false);
308 325 string script = Utils.BytesToString(asset.Data);
309 string script = Utils.BytesToString(asset.Data); 326 m_part.ParentGroup.Scene.EventManager.TriggerRezScript(
310 m_part.ParentGroup.Scene.EventManager.TriggerRezScript( 327 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource);
311 m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); 328 StoreScriptErrors(item.ItemID, null);
312 m_part.ParentGroup.AddActiveScriptCount(1); 329 m_part.ParentGroup.AddActiveScriptCount(1);
313 m_part.ScheduleFullUpdate(); 330 m_part.ScheduleFullUpdate();
314 } 331 }
315 } 332 });
316 } 333 }
317 ); 334 else
335 {
336 StoreScriptError(item.ItemID, "scripts disabled");
318 } 337 }
319 } 338 }
320 339
@@ -375,27 +394,145 @@ namespace OpenSim.Region.Framework.Scenes
375 394
376 /// <summary> 395 /// <summary>
377 /// Start a script which is in this prim's inventory. 396 /// Start a script which is in this prim's inventory.
397 /// Some processing may occur in the background, but this routine returns asap.
378 /// </summary> 398 /// </summary>
379 /// <param name="itemId"> 399 /// <param name="itemId">
380 /// A <see cref="UUID"/> 400 /// A <see cref="UUID"/>
381 /// </param> 401 /// </param>
382 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) 402 public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
383 { 403 {
384 lock (m_items) 404 lock (m_scriptErrors)
405 {
406 // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion
407 m_scriptErrors.Remove(itemId);
408 }
409 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
410 }
411
412 private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
413 {
414 m_items.LockItemsForRead(true);
415 if (m_items.ContainsKey(itemId))
385 { 416 {
386 if (m_items.ContainsKey(itemId)) 417 if (m_items.ContainsKey(itemId))
387 { 418 {
419 m_items.LockItemsForRead(false);
388 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); 420 CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource);
389 } 421 }
390 else 422 else
391 { 423 {
424 m_items.LockItemsForRead(false);
425 string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID,
426 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
427 StoreScriptError(itemId, msg);
392 m_log.ErrorFormat( 428 m_log.ErrorFormat(
393 "[PRIM INVENTORY]: " + 429 "[PRIM INVENTORY]: " +
394 "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", 430 "Couldn't start script with ID {0} since it {1}", itemId, msg);
395 itemId, m_part.Name, m_part.UUID, 431 }
396 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); 432 }
433 else
434 {
435 m_items.LockItemsForRead(false);
436 string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID);
437 StoreScriptError(itemId, msg);
438 m_log.ErrorFormat(
439 "[PRIM INVENTORY]: " +
440 "Couldn't start script with ID {0} since it {1}", itemId, msg);
441 }
442
443 }
444
445 /// <summary>
446 /// Start a script which is in this prim's inventory and return any compilation error messages.
447 /// </summary>
448 /// <param name="itemId">
449 /// A <see cref="UUID"/>
450 /// </param>
451 public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource)
452 {
453 ArrayList errors;
454
455 // Indicate to CreateScriptInstanceInternal() we want it to
456 // post any compilation/loading error messages
457 lock (m_scriptErrors)
458 {
459 m_scriptErrors[itemId] = null;
460 }
461
462 // Perform compilation/loading
463 CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource);
464
465 // Wait for and retrieve any errors
466 lock (m_scriptErrors)
467 {
468 while ((errors = m_scriptErrors[itemId]) == null)
469 {
470 if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000))
471 {
472 m_log.ErrorFormat(
473 "[PRIM INVENTORY]: " +
474 "timedout waiting for script {0} errors", itemId);
475 errors = m_scriptErrors[itemId];
476 if (errors == null)
477 {
478 errors = new ArrayList(1);
479 errors.Add("timedout waiting for errors");
480 }
481 break;
482 }
397 } 483 }
484 m_scriptErrors.Remove(itemId);
398 } 485 }
486 return errors;
487 }
488
489 // Signal to CreateScriptInstanceEr() that compilation/loading is complete
490 private void StoreScriptErrors(UUID itemId, ArrayList errors)
491 {
492 lock (m_scriptErrors)
493 {
494 // If compilation/loading initiated via CreateScriptInstance(),
495 // it does not want the errors, so just get out
496 if (!m_scriptErrors.ContainsKey(itemId))
497 {
498 return;
499 }
500
501 // Initiated via CreateScriptInstanceEr(), if we know what the
502 // errors are, save them and wake CreateScriptInstanceEr().
503 if (errors != null)
504 {
505 m_scriptErrors[itemId] = errors;
506 System.Threading.Monitor.PulseAll(m_scriptErrors);
507 return;
508 }
509 }
510
511 // Initiated via CreateScriptInstanceEr() but we don't know what
512 // the errors are yet, so retrieve them from the script engine.
513 // This may involve some waiting internal to GetScriptErrors().
514 errors = GetScriptErrors(itemId);
515
516 // Get a default non-null value to indicate success.
517 if (errors == null)
518 {
519 errors = new ArrayList();
520 }
521
522 // Post to CreateScriptInstanceEr() and wake it up
523 lock (m_scriptErrors)
524 {
525 m_scriptErrors[itemId] = errors;
526 System.Threading.Monitor.PulseAll(m_scriptErrors);
527 }
528 }
529
530 // Like StoreScriptErrors(), but just posts a single string message
531 private void StoreScriptError(UUID itemId, string message)
532 {
533 ArrayList errors = new ArrayList(1);
534 errors.Add(message);
535 StoreScriptErrors(itemId, errors);
399 } 536 }
400 537
401 /// <summary> 538 /// <summary>
@@ -408,15 +545,7 @@ namespace OpenSim.Region.Framework.Scenes
408 /// </param> 545 /// </param>
409 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) 546 public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted)
410 { 547 {
411 bool scriptPresent = false; 548 if (m_items.ContainsKey(itemId))
412
413 lock (m_items)
414 {
415 if (m_items.ContainsKey(itemId))
416 scriptPresent = true;
417 }
418
419 if (scriptPresent)
420 { 549 {
421 if (!sceneObjectBeingDeleted) 550 if (!sceneObjectBeingDeleted)
422 m_part.RemoveScriptEvents(itemId); 551 m_part.RemoveScriptEvents(itemId);
@@ -442,11 +571,16 @@ namespace OpenSim.Region.Framework.Scenes
442 /// <returns></returns> 571 /// <returns></returns>
443 private bool InventoryContainsName(string name) 572 private bool InventoryContainsName(string name)
444 { 573 {
445 foreach (TaskInventoryItem item in Items.Values) 574 m_items.LockItemsForRead(true);
575 foreach (TaskInventoryItem item in m_items.Values)
446 { 576 {
447 if (item.Name == name) 577 if (item.Name == name)
578 {
579 m_items.LockItemsForRead(false);
448 return true; 580 return true;
581 }
449 } 582 }
583 m_items.LockItemsForRead(false);
450 return false; 584 return false;
451 } 585 }
452 586
@@ -488,13 +622,9 @@ namespace OpenSim.Region.Framework.Scenes
488 /// <param name="item"></param> 622 /// <param name="item"></param>
489 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) 623 public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop)
490 { 624 {
491 List<TaskInventoryItem> il; 625 m_items.LockItemsForRead(true);
492 626 List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values);
493 lock (m_items) 627 m_items.LockItemsForRead(false);
494 {
495 il = new List<TaskInventoryItem>(m_items.Values);
496 }
497
498 foreach (TaskInventoryItem i in il) 628 foreach (TaskInventoryItem i in il)
499 { 629 {
500 if (i.Name == item.Name) 630 if (i.Name == item.Name)
@@ -532,15 +662,14 @@ namespace OpenSim.Region.Framework.Scenes
532 item.Name = name; 662 item.Name = name;
533 item.GroupID = m_part.GroupID; 663 item.GroupID = m_part.GroupID;
534 664
535 lock (m_items) 665 m_items.LockItemsForWrite(true);
536 { 666 m_items.Add(item.ItemID, item);
537 m_items.Add(item.ItemID, item); 667 m_items.LockItemsForWrite(false);
538
539 if (allowedDrop) 668 if (allowedDrop)
540 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); 669 m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP);
541 else 670 else
542 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 671 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
543 } 672
544 673
545 m_inventorySerial++; 674 m_inventorySerial++;
546 //m_inventorySerial += 2; 675 //m_inventorySerial += 2;
@@ -557,14 +686,13 @@ namespace OpenSim.Region.Framework.Scenes
557 /// <param name="items"></param> 686 /// <param name="items"></param>
558 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) 687 public void RestoreInventoryItems(ICollection<TaskInventoryItem> items)
559 { 688 {
560 lock (m_items) 689 m_items.LockItemsForWrite(true);
690 foreach (TaskInventoryItem item in items)
561 { 691 {
562 foreach (TaskInventoryItem item in items) 692 m_items.Add(item.ItemID, item);
563 { 693 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
564 m_items.Add(item.ItemID, item);
565 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
566 }
567 } 694 }
695 m_items.LockItemsForWrite(false);
568 696
569 m_inventorySerial++; 697 m_inventorySerial++;
570 } 698 }
@@ -577,10 +705,9 @@ namespace OpenSim.Region.Framework.Scenes
577 public TaskInventoryItem GetInventoryItem(UUID itemId) 705 public TaskInventoryItem GetInventoryItem(UUID itemId)
578 { 706 {
579 TaskInventoryItem item; 707 TaskInventoryItem item;
580 708 m_items.LockItemsForRead(true);
581 lock (m_items) 709 m_items.TryGetValue(itemId, out item);
582 m_items.TryGetValue(itemId, out item); 710 m_items.LockItemsForRead(false);
583
584 return item; 711 return item;
585 } 712 }
586 713
@@ -616,51 +743,51 @@ namespace OpenSim.Region.Framework.Scenes
616 /// <returns>false if the item did not exist, true if the update occurred successfully</returns> 743 /// <returns>false if the item did not exist, true if the update occurred successfully</returns>
617 public bool UpdateInventoryItem(TaskInventoryItem item) 744 public bool UpdateInventoryItem(TaskInventoryItem item)
618 { 745 {
619 lock (m_items) 746 m_items.LockItemsForWrite(true);
747
748 if (m_items.ContainsKey(item.ItemID))
620 { 749 {
621 if (m_items.ContainsKey(item.ItemID)) 750 item.ParentID = m_part.UUID;
751 item.ParentPartID = m_part.UUID;
752 item.Flags = m_items[item.ItemID].Flags;
753 // If group permissions have been set on, check that the groupID is up to date in case it has
754 // changed since permissions were last set.
755 if (item.GroupPermissions != (uint)PermissionMask.None)
756 item.GroupID = m_part.GroupID;
757
758 if (item.AssetID == UUID.Zero)
622 { 759 {
623 item.ParentID = m_part.UUID; 760 item.AssetID = m_items[item.ItemID].AssetID;
624 item.ParentPartID = m_part.UUID; 761 }
625 item.Flags = m_items[item.ItemID].Flags; 762 else if ((InventoryType)item.Type == InventoryType.Notecard)
626 763 {
627 // If group permissions have been set on, check that the groupID is up to date in case it has 764 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
628 // changed since permissions were last set.
629 if (item.GroupPermissions != (uint)PermissionMask.None)
630 item.GroupID = m_part.GroupID;
631
632 if (item.AssetID == UUID.Zero)
633 {
634 item.AssetID = m_items[item.ItemID].AssetID;
635 }
636 else if ((InventoryType)item.Type == InventoryType.Notecard)
637 {
638 ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID);
639 765
640 if (presence != null) 766 if (presence != null)
641 { 767 {
642 presence.ControllingClient.SendAgentAlertMessage( 768 presence.ControllingClient.SendAgentAlertMessage(
643 "Notecard saved", false); 769 "Notecard saved", false);
644 }
645 } 770 }
771 }
646 772
647 m_items[item.ItemID] = item; 773 m_items[item.ItemID] = item;
648 m_inventorySerial++; 774 m_inventorySerial++;
649 m_part.TriggerScriptChangedEvent(Changed.INVENTORY); 775 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
650 HasInventoryChanged = true;
651 m_part.ParentGroup.HasGroupChanged = true;
652 776
653 return true; 777 HasInventoryChanged = true;
654 } 778 m_part.ParentGroup.HasGroupChanged = true;
655 else 779 m_items.LockItemsForWrite(false);
656 { 780 return true;
657 m_log.ErrorFormat(
658 "[PRIM INVENTORY]: " +
659 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
660 item.ItemID, m_part.Name, m_part.UUID,
661 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
662 }
663 } 781 }
782 else
783 {
784 m_log.ErrorFormat(
785 "[PRIM INVENTORY]: " +
786 "Tried to retrieve item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
787 item.ItemID, m_part.Name, m_part.UUID,
788 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
789 }
790 m_items.LockItemsForWrite(false);
664 791
665 return false; 792 return false;
666 } 793 }
@@ -673,53 +800,54 @@ namespace OpenSim.Region.Framework.Scenes
673 /// in this prim's inventory.</returns> 800 /// in this prim's inventory.</returns>
674 public int RemoveInventoryItem(UUID itemID) 801 public int RemoveInventoryItem(UUID itemID)
675 { 802 {
676 lock (m_items) 803 m_items.LockItemsForRead(true);
804
805 if (m_items.ContainsKey(itemID))
677 { 806 {
678 if (m_items.ContainsKey(itemID)) 807 int type = m_items[itemID].InvType;
808 m_items.LockItemsForRead(false);
809 if (type == 10) // Script
679 { 810 {
680 int type = m_items[itemID].InvType; 811 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID);
681 if (type == 10) // Script 812 }
682 { 813 m_items.LockItemsForWrite(true);
683 m_part.RemoveScriptEvents(itemID); 814 m_items.Remove(itemID);
684 m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); 815 m_items.LockItemsForWrite(false);
685 } 816 m_inventorySerial++;
686 m_items.Remove(itemID); 817 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
687 m_inventorySerial++;
688 m_part.TriggerScriptChangedEvent(Changed.INVENTORY);
689
690 HasInventoryChanged = true;
691 m_part.ParentGroup.HasGroupChanged = true;
692 818
693 int scriptcount = 0; 819 HasInventoryChanged = true;
694 lock (m_items) 820 m_part.ParentGroup.HasGroupChanged = true;
695 {
696 foreach (TaskInventoryItem item in m_items.Values)
697 {
698 if (item.Type == 10)
699 {
700 scriptcount++;
701 }
702 }
703 }
704 821
705 if (scriptcount <= 0) 822 int scriptcount = 0;
823 m_items.LockItemsForRead(true);
824 foreach (TaskInventoryItem item in m_items.Values)
825 {
826 if (item.Type == 10)
706 { 827 {
707 m_part.RemFlag(PrimFlags.Scripted); 828 scriptcount++;
708 } 829 }
709
710 m_part.ScheduleFullUpdate();
711
712 return type;
713 } 830 }
714 else 831 m_items.LockItemsForRead(false);
832
833
834 if (scriptcount <= 0)
715 { 835 {
716 m_log.ErrorFormat( 836 m_part.RemFlag(PrimFlags.Scripted);
717 "[PRIM INVENTORY]: " +
718 "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory",
719 itemID, m_part.Name, m_part.UUID,
720 m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName);
721 } 837 }
838
839 m_part.ScheduleFullUpdate();
840
841 return type;
842 }
843 else
844 {
845 m_log.ErrorFormat(
846 "[PRIM INVENTORY]: " +
847 "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory",
848 itemID, m_part.Name, m_part.UUID);
722 } 849 }
850 m_items.LockItemsForWrite(false);
723 851
724 return -1; 852 return -1;
725 } 853 }
@@ -772,53 +900,54 @@ namespace OpenSim.Region.Framework.Scenes
772 // isn't available (such as drag from prim inventory to agent inventory) 900 // isn't available (such as drag from prim inventory to agent inventory)
773 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); 901 InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero);
774 902
775 lock (m_items) 903 m_items.LockItemsForRead(true);
904
905 foreach (TaskInventoryItem item in m_items.Values)
776 { 906 {
777 foreach (TaskInventoryItem item in m_items.Values) 907 UUID ownerID = item.OwnerID;
778 { 908 uint everyoneMask = 0;
779 UUID ownerID = item.OwnerID; 909 uint baseMask = item.BasePermissions;
780 uint everyoneMask = 0; 910 uint ownerMask = item.CurrentPermissions;
781 uint baseMask = item.BasePermissions; 911 uint groupMask = item.GroupPermissions;
782 uint ownerMask = item.CurrentPermissions;
783 uint groupMask = item.GroupPermissions;
784 912
785 invString.AddItemStart(); 913 invString.AddItemStart();
786 invString.AddNameValueLine("item_id", item.ItemID.ToString()); 914 invString.AddNameValueLine("item_id", item.ItemID.ToString());
787 invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); 915 invString.AddNameValueLine("parent_id", m_part.UUID.ToString());
788 916
789 invString.AddPermissionsStart(); 917 invString.AddPermissionsStart();
790 918
791 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); 919 invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask));
792 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); 920 invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask));
793 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); 921 invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask));
794 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); 922 invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask));
795 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); 923 invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions));
796 924
797 invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); 925 invString.AddNameValueLine("creator_id", item.CreatorID.ToString());
798 invString.AddNameValueLine("owner_id", ownerID.ToString()); 926 invString.AddNameValueLine("owner_id", ownerID.ToString());
799 927
800 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); 928 invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString());
801 929
802 invString.AddNameValueLine("group_id", item.GroupID.ToString()); 930 invString.AddNameValueLine("group_id", item.GroupID.ToString());
803 invString.AddSectionEnd(); 931 invString.AddSectionEnd();
804 932
805 invString.AddNameValueLine("asset_id", item.AssetID.ToString()); 933 invString.AddNameValueLine("asset_id", item.AssetID.ToString());
806 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); 934 invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]);
807 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); 935 invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]);
808 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); 936 invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags));
809 937
810 invString.AddSaleStart(); 938 invString.AddSaleStart();
811 invString.AddNameValueLine("sale_type", "not"); 939 invString.AddNameValueLine("sale_type", "not");
812 invString.AddNameValueLine("sale_price", "0"); 940 invString.AddNameValueLine("sale_price", "0");
813 invString.AddSectionEnd(); 941 invString.AddSectionEnd();
814 942
815 invString.AddNameValueLine("name", item.Name + "|"); 943 invString.AddNameValueLine("name", item.Name + "|");
816 invString.AddNameValueLine("desc", item.Description + "|"); 944 invString.AddNameValueLine("desc", item.Description + "|");
817 945
818 invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); 946 invString.AddNameValueLine("creation_date", item.CreationDate.ToString());
819 invString.AddSectionEnd(); 947 invString.AddSectionEnd();
820 }
821 } 948 }
949 int count = m_items.Count;
950 m_items.LockItemsForRead(false);
822 951
823 fileData = Utils.StringToBytes(invString.BuildString); 952 fileData = Utils.StringToBytes(invString.BuildString);
824 953
@@ -839,10 +968,9 @@ namespace OpenSim.Region.Framework.Scenes
839 { 968 {
840 if (HasInventoryChanged) 969 if (HasInventoryChanged)
841 { 970 {
842 lock (Items) 971 Items.LockItemsForRead(true);
843 { 972 datastore.StorePrimInventory(m_part.UUID, Items.Values);
844 datastore.StorePrimInventory(m_part.UUID, Items.Values); 973 Items.LockItemsForRead(false);
845 }
846 974
847 HasInventoryChanged = false; 975 HasInventoryChanged = false;
848 } 976 }
@@ -911,61 +1039,54 @@ namespace OpenSim.Region.Framework.Scenes
911 { 1039 {
912 uint mask=0x7fffffff; 1040 uint mask=0x7fffffff;
913 1041
914 lock (m_items) 1042 foreach (TaskInventoryItem item in m_items.Values)
915 { 1043 {
916 foreach (TaskInventoryItem item in m_items.Values) 1044 if (item.InvType != (int)InventoryType.Object)
917 { 1045 {
918 if (item.InvType != (int)InventoryType.Object) 1046 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0)
919 { 1047 mask &= ~((uint)PermissionMask.Copy >> 13);
920 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) 1048 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0)
921 mask &= ~((uint)PermissionMask.Copy >> 13); 1049 mask &= ~((uint)PermissionMask.Transfer >> 13);
922 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) 1050 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0)
923 mask &= ~((uint)PermissionMask.Transfer >> 13); 1051 mask &= ~((uint)PermissionMask.Modify >> 13);
924 if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) 1052 }
925 mask &= ~((uint)PermissionMask.Modify >> 13); 1053 else
926 } 1054 {
927 else 1055 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
928 { 1056 mask &= ~((uint)PermissionMask.Copy >> 13);
929 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1057 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
930 mask &= ~((uint)PermissionMask.Copy >> 13); 1058 mask &= ~((uint)PermissionMask.Transfer >> 13);
931 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1059 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
932 mask &= ~((uint)PermissionMask.Transfer >> 13); 1060 mask &= ~((uint)PermissionMask.Modify >> 13);
933 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
934 mask &= ~((uint)PermissionMask.Modify >> 13);
935 }
936
937 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
938 mask &= ~(uint)PermissionMask.Copy;
939 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
940 mask &= ~(uint)PermissionMask.Transfer;
941 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
942 mask &= ~(uint)PermissionMask.Modify;
943 } 1061 }
1062
1063 if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0)
1064 mask &= ~(uint)PermissionMask.Copy;
1065 if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0)
1066 mask &= ~(uint)PermissionMask.Transfer;
1067 if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0)
1068 mask &= ~(uint)PermissionMask.Modify;
944 } 1069 }
945
946 return mask; 1070 return mask;
947 } 1071 }
948 1072
949 public void ApplyNextOwnerPermissions() 1073 public void ApplyNextOwnerPermissions()
950 { 1074 {
951 lock (m_items) 1075 foreach (TaskInventoryItem item in m_items.Values)
952 { 1076 {
953 foreach (TaskInventoryItem item in m_items.Values) 1077 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0)
954 { 1078 {
955 if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) 1079 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0)
956 { 1080 item.CurrentPermissions &= ~(uint)PermissionMask.Copy;
957 if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) 1081 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0)
958 item.CurrentPermissions &= ~(uint)PermissionMask.Copy; 1082 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer;
959 if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) 1083 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0)
960 item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; 1084 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
961 if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) 1085 item.CurrentPermissions |= 8;
962 item.CurrentPermissions &= ~(uint)PermissionMask.Modify;
963 item.CurrentPermissions |= 8;
964 }
965 item.CurrentPermissions &= item.NextPermissions;
966 item.BasePermissions &= item.NextPermissions;
967 item.EveryonePermissions &= item.NextPermissions;
968 } 1086 }
1087 item.CurrentPermissions &= item.NextPermissions;
1088 item.BasePermissions &= item.NextPermissions;
1089 item.EveryonePermissions &= item.NextPermissions;
969 } 1090 }
970 1091
971 m_part.TriggerScriptChangedEvent(Changed.OWNER); 1092 m_part.TriggerScriptChangedEvent(Changed.OWNER);
@@ -973,29 +1094,22 @@ namespace OpenSim.Region.Framework.Scenes
973 1094
974 public void ApplyGodPermissions(uint perms) 1095 public void ApplyGodPermissions(uint perms)
975 { 1096 {
976 lock (m_items) 1097 foreach (TaskInventoryItem item in m_items.Values)
977 { 1098 {
978 foreach (TaskInventoryItem item in m_items.Values) 1099 item.CurrentPermissions = perms;
979 { 1100 item.BasePermissions = perms;
980 item.CurrentPermissions = perms;
981 item.BasePermissions = perms;
982 }
983 } 1101 }
984 } 1102 }
985 1103
986 public bool ContainsScripts() 1104 public bool ContainsScripts()
987 { 1105 {
988 lock (m_items) 1106 foreach (TaskInventoryItem item in m_items.Values)
989 { 1107 {
990 foreach (TaskInventoryItem item in m_items.Values) 1108 if (item.InvType == (int)InventoryType.LSL)
991 { 1109 {
992 if (item.InvType == (int)InventoryType.LSL) 1110 return true;
993 {
994 return true;
995 }
996 } 1111 }
997 } 1112 }
998
999 return false; 1113 return false;
1000 } 1114 }
1001 1115
@@ -1003,11 +1117,8 @@ namespace OpenSim.Region.Framework.Scenes
1003 { 1117 {
1004 List<UUID> ret = new List<UUID>(); 1118 List<UUID> ret = new List<UUID>();
1005 1119
1006 lock (m_items) 1120 foreach (TaskInventoryItem item in m_items.Values)
1007 { 1121 ret.Add(item.ItemID);
1008 foreach (TaskInventoryItem item in m_items.Values)
1009 ret.Add(item.ItemID);
1010 }
1011 1122
1012 return ret; 1123 return ret;
1013 } 1124 }
@@ -1020,30 +1131,26 @@ namespace OpenSim.Region.Framework.Scenes
1020 if (engines == null) // No engine at all 1131 if (engines == null) // No engine at all
1021 return ret; 1132 return ret;
1022 1133
1023 lock (m_items) 1134 foreach (TaskInventoryItem item in m_items.Values)
1024 { 1135 {
1025 foreach (TaskInventoryItem item in m_items.Values) 1136 if (item.InvType == (int)InventoryType.LSL)
1026 { 1137 {
1027 if (item.InvType == (int)InventoryType.LSL) 1138 foreach (IScriptModule e in engines)
1028 { 1139 {
1029 foreach (IScriptModule e in engines) 1140 if (e != null)
1030 { 1141 {
1031 if (e != null) 1142 string n = e.GetXMLState(item.ItemID);
1143 if (n != String.Empty)
1032 { 1144 {
1033 string n = e.GetXMLState(item.ItemID); 1145 if (!ret.ContainsKey(item.ItemID))
1034 if (n != String.Empty) 1146 ret[item.ItemID] = n;
1035 { 1147 break;
1036 if (!ret.ContainsKey(item.ItemID))
1037 ret[item.ItemID] = n;
1038 break;
1039 }
1040 } 1148 }
1041 } 1149 }
1042 } 1150 }
1043 } 1151 }
1044 } 1152 }
1045
1046 return ret; 1153 return ret;
1047 } 1154 }
1048 } 1155 }
1049} \ No newline at end of file 1156}