diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 553 |
1 files changed, 359 insertions, 194 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 53ddb5d..2de439b 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,25 +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 | if (null == m_part || null == m_part.ParentGroup) | 126 | m_items.LockItemsForWrite(true); |
123 | return; | 127 | |
124 | 128 | if (Items.Count == 0) | |
125 | lock (m_items) | ||
126 | { | 129 | { |
127 | if (0 == m_items.Count) | 130 | m_items.LockItemsForWrite(false); |
128 | return; | 131 | return; |
132 | } | ||
129 | 133 | ||
130 | HasInventoryChanged = true; | 134 | HasInventoryChanged = true; |
131 | m_part.ParentGroup.HasGroupChanged = true; | 135 | m_part.ParentGroup.HasGroupChanged = true; |
132 | IList<TaskInventoryItem> items = GetInventoryItems(); | 136 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
133 | m_items.Clear(); | 137 | Items.Clear(); |
134 | 138 | ||
135 | foreach (TaskInventoryItem item in items) | 139 | foreach (TaskInventoryItem item in items) |
136 | { | 140 | { |
137 | item.ResetIDs(m_part.UUID); | 141 | item.ResetIDs(m_part.UUID); |
138 | m_items.Add(item.ItemID, item); | 142 | Items.Add(item.ItemID, item); |
139 | } | ||
140 | } | 143 | } |
144 | m_items.LockItemsForWrite(false); | ||
141 | } | 145 | } |
142 | 146 | ||
143 | /// <summary> | 147 | /// <summary> |
@@ -146,12 +150,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
146 | /// <param name="ownerId"></param> | 150 | /// <param name="ownerId"></param> |
147 | public void ChangeInventoryOwner(UUID ownerId) | 151 | public void ChangeInventoryOwner(UUID ownerId) |
148 | { | 152 | { |
149 | lock (Items) | 153 | m_items.LockItemsForWrite(true); |
154 | if (0 == Items.Count) | ||
150 | { | 155 | { |
151 | if (0 == Items.Count) | 156 | m_items.LockItemsForWrite(false); |
152 | { | 157 | return; |
153 | return; | ||
154 | } | ||
155 | } | 158 | } |
156 | 159 | ||
157 | HasInventoryChanged = true; | 160 | HasInventoryChanged = true; |
@@ -165,6 +168,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
165 | item.OwnerID = ownerId; | 168 | item.OwnerID = ownerId; |
166 | } | 169 | } |
167 | } | 170 | } |
171 | m_items.LockItemsForWrite(false); | ||
168 | } | 172 | } |
169 | 173 | ||
170 | /// <summary> | 174 | /// <summary> |
@@ -173,22 +177,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
173 | /// <param name="groupID"></param> | 177 | /// <param name="groupID"></param> |
174 | public void ChangeInventoryGroup(UUID groupID) | 178 | public void ChangeInventoryGroup(UUID groupID) |
175 | { | 179 | { |
176 | lock (Items) | 180 | m_items.LockItemsForWrite(true); |
181 | if (0 == Items.Count) | ||
177 | { | 182 | { |
178 | if (0 == Items.Count) | 183 | m_items.LockItemsForWrite(false); |
179 | { | 184 | return; |
180 | return; | ||
181 | } | ||
182 | } | 185 | } |
183 | 186 | ||
184 | HasInventoryChanged = true; | 187 | HasInventoryChanged = true; |
185 | m_part.ParentGroup.HasGroupChanged = true; | 188 | m_part.ParentGroup.HasGroupChanged = true; |
186 | List<TaskInventoryItem> items = GetInventoryItems(); | 189 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
187 | foreach (TaskInventoryItem item in items) | 190 | foreach (TaskInventoryItem item in items) |
188 | { | 191 | { |
189 | if (groupID != item.GroupID) | 192 | if (groupID != item.GroupID) |
193 | { | ||
190 | item.GroupID = groupID; | 194 | item.GroupID = groupID; |
195 | } | ||
191 | } | 196 | } |
197 | m_items.LockItemsForWrite(false); | ||
192 | } | 198 | } |
193 | 199 | ||
194 | /// <summary> | 200 | /// <summary> |
@@ -196,9 +202,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
196 | /// </summary> | 202 | /// </summary> |
197 | public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) | 203 | public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) |
198 | { | 204 | { |
199 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | 205 | Items.LockItemsForRead(true); |
200 | foreach (TaskInventoryItem item in scripts) | 206 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
201 | 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 | } | ||
202 | } | 213 | } |
203 | 214 | ||
204 | public ArrayList GetScriptErrors(UUID itemID) | 215 | public ArrayList GetScriptErrors(UUID itemID) |
@@ -231,9 +242,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
231 | /// </param> | 242 | /// </param> |
232 | public void RemoveScriptInstances(bool sceneObjectBeingDeleted) | 243 | public void RemoveScriptInstances(bool sceneObjectBeingDeleted) |
233 | { | 244 | { |
234 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | 245 | Items.LockItemsForRead(true); |
235 | foreach (TaskInventoryItem item in scripts) | 246 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
236 | 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 | } | ||
237 | } | 257 | } |
238 | 258 | ||
239 | /// <summary> | 259 | /// <summary> |
@@ -249,7 +269,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
249 | // item.Name, item.ItemID, Name, UUID); | 269 | // item.Name, item.ItemID, Name, UUID); |
250 | 270 | ||
251 | 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"); | ||
252 | return; | 274 | return; |
275 | } | ||
253 | 276 | ||
254 | m_part.AddFlag(PrimFlags.Scripted); | 277 | m_part.AddFlag(PrimFlags.Scripted); |
255 | 278 | ||
@@ -258,14 +281,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
258 | if (stateSource == 2 && // Prim crossing | 281 | if (stateSource == 2 && // Prim crossing |
259 | m_part.ParentGroup.Scene.m_trustBinaries) | 282 | m_part.ParentGroup.Scene.m_trustBinaries) |
260 | { | 283 | { |
261 | lock (m_items) | 284 | m_items.LockItemsForWrite(true); |
262 | { | 285 | m_items[item.ItemID].PermsMask = 0; |
263 | m_items[item.ItemID].PermsMask = 0; | 286 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
264 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 287 | m_items.LockItemsForWrite(false); |
265 | } | ||
266 | |||
267 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 288 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
268 | 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); | ||
269 | m_part.ParentGroup.AddActiveScriptCount(1); | 291 | m_part.ParentGroup.AddActiveScriptCount(1); |
270 | m_part.ScheduleFullUpdate(); | 292 | m_part.ScheduleFullUpdate(); |
271 | return; | 293 | return; |
@@ -274,6 +296,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
274 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); | 296 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); |
275 | if (null == asset) | 297 | if (null == asset) |
276 | { | 298 | { |
299 | string msg = String.Format("asset ID {0} could not be found", item.AssetID); | ||
300 | StoreScriptError(item.ItemID, msg); | ||
277 | m_log.ErrorFormat( | 301 | m_log.ErrorFormat( |
278 | "[PRIM INVENTORY]: " + | 302 | "[PRIM INVENTORY]: " + |
279 | "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", |
@@ -285,15 +309,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
285 | if (m_part.ParentGroup.m_savedScriptState != null) | 309 | if (m_part.ParentGroup.m_savedScriptState != null) |
286 | RestoreSavedScriptState(item.OldItemID, item.ItemID); | 310 | RestoreSavedScriptState(item.OldItemID, item.ItemID); |
287 | 311 | ||
288 | lock (m_items) | 312 | m_items.LockItemsForWrite(true); |
289 | { | 313 | |
290 | m_items[item.ItemID].PermsMask = 0; | 314 | m_items[item.ItemID].PermsMask = 0; |
291 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 315 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
292 | } | 316 | |
317 | m_items.LockItemsForWrite(false); | ||
293 | 318 | ||
294 | string script = Utils.BytesToString(asset.Data); | 319 | string script = Utils.BytesToString(asset.Data); |
295 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 320 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
296 | 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); | ||
297 | m_part.ParentGroup.AddActiveScriptCount(1); | 323 | m_part.ParentGroup.AddActiveScriptCount(1); |
298 | m_part.ScheduleFullUpdate(); | 324 | m_part.ScheduleFullUpdate(); |
299 | } | 325 | } |
@@ -357,21 +383,145 @@ namespace OpenSim.Region.Framework.Scenes | |||
357 | 383 | ||
358 | /// <summary> | 384 | /// <summary> |
359 | /// 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. | ||
360 | /// </summary> | 387 | /// </summary> |
361 | /// <param name="itemId"> | 388 | /// <param name="itemId"> |
362 | /// A <see cref="UUID"/> | 389 | /// A <see cref="UUID"/> |
363 | /// </param> | 390 | /// </param> |
364 | 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) |
365 | { | 392 | { |
366 | TaskInventoryItem item = GetInventoryItem(itemId); | 393 | lock (m_scriptErrors) |
367 | if (item != null) | 394 | { |
368 | 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 | } | ||
369 | 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); | ||
370 | m_log.ErrorFormat( | 427 | m_log.ErrorFormat( |
371 | "[PRIM INVENTORY]: " + | 428 | "[PRIM INVENTORY]: " + |
372 | "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); |
373 | itemId, m_part.Name, m_part.UUID, | 430 | } |
374 | 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); | ||
375 | } | 525 | } |
376 | 526 | ||
377 | /// <summary> | 527 | /// <summary> |
@@ -384,15 +534,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
384 | /// </param> | 534 | /// </param> |
385 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) | 535 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) |
386 | { | 536 | { |
387 | bool scriptPresent = false; | 537 | if (m_items.ContainsKey(itemId)) |
388 | |||
389 | lock (m_items) | ||
390 | { | ||
391 | if (m_items.ContainsKey(itemId)) | ||
392 | scriptPresent = true; | ||
393 | } | ||
394 | |||
395 | if (scriptPresent) | ||
396 | { | 538 | { |
397 | if (!sceneObjectBeingDeleted) | 539 | if (!sceneObjectBeingDeleted) |
398 | m_part.RemoveScriptEvents(itemId); | 540 | m_part.RemoveScriptEvents(itemId); |
@@ -417,14 +559,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
417 | /// <returns></returns> | 559 | /// <returns></returns> |
418 | private bool InventoryContainsName(string name) | 560 | private bool InventoryContainsName(string name) |
419 | { | 561 | { |
420 | lock (m_items) | 562 | m_items.LockItemsForRead(true); |
563 | foreach (TaskInventoryItem item in m_items.Values) | ||
421 | { | 564 | { |
422 | foreach (TaskInventoryItem item in m_items.Values) | 565 | if (item.Name == name) |
423 | { | 566 | { |
424 | if (item.Name == name) | 567 | m_items.LockItemsForRead(false); |
425 | return true; | 568 | return true; |
426 | } | 569 | } |
427 | } | 570 | } |
571 | m_items.LockItemsForRead(false); | ||
428 | return false; | 572 | return false; |
429 | } | 573 | } |
430 | 574 | ||
@@ -466,8 +610,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
466 | /// <param name="item"></param> | 610 | /// <param name="item"></param> |
467 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) | 611 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) |
468 | { | 612 | { |
469 | List<TaskInventoryItem> il = GetInventoryItems(); | 613 | m_items.LockItemsForRead(true); |
470 | 614 | List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); | |
615 | m_items.LockItemsForRead(false); | ||
471 | foreach (TaskInventoryItem i in il) | 616 | foreach (TaskInventoryItem i in il) |
472 | { | 617 | { |
473 | if (i.Name == item.Name) | 618 | if (i.Name == item.Name) |
@@ -505,14 +650,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
505 | item.Name = name; | 650 | item.Name = name; |
506 | item.GroupID = m_part.GroupID; | 651 | item.GroupID = m_part.GroupID; |
507 | 652 | ||
508 | lock (m_items) | 653 | m_items.LockItemsForWrite(true); |
509 | m_items.Add(item.ItemID, item); | 654 | m_items.Add(item.ItemID, item); |
510 | 655 | m_items.LockItemsForWrite(false); | |
511 | if (allowedDrop) | 656 | if (allowedDrop) |
512 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); | 657 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); |
513 | else | 658 | else |
514 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 659 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
515 | 660 | ||
516 | m_inventorySerial++; | 661 | m_inventorySerial++; |
517 | //m_inventorySerial += 2; | 662 | //m_inventorySerial += 2; |
518 | HasInventoryChanged = true; | 663 | HasInventoryChanged = true; |
@@ -528,15 +673,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
528 | /// <param name="items"></param> | 673 | /// <param name="items"></param> |
529 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) | 674 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) |
530 | { | 675 | { |
531 | lock (m_items) | 676 | m_items.LockItemsForWrite(true); |
677 | foreach (TaskInventoryItem item in items) | ||
532 | { | 678 | { |
533 | foreach (TaskInventoryItem item in items) | 679 | m_items.Add(item.ItemID, item); |
534 | { | 680 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
535 | m_items.Add(item.ItemID, item); | ||
536 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
537 | } | ||
538 | m_inventorySerial++; | ||
539 | } | 681 | } |
682 | m_items.LockItemsForWrite(false); | ||
683 | |||
684 | m_inventorySerial++; | ||
540 | } | 685 | } |
541 | 686 | ||
542 | /// <summary> | 687 | /// <summary> |
@@ -547,10 +692,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
547 | public TaskInventoryItem GetInventoryItem(UUID itemId) | 692 | public TaskInventoryItem GetInventoryItem(UUID itemId) |
548 | { | 693 | { |
549 | TaskInventoryItem item; | 694 | TaskInventoryItem item; |
550 | 695 | m_items.LockItemsForRead(true); | |
551 | lock (m_items) | 696 | m_items.TryGetValue(itemId, out item); |
552 | m_items.TryGetValue(itemId, out item); | 697 | m_items.LockItemsForRead(false); |
553 | |||
554 | return item; | 698 | return item; |
555 | } | 699 | } |
556 | 700 | ||
@@ -566,15 +710,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
566 | { | 710 | { |
567 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); | 711 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); |
568 | 712 | ||
569 | lock (m_items) | 713 | m_items.LockItemsForRead(true); |
714 | |||
715 | foreach (TaskInventoryItem item in m_items.Values) | ||
570 | { | 716 | { |
571 | foreach (TaskInventoryItem item in m_items.Values) | 717 | if (item.Name == name) |
572 | { | 718 | items.Add(item); |
573 | if (item.Name == name) | ||
574 | items.Add(item); | ||
575 | } | ||
576 | } | 719 | } |
577 | 720 | ||
721 | m_items.LockItemsForRead(false); | ||
722 | |||
578 | return items; | 723 | return items; |
579 | } | 724 | } |
580 | 725 | ||
@@ -655,8 +800,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
655 | 800 | ||
656 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents) | 801 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents) |
657 | { | 802 | { |
658 | TaskInventoryItem it = GetInventoryItem(item.ItemID); | 803 | m_items.LockItemsForWrite(true); |
659 | if (it != null) | 804 | |
805 | if (m_items.ContainsKey(item.ItemID)) | ||
660 | { | 806 | { |
661 | item.ParentID = m_part.UUID; | 807 | item.ParentID = m_part.UUID; |
662 | item.ParentPartID = m_part.UUID; | 808 | item.ParentPartID = m_part.UUID; |
@@ -668,19 +814,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
668 | item.GroupID = m_part.GroupID; | 814 | item.GroupID = m_part.GroupID; |
669 | 815 | ||
670 | if (item.AssetID == UUID.Zero) | 816 | if (item.AssetID == UUID.Zero) |
671 | item.AssetID = it.AssetID; | 817 | item.AssetID = m_items[item.ItemID].AssetID; |
672 | |||
673 | lock (m_items) | ||
674 | { | ||
675 | m_items[item.ItemID] = item; | ||
676 | m_inventorySerial++; | ||
677 | } | ||
678 | 818 | ||
819 | m_items[item.ItemID] = item; | ||
820 | m_inventorySerial++; | ||
679 | if (fireScriptEvents) | 821 | if (fireScriptEvents) |
680 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 822 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
681 | |||
682 | HasInventoryChanged = true; | 823 | HasInventoryChanged = true; |
683 | m_part.ParentGroup.HasGroupChanged = true; | 824 | m_part.ParentGroup.HasGroupChanged = true; |
825 | m_items.LockItemsForWrite(false); | ||
684 | return true; | 826 | return true; |
685 | } | 827 | } |
686 | else | 828 | else |
@@ -691,8 +833,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
691 | item.ItemID, m_part.Name, m_part.UUID, | 833 | item.ItemID, m_part.Name, m_part.UUID, |
692 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 834 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
693 | } | 835 | } |
694 | return false; | 836 | m_items.LockItemsForWrite(false); |
695 | 837 | ||
838 | return false; | ||
696 | } | 839 | } |
697 | 840 | ||
698 | /// <summary> | 841 | /// <summary> |
@@ -703,37 +846,53 @@ namespace OpenSim.Region.Framework.Scenes | |||
703 | /// in this prim's inventory.</returns> | 846 | /// in this prim's inventory.</returns> |
704 | public int RemoveInventoryItem(UUID itemID) | 847 | public int RemoveInventoryItem(UUID itemID) |
705 | { | 848 | { |
706 | TaskInventoryItem item = GetInventoryItem(itemID); | 849 | m_items.LockItemsForRead(true); |
707 | if (item != null) | 850 | |
851 | if (m_items.ContainsKey(itemID)) | ||
708 | { | 852 | { |
709 | int type = m_items[itemID].InvType; | 853 | int type = m_items[itemID].InvType; |
854 | m_items.LockItemsForRead(false); | ||
710 | if (type == 10) // Script | 855 | if (type == 10) // Script |
711 | { | 856 | { |
712 | m_part.RemoveScriptEvents(itemID); | ||
713 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); | 857 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); |
714 | } | 858 | } |
859 | m_items.LockItemsForWrite(true); | ||
715 | m_items.Remove(itemID); | 860 | m_items.Remove(itemID); |
861 | m_items.LockItemsForWrite(false); | ||
716 | m_inventorySerial++; | 862 | m_inventorySerial++; |
717 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 863 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
718 | 864 | ||
719 | HasInventoryChanged = true; | 865 | HasInventoryChanged = true; |
720 | m_part.ParentGroup.HasGroupChanged = true; | 866 | m_part.ParentGroup.HasGroupChanged = true; |
721 | 867 | ||
722 | if (!ContainsScripts()) | 868 | int scriptcount = 0; |
869 | m_items.LockItemsForRead(true); | ||
870 | foreach (TaskInventoryItem item in m_items.Values) | ||
871 | { | ||
872 | if (item.Type == 10) | ||
873 | { | ||
874 | scriptcount++; | ||
875 | } | ||
876 | } | ||
877 | m_items.LockItemsForRead(false); | ||
878 | |||
879 | |||
880 | if (scriptcount <= 0) | ||
881 | { | ||
723 | m_part.RemFlag(PrimFlags.Scripted); | 882 | m_part.RemFlag(PrimFlags.Scripted); |
883 | } | ||
724 | 884 | ||
725 | m_part.ScheduleFullUpdate(); | 885 | m_part.ScheduleFullUpdate(); |
726 | 886 | ||
727 | return type; | 887 | return type; |
728 | |||
729 | } | 888 | } |
730 | else | 889 | else |
731 | { | 890 | { |
891 | m_items.LockItemsForRead(false); | ||
732 | m_log.ErrorFormat( | 892 | m_log.ErrorFormat( |
733 | "[PRIM INVENTORY]: " + | 893 | "[PRIM INVENTORY]: " + |
734 | "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", | 894 | "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", |
735 | itemID, m_part.Name, m_part.UUID, | 895 | itemID, m_part.Name, m_part.UUID); |
736 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
737 | } | 896 | } |
738 | 897 | ||
739 | return -1; | 898 | return -1; |
@@ -787,8 +946,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
787 | // isn't available (such as drag from prim inventory to agent inventory) | 946 | // isn't available (such as drag from prim inventory to agent inventory) |
788 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | 947 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); |
789 | 948 | ||
790 | List<TaskInventoryItem> items = GetInventoryItems(); | 949 | m_items.LockItemsForRead(true); |
791 | foreach (TaskInventoryItem item in items) | 950 | |
951 | foreach (TaskInventoryItem item in m_items.Values) | ||
792 | { | 952 | { |
793 | UUID ownerID = item.OwnerID; | 953 | UUID ownerID = item.OwnerID; |
794 | uint everyoneMask = 0; | 954 | uint everyoneMask = 0; |
@@ -832,6 +992,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
832 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | 992 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); |
833 | invString.AddSectionEnd(); | 993 | invString.AddSectionEnd(); |
834 | } | 994 | } |
995 | int count = m_items.Count; | ||
996 | m_items.LockItemsForRead(false); | ||
835 | 997 | ||
836 | fileData = Utils.StringToBytes(invString.BuildString); | 998 | fileData = Utils.StringToBytes(invString.BuildString); |
837 | 999 | ||
@@ -852,10 +1014,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
852 | { | 1014 | { |
853 | if (HasInventoryChanged) | 1015 | if (HasInventoryChanged) |
854 | { | 1016 | { |
855 | HasInventoryChanged = false; | 1017 | Items.LockItemsForRead(true); |
856 | List<TaskInventoryItem> items = GetInventoryItems(); | 1018 | datastore.StorePrimInventory(m_part.UUID, Items.Values); |
857 | datastore.StorePrimInventory(m_part.UUID, items); | 1019 | Items.LockItemsForRead(false); |
858 | 1020 | ||
1021 | HasInventoryChanged = false; | ||
859 | } | 1022 | } |
860 | } | 1023 | } |
861 | 1024 | ||
@@ -922,89 +1085,75 @@ namespace OpenSim.Region.Framework.Scenes | |||
922 | { | 1085 | { |
923 | uint mask=0x7fffffff; | 1086 | uint mask=0x7fffffff; |
924 | 1087 | ||
925 | lock (m_items) | 1088 | foreach (TaskInventoryItem item in m_items.Values) |
926 | { | 1089 | { |
927 | foreach (TaskInventoryItem item in m_items.Values) | 1090 | if (item.InvType != (int)InventoryType.Object) |
928 | { | 1091 | { |
929 | if (item.InvType != (int)InventoryType.Object) | 1092 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) |
930 | { | 1093 | mask &= ~((uint)PermissionMask.Copy >> 13); |
931 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | 1094 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) |
932 | mask &= ~((uint)PermissionMask.Copy >> 13); | 1095 | mask &= ~((uint)PermissionMask.Transfer >> 13); |
933 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | 1096 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) |
934 | mask &= ~((uint)PermissionMask.Transfer >> 13); | 1097 | mask &= ~((uint)PermissionMask.Modify >> 13); |
935 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | 1098 | } |
936 | mask &= ~((uint)PermissionMask.Modify >> 13); | 1099 | else |
937 | } | 1100 | { |
938 | else | 1101 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
939 | { | 1102 | mask &= ~((uint)PermissionMask.Copy >> 13); |
940 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | 1103 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
941 | mask &= ~((uint)PermissionMask.Copy >> 13); | 1104 | mask &= ~((uint)PermissionMask.Transfer >> 13); |
942 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | 1105 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
943 | mask &= ~((uint)PermissionMask.Transfer >> 13); | 1106 | mask &= ~((uint)PermissionMask.Modify >> 13); |
944 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
945 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
946 | } | ||
947 | |||
948 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
949 | mask &= ~(uint)PermissionMask.Copy; | ||
950 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
951 | mask &= ~(uint)PermissionMask.Transfer; | ||
952 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
953 | mask &= ~(uint)PermissionMask.Modify; | ||
954 | } | 1107 | } |
1108 | |||
1109 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1110 | mask &= ~(uint)PermissionMask.Copy; | ||
1111 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1112 | mask &= ~(uint)PermissionMask.Transfer; | ||
1113 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
1114 | mask &= ~(uint)PermissionMask.Modify; | ||
955 | } | 1115 | } |
956 | |||
957 | return mask; | 1116 | return mask; |
958 | } | 1117 | } |
959 | 1118 | ||
960 | public void ApplyNextOwnerPermissions() | 1119 | public void ApplyNextOwnerPermissions() |
961 | { | 1120 | { |
962 | lock (m_items) | 1121 | foreach (TaskInventoryItem item in m_items.Values) |
963 | { | 1122 | { |
964 | foreach (TaskInventoryItem item in m_items.Values) | 1123 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) |
965 | { | 1124 | { |
966 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) | 1125 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
967 | { | 1126 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; |
968 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | 1127 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
969 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; | 1128 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; |
970 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | 1129 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
971 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | 1130 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; |
972 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
973 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; | ||
974 | } | ||
975 | item.CurrentPermissions &= item.NextPermissions; | ||
976 | item.BasePermissions &= item.NextPermissions; | ||
977 | item.EveryonePermissions &= item.NextPermissions; | ||
978 | item.OwnerChanged = true; | ||
979 | } | 1131 | } |
1132 | item.OwnerChanged = true; | ||
1133 | item.CurrentPermissions &= item.NextPermissions; | ||
1134 | item.BasePermissions &= item.NextPermissions; | ||
1135 | item.EveryonePermissions &= item.NextPermissions; | ||
980 | } | 1136 | } |
981 | } | 1137 | } |
982 | 1138 | ||
983 | public void ApplyGodPermissions(uint perms) | 1139 | public void ApplyGodPermissions(uint perms) |
984 | { | 1140 | { |
985 | lock (m_items) | 1141 | foreach (TaskInventoryItem item in m_items.Values) |
986 | { | 1142 | { |
987 | foreach (TaskInventoryItem item in m_items.Values) | 1143 | item.CurrentPermissions = perms; |
988 | { | 1144 | item.BasePermissions = perms; |
989 | item.CurrentPermissions = perms; | ||
990 | item.BasePermissions = perms; | ||
991 | } | ||
992 | } | 1145 | } |
993 | } | 1146 | } |
994 | 1147 | ||
995 | public bool ContainsScripts() | 1148 | public bool ContainsScripts() |
996 | { | 1149 | { |
997 | lock (m_items) | 1150 | foreach (TaskInventoryItem item in m_items.Values) |
998 | { | 1151 | { |
999 | foreach (TaskInventoryItem item in m_items.Values) | 1152 | if (item.InvType == (int)InventoryType.LSL) |
1000 | { | 1153 | { |
1001 | if (item.InvType == (int)InventoryType.LSL) | 1154 | return true; |
1002 | { | ||
1003 | return true; | ||
1004 | } | ||
1005 | } | 1155 | } |
1006 | } | 1156 | } |
1007 | |||
1008 | return false; | 1157 | return false; |
1009 | } | 1158 | } |
1010 | 1159 | ||
@@ -1012,11 +1161,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1012 | { | 1161 | { |
1013 | List<UUID> ret = new List<UUID>(); | 1162 | List<UUID> ret = new List<UUID>(); |
1014 | 1163 | ||
1015 | lock (m_items) | 1164 | foreach (TaskInventoryItem item in m_items.Values) |
1016 | { | 1165 | ret.Add(item.ItemID); |
1017 | foreach (TaskInventoryItem item in m_items.Values) | ||
1018 | ret.Add(item.ItemID); | ||
1019 | } | ||
1020 | 1166 | ||
1021 | return ret; | 1167 | return ret; |
1022 | } | 1168 | } |
@@ -1047,31 +1193,44 @@ namespace OpenSim.Region.Framework.Scenes | |||
1047 | 1193 | ||
1048 | public Dictionary<UUID, string> GetScriptStates() | 1194 | public Dictionary<UUID, string> GetScriptStates() |
1049 | { | 1195 | { |
1196 | return GetScriptStates(false); | ||
1197 | } | ||
1198 | |||
1199 | public Dictionary<UUID, string> GetScriptStates(bool oldIDs) | ||
1200 | { | ||
1050 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); | 1201 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); |
1051 | 1202 | ||
1052 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); | 1203 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); |
1053 | if (engines == null) // No engine at all | 1204 | if (engines == null) // No engine at all |
1054 | return ret; | 1205 | return ret; |
1055 | 1206 | ||
1056 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | 1207 | foreach (TaskInventoryItem item in m_items.Values) |
1057 | |||
1058 | foreach (TaskInventoryItem item in scripts) | ||
1059 | { | 1208 | { |
1060 | foreach (IScriptModule e in engines) | 1209 | if (item.InvType == (int)InventoryType.LSL) |
1061 | { | 1210 | { |
1062 | if (e != null) | 1211 | foreach (IScriptModule e in engines) |
1063 | { | 1212 | { |
1064 | string n = e.GetXMLState(item.ItemID); | 1213 | if (e != null) |
1065 | if (n != String.Empty) | ||
1066 | { | 1214 | { |
1067 | if (!ret.ContainsKey(item.ItemID)) | 1215 | string n = e.GetXMLState(item.ItemID); |
1068 | ret[item.ItemID] = n; | 1216 | if (n != String.Empty) |
1069 | break; | 1217 | { |
1218 | if (oldIDs) | ||
1219 | { | ||
1220 | if (!ret.ContainsKey(item.OldItemID)) | ||
1221 | ret[item.OldItemID] = n; | ||
1222 | } | ||
1223 | else | ||
1224 | { | ||
1225 | if (!ret.ContainsKey(item.ItemID)) | ||
1226 | ret[item.ItemID] = n; | ||
1227 | } | ||
1228 | break; | ||
1229 | } | ||
1070 | } | 1230 | } |
1071 | } | 1231 | } |
1072 | } | 1232 | } |
1073 | } | 1233 | } |
1074 | |||
1075 | return ret; | 1234 | return ret; |
1076 | } | 1235 | } |
1077 | 1236 | ||
@@ -1081,21 +1240,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
1081 | if (engines == null) | 1240 | if (engines == null) |
1082 | return; | 1241 | return; |
1083 | 1242 | ||
1084 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | ||
1085 | 1243 | ||
1086 | foreach (TaskInventoryItem item in scripts) | 1244 | Items.LockItemsForRead(true); |
1245 | |||
1246 | foreach (TaskInventoryItem item in m_items.Values) | ||
1087 | { | 1247 | { |
1088 | foreach (IScriptModule engine in engines) | 1248 | if (item.InvType == (int)InventoryType.LSL) |
1089 | { | 1249 | { |
1090 | if (engine != null) | 1250 | foreach (IScriptModule engine in engines) |
1091 | { | 1251 | { |
1092 | if (item.OwnerChanged) | 1252 | if (engine != null) |
1093 | engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); | 1253 | { |
1094 | item.OwnerChanged = false; | 1254 | if (item.OwnerChanged) |
1095 | engine.ResumeScript(item.ItemID); | 1255 | engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); |
1256 | item.OwnerChanged = false; | ||
1257 | engine.ResumeScript(item.ItemID); | ||
1258 | } | ||
1096 | } | 1259 | } |
1097 | } | 1260 | } |
1098 | } | 1261 | } |
1262 | |||
1263 | Items.LockItemsForRead(false); | ||
1099 | } | 1264 | } |
1100 | } | 1265 | } |
1101 | } | 1266 | } |