diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 767 |
1 files changed, 465 insertions, 302 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index db723fa..3a9a146 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -48,6 +48,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
48 | private string m_inventoryFileName = String.Empty; | 48 | private string m_inventoryFileName = String.Empty; |
49 | private byte[] m_inventoryFileData = new byte[0]; | 49 | private byte[] m_inventoryFileData = new byte[0]; |
50 | private uint m_inventoryFileNameSerial = 0; | 50 | private uint m_inventoryFileNameSerial = 0; |
51 | private bool m_inventoryPrivileged = false; | ||
52 | |||
53 | private Dictionary<UUID, ArrayList> m_scriptErrors = new Dictionary<UUID, ArrayList>(); | ||
51 | 54 | ||
52 | /// <value> | 55 | /// <value> |
53 | /// The part to which the inventory belongs. | 56 | /// The part to which the inventory belongs. |
@@ -84,7 +87,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
84 | /// </value> | 87 | /// </value> |
85 | protected internal TaskInventoryDictionary Items | 88 | protected internal TaskInventoryDictionary Items |
86 | { | 89 | { |
87 | get { return m_items; } | 90 | get { |
91 | return m_items; | ||
92 | } | ||
88 | set | 93 | set |
89 | { | 94 | { |
90 | m_items = value; | 95 | m_items = value; |
@@ -133,38 +138,45 @@ namespace OpenSim.Region.Framework.Scenes | |||
133 | public void ResetInventoryIDs() | 138 | public void ResetInventoryIDs() |
134 | { | 139 | { |
135 | if (null == m_part) | 140 | if (null == m_part) |
136 | return; | 141 | m_items.LockItemsForWrite(true); |
137 | 142 | ||
138 | lock (m_items) | 143 | if (Items.Count == 0) |
139 | { | 144 | { |
140 | if (0 == m_items.Count) | 145 | m_items.LockItemsForWrite(false); |
141 | return; | 146 | return; |
147 | } | ||
142 | 148 | ||
143 | IList<TaskInventoryItem> items = GetInventoryItems(); | 149 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
144 | m_items.Clear(); | 150 | Items.Clear(); |
145 | 151 | ||
146 | foreach (TaskInventoryItem item in items) | 152 | foreach (TaskInventoryItem item in items) |
147 | { | 153 | { |
148 | item.ResetIDs(m_part.UUID); | 154 | item.ResetIDs(m_part.UUID); |
149 | m_items.Add(item.ItemID, item); | 155 | Items.Add(item.ItemID, item); |
150 | } | ||
151 | } | 156 | } |
157 | m_items.LockItemsForWrite(false); | ||
152 | } | 158 | } |
153 | 159 | ||
154 | public void ResetObjectID() | 160 | public void ResetObjectID() |
155 | { | 161 | { |
156 | lock (Items) | 162 | m_items.LockItemsForWrite(true); |
163 | |||
164 | if (Items.Count == 0) | ||
157 | { | 165 | { |
158 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | 166 | m_items.LockItemsForWrite(false); |
159 | Items.Clear(); | 167 | return; |
160 | |||
161 | foreach (TaskInventoryItem item in items) | ||
162 | { | ||
163 | item.ParentPartID = m_part.UUID; | ||
164 | item.ParentID = m_part.UUID; | ||
165 | Items.Add(item.ItemID, item); | ||
166 | } | ||
167 | } | 168 | } |
169 | |||
170 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | ||
171 | Items.Clear(); | ||
172 | |||
173 | foreach (TaskInventoryItem item in items) | ||
174 | { | ||
175 | item.ParentPartID = m_part.UUID; | ||
176 | item.ParentID = m_part.UUID; | ||
177 | Items.Add(item.ItemID, item); | ||
178 | } | ||
179 | m_items.LockItemsForWrite(false); | ||
168 | } | 180 | } |
169 | 181 | ||
170 | /// <summary> | 182 | /// <summary> |
@@ -173,17 +185,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
173 | /// <param name="ownerId"></param> | 185 | /// <param name="ownerId"></param> |
174 | public void ChangeInventoryOwner(UUID ownerId) | 186 | public void ChangeInventoryOwner(UUID ownerId) |
175 | { | 187 | { |
176 | lock (Items) | 188 | List<TaskInventoryItem> items = GetInventoryItems(); |
177 | { | 189 | |
178 | if (0 == Items.Count) | 190 | if (items.Count == 0) |
179 | { | 191 | return; |
180 | return; | ||
181 | } | ||
182 | } | ||
183 | 192 | ||
193 | m_items.LockItemsForWrite(true); | ||
184 | HasInventoryChanged = true; | 194 | HasInventoryChanged = true; |
185 | m_part.ParentGroup.HasGroupChanged = true; | 195 | m_part.ParentGroup.HasGroupChanged = true; |
186 | List<TaskInventoryItem> items = GetInventoryItems(); | ||
187 | foreach (TaskInventoryItem item in items) | 196 | foreach (TaskInventoryItem item in items) |
188 | { | 197 | { |
189 | if (ownerId != item.OwnerID) | 198 | if (ownerId != item.OwnerID) |
@@ -194,6 +203,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
194 | item.PermsGranter = UUID.Zero; | 203 | item.PermsGranter = UUID.Zero; |
195 | item.OwnerChanged = true; | 204 | item.OwnerChanged = true; |
196 | } | 205 | } |
206 | m_items.LockItemsForWrite(false); | ||
197 | } | 207 | } |
198 | 208 | ||
199 | /// <summary> | 209 | /// <summary> |
@@ -202,12 +212,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
202 | /// <param name="groupID"></param> | 212 | /// <param name="groupID"></param> |
203 | public void ChangeInventoryGroup(UUID groupID) | 213 | public void ChangeInventoryGroup(UUID groupID) |
204 | { | 214 | { |
205 | lock (Items) | 215 | m_items.LockItemsForWrite(true); |
216 | if (0 == Items.Count) | ||
206 | { | 217 | { |
207 | if (0 == Items.Count) | 218 | m_items.LockItemsForWrite(false); |
208 | { | 219 | return; |
209 | return; | ||
210 | } | ||
211 | } | 220 | } |
212 | 221 | ||
213 | // Don't let this set the HasGroupChanged flag for attachments | 222 | // Don't let this set the HasGroupChanged flag for attachments |
@@ -219,12 +228,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
219 | m_part.ParentGroup.HasGroupChanged = true; | 228 | m_part.ParentGroup.HasGroupChanged = true; |
220 | } | 229 | } |
221 | 230 | ||
222 | List<TaskInventoryItem> items = GetInventoryItems(); | 231 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
223 | foreach (TaskInventoryItem item in items) | 232 | foreach (TaskInventoryItem item in items) |
224 | { | 233 | { |
225 | if (groupID != item.GroupID) | 234 | if (groupID != item.GroupID) |
235 | { | ||
226 | item.GroupID = groupID; | 236 | item.GroupID = groupID; |
237 | } | ||
227 | } | 238 | } |
239 | m_items.LockItemsForWrite(false); | ||
228 | } | 240 | } |
229 | 241 | ||
230 | private void QueryScriptStates() | 242 | private void QueryScriptStates() |
@@ -232,15 +244,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
232 | if (m_part == null || m_part.ParentGroup == null || m_part.ParentGroup.Scene == null) | 244 | if (m_part == null || m_part.ParentGroup == null || m_part.ParentGroup.Scene == null) |
233 | return; | 245 | return; |
234 | 246 | ||
235 | lock (Items) | 247 | Items.LockItemsForRead(true); |
248 | foreach (TaskInventoryItem item in Items.Values) | ||
236 | { | 249 | { |
237 | foreach (TaskInventoryItem item in Items.Values) | 250 | if (item.InvType == (int)InventoryType.LSL) |
238 | { | 251 | { |
239 | bool running; | 252 | bool running; |
240 | if (TryGetScriptInstanceRunning(m_part.ParentGroup.Scene, item, out running)) | 253 | if (TryGetScriptInstanceRunning(m_part.ParentGroup.Scene, item, out running)) |
241 | item.ScriptRunning = running; | 254 | item.ScriptRunning = running; |
242 | } | 255 | } |
243 | } | 256 | } |
257 | |||
258 | Items.LockItemsForRead(false); | ||
244 | } | 259 | } |
245 | 260 | ||
246 | public bool TryGetScriptInstanceRunning(UUID itemId, out bool running) | 261 | public bool TryGetScriptInstanceRunning(UUID itemId, out bool running) |
@@ -317,7 +332,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
317 | { | 332 | { |
318 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); | 333 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); |
319 | foreach (TaskInventoryItem item in scripts) | 334 | foreach (TaskInventoryItem item in scripts) |
335 | { | ||
320 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); | 336 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); |
337 | m_part.RemoveScriptEvents(item.ItemID); | ||
338 | } | ||
321 | } | 339 | } |
322 | 340 | ||
323 | /// <summary> | 341 | /// <summary> |
@@ -339,7 +357,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
339 | // item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 357 | // item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
340 | 358 | ||
341 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) | 359 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) |
360 | { | ||
361 | StoreScriptError(item.ItemID, "no permission"); | ||
342 | return false; | 362 | return false; |
363 | } | ||
343 | 364 | ||
344 | m_part.AddFlag(PrimFlags.Scripted); | 365 | m_part.AddFlag(PrimFlags.Scripted); |
345 | 366 | ||
@@ -349,14 +370,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
349 | if (stateSource == 2 && // Prim crossing | 370 | if (stateSource == 2 && // Prim crossing |
350 | m_part.ParentGroup.Scene.m_trustBinaries) | 371 | m_part.ParentGroup.Scene.m_trustBinaries) |
351 | { | 372 | { |
352 | lock (m_items) | 373 | m_items.LockItemsForWrite(true); |
353 | { | 374 | m_items[item.ItemID].PermsMask = 0; |
354 | m_items[item.ItemID].PermsMask = 0; | 375 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
355 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 376 | m_items.LockItemsForWrite(false); |
356 | } | ||
357 | |||
358 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 377 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
359 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); | 378 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); |
379 | StoreScriptErrors(item.ItemID, null); | ||
360 | m_part.ParentGroup.AddActiveScriptCount(1); | 380 | m_part.ParentGroup.AddActiveScriptCount(1); |
361 | m_part.ScheduleFullUpdate(); | 381 | m_part.ScheduleFullUpdate(); |
362 | return true; | 382 | return true; |
@@ -365,6 +385,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
365 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); | 385 | AssetBase asset = m_part.ParentGroup.Scene.AssetService.Get(item.AssetID.ToString()); |
366 | if (null == asset) | 386 | if (null == asset) |
367 | { | 387 | { |
388 | string msg = String.Format("asset ID {0} could not be found", item.AssetID); | ||
389 | StoreScriptError(item.ItemID, msg); | ||
368 | m_log.ErrorFormat( | 390 | m_log.ErrorFormat( |
369 | "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", | 391 | "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", |
370 | item.Name, item.ItemID, m_part.AbsolutePosition, | 392 | item.Name, item.ItemID, m_part.AbsolutePosition, |
@@ -377,16 +399,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
377 | if (m_part.ParentGroup.m_savedScriptState != null) | 399 | if (m_part.ParentGroup.m_savedScriptState != null) |
378 | item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); | 400 | item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); |
379 | 401 | ||
380 | lock (m_items) | 402 | m_items.LockItemsForWrite(true); |
381 | { | 403 | |
382 | m_items[item.ItemID].OldItemID = item.OldItemID; | 404 | m_items[item.ItemID].OldItemID = item.OldItemID; |
383 | m_items[item.ItemID].PermsMask = 0; | 405 | m_items[item.ItemID].PermsMask = 0; |
384 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 406 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
385 | } | ||
386 | 407 | ||
408 | m_items.LockItemsForWrite(false); | ||
409 | |||
387 | string script = Utils.BytesToString(asset.Data); | 410 | string script = Utils.BytesToString(asset.Data); |
388 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 411 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
389 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); | 412 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); |
413 | StoreScriptErrors(item.ItemID, null); | ||
390 | if (!item.ScriptRunning) | 414 | if (!item.ScriptRunning) |
391 | m_part.ParentGroup.Scene.EventManager.TriggerStopScript( | 415 | m_part.ParentGroup.Scene.EventManager.TriggerStopScript( |
392 | m_part.LocalId, item.ItemID); | 416 | m_part.LocalId, item.ItemID); |
@@ -459,22 +483,149 @@ namespace OpenSim.Region.Framework.Scenes | |||
459 | return stateID; | 483 | return stateID; |
460 | } | 484 | } |
461 | 485 | ||
486 | /// <summary> | ||
487 | /// Start a script which is in this prim's inventory. | ||
488 | /// Some processing may occur in the background, but this routine returns asap. | ||
489 | /// </summary> | ||
490 | /// <param name="itemId"> | ||
491 | /// A <see cref="UUID"/> | ||
492 | /// </param> | ||
462 | public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | 493 | public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) |
463 | { | 494 | { |
464 | TaskInventoryItem item = GetInventoryItem(itemId); | 495 | lock (m_scriptErrors) |
465 | if (item != null) | ||
466 | { | 496 | { |
467 | return CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | 497 | // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion |
498 | m_scriptErrors.Remove(itemId); | ||
499 | } | ||
500 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
501 | return true; | ||
502 | } | ||
503 | |||
504 | private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
505 | { | ||
506 | m_items.LockItemsForRead(true); | ||
507 | if (m_items.ContainsKey(itemId)) | ||
508 | { | ||
509 | if (m_items.ContainsKey(itemId)) | ||
510 | { | ||
511 | m_items.LockItemsForRead(false); | ||
512 | CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); | ||
513 | } | ||
514 | else | ||
515 | { | ||
516 | m_items.LockItemsForRead(false); | ||
517 | string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID, | ||
518 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
519 | StoreScriptError(itemId, msg); | ||
520 | m_log.ErrorFormat( | ||
521 | "[PRIM INVENTORY]: " + | ||
522 | "Couldn't start script with ID {0} since it {1}", itemId, msg); | ||
523 | } | ||
468 | } | 524 | } |
469 | else | 525 | else |
470 | { | 526 | { |
527 | m_items.LockItemsForRead(false); | ||
528 | string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID); | ||
529 | StoreScriptError(itemId, msg); | ||
471 | m_log.ErrorFormat( | 530 | m_log.ErrorFormat( |
472 | "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", | 531 | "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", |
473 | itemId, m_part.Name, m_part.UUID, | 532 | itemId, m_part.Name, m_part.UUID, |
474 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 533 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
534 | } | ||
535 | |||
536 | } | ||
475 | 537 | ||
476 | return false; | 538 | /// <summary> |
539 | /// Start a script which is in this prim's inventory and return any compilation error messages. | ||
540 | /// </summary> | ||
541 | /// <param name="itemId"> | ||
542 | /// A <see cref="UUID"/> | ||
543 | /// </param> | ||
544 | public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
545 | { | ||
546 | ArrayList errors; | ||
547 | |||
548 | // Indicate to CreateScriptInstanceInternal() we want it to | ||
549 | // post any compilation/loading error messages | ||
550 | lock (m_scriptErrors) | ||
551 | { | ||
552 | m_scriptErrors[itemId] = null; | ||
553 | } | ||
554 | |||
555 | // Perform compilation/loading | ||
556 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
557 | |||
558 | // Wait for and retrieve any errors | ||
559 | lock (m_scriptErrors) | ||
560 | { | ||
561 | while ((errors = m_scriptErrors[itemId]) == null) | ||
562 | { | ||
563 | if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000)) | ||
564 | { | ||
565 | m_log.ErrorFormat( | ||
566 | "[PRIM INVENTORY]: " + | ||
567 | "timedout waiting for script {0} errors", itemId); | ||
568 | errors = m_scriptErrors[itemId]; | ||
569 | if (errors == null) | ||
570 | { | ||
571 | errors = new ArrayList(1); | ||
572 | errors.Add("timedout waiting for errors"); | ||
573 | } | ||
574 | break; | ||
575 | } | ||
576 | } | ||
577 | m_scriptErrors.Remove(itemId); | ||
477 | } | 578 | } |
579 | return errors; | ||
580 | } | ||
581 | |||
582 | // Signal to CreateScriptInstanceEr() that compilation/loading is complete | ||
583 | private void StoreScriptErrors(UUID itemId, ArrayList errors) | ||
584 | { | ||
585 | lock (m_scriptErrors) | ||
586 | { | ||
587 | // If compilation/loading initiated via CreateScriptInstance(), | ||
588 | // it does not want the errors, so just get out | ||
589 | if (!m_scriptErrors.ContainsKey(itemId)) | ||
590 | { | ||
591 | return; | ||
592 | } | ||
593 | |||
594 | // Initiated via CreateScriptInstanceEr(), if we know what the | ||
595 | // errors are, save them and wake CreateScriptInstanceEr(). | ||
596 | if (errors != null) | ||
597 | { | ||
598 | m_scriptErrors[itemId] = errors; | ||
599 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
600 | return; | ||
601 | } | ||
602 | } | ||
603 | |||
604 | // Initiated via CreateScriptInstanceEr() but we don't know what | ||
605 | // the errors are yet, so retrieve them from the script engine. | ||
606 | // This may involve some waiting internal to GetScriptErrors(). | ||
607 | errors = GetScriptErrors(itemId); | ||
608 | |||
609 | // Get a default non-null value to indicate success. | ||
610 | if (errors == null) | ||
611 | { | ||
612 | errors = new ArrayList(); | ||
613 | } | ||
614 | |||
615 | // Post to CreateScriptInstanceEr() and wake it up | ||
616 | lock (m_scriptErrors) | ||
617 | { | ||
618 | m_scriptErrors[itemId] = errors; | ||
619 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
620 | } | ||
621 | } | ||
622 | |||
623 | // Like StoreScriptErrors(), but just posts a single string message | ||
624 | private void StoreScriptError(UUID itemId, string message) | ||
625 | { | ||
626 | ArrayList errors = new ArrayList(1); | ||
627 | errors.Add(message); | ||
628 | StoreScriptErrors(itemId, errors); | ||
478 | } | 629 | } |
479 | 630 | ||
480 | /// <summary> | 631 | /// <summary> |
@@ -487,15 +638,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
487 | /// </param> | 638 | /// </param> |
488 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) | 639 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) |
489 | { | 640 | { |
490 | bool scriptPresent = false; | 641 | if (m_items.ContainsKey(itemId)) |
491 | |||
492 | lock (m_items) | ||
493 | { | ||
494 | if (m_items.ContainsKey(itemId)) | ||
495 | scriptPresent = true; | ||
496 | } | ||
497 | |||
498 | if (scriptPresent) | ||
499 | { | 642 | { |
500 | if (!sceneObjectBeingDeleted) | 643 | if (!sceneObjectBeingDeleted) |
501 | m_part.RemoveScriptEvents(itemId); | 644 | m_part.RemoveScriptEvents(itemId); |
@@ -565,14 +708,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
565 | /// <returns></returns> | 708 | /// <returns></returns> |
566 | private bool InventoryContainsName(string name) | 709 | private bool InventoryContainsName(string name) |
567 | { | 710 | { |
568 | lock (m_items) | 711 | m_items.LockItemsForRead(true); |
712 | foreach (TaskInventoryItem item in m_items.Values) | ||
569 | { | 713 | { |
570 | foreach (TaskInventoryItem item in m_items.Values) | 714 | if (item.Name == name) |
571 | { | 715 | { |
572 | if (item.Name == name) | 716 | m_items.LockItemsForRead(false); |
573 | return true; | 717 | return true; |
574 | } | 718 | } |
575 | } | 719 | } |
720 | m_items.LockItemsForRead(false); | ||
576 | return false; | 721 | return false; |
577 | } | 722 | } |
578 | 723 | ||
@@ -614,8 +759,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
614 | /// <param name="item"></param> | 759 | /// <param name="item"></param> |
615 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) | 760 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) |
616 | { | 761 | { |
617 | List<TaskInventoryItem> il = GetInventoryItems(); | 762 | m_items.LockItemsForRead(true); |
618 | 763 | List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); | |
764 | m_items.LockItemsForRead(false); | ||
619 | foreach (TaskInventoryItem i in il) | 765 | foreach (TaskInventoryItem i in il) |
620 | { | 766 | { |
621 | if (i.Name == item.Name) | 767 | if (i.Name == item.Name) |
@@ -653,14 +799,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
653 | item.Name = name; | 799 | item.Name = name; |
654 | item.GroupID = m_part.GroupID; | 800 | item.GroupID = m_part.GroupID; |
655 | 801 | ||
656 | lock (m_items) | 802 | m_items.LockItemsForWrite(true); |
657 | m_items.Add(item.ItemID, item); | 803 | m_items.Add(item.ItemID, item); |
658 | 804 | m_items.LockItemsForWrite(false); | |
659 | if (allowedDrop) | 805 | if (allowedDrop) |
660 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); | 806 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); |
661 | else | 807 | else |
662 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 808 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
663 | 809 | ||
664 | m_inventorySerial++; | 810 | m_inventorySerial++; |
665 | //m_inventorySerial += 2; | 811 | //m_inventorySerial += 2; |
666 | HasInventoryChanged = true; | 812 | HasInventoryChanged = true; |
@@ -676,15 +822,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
676 | /// <param name="items"></param> | 822 | /// <param name="items"></param> |
677 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) | 823 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) |
678 | { | 824 | { |
679 | lock (m_items) | 825 | m_items.LockItemsForWrite(true); |
826 | foreach (TaskInventoryItem item in items) | ||
680 | { | 827 | { |
681 | foreach (TaskInventoryItem item in items) | 828 | m_items.Add(item.ItemID, item); |
682 | { | 829 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
683 | m_items.Add(item.ItemID, item); | ||
684 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
685 | } | ||
686 | m_inventorySerial++; | ||
687 | } | 830 | } |
831 | m_items.LockItemsForWrite(false); | ||
832 | |||
833 | m_inventorySerial++; | ||
688 | } | 834 | } |
689 | 835 | ||
690 | /// <summary> | 836 | /// <summary> |
@@ -695,23 +841,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
695 | public TaskInventoryItem GetInventoryItem(UUID itemId) | 841 | public TaskInventoryItem GetInventoryItem(UUID itemId) |
696 | { | 842 | { |
697 | TaskInventoryItem item; | 843 | TaskInventoryItem item; |
698 | 844 | m_items.LockItemsForRead(true); | |
699 | lock (m_items) | 845 | m_items.TryGetValue(itemId, out item); |
700 | m_items.TryGetValue(itemId, out item); | 846 | m_items.LockItemsForRead(false); |
701 | |||
702 | return item; | 847 | return item; |
703 | } | 848 | } |
704 | 849 | ||
705 | public TaskInventoryItem GetInventoryItem(string name) | 850 | public TaskInventoryItem GetInventoryItem(string name) |
706 | { | 851 | { |
707 | lock (m_items) | 852 | m_items.LockItemsForRead(true); |
853 | foreach (TaskInventoryItem item in m_items.Values) | ||
708 | { | 854 | { |
709 | foreach (TaskInventoryItem item in m_items.Values) | 855 | if (item.Name == name) |
710 | { | 856 | { |
711 | if (item.Name == name) | 857 | m_items.LockItemsForRead(false); |
712 | return item; | 858 | return item; |
713 | } | 859 | } |
714 | } | 860 | } |
861 | m_items.LockItemsForRead(false); | ||
715 | 862 | ||
716 | return null; | 863 | return null; |
717 | } | 864 | } |
@@ -720,15 +867,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
720 | { | 867 | { |
721 | List<TaskInventoryItem> items = new List<TaskInventoryItem>(); | 868 | List<TaskInventoryItem> items = new List<TaskInventoryItem>(); |
722 | 869 | ||
723 | lock (m_items) | 870 | m_items.LockItemsForRead(true); |
871 | |||
872 | foreach (TaskInventoryItem item in m_items.Values) | ||
724 | { | 873 | { |
725 | foreach (TaskInventoryItem item in m_items.Values) | 874 | if (item.Name == name) |
726 | { | 875 | items.Add(item); |
727 | if (item.Name == name) | ||
728 | items.Add(item); | ||
729 | } | ||
730 | } | 876 | } |
731 | 877 | ||
878 | m_items.LockItemsForRead(false); | ||
879 | |||
732 | return items; | 880 | return items; |
733 | } | 881 | } |
734 | 882 | ||
@@ -747,6 +895,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
747 | string xmlData = Utils.BytesToString(rezAsset.Data); | 895 | string xmlData = Utils.BytesToString(rezAsset.Data); |
748 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | 896 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); |
749 | 897 | ||
898 | group.RootPart.AttachPoint = group.RootPart.Shape.State; | ||
899 | group.RootPart.AttachOffset = group.AbsolutePosition; | ||
900 | group.RootPart.AttachRotation = group.GroupRotation; | ||
901 | |||
750 | group.ResetIDs(); | 902 | group.ResetIDs(); |
751 | 903 | ||
752 | SceneObjectPart rootPart = group.GetPart(group.UUID); | 904 | SceneObjectPart rootPart = group.GetPart(group.UUID); |
@@ -821,8 +973,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
821 | 973 | ||
822 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) | 974 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) |
823 | { | 975 | { |
824 | TaskInventoryItem it = GetInventoryItem(item.ItemID); | 976 | m_items.LockItemsForWrite(true); |
825 | if (it != null) | 977 | |
978 | if (m_items.ContainsKey(item.ItemID)) | ||
826 | { | 979 | { |
827 | // m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); | 980 | // m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); |
828 | 981 | ||
@@ -835,14 +988,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
835 | item.GroupID = m_part.GroupID; | 988 | item.GroupID = m_part.GroupID; |
836 | 989 | ||
837 | if (item.AssetID == UUID.Zero) | 990 | if (item.AssetID == UUID.Zero) |
838 | item.AssetID = it.AssetID; | 991 | item.AssetID = m_items[item.ItemID].AssetID; |
839 | 992 | ||
840 | lock (m_items) | 993 | m_items[item.ItemID] = item; |
841 | { | 994 | m_inventorySerial++; |
842 | m_items[item.ItemID] = item; | ||
843 | m_inventorySerial++; | ||
844 | } | ||
845 | |||
846 | if (fireScriptEvents) | 995 | if (fireScriptEvents) |
847 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 996 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
848 | 997 | ||
@@ -851,7 +1000,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
851 | HasInventoryChanged = true; | 1000 | HasInventoryChanged = true; |
852 | m_part.ParentGroup.HasGroupChanged = true; | 1001 | m_part.ParentGroup.HasGroupChanged = true; |
853 | } | 1002 | } |
854 | 1003 | m_items.LockItemsForWrite(false); | |
855 | return true; | 1004 | return true; |
856 | } | 1005 | } |
857 | else | 1006 | else |
@@ -862,8 +1011,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
862 | item.ItemID, m_part.Name, m_part.UUID, | 1011 | item.ItemID, m_part.Name, m_part.UUID, |
863 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 1012 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
864 | } | 1013 | } |
865 | return false; | 1014 | m_items.LockItemsForWrite(false); |
866 | 1015 | ||
1016 | return false; | ||
867 | } | 1017 | } |
868 | 1018 | ||
869 | /// <summary> | 1019 | /// <summary> |
@@ -874,43 +1024,59 @@ namespace OpenSim.Region.Framework.Scenes | |||
874 | /// in this prim's inventory.</returns> | 1024 | /// in this prim's inventory.</returns> |
875 | public int RemoveInventoryItem(UUID itemID) | 1025 | public int RemoveInventoryItem(UUID itemID) |
876 | { | 1026 | { |
877 | TaskInventoryItem item = GetInventoryItem(itemID); | 1027 | m_items.LockItemsForRead(true); |
878 | if (item != null) | 1028 | |
1029 | if (m_items.ContainsKey(itemID)) | ||
879 | { | 1030 | { |
880 | int type = m_items[itemID].InvType; | 1031 | int type = m_items[itemID].InvType; |
1032 | m_items.LockItemsForRead(false); | ||
881 | if (type == 10) // Script | 1033 | if (type == 10) // Script |
882 | { | 1034 | { |
883 | m_part.RemoveScriptEvents(itemID); | ||
884 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); | 1035 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); |
885 | } | 1036 | } |
1037 | m_items.LockItemsForWrite(true); | ||
886 | m_items.Remove(itemID); | 1038 | m_items.Remove(itemID); |
1039 | m_items.LockItemsForWrite(false); | ||
887 | m_inventorySerial++; | 1040 | m_inventorySerial++; |
888 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 1041 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
889 | 1042 | ||
890 | HasInventoryChanged = true; | 1043 | HasInventoryChanged = true; |
891 | m_part.ParentGroup.HasGroupChanged = true; | 1044 | m_part.ParentGroup.HasGroupChanged = true; |
892 | 1045 | ||
893 | if (!ContainsScripts()) | 1046 | int scriptcount = 0; |
1047 | m_items.LockItemsForRead(true); | ||
1048 | foreach (TaskInventoryItem item in m_items.Values) | ||
1049 | { | ||
1050 | if (item.Type == 10) | ||
1051 | { | ||
1052 | scriptcount++; | ||
1053 | } | ||
1054 | } | ||
1055 | m_items.LockItemsForRead(false); | ||
1056 | |||
1057 | |||
1058 | if (scriptcount <= 0) | ||
1059 | { | ||
894 | m_part.RemFlag(PrimFlags.Scripted); | 1060 | m_part.RemFlag(PrimFlags.Scripted); |
1061 | } | ||
895 | 1062 | ||
896 | m_part.ScheduleFullUpdate(); | 1063 | m_part.ScheduleFullUpdate(); |
897 | 1064 | ||
898 | return type; | 1065 | return type; |
899 | |||
900 | } | 1066 | } |
901 | else | 1067 | else |
902 | { | 1068 | { |
1069 | m_items.LockItemsForRead(false); | ||
903 | m_log.ErrorFormat( | 1070 | m_log.ErrorFormat( |
904 | "[PRIM INVENTORY]: " + | 1071 | "[PRIM INVENTORY]: " + |
905 | "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", | 1072 | "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", |
906 | itemID, m_part.Name, m_part.UUID, | 1073 | itemID, m_part.Name, m_part.UUID); |
907 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
908 | } | 1074 | } |
909 | 1075 | ||
910 | return -1; | 1076 | return -1; |
911 | } | 1077 | } |
912 | 1078 | ||
913 | private bool CreateInventoryFile() | 1079 | private bool CreateInventoryFileName() |
914 | { | 1080 | { |
915 | // m_log.DebugFormat( | 1081 | // m_log.DebugFormat( |
916 | // "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", | 1082 | // "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", |
@@ -919,70 +1085,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
919 | if (m_inventoryFileName == String.Empty || | 1085 | if (m_inventoryFileName == String.Empty || |
920 | m_inventoryFileNameSerial < m_inventorySerial) | 1086 | m_inventoryFileNameSerial < m_inventorySerial) |
921 | { | 1087 | { |
922 | // Something changed, we need to create a new file | ||
923 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; | 1088 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; |
924 | m_inventoryFileNameSerial = m_inventorySerial; | 1089 | m_inventoryFileNameSerial = m_inventorySerial; |
925 | 1090 | ||
926 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | ||
927 | |||
928 | lock (m_items) | ||
929 | { | ||
930 | foreach (TaskInventoryItem item in m_items.Values) | ||
931 | { | ||
932 | // m_log.DebugFormat( | ||
933 | // "[PRIM INVENTORY]: Adding item {0} {1} for serial {2} on prim {3} {4} {5}", | ||
934 | // item.Name, item.ItemID, m_inventorySerial, m_part.Name, m_part.UUID, m_part.LocalId); | ||
935 | |||
936 | UUID ownerID = item.OwnerID; | ||
937 | uint everyoneMask = 0; | ||
938 | uint baseMask = item.BasePermissions; | ||
939 | uint ownerMask = item.CurrentPermissions; | ||
940 | uint groupMask = item.GroupPermissions; | ||
941 | |||
942 | invString.AddItemStart(); | ||
943 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
944 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
945 | |||
946 | invString.AddPermissionsStart(); | ||
947 | |||
948 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | ||
949 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
950 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
951 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
952 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
953 | |||
954 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | ||
955 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
956 | |||
957 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
958 | |||
959 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | ||
960 | invString.AddSectionEnd(); | ||
961 | |||
962 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
963 | invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type)); | ||
964 | invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType)); | ||
965 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
966 | |||
967 | invString.AddSaleStart(); | ||
968 | invString.AddNameValueLine("sale_type", "not"); | ||
969 | invString.AddNameValueLine("sale_price", "0"); | ||
970 | invString.AddSectionEnd(); | ||
971 | |||
972 | invString.AddNameValueLine("name", item.Name + "|"); | ||
973 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
974 | |||
975 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
976 | invString.AddSectionEnd(); | ||
977 | } | ||
978 | } | ||
979 | |||
980 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | ||
981 | |||
982 | return true; | 1091 | return true; |
983 | } | 1092 | } |
984 | 1093 | ||
985 | // No need to recreate, the existing file is fine | ||
986 | return false; | 1094 | return false; |
987 | } | 1095 | } |
988 | 1096 | ||
@@ -992,43 +1100,110 @@ namespace OpenSim.Region.Framework.Scenes | |||
992 | /// <param name="xferManager"></param> | 1100 | /// <param name="xferManager"></param> |
993 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) | 1101 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) |
994 | { | 1102 | { |
995 | lock (m_items) | 1103 | bool changed = CreateInventoryFileName(); |
996 | { | ||
997 | // Don't send a inventory xfer name if there are no items. Doing so causes viewer 3 to crash when rezzing | ||
998 | // a new script if any previous deletion has left the prim inventory empty. | ||
999 | if (m_items.Count == 0) // No inventory | ||
1000 | { | ||
1001 | // m_log.DebugFormat( | ||
1002 | // "[PRIM INVENTORY]: Not sending inventory data for part {0} {1} {2} for {3} since no items", | ||
1003 | // m_part.Name, m_part.LocalId, m_part.UUID, client.Name); | ||
1004 | 1104 | ||
1005 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | 1105 | bool includeAssets = false; |
1006 | return; | 1106 | if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) |
1007 | } | 1107 | includeAssets = true; |
1108 | |||
1109 | if (m_inventoryPrivileged != includeAssets) | ||
1110 | changed = true; | ||
1111 | |||
1112 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | ||
1113 | |||
1114 | Items.LockItemsForRead(true); | ||
1115 | |||
1116 | if (m_inventorySerial == 0) // No inventory | ||
1117 | { | ||
1118 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
1119 | Items.LockItemsForRead(false); | ||
1120 | return; | ||
1121 | } | ||
1008 | 1122 | ||
1009 | CreateInventoryFile(); | 1123 | if (m_items.Count == 0) // No inventory |
1124 | { | ||
1125 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
1126 | Items.LockItemsForRead(false); | ||
1127 | return; | ||
1128 | } | ||
1010 | 1129 | ||
1011 | // In principle, we should only do the rest if the inventory changed; | 1130 | if (!changed) |
1012 | // by sending m_inventorySerial to the client, it ought to know | 1131 | { |
1013 | // that nothing changed and that it doesn't need to request the file. | ||
1014 | // Unfortunately, it doesn't look like the client optimizes this; | ||
1015 | // the client seems to always come back and request the Xfer, | ||
1016 | // no matter what value m_inventorySerial has. | ||
1017 | // FIXME: Could probably be > 0 here rather than > 2 | ||
1018 | if (m_inventoryFileData.Length > 2) | 1132 | if (m_inventoryFileData.Length > 2) |
1019 | { | 1133 | { |
1020 | // Add the file for Xfer | 1134 | xferManager.AddNewFile(m_inventoryFileName, |
1021 | // m_log.DebugFormat( | 1135 | m_inventoryFileData); |
1022 | // "[PRIM INVENTORY]: Adding inventory file {0} (length {1}) for transfer on {2} {3} {4}", | 1136 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, |
1023 | // m_inventoryFileName, m_inventoryFileData.Length, m_part.Name, m_part.UUID, m_part.LocalId); | 1137 | Util.StringToBytes256(m_inventoryFileName)); |
1024 | 1138 | ||
1025 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | 1139 | Items.LockItemsForRead(false); |
1140 | return; | ||
1026 | } | 1141 | } |
1027 | |||
1028 | // Tell the client we're ready to Xfer the file | ||
1029 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | ||
1030 | Util.StringToBytes256(m_inventoryFileName)); | ||
1031 | } | 1142 | } |
1143 | |||
1144 | m_inventoryPrivileged = includeAssets; | ||
1145 | |||
1146 | foreach (TaskInventoryItem item in m_items.Values) | ||
1147 | { | ||
1148 | UUID ownerID = item.OwnerID; | ||
1149 | uint everyoneMask = 0; | ||
1150 | uint baseMask = item.BasePermissions; | ||
1151 | uint ownerMask = item.CurrentPermissions; | ||
1152 | uint groupMask = item.GroupPermissions; | ||
1153 | |||
1154 | invString.AddItemStart(); | ||
1155 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
1156 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
1157 | |||
1158 | invString.AddPermissionsStart(); | ||
1159 | |||
1160 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | ||
1161 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
1162 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
1163 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
1164 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
1165 | |||
1166 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | ||
1167 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
1168 | |||
1169 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
1170 | |||
1171 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | ||
1172 | invString.AddSectionEnd(); | ||
1173 | |||
1174 | if (includeAssets) | ||
1175 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
1176 | else | ||
1177 | invString.AddNameValueLine("asset_id", UUID.Zero.ToString()); | ||
1178 | invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type)); | ||
1179 | invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType)); | ||
1180 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
1181 | |||
1182 | invString.AddSaleStart(); | ||
1183 | invString.AddNameValueLine("sale_type", "not"); | ||
1184 | invString.AddNameValueLine("sale_price", "0"); | ||
1185 | invString.AddSectionEnd(); | ||
1186 | |||
1187 | invString.AddNameValueLine("name", item.Name + "|"); | ||
1188 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
1189 | |||
1190 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
1191 | invString.AddSectionEnd(); | ||
1192 | } | ||
1193 | |||
1194 | Items.LockItemsForRead(false); | ||
1195 | |||
1196 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | ||
1197 | |||
1198 | if (m_inventoryFileData.Length > 2) | ||
1199 | { | ||
1200 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | ||
1201 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | ||
1202 | Util.StringToBytes256(m_inventoryFileName)); | ||
1203 | return; | ||
1204 | } | ||
1205 | |||
1206 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
1032 | } | 1207 | } |
1033 | 1208 | ||
1034 | /// <summary> | 1209 | /// <summary> |
@@ -1037,13 +1212,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
1037 | /// <param name="datastore"></param> | 1212 | /// <param name="datastore"></param> |
1038 | public void ProcessInventoryBackup(ISimulationDataService datastore) | 1213 | public void ProcessInventoryBackup(ISimulationDataService datastore) |
1039 | { | 1214 | { |
1040 | if (HasInventoryChanged) | 1215 | // Removed this because linking will cause an immediate delete of the new |
1041 | { | 1216 | // child prim from the database and the subsequent storing of the prim sees |
1042 | HasInventoryChanged = false; | 1217 | // the inventory of it as unchanged and doesn't store it at all. The overhead |
1043 | List<TaskInventoryItem> items = GetInventoryItems(); | 1218 | // of storing prim inventory needlessly is much less than the aggravation |
1044 | datastore.StorePrimInventory(m_part.UUID, items); | 1219 | // of prim inventory loss. |
1220 | // if (HasInventoryChanged) | ||
1221 | // { | ||
1222 | Items.LockItemsForRead(true); | ||
1223 | datastore.StorePrimInventory(m_part.UUID, Items.Values); | ||
1224 | Items.LockItemsForRead(false); | ||
1045 | 1225 | ||
1046 | } | 1226 | HasInventoryChanged = false; |
1227 | // } | ||
1047 | } | 1228 | } |
1048 | 1229 | ||
1049 | public class InventoryStringBuilder | 1230 | public class InventoryStringBuilder |
@@ -1109,87 +1290,63 @@ namespace OpenSim.Region.Framework.Scenes | |||
1109 | { | 1290 | { |
1110 | uint mask=0x7fffffff; | 1291 | uint mask=0x7fffffff; |
1111 | 1292 | ||
1112 | lock (m_items) | 1293 | foreach (TaskInventoryItem item in m_items.Values) |
1113 | { | 1294 | { |
1114 | foreach (TaskInventoryItem item in m_items.Values) | 1295 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) |
1296 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1297 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1298 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1299 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | ||
1300 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1301 | |||
1302 | if (item.InvType == (int)InventoryType.Object) | ||
1115 | { | 1303 | { |
1116 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | 1304 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
1117 | mask &= ~((uint)PermissionMask.Copy >> 13); | 1305 | mask &= ~((uint)PermissionMask.Copy >> 13); |
1118 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | 1306 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
1119 | mask &= ~((uint)PermissionMask.Transfer >> 13); | 1307 | mask &= ~((uint)PermissionMask.Transfer >> 13); |
1120 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | 1308 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
1121 | mask &= ~((uint)PermissionMask.Modify >> 13); | 1309 | mask &= ~((uint)PermissionMask.Modify >> 13); |
1122 | |||
1123 | if (item.InvType != (int)InventoryType.Object) | ||
1124 | { | ||
1125 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | ||
1126 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1127 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1128 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1129 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | ||
1130 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1131 | } | ||
1132 | else | ||
1133 | { | ||
1134 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | ||
1135 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1136 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | ||
1137 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1138 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
1139 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1140 | } | ||
1141 | |||
1142 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1143 | mask &= ~(uint)PermissionMask.Copy; | ||
1144 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1145 | mask &= ~(uint)PermissionMask.Transfer; | ||
1146 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
1147 | mask &= ~(uint)PermissionMask.Modify; | ||
1148 | } | 1310 | } |
1311 | |||
1312 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1313 | mask &= ~(uint)PermissionMask.Copy; | ||
1314 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1315 | mask &= ~(uint)PermissionMask.Transfer; | ||
1316 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
1317 | mask &= ~(uint)PermissionMask.Modify; | ||
1149 | } | 1318 | } |
1150 | |||
1151 | return mask; | 1319 | return mask; |
1152 | } | 1320 | } |
1153 | 1321 | ||
1154 | public void ApplyNextOwnerPermissions() | 1322 | public void ApplyNextOwnerPermissions() |
1155 | { | 1323 | { |
1156 | lock (m_items) | 1324 | foreach (TaskInventoryItem item in m_items.Values) |
1157 | { | 1325 | { |
1158 | foreach (TaskInventoryItem item in m_items.Values) | 1326 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) |
1159 | { | 1327 | { |
1160 | // m_log.DebugFormat ( | 1328 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
1161 | // "[SCENE OBJECT PART INVENTORY]: Applying next permissions {0} to {1} in {2} with current {3}, base {4}, everyone {5}", | 1329 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; |
1162 | // item.NextPermissions, item.Name, m_part.Name, item.CurrentPermissions, item.BasePermissions, item.EveryonePermissions); | 1330 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
1163 | 1331 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | |
1164 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) | 1332 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
1165 | { | 1333 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; |
1166 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | ||
1167 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; | ||
1168 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | ||
1169 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | ||
1170 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
1171 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; | ||
1172 | } | ||
1173 | |||
1174 | item.CurrentPermissions &= item.NextPermissions; | ||
1175 | item.BasePermissions &= item.NextPermissions; | ||
1176 | item.EveryonePermissions &= item.NextPermissions; | ||
1177 | item.OwnerChanged = true; | ||
1178 | item.PermsMask = 0; | ||
1179 | item.PermsGranter = UUID.Zero; | ||
1180 | } | 1334 | } |
1335 | item.CurrentPermissions &= item.NextPermissions; | ||
1336 | item.BasePermissions &= item.NextPermissions; | ||
1337 | item.EveryonePermissions &= item.NextPermissions; | ||
1338 | item.OwnerChanged = true; | ||
1339 | item.PermsMask = 0; | ||
1340 | item.PermsGranter = UUID.Zero; | ||
1181 | } | 1341 | } |
1182 | } | 1342 | } |
1183 | 1343 | ||
1184 | public void ApplyGodPermissions(uint perms) | 1344 | public void ApplyGodPermissions(uint perms) |
1185 | { | 1345 | { |
1186 | lock (m_items) | 1346 | foreach (TaskInventoryItem item in m_items.Values) |
1187 | { | 1347 | { |
1188 | foreach (TaskInventoryItem item in m_items.Values) | 1348 | item.CurrentPermissions = perms; |
1189 | { | 1349 | item.BasePermissions = perms; |
1190 | item.CurrentPermissions = perms; | ||
1191 | item.BasePermissions = perms; | ||
1192 | } | ||
1193 | } | 1350 | } |
1194 | 1351 | ||
1195 | m_inventorySerial++; | 1352 | m_inventorySerial++; |
@@ -1202,14 +1359,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1202 | /// <returns></returns> | 1359 | /// <returns></returns> |
1203 | public bool ContainsScripts() | 1360 | public bool ContainsScripts() |
1204 | { | 1361 | { |
1205 | lock (m_items) | 1362 | foreach (TaskInventoryItem item in m_items.Values) |
1206 | { | 1363 | { |
1207 | foreach (TaskInventoryItem item in m_items.Values) | 1364 | if (item.InvType == (int)InventoryType.LSL) |
1208 | { | 1365 | { |
1209 | if (item.InvType == (int)InventoryType.LSL) | 1366 | return true; |
1210 | { | ||
1211 | return true; | ||
1212 | } | ||
1213 | } | 1367 | } |
1214 | } | 1368 | } |
1215 | 1369 | ||
@@ -1223,17 +1377,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1223 | public int ScriptCount() | 1377 | public int ScriptCount() |
1224 | { | 1378 | { |
1225 | int count = 0; | 1379 | int count = 0; |
1226 | lock (m_items) | 1380 | Items.LockItemsForRead(true); |
1381 | foreach (TaskInventoryItem item in m_items.Values) | ||
1227 | { | 1382 | { |
1228 | foreach (TaskInventoryItem item in m_items.Values) | 1383 | if (item.InvType == (int)InventoryType.LSL) |
1229 | { | 1384 | { |
1230 | if (item.InvType == (int)InventoryType.LSL) | 1385 | count++; |
1231 | { | ||
1232 | count++; | ||
1233 | } | ||
1234 | } | 1386 | } |
1235 | } | 1387 | } |
1236 | 1388 | Items.LockItemsForRead(false); | |
1237 | return count; | 1389 | return count; |
1238 | } | 1390 | } |
1239 | /// <summary> | 1391 | /// <summary> |
@@ -1269,11 +1421,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1269 | { | 1421 | { |
1270 | List<UUID> ret = new List<UUID>(); | 1422 | List<UUID> ret = new List<UUID>(); |
1271 | 1423 | ||
1272 | lock (m_items) | 1424 | foreach (TaskInventoryItem item in m_items.Values) |
1273 | { | 1425 | ret.Add(item.ItemID); |
1274 | foreach (TaskInventoryItem item in m_items.Values) | ||
1275 | ret.Add(item.ItemID); | ||
1276 | } | ||
1277 | 1426 | ||
1278 | return ret; | 1427 | return ret; |
1279 | } | 1428 | } |
@@ -1282,8 +1431,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1282 | { | 1431 | { |
1283 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1432 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); |
1284 | 1433 | ||
1285 | lock (m_items) | 1434 | Items.LockItemsForRead(true); |
1286 | ret = new List<TaskInventoryItem>(m_items.Values); | 1435 | ret = new List<TaskInventoryItem>(m_items.Values); |
1436 | Items.LockItemsForRead(false); | ||
1287 | 1437 | ||
1288 | return ret; | 1438 | return ret; |
1289 | } | 1439 | } |
@@ -1292,18 +1442,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
1292 | { | 1442 | { |
1293 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1443 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); |
1294 | 1444 | ||
1295 | lock (m_items) | 1445 | Items.LockItemsForRead(true); |
1296 | { | 1446 | |
1297 | foreach (TaskInventoryItem item in m_items.Values) | 1447 | foreach (TaskInventoryItem item in m_items.Values) |
1298 | if (item.InvType == (int)type) | 1448 | if (item.InvType == (int)type) |
1299 | ret.Add(item); | 1449 | ret.Add(item); |
1300 | } | 1450 | |
1451 | Items.LockItemsForRead(false); | ||
1301 | 1452 | ||
1302 | return ret; | 1453 | return ret; |
1303 | } | 1454 | } |
1304 | 1455 | ||
1305 | public Dictionary<UUID, string> GetScriptStates() | 1456 | public Dictionary<UUID, string> GetScriptStates() |
1306 | { | 1457 | { |
1458 | return GetScriptStates(false); | ||
1459 | } | ||
1460 | |||
1461 | public Dictionary<UUID, string> GetScriptStates(bool oldIDs) | ||
1462 | { | ||
1307 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); | 1463 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); |
1308 | 1464 | ||
1309 | if (m_part.ParentGroup.Scene == null) // Group not in a scene | 1465 | if (m_part.ParentGroup.Scene == null) // Group not in a scene |
@@ -1329,14 +1485,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1329 | string n = e.GetXMLState(item.ItemID); | 1485 | string n = e.GetXMLState(item.ItemID); |
1330 | if (n != String.Empty) | 1486 | if (n != String.Empty) |
1331 | { | 1487 | { |
1332 | if (!ret.ContainsKey(item.ItemID)) | 1488 | if (oldIDs) |
1333 | ret[item.ItemID] = n; | 1489 | { |
1490 | if (!ret.ContainsKey(item.OldItemID)) | ||
1491 | ret[item.OldItemID] = n; | ||
1492 | } | ||
1493 | else | ||
1494 | { | ||
1495 | if (!ret.ContainsKey(item.ItemID)) | ||
1496 | ret[item.ItemID] = n; | ||
1497 | } | ||
1334 | break; | 1498 | break; |
1335 | } | 1499 | } |
1336 | } | 1500 | } |
1337 | } | 1501 | } |
1338 | } | 1502 | } |
1339 | |||
1340 | return ret; | 1503 | return ret; |
1341 | } | 1504 | } |
1342 | 1505 | ||