diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 550 |
1 files changed, 359 insertions, 191 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index e08fa77..10931b7 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 (m_items) | 126 | m_items.LockItemsForWrite(true); |
127 | |||
128 | if (0 == Items.Count) | ||
123 | { | 129 | { |
124 | if (0 == m_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 = GetInventoryItems(); | 136 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
130 | m_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 | m_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,12 +150,11 @@ 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; | ||
151 | } | ||
152 | } | 158 | } |
153 | 159 | ||
154 | HasInventoryChanged = true; | 160 | HasInventoryChanged = true; |
@@ -162,6 +168,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
162 | item.OwnerID = ownerId; | 168 | item.OwnerID = ownerId; |
163 | } | 169 | } |
164 | } | 170 | } |
171 | m_items.LockItemsForWrite(false); | ||
165 | } | 172 | } |
166 | 173 | ||
167 | /// <summary> | 174 | /// <summary> |
@@ -170,22 +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; | ||
178 | } | ||
179 | } | 185 | } |
180 | 186 | ||
181 | HasInventoryChanged = true; | 187 | HasInventoryChanged = true; |
182 | m_part.ParentGroup.HasGroupChanged = true; | 188 | m_part.ParentGroup.HasGroupChanged = true; |
183 | List<TaskInventoryItem> items = GetInventoryItems(); | 189 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
184 | foreach (TaskInventoryItem item in items) | 190 | foreach (TaskInventoryItem item in items) |
185 | { | 191 | { |
186 | if (groupID != item.GroupID) | 192 | if (groupID != item.GroupID) |
193 | { | ||
187 | item.GroupID = groupID; | 194 | item.GroupID = groupID; |
195 | } | ||
188 | } | 196 | } |
197 | m_items.LockItemsForWrite(false); | ||
189 | } | 198 | } |
190 | 199 | ||
191 | /// <summary> | 200 | /// <summary> |
@@ -193,9 +202,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
193 | /// </summary> | 202 | /// </summary> |
194 | public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) | 203 | public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) |
195 | { | 204 | { |
196 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | 205 | Items.LockItemsForRead(true); |
197 | foreach (TaskInventoryItem item in scripts) | 206 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
198 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | 207 | Items.LockItemsForRead(false); |
208 | foreach (TaskInventoryItem item in items) | ||
209 | { | ||
210 | if ((int)InventoryType.LSL == item.InvType) | ||
211 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | ||
212 | } | ||
199 | } | 213 | } |
200 | 214 | ||
201 | public ArrayList GetScriptErrors(UUID itemID) | 215 | public ArrayList GetScriptErrors(UUID itemID) |
@@ -228,9 +242,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
228 | /// </param> | 242 | /// </param> |
229 | public void RemoveScriptInstances(bool sceneObjectBeingDeleted) | 243 | public void RemoveScriptInstances(bool sceneObjectBeingDeleted) |
230 | { | 244 | { |
231 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | 245 | Items.LockItemsForRead(true); |
232 | foreach (TaskInventoryItem item in scripts) | 246 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
233 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); | 247 | Items.LockItemsForRead(false); |
248 | |||
249 | foreach (TaskInventoryItem item in items) | ||
250 | { | ||
251 | if ((int)InventoryType.LSL == item.InvType) | ||
252 | { | ||
253 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); | ||
254 | m_part.RemoveScriptEvents(item.ItemID); | ||
255 | } | ||
256 | } | ||
234 | } | 257 | } |
235 | 258 | ||
236 | /// <summary> | 259 | /// <summary> |
@@ -246,7 +269,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
246 | // item.Name, item.ItemID, Name, UUID); | 269 | // item.Name, item.ItemID, Name, UUID); |
247 | 270 | ||
248 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) | 271 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) |
272 | { | ||
273 | StoreScriptError(item.ItemID, "no permission"); | ||
249 | return; | 274 | return; |
275 | } | ||
250 | 276 | ||
251 | m_part.AddFlag(PrimFlags.Scripted); | 277 | m_part.AddFlag(PrimFlags.Scripted); |
252 | 278 | ||
@@ -255,14 +281,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
255 | if (stateSource == 1 && // Prim crossing | 281 | if (stateSource == 1 && // Prim crossing |
256 | m_part.ParentGroup.Scene.m_trustBinaries) | 282 | m_part.ParentGroup.Scene.m_trustBinaries) |
257 | { | 283 | { |
258 | lock (m_items) | 284 | m_items.LockItemsForWrite(true); |
259 | { | 285 | m_items[item.ItemID].PermsMask = 0; |
260 | m_items[item.ItemID].PermsMask = 0; | 286 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
261 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 287 | m_items.LockItemsForWrite(false); |
262 | } | ||
263 | |||
264 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 288 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
265 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); | 289 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); |
290 | StoreScriptErrors(item.ItemID, null); | ||
266 | m_part.ParentGroup.AddActiveScriptCount(1); | 291 | m_part.ParentGroup.AddActiveScriptCount(1); |
267 | m_part.ScheduleFullUpdate(); | 292 | m_part.ScheduleFullUpdate(); |
268 | return; | 293 | return; |
@@ -271,6 +296,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
271 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); | 296 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); |
272 | if (null == asset) | 297 | if (null == asset) |
273 | { | 298 | { |
299 | string msg = String.Format("asset ID {0} could not be found", item.AssetID); | ||
300 | StoreScriptError(item.ItemID, msg); | ||
274 | m_log.ErrorFormat( | 301 | m_log.ErrorFormat( |
275 | "[PRIM INVENTORY]: " + | 302 | "[PRIM INVENTORY]: " + |
276 | "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", | 303 | "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", |
@@ -282,15 +309,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
282 | if (m_part.ParentGroup.m_savedScriptState != null) | 309 | if (m_part.ParentGroup.m_savedScriptState != null) |
283 | RestoreSavedScriptState(item.OldItemID, item.ItemID); | 310 | RestoreSavedScriptState(item.OldItemID, item.ItemID); |
284 | 311 | ||
285 | lock (m_items) | 312 | m_items.LockItemsForWrite(true); |
286 | { | 313 | |
287 | m_items[item.ItemID].PermsMask = 0; | 314 | m_items[item.ItemID].PermsMask = 0; |
288 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 315 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
289 | } | 316 | |
317 | m_items.LockItemsForWrite(false); | ||
290 | 318 | ||
291 | string script = Utils.BytesToString(asset.Data); | 319 | string script = Utils.BytesToString(asset.Data); |
292 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 320 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
293 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); | 321 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); |
322 | StoreScriptErrors(item.ItemID, null); | ||
294 | m_part.ParentGroup.AddActiveScriptCount(1); | 323 | m_part.ParentGroup.AddActiveScriptCount(1); |
295 | m_part.ScheduleFullUpdate(); | 324 | m_part.ScheduleFullUpdate(); |
296 | } | 325 | } |
@@ -354,21 +383,145 @@ namespace OpenSim.Region.Framework.Scenes | |||
354 | 383 | ||
355 | /// <summary> | 384 | /// <summary> |
356 | /// Start a script which is in this prim's inventory. | 385 | /// Start a script which is in this prim's inventory. |
386 | /// Some processing may occur in the background, but this routine returns asap. | ||
357 | /// </summary> | 387 | /// </summary> |
358 | /// <param name="itemId"> | 388 | /// <param name="itemId"> |
359 | /// A <see cref="UUID"/> | 389 | /// A <see cref="UUID"/> |
360 | /// </param> | 390 | /// </param> |
361 | public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | 391 | public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) |
362 | { | 392 | { |
363 | TaskInventoryItem item = GetInventoryItem(itemId); | 393 | lock (m_scriptErrors) |
364 | if (item != null) | 394 | { |
365 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | 395 | // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion |
396 | m_scriptErrors.Remove(itemId); | ||
397 | } | ||
398 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
399 | } | ||
400 | |||
401 | private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
402 | { | ||
403 | m_items.LockItemsForRead(true); | ||
404 | if (m_items.ContainsKey(itemId)) | ||
405 | { | ||
406 | if (m_items.ContainsKey(itemId)) | ||
407 | { | ||
408 | m_items.LockItemsForRead(false); | ||
409 | CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); | ||
410 | } | ||
411 | else | ||
412 | { | ||
413 | m_items.LockItemsForRead(false); | ||
414 | string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID, | ||
415 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
416 | StoreScriptError(itemId, msg); | ||
417 | m_log.ErrorFormat( | ||
418 | "[PRIM INVENTORY]: " + | ||
419 | "Couldn't start script with ID {0} since it {1}", itemId, msg); | ||
420 | } | ||
421 | } | ||
366 | else | 422 | else |
423 | { | ||
424 | m_items.LockItemsForRead(false); | ||
425 | string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID); | ||
426 | StoreScriptError(itemId, msg); | ||
367 | m_log.ErrorFormat( | 427 | m_log.ErrorFormat( |
368 | "[PRIM INVENTORY]: " + | 428 | "[PRIM INVENTORY]: " + |
369 | "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", | 429 | "Couldn't start script with ID {0} since it {1}", itemId, msg); |
370 | itemId, m_part.Name, m_part.UUID, | 430 | } |
371 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 431 | |
432 | } | ||
433 | |||
434 | /// <summary> | ||
435 | /// Start a script which is in this prim's inventory and return any compilation error messages. | ||
436 | /// </summary> | ||
437 | /// <param name="itemId"> | ||
438 | /// A <see cref="UUID"/> | ||
439 | /// </param> | ||
440 | public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
441 | { | ||
442 | ArrayList errors; | ||
443 | |||
444 | // Indicate to CreateScriptInstanceInternal() we want it to | ||
445 | // post any compilation/loading error messages | ||
446 | lock (m_scriptErrors) | ||
447 | { | ||
448 | m_scriptErrors[itemId] = null; | ||
449 | } | ||
450 | |||
451 | // Perform compilation/loading | ||
452 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
453 | |||
454 | // Wait for and retrieve any errors | ||
455 | lock (m_scriptErrors) | ||
456 | { | ||
457 | while ((errors = m_scriptErrors[itemId]) == null) | ||
458 | { | ||
459 | if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000)) | ||
460 | { | ||
461 | m_log.ErrorFormat( | ||
462 | "[PRIM INVENTORY]: " + | ||
463 | "timedout waiting for script {0} errors", itemId); | ||
464 | errors = m_scriptErrors[itemId]; | ||
465 | if (errors == null) | ||
466 | { | ||
467 | errors = new ArrayList(1); | ||
468 | errors.Add("timedout waiting for errors"); | ||
469 | } | ||
470 | break; | ||
471 | } | ||
472 | } | ||
473 | m_scriptErrors.Remove(itemId); | ||
474 | } | ||
475 | return errors; | ||
476 | } | ||
477 | |||
478 | // Signal to CreateScriptInstanceEr() that compilation/loading is complete | ||
479 | private void StoreScriptErrors(UUID itemId, ArrayList errors) | ||
480 | { | ||
481 | lock (m_scriptErrors) | ||
482 | { | ||
483 | // If compilation/loading initiated via CreateScriptInstance(), | ||
484 | // it does not want the errors, so just get out | ||
485 | if (!m_scriptErrors.ContainsKey(itemId)) | ||
486 | { | ||
487 | return; | ||
488 | } | ||
489 | |||
490 | // Initiated via CreateScriptInstanceEr(), if we know what the | ||
491 | // errors are, save them and wake CreateScriptInstanceEr(). | ||
492 | if (errors != null) | ||
493 | { | ||
494 | m_scriptErrors[itemId] = errors; | ||
495 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
496 | return; | ||
497 | } | ||
498 | } | ||
499 | |||
500 | // Initiated via CreateScriptInstanceEr() but we don't know what | ||
501 | // the errors are yet, so retrieve them from the script engine. | ||
502 | // This may involve some waiting internal to GetScriptErrors(). | ||
503 | errors = GetScriptErrors(itemId); | ||
504 | |||
505 | // Get a default non-null value to indicate success. | ||
506 | if (errors == null) | ||
507 | { | ||
508 | errors = new ArrayList(); | ||
509 | } | ||
510 | |||
511 | // Post to CreateScriptInstanceEr() and wake it up | ||
512 | lock (m_scriptErrors) | ||
513 | { | ||
514 | m_scriptErrors[itemId] = errors; | ||
515 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
516 | } | ||
517 | } | ||
518 | |||
519 | // Like StoreScriptErrors(), but just posts a single string message | ||
520 | private void StoreScriptError(UUID itemId, string message) | ||
521 | { | ||
522 | ArrayList errors = new ArrayList(1); | ||
523 | errors.Add(message); | ||
524 | StoreScriptErrors(itemId, errors); | ||
372 | } | 525 | } |
373 | 526 | ||
374 | /// <summary> | 527 | /// <summary> |
@@ -381,15 +534,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
381 | /// </param> | 534 | /// </param> |
382 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) | 535 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) |
383 | { | 536 | { |
384 | bool scriptPresent = false; | 537 | if (m_items.ContainsKey(itemId)) |
385 | |||
386 | lock (m_items) | ||
387 | { | ||
388 | if (m_items.ContainsKey(itemId)) | ||
389 | scriptPresent = true; | ||
390 | } | ||
391 | |||
392 | if (scriptPresent) | ||
393 | { | 538 | { |
394 | if (!sceneObjectBeingDeleted) | 539 | if (!sceneObjectBeingDeleted) |
395 | m_part.RemoveScriptEvents(itemId); | 540 | m_part.RemoveScriptEvents(itemId); |
@@ -414,14 +559,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
414 | /// <returns></returns> | 559 | /// <returns></returns> |
415 | private bool InventoryContainsName(string name) | 560 | private bool InventoryContainsName(string name) |
416 | { | 561 | { |
417 | lock (m_items) | 562 | m_items.LockItemsForRead(true); |
563 | foreach (TaskInventoryItem item in m_items.Values) | ||
418 | { | 564 | { |
419 | foreach (TaskInventoryItem item in m_items.Values) | 565 | if (item.Name == name) |
420 | { | 566 | { |
421 | if (item.Name == name) | 567 | m_items.LockItemsForRead(false); |
422 | return true; | 568 | return true; |
423 | } | 569 | } |
424 | } | 570 | } |
571 | m_items.LockItemsForRead(false); | ||
425 | return false; | 572 | return false; |
426 | } | 573 | } |
427 | 574 | ||
@@ -463,8 +610,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
463 | /// <param name="item"></param> | 610 | /// <param name="item"></param> |
464 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) | 611 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) |
465 | { | 612 | { |
466 | List<TaskInventoryItem> il = GetInventoryItems(); | 613 | m_items.LockItemsForRead(true); |
467 | 614 | List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); | |
615 | m_items.LockItemsForRead(false); | ||
468 | foreach (TaskInventoryItem i in il) | 616 | foreach (TaskInventoryItem i in il) |
469 | { | 617 | { |
470 | if (i.Name == item.Name) | 618 | if (i.Name == item.Name) |
@@ -502,14 +650,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
502 | item.Name = name; | 650 | item.Name = name; |
503 | item.GroupID = m_part.GroupID; | 651 | item.GroupID = m_part.GroupID; |
504 | 652 | ||
505 | lock (m_items) | 653 | m_items.LockItemsForWrite(true); |
506 | m_items.Add(item.ItemID, item); | 654 | m_items.Add(item.ItemID, item); |
507 | 655 | m_items.LockItemsForWrite(false); | |
508 | if (allowedDrop) | 656 | if (allowedDrop) |
509 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); | 657 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); |
510 | else | 658 | else |
511 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 659 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
512 | 660 | ||
513 | m_inventorySerial++; | 661 | m_inventorySerial++; |
514 | //m_inventorySerial += 2; | 662 | //m_inventorySerial += 2; |
515 | HasInventoryChanged = true; | 663 | HasInventoryChanged = true; |
@@ -525,15 +673,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
525 | /// <param name="items"></param> | 673 | /// <param name="items"></param> |
526 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) | 674 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) |
527 | { | 675 | { |
528 | lock (m_items) | 676 | m_items.LockItemsForWrite(true); |
677 | foreach (TaskInventoryItem item in items) | ||
529 | { | 678 | { |
530 | foreach (TaskInventoryItem item in items) | 679 | m_items.Add(item.ItemID, item); |
531 | { | 680 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
532 | m_items.Add(item.ItemID, item); | ||
533 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
534 | } | ||
535 | m_inventorySerial++; | ||
536 | } | 681 | } |
682 | m_items.LockItemsForWrite(false); | ||
683 | |||
684 | m_inventorySerial++; | ||
537 | } | 685 | } |
538 | 686 | ||
539 | /// <summary> | 687 | /// <summary> |
@@ -544,10 +692,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
544 | public TaskInventoryItem GetInventoryItem(UUID itemId) | 692 | public TaskInventoryItem GetInventoryItem(UUID itemId) |
545 | { | 693 | { |
546 | TaskInventoryItem item; | 694 | TaskInventoryItem item; |
547 | 695 | m_items.LockItemsForRead(true); | |
548 | lock (m_items) | 696 | m_items.TryGetValue(itemId, out item); |
549 | m_items.TryGetValue(itemId, out item); | 697 | m_items.LockItemsForRead(false); |
550 | |||
551 | return item; | 698 | return item; |
552 | } | 699 | } |
553 | 700 | ||
@@ -563,15 +710,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
563 | { | 710 | { |
564 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); | 711 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); |
565 | 712 | ||
566 | lock (m_items) | 713 | m_items.LockItemsForRead(true); |
714 | |||
715 | foreach (TaskInventoryItem item in m_items.Values) | ||
567 | { | 716 | { |
568 | foreach (TaskInventoryItem item in m_items.Values) | 717 | if (item.Name == name) |
569 | { | 718 | items.Add(item); |
570 | if (item.Name == name) | ||
571 | items.Add(item); | ||
572 | } | ||
573 | } | 719 | } |
574 | 720 | ||
721 | m_items.LockItemsForRead(false); | ||
722 | |||
575 | return items; | 723 | return items; |
576 | } | 724 | } |
577 | 725 | ||
@@ -653,8 +801,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
653 | 801 | ||
654 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents) | 802 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents) |
655 | { | 803 | { |
656 | TaskInventoryItem it = GetInventoryItem(item.ItemID); | 804 | m_items.LockItemsForWrite(true); |
657 | if (it != null) | 805 | |
806 | if (m_items.ContainsKey(item.ItemID)) | ||
658 | { | 807 | { |
659 | item.ParentID = m_part.UUID; | 808 | item.ParentID = m_part.UUID; |
660 | item.ParentPartID = m_part.UUID; | 809 | item.ParentPartID = m_part.UUID; |
@@ -666,19 +815,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
666 | item.GroupID = m_part.GroupID; | 815 | item.GroupID = m_part.GroupID; |
667 | 816 | ||
668 | if (item.AssetID == UUID.Zero) | 817 | if (item.AssetID == UUID.Zero) |
669 | item.AssetID = it.AssetID; | 818 | item.AssetID = m_items[item.ItemID].AssetID; |
670 | |||
671 | lock (m_items) | ||
672 | { | ||
673 | m_items[item.ItemID] = item; | ||
674 | m_inventorySerial++; | ||
675 | } | ||
676 | 819 | ||
820 | m_items[item.ItemID] = item; | ||
821 | m_inventorySerial++; | ||
677 | if (fireScriptEvents) | 822 | if (fireScriptEvents) |
678 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 823 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
679 | |||
680 | HasInventoryChanged = true; | 824 | HasInventoryChanged = true; |
681 | m_part.ParentGroup.HasGroupChanged = true; | 825 | m_part.ParentGroup.HasGroupChanged = true; |
826 | m_items.LockItemsForWrite(false); | ||
682 | return true; | 827 | return true; |
683 | } | 828 | } |
684 | else | 829 | else |
@@ -689,8 +834,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
689 | item.ItemID, m_part.Name, m_part.UUID, | 834 | item.ItemID, m_part.Name, m_part.UUID, |
690 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 835 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
691 | } | 836 | } |
692 | return false; | 837 | m_items.LockItemsForWrite(false); |
693 | 838 | ||
839 | return false; | ||
694 | } | 840 | } |
695 | 841 | ||
696 | /// <summary> | 842 | /// <summary> |
@@ -701,37 +847,53 @@ namespace OpenSim.Region.Framework.Scenes | |||
701 | /// in this prim's inventory.</returns> | 847 | /// in this prim's inventory.</returns> |
702 | public int RemoveInventoryItem(UUID itemID) | 848 | public int RemoveInventoryItem(UUID itemID) |
703 | { | 849 | { |
704 | TaskInventoryItem item = GetInventoryItem(itemID); | 850 | m_items.LockItemsForRead(true); |
705 | if (item != null) | 851 | |
852 | if (m_items.ContainsKey(itemID)) | ||
706 | { | 853 | { |
707 | int type = m_items[itemID].InvType; | 854 | int type = m_items[itemID].InvType; |
855 | m_items.LockItemsForRead(false); | ||
708 | if (type == 10) // Script | 856 | if (type == 10) // Script |
709 | { | 857 | { |
710 | m_part.RemoveScriptEvents(itemID); | ||
711 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); | 858 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); |
712 | } | 859 | } |
860 | m_items.LockItemsForWrite(true); | ||
713 | m_items.Remove(itemID); | 861 | m_items.Remove(itemID); |
862 | m_items.LockItemsForWrite(false); | ||
714 | m_inventorySerial++; | 863 | m_inventorySerial++; |
715 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 864 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
716 | 865 | ||
717 | HasInventoryChanged = true; | 866 | HasInventoryChanged = true; |
718 | m_part.ParentGroup.HasGroupChanged = true; | 867 | m_part.ParentGroup.HasGroupChanged = true; |
719 | 868 | ||
720 | if (!ContainsScripts()) | 869 | int scriptcount = 0; |
870 | m_items.LockItemsForRead(true); | ||
871 | foreach (TaskInventoryItem item in m_items.Values) | ||
872 | { | ||
873 | if (item.Type == 10) | ||
874 | { | ||
875 | scriptcount++; | ||
876 | } | ||
877 | } | ||
878 | m_items.LockItemsForRead(false); | ||
879 | |||
880 | |||
881 | if (scriptcount <= 0) | ||
882 | { | ||
721 | m_part.RemFlag(PrimFlags.Scripted); | 883 | m_part.RemFlag(PrimFlags.Scripted); |
884 | } | ||
722 | 885 | ||
723 | m_part.ScheduleFullUpdate(); | 886 | m_part.ScheduleFullUpdate(); |
724 | 887 | ||
725 | return type; | 888 | return type; |
726 | |||
727 | } | 889 | } |
728 | else | 890 | else |
729 | { | 891 | { |
892 | m_items.LockItemsForRead(false); | ||
730 | m_log.ErrorFormat( | 893 | m_log.ErrorFormat( |
731 | "[PRIM INVENTORY]: " + | 894 | "[PRIM INVENTORY]: " + |
732 | "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", | 895 | "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", |
733 | itemID, m_part.Name, m_part.UUID, | 896 | itemID, m_part.Name, m_part.UUID); |
734 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
735 | } | 897 | } |
736 | 898 | ||
737 | return -1; | 899 | return -1; |
@@ -785,8 +947,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
785 | // isn't available (such as drag from prim inventory to agent inventory) | 947 | // isn't available (such as drag from prim inventory to agent inventory) |
786 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | 948 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); |
787 | 949 | ||
788 | List<TaskInventoryItem> items = GetInventoryItems(); | 950 | m_items.LockItemsForRead(true); |
789 | foreach (TaskInventoryItem item in items) | 951 | |
952 | foreach (TaskInventoryItem item in m_items.Values) | ||
790 | { | 953 | { |
791 | UUID ownerID = item.OwnerID; | 954 | UUID ownerID = item.OwnerID; |
792 | uint everyoneMask = 0; | 955 | uint everyoneMask = 0; |
@@ -830,6 +993,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
830 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | 993 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); |
831 | invString.AddSectionEnd(); | 994 | invString.AddSectionEnd(); |
832 | } | 995 | } |
996 | int count = m_items.Count; | ||
997 | m_items.LockItemsForRead(false); | ||
833 | 998 | ||
834 | fileData = Utils.StringToBytes(invString.BuildString); | 999 | fileData = Utils.StringToBytes(invString.BuildString); |
835 | 1000 | ||
@@ -850,10 +1015,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
850 | { | 1015 | { |
851 | if (HasInventoryChanged) | 1016 | if (HasInventoryChanged) |
852 | { | 1017 | { |
853 | HasInventoryChanged = false; | 1018 | Items.LockItemsForRead(true); |
854 | List<TaskInventoryItem> items = GetInventoryItems(); | 1019 | datastore.StorePrimInventory(m_part.UUID, Items.Values); |
855 | datastore.StorePrimInventory(m_part.UUID, items); | 1020 | Items.LockItemsForRead(false); |
856 | 1021 | ||
1022 | HasInventoryChanged = false; | ||
857 | } | 1023 | } |
858 | } | 1024 | } |
859 | 1025 | ||
@@ -920,89 +1086,75 @@ namespace OpenSim.Region.Framework.Scenes | |||
920 | { | 1086 | { |
921 | uint mask=0x7fffffff; | 1087 | uint mask=0x7fffffff; |
922 | 1088 | ||
923 | lock (m_items) | 1089 | foreach (TaskInventoryItem item in m_items.Values) |
924 | { | 1090 | { |
925 | foreach (TaskInventoryItem item in m_items.Values) | 1091 | if (item.InvType != (int)InventoryType.Object) |
926 | { | 1092 | { |
927 | if (item.InvType != (int)InventoryType.Object) | 1093 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) |
928 | { | 1094 | mask &= ~((uint)PermissionMask.Copy >> 13); |
929 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | 1095 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) |
930 | mask &= ~((uint)PermissionMask.Copy >> 13); | 1096 | mask &= ~((uint)PermissionMask.Transfer >> 13); |
931 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | 1097 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) |
932 | mask &= ~((uint)PermissionMask.Transfer >> 13); | 1098 | mask &= ~((uint)PermissionMask.Modify >> 13); |
933 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | 1099 | } |
934 | mask &= ~((uint)PermissionMask.Modify >> 13); | 1100 | else |
935 | } | 1101 | { |
936 | else | 1102 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
937 | { | 1103 | mask &= ~((uint)PermissionMask.Copy >> 13); |
938 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | 1104 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
939 | mask &= ~((uint)PermissionMask.Copy >> 13); | 1105 | mask &= ~((uint)PermissionMask.Transfer >> 13); |
940 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | 1106 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
941 | mask &= ~((uint)PermissionMask.Transfer >> 13); | 1107 | mask &= ~((uint)PermissionMask.Modify >> 13); |
942 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
943 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
944 | } | ||
945 | |||
946 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
947 | mask &= ~(uint)PermissionMask.Copy; | ||
948 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
949 | mask &= ~(uint)PermissionMask.Transfer; | ||
950 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
951 | mask &= ~(uint)PermissionMask.Modify; | ||
952 | } | 1108 | } |
1109 | |||
1110 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1111 | mask &= ~(uint)PermissionMask.Copy; | ||
1112 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1113 | mask &= ~(uint)PermissionMask.Transfer; | ||
1114 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
1115 | mask &= ~(uint)PermissionMask.Modify; | ||
953 | } | 1116 | } |
954 | |||
955 | return mask; | 1117 | return mask; |
956 | } | 1118 | } |
957 | 1119 | ||
958 | public void ApplyNextOwnerPermissions() | 1120 | public void ApplyNextOwnerPermissions() |
959 | { | 1121 | { |
960 | lock (m_items) | 1122 | foreach (TaskInventoryItem item in m_items.Values) |
961 | { | 1123 | { |
962 | foreach (TaskInventoryItem item in m_items.Values) | 1124 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) |
963 | { | 1125 | { |
964 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) | 1126 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
965 | { | 1127 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; |
966 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | 1128 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
967 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; | 1129 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; |
968 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | 1130 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
969 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | 1131 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; |
970 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
971 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; | ||
972 | } | ||
973 | item.CurrentPermissions &= item.NextPermissions; | ||
974 | item.BasePermissions &= item.NextPermissions; | ||
975 | item.EveryonePermissions &= item.NextPermissions; | ||
976 | item.OwnerChanged = true; | ||
977 | } | 1132 | } |
1133 | item.OwnerChanged = true; | ||
1134 | item.CurrentPermissions &= item.NextPermissions; | ||
1135 | item.BasePermissions &= item.NextPermissions; | ||
1136 | item.EveryonePermissions &= item.NextPermissions; | ||
978 | } | 1137 | } |
979 | } | 1138 | } |
980 | 1139 | ||
981 | public void ApplyGodPermissions(uint perms) | 1140 | public void ApplyGodPermissions(uint perms) |
982 | { | 1141 | { |
983 | lock (m_items) | 1142 | foreach (TaskInventoryItem item in m_items.Values) |
984 | { | 1143 | { |
985 | foreach (TaskInventoryItem item in m_items.Values) | 1144 | item.CurrentPermissions = perms; |
986 | { | 1145 | item.BasePermissions = perms; |
987 | item.CurrentPermissions = perms; | ||
988 | item.BasePermissions = perms; | ||
989 | } | ||
990 | } | 1146 | } |
991 | } | 1147 | } |
992 | 1148 | ||
993 | public bool ContainsScripts() | 1149 | public bool ContainsScripts() |
994 | { | 1150 | { |
995 | lock (m_items) | 1151 | foreach (TaskInventoryItem item in m_items.Values) |
996 | { | 1152 | { |
997 | foreach (TaskInventoryItem item in m_items.Values) | 1153 | if (item.InvType == (int)InventoryType.LSL) |
998 | { | 1154 | { |
999 | if (item.InvType == (int)InventoryType.LSL) | 1155 | return true; |
1000 | { | ||
1001 | return true; | ||
1002 | } | ||
1003 | } | 1156 | } |
1004 | } | 1157 | } |
1005 | |||
1006 | return false; | 1158 | return false; |
1007 | } | 1159 | } |
1008 | 1160 | ||
@@ -1010,11 +1162,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1010 | { | 1162 | { |
1011 | List<UUID> ret = new List<UUID>(); | 1163 | List<UUID> ret = new List<UUID>(); |
1012 | 1164 | ||
1013 | lock (m_items) | 1165 | foreach (TaskInventoryItem item in m_items.Values) |
1014 | { | 1166 | ret.Add(item.ItemID); |
1015 | foreach (TaskInventoryItem item in m_items.Values) | ||
1016 | ret.Add(item.ItemID); | ||
1017 | } | ||
1018 | 1167 | ||
1019 | return ret; | 1168 | return ret; |
1020 | } | 1169 | } |
@@ -1045,31 +1194,44 @@ namespace OpenSim.Region.Framework.Scenes | |||
1045 | 1194 | ||
1046 | public Dictionary<UUID, string> GetScriptStates() | 1195 | public Dictionary<UUID, string> GetScriptStates() |
1047 | { | 1196 | { |
1197 | return GetScriptStates(false); | ||
1198 | } | ||
1199 | |||
1200 | public Dictionary<UUID, string> GetScriptStates(bool oldIDs) | ||
1201 | { | ||
1048 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); | 1202 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); |
1049 | 1203 | ||
1050 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); | 1204 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); |
1051 | if (engines == null) // No engine at all | 1205 | if (engines == null) // No engine at all |
1052 | return ret; | 1206 | return ret; |
1053 | 1207 | ||
1054 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | 1208 | foreach (TaskInventoryItem item in m_items.Values) |
1055 | |||
1056 | foreach (TaskInventoryItem item in scripts) | ||
1057 | { | 1209 | { |
1058 | foreach (IScriptModule e in engines) | 1210 | if (item.InvType == (int)InventoryType.LSL) |
1059 | { | 1211 | { |
1060 | if (e != null) | 1212 | foreach (IScriptModule e in engines) |
1061 | { | 1213 | { |
1062 | string n = e.GetXMLState(item.ItemID); | 1214 | if (e != null) |
1063 | if (n != String.Empty) | ||
1064 | { | 1215 | { |
1065 | if (!ret.ContainsKey(item.ItemID)) | 1216 | string n = e.GetXMLState(item.ItemID); |
1066 | ret[item.ItemID] = n; | 1217 | if (n != String.Empty) |
1067 | break; | 1218 | { |
1219 | if (oldIDs) | ||
1220 | { | ||
1221 | if (!ret.ContainsKey(item.OldItemID)) | ||
1222 | ret[item.OldItemID] = n; | ||
1223 | } | ||
1224 | else | ||
1225 | { | ||
1226 | if (!ret.ContainsKey(item.ItemID)) | ||
1227 | ret[item.ItemID] = n; | ||
1228 | } | ||
1229 | break; | ||
1230 | } | ||
1068 | } | 1231 | } |
1069 | } | 1232 | } |
1070 | } | 1233 | } |
1071 | } | 1234 | } |
1072 | |||
1073 | return ret; | 1235 | return ret; |
1074 | } | 1236 | } |
1075 | 1237 | ||
@@ -1079,21 +1241,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
1079 | if (engines == null) | 1241 | if (engines == null) |
1080 | return; | 1242 | return; |
1081 | 1243 | ||
1082 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | ||
1083 | 1244 | ||
1084 | foreach (TaskInventoryItem item in scripts) | 1245 | Items.LockItemsForRead(true); |
1246 | |||
1247 | foreach (TaskInventoryItem item in m_items.Values) | ||
1085 | { | 1248 | { |
1086 | foreach (IScriptModule engine in engines) | 1249 | if (item.InvType == (int)InventoryType.LSL) |
1087 | { | 1250 | { |
1088 | if (engine != null) | 1251 | foreach (IScriptModule engine in engines) |
1089 | { | 1252 | { |
1090 | if (item.OwnerChanged) | 1253 | if (engine != null) |
1091 | engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); | 1254 | { |
1092 | item.OwnerChanged = false; | 1255 | if (item.OwnerChanged) |
1093 | engine.ResumeScript(item.ItemID); | 1256 | engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); |
1257 | item.OwnerChanged = false; | ||
1258 | engine.ResumeScript(item.ItemID); | ||
1259 | } | ||
1094 | } | 1260 | } |
1095 | } | 1261 | } |
1096 | } | 1262 | } |
1263 | |||
1264 | Items.LockItemsForRead(false); | ||
1097 | } | 1265 | } |
1098 | } | 1266 | } |
1099 | } \ No newline at end of file | 1267 | } \ No newline at end of file |