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