diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 711 |
1 files changed, 447 insertions, 264 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 39ebaef..3cfca4b 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -48,6 +48,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
48 | private string m_inventoryFileName = String.Empty; | 48 | private string m_inventoryFileName = String.Empty; |
49 | private byte[] m_inventoryFileData = new byte[0]; | 49 | private byte[] m_inventoryFileData = new byte[0]; |
50 | private uint m_inventoryFileNameSerial = 0; | 50 | private uint m_inventoryFileNameSerial = 0; |
51 | |||
52 | private Dictionary<UUID, ArrayList> m_scriptErrors = new Dictionary<UUID, ArrayList>(); | ||
51 | 53 | ||
52 | /// <value> | 54 | /// <value> |
53 | /// The part to which the inventory belongs. | 55 | /// The part to which the inventory belongs. |
@@ -84,7 +86,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
84 | /// </value> | 86 | /// </value> |
85 | protected internal TaskInventoryDictionary Items | 87 | protected internal TaskInventoryDictionary Items |
86 | { | 88 | { |
87 | get { return m_items; } | 89 | get { |
90 | return m_items; | ||
91 | } | ||
88 | set | 92 | set |
89 | { | 93 | { |
90 | m_items = value; | 94 | m_items = value; |
@@ -120,39 +124,45 @@ namespace OpenSim.Region.Framework.Scenes | |||
120 | /// <param name="linkNum">Link number for the part</param> | 124 | /// <param name="linkNum">Link number for the part</param> |
121 | public void ResetInventoryIDs() | 125 | public void ResetInventoryIDs() |
122 | { | 126 | { |
123 | if (null == m_part || null == m_part.ParentGroup) | 127 | m_items.LockItemsForWrite(true); |
124 | return; | 128 | |
125 | 129 | if (Items.Count == 0) | |
126 | lock (m_items) | ||
127 | { | 130 | { |
128 | if (0 == m_items.Count) | 131 | m_items.LockItemsForWrite(false); |
129 | return; | 132 | return; |
133 | } | ||
130 | 134 | ||
131 | IList<TaskInventoryItem> items = GetInventoryItems(); | 135 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
132 | m_items.Clear(); | 136 | Items.Clear(); |
133 | 137 | ||
134 | foreach (TaskInventoryItem item in items) | 138 | foreach (TaskInventoryItem item in items) |
135 | { | 139 | { |
136 | item.ResetIDs(m_part.UUID); | 140 | item.ResetIDs(m_part.UUID); |
137 | m_items.Add(item.ItemID, item); | 141 | Items.Add(item.ItemID, item); |
138 | } | ||
139 | } | 142 | } |
143 | m_items.LockItemsForWrite(false); | ||
140 | } | 144 | } |
141 | 145 | ||
142 | public void ResetObjectID() | 146 | public void ResetObjectID() |
143 | { | 147 | { |
144 | lock (Items) | 148 | m_items.LockItemsForWrite(true); |
149 | |||
150 | if (Items.Count == 0) | ||
145 | { | 151 | { |
146 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | 152 | m_items.LockItemsForWrite(false); |
147 | Items.Clear(); | 153 | return; |
148 | |||
149 | foreach (TaskInventoryItem item in items) | ||
150 | { | ||
151 | item.ParentPartID = m_part.UUID; | ||
152 | item.ParentID = m_part.UUID; | ||
153 | Items.Add(item.ItemID, item); | ||
154 | } | ||
155 | } | 154 | } |
155 | |||
156 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | ||
157 | Items.Clear(); | ||
158 | |||
159 | foreach (TaskInventoryItem item in items) | ||
160 | { | ||
161 | item.ParentPartID = m_part.UUID; | ||
162 | item.ParentID = m_part.UUID; | ||
163 | Items.Add(item.ItemID, item); | ||
164 | } | ||
165 | m_items.LockItemsForWrite(false); | ||
156 | } | 166 | } |
157 | 167 | ||
158 | /// <summary> | 168 | /// <summary> |
@@ -161,12 +171,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
161 | /// <param name="ownerId"></param> | 171 | /// <param name="ownerId"></param> |
162 | public void ChangeInventoryOwner(UUID ownerId) | 172 | public void ChangeInventoryOwner(UUID ownerId) |
163 | { | 173 | { |
164 | lock (Items) | 174 | m_items.LockItemsForWrite(true); |
175 | if (0 == Items.Count) | ||
165 | { | 176 | { |
166 | if (0 == Items.Count) | 177 | m_items.LockItemsForWrite(false); |
167 | { | 178 | return; |
168 | return; | ||
169 | } | ||
170 | } | 179 | } |
171 | 180 | ||
172 | HasInventoryChanged = true; | 181 | HasInventoryChanged = true; |
@@ -180,6 +189,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
180 | item.OwnerID = ownerId; | 189 | item.OwnerID = ownerId; |
181 | } | 190 | } |
182 | } | 191 | } |
192 | m_items.LockItemsForWrite(false); | ||
183 | } | 193 | } |
184 | 194 | ||
185 | /// <summary> | 195 | /// <summary> |
@@ -188,12 +198,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
188 | /// <param name="groupID"></param> | 198 | /// <param name="groupID"></param> |
189 | public void ChangeInventoryGroup(UUID groupID) | 199 | public void ChangeInventoryGroup(UUID groupID) |
190 | { | 200 | { |
191 | lock (Items) | 201 | m_items.LockItemsForWrite(true); |
202 | if (0 == Items.Count) | ||
192 | { | 203 | { |
193 | if (0 == Items.Count) | 204 | m_items.LockItemsForWrite(false); |
194 | { | 205 | return; |
195 | return; | ||
196 | } | ||
197 | } | 206 | } |
198 | 207 | ||
199 | // Don't let this set the HasGroupChanged flag for attachments | 208 | // Don't let this set the HasGroupChanged flag for attachments |
@@ -205,12 +214,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
205 | m_part.ParentGroup.HasGroupChanged = true; | 214 | m_part.ParentGroup.HasGroupChanged = true; |
206 | } | 215 | } |
207 | 216 | ||
208 | List<TaskInventoryItem> items = GetInventoryItems(); | 217 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
209 | foreach (TaskInventoryItem item in items) | 218 | foreach (TaskInventoryItem item in items) |
210 | { | 219 | { |
211 | if (groupID != item.GroupID) | 220 | if (groupID != item.GroupID) |
221 | { | ||
212 | item.GroupID = groupID; | 222 | item.GroupID = groupID; |
223 | } | ||
213 | } | 224 | } |
225 | m_items.LockItemsForWrite(false); | ||
214 | } | 226 | } |
215 | 227 | ||
216 | /// <summary> | 228 | /// <summary> |
@@ -218,9 +230,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
218 | /// </summary> | 230 | /// </summary> |
219 | public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) | 231 | public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) |
220 | { | 232 | { |
221 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | 233 | Items.LockItemsForRead(true); |
222 | foreach (TaskInventoryItem item in scripts) | 234 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
223 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | 235 | Items.LockItemsForRead(false); |
236 | foreach (TaskInventoryItem item in items) | ||
237 | { | ||
238 | if ((int)InventoryType.LSL == item.InvType) | ||
239 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | ||
240 | } | ||
224 | } | 241 | } |
225 | 242 | ||
226 | public ArrayList GetScriptErrors(UUID itemID) | 243 | public ArrayList GetScriptErrors(UUID itemID) |
@@ -253,9 +270,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
253 | /// </param> | 270 | /// </param> |
254 | public void RemoveScriptInstances(bool sceneObjectBeingDeleted) | 271 | public void RemoveScriptInstances(bool sceneObjectBeingDeleted) |
255 | { | 272 | { |
256 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | 273 | Items.LockItemsForRead(true); |
257 | foreach (TaskInventoryItem item in scripts) | 274 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
258 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); | 275 | Items.LockItemsForRead(false); |
276 | |||
277 | foreach (TaskInventoryItem item in items) | ||
278 | { | ||
279 | if ((int)InventoryType.LSL == item.InvType) | ||
280 | { | ||
281 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); | ||
282 | m_part.RemoveScriptEvents(item.ItemID); | ||
283 | } | ||
284 | } | ||
259 | } | 285 | } |
260 | 286 | ||
261 | /// <summary> | 287 | /// <summary> |
@@ -271,7 +297,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
271 | // item.Name, item.ItemID, Name, UUID); | 297 | // item.Name, item.ItemID, Name, UUID); |
272 | 298 | ||
273 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) | 299 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) |
300 | { | ||
301 | StoreScriptError(item.ItemID, "no permission"); | ||
274 | return; | 302 | return; |
303 | } | ||
275 | 304 | ||
276 | m_part.AddFlag(PrimFlags.Scripted); | 305 | m_part.AddFlag(PrimFlags.Scripted); |
277 | 306 | ||
@@ -280,14 +309,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
280 | if (stateSource == 2 && // Prim crossing | 309 | if (stateSource == 2 && // Prim crossing |
281 | m_part.ParentGroup.Scene.m_trustBinaries) | 310 | m_part.ParentGroup.Scene.m_trustBinaries) |
282 | { | 311 | { |
283 | lock (m_items) | 312 | m_items.LockItemsForWrite(true); |
284 | { | 313 | m_items[item.ItemID].PermsMask = 0; |
285 | m_items[item.ItemID].PermsMask = 0; | 314 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
286 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 315 | m_items.LockItemsForWrite(false); |
287 | } | ||
288 | |||
289 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 316 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
290 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); | 317 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); |
318 | StoreScriptErrors(item.ItemID, null); | ||
291 | m_part.ParentGroup.AddActiveScriptCount(1); | 319 | m_part.ParentGroup.AddActiveScriptCount(1); |
292 | m_part.ScheduleFullUpdate(); | 320 | m_part.ScheduleFullUpdate(); |
293 | return; | 321 | return; |
@@ -296,6 +324,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
296 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); | 324 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); |
297 | if (null == asset) | 325 | if (null == asset) |
298 | { | 326 | { |
327 | string msg = String.Format("asset ID {0} could not be found", item.AssetID); | ||
328 | StoreScriptError(item.ItemID, msg); | ||
299 | m_log.ErrorFormat( | 329 | m_log.ErrorFormat( |
300 | "[PRIM INVENTORY]: " + | 330 | "[PRIM INVENTORY]: " + |
301 | "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", | 331 | "Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", |
@@ -307,15 +337,17 @@ namespace OpenSim.Region.Framework.Scenes | |||
307 | if (m_part.ParentGroup.m_savedScriptState != null) | 337 | if (m_part.ParentGroup.m_savedScriptState != null) |
308 | RestoreSavedScriptState(item.OldItemID, item.ItemID); | 338 | RestoreSavedScriptState(item.OldItemID, item.ItemID); |
309 | 339 | ||
310 | lock (m_items) | 340 | m_items.LockItemsForWrite(true); |
311 | { | 341 | |
312 | m_items[item.ItemID].PermsMask = 0; | 342 | m_items[item.ItemID].PermsMask = 0; |
313 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 343 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
314 | } | 344 | |
345 | m_items.LockItemsForWrite(false); | ||
315 | 346 | ||
316 | string script = Utils.BytesToString(asset.Data); | 347 | string script = Utils.BytesToString(asset.Data); |
317 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 348 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
318 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); | 349 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); |
350 | StoreScriptErrors(item.ItemID, null); | ||
319 | m_part.ParentGroup.AddActiveScriptCount(1); | 351 | m_part.ParentGroup.AddActiveScriptCount(1); |
320 | m_part.ScheduleFullUpdate(); | 352 | m_part.ScheduleFullUpdate(); |
321 | } | 353 | } |
@@ -379,21 +411,145 @@ namespace OpenSim.Region.Framework.Scenes | |||
379 | 411 | ||
380 | /// <summary> | 412 | /// <summary> |
381 | /// Start a script which is in this prim's inventory. | 413 | /// Start a script which is in this prim's inventory. |
414 | /// Some processing may occur in the background, but this routine returns asap. | ||
382 | /// </summary> | 415 | /// </summary> |
383 | /// <param name="itemId"> | 416 | /// <param name="itemId"> |
384 | /// A <see cref="UUID"/> | 417 | /// A <see cref="UUID"/> |
385 | /// </param> | 418 | /// </param> |
386 | public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | 419 | public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) |
387 | { | 420 | { |
388 | TaskInventoryItem item = GetInventoryItem(itemId); | 421 | lock (m_scriptErrors) |
389 | if (item != null) | 422 | { |
390 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | 423 | // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion |
424 | m_scriptErrors.Remove(itemId); | ||
425 | } | ||
426 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
427 | } | ||
428 | |||
429 | private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
430 | { | ||
431 | m_items.LockItemsForRead(true); | ||
432 | if (m_items.ContainsKey(itemId)) | ||
433 | { | ||
434 | if (m_items.ContainsKey(itemId)) | ||
435 | { | ||
436 | m_items.LockItemsForRead(false); | ||
437 | CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); | ||
438 | } | ||
439 | else | ||
440 | { | ||
441 | m_items.LockItemsForRead(false); | ||
442 | string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID, | ||
443 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
444 | StoreScriptError(itemId, msg); | ||
445 | m_log.ErrorFormat( | ||
446 | "[PRIM INVENTORY]: " + | ||
447 | "Couldn't start script with ID {0} since it {1}", itemId, msg); | ||
448 | } | ||
449 | } | ||
391 | else | 450 | else |
451 | { | ||
452 | m_items.LockItemsForRead(false); | ||
453 | string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID); | ||
454 | StoreScriptError(itemId, msg); | ||
392 | m_log.ErrorFormat( | 455 | m_log.ErrorFormat( |
393 | "[PRIM INVENTORY]: " + | 456 | "[PRIM INVENTORY]: " + |
394 | "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", | 457 | "Couldn't start script with ID {0} since it {1}", itemId, msg); |
395 | itemId, m_part.Name, m_part.UUID, | 458 | } |
396 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 459 | |
460 | } | ||
461 | |||
462 | /// <summary> | ||
463 | /// Start a script which is in this prim's inventory and return any compilation error messages. | ||
464 | /// </summary> | ||
465 | /// <param name="itemId"> | ||
466 | /// A <see cref="UUID"/> | ||
467 | /// </param> | ||
468 | public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
469 | { | ||
470 | ArrayList errors; | ||
471 | |||
472 | // Indicate to CreateScriptInstanceInternal() we want it to | ||
473 | // post any compilation/loading error messages | ||
474 | lock (m_scriptErrors) | ||
475 | { | ||
476 | m_scriptErrors[itemId] = null; | ||
477 | } | ||
478 | |||
479 | // Perform compilation/loading | ||
480 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
481 | |||
482 | // Wait for and retrieve any errors | ||
483 | lock (m_scriptErrors) | ||
484 | { | ||
485 | while ((errors = m_scriptErrors[itemId]) == null) | ||
486 | { | ||
487 | if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000)) | ||
488 | { | ||
489 | m_log.ErrorFormat( | ||
490 | "[PRIM INVENTORY]: " + | ||
491 | "timedout waiting for script {0} errors", itemId); | ||
492 | errors = m_scriptErrors[itemId]; | ||
493 | if (errors == null) | ||
494 | { | ||
495 | errors = new ArrayList(1); | ||
496 | errors.Add("timedout waiting for errors"); | ||
497 | } | ||
498 | break; | ||
499 | } | ||
500 | } | ||
501 | m_scriptErrors.Remove(itemId); | ||
502 | } | ||
503 | return errors; | ||
504 | } | ||
505 | |||
506 | // Signal to CreateScriptInstanceEr() that compilation/loading is complete | ||
507 | private void StoreScriptErrors(UUID itemId, ArrayList errors) | ||
508 | { | ||
509 | lock (m_scriptErrors) | ||
510 | { | ||
511 | // If compilation/loading initiated via CreateScriptInstance(), | ||
512 | // it does not want the errors, so just get out | ||
513 | if (!m_scriptErrors.ContainsKey(itemId)) | ||
514 | { | ||
515 | return; | ||
516 | } | ||
517 | |||
518 | // Initiated via CreateScriptInstanceEr(), if we know what the | ||
519 | // errors are, save them and wake CreateScriptInstanceEr(). | ||
520 | if (errors != null) | ||
521 | { | ||
522 | m_scriptErrors[itemId] = errors; | ||
523 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
524 | return; | ||
525 | } | ||
526 | } | ||
527 | |||
528 | // Initiated via CreateScriptInstanceEr() but we don't know what | ||
529 | // the errors are yet, so retrieve them from the script engine. | ||
530 | // This may involve some waiting internal to GetScriptErrors(). | ||
531 | errors = GetScriptErrors(itemId); | ||
532 | |||
533 | // Get a default non-null value to indicate success. | ||
534 | if (errors == null) | ||
535 | { | ||
536 | errors = new ArrayList(); | ||
537 | } | ||
538 | |||
539 | // Post to CreateScriptInstanceEr() and wake it up | ||
540 | lock (m_scriptErrors) | ||
541 | { | ||
542 | m_scriptErrors[itemId] = errors; | ||
543 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
544 | } | ||
545 | } | ||
546 | |||
547 | // Like StoreScriptErrors(), but just posts a single string message | ||
548 | private void StoreScriptError(UUID itemId, string message) | ||
549 | { | ||
550 | ArrayList errors = new ArrayList(1); | ||
551 | errors.Add(message); | ||
552 | StoreScriptErrors(itemId, errors); | ||
397 | } | 553 | } |
398 | 554 | ||
399 | /// <summary> | 555 | /// <summary> |
@@ -406,15 +562,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
406 | /// </param> | 562 | /// </param> |
407 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) | 563 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) |
408 | { | 564 | { |
409 | bool scriptPresent = false; | 565 | if (m_items.ContainsKey(itemId)) |
410 | |||
411 | lock (m_items) | ||
412 | { | ||
413 | if (m_items.ContainsKey(itemId)) | ||
414 | scriptPresent = true; | ||
415 | } | ||
416 | |||
417 | if (scriptPresent) | ||
418 | { | 566 | { |
419 | if (!sceneObjectBeingDeleted) | 567 | if (!sceneObjectBeingDeleted) |
420 | m_part.RemoveScriptEvents(itemId); | 568 | m_part.RemoveScriptEvents(itemId); |
@@ -439,14 +587,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
439 | /// <returns></returns> | 587 | /// <returns></returns> |
440 | private bool InventoryContainsName(string name) | 588 | private bool InventoryContainsName(string name) |
441 | { | 589 | { |
442 | lock (m_items) | 590 | m_items.LockItemsForRead(true); |
591 | foreach (TaskInventoryItem item in m_items.Values) | ||
443 | { | 592 | { |
444 | foreach (TaskInventoryItem item in m_items.Values) | 593 | if (item.Name == name) |
445 | { | 594 | { |
446 | if (item.Name == name) | 595 | m_items.LockItemsForRead(false); |
447 | return true; | 596 | return true; |
448 | } | 597 | } |
449 | } | 598 | } |
599 | m_items.LockItemsForRead(false); | ||
450 | return false; | 600 | return false; |
451 | } | 601 | } |
452 | 602 | ||
@@ -488,8 +638,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
488 | /// <param name="item"></param> | 638 | /// <param name="item"></param> |
489 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) | 639 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) |
490 | { | 640 | { |
491 | List<TaskInventoryItem> il = GetInventoryItems(); | 641 | m_items.LockItemsForRead(true); |
492 | 642 | List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); | |
643 | m_items.LockItemsForRead(false); | ||
493 | foreach (TaskInventoryItem i in il) | 644 | foreach (TaskInventoryItem i in il) |
494 | { | 645 | { |
495 | if (i.Name == item.Name) | 646 | if (i.Name == item.Name) |
@@ -527,14 +678,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
527 | item.Name = name; | 678 | item.Name = name; |
528 | item.GroupID = m_part.GroupID; | 679 | item.GroupID = m_part.GroupID; |
529 | 680 | ||
530 | lock (m_items) | 681 | m_items.LockItemsForWrite(true); |
531 | m_items.Add(item.ItemID, item); | 682 | m_items.Add(item.ItemID, item); |
532 | 683 | m_items.LockItemsForWrite(false); | |
533 | if (allowedDrop) | 684 | if (allowedDrop) |
534 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); | 685 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); |
535 | else | 686 | else |
536 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 687 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
537 | 688 | ||
538 | m_inventorySerial++; | 689 | m_inventorySerial++; |
539 | //m_inventorySerial += 2; | 690 | //m_inventorySerial += 2; |
540 | HasInventoryChanged = true; | 691 | HasInventoryChanged = true; |
@@ -550,15 +701,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
550 | /// <param name="items"></param> | 701 | /// <param name="items"></param> |
551 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) | 702 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) |
552 | { | 703 | { |
553 | lock (m_items) | 704 | m_items.LockItemsForWrite(true); |
705 | foreach (TaskInventoryItem item in items) | ||
554 | { | 706 | { |
555 | foreach (TaskInventoryItem item in items) | 707 | m_items.Add(item.ItemID, item); |
556 | { | 708 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
557 | m_items.Add(item.ItemID, item); | ||
558 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
559 | } | ||
560 | m_inventorySerial++; | ||
561 | } | 709 | } |
710 | m_items.LockItemsForWrite(false); | ||
711 | |||
712 | m_inventorySerial++; | ||
562 | } | 713 | } |
563 | 714 | ||
564 | /// <summary> | 715 | /// <summary> |
@@ -569,10 +720,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
569 | public TaskInventoryItem GetInventoryItem(UUID itemId) | 720 | public TaskInventoryItem GetInventoryItem(UUID itemId) |
570 | { | 721 | { |
571 | TaskInventoryItem item; | 722 | TaskInventoryItem item; |
572 | 723 | m_items.LockItemsForRead(true); | |
573 | lock (m_items) | 724 | m_items.TryGetValue(itemId, out item); |
574 | m_items.TryGetValue(itemId, out item); | 725 | m_items.LockItemsForRead(false); |
575 | |||
576 | return item; | 726 | return item; |
577 | } | 727 | } |
578 | 728 | ||
@@ -588,15 +738,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
588 | { | 738 | { |
589 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); | 739 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(); |
590 | 740 | ||
591 | lock (m_items) | 741 | m_items.LockItemsForRead(true); |
742 | |||
743 | foreach (TaskInventoryItem item in m_items.Values) | ||
592 | { | 744 | { |
593 | foreach (TaskInventoryItem item in m_items.Values) | 745 | if (item.Name == name) |
594 | { | 746 | items.Add(item); |
595 | if (item.Name == name) | ||
596 | items.Add(item); | ||
597 | } | ||
598 | } | 747 | } |
599 | 748 | ||
749 | m_items.LockItemsForRead(false); | ||
750 | |||
600 | return items; | 751 | return items; |
601 | } | 752 | } |
602 | 753 | ||
@@ -679,9 +830,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
679 | 830 | ||
680 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) | 831 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) |
681 | { | 832 | { |
682 | TaskInventoryItem it = GetInventoryItem(item.ItemID); | 833 | m_items.LockItemsForWrite(true); |
683 | if (it != null) | ||
684 | 834 | ||
835 | if (m_items.ContainsKey(item.ItemID)) | ||
685 | { | 836 | { |
686 | item.ParentID = m_part.UUID; | 837 | item.ParentID = m_part.UUID; |
687 | item.ParentPartID = m_part.UUID; | 838 | item.ParentPartID = m_part.UUID; |
@@ -693,14 +844,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
693 | item.GroupID = m_part.GroupID; | 844 | item.GroupID = m_part.GroupID; |
694 | 845 | ||
695 | if (item.AssetID == UUID.Zero) | 846 | if (item.AssetID == UUID.Zero) |
696 | item.AssetID = it.AssetID; | 847 | item.AssetID = m_items[item.ItemID].AssetID; |
697 | |||
698 | lock (m_items) | ||
699 | { | ||
700 | m_items[item.ItemID] = item; | ||
701 | m_inventorySerial++; | ||
702 | } | ||
703 | 848 | ||
849 | m_items[item.ItemID] = item; | ||
850 | m_inventorySerial++; | ||
704 | if (fireScriptEvents) | 851 | if (fireScriptEvents) |
705 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 852 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
706 | if (considerChanged) | 853 | if (considerChanged) |
@@ -708,6 +855,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
708 | HasInventoryChanged = true; | 855 | HasInventoryChanged = true; |
709 | m_part.ParentGroup.HasGroupChanged = true; | 856 | m_part.ParentGroup.HasGroupChanged = true; |
710 | } | 857 | } |
858 | m_items.LockItemsForWrite(false); | ||
711 | return true; | 859 | return true; |
712 | } | 860 | } |
713 | else | 861 | else |
@@ -718,8 +866,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
718 | item.ItemID, m_part.Name, m_part.UUID, | 866 | item.ItemID, m_part.Name, m_part.UUID, |
719 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 867 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
720 | } | 868 | } |
721 | return false; | 869 | m_items.LockItemsForWrite(false); |
722 | 870 | ||
871 | return false; | ||
723 | } | 872 | } |
724 | 873 | ||
725 | /// <summary> | 874 | /// <summary> |
@@ -730,107 +879,68 @@ namespace OpenSim.Region.Framework.Scenes | |||
730 | /// in this prim's inventory.</returns> | 879 | /// in this prim's inventory.</returns> |
731 | public int RemoveInventoryItem(UUID itemID) | 880 | public int RemoveInventoryItem(UUID itemID) |
732 | { | 881 | { |
733 | TaskInventoryItem item = GetInventoryItem(itemID); | 882 | m_items.LockItemsForRead(true); |
734 | if (item != null) | 883 | |
884 | if (m_items.ContainsKey(itemID)) | ||
735 | { | 885 | { |
736 | int type = m_items[itemID].InvType; | 886 | int type = m_items[itemID].InvType; |
887 | m_items.LockItemsForRead(false); | ||
737 | if (type == 10) // Script | 888 | if (type == 10) // Script |
738 | { | 889 | { |
739 | m_part.RemoveScriptEvents(itemID); | ||
740 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); | 890 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); |
741 | } | 891 | } |
892 | m_items.LockItemsForWrite(true); | ||
742 | m_items.Remove(itemID); | 893 | m_items.Remove(itemID); |
894 | m_items.LockItemsForWrite(false); | ||
743 | m_inventorySerial++; | 895 | m_inventorySerial++; |
744 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 896 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
745 | 897 | ||
746 | HasInventoryChanged = true; | 898 | HasInventoryChanged = true; |
747 | m_part.ParentGroup.HasGroupChanged = true; | 899 | m_part.ParentGroup.HasGroupChanged = true; |
748 | 900 | ||
749 | if (!ContainsScripts()) | 901 | int scriptcount = 0; |
902 | m_items.LockItemsForRead(true); | ||
903 | foreach (TaskInventoryItem item in m_items.Values) | ||
904 | { | ||
905 | if (item.Type == 10) | ||
906 | { | ||
907 | scriptcount++; | ||
908 | } | ||
909 | } | ||
910 | m_items.LockItemsForRead(false); | ||
911 | |||
912 | |||
913 | if (scriptcount <= 0) | ||
914 | { | ||
750 | m_part.RemFlag(PrimFlags.Scripted); | 915 | m_part.RemFlag(PrimFlags.Scripted); |
916 | } | ||
751 | 917 | ||
752 | m_part.ScheduleFullUpdate(); | 918 | m_part.ScheduleFullUpdate(); |
753 | 919 | ||
754 | return type; | 920 | return type; |
755 | |||
756 | } | 921 | } |
757 | else | 922 | else |
758 | { | 923 | { |
924 | m_items.LockItemsForRead(false); | ||
759 | m_log.ErrorFormat( | 925 | m_log.ErrorFormat( |
760 | "[PRIM INVENTORY]: " + | 926 | "[PRIM INVENTORY]: " + |
761 | "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", | 927 | "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", |
762 | itemID, m_part.Name, m_part.UUID, | 928 | itemID, m_part.Name, m_part.UUID); |
763 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
764 | } | 929 | } |
765 | 930 | ||
766 | return -1; | 931 | return -1; |
767 | } | 932 | } |
768 | 933 | ||
769 | private bool CreateInventoryFile() | 934 | private bool CreateInventoryFileName() |
770 | { | 935 | { |
771 | if (m_inventoryFileName == String.Empty || | 936 | if (m_inventoryFileName == String.Empty || |
772 | m_inventoryFileNameSerial < m_inventorySerial) | 937 | m_inventoryFileNameSerial < m_inventorySerial) |
773 | { | 938 | { |
774 | // Something changed, we need to create a new file | ||
775 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; | 939 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; |
776 | m_inventoryFileNameSerial = m_inventorySerial; | 940 | m_inventoryFileNameSerial = m_inventorySerial; |
777 | |||
778 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | ||
779 | |||
780 | lock (m_items) | ||
781 | { | ||
782 | foreach (TaskInventoryItem item in m_items.Values) | ||
783 | { | ||
784 | UUID ownerID = item.OwnerID; | ||
785 | uint everyoneMask = 0; | ||
786 | uint baseMask = item.BasePermissions; | ||
787 | uint ownerMask = item.CurrentPermissions; | ||
788 | uint groupMask = item.GroupPermissions; | ||
789 | |||
790 | invString.AddItemStart(); | ||
791 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
792 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
793 | |||
794 | invString.AddPermissionsStart(); | ||
795 | |||
796 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | ||
797 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
798 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
799 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
800 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
801 | |||
802 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | ||
803 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
804 | |||
805 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
806 | |||
807 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | ||
808 | invString.AddSectionEnd(); | ||
809 | |||
810 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
811 | invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); | ||
812 | invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); | ||
813 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
814 | |||
815 | invString.AddSaleStart(); | ||
816 | invString.AddNameValueLine("sale_type", "not"); | ||
817 | invString.AddNameValueLine("sale_price", "0"); | ||
818 | invString.AddSectionEnd(); | ||
819 | |||
820 | invString.AddNameValueLine("name", item.Name + "|"); | ||
821 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
822 | |||
823 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
824 | invString.AddSectionEnd(); | ||
825 | } | ||
826 | } | ||
827 | |||
828 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | ||
829 | |||
830 | return true; | 941 | return true; |
831 | } | 942 | } |
832 | 943 | ||
833 | // No need to recreate, the existing file is fine | ||
834 | return false; | 944 | return false; |
835 | } | 945 | } |
836 | 946 | ||
@@ -840,26 +950,94 @@ namespace OpenSim.Region.Framework.Scenes | |||
840 | /// <param name="xferManager"></param> | 950 | /// <param name="xferManager"></param> |
841 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) | 951 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) |
842 | { | 952 | { |
843 | bool changed = CreateInventoryFile(); | 953 | bool changed = CreateInventoryFileName(); |
954 | |||
955 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | ||
956 | |||
957 | Items.LockItemsForRead(true); | ||
844 | 958 | ||
845 | if (m_inventorySerial == 0) // No inventory | 959 | if (m_inventorySerial == 0) // No inventory |
846 | { | 960 | { |
847 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | 961 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); |
962 | Items.LockItemsForRead(false); | ||
848 | return; | 963 | return; |
849 | } | 964 | } |
850 | 965 | ||
851 | // In principle, we should only do the rest if the inventory changed; | 966 | if (!changed) |
852 | // by sending m_inventorySerial to the client, it ought to know | 967 | { |
853 | // that nothing changed and that it doesn't need to request the file. | 968 | if (m_inventoryFileData.Length > 2) |
854 | // Unfortunately, it doesn't look like the client optimizes this; | 969 | { |
855 | // the client seems to always come back and request the Xfer, | 970 | xferManager.AddNewFile(m_inventoryFileName, |
856 | // no matter what value m_inventorySerial has. | 971 | m_inventoryFileData); |
972 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | ||
973 | Util.StringToBytes256(m_inventoryFileName)); | ||
974 | |||
975 | Items.LockItemsForRead(false); | ||
976 | return; | ||
977 | } | ||
978 | } | ||
979 | |||
980 | bool includeAssets = false; | ||
981 | if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) | ||
982 | includeAssets = true; | ||
983 | |||
984 | foreach (TaskInventoryItem item in m_items.Values) | ||
985 | { | ||
986 | UUID ownerID = item.OwnerID; | ||
987 | uint everyoneMask = 0; | ||
988 | uint baseMask = item.BasePermissions; | ||
989 | uint ownerMask = item.CurrentPermissions; | ||
990 | uint groupMask = item.GroupPermissions; | ||
991 | |||
992 | invString.AddItemStart(); | ||
993 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
994 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
995 | |||
996 | invString.AddPermissionsStart(); | ||
997 | |||
998 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | ||
999 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
1000 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
1001 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
1002 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
1003 | |||
1004 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | ||
1005 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
1006 | |||
1007 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
1008 | |||
1009 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | ||
1010 | invString.AddSectionEnd(); | ||
1011 | |||
1012 | if (includeAssets) | ||
1013 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
1014 | else | ||
1015 | invString.AddNameValueLine("asset_id", UUID.Zero.ToString()); | ||
1016 | invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); | ||
1017 | invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); | ||
1018 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
1019 | |||
1020 | invString.AddSaleStart(); | ||
1021 | invString.AddNameValueLine("sale_type", "not"); | ||
1022 | invString.AddNameValueLine("sale_price", "0"); | ||
1023 | invString.AddSectionEnd(); | ||
1024 | |||
1025 | invString.AddNameValueLine("name", item.Name + "|"); | ||
1026 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
1027 | |||
1028 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
1029 | invString.AddSectionEnd(); | ||
1030 | } | ||
1031 | |||
1032 | Items.LockItemsForRead(false); | ||
1033 | |||
1034 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | ||
857 | 1035 | ||
858 | if (m_inventoryFileData.Length > 2) | 1036 | if (m_inventoryFileData.Length > 2) |
859 | // Add the file for Xfer | 1037 | { |
860 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | 1038 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); |
1039 | } | ||
861 | 1040 | ||
862 | // Tell the client we're ready to Xfer the file | ||
863 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | 1041 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, |
864 | Util.StringToBytes256(m_inventoryFileName)); | 1042 | Util.StringToBytes256(m_inventoryFileName)); |
865 | } | 1043 | } |
@@ -872,10 +1050,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
872 | { | 1050 | { |
873 | if (HasInventoryChanged) | 1051 | if (HasInventoryChanged) |
874 | { | 1052 | { |
875 | HasInventoryChanged = false; | 1053 | Items.LockItemsForRead(true); |
876 | List<TaskInventoryItem> items = GetInventoryItems(); | 1054 | datastore.StorePrimInventory(m_part.UUID, Items.Values); |
877 | datastore.StorePrimInventory(m_part.UUID, items); | 1055 | Items.LockItemsForRead(false); |
878 | 1056 | ||
1057 | HasInventoryChanged = false; | ||
879 | } | 1058 | } |
880 | } | 1059 | } |
881 | 1060 | ||
@@ -942,89 +1121,75 @@ namespace OpenSim.Region.Framework.Scenes | |||
942 | { | 1121 | { |
943 | uint mask=0x7fffffff; | 1122 | uint mask=0x7fffffff; |
944 | 1123 | ||
945 | lock (m_items) | 1124 | foreach (TaskInventoryItem item in m_items.Values) |
946 | { | 1125 | { |
947 | foreach (TaskInventoryItem item in m_items.Values) | 1126 | if (item.InvType != (int)InventoryType.Object) |
948 | { | 1127 | { |
949 | if (item.InvType != (int)InventoryType.Object) | 1128 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) |
950 | { | 1129 | mask &= ~((uint)PermissionMask.Copy >> 13); |
951 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | 1130 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) |
952 | mask &= ~((uint)PermissionMask.Copy >> 13); | 1131 | mask &= ~((uint)PermissionMask.Transfer >> 13); |
953 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | 1132 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) |
954 | mask &= ~((uint)PermissionMask.Transfer >> 13); | 1133 | mask &= ~((uint)PermissionMask.Modify >> 13); |
955 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | 1134 | } |
956 | mask &= ~((uint)PermissionMask.Modify >> 13); | 1135 | else |
957 | } | 1136 | { |
958 | else | 1137 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
959 | { | 1138 | mask &= ~((uint)PermissionMask.Copy >> 13); |
960 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | 1139 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
961 | mask &= ~((uint)PermissionMask.Copy >> 13); | 1140 | mask &= ~((uint)PermissionMask.Transfer >> 13); |
962 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | 1141 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
963 | mask &= ~((uint)PermissionMask.Transfer >> 13); | 1142 | mask &= ~((uint)PermissionMask.Modify >> 13); |
964 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
965 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
966 | } | ||
967 | |||
968 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
969 | mask &= ~(uint)PermissionMask.Copy; | ||
970 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
971 | mask &= ~(uint)PermissionMask.Transfer; | ||
972 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
973 | mask &= ~(uint)PermissionMask.Modify; | ||
974 | } | 1143 | } |
1144 | |||
1145 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1146 | mask &= ~(uint)PermissionMask.Copy; | ||
1147 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1148 | mask &= ~(uint)PermissionMask.Transfer; | ||
1149 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
1150 | mask &= ~(uint)PermissionMask.Modify; | ||
975 | } | 1151 | } |
976 | |||
977 | return mask; | 1152 | return mask; |
978 | } | 1153 | } |
979 | 1154 | ||
980 | public void ApplyNextOwnerPermissions() | 1155 | public void ApplyNextOwnerPermissions() |
981 | { | 1156 | { |
982 | lock (m_items) | 1157 | foreach (TaskInventoryItem item in m_items.Values) |
983 | { | 1158 | { |
984 | foreach (TaskInventoryItem item in m_items.Values) | 1159 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) |
985 | { | 1160 | { |
986 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) | 1161 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
987 | { | 1162 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; |
988 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | 1163 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
989 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; | 1164 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; |
990 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | 1165 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
991 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | 1166 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; |
992 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
993 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; | ||
994 | } | ||
995 | item.CurrentPermissions &= item.NextPermissions; | ||
996 | item.BasePermissions &= item.NextPermissions; | ||
997 | item.EveryonePermissions &= item.NextPermissions; | ||
998 | item.OwnerChanged = true; | ||
999 | } | 1167 | } |
1168 | item.OwnerChanged = true; | ||
1169 | item.CurrentPermissions &= item.NextPermissions; | ||
1170 | item.BasePermissions &= item.NextPermissions; | ||
1171 | item.EveryonePermissions &= item.NextPermissions; | ||
1000 | } | 1172 | } |
1001 | } | 1173 | } |
1002 | 1174 | ||
1003 | public void ApplyGodPermissions(uint perms) | 1175 | public void ApplyGodPermissions(uint perms) |
1004 | { | 1176 | { |
1005 | lock (m_items) | 1177 | foreach (TaskInventoryItem item in m_items.Values) |
1006 | { | 1178 | { |
1007 | foreach (TaskInventoryItem item in m_items.Values) | 1179 | item.CurrentPermissions = perms; |
1008 | { | 1180 | item.BasePermissions = perms; |
1009 | item.CurrentPermissions = perms; | ||
1010 | item.BasePermissions = perms; | ||
1011 | } | ||
1012 | } | 1181 | } |
1013 | } | 1182 | } |
1014 | 1183 | ||
1015 | public bool ContainsScripts() | 1184 | public bool ContainsScripts() |
1016 | { | 1185 | { |
1017 | lock (m_items) | 1186 | foreach (TaskInventoryItem item in m_items.Values) |
1018 | { | 1187 | { |
1019 | foreach (TaskInventoryItem item in m_items.Values) | 1188 | if (item.InvType == (int)InventoryType.LSL) |
1020 | { | 1189 | { |
1021 | if (item.InvType == (int)InventoryType.LSL) | 1190 | return true; |
1022 | { | ||
1023 | return true; | ||
1024 | } | ||
1025 | } | 1191 | } |
1026 | } | 1192 | } |
1027 | |||
1028 | return false; | 1193 | return false; |
1029 | } | 1194 | } |
1030 | 1195 | ||
@@ -1032,11 +1197,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1032 | { | 1197 | { |
1033 | List<UUID> ret = new List<UUID>(); | 1198 | List<UUID> ret = new List<UUID>(); |
1034 | 1199 | ||
1035 | lock (m_items) | 1200 | foreach (TaskInventoryItem item in m_items.Values) |
1036 | { | 1201 | ret.Add(item.ItemID); |
1037 | foreach (TaskInventoryItem item in m_items.Values) | ||
1038 | ret.Add(item.ItemID); | ||
1039 | } | ||
1040 | 1202 | ||
1041 | return ret; | 1203 | return ret; |
1042 | } | 1204 | } |
@@ -1067,31 +1229,46 @@ namespace OpenSim.Region.Framework.Scenes | |||
1067 | 1229 | ||
1068 | public Dictionary<UUID, string> GetScriptStates() | 1230 | public Dictionary<UUID, string> GetScriptStates() |
1069 | { | 1231 | { |
1232 | return GetScriptStates(false); | ||
1233 | } | ||
1234 | |||
1235 | public Dictionary<UUID, string> GetScriptStates(bool oldIDs) | ||
1236 | { | ||
1070 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); | 1237 | IScriptModule[] engines = m_part.ParentGroup.Scene.RequestModuleInterfaces<IScriptModule>(); |
1071 | 1238 | ||
1072 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); | 1239 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); |
1073 | if (engines == null) // No engine at all | 1240 | if (engines == null) // No engine at all |
1074 | return ret; | 1241 | return ret; |
1075 | 1242 | ||
1076 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | 1243 | Items.LockItemsForRead(true); |
1077 | 1244 | foreach (TaskInventoryItem item in m_items.Values) | |
1078 | foreach (TaskInventoryItem item in scripts) | ||
1079 | { | 1245 | { |
1080 | foreach (IScriptModule e in engines) | 1246 | if (item.InvType == (int)InventoryType.LSL) |
1081 | { | 1247 | { |
1082 | if (e != null) | 1248 | foreach (IScriptModule e in engines) |
1083 | { | 1249 | { |
1084 | string n = e.GetXMLState(item.ItemID); | 1250 | if (e != null) |
1085 | if (n != String.Empty) | ||
1086 | { | 1251 | { |
1087 | if (!ret.ContainsKey(item.ItemID)) | 1252 | string n = e.GetXMLState(item.ItemID); |
1088 | ret[item.ItemID] = n; | 1253 | if (n != String.Empty) |
1089 | break; | 1254 | { |
1255 | if (oldIDs) | ||
1256 | { | ||
1257 | if (!ret.ContainsKey(item.OldItemID)) | ||
1258 | ret[item.OldItemID] = n; | ||
1259 | } | ||
1260 | else | ||
1261 | { | ||
1262 | if (!ret.ContainsKey(item.ItemID)) | ||
1263 | ret[item.ItemID] = n; | ||
1264 | } | ||
1265 | break; | ||
1266 | } | ||
1090 | } | 1267 | } |
1091 | } | 1268 | } |
1092 | } | 1269 | } |
1093 | } | 1270 | } |
1094 | 1271 | Items.LockItemsForRead(false); | |
1095 | return ret; | 1272 | return ret; |
1096 | } | 1273 | } |
1097 | 1274 | ||
@@ -1101,21 +1278,27 @@ namespace OpenSim.Region.Framework.Scenes | |||
1101 | if (engines == null) | 1278 | if (engines == null) |
1102 | return; | 1279 | return; |
1103 | 1280 | ||
1104 | List<TaskInventoryItem> scripts = GetInventoryScripts(); | ||
1105 | 1281 | ||
1106 | foreach (TaskInventoryItem item in scripts) | 1282 | Items.LockItemsForRead(true); |
1283 | |||
1284 | foreach (TaskInventoryItem item in m_items.Values) | ||
1107 | { | 1285 | { |
1108 | foreach (IScriptModule engine in engines) | 1286 | if (item.InvType == (int)InventoryType.LSL) |
1109 | { | 1287 | { |
1110 | if (engine != null) | 1288 | foreach (IScriptModule engine in engines) |
1111 | { | 1289 | { |
1112 | if (item.OwnerChanged) | 1290 | if (engine != null) |
1113 | engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); | 1291 | { |
1114 | item.OwnerChanged = false; | 1292 | if (item.OwnerChanged) |
1115 | engine.ResumeScript(item.ItemID); | 1293 | engine.PostScriptEvent(item.ItemID, "changed", new Object[] { (int)Changed.OWNER }); |
1294 | item.OwnerChanged = false; | ||
1295 | engine.ResumeScript(item.ItemID); | ||
1296 | } | ||
1116 | } | 1297 | } |
1117 | } | 1298 | } |
1118 | } | 1299 | } |
1300 | |||
1301 | Items.LockItemsForRead(false); | ||
1119 | } | 1302 | } |
1120 | } | 1303 | } |
1121 | } | 1304 | } |