diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 787 |
1 files changed, 476 insertions, 311 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index 821fd81..1c9a17e 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; |
@@ -124,38 +129,45 @@ namespace OpenSim.Region.Framework.Scenes | |||
124 | public void ResetInventoryIDs() | 129 | public void ResetInventoryIDs() |
125 | { | 130 | { |
126 | if (null == m_part) | 131 | if (null == m_part) |
127 | return; | 132 | m_items.LockItemsForWrite(true); |
128 | 133 | ||
129 | lock (m_items) | 134 | if (Items.Count == 0) |
130 | { | 135 | { |
131 | if (0 == m_items.Count) | 136 | m_items.LockItemsForWrite(false); |
132 | return; | 137 | return; |
138 | } | ||
133 | 139 | ||
134 | IList<TaskInventoryItem> items = GetInventoryItems(); | 140 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
135 | m_items.Clear(); | 141 | Items.Clear(); |
136 | 142 | ||
137 | foreach (TaskInventoryItem item in items) | 143 | foreach (TaskInventoryItem item in items) |
138 | { | 144 | { |
139 | item.ResetIDs(m_part.UUID); | 145 | item.ResetIDs(m_part.UUID); |
140 | m_items.Add(item.ItemID, item); | 146 | Items.Add(item.ItemID, item); |
141 | } | ||
142 | } | 147 | } |
148 | m_items.LockItemsForWrite(false); | ||
143 | } | 149 | } |
144 | 150 | ||
145 | public void ResetObjectID() | 151 | public void ResetObjectID() |
146 | { | 152 | { |
147 | lock (Items) | 153 | m_items.LockItemsForWrite(true); |
154 | |||
155 | if (Items.Count == 0) | ||
148 | { | 156 | { |
149 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | 157 | m_items.LockItemsForWrite(false); |
150 | Items.Clear(); | 158 | return; |
151 | |||
152 | foreach (TaskInventoryItem item in items) | ||
153 | { | ||
154 | item.ParentPartID = m_part.UUID; | ||
155 | item.ParentID = m_part.UUID; | ||
156 | Items.Add(item.ItemID, item); | ||
157 | } | ||
158 | } | 159 | } |
160 | |||
161 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | ||
162 | Items.Clear(); | ||
163 | |||
164 | foreach (TaskInventoryItem item in items) | ||
165 | { | ||
166 | item.ParentPartID = m_part.UUID; | ||
167 | item.ParentID = m_part.UUID; | ||
168 | Items.Add(item.ItemID, item); | ||
169 | } | ||
170 | m_items.LockItemsForWrite(false); | ||
159 | } | 171 | } |
160 | 172 | ||
161 | /// <summary> | 173 | /// <summary> |
@@ -164,17 +176,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
164 | /// <param name="ownerId"></param> | 176 | /// <param name="ownerId"></param> |
165 | public void ChangeInventoryOwner(UUID ownerId) | 177 | public void ChangeInventoryOwner(UUID ownerId) |
166 | { | 178 | { |
167 | lock (Items) | 179 | List<TaskInventoryItem> items = GetInventoryItems(); |
168 | { | ||
169 | if (0 == Items.Count) | ||
170 | { | ||
171 | return; | ||
172 | } | ||
173 | } | ||
174 | 180 | ||
181 | if (items.Count == 0) | ||
182 | return; | ||
183 | |||
184 | m_items.LockItemsForWrite(true); | ||
175 | HasInventoryChanged = true; | 185 | HasInventoryChanged = true; |
176 | m_part.ParentGroup.HasGroupChanged = true; | 186 | m_part.ParentGroup.HasGroupChanged = true; |
177 | List<TaskInventoryItem> items = GetInventoryItems(); | ||
178 | foreach (TaskInventoryItem item in items) | 187 | foreach (TaskInventoryItem item in items) |
179 | { | 188 | { |
180 | if (ownerId != item.OwnerID) | 189 | if (ownerId != item.OwnerID) |
@@ -185,6 +194,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
185 | item.PermsGranter = UUID.Zero; | 194 | item.PermsGranter = UUID.Zero; |
186 | item.OwnerChanged = true; | 195 | item.OwnerChanged = true; |
187 | } | 196 | } |
197 | m_items.LockItemsForWrite(false); | ||
188 | } | 198 | } |
189 | 199 | ||
190 | /// <summary> | 200 | /// <summary> |
@@ -193,12 +203,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
193 | /// <param name="groupID"></param> | 203 | /// <param name="groupID"></param> |
194 | public void ChangeInventoryGroup(UUID groupID) | 204 | public void ChangeInventoryGroup(UUID groupID) |
195 | { | 205 | { |
196 | lock (Items) | 206 | m_items.LockItemsForWrite(true); |
207 | if (0 == Items.Count) | ||
197 | { | 208 | { |
198 | if (0 == Items.Count) | 209 | m_items.LockItemsForWrite(false); |
199 | { | 210 | return; |
200 | return; | ||
201 | } | ||
202 | } | 211 | } |
203 | 212 | ||
204 | // Don't let this set the HasGroupChanged flag for attachments | 213 | // Don't let this set the HasGroupChanged flag for attachments |
@@ -210,12 +219,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
210 | m_part.ParentGroup.HasGroupChanged = true; | 219 | m_part.ParentGroup.HasGroupChanged = true; |
211 | } | 220 | } |
212 | 221 | ||
213 | List<TaskInventoryItem> items = GetInventoryItems(); | 222 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
214 | foreach (TaskInventoryItem item in items) | 223 | foreach (TaskInventoryItem item in items) |
215 | { | 224 | { |
216 | if (groupID != item.GroupID) | 225 | if (groupID != item.GroupID) |
226 | { | ||
217 | item.GroupID = groupID; | 227 | item.GroupID = groupID; |
228 | } | ||
218 | } | 229 | } |
230 | m_items.LockItemsForWrite(false); | ||
219 | } | 231 | } |
220 | 232 | ||
221 | private void QueryScriptStates() | 233 | private void QueryScriptStates() |
@@ -227,25 +239,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
227 | if (engines == null) // No engine at all | 239 | if (engines == null) // No engine at all |
228 | return; | 240 | return; |
229 | 241 | ||
230 | lock (Items) | 242 | Items.LockItemsForRead(true); |
243 | foreach (TaskInventoryItem item in Items.Values) | ||
231 | { | 244 | { |
232 | foreach (TaskInventoryItem item in Items.Values) | 245 | if (item.InvType == (int)InventoryType.LSL) |
233 | { | 246 | { |
234 | if (item.InvType == (int)InventoryType.LSL) | 247 | foreach (IScriptModule e in engines) |
235 | { | 248 | { |
236 | foreach (IScriptModule e in engines) | 249 | bool running; |
237 | { | ||
238 | bool running; | ||
239 | 250 | ||
240 | if (e.HasScript(item.ItemID, out running)) | 251 | if (e.HasScript(item.ItemID, out running)) |
241 | { | 252 | { |
242 | item.ScriptRunning = running; | 253 | item.ScriptRunning = running; |
243 | break; | 254 | break; |
244 | } | ||
245 | } | 255 | } |
246 | } | 256 | } |
247 | } | 257 | } |
248 | } | 258 | } |
259 | |||
260 | Items.LockItemsForRead(false); | ||
249 | } | 261 | } |
250 | 262 | ||
251 | public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) | 263 | public int CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) |
@@ -290,7 +302,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
290 | { | 302 | { |
291 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); | 303 | List<TaskInventoryItem> scripts = GetInventoryItems(InventoryType.LSL); |
292 | foreach (TaskInventoryItem item in scripts) | 304 | foreach (TaskInventoryItem item in scripts) |
305 | { | ||
293 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); | 306 | RemoveScriptInstance(item.ItemID, sceneObjectBeingDeleted); |
307 | m_part.RemoveScriptEvents(item.ItemID); | ||
308 | } | ||
294 | } | 309 | } |
295 | 310 | ||
296 | /// <summary> | 311 | /// <summary> |
@@ -312,7 +327,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
312 | // item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 327 | // item.Name, item.ItemID, m_part.Name, m_part.UUID, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
313 | 328 | ||
314 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) | 329 | if (!m_part.ParentGroup.Scene.Permissions.CanRunScript(item.ItemID, m_part.UUID, item.OwnerID)) |
330 | { | ||
331 | StoreScriptError(item.ItemID, "no permission"); | ||
315 | return false; | 332 | return false; |
333 | } | ||
316 | 334 | ||
317 | m_part.AddFlag(PrimFlags.Scripted); | 335 | m_part.AddFlag(PrimFlags.Scripted); |
318 | 336 | ||
@@ -322,14 +340,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
322 | if (stateSource == 2 && // Prim crossing | 340 | if (stateSource == 2 && // Prim crossing |
323 | m_part.ParentGroup.Scene.m_trustBinaries) | 341 | m_part.ParentGroup.Scene.m_trustBinaries) |
324 | { | 342 | { |
325 | lock (m_items) | 343 | m_items.LockItemsForWrite(true); |
326 | { | 344 | m_items[item.ItemID].PermsMask = 0; |
327 | m_items[item.ItemID].PermsMask = 0; | 345 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
328 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 346 | m_items.LockItemsForWrite(false); |
329 | } | ||
330 | |||
331 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 347 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
332 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); | 348 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); |
349 | StoreScriptErrors(item.ItemID, null); | ||
333 | m_part.ParentGroup.AddActiveScriptCount(1); | 350 | m_part.ParentGroup.AddActiveScriptCount(1); |
334 | m_part.ScheduleFullUpdate(); | 351 | m_part.ScheduleFullUpdate(); |
335 | return true; | 352 | return true; |
@@ -350,16 +367,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
350 | if (m_part.ParentGroup.m_savedScriptState != null) | 367 | if (m_part.ParentGroup.m_savedScriptState != null) |
351 | item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); | 368 | item.OldItemID = RestoreSavedScriptState(item.LoadedItemID, item.OldItemID, item.ItemID); |
352 | 369 | ||
353 | lock (m_items) | 370 | string msg = String.Format("asset ID {0} could not be found", item.AssetID); |
354 | { | 371 | StoreScriptError(item.ItemID, msg); |
355 | m_items[item.ItemID].OldItemID = item.OldItemID; | 372 | m_log.ErrorFormat( |
356 | m_items[item.ItemID].PermsMask = 0; | 373 | "[PRIM INVENTORY]: Couldn't start script {0}, {1} at {2} in {3} since asset ID {4} could not be found", |
357 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 374 | item.Name, item.ItemID, m_part.AbsolutePosition, |
358 | } | 375 | m_part.ParentGroup.Scene.RegionInfo.RegionName, item.AssetID); |
359 | 376 | ||
377 | m_items.LockItemsForWrite(true); | ||
378 | |||
379 | m_items[item.ItemID].OldItemID = item.OldItemID; | ||
380 | m_items[item.ItemID].PermsMask = 0; | ||
381 | m_items[item.ItemID].PermsGranter = UUID.Zero; | ||
382 | |||
383 | m_items.LockItemsForWrite(false); | ||
384 | |||
360 | string script = Utils.BytesToString(asset.Data); | 385 | string script = Utils.BytesToString(asset.Data); |
361 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 386 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
362 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); | 387 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); |
388 | StoreScriptErrors(item.ItemID, null); | ||
363 | if (!item.ScriptRunning) | 389 | if (!item.ScriptRunning) |
364 | m_part.ParentGroup.Scene.EventManager.TriggerStopScript( | 390 | m_part.ParentGroup.Scene.EventManager.TriggerStopScript( |
365 | m_part.LocalId, item.ItemID); | 391 | m_part.LocalId, item.ItemID); |
@@ -432,22 +458,149 @@ namespace OpenSim.Region.Framework.Scenes | |||
432 | return stateID; | 458 | return stateID; |
433 | } | 459 | } |
434 | 460 | ||
461 | /// <summary> | ||
462 | /// Start a script which is in this prim's inventory. | ||
463 | /// Some processing may occur in the background, but this routine returns asap. | ||
464 | /// </summary> | ||
465 | /// <param name="itemId"> | ||
466 | /// A <see cref="UUID"/> | ||
467 | /// </param> | ||
435 | public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | 468 | public bool CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) |
436 | { | 469 | { |
437 | TaskInventoryItem item = GetInventoryItem(itemId); | 470 | lock (m_scriptErrors) |
438 | if (item != null) | ||
439 | { | 471 | { |
440 | return CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | 472 | // Indicate to CreateScriptInstanceInternal() we don't want it to wait for completion |
473 | m_scriptErrors.Remove(itemId); | ||
474 | } | ||
475 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
476 | return true; | ||
477 | } | ||
478 | |||
479 | private void CreateScriptInstanceInternal(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
480 | { | ||
481 | m_items.LockItemsForRead(true); | ||
482 | if (m_items.ContainsKey(itemId)) | ||
483 | { | ||
484 | if (m_items.ContainsKey(itemId)) | ||
485 | { | ||
486 | m_items.LockItemsForRead(false); | ||
487 | CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); | ||
488 | } | ||
489 | else | ||
490 | { | ||
491 | m_items.LockItemsForRead(false); | ||
492 | string msg = String.Format("couldn't be found for prim {0}, {1} at {2} in {3}", m_part.Name, m_part.UUID, | ||
493 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
494 | StoreScriptError(itemId, msg); | ||
495 | m_log.ErrorFormat( | ||
496 | "[PRIM INVENTORY]: " + | ||
497 | "Couldn't start script with ID {0} since it {1}", itemId, msg); | ||
498 | } | ||
441 | } | 499 | } |
442 | else | 500 | else |
443 | { | 501 | { |
502 | m_items.LockItemsForRead(false); | ||
503 | string msg = String.Format("couldn't be found for prim {0}, {1}", m_part.Name, m_part.UUID); | ||
504 | StoreScriptError(itemId, msg); | ||
444 | m_log.ErrorFormat( | 505 | m_log.ErrorFormat( |
445 | "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", | 506 | "[PRIM INVENTORY]: Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2} at {3} in {4}", |
446 | itemId, m_part.Name, m_part.UUID, | 507 | itemId, m_part.Name, m_part.UUID, |
447 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 508 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
509 | } | ||
510 | |||
511 | } | ||
448 | 512 | ||
449 | return false; | 513 | /// <summary> |
514 | /// Start a script which is in this prim's inventory and return any compilation error messages. | ||
515 | /// </summary> | ||
516 | /// <param name="itemId"> | ||
517 | /// A <see cref="UUID"/> | ||
518 | /// </param> | ||
519 | public ArrayList CreateScriptInstanceEr(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | ||
520 | { | ||
521 | ArrayList errors; | ||
522 | |||
523 | // Indicate to CreateScriptInstanceInternal() we want it to | ||
524 | // post any compilation/loading error messages | ||
525 | lock (m_scriptErrors) | ||
526 | { | ||
527 | m_scriptErrors[itemId] = null; | ||
528 | } | ||
529 | |||
530 | // Perform compilation/loading | ||
531 | CreateScriptInstanceInternal(itemId, startParam, postOnRez, engine, stateSource); | ||
532 | |||
533 | // Wait for and retrieve any errors | ||
534 | lock (m_scriptErrors) | ||
535 | { | ||
536 | while ((errors = m_scriptErrors[itemId]) == null) | ||
537 | { | ||
538 | if (!System.Threading.Monitor.Wait(m_scriptErrors, 15000)) | ||
539 | { | ||
540 | m_log.ErrorFormat( | ||
541 | "[PRIM INVENTORY]: " + | ||
542 | "timedout waiting for script {0} errors", itemId); | ||
543 | errors = m_scriptErrors[itemId]; | ||
544 | if (errors == null) | ||
545 | { | ||
546 | errors = new ArrayList(1); | ||
547 | errors.Add("timedout waiting for errors"); | ||
548 | } | ||
549 | break; | ||
550 | } | ||
551 | } | ||
552 | m_scriptErrors.Remove(itemId); | ||
553 | } | ||
554 | return errors; | ||
555 | } | ||
556 | |||
557 | // Signal to CreateScriptInstanceEr() that compilation/loading is complete | ||
558 | private void StoreScriptErrors(UUID itemId, ArrayList errors) | ||
559 | { | ||
560 | lock (m_scriptErrors) | ||
561 | { | ||
562 | // If compilation/loading initiated via CreateScriptInstance(), | ||
563 | // it does not want the errors, so just get out | ||
564 | if (!m_scriptErrors.ContainsKey(itemId)) | ||
565 | { | ||
566 | return; | ||
567 | } | ||
568 | |||
569 | // Initiated via CreateScriptInstanceEr(), if we know what the | ||
570 | // errors are, save them and wake CreateScriptInstanceEr(). | ||
571 | if (errors != null) | ||
572 | { | ||
573 | m_scriptErrors[itemId] = errors; | ||
574 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
575 | return; | ||
576 | } | ||
450 | } | 577 | } |
578 | |||
579 | // Initiated via CreateScriptInstanceEr() but we don't know what | ||
580 | // the errors are yet, so retrieve them from the script engine. | ||
581 | // This may involve some waiting internal to GetScriptErrors(). | ||
582 | errors = GetScriptErrors(itemId); | ||
583 | |||
584 | // Get a default non-null value to indicate success. | ||
585 | if (errors == null) | ||
586 | { | ||
587 | errors = new ArrayList(); | ||
588 | } | ||
589 | |||
590 | // Post to CreateScriptInstanceEr() and wake it up | ||
591 | lock (m_scriptErrors) | ||
592 | { | ||
593 | m_scriptErrors[itemId] = errors; | ||
594 | System.Threading.Monitor.PulseAll(m_scriptErrors); | ||
595 | } | ||
596 | } | ||
597 | |||
598 | // Like StoreScriptErrors(), but just posts a single string message | ||
599 | private void StoreScriptError(UUID itemId, string message) | ||
600 | { | ||
601 | ArrayList errors = new ArrayList(1); | ||
602 | errors.Add(message); | ||
603 | StoreScriptErrors(itemId, errors); | ||
451 | } | 604 | } |
452 | 605 | ||
453 | /// <summary> | 606 | /// <summary> |
@@ -460,15 +613,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
460 | /// </param> | 613 | /// </param> |
461 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) | 614 | public void RemoveScriptInstance(UUID itemId, bool sceneObjectBeingDeleted) |
462 | { | 615 | { |
463 | bool scriptPresent = false; | 616 | if (m_items.ContainsKey(itemId)) |
464 | |||
465 | lock (m_items) | ||
466 | { | ||
467 | if (m_items.ContainsKey(itemId)) | ||
468 | scriptPresent = true; | ||
469 | } | ||
470 | |||
471 | if (scriptPresent) | ||
472 | { | 617 | { |
473 | if (!sceneObjectBeingDeleted) | 618 | if (!sceneObjectBeingDeleted) |
474 | m_part.RemoveScriptEvents(itemId); | 619 | m_part.RemoveScriptEvents(itemId); |
@@ -538,14 +683,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
538 | /// <returns></returns> | 683 | /// <returns></returns> |
539 | private bool InventoryContainsName(string name) | 684 | private bool InventoryContainsName(string name) |
540 | { | 685 | { |
541 | lock (m_items) | 686 | m_items.LockItemsForRead(true); |
687 | foreach (TaskInventoryItem item in m_items.Values) | ||
542 | { | 688 | { |
543 | foreach (TaskInventoryItem item in m_items.Values) | 689 | if (item.Name == name) |
544 | { | 690 | { |
545 | if (item.Name == name) | 691 | m_items.LockItemsForRead(false); |
546 | return true; | 692 | return true; |
547 | } | 693 | } |
548 | } | 694 | } |
695 | m_items.LockItemsForRead(false); | ||
549 | return false; | 696 | return false; |
550 | } | 697 | } |
551 | 698 | ||
@@ -587,8 +734,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
587 | /// <param name="item"></param> | 734 | /// <param name="item"></param> |
588 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) | 735 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) |
589 | { | 736 | { |
590 | List<TaskInventoryItem> il = GetInventoryItems(); | 737 | m_items.LockItemsForRead(true); |
591 | 738 | List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); | |
739 | m_items.LockItemsForRead(false); | ||
592 | foreach (TaskInventoryItem i in il) | 740 | foreach (TaskInventoryItem i in il) |
593 | { | 741 | { |
594 | if (i.Name == item.Name) | 742 | if (i.Name == item.Name) |
@@ -626,14 +774,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
626 | item.Name = name; | 774 | item.Name = name; |
627 | item.GroupID = m_part.GroupID; | 775 | item.GroupID = m_part.GroupID; |
628 | 776 | ||
629 | lock (m_items) | 777 | m_items.LockItemsForWrite(true); |
630 | m_items.Add(item.ItemID, item); | 778 | m_items.Add(item.ItemID, item); |
631 | 779 | m_items.LockItemsForWrite(false); | |
632 | if (allowedDrop) | 780 | if (allowedDrop) |
633 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); | 781 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); |
634 | else | 782 | else |
635 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 783 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
636 | 784 | ||
637 | m_inventorySerial++; | 785 | m_inventorySerial++; |
638 | //m_inventorySerial += 2; | 786 | //m_inventorySerial += 2; |
639 | HasInventoryChanged = true; | 787 | HasInventoryChanged = true; |
@@ -649,15 +797,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
649 | /// <param name="items"></param> | 797 | /// <param name="items"></param> |
650 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) | 798 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) |
651 | { | 799 | { |
652 | lock (m_items) | 800 | m_items.LockItemsForWrite(true); |
801 | foreach (TaskInventoryItem item in items) | ||
653 | { | 802 | { |
654 | foreach (TaskInventoryItem item in items) | 803 | m_items.Add(item.ItemID, item); |
655 | { | 804 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
656 | m_items.Add(item.ItemID, item); | ||
657 | // m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
658 | } | ||
659 | m_inventorySerial++; | ||
660 | } | 805 | } |
806 | m_items.LockItemsForWrite(false); | ||
807 | |||
808 | m_inventorySerial++; | ||
661 | } | 809 | } |
662 | 810 | ||
663 | /// <summary> | 811 | /// <summary> |
@@ -668,23 +816,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
668 | public TaskInventoryItem GetInventoryItem(UUID itemId) | 816 | public TaskInventoryItem GetInventoryItem(UUID itemId) |
669 | { | 817 | { |
670 | TaskInventoryItem item; | 818 | TaskInventoryItem item; |
671 | 819 | m_items.LockItemsForRead(true); | |
672 | lock (m_items) | 820 | m_items.TryGetValue(itemId, out item); |
673 | m_items.TryGetValue(itemId, out item); | 821 | m_items.LockItemsForRead(false); |
674 | |||
675 | return item; | 822 | return item; |
676 | } | 823 | } |
677 | 824 | ||
678 | public TaskInventoryItem GetInventoryItem(string name) | 825 | public TaskInventoryItem GetInventoryItem(string name) |
679 | { | 826 | { |
680 | lock (m_items) | 827 | m_items.LockItemsForRead(true); |
828 | foreach (TaskInventoryItem item in m_items.Values) | ||
681 | { | 829 | { |
682 | foreach (TaskInventoryItem item in m_items.Values) | 830 | if (item.Name == name) |
683 | { | 831 | { |
684 | if (item.Name == name) | 832 | m_items.LockItemsForRead(false); |
685 | return item; | 833 | return item; |
686 | } | 834 | } |
687 | } | 835 | } |
836 | m_items.LockItemsForRead(false); | ||
688 | 837 | ||
689 | return null; | 838 | return null; |
690 | } | 839 | } |
@@ -693,15 +842,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
693 | { | 842 | { |
694 | List<TaskInventoryItem> items = new List<TaskInventoryItem>(); | 843 | List<TaskInventoryItem> items = new List<TaskInventoryItem>(); |
695 | 844 | ||
696 | lock (m_items) | 845 | m_items.LockItemsForRead(true); |
846 | |||
847 | foreach (TaskInventoryItem item in m_items.Values) | ||
697 | { | 848 | { |
698 | foreach (TaskInventoryItem item in m_items.Values) | 849 | if (item.Name == name) |
699 | { | 850 | items.Add(item); |
700 | if (item.Name == name) | ||
701 | items.Add(item); | ||
702 | } | ||
703 | } | 851 | } |
704 | 852 | ||
853 | m_items.LockItemsForRead(false); | ||
854 | |||
705 | return items; | 855 | return items; |
706 | } | 856 | } |
707 | 857 | ||
@@ -720,6 +870,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
720 | string xmlData = Utils.BytesToString(rezAsset.Data); | 870 | string xmlData = Utils.BytesToString(rezAsset.Data); |
721 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); | 871 | SceneObjectGroup group = SceneObjectSerializer.FromOriginalXmlFormat(xmlData); |
722 | 872 | ||
873 | group.RootPart.AttachPoint = group.RootPart.Shape.State; | ||
874 | group.RootPart.AttachOffset = group.AbsolutePosition; | ||
875 | group.RootPart.AttachRotation = group.GroupRotation; | ||
876 | |||
723 | group.ResetIDs(); | 877 | group.ResetIDs(); |
724 | 878 | ||
725 | SceneObjectPart rootPart = group.GetPart(group.UUID); | 879 | SceneObjectPart rootPart = group.GetPart(group.UUID); |
@@ -794,8 +948,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
794 | 948 | ||
795 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) | 949 | public bool UpdateInventoryItem(TaskInventoryItem item, bool fireScriptEvents, bool considerChanged) |
796 | { | 950 | { |
797 | TaskInventoryItem it = GetInventoryItem(item.ItemID); | 951 | m_items.LockItemsForWrite(true); |
798 | if (it != null) | 952 | |
953 | if (m_items.ContainsKey(item.ItemID)) | ||
799 | { | 954 | { |
800 | // m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); | 955 | // m_log.DebugFormat("[PRIM INVENTORY]: Updating item {0} in {1}", item.Name, m_part.Name); |
801 | 956 | ||
@@ -808,14 +963,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
808 | item.GroupID = m_part.GroupID; | 963 | item.GroupID = m_part.GroupID; |
809 | 964 | ||
810 | if (item.AssetID == UUID.Zero) | 965 | if (item.AssetID == UUID.Zero) |
811 | item.AssetID = it.AssetID; | 966 | item.AssetID = m_items[item.ItemID].AssetID; |
812 | 967 | ||
813 | lock (m_items) | 968 | m_items[item.ItemID] = item; |
814 | { | 969 | m_inventorySerial++; |
815 | m_items[item.ItemID] = item; | ||
816 | m_inventorySerial++; | ||
817 | } | ||
818 | |||
819 | if (fireScriptEvents) | 970 | if (fireScriptEvents) |
820 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 971 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
821 | 972 | ||
@@ -824,7 +975,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
824 | HasInventoryChanged = true; | 975 | HasInventoryChanged = true; |
825 | m_part.ParentGroup.HasGroupChanged = true; | 976 | m_part.ParentGroup.HasGroupChanged = true; |
826 | } | 977 | } |
827 | 978 | m_items.LockItemsForWrite(false); | |
828 | return true; | 979 | return true; |
829 | } | 980 | } |
830 | else | 981 | else |
@@ -835,8 +986,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
835 | item.ItemID, m_part.Name, m_part.UUID, | 986 | item.ItemID, m_part.Name, m_part.UUID, |
836 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | 987 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); |
837 | } | 988 | } |
838 | return false; | 989 | m_items.LockItemsForWrite(false); |
839 | 990 | ||
991 | return false; | ||
840 | } | 992 | } |
841 | 993 | ||
842 | /// <summary> | 994 | /// <summary> |
@@ -847,43 +999,59 @@ namespace OpenSim.Region.Framework.Scenes | |||
847 | /// in this prim's inventory.</returns> | 999 | /// in this prim's inventory.</returns> |
848 | public int RemoveInventoryItem(UUID itemID) | 1000 | public int RemoveInventoryItem(UUID itemID) |
849 | { | 1001 | { |
850 | TaskInventoryItem item = GetInventoryItem(itemID); | 1002 | m_items.LockItemsForRead(true); |
851 | if (item != null) | 1003 | |
1004 | if (m_items.ContainsKey(itemID)) | ||
852 | { | 1005 | { |
853 | int type = m_items[itemID].InvType; | 1006 | int type = m_items[itemID].InvType; |
1007 | m_items.LockItemsForRead(false); | ||
854 | if (type == 10) // Script | 1008 | if (type == 10) // Script |
855 | { | 1009 | { |
856 | m_part.RemoveScriptEvents(itemID); | ||
857 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); | 1010 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); |
858 | } | 1011 | } |
1012 | m_items.LockItemsForWrite(true); | ||
859 | m_items.Remove(itemID); | 1013 | m_items.Remove(itemID); |
1014 | m_items.LockItemsForWrite(false); | ||
860 | m_inventorySerial++; | 1015 | m_inventorySerial++; |
861 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 1016 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
862 | 1017 | ||
863 | HasInventoryChanged = true; | 1018 | HasInventoryChanged = true; |
864 | m_part.ParentGroup.HasGroupChanged = true; | 1019 | m_part.ParentGroup.HasGroupChanged = true; |
865 | 1020 | ||
866 | if (!ContainsScripts()) | 1021 | int scriptcount = 0; |
1022 | m_items.LockItemsForRead(true); | ||
1023 | foreach (TaskInventoryItem item in m_items.Values) | ||
1024 | { | ||
1025 | if (item.Type == 10) | ||
1026 | { | ||
1027 | scriptcount++; | ||
1028 | } | ||
1029 | } | ||
1030 | m_items.LockItemsForRead(false); | ||
1031 | |||
1032 | |||
1033 | if (scriptcount <= 0) | ||
1034 | { | ||
867 | m_part.RemFlag(PrimFlags.Scripted); | 1035 | m_part.RemFlag(PrimFlags.Scripted); |
1036 | } | ||
868 | 1037 | ||
869 | m_part.ScheduleFullUpdate(); | 1038 | m_part.ScheduleFullUpdate(); |
870 | 1039 | ||
871 | return type; | 1040 | return type; |
872 | |||
873 | } | 1041 | } |
874 | else | 1042 | else |
875 | { | 1043 | { |
1044 | m_items.LockItemsForRead(false); | ||
876 | m_log.ErrorFormat( | 1045 | m_log.ErrorFormat( |
877 | "[PRIM INVENTORY]: " + | 1046 | "[PRIM INVENTORY]: " + |
878 | "Tried to remove item ID {0} from prim {1}, {2} at {3} in {4} but the item does not exist in this inventory", | 1047 | "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", |
879 | itemID, m_part.Name, m_part.UUID, | 1048 | itemID, m_part.Name, m_part.UUID); |
880 | m_part.AbsolutePosition, m_part.ParentGroup.Scene.RegionInfo.RegionName); | ||
881 | } | 1049 | } |
882 | 1050 | ||
883 | return -1; | 1051 | return -1; |
884 | } | 1052 | } |
885 | 1053 | ||
886 | private bool CreateInventoryFile() | 1054 | private bool CreateInventoryFileName() |
887 | { | 1055 | { |
888 | // m_log.DebugFormat( | 1056 | // m_log.DebugFormat( |
889 | // "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", | 1057 | // "[PRIM INVENTORY]: Creating inventory file for {0} {1} {2}, serial {3}", |
@@ -892,70 +1060,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
892 | if (m_inventoryFileName == String.Empty || | 1060 | if (m_inventoryFileName == String.Empty || |
893 | m_inventoryFileNameSerial < m_inventorySerial) | 1061 | m_inventoryFileNameSerial < m_inventorySerial) |
894 | { | 1062 | { |
895 | // Something changed, we need to create a new file | ||
896 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; | 1063 | m_inventoryFileName = "inventory_" + UUID.Random().ToString() + ".tmp"; |
897 | m_inventoryFileNameSerial = m_inventorySerial; | 1064 | m_inventoryFileNameSerial = m_inventorySerial; |
898 | 1065 | ||
899 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | ||
900 | |||
901 | lock (m_items) | ||
902 | { | ||
903 | foreach (TaskInventoryItem item in m_items.Values) | ||
904 | { | ||
905 | // m_log.DebugFormat( | ||
906 | // "[PRIM INVENTORY]: Adding item {0} {1} for serial {2} on prim {3} {4} {5}", | ||
907 | // item.Name, item.ItemID, m_inventorySerial, m_part.Name, m_part.UUID, m_part.LocalId); | ||
908 | |||
909 | UUID ownerID = item.OwnerID; | ||
910 | uint everyoneMask = 0; | ||
911 | uint baseMask = item.BasePermissions; | ||
912 | uint ownerMask = item.CurrentPermissions; | ||
913 | uint groupMask = item.GroupPermissions; | ||
914 | |||
915 | invString.AddItemStart(); | ||
916 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
917 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
918 | |||
919 | invString.AddPermissionsStart(); | ||
920 | |||
921 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | ||
922 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
923 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
924 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
925 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
926 | |||
927 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | ||
928 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
929 | |||
930 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
931 | |||
932 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | ||
933 | invString.AddSectionEnd(); | ||
934 | |||
935 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
936 | invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type)); | ||
937 | invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType)); | ||
938 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
939 | |||
940 | invString.AddSaleStart(); | ||
941 | invString.AddNameValueLine("sale_type", "not"); | ||
942 | invString.AddNameValueLine("sale_price", "0"); | ||
943 | invString.AddSectionEnd(); | ||
944 | |||
945 | invString.AddNameValueLine("name", item.Name + "|"); | ||
946 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
947 | |||
948 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
949 | invString.AddSectionEnd(); | ||
950 | } | ||
951 | } | ||
952 | |||
953 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | ||
954 | |||
955 | return true; | 1066 | return true; |
956 | } | 1067 | } |
957 | 1068 | ||
958 | // No need to recreate, the existing file is fine | ||
959 | return false; | 1069 | return false; |
960 | } | 1070 | } |
961 | 1071 | ||
@@ -965,43 +1075,110 @@ namespace OpenSim.Region.Framework.Scenes | |||
965 | /// <param name="xferManager"></param> | 1075 | /// <param name="xferManager"></param> |
966 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) | 1076 | public void RequestInventoryFile(IClientAPI client, IXfer xferManager) |
967 | { | 1077 | { |
968 | lock (m_items) | 1078 | bool changed = CreateInventoryFileName(); |
969 | { | ||
970 | // Don't send a inventory xfer name if there are no items. Doing so causes viewer 3 to crash when rezzing | ||
971 | // a new script if any previous deletion has left the prim inventory empty. | ||
972 | if (m_items.Count == 0) // No inventory | ||
973 | { | ||
974 | // m_log.DebugFormat( | ||
975 | // "[PRIM INVENTORY]: Not sending inventory data for part {0} {1} {2} for {3} since no items", | ||
976 | // m_part.Name, m_part.LocalId, m_part.UUID, client.Name); | ||
977 | 1079 | ||
978 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | 1080 | bool includeAssets = false; |
979 | return; | 1081 | if (m_part.ParentGroup.Scene.Permissions.CanEditObjectInventory(m_part.UUID, client.AgentId)) |
980 | } | 1082 | includeAssets = true; |
1083 | |||
1084 | if (m_inventoryPrivileged != includeAssets) | ||
1085 | changed = true; | ||
981 | 1086 | ||
982 | CreateInventoryFile(); | 1087 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); |
1088 | |||
1089 | Items.LockItemsForRead(true); | ||
1090 | |||
1091 | if (m_inventorySerial == 0) // No inventory | ||
1092 | { | ||
1093 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
1094 | Items.LockItemsForRead(false); | ||
1095 | return; | ||
1096 | } | ||
1097 | |||
1098 | if (m_items.Count == 0) // No inventory | ||
1099 | { | ||
1100 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
1101 | Items.LockItemsForRead(false); | ||
1102 | return; | ||
1103 | } | ||
983 | 1104 | ||
984 | // In principle, we should only do the rest if the inventory changed; | 1105 | if (!changed) |
985 | // by sending m_inventorySerial to the client, it ought to know | 1106 | { |
986 | // that nothing changed and that it doesn't need to request the file. | ||
987 | // Unfortunately, it doesn't look like the client optimizes this; | ||
988 | // the client seems to always come back and request the Xfer, | ||
989 | // no matter what value m_inventorySerial has. | ||
990 | // FIXME: Could probably be > 0 here rather than > 2 | ||
991 | if (m_inventoryFileData.Length > 2) | 1107 | if (m_inventoryFileData.Length > 2) |
992 | { | 1108 | { |
993 | // Add the file for Xfer | 1109 | xferManager.AddNewFile(m_inventoryFileName, |
994 | // m_log.DebugFormat( | 1110 | m_inventoryFileData); |
995 | // "[PRIM INVENTORY]: Adding inventory file {0} (length {1}) for transfer on {2} {3} {4}", | 1111 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, |
996 | // m_inventoryFileName, m_inventoryFileData.Length, m_part.Name, m_part.UUID, m_part.LocalId); | 1112 | Util.StringToBytes256(m_inventoryFileName)); |
997 | 1113 | ||
998 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | 1114 | Items.LockItemsForRead(false); |
1115 | return; | ||
999 | } | 1116 | } |
1000 | |||
1001 | // Tell the client we're ready to Xfer the file | ||
1002 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | ||
1003 | Util.StringToBytes256(m_inventoryFileName)); | ||
1004 | } | 1117 | } |
1118 | |||
1119 | m_inventoryPrivileged = includeAssets; | ||
1120 | |||
1121 | foreach (TaskInventoryItem item in m_items.Values) | ||
1122 | { | ||
1123 | UUID ownerID = item.OwnerID; | ||
1124 | uint everyoneMask = 0; | ||
1125 | uint baseMask = item.BasePermissions; | ||
1126 | uint ownerMask = item.CurrentPermissions; | ||
1127 | uint groupMask = item.GroupPermissions; | ||
1128 | |||
1129 | invString.AddItemStart(); | ||
1130 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | ||
1131 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | ||
1132 | |||
1133 | invString.AddPermissionsStart(); | ||
1134 | |||
1135 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | ||
1136 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | ||
1137 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(groupMask)); | ||
1138 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | ||
1139 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | ||
1140 | |||
1141 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | ||
1142 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | ||
1143 | |||
1144 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | ||
1145 | |||
1146 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | ||
1147 | invString.AddSectionEnd(); | ||
1148 | |||
1149 | if (includeAssets) | ||
1150 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | ||
1151 | else | ||
1152 | invString.AddNameValueLine("asset_id", UUID.Zero.ToString()); | ||
1153 | invString.AddNameValueLine("type", Utils.AssetTypeToString((AssetType)item.Type)); | ||
1154 | invString.AddNameValueLine("inv_type", Utils.InventoryTypeToString((InventoryType)item.InvType)); | ||
1155 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | ||
1156 | |||
1157 | invString.AddSaleStart(); | ||
1158 | invString.AddNameValueLine("sale_type", "not"); | ||
1159 | invString.AddNameValueLine("sale_price", "0"); | ||
1160 | invString.AddSectionEnd(); | ||
1161 | |||
1162 | invString.AddNameValueLine("name", item.Name + "|"); | ||
1163 | invString.AddNameValueLine("desc", item.Description + "|"); | ||
1164 | |||
1165 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | ||
1166 | invString.AddSectionEnd(); | ||
1167 | } | ||
1168 | |||
1169 | Items.LockItemsForRead(false); | ||
1170 | |||
1171 | m_inventoryFileData = Utils.StringToBytes(invString.BuildString); | ||
1172 | |||
1173 | if (m_inventoryFileData.Length > 2) | ||
1174 | { | ||
1175 | xferManager.AddNewFile(m_inventoryFileName, m_inventoryFileData); | ||
1176 | client.SendTaskInventory(m_part.UUID, (short)m_inventorySerial, | ||
1177 | Util.StringToBytes256(m_inventoryFileName)); | ||
1178 | return; | ||
1179 | } | ||
1180 | |||
1181 | client.SendTaskInventory(m_part.UUID, 0, new byte[0]); | ||
1005 | } | 1182 | } |
1006 | 1183 | ||
1007 | /// <summary> | 1184 | /// <summary> |
@@ -1010,13 +1187,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
1010 | /// <param name="datastore"></param> | 1187 | /// <param name="datastore"></param> |
1011 | public void ProcessInventoryBackup(ISimulationDataService datastore) | 1188 | public void ProcessInventoryBackup(ISimulationDataService datastore) |
1012 | { | 1189 | { |
1013 | if (HasInventoryChanged) | 1190 | // Removed this because linking will cause an immediate delete of the new |
1014 | { | 1191 | // child prim from the database and the subsequent storing of the prim sees |
1015 | HasInventoryChanged = false; | 1192 | // the inventory of it as unchanged and doesn't store it at all. The overhead |
1016 | List<TaskInventoryItem> items = GetInventoryItems(); | 1193 | // of storing prim inventory needlessly is much less than the aggravation |
1017 | datastore.StorePrimInventory(m_part.UUID, items); | 1194 | // of prim inventory loss. |
1195 | // if (HasInventoryChanged) | ||
1196 | // { | ||
1197 | Items.LockItemsForRead(true); | ||
1198 | datastore.StorePrimInventory(m_part.UUID, Items.Values); | ||
1199 | Items.LockItemsForRead(false); | ||
1018 | 1200 | ||
1019 | } | 1201 | HasInventoryChanged = false; |
1202 | // } | ||
1020 | } | 1203 | } |
1021 | 1204 | ||
1022 | public class InventoryStringBuilder | 1205 | public class InventoryStringBuilder |
@@ -1082,87 +1265,63 @@ namespace OpenSim.Region.Framework.Scenes | |||
1082 | { | 1265 | { |
1083 | uint mask=0x7fffffff; | 1266 | uint mask=0x7fffffff; |
1084 | 1267 | ||
1085 | lock (m_items) | 1268 | foreach (TaskInventoryItem item in m_items.Values) |
1086 | { | 1269 | { |
1087 | foreach (TaskInventoryItem item in m_items.Values) | 1270 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) |
1271 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1272 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1273 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1274 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | ||
1275 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1276 | |||
1277 | if (item.InvType == (int)InventoryType.Object) | ||
1088 | { | 1278 | { |
1089 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | 1279 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
1090 | mask &= ~((uint)PermissionMask.Copy >> 13); | 1280 | mask &= ~((uint)PermissionMask.Copy >> 13); |
1091 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | 1281 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
1092 | mask &= ~((uint)PermissionMask.Transfer >> 13); | 1282 | mask &= ~((uint)PermissionMask.Transfer >> 13); |
1093 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | 1283 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
1094 | mask &= ~((uint)PermissionMask.Modify >> 13); | 1284 | mask &= ~((uint)PermissionMask.Modify >> 13); |
1095 | |||
1096 | if (item.InvType != (int)InventoryType.Object) | ||
1097 | { | ||
1098 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Copy) == 0) | ||
1099 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1100 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1101 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1102 | if ((item.CurrentPermissions & item.NextPermissions & (uint)PermissionMask.Modify) == 0) | ||
1103 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1104 | } | ||
1105 | else | ||
1106 | { | ||
1107 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | ||
1108 | mask &= ~((uint)PermissionMask.Copy >> 13); | ||
1109 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | ||
1110 | mask &= ~((uint)PermissionMask.Transfer >> 13); | ||
1111 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
1112 | mask &= ~((uint)PermissionMask.Modify >> 13); | ||
1113 | } | ||
1114 | |||
1115 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1116 | mask &= ~(uint)PermissionMask.Copy; | ||
1117 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1118 | mask &= ~(uint)PermissionMask.Transfer; | ||
1119 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
1120 | mask &= ~(uint)PermissionMask.Modify; | ||
1121 | } | 1285 | } |
1286 | |||
1287 | if ((item.CurrentPermissions & (uint)PermissionMask.Copy) == 0) | ||
1288 | mask &= ~(uint)PermissionMask.Copy; | ||
1289 | if ((item.CurrentPermissions & (uint)PermissionMask.Transfer) == 0) | ||
1290 | mask &= ~(uint)PermissionMask.Transfer; | ||
1291 | if ((item.CurrentPermissions & (uint)PermissionMask.Modify) == 0) | ||
1292 | mask &= ~(uint)PermissionMask.Modify; | ||
1122 | } | 1293 | } |
1123 | |||
1124 | return mask; | 1294 | return mask; |
1125 | } | 1295 | } |
1126 | 1296 | ||
1127 | public void ApplyNextOwnerPermissions() | 1297 | public void ApplyNextOwnerPermissions() |
1128 | { | 1298 | { |
1129 | lock (m_items) | 1299 | foreach (TaskInventoryItem item in m_items.Values) |
1130 | { | 1300 | { |
1131 | foreach (TaskInventoryItem item in m_items.Values) | 1301 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) |
1132 | { | 1302 | { |
1133 | // m_log.DebugFormat ( | 1303 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) |
1134 | // "[SCENE OBJECT PART INVENTORY]: Applying next permissions {0} to {1} in {2} with current {3}, base {4}, everyone {5}", | 1304 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; |
1135 | // item.NextPermissions, item.Name, m_part.Name, item.CurrentPermissions, item.BasePermissions, item.EveryonePermissions); | 1305 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) |
1136 | 1306 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | |
1137 | if (item.InvType == (int)InventoryType.Object && (item.CurrentPermissions & 7) != 0) | 1307 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) |
1138 | { | 1308 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; |
1139 | if ((item.CurrentPermissions & ((uint)PermissionMask.Copy >> 13)) == 0) | ||
1140 | item.CurrentPermissions &= ~(uint)PermissionMask.Copy; | ||
1141 | if ((item.CurrentPermissions & ((uint)PermissionMask.Transfer >> 13)) == 0) | ||
1142 | item.CurrentPermissions &= ~(uint)PermissionMask.Transfer; | ||
1143 | if ((item.CurrentPermissions & ((uint)PermissionMask.Modify >> 13)) == 0) | ||
1144 | item.CurrentPermissions &= ~(uint)PermissionMask.Modify; | ||
1145 | } | ||
1146 | |||
1147 | item.CurrentPermissions &= item.NextPermissions; | ||
1148 | item.BasePermissions &= item.NextPermissions; | ||
1149 | item.EveryonePermissions &= item.NextPermissions; | ||
1150 | item.OwnerChanged = true; | ||
1151 | item.PermsMask = 0; | ||
1152 | item.PermsGranter = UUID.Zero; | ||
1153 | } | 1309 | } |
1310 | item.CurrentPermissions &= item.NextPermissions; | ||
1311 | item.BasePermissions &= item.NextPermissions; | ||
1312 | item.EveryonePermissions &= item.NextPermissions; | ||
1313 | item.OwnerChanged = true; | ||
1314 | item.PermsMask = 0; | ||
1315 | item.PermsGranter = UUID.Zero; | ||
1154 | } | 1316 | } |
1155 | } | 1317 | } |
1156 | 1318 | ||
1157 | public void ApplyGodPermissions(uint perms) | 1319 | public void ApplyGodPermissions(uint perms) |
1158 | { | 1320 | { |
1159 | lock (m_items) | 1321 | foreach (TaskInventoryItem item in m_items.Values) |
1160 | { | 1322 | { |
1161 | foreach (TaskInventoryItem item in m_items.Values) | 1323 | item.CurrentPermissions = perms; |
1162 | { | 1324 | item.BasePermissions = perms; |
1163 | item.CurrentPermissions = perms; | ||
1164 | item.BasePermissions = perms; | ||
1165 | } | ||
1166 | } | 1325 | } |
1167 | 1326 | ||
1168 | m_inventorySerial++; | 1327 | m_inventorySerial++; |
@@ -1175,14 +1334,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
1175 | /// <returns></returns> | 1334 | /// <returns></returns> |
1176 | public bool ContainsScripts() | 1335 | public bool ContainsScripts() |
1177 | { | 1336 | { |
1178 | lock (m_items) | 1337 | foreach (TaskInventoryItem item in m_items.Values) |
1179 | { | 1338 | { |
1180 | foreach (TaskInventoryItem item in m_items.Values) | 1339 | if (item.InvType == (int)InventoryType.LSL) |
1181 | { | 1340 | { |
1182 | if (item.InvType == (int)InventoryType.LSL) | 1341 | return true; |
1183 | { | ||
1184 | return true; | ||
1185 | } | ||
1186 | } | 1342 | } |
1187 | } | 1343 | } |
1188 | 1344 | ||
@@ -1196,17 +1352,15 @@ namespace OpenSim.Region.Framework.Scenes | |||
1196 | public int ScriptCount() | 1352 | public int ScriptCount() |
1197 | { | 1353 | { |
1198 | int count = 0; | 1354 | int count = 0; |
1199 | lock (m_items) | 1355 | Items.LockItemsForRead(true); |
1356 | foreach (TaskInventoryItem item in m_items.Values) | ||
1200 | { | 1357 | { |
1201 | foreach (TaskInventoryItem item in m_items.Values) | 1358 | if (item.InvType == (int)InventoryType.LSL) |
1202 | { | 1359 | { |
1203 | if (item.InvType == (int)InventoryType.LSL) | 1360 | count++; |
1204 | { | ||
1205 | count++; | ||
1206 | } | ||
1207 | } | 1361 | } |
1208 | } | 1362 | } |
1209 | 1363 | Items.LockItemsForRead(false); | |
1210 | return count; | 1364 | return count; |
1211 | } | 1365 | } |
1212 | /// <summary> | 1366 | /// <summary> |
@@ -1242,11 +1396,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1242 | { | 1396 | { |
1243 | List<UUID> ret = new List<UUID>(); | 1397 | List<UUID> ret = new List<UUID>(); |
1244 | 1398 | ||
1245 | lock (m_items) | 1399 | foreach (TaskInventoryItem item in m_items.Values) |
1246 | { | 1400 | ret.Add(item.ItemID); |
1247 | foreach (TaskInventoryItem item in m_items.Values) | ||
1248 | ret.Add(item.ItemID); | ||
1249 | } | ||
1250 | 1401 | ||
1251 | return ret; | 1402 | return ret; |
1252 | } | 1403 | } |
@@ -1255,8 +1406,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
1255 | { | 1406 | { |
1256 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1407 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); |
1257 | 1408 | ||
1258 | lock (m_items) | 1409 | Items.LockItemsForRead(true); |
1259 | ret = new List<TaskInventoryItem>(m_items.Values); | 1410 | ret = new List<TaskInventoryItem>(m_items.Values); |
1411 | Items.LockItemsForRead(false); | ||
1260 | 1412 | ||
1261 | return ret; | 1413 | return ret; |
1262 | } | 1414 | } |
@@ -1265,18 +1417,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
1265 | { | 1417 | { |
1266 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); | 1418 | List<TaskInventoryItem> ret = new List<TaskInventoryItem>(); |
1267 | 1419 | ||
1268 | lock (m_items) | 1420 | Items.LockItemsForRead(true); |
1269 | { | 1421 | |
1270 | foreach (TaskInventoryItem item in m_items.Values) | 1422 | foreach (TaskInventoryItem item in m_items.Values) |
1271 | if (item.InvType == (int)type) | 1423 | if (item.InvType == (int)type) |
1272 | ret.Add(item); | 1424 | ret.Add(item); |
1273 | } | 1425 | |
1426 | Items.LockItemsForRead(false); | ||
1274 | 1427 | ||
1275 | return ret; | 1428 | return ret; |
1276 | } | 1429 | } |
1277 | 1430 | ||
1278 | public Dictionary<UUID, string> GetScriptStates() | 1431 | public Dictionary<UUID, string> GetScriptStates() |
1279 | { | 1432 | { |
1433 | return GetScriptStates(false); | ||
1434 | } | ||
1435 | |||
1436 | public Dictionary<UUID, string> GetScriptStates(bool oldIDs) | ||
1437 | { | ||
1280 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); | 1438 | Dictionary<UUID, string> ret = new Dictionary<UUID, string>(); |
1281 | 1439 | ||
1282 | if (m_part.ParentGroup.Scene == null) // Group not in a scene | 1440 | if (m_part.ParentGroup.Scene == null) // Group not in a scene |
@@ -1302,14 +1460,21 @@ namespace OpenSim.Region.Framework.Scenes | |||
1302 | string n = e.GetXMLState(item.ItemID); | 1460 | string n = e.GetXMLState(item.ItemID); |
1303 | if (n != String.Empty) | 1461 | if (n != String.Empty) |
1304 | { | 1462 | { |
1305 | if (!ret.ContainsKey(item.ItemID)) | 1463 | if (oldIDs) |
1306 | ret[item.ItemID] = n; | 1464 | { |
1465 | if (!ret.ContainsKey(item.OldItemID)) | ||
1466 | ret[item.OldItemID] = n; | ||
1467 | } | ||
1468 | else | ||
1469 | { | ||
1470 | if (!ret.ContainsKey(item.ItemID)) | ||
1471 | ret[item.ItemID] = n; | ||
1472 | } | ||
1307 | break; | 1473 | break; |
1308 | } | 1474 | } |
1309 | } | 1475 | } |
1310 | } | 1476 | } |
1311 | } | 1477 | } |
1312 | |||
1313 | return ret; | 1478 | return ret; |
1314 | } | 1479 | } |
1315 | 1480 | ||